mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-09-22 05:16:07 +00:00
Small refactor, internalise the datastruct
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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"""
|
||||
|
||||
@@ -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
@@ -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')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user