mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-12-12 02:55:43 +00:00
Add [diff] mechanism
This commit is contained in:
@@ -10,7 +10,9 @@
|
||||
# @todo on change detected, config for calling some API
|
||||
# @todo make tables responsive!
|
||||
# @todo fetch title into json
|
||||
|
||||
# https://distill.io/features
|
||||
# proxy per check
|
||||
#i
|
||||
import json
|
||||
import eventlet
|
||||
import eventlet.wsgi
|
||||
@@ -34,6 +36,7 @@ ticker_thread = None
|
||||
|
||||
datastore = store.ChangeDetectionStore()
|
||||
messages = []
|
||||
extra_stylesheets = []
|
||||
running_update_threads = {}
|
||||
|
||||
app = Flask(__name__, static_url_path='/static')
|
||||
@@ -149,6 +152,31 @@ def import_page():
|
||||
return output
|
||||
|
||||
|
||||
@app.route("/diff/<string:uuid>", methods=['GET'])
|
||||
def diff_history_page(uuid):
|
||||
global messages
|
||||
global extra_stylesheets
|
||||
extra_stylesheets.append('/static/css/diff.css')
|
||||
|
||||
watch = datastore.data['watching'][uuid]
|
||||
|
||||
dates = list(watch['history'].keys())
|
||||
dates = [int(i) for i in dates]
|
||||
dates.sort(reverse=True)
|
||||
|
||||
left_file_contents = right_file_contents = ""
|
||||
l_file = watch['history'][str(dates[-1])]
|
||||
with open(l_file, 'r') as f:
|
||||
left_file_contents = f.read()
|
||||
|
||||
r_file = watch['history'][str(dates[-2])]
|
||||
with open(r_file, 'r') as f:
|
||||
right_file_contents = f.read()
|
||||
|
||||
output = render_template("diff.html", watch_a=watch, messages=messages, left=left_file_contents,
|
||||
right=right_file_contents, extra_stylesheets=extra_stylesheets)
|
||||
return output
|
||||
|
||||
@app.route("/favicon.ico", methods=['GET'])
|
||||
def favicon():
|
||||
return send_from_directory("/app/static/images", filename="favicon.ico")
|
||||
|
||||
@@ -127,7 +127,7 @@ class perform_site_check(Thread):
|
||||
# attempt because 'self.current_md5 != fetched_md5' (current_md5 will be None when not run)
|
||||
# need to learn more about attr/setters/getters
|
||||
history = self.datastore.get_val(self.uuid, 'history')
|
||||
history.update(dict([(self.timestamp, output_filepath)]))
|
||||
history.update(dict([(str(self.timestamp), output_filepath)]))
|
||||
self.datastore.update_watch(self.uuid, 'history', history)
|
||||
|
||||
self.datastore.update_watch(self.uuid, 'last_checked', int(time.time()))
|
||||
|
||||
61
backend/static/css/diff.css
Normal file
61
backend/static/css/diff.css
Normal file
@@ -0,0 +1,61 @@
|
||||
table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
td {
|
||||
width: 33%;
|
||||
padding: 3px 4px;
|
||||
border: 1px solid transparent;
|
||||
vertical-align: top;
|
||||
font: 1em monospace;
|
||||
text-align: left;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
h1 {
|
||||
display: inline;
|
||||
font-size: 100%;
|
||||
}
|
||||
del {
|
||||
text-decoration: none;
|
||||
color: #b30000;
|
||||
background: #fadad7;
|
||||
}
|
||||
|
||||
ins {
|
||||
background: #eaf2c2;
|
||||
color: #406619;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#result {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#settings {
|
||||
|
||||
|
||||
line-height: 2em;
|
||||
}
|
||||
#settings label {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.source {
|
||||
position: absolute;
|
||||
right: 1%;
|
||||
top: .2em;
|
||||
}
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
body {
|
||||
height: 99%; /* Hide scroll bar in Firefox */
|
||||
}
|
||||
}
|
||||
|
||||
#diff-ui {
|
||||
background: #fff;
|
||||
padding: 2em;
|
||||
margin: 1em;
|
||||
border-radius: 5px;
|
||||
font-size: 9px;
|
||||
}
|
||||
@@ -48,6 +48,7 @@ section.content {
|
||||
}
|
||||
.watch-tag-list {
|
||||
color: #e70069;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.box {
|
||||
|
||||
1055
backend/static/js/diff.js
Normal file
1055
backend/static/js/diff.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ class ChangeDetectionStore:
|
||||
self.needs_write = False
|
||||
|
||||
self.__data = {
|
||||
'note' : "Hello! If you change this file manually, please be sure to restart your changedetection.io instance!",
|
||||
'watching': {},
|
||||
'settings': {
|
||||
'headers': {
|
||||
@@ -126,7 +127,6 @@ class ChangeDetectionStore:
|
||||
|
||||
|
||||
def sync_to_json(self):
|
||||
print ("Saving index....")
|
||||
with open('/datastore/url-watches.json', 'w') as json_file:
|
||||
json.dump(self.data, json_file, indent=4)
|
||||
self.needs_write = False
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
<title>Change Detection</title>
|
||||
<link rel="stylesheet" href="/static/css/pure-min.css">
|
||||
<link rel="stylesheet" href="/static/css/styles.css">
|
||||
{% if extra_stylesheets %}
|
||||
{% for m in extra_stylesheets %}
|
||||
<link rel="stylesheet" href="{{ m }}">
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
98
backend/templates/diff.html
Normal file
98
backend/templates/diff.html
Normal file
@@ -0,0 +1,98 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="diff-ui">
|
||||
<del>Removed text</del>
|
||||
<ins>Inserted Text</ins>
|
||||
|
||||
<div id="settings">
|
||||
<h3>Diff</h3>
|
||||
<label><input type="radio" name="diff_type" value="diffChars"> Chars</label>
|
||||
<label><input type="radio" name="diff_type" value="diffWords" > Words</label>
|
||||
<label><input type="radio" name="diff_type" value="diffLines" checked=""> Lines</label>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<!-- just proof of concept copied straight from github.com/kpdecker/jsdiff -->
|
||||
<td id="a" style="display: none;">{{left}}</td>
|
||||
<td id="b" style="display: none;">{{right}}</td>
|
||||
<td>
|
||||
<pre id="result"></pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
Diff algorithm from the amazing <a href="https://github.com/kpdecker/jsdiff" >github.com/kpdecker/jsdiff</a>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/diff.js"></script>
|
||||
<script defer="">
|
||||
var a = document.getElementById('a');
|
||||
var b = document.getElementById('b');
|
||||
var result = document.getElementById('result');
|
||||
|
||||
function changed() {
|
||||
var diff = JsDiff[window.diffType](a.textContent, b.textContent);
|
||||
var fragment = document.createDocumentFragment();
|
||||
for (var i=0; i < diff.length; i++) {
|
||||
|
||||
if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
|
||||
var swap = diff[i];
|
||||
diff[i] = diff[i + 1];
|
||||
diff[i + 1] = swap;
|
||||
}
|
||||
|
||||
var node;
|
||||
if (diff[i].removed) {
|
||||
node = document.createElement('del');
|
||||
node.appendChild(document.createTextNode(diff[i].value));
|
||||
} else if (diff[i].added) {
|
||||
node = document.createElement('ins');
|
||||
node.appendChild(document.createTextNode(diff[i].value));
|
||||
} else {
|
||||
node = document.createTextNode(diff[i].value);
|
||||
}
|
||||
fragment.appendChild(node);
|
||||
}
|
||||
|
||||
result.textContent = '';
|
||||
result.appendChild(fragment);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
onDiffTypeChange(document.querySelector('#settings [name="diff_type"]:checked'));
|
||||
changed();
|
||||
};
|
||||
|
||||
a.onpaste = a.onchange =
|
||||
b.onpaste = b.onchange = changed;
|
||||
|
||||
if ('oninput' in a) {
|
||||
a.oninput = b.oninput = changed;
|
||||
} else {
|
||||
a.onkeyup = b.onkeyup = changed;
|
||||
}
|
||||
|
||||
function onDiffTypeChange(radio) {
|
||||
window.diffType = radio.value;
|
||||
document.title = "Diff " + radio.value.slice(4);
|
||||
}
|
||||
|
||||
var radio = document.getElementsByName('diff_type');
|
||||
for (var i = 0; i < radio.length; i++) {
|
||||
radio[i].onchange = function(e) {
|
||||
onDiffTypeChange(e.target);
|
||||
changed();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -26,6 +26,7 @@
|
||||
</div>
|
||||
|
||||
<div id="watch-table-wrapper">
|
||||
|
||||
<table class="pure-table pure-table-striped watch-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -56,6 +57,9 @@
|
||||
<td>{{watch.last_changed|format_timestamp_timeago}}</td>
|
||||
<td><a href="/api/checknow?uuid={{ watch.uuid}}" class="pure-button button-small pure-button-primary">Recheck</a>
|
||||
<a href="/edit?uuid={{ watch.uuid}}" class="pure-button button-small pure-button-primary">Edit</a>
|
||||
{% if watch.history|length >= 2 %}
|
||||
<a href="/diff/{{ watch.uuid}}" class="pure-button button-small pure-button-primary">Diff</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user