First Working version. I can add table
This commit is contained in:
210
src/core/settings_management.py
Normal file
210
src/core/settings_management.py
Normal file
@@ -0,0 +1,210 @@
|
||||
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 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()
|
||||
Reference in New Issue
Block a user