Files
MyManagingTools/src/core/settings_management.py
2025-05-10 20:40:03 +02:00

229 lines
7.0 KiB
Python

import json
import logging
import os.path
from core.dbengine import DbEngine, DbException
from core.instance_manager import NO_SESSION, NOT_LOGGED
from core.settings_objects import *
load_settings_obj() # needed to make sure that the import of core is not removed
FAKE_USER_ID = "FakeUserId"
logger = logging.getLogger(__name__)
class NoDefaultCls:
pass
NoDefault = NoDefaultCls()
class DummyDbEngine:
"""
Dummy DB engine
Can only serialize object defined in settings_object module
Save everything in a single file
"""
def __init__(self, setting_path="settings.json"):
self.db_path = setting_path
def save(self, user_id: str, entry: str, obj: object) -> bool:
if not hasattr(obj, "as_dict"):
raise Exception("'as_dict' not found. Not supported")
as_dict = getattr(obj, "as_dict")()
as_dict["__type__"] = type(obj).__name__
if os.path.exists(self.db_path):
with open(self.db_path, "r") as settings_file:
as_json = json.load(settings_file)
as_json[entry] = as_dict
with open(self.db_path, "w") as settings_file:
json.dump(as_json, settings_file)
else:
as_json = {entry: as_dict}
with open(self.db_path, "w") as settings_file:
json.dump(as_json, settings_file)
return True
def load(self, user_id: str, entry: str, digest: str = None):
try:
with open(self.db_path, "r") as settings_file:
as_json = json.load(settings_file)
as_dict = as_json[entry]
obj_type = as_dict.pop("__type__")
obj = globals()[obj_type]()
getattr(obj, "from_dict")(as_dict)
return obj
except Exception as ex:
raise DbException(f"Entry '{entry}' is not found.")
def is_initialized(self):
return os.path.exists(self.db_path)
def init(self):
pass
class MemoryDbEngine:
"""
Keeps everything in memory
"""
def __init__(self):
self.db = {}
def init_db(self, entry, key, obj):
self.db[entry] = {key: obj}
def save(self, user_id: str, entry: str, obj: object) -> bool:
self.db[entry] = obj
return True
def load(self, user_id: str, entry: str, digest: str = None):
try:
return self.db[entry]
except KeyError:
return {}
def get(self, user_id: str, entry: str, key: str | None = None, digest=None):
return self.db[entry][key]
def put(self, user_id: str, entry, key: str, value: object):
if entry not in self.db:
self.db[entry] = {}
self.db[entry][key] = value
def is_initialized(self):
return True
class SettingsManager:
def __init__(self, engine=None):
self._db_engine = engine or DbEngine()
def save(self, user_id: str, entry: str, obj: object):
return self._db_engine.save(user_id, entry, obj)
def load(self, user_id: str, entry: str):
return self._db_engine.load(user_id, entry)
def get_all(self, user_id: str, entry: str):
""""
Returns all the items of an entry
"""
return self._db_engine.get(user_id, entry, None)
def put(self, session: dict, key: str, value: object):
"""
Inserts or updates a key-value pair in the database for the current user session.
The method extracts the user ID and email from the session dictionary and
utilizes the database engine to perform the storage operation.
:param session: A dictionary containing session-specific details,
including 'user_id' and 'user_email'.
:type session: dict
:param key: The key under which the value should be stored in the database.
:type key: str
:param value: The value to be stored, associated with the specified key.
:type value: object
:return: The result of the database engine's put operation.
:rtype: object
"""
user_id = session["user_id"] if session else NO_SESSION
user_email = session["user_email"] if session else NOT_LOGGED
return self._db_engine.put(user_email, str(user_id), key, value)
def get(self, session: dict, key: str | None = None, default=NoDefault):
"""
Fetches a value associated with a specific key for a user session from the
database. If the key is not found in the database and a default value is
provided, returns the default value. If no default is provided and the key
is not found, raises a KeyError.
:param session: A dictionary containing session data. Must include "user_id"
and "user_email" keys.
:type session: dict
:param key: The key to fetch from the database for the given session user.
Defaults to None if not specified.
:type key: str | None
:param default: The default value to return if the key is not found in the
database. If not provided, raises KeyError when the key is missing.
:type default: Any
:return: The value associated with the key for the user session if found in
the database, or the provided default value if the key is not found.
"""
try:
user_id = session["user_id"] if session else NO_SESSION
user_email = session["user_email"] if session else NOT_LOGGED
return self._db_engine.get(user_email, str(user_id), key)
except KeyError:
if default is NoDefault:
raise
else:
return default
def remove(self, session: dict, key: str):
user_id = session["user_id"] if session else NO_SESSION
user_email = session["user_email"] if session else NOT_LOGGED
return self._db_engine.remove(user_email, user_id, key)
def update(self, session: dict, old_key: str, key: str, value: object):
user_id = session["user_id"] if session else NO_SESSION
user_email = session["user_email"] if session else NOT_LOGGED
def _update_helper(_old_key, _key, _value):
pass
if hasattr(self._db_engine, "lock"):
with self._db_engine.lock:
_update_helper(old_key, key, value)
else:
_update_helper(old_key, key, value)
def init_user(self, user_id: str, user_email: str):
"""
Init the settings block space for a user
:param user_id:
:param user_email:
:return:
"""
if not self._db_engine.exists(user_id):
self._db_engine.save(user_email, user_id, {})
def get_db_engine_root(self):
return os.path.abspath(self._db_engine.root)
def get_db_engine(self):
return self._db_engine
class SettingsTransaction:
def __init__(self, session, settings_manager: SettingsManager):
self._settings_manager = settings_manager
self._session = session
self._user_id = session["user_id"] if session else NO_SESSION
self._user_email = session["user_email"] if session else NOT_LOGGED
self._entries = None
def __enter__(self):
self._entries = self._settings_manager.load(self._user_email, self._user_id)
return self
def put(self, key: str, value: object):
self._entries[key] = value
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None:
self._settings_manager.save(self._user_email, self._user_id, self._entries)
#
# settings_manager = SettingsManager()
# settings_manager.init()