229 lines
7.0 KiB
Python
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()
|