Small refactor, internalise the datastruct

This commit is contained in:
dgtlmoon
2024-12-30 10:57:30 +01:00
parent 2d37f94c5f
commit 281f637068
5 changed files with 35 additions and 49 deletions
+1 -1
View File
@@ -801,7 +801,7 @@ def changedetection_app(config=None, datastore_o=None):
# Recast it if need be to right data Watch handler
watch_class = get_custom_watch_obj_for_processor(form.data.get('processor'))
datastore.data['watching'][uuid] = watch_class(datastore_path=datastore_o.datastore_path, default=datastore.data['watching'][uuid])
datastore.data['watching'][uuid] = watch_class(__datastore=datastore_o, default=datastore.data['watching'][uuid])
flash("Updated watch - unpaused!" if request.args.get('unpause_on_save') else "Updated watch.")
# Re #286 - We wait for syncing new data to disk in another thread every 60 seconds
+2 -2
View File
@@ -10,7 +10,7 @@ _FILTER_FAILURE_THRESHOLD_ATTEMPTS_DEFAULT = 6
DEFAULT_SETTINGS_HEADERS_USERAGENT='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'
class model(dict):
base_config = {
__base_config = {
'note': "Hello! If you change this file manually, please be sure to restart your changedetection.io instance!",
'watching': {},
'settings': {
@@ -60,7 +60,7 @@ class model(dict):
def __init__(self, *arg, **kw):
super(model, self).__init__(*arg, **kw)
self.update(self.base_config)
self.update(self.__base_config)
def parse_headers_from_text_file(filepath):
+9 -6
View File
@@ -33,14 +33,17 @@ def is_safe_url(test_url):
class model(WatchBase):
__newest_history_key = None
__datastore = None
__history_n = 0
__newest_history_key = None
jitter_seconds = 0
def __init__(self, *arg, **kw):
self.__datastore_path = kw.get('datastore_path')
if kw.get('datastore_path'):
del kw['datastore_path']
if not kw.get('__datastore'):
logger.critical('No __datastore reference was set!')
self.__datastore = kw.get('__datastore')
super(model, self).__init__(*arg, **kw)
if kw.get('default'):
self.update(kw['default'])
@@ -419,7 +422,7 @@ class model(WatchBase):
@property
def watch_data_dir(self):
# The base dir of the watch data
return os.path.join(self.__datastore_path, self['uuid']) if self.__datastore_path else None
return os.path.join(self.__datastore.datastore_path, self['uuid']) if self.__datastore.datastore_path else None
def get_error_text(self):
"""Return the text saved from a previous request that resulted in a non-200 error"""
+11 -27
View File
@@ -7,7 +7,7 @@ from changedetectionio.notification import default_notification_format_for_watch
class WatchBase(MutableMapping):
def __init__(self, *args, **kwargs):
self.internal_dict = {
self.__internal_dict = {
# Custom notification content
# Re #110, so then if this is set to None, we know to use the default value instead
# Requires setting to None on submit if it's the same as the default
@@ -137,42 +137,26 @@ class WatchBase(MutableMapping):
# Implement abstract methods required by MutableMapping
def __getitem__(self, key):
return self.internal_dict[key]
return self.__internal_dict[key]
def __setitem__(self, key, value):
self.internal_dict[key] = value
if key == '__datastore':
self.__datastore = value
else:
self.__internal_dict[key] = value
def __delitem__(self, key):
del self.internal_dict[key]
del self.__internal_dict[key]
def __iter__(self):
return iter(self.internal_dict)
return iter(self.__internal_dict)
def __len__(self):
return len(self.internal_dict)
return len(self.__internal_dict)
# Optional: Implement additional methods for convenience
def __repr__(self):
return f"{self.__class__.__name__}({self.internal_dict})"
return f"{self.__class__.__name__}({self.__internal_dict})"
def as_dict(self):
return self.internal_dict
# def __getattr__(self, attr):
# Allow attribute-style access
# try:
# return self.internal_dict[attr]
# except KeyError:
# raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{attr}'")
# def __setattr__(self, attr, value):
# if attr == 'internal_dict':
# super().__setattr__(attr, value)
# else:
# self.internal_dict[attr] = value
# def __delattr__(self, attr):
# if attr == 'internal_dict':
# super().__delattr__(attr)
# else:
# del self.internal_dict[attr]
return self.__internal_dict
+12 -13
View File
@@ -28,8 +28,8 @@ dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, WatchBase):
return obj.internal_dict
if obj and isinstance(obj, WatchBase):
return obj.as_dict()
# Add more custom type handlers here
return super().default(obj)
@@ -56,9 +56,6 @@ class ChangeDetectionStore:
self.needs_write = False
self.start_time = time.time()
self.stop_thread = False
# Base definition for all watchers
# deepcopy part of #569 - not sure why its needed exactly
self.generic_definition = deepcopy(Watch.model(datastore_path = datastore_path, default={}))
if path.isfile('changedetectionio/source.txt'):
with open('changedetectionio/source.txt') as f:
@@ -165,7 +162,7 @@ class ChangeDetectionStore:
if entity.get('uuid') != 'text_json_diff':
logger.trace(f"Loading Watch object '{watch_class.__module__}.{watch_class.__name__}' for UUID {uuid}")
entity = watch_class(datastore_path=self.datastore_path, default=entity)
entity = watch_class(__datastore=self, default=entity)
return entity
def set_last_viewed(self, uuid, timestamp):
@@ -184,13 +181,15 @@ class ChangeDetectionStore:
return
with self.lock:
# deepcopy part of #569 - not sure why its needed exactly
# self.generic_definition = deepcopy(Watch.model(default={}))
# In python 3.9 we have the |= dict operator, but that still will lose data on nested structures...
for dict_key, d in self.generic_definition.items():
if isinstance(d, dict):
if update_obj is not None and dict_key in update_obj:
self.__data['watching'][uuid][dict_key].update(update_obj[dict_key])
del (update_obj[dict_key])
# # In python 3.9 we have the |= dict operator, but that still will lose data on nested structures...
# for dict_key, d in self.generic_definition.items():
# if isinstance(d, dict):
# if update_obj is not None and dict_key in update_obj:
# self.__data['watching'][uuid][dict_key].update(update_obj[dict_key])
# del (update_obj[dict_key])
self.__data['watching'][uuid].update(update_obj)
self.needs_write = True
@@ -353,7 +352,7 @@ class ChangeDetectionStore:
# If the processor also has its own Watch implementation
watch_class = get_custom_watch_obj_for_processor(apply_extras.get('processor'))
new_watch = watch_class(datastore_path=self.datastore_path, url=url)
new_watch = watch_class(__datastore=self, url=url)
new_uuid = new_watch.get('uuid')