verify markdown saves with a full roundtrip

This commit is contained in:
ed 2020-05-03 20:57:52 +02:00
parent da1094db84
commit 6e43ee7cc7
4 changed files with 69 additions and 8 deletions

View file

@ -8,7 +8,6 @@ import time
import json
from datetime import datetime
import calendar
import mimetypes
from .__init__ import E, PY2, WINDOWS
from .util import * # noqa # pylint: disable=unused-wildcard-import
@ -526,7 +525,7 @@ class HttpCli(object):
except Pebkac as ex:
errmsg = str(ex)
td = time.time() - t0
td = max(0.1, time.time() - t0)
sz_total = sum(x[0] for x in files)
spd = (sz_total / td) / (1024 * 1024)
@ -665,6 +664,7 @@ class HttpCli(object):
return file_lastmod, int(file_ts) > int(cli_ts)
except:
self.log("bad lastmod format: {}".format(cli_lastmod))
self.log(" expected format: {}".format(file_lastmod))
return file_lastmod, file_lastmod != cli_lastmod
return file_lastmod, True
@ -789,7 +789,7 @@ class HttpCli(object):
self.send_headers(
length=upper - lower,
status=status,
mime=mimetypes.guess_type(req_path)[0] or "application/octet-stream",
mime=guess_mime(req_path)[0] or "application/octet-stream",
)
logmsg += str(status) + logtail

View file

@ -8,6 +8,7 @@ import struct
import hashlib
import platform
import threading
import mimetypes
import subprocess as sp # nosec
from .__init__ import PY2, WINDOWS
@ -474,6 +475,13 @@ def unescape_cookie(orig):
return ret
def guess_mime(url):
if url.endswith(".md"):
return ["text/plain; charset=UTF-8"]
return mimetypes.guess_type(url)
def runcmd(*argv):
p = sp.Popen(argv, stdout=sp.PIPE, stderr=sp.PIPE)
stdout, stderr = p.communicate()

View file

@ -47,6 +47,9 @@ var dom_md = document.getElementById('mt');
gfm: true
}
},
shortcuts: {
"save": "Ctrl-S"
},
insertTexts: ["[](", ")"],
tabSize: 4,
toolbar: tbar,
@ -85,10 +88,12 @@ function save(mde) {
return;
}
var txt = mde.value();
var fd = new FormData();
fd.append("act", "tput");
fd.append("lastmod", (force ? -1 : last_modified));
fd.append("body", mde.value());
fd.append("body", txt);
var url = (document.location + '').split('?')[0] + '?raw';
var xhr = new XMLHttpRequest();
@ -97,6 +102,7 @@ function save(mde) {
xhr.onreadystatechange = save_cb;
xhr.btn = save_btn;
xhr.mde = mde;
xhr.txt = txt;
xhr.send(fd);
}
@ -138,8 +144,55 @@ function save_cb() {
return;
}
last_modified = r.lastmod;
this.btn.classList.remove('force-save');
alert('save OK -- wrote ' + r.size + ' bytes.\n\nsha512: ' + r.sha512);
md_changed(this.mde, true);
//alert('save OK -- wrote ' + r.size + ' bytes.\n\nsha512: ' + r.sha512);
// download the saved doc from the server and compare
var url = (document.location + '').split('?')[0] + '?raw';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'text';
xhr.onreadystatechange = save_chk;
xhr.btn = this.save_btn;
xhr.mde = this.mde;
xhr.txt = this.txt;
xhr.lastmod = r.lastmod;
xhr.send();
}
function save_chk() {
if (this.readyState != XMLHttpRequest.DONE)
return;
if (this.status !== 200) {
alert('Error! The file was NOT saved.\n\n' + this.status + ": " + (this.responseText + '').replace(/^<pre>/, ""));
return;
}
var doc1 = this.txt.replace(/\r/g, "");
var doc2 = this.responseText.replace(/\r/g, "");
if (doc1 != doc2) {
alert(
'Error! The document on the server does not appear to have saved correctly (your editor contents and the server copy is not identical). Place the document on your clipboard for now and check the server logs for hints\n\n' +
'Length: yours=' + doc1.length + ', server=' + doc2.length
);
alert('yours, ' + doc1.length + ' byte:\n[' + doc1 + ']');
alert('server, ' + doc2.length + ' byte:\n[' + doc2 + ']');
return;
}
last_modified = this.lastmod;
md_changed(this.mde, true);
var ok = document.createElement('div');
ok.setAttribute('style', 'font-size:6em;font-family:serif;font-weight:bold;color:#cf6;background:#444;border-radius:.3em;padding:.6em 0;position:fixed;top:30%;left:calc(50% - 2em);width:4em;text-align:center;z-index:9001;transition:opacity 0.2s ease-in-out;opacity:1');
ok.innerHTML = 'OK✔';
var parent = document.getElementById('m');
document.documentElement.appendChild(ok);
setTimeout(function () {
ok.style.opacity = 0;
}, 500);
setTimeout(function () {
ok.parentNode.removeChild(ok);
}, 750);
}

View file

@ -22,7 +22,7 @@
</form>
</div>
<div id="op_new_md" class="opview opbox act">
<div id="op_new_md" class="opview opbox">
<form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="/{{ vdir }}">
<input type="hidden" name="act" value="new_md" />
<input type="text" name="name" size="30">