From bef2e92cef64f4b8030558a7bfe4e21cc3d02ec8 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 30 Apr 2020 00:47:28 +0200 Subject: [PATCH] markdown-editor joke stopped being a joke... --- copyparty/broker_mpw.py | 2 +- copyparty/broker_thr.py | 2 +- copyparty/httpcli.py | 13 ++++-- copyparty/httpconn.py | 1 + copyparty/httpsrv.py | 10 +++-- copyparty/tcpsrv.py | 2 +- copyparty/web/md.html | 2 +- copyparty/web/md.js | 8 ++-- copyparty/web/mde.css | 75 ++++++++++++++++++++++++++++++++++ copyparty/web/mde.html | 29 +++++++++++++ copyparty/web/mde.js | 40 ++++++++++++++++++ scripts/deps-docker/Dockerfile | 33 +++++++++++++-- 12 files changed, 199 insertions(+), 18 deletions(-) create mode 100644 copyparty/web/mde.css create mode 100644 copyparty/web/mde.html create mode 100644 copyparty/web/mde.js diff --git a/copyparty/broker_mpw.py b/copyparty/broker_mpw.py index b4b540d8..815ca50a 100644 --- a/copyparty/broker_mpw.py +++ b/copyparty/broker_mpw.py @@ -73,7 +73,7 @@ class MpWorker(object): if PY2: sck = pickle.loads(sck) # nosec - self.log(str(addr), "-" * 4 + "C-qpop") + self.log("%s %s" % addr, "-" * 4 + "C-qpop") self.httpsrv.accept(sck, addr) with self.mutex: diff --git a/copyparty/broker_thr.py b/copyparty/broker_thr.py index 189aaffd..855387bf 100644 --- a/copyparty/broker_thr.py +++ b/copyparty/broker_thr.py @@ -28,7 +28,7 @@ class BrokerThr(object): def put(self, want_retval, dest, *args): if dest == "httpconn": sck, addr = args - self.log(str(addr), "-" * 4 + "C-qpop") + self.log("%s %s" % addr, "-" * 4 + "C-qpop") self.httpsrv.accept(sck, addr) else: diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index cf2d52f1..015d65e2 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -708,7 +708,14 @@ class HttpCli(object): def tx_md(self, fs_path): logmsg = "{:4} {} ".format("", self.req) - html_path = os.path.join(E.mod, "web/md.html") + if "edit" in self.uparam: + html_path = "web/mde.html" + template = self.conn.tpl_mde + else: + html_path = "web/md.html" + template = self.conn.tpl_md + + html_path = os.path.join(E.mod, html_path) st = os.stat(fsenc(fs_path)) sz_md = st.st_size @@ -726,7 +733,7 @@ class HttpCli(object): "title": html_escape(self.vpath, quote=False), "md": "", } - sz_html = len(self.conn.tpl_md.render(**targs).encode("utf-8")) + sz_html = len(template.render(**targs).encode("utf-8")) self.send_headers(sz_html + sz_md, status) logmsg += str(status) @@ -738,7 +745,7 @@ class HttpCli(object): md = f.read() targs["md"] = md.decode("utf-8", "replace") - html = self.conn.tpl_md.render(**targs).encode("utf-8") + html = template.render(**targs).encode("utf-8") try: self.s.sendall(html) except: diff --git a/copyparty/httpconn.py b/copyparty/httpconn.py index e1bda616..bca54b8f 100644 --- a/copyparty/httpconn.py +++ b/copyparty/httpconn.py @@ -36,6 +36,7 @@ class HttpConn(object): self.tpl_browser = env.get_template("browser.html") self.tpl_msg = env.get_template("msg.html") self.tpl_md = env.get_template("md.html") + self.tpl_mde = env.get_template("mde.html") def respath(self, res_name): return os.path.join(E.mod, "web", res_name) diff --git a/copyparty/httpsrv.py b/copyparty/httpsrv.py index eb36374d..7182a7b9 100644 --- a/copyparty/httpsrv.py +++ b/copyparty/httpsrv.py @@ -38,7 +38,7 @@ class HttpSrv(object): def accept(self, sck, addr): """takes an incoming tcp connection and creates a thread to handle it""" - self.log(str(addr), "-" * 5 + "C-cthr") + self.log("%s %s" % addr, "-" * 5 + "C-cthr") thr = threading.Thread(target=self.thr_client, args=(sck, addr)) thr.daemon = True thr.start() @@ -66,16 +66,18 @@ class HttpSrv(object): thr.start() try: - self.log(str(addr), "-" * 6 + "C-crun") + self.log("%s %s" % addr, "-" * 6 + "C-crun") cli.run() finally: - self.log(str(addr), "-" * 7 + "C-done") + self.log("%s %s" % addr, "-" * 7 + "C-done") try: sck.shutdown(socket.SHUT_RDWR) sck.close() except (OSError, socket.error) as ex: - self.log(str(addr), "shut_rdwr err:\n {}\n {}".format(repr(sck), ex)) + self.log( + "%s %s" % addr, "shut_rdwr err:\n {}\n {}".format(repr(sck), ex), + ) if ex.errno not in [10038, 107, 57, 9]: # 10038 No longer considered a socket # 107 Transport endpoint not connected diff --git a/copyparty/tcpsrv.py b/copyparty/tcpsrv.py index d346ea68..29e5f349 100644 --- a/copyparty/tcpsrv.py +++ b/copyparty/tcpsrv.py @@ -64,7 +64,7 @@ class TcpSrv(object): self.log("tcpsrv", "-" * 2 + "C-acc1") sck, addr = self.srv.accept() - self.log(str(addr), "-" * 3 + "C-acc2") + self.log("%s %s" % addr, "-" * 3 + "C-acc2") self.num_clients.add() self.hub.broker.put(False, "httpconn", sck, addr) diff --git a/copyparty/web/md.html b/copyparty/web/md.html index 9cbb39fa..d9fb97bf 100644 --- a/copyparty/web/md.html +++ b/copyparty/web/md.html @@ -11,7 +11,7 @@
dark - there will soon be more buttons on this row so it looks less dumb + edit
diff --git a/copyparty/web/md.js b/copyparty/web/md.js index 56e894dd..0c4ae026 100644 --- a/copyparty/web/md.js +++ b/copyparty/web/md.js @@ -14,15 +14,15 @@ var dom_md = document.getElementById('mt'); // add toolbar buttons (function () { var n = document.location + ''; - n = n.substr(n.indexOf('//') + 2).split('/'); + n = n.substr(n.indexOf('//') + 2).split('?')[0].split('/'); n[0] = 'top'; + var loc = []; var nav = []; - var url = '/'; for (var a = 0; a < n.length; a++) { if (a > 0) - url += n[a] + '/'; + loc.push(n[a]); - nav.push('' + n[a] + ''); + nav.push('' + n[a] + ''); } dom_nav.innerHTML = nav.join(''); })(); diff --git a/copyparty/web/mde.css b/copyparty/web/mde.css new file mode 100644 index 00000000..c69c24af --- /dev/null +++ b/copyparty/web/mde.css @@ -0,0 +1,75 @@ +/* fontawesome is 2big */ +.fa { font-size: 1.5em; line-height: 1em; margin: -3em; position: relative; left: -.05em; font-style: normal } +.fa-bold:before { content: 'B'; font-weight: bold } +.fa-italic:before { content: 'I'; font-style: italic } +.fa-strikethrough:before { content: ' S '; text-decoration: line-through } +.fa-header:before { content: 'H'; font-weight: bold; font-family: serif; top: -.2em; left: .5em } +.fa-quote-left:before { content: '❝'; font-family: serif; top: -.5em } +.fa-list-ul:before { content: '•' } +.fa-list-ol:before { content: '①' } +.fa-link:before { content: '🔗'; font-size: .8em } +.fa-image:before { content: '🎨' } +.fa-eye:before { content: '👀'; font-size: .9em } +.fa-columns:before { content: '◫' } +.fa-arrows-alt:before { content: '⛶' } +.fa-undo:before { content: '⟲' } +.fa-redo:before { content: '⟳' } +.fa-question-circle:before { content: '?' } +.fa-code:before { content: '‹/›'; font-size: .8em; } +.fa-eraser:before { content: '⁋' } +.fa-table:before { content: '⊞' } +.fa-minus:before { content: '−' } + +/* +https://dev.w3.org/html5/html-author/charref +http://xahlee.info/comp/unicode_arrows.html +https://www.fileformat.info/info/unicode/block/miscellaneous_symbols_and_pictographs/list.htm +↶ ↷ 💾 🗙 +*/ + +button { border: 1px solid #999 !important; } + +html, body { + margin: 0; + padding: 0; + min-height: 100%; + font-family: sans-serif; +} +#mn { + font-weight: normal; + margin: 1.3em 0 .7em 1em; + font-size: 1.4em; +} +#mn a { + color: #444; + margin: 0 0 0 -.2em; + padding: 0 0 0 .4em; + text-decoration: none; +} +#mn a:first-child { + padding-left: .5em; +} +#mn a:last-child { + padding-right: .5em; +} +#mn a:not(:last-child):after { + content: ''; + width: 1.05em; + height: 1.05em; + margin: -.2em .3em -.2em -.4em; + display: inline-block; + border: 1px solid rgba(0,0,0,0.3); + border-width: .05em .05em 0 0; + transform: rotate(45deg); +} +#mn a:hover { + color: #000; + text-decoration: underline; +} + +*[data-ln]:before { + content: attr(data-ln); + font-size: .8em; + margin: 0 .4em; + color: #f0c; +} diff --git a/copyparty/web/mde.html b/copyparty/web/mde.html new file mode 100644 index 00000000..93c01647 --- /dev/null +++ b/copyparty/web/mde.html @@ -0,0 +1,29 @@ + + + 📝🎉 {{ title }} + + + + + + +
+
+
+
+
Loading
+ if you're still reading this, check that javascript is allowed +
+
+
+ +
+
+ + + + diff --git a/copyparty/web/mde.js b/copyparty/web/mde.js new file mode 100644 index 00000000..5a0a108c --- /dev/null +++ b/copyparty/web/mde.js @@ -0,0 +1,40 @@ +var dom_wrap = document.getElementById('mw'); +var dom_nav = document.getElementById('mn'); +var dom_doc = document.getElementById('m'); +var dom_md = document.getElementById('mt'); + +(function () { + var n = document.location + ''; + n = n.substr(n.indexOf('//') + 2).split('?')[0].split('/'); + n[0] = 'top'; + var loc = []; + var nav = []; + for (var a = 0; a < n.length; a++) { + if (a > 0) + loc.push(n[a]); + + nav.push('' + n[a] + ''); + } + dom_nav.innerHTML = nav.join(''); +})(); + +(function () { + var mde = new EasyMDE({ + autoDownloadFontAwesome: false, + autofocus: true, + insertTexts: ["[](", ")"], + renderingConfig: { + markedOptions: { + breaks: true, + gfm: true + } + }, + spellChecker: false, + tabSize: 4, + showIcons: ['strikethrough', 'code', 'table', 'undo', 'redo', 'heading', 'clean-block', 'horizontal-rule'] + }); + var loader = document.getElementById('ml'); + loader.parentNode.removeChild(loader); +})(); + +zsetTimeout(function () { window.location.reload(true); }, 1000); diff --git a/scripts/deps-docker/Dockerfile b/scripts/deps-docker/Dockerfile index 571156f7..020b67ba 100644 --- a/scripts/deps-docker/Dockerfile +++ b/scripts/deps-docker/Dockerfile @@ -4,7 +4,8 @@ ENV ver_asmcrypto=2821dd1dedd1196c378f5854037dda5c869313f3 \ ver_markdownit=10.0.0 \ ver_showdown=1.9.1 \ ver_marked=1.0.0 \ - ver_ogvjs=1.6.1 + ver_ogvjs=1.6.1 \ + ver_mde=2.10.1 # download @@ -12,6 +13,7 @@ RUN apk add make g++ git bash npm patch wget tar pigz brotli gzip unzip \ && wget https://github.com/brion/ogv.js/releases/download/$ver_ogvjs/ogvjs-$ver_ogvjs.zip -O ogvjs.zip \ && wget https://github.com/asmcrypto/asmcrypto.js/archive/$ver_asmcrypto.tar.gz -O asmcrypto.tgz \ && wget https://github.com/markedjs/marked/archive/v$ver_marked.tar.gz -O marked.tgz \ + && wget https://github.com/Ionaru/easy-markdown-editor/archive/$ver_mde.tar.gz -O mde.tgz \ && unzip ogvjs.zip \ && (tar -xf asmcrypto.tgz \ && cd asmcrypto.js-$ver_asmcrypto \ @@ -20,7 +22,13 @@ RUN apk add make g++ git bash npm patch wget tar pigz brotli gzip unzip \ && cd marked-$ver_marked \ && npm install \ && npm i grunt uglify-js -g ) \ + && (tar -xf mde.tgz \ + && cd easy-markdown-editor* \ + && npm install \ + && npm i gulp-cli -g ) \ && mkdir /z/dist +# && wget https://github.com/FortAwesome/Font-Awesome/releases/download/5.0.11/fontawesome-free-5.0.11.zip -O fontawesome.zip \ +# && unzip fontawesome.zip \ # uncomment if you wanna test the abandoned markdown converters @@ -74,10 +82,26 @@ RUN cd marked-$ver_marked \ && patch -p1 < /z/marked.patch \ && npm run build \ && cp -pv marked.min.js /z/dist/marked.js \ - && cp -pv lib/marked.js /z/dist/marked.full.js + && cp -pv lib/marked.js /z/dist/marked.full.js \ + && mkdir -p /z/nodepkgs \ + && ln -s $(pwd) /z/nodepkgs/marked # && npm run test \ +# build easymde (TODO man this thing is big) +RUN cd easy-markdown-editor-$ver_mde \ + && sed -ri 's`https://registry.npmjs.org/marked/-/marked-0.8.2.tgz`file:/z/nodepkgs/marked`' package-lock.json \ + && sed -ri 's`("marked": ")[^"]+`\1file:/z/nodepkgs/marked`' ./package.json \ + && npm install \ + && gulp \ + && cp -pv dist/easymde.min.css /z/dist/easymde.css \ + && cp -pv dist/easymde.min.js /z/dist/easymde.js \ + && sed -ri '/pipe.terser/d; /cleanCSS/d' gulpfile.js \ + && gulp \ + && cp -pv dist/easymde.min.css /z/dist/easymde.full.css \ + && cp -pv dist/easymde.min.js /z/dist/easymde.full.js + + # build showdown (abandoned; disabled by default) COPY showdown.patch /z/ RUN [ $build_abandoned ] || exit 0; \ @@ -126,6 +150,9 @@ COPY zopfli.makefile /z/dist/Makefile RUN cd /z/dist \ && make -j$(nproc) \ && rm Makefile +# && cp -pv "$(find /z/fontawesome-fre* -name fa-regular-400.woff | head -n 1)" fontawesome.woff +# && cp -pv "$(find /z/fontawesome-fre* -name fontawesome.min.css | head -n 1)" fontawesome.css \ +# && sed -ri 's`@font-face.*``' fontawesome.css \ # showdown: abandoned due to code-blocks in lists failing @@ -156,5 +183,5 @@ RUN cd /z/dist \ # f=../../copyparty/web/deps/marked.js.gz; (cd ~ed/src/ && diff -NarU1 marked-1.0.0-orig/ marked-1.0.0-edit/) >marked.patch; make && printf '%d ' $(wc -c <$f) $(gzip -d <$f | wc -c); echo -# d=/home/ed/dev/copyparty/scripts/deps-docker/; scp Dockerfile marked-ln.patch root@$bip:$d && ssh root@$bip "cd $d && make" && ssh root@$bip 'tar -cC /home/ed/dev/copyparty/copyparty/web deps' | (cd ../../copyparty/web/; cat > the.tgz; tar -xvf the.tgz) +# d=/home/ed/dev/copyparty/scripts/deps-docker/; tar -cf ../x . && ssh root@$bip "cd $d && tar -xv >&2 && make >&2 && tar -cC ../../copyparty/web deps" <../x | (cd ../../copyparty/web/; cat > the.tgz; tar -xvf the.tgz) # gzip -dkf ../dev/copyparty/copyparty/web/deps/deps/marked.full.js.gz && diff -NarU2 ../dev/copyparty/copyparty/web/deps/{,deps/}marked.full.js