diff --git a/changedetectionio/__init__.py b/changedetectionio/__init__.py
index 556503122..4c8756fa9 100644
--- a/changedetectionio/__init__.py
+++ b/changedetectionio/__init__.py
@@ -370,20 +370,20 @@ def changedetection_app(config=None, datastore_o=None):
from changedetectionio import forms
limit_tag = request.args.get('tag')
- pause_uuid = request.args.get('pause')
-
# Redirect for the old rss path which used the /?rss=true
if request.args.get('rss'):
return redirect(url_for('rss', tag=limit_tag))
- if pause_uuid:
- try:
- datastore.data['watching'][pause_uuid]['paused'] ^= True
- datastore.needs_write = True
+ op = request.args.get('op')
+ if op:
+ uuid = request.args.get('uuid')
+ if op == 'pause':
+ datastore.data['watching'][uuid]['paused'] ^= True
+ elif op == 'mute':
+ datastore.data['watching'][uuid]['notification_muted'] ^= True
- return redirect(url_for('index', tag = limit_tag))
- except KeyError:
- pass
+ datastore.needs_write = True
+ return redirect(url_for('index', tag = limit_tag))
# Sort by last_changed and add the uuid which is usually the key..
sorted_watches = []
diff --git a/changedetectionio/model/Watch.py b/changedetectionio/model/Watch.py
index b53688d3c..458a6fd2f 100644
--- a/changedetectionio/model/Watch.py
+++ b/changedetectionio/model/Watch.py
@@ -36,6 +36,7 @@ class model(dict):
'notification_title': default_notification_title,
'notification_body': default_notification_body,
'notification_format': default_notification_format,
+ 'notification_muted': False,
'css_filter': '',
'extract_text': [], # Extract text by regex after filters
'subtractive_selectors': [],
diff --git a/changedetectionio/static/styles/styles.css b/changedetectionio/static/styles/styles.css
index 1271c2048..34934f9a7 100644
--- a/changedetectionio/static/styles/styles.css
+++ b/changedetectionio/static/styles/styles.css
@@ -271,13 +271,15 @@ footer {
#new-version-text a {
color: #e07171; }
-.watch-controls.state-False img {
- opacity: 0.2;
- transition: opacity 0.3s; }
-
-.watch-controls img:hover {
- transition: opacity 0.3s;
- opacity: 0.8; }
+.watch-controls {
+ /* default */ }
+ .watch-controls .state-on img {
+ opacity: 0.8; }
+ .watch-controls img {
+ opacity: 0.2; }
+ .watch-controls img:hover {
+ transition: opacity 0.3s;
+ opacity: 0.8; }
.monospaced-textarea textarea {
width: 100%;
diff --git a/changedetectionio/static/styles/styles.scss b/changedetectionio/static/styles/styles.scss
index f16c4e0cb..acfcacbef 100644
--- a/changedetectionio/static/styles/styles.scss
+++ b/changedetectionio/static/styles/styles.scss
@@ -363,16 +363,24 @@ footer {
}
.watch-controls {
- &.state-False img {
- opacity: 0.2;
- transition: opacity 0.3s;
+ .state-on {
+ img {
+ opacity: 0.8;
+ }
}
+
+ /* default */
+ img {
+ opacity: 0.2;
+ }
+
img {
&:hover {
transition: opacity 0.3s;
opacity: 0.8;
}
}
+
}
.monospaced-textarea {
diff --git a/changedetectionio/templates/watch-overview.html b/changedetectionio/templates/watch-overview.html
index 0377dcf58..0ab08decf 100644
--- a/changedetectionio/templates/watch-overview.html
+++ b/changedetectionio/templates/watch-overview.html
@@ -56,11 +56,10 @@
{% if watch.newest_history_key| int > watch.last_viewed and watch.history_n>=2 %}unviewed{% endif %}
{% if watch.uuid in queued_uuids %}queued{% endif %}">
{{ loop.index }} |
-
-
-
+ |
+
+
|
-
{{watch.title if watch.title is not none and watch.title|length > 0 else watch.url}}
diff --git a/changedetectionio/update_worker.py b/changedetectionio/update_worker.py
index 02ea036ce..697abbc1f 100644
--- a/changedetectionio/update_worker.py
+++ b/changedetectionio/update_worker.py
@@ -21,6 +21,63 @@ class update_worker(threading.Thread):
self.datastore = datastore
super().__init__(*args, **kwargs)
+ def send_content_changed_notification(self, uuid):
+ n_object = {}
+ watch = self.datastore.data['watching'].get(uuid, False)
+ if not watch:
+ return
+
+ watch_history = watch.history
+ dates = list(watch_history.keys())
+ # Theoretically it's possible that this could be just 1 long,
+ # - In the case that the timestamp key was not unique
+ if len(dates) == 1:
+ raise ValueError(
+ "History index had 2 or more, but only 1 date loaded, timestamps were not unique? maybe two of the same timestamps got written, needs more delay?"
+ )
+
+ # Did it have any notification alerts to hit?
+ if len(watch['notification_urls']):
+ print(">>> Notifications queued for UUID from watch {}".format(uuid))
+ n_object['notification_urls'] = watch['notification_urls']
+ n_object['notification_title'] = watch['notification_title']
+ n_object['notification_body'] = watch['notification_body']
+ n_object['notification_format'] = watch['notification_format']
+
+ # No? maybe theres a global setting, queue them all
+ elif len(self.datastore.data['settings']['application']['notification_urls']):
+ print(">>> Watch notification URLs were empty, using GLOBAL notifications for UUID: {}".format(uuid))
+ n_object['notification_urls'] = self.datastore.data['settings']['application']['notification_urls']
+ n_object['notification_title'] = self.datastore.data['settings']['application']['notification_title']
+ n_object['notification_body'] = self.datastore.data['settings']['application']['notification_body']
+ n_object['notification_format'] = self.datastore.data['settings']['application']['notification_format']
+ else:
+ print(">>> NO notifications queued, watch and global notification URLs were empty.")
+
+ # Only prepare to notify if the rules above matched
+ if 'notification_urls' in n_object:
+ # HTML needs linebreak, but MarkDown and Text can use a linefeed
+ if n_object['notification_format'] == 'HTML':
+ line_feed_sep = ""
+ else:
+ line_feed_sep = "\n"
+
+ from changedetectionio import diff
+
+ snapshot_contents = ''
+ with open(watch_history[dates[-1]], 'rb') as f:
+ snapshot_contents = f.read()
+
+ n_object.update({
+ 'watch_url': watch['url'],
+ 'uuid': uuid,
+ 'current_snapshot': snapshot_contents.decode('utf-8'),
+ 'diff': diff.render_diff(watch_history[dates[-2]], watch_history[dates[-1]], line_feed_sep=line_feed_sep),
+ 'diff_full': diff.render_diff(watch_history[dates[-2]], watch_history[dates[-1]], True, line_feed_sep=line_feed_sep)
+ })
+
+ self.notification_q.put(n_object)
+
def send_filter_failure_notification(self, uuid):
threshold = self.datastore.data['settings']['application'].get('filter_failure_notification_threshold_attempts')
@@ -105,8 +162,10 @@ class update_worker(threading.Thread):
0)
print("Filter for {} not found, consecutive_filter_failures: {}".format(uuid, c))
if threshold > 0 and c >= threshold:
- self.send_filter_failure_notification(uuid)
+ if self.datastore.data['watching'][uuid].get('notification_muted'):
+ self.send_filter_failure_notification(uuid)
c = 0
+
self.datastore.update_watch(uuid=uuid, update_obj={'consecutive_filter_failures': c})
process_changedetection_results = True
@@ -143,66 +202,21 @@ class update_worker(threading.Thread):
# For the FIRST time we check a site, or a change detected, save the snapshot.
if changed_detected or not watch['last_checked']:
# A change was detected
- fname = watch.save_history_text(contents=contents, timestamp=str(round(time.time())))
+ watch.save_history_text(contents=contents, timestamp=str(round(time.time())))
self.datastore.update_watch(uuid=uuid, update_obj=update_obj)
# A change was detected
if changed_detected:
- n_object = {}
print (">> Change detected in UUID {} - {}".format(uuid, watch['url']))
# Notifications should only trigger on the second time (first time, we gather the initial snapshot)
if watch.history_n >= 2:
# Atleast 2, means there really was a change
self.datastore.update_watch(uuid=uuid, update_obj={'last_changed': round(now)})
+ if not self.datastore.data['watching'][uuid].get('notification_muted'):
+ self.send_content_changed_notification(self, uuid)
- watch_history = watch.history
- dates = list(watch_history.keys())
- # Theoretically it's possible that this could be just 1 long,
- # - In the case that the timestamp key was not unique
- if len(dates) == 1:
- raise ValueError(
- "History index had 2 or more, but only 1 date loaded, timestamps were not unique? maybe two of the same timestamps got written, needs more delay?"
- )
- prev_fname = watch_history[dates[-2]]
-
- # Did it have any notification alerts to hit?
- if len(watch['notification_urls']):
- print(">>> Notifications queued for UUID from watch {}".format(uuid))
- n_object['notification_urls'] = watch['notification_urls']
- n_object['notification_title'] = watch['notification_title']
- n_object['notification_body'] = watch['notification_body']
- n_object['notification_format'] = watch['notification_format']
-
- # No? maybe theres a global setting, queue them all
- elif len(self.datastore.data['settings']['application']['notification_urls']):
- print(">>> Watch notification URLs were empty, using GLOBAL notifications for UUID: {}".format(uuid))
- n_object['notification_urls'] = self.datastore.data['settings']['application']['notification_urls']
- n_object['notification_title'] = self.datastore.data['settings']['application']['notification_title']
- n_object['notification_body'] = self.datastore.data['settings']['application']['notification_body']
- n_object['notification_format'] = self.datastore.data['settings']['application']['notification_format']
- else:
- print(">>> NO notifications queued, watch and global notification URLs were empty.")
-
- # Only prepare to notify if the rules above matched
- if 'notification_urls' in n_object:
- # HTML needs linebreak, but MarkDown and Text can use a linefeed
- if n_object['notification_format'] == 'HTML':
- line_feed_sep = ""
- else:
- line_feed_sep = "\n"
-
- from changedetectionio import diff
- n_object.update({
- 'watch_url': watch['url'],
- 'uuid': uuid,
- 'current_snapshot': contents.decode('utf-8'),
- 'diff': diff.render_diff(prev_fname, fname, line_feed_sep=line_feed_sep),
- 'diff_full': diff.render_diff(prev_fname, fname, True, line_feed_sep=line_feed_sep)
- })
-
- self.notification_q.put(n_object)
except Exception as e:
# Catch everything possible here, so that if a worker crashes, we don't lose it until restart!
|