diff --git a/changedetectionio/__init__.py b/changedetectionio/__init__.py
index 21684fe9..1370e5e2 100644
--- a/changedetectionio/__init__.py
+++ b/changedetectionio/__init__.py
@@ -766,6 +766,16 @@ def changedetection_app(config=None, datastore_o=None):
return redirect(url_for('index'))
+ @app.route("/api/clone", methods=['GET'])
+ @login_required
+ def api_clone():
+
+ uuid = request.args.get('uuid')
+ datastore.clone(uuid)
+ flash('Cloned.')
+
+ return redirect(url_for('index'))
+
@app.route("/api/checknow", methods=['GET'])
@login_required
def api_watch_checknow():
diff --git a/changedetectionio/store.py b/changedetectionio/store.py
index 15861b58..8a28f6b6 100644
--- a/changedetectionio/store.py
+++ b/changedetectionio/store.py
@@ -242,6 +242,27 @@ class ChangeDetectionStore:
self.needs_write = True
+ # Clone a watch by UUID
+ def clone(self, uuid):
+ with self.lock:
+ new_uuid = str(uuid_builder.uuid4())
+ _clone = deepcopy(self.data['watching'][uuid])
+ _clone.update({'uuid': new_uuid})
+
+ attributes_to_reset = [
+ 'last_checked',
+ 'last_changed',
+ 'last_viewed',
+ 'newest_history_key',
+ 'previous_md5',
+ 'history'
+ ]
+ for attribute in attributes_to_reset:
+ _clone.update({attribute: self.generic_definition[attribute]})
+
+ self.data['watching'][new_uuid] = _clone
+ self.needs_write = True
+
def url_exists(self, url):
# Probably their should be dict...
diff --git a/changedetectionio/templates/edit.html b/changedetectionio/templates/edit.html
index 16233e83..cd55da0c 100644
--- a/changedetectionio/templates/edit.html
+++ b/changedetectionio/templates/edit.html
@@ -124,6 +124,8 @@ User-Agent: wonderbra 1.0") }}
Delete
+ Create Copy