import logging from functools import wraps from django.db.models import Model from django_proxmox_mikrotik.configs import MIKROTIK_READONLY, MikrotikConfig, PROXMOX_READONLY, ProxmoxConfig def readonly(func): """Decorator to temporarily enable READONLY for both Proxmox and Mikrotik""" @wraps(func) def wrapper(*args, **kwargs): pm_initial = ProxmoxConfig.READONLY mk_initial = MikrotikConfig.READONLY ProxmoxConfig.READONLY = True MikrotikConfig.READONLY = True logging.debug(f"READONLY: Setting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} " f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}") try: return func(*args, **kwargs) finally: logging.debug(f"READONLY: Resetting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} " f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}") ProxmoxConfig.READONLY = PROXMOX_READONLY MikrotikConfig.READONLY = MIKROTIK_READONLY return wrapper def force_write(func): """Decorator to temporarily disable READONLY for both Proxmox and Mikrotik""" @wraps(func) def wrapper(*args, **kwargs): pm_initial = ProxmoxConfig.READONLY mk_initial = MikrotikConfig.READONLY ProxmoxConfig.READONLY = False MikrotikConfig.READONLY = False logging.debug(f"FORCE WRITE: Setting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} " f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}") try: return func(*args, **kwargs) finally: logging.debug(f"FORCE WRITE: Resetting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} " f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}") ProxmoxConfig.READONLY = PROXMOX_READONLY MikrotikConfig.READONLY = MIKROTIK_READONLY return wrapper def skip_signal(signaltype='post_save', **kwargs): """This should be used as decorator for signal handlers to prevent recursion. Mostly used for post_save and post_delete. The signaltype is just for logging.""" def _decorator(signal_handler): @wraps(signal_handler) def _wrapper(sender, instance: Model, **kwargs): if getattr(instance, '_skip_signal', False): logging.debug( f'Skip signal handler for {signaltype} : {signal_handler.__name__} - {sender.__name__} - {instance.__class__.__name__}') return instance._skip_signal = True try: return signal_handler(sender, instance, **kwargs) finally: try: del instance._skip_signal except AttributeError: logging.debug( f'{instance.__class__.__name__} instance has no attribute "_skip_signal" - could not delete it.') except Exception as e: logging.exception('WTF????', str(e)) return _wrapper return _decorator