second commit

This commit is contained in:
2026-04-13 23:14:05 +02:00
parent 1c031ebf63
commit e08597fc72
125 changed files with 26221 additions and 0 deletions
+261
View File
@@ -0,0 +1,261 @@
'''
Created on 20 avr. 2022
@author: denis
'''
import yaml
import time
import importlib
from datetime import datetime
import string, secrets
import uuid
from threading import Event, Thread
from urllib.parse import urlsplit
import asyncio
# sysutils.py
import os
import mmap
import fcntl
import psutil
SHM_DIR = "/dev/shm"
def open_shm(name: str, size: int, create=True):
path = os.path.join(SHM_DIR, name)
flags = os.O_RDWR | (os.O_CREAT if create else 0)
fd = os.open(path, flags)
try:
if create:
os.ftruncate(fd, size)
mm = mmap.mmap(fd, size)
finally:
os.close(fd)
return mm, path
def read_shm(name: str, size: int):
mm, path = open_shm(name, size, create=False) # @UnusedVariable
try:
mm.seek(0)
data = mm.read(size)
return data.rstrip(b"\0")
finally:
mm.close()
def write_shm(name: str, size: int, data: bytes):
mm, path = open_shm(name, size, create=True)
fd = os.open(path, os.O_RDWR)
try:
fcntl.flock(fd, fcntl.LOCK_EX)
try:
mm.seek(0)
mm.write(data.ljust(size, b"\0")[:size])
mm.flush()
finally:
fcntl.flock(fd, fcntl.LOCK_UN)
finally:
mm.close()
os.close(fd)
def get_tmpfs_info(mount_point="/ramdisk"):
def sizeof(n):
for unit in ['B','KB','MB','GB','TB']:
if n < 1024:
return f"{n:.1f}{unit}"
n /= 1024
return f"{n:.1f}PB"
usage = None
for part in psutil.disk_partitions(all=True):
if part.mountpoint == mount_point and part.fstype.lower() == "tmpfs":
usage = psutil.disk_usage(part.mountpoint)
print(f"Mount: {part.mountpoint}")
print(f" Device: {part.device}")
print(f" Fstype: {part.fstype}")
print(f" Total: {usage.total} bytes ({sizeof(usage.total)})")
print(f" Used: {usage.used} bytes ({sizeof(usage.used)})")
print(f" Free: {usage.free} bytes ({sizeof(usage.free)})")
print(f" Percent used: {usage.percent}%")
break
return {
"percent": usage.percent,
"mount": part.mountpoint,
"device": part.device,
"fstype": part.fstype,
"total": usage.total,
"used": usage.used,
"free": usage.free,
}
def get_cpu_info():
# cpu percent par coeur et moyennes load
return {
"cpu_percent_per_cpu": psutil.cpu_percent(interval=0.5, percpu=True),
"cpu_percent_total": psutil.cpu_percent(interval=None),
"load_avg": os.getloadavg(), # (1,5,15)
"cpu_count": psutil.cpu_count(logical=True),
}
def get_memory_info():
vm = psutil.virtual_memory()
sm = psutil.swap_memory()
return {
"total": vm.total,
"available": vm.available,
"used": vm.used,
"free": vm.free,
"percent": vm.percent,
"swap_total": sm.total,
"swap_used": sm.used,
"swap_free": sm.free,
"swap_percent": sm.percent,
}
def get_disk_info(path="/"):
du = psutil.disk_usage(path)
return {
"path": path,
"total": du.total,
"used": du.used,
"free": du.free,
"percent": du.percent,
}
def extract_host_port_path(url, default_port=None):
"""
Retoure (host, port, path) où:
- host: string (IP ou hostname) ou None
- port: int ou None (utilise default_port si fourni et aucun port explicite)
- path: string (chemin + query + fragment si présents), ou '' si absent
"""
parts = urlsplit(url if '://' in url else '//' + url, scheme='')
host = parts.hostname
port = parts.port or default_port
# Reconstruire path complet: path + ('?' + query) + ('#' + fragment)
path = parts.path or ''
if parts.query:
path += '?' + parts.query
if parts.fragment:
path += '#' + parts.fragment
return host, port, path
def image_path(imagefile):
image_path = imagefile.path
pdir = os.path.dirname(image_path)
os.makedirs(pdir, exist_ok=True)
return str(image_path)
def serialize_datetime(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError("Type not serializable")
def start_async():
loop = asyncio.new_event_loop()
Thread(target=loop.run_forever, daemon=True).start()
return loop
def stop_async(loop):
loop.call_soon_threadsafe(loop.stop)
def submit_async(loop, awaitable):
return asyncio.run_coroutine_threadsafe(awaitable, loop)
def to_choice(d):
choices = []
for k, v in d.items():
choices.append((k, v))
return choices
def get_instance_class(module):
modulename, classname = module.rsplit(".", 1)
return getattr(importlib.import_module(modulename), classname)
def wait_for(timeout):
Event().wait(timeout)
def yaml_load(f):
with open(f, 'r') as stream:
return yaml.safe_load(stream)
return {}
def yaml_save(f, context):
with open(f, 'w') as stream:
yaml.dump(context, stream, default_flow_style = False)
def get_uuid():
return str(hex(uuid.getnode()))[2:]
def millis():
return round(time.time() * 1000)
def now():
return datetime.now()
def ts_now():
# float second
return now().timestamp()
def ts_now_s():
return int(ts_now())
def ts_now_ms():
return int(ts_now()*1000)
def ts_now_us():
return int(ts_now()*1000000)
def random_num(n=16):
alphabet = string.digits
return ''.join(secrets.choice(alphabet) for i in range(n)) # @UnusedVariable
def random_chars(n=6):
alphabet = string.ascii_letters + string.digits
return ''.join(secrets.choice(alphabet) for i in range(n)) # @UnusedVariable
def get_apikey(n=32):
chars = 'abcdefgh01234ijklABCD4567EFGHIJKLmnopqrstuvwxyz0123456789MNOPQRS789TUVWXYZ'
return ''.join(secrets.choice(chars) for i in range(n)) # @UnusedVariable
def gen_keywords(s):
c = s.replace(',', ' ').replace('+', ' ')
return [ w.strip() for w in c.split(' ') if w]
def gen_device_uuid(n=19):
return hex(int(random_num(n)))[2:]
def get_device_uuid(n=19):
return f'0x{gen_device_uuid(n)}'