|
|
@ -243,7 +243,6 @@ class update_worker(threading.Thread):
|
|
|
|
os.unlink(full_path)
|
|
|
|
os.unlink(full_path)
|
|
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
def run(self):
|
|
|
|
now = time.time()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while not self.app.config.exit.is_set():
|
|
|
|
while not self.app.config.exit.is_set():
|
|
|
|
update_handler = None
|
|
|
|
update_handler = None
|
|
|
@ -254,6 +253,7 @@ class update_worker(threading.Thread):
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
|
|
|
|
fetch_start_time = time.time()
|
|
|
|
uuid = queued_item_data.item.get('uuid')
|
|
|
|
uuid = queued_item_data.item.get('uuid')
|
|
|
|
self.current_uuid = uuid
|
|
|
|
self.current_uuid = uuid
|
|
|
|
if uuid in list(self.datastore.data['watching'].keys()) and self.datastore.data['watching'][uuid].get('url'):
|
|
|
|
if uuid in list(self.datastore.data['watching'].keys()) and self.datastore.data['watching'][uuid].get('url'):
|
|
|
@ -268,7 +268,6 @@ class update_worker(threading.Thread):
|
|
|
|
watch = self.datastore.data['watching'].get(uuid)
|
|
|
|
watch = self.datastore.data['watching'].get(uuid)
|
|
|
|
|
|
|
|
|
|
|
|
logger.info(f"Processing watch UUID {uuid} Priority {queued_item_data.priority} URL {watch['url']}")
|
|
|
|
logger.info(f"Processing watch UUID {uuid} Priority {queued_item_data.priority} URL {watch['url']}")
|
|
|
|
now = time.time()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
# Processor is what we are using for detecting the "Change"
|
|
|
|
# Processor is what we are using for detecting the "Change"
|
|
|
@ -288,6 +287,10 @@ class update_worker(threading.Thread):
|
|
|
|
|
|
|
|
|
|
|
|
update_handler.call_browser()
|
|
|
|
update_handler.call_browser()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# In reality, the actual time of when the change was detected could be a few seconds after this
|
|
|
|
|
|
|
|
# For example it should include when the page stopped rendering if using a playwright/chrome type fetch
|
|
|
|
|
|
|
|
fetch_start_time = time.time()
|
|
|
|
|
|
|
|
|
|
|
|
changed_detected, update_obj, contents = update_handler.run_changedetection(watch=watch)
|
|
|
|
changed_detected, update_obj, contents = update_handler.run_changedetection(watch=watch)
|
|
|
|
|
|
|
|
|
|
|
|
# Re #342
|
|
|
|
# Re #342
|
|
|
@ -512,7 +515,7 @@ class update_worker(threading.Thread):
|
|
|
|
|
|
|
|
|
|
|
|
if not self.datastore.data['watching'].get(uuid):
|
|
|
|
if not self.datastore.data['watching'].get(uuid):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
#
|
|
|
|
|
|
|
|
# Different exceptions mean that we may or may not want to bump the snapshot, trigger notifications etc
|
|
|
|
# Different exceptions mean that we may or may not want to bump the snapshot, trigger notifications etc
|
|
|
|
if process_changedetection_results:
|
|
|
|
if process_changedetection_results:
|
|
|
|
|
|
|
|
|
|
|
@ -525,8 +528,6 @@ class update_worker(threading.Thread):
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
logger.warning(f"UUID: {uuid} Extract <title> as watch title was enabled, but couldn't find a <title>.")
|
|
|
|
logger.warning(f"UUID: {uuid} Extract <title> as watch title was enabled, but couldn't find a <title>.")
|
|
|
|
|
|
|
|
|
|
|
|
# Now update after running everything
|
|
|
|
|
|
|
|
timestamp = round(time.time())
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.datastore.update_watch(uuid=uuid, update_obj=update_obj)
|
|
|
|
self.datastore.update_watch(uuid=uuid, update_obj=update_obj)
|
|
|
|
|
|
|
|
|
|
|
@ -542,24 +543,28 @@ class update_worker(threading.Thread):
|
|
|
|
|
|
|
|
|
|
|
|
# Small hack so that we sleep just enough to allow 1 second between history snapshots
|
|
|
|
# Small hack so that we sleep just enough to allow 1 second between history snapshots
|
|
|
|
# this is because history.txt indexes/keys snapshots by epoch seconds and we dont want dupe keys
|
|
|
|
# this is because history.txt indexes/keys snapshots by epoch seconds and we dont want dupe keys
|
|
|
|
|
|
|
|
# @also - the keys are one per second at the most (for now)
|
|
|
|
if watch.newest_history_key and int(timestamp) == int(watch.newest_history_key):
|
|
|
|
if watch.newest_history_key and int(fetch_start_time) == int(watch.newest_history_key):
|
|
|
|
logger.warning(
|
|
|
|
logger.warning(
|
|
|
|
f"Timestamp {timestamp} already exists, waiting 1 seconds so we have a unique key in history.txt")
|
|
|
|
f"Timestamp {fetch_start_time} already exists, waiting 1 seconds so we have a unique key in history.txt")
|
|
|
|
timestamp = str(int(timestamp) + 1)
|
|
|
|
fetch_start_time += 1
|
|
|
|
time.sleep(1)
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
|
|
|
|
watch.save_history_text(contents=contents,
|
|
|
|
watch.save_history_text(contents=contents,
|
|
|
|
timestamp=timestamp,
|
|
|
|
timestamp=int(fetch_start_time),
|
|
|
|
snapshot_id=update_obj.get('previous_md5', 'none'))
|
|
|
|
snapshot_id=update_obj.get('previous_md5', 'none'))
|
|
|
|
|
|
|
|
|
|
|
|
if update_handler.fetcher.content:
|
|
|
|
|
|
|
|
watch.save_last_fetched_html(contents=update_handler.fetcher.content, timestamp=timestamp)
|
|
|
|
empty_pages_are_a_change = self.datastore.data['settings']['application'].get('empty_pages_are_a_change', False)
|
|
|
|
|
|
|
|
if update_handler.fetcher.content or (not update_handler.fetcher.content and empty_pages_are_a_change):
|
|
|
|
|
|
|
|
# attribute .last_changed is then based on this data
|
|
|
|
|
|
|
|
watch.save_last_fetched_html(contents=update_handler.fetcher.content, timestamp=int(fetch_start_time))
|
|
|
|
|
|
|
|
|
|
|
|
# Notifications should only trigger on the second time (first time, we gather the initial snapshot)
|
|
|
|
# Notifications should only trigger on the second time (first time, we gather the initial snapshot)
|
|
|
|
if watch.history_n >= 2:
|
|
|
|
if watch.history_n >= 2:
|
|
|
|
logger.info(f"Change detected in UUID {uuid} - {watch['url']}")
|
|
|
|
logger.info(f"Change detected in UUID {uuid} - {watch['url']}")
|
|
|
|
if not watch.get('notification_muted'):
|
|
|
|
if not watch.get('notification_muted'):
|
|
|
|
|
|
|
|
# @todo only run this if notifications exist
|
|
|
|
self.send_content_changed_notification(watch_uuid=uuid)
|
|
|
|
self.send_content_changed_notification(watch_uuid=uuid)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
@ -581,15 +586,15 @@ class update_worker(threading.Thread):
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
self.datastore.update_watch(uuid=uuid, update_obj={'fetch_time': round(time.time() - now, 3),
|
|
|
|
self.datastore.update_watch(uuid=uuid, update_obj={'fetch_time': round(time.time() - fetch_start_time, 3),
|
|
|
|
'last_checked': round(time.time()),
|
|
|
|
'last_checked': int(fetch_start_time),
|
|
|
|
'check_count': count
|
|
|
|
'check_count': count
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.current_uuid = None # Done
|
|
|
|
self.current_uuid = None # Done
|
|
|
|
self.q.task_done()
|
|
|
|
self.q.task_done()
|
|
|
|
logger.debug(f"Watch {uuid} done in {time.time()-now:.2f}s")
|
|
|
|
logger.debug(f"Watch {uuid} done in {time.time()-fetch_start_time:.2f}s")
|
|
|
|
|
|
|
|
|
|
|
|
# Give the CPU time to interrupt
|
|
|
|
# Give the CPU time to interrupt
|
|
|
|
time.sleep(0.1)
|
|
|
|
time.sleep(0.1)
|
|
|
|