diff options
-rw-r--r-- | config/Makefile | 9 | ||||
-rw-r--r-- | config/hex-zero.conf.example | 8 | ||||
-rw-r--r-- | dd-upload.html.in | 31 | ||||
-rw-r--r-- | debian/README.Debian | 2 | ||||
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | debian/copyright | 10 | ||||
-rw-r--r-- | debian/hex-zero.dsc | 14 | ||||
-rw-r--r-- | front.html.in | 5 | ||||
-rwxr-xr-x | hex_zero.py | 28 | ||||
-rw-r--r-- | static/dd-upload.css | 17 | ||||
-rw-r--r-- | static/dd-upload.js | 103 | ||||
-rw-r--r-- | static/styles.css | 2 |
12 files changed, 217 insertions, 18 deletions
diff --git a/config/Makefile b/config/Makefile index b99dac7..686fb0a 100644 --- a/config/Makefile +++ b/config/Makefile @@ -16,7 +16,7 @@ APPNAME = hex-zero APPNAME_ = hex_zero -APPVERSION = 0.0.1 +APPVERSION = 0.0.2 SRCDIR = $(CURDIR)/..# because Makefile is in config/ inside this repo prefix = /usr SYSCONFDIR = $(DESTDIR)/etc @@ -82,8 +82,8 @@ deplist_opts: install_files: ${installbin} -m0755 -d ${LOGDIR} ${APPDIR}/up ${APPDIR}/static ${DOCDIR} ${DEFAULTDIR} - ${installbin} -m0644 -t ${APPDIR} ${SRCDIR}/front.html.in - ${installbin} -m0644 -t ${APPDIR}/static ${SRCDIR}/static/styles.css + ${installbin} -m0644 -t ${APPDIR} ${SRCDIR}/*.html.in + ${installbin} -m0644 -t ${APPDIR}/static ${SRCDIR}/static/* ${installbin} -m0644 ${SRCDIR}/config/${APPNAME}.conf.example ${APPDIR}/${APPNAME}.conf ${installbin} -m0755 -t ${APPDIR} ${SRCDIR}/${APPNAME_}.py ${SRCDIR}/${APPNAME}.wsgi \ ${SRCDIR}/check-for-short_url.sh @@ -121,7 +121,8 @@ uninstall: @${echobin} SRCDIR=${SRCDIR} ${rmbin} -f ${APPDIR}/${APPNAME}.conf ${APPDIR}/${APPNAME_}.py ${APPDIR}/${APPNAME}.wsgi \ ${APPDIR}/check-for-short_url.sh \ - ${APPDIR}/front.html.in ${DOCDIR}/* ${DEFAULTDIR}/${APPNAME} \ + ${APPDIR}/front.html.in ${APPDIR}/dd-upload.html.in \ + ${DOCDIR}/* ${DEFAULTDIR}/${APPNAME} \ ${APPDIR}/migrations/versions/* ${APPDIR}/migrations/* \ ${APPDIR}/static/* \ 1>/dev/null 2>&1 || : diff --git a/config/hex-zero.conf.example b/config/hex-zero.conf.example index 3b62410..9b5d165 100644 --- a/config/hex-zero.conf.example +++ b/config/hex-zero.conf.example @@ -26,11 +26,13 @@ FHOST_MIME_BLACKLIST = [ ] # template for front page of app -FHOST_FRONTPAGE = "/var/www/hex-zero/front.html.in" +FRONTPAGE = "/var/www/hex-zero/front.html.in" +DRAG_AND_DROP_PAGE = "/var/www/hex-zero/dd-upload.html.in" -ADMIN_EMAIL = "root@d2-03a" +ADMIN_EMAIL = "webmaster@example.com" # with this, as well as use this for printing the base url of the app -APP_URL = "http://d2-03a/hex-zero" +APP_URL = "https://upload.example.com/hex-zero" +APP_PATH = "/hex-zero" # use the forwarded IP address header instead of the requester IP address USE_HTTP_X_FORWARDED_FOR = True # If you want to expose this app directly on 0.0.0.0 that is dangerous, but up to you. diff --git a/dd-upload.html.in b/dd-upload.html.in new file mode 100644 index 0000000..e84c3d2 --- /dev/null +++ b/dd-upload.html.in @@ -0,0 +1,31 @@ +<!DOCTYPE html>
+<!--
+ Author: W.S. Toh
+ SPDX-License-Identifier: MIT
+ -->
+<html>
+ <head>
+ <title>
+ Drag-and-drop Upload Demo
+ </title>
+
+ <!-- (A) CSS + JS -->
+ <link rel="stylesheet" href="{0}/static/dd-upload.css"/>
+ <script src="{0}/static/dd-upload.js"></script>
+ </head>
+ <body>
+ <!-- (B) FILE DROP ZONE -->
+ <div id="upzone">
+ Drop Files Here
+ </div>
+
+ <!-- (C) UPLOAD STATUS -->
+ <div id="upstat"></div>
+
+ <!-- (D) FALLBACK -->
+ <form id="upform" action="{0}" method="post" enctype="multipart/form-data">
+ <input type="file" name="file" accept="*" required>
+ <input type="submit" value="Upload File">
+ </form>
+ </body>
+</html>
diff --git a/debian/README.Debian b/debian/README.Debian index e2bbc21..3636821 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -7,4 +7,6 @@ At initial install, you will need to manually install short_url with pip. The dp sudo su hex-zero -c 'pip3 install --user short_url' sudo dpkg-reconfigure hex-zero +This project combines the above 0x0 from envs.sh as well as https://code-boxx.com/simple-drag-and-drop-file-upload/ for the drag-and-drop upload form. + -- B. Stack <bgstack15@gmail.com> Thu, 10 Dec 2020 08:10:02 -0500 diff --git a/debian/changelog b/debian/changelog index aeec6c0..ab384ca 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +hex-zero (0.0.2-1) obs; urgency=low + + * Add drag-and-drop route at /hex-zero/upload/ using javascript + + -- B. Stack <bgstack15@gmail.com> Fri, 18 Dec 2020 19:21:50 -0500 + hex-zero (0.0.1-1) obs; urgency=low * Initial release. Closes: packages-want#000 diff --git a/debian/copyright b/debian/copyright index 343411d..dd793b4 100644 --- a/debian/copyright +++ b/debian/copyright @@ -12,6 +12,7 @@ Files: .gitignore config/hex-zero.conf.apache config/hex-zero.conf.example config/hex-zero.etc.default + config/hex-zero.init hex-zero.wsgi Copyright: B. Stack <bgstack15@gmail.com> License: CC-BY-SA 4.0 @@ -48,9 +49,12 @@ License: EUPL 1.2 See the License for the specific language governing permissions and limitations under the License. -Files: config/hex-zero.init -Copyright: B. Stack <bgstack15@gmail.com> -License: CC-BY-SA 4.0 +Files: dd-upload.html.in + static/dd-upload.css + static/dd-upload.js +Copyright: 2020 W.S. Toh +License: MIT +Comment: From public demo at https://code-boxx.com/simple-drag-and-drop-file-upload/ Files: nsfw_model/LICENSE.md Copyright: 2016 Yahoo Inc. diff --git a/debian/hex-zero.dsc b/debian/hex-zero.dsc new file mode 100644 index 0000000..b495fe9 --- /dev/null +++ b/debian/hex-zero.dsc @@ -0,0 +1,14 @@ +Format: 3.0 (quilt) +Source: hex-zero +Binary: hex-zero +Architecture: all +Version: 0.0.2-1 +Maintainer: B. Stack <bgstack15@gmail.com> +Homepage: https://gitlab.com/bgstack15/hex-zero +Standards-Version: 4.5.0 +Build-Depends: debhelper-compat (= 12) +Package-List: + hex-zero deb web optional arch=all +Files: + 00000000000000000000000000000000 1 hex-zero.orig.tar.gz + 00000000000000000000000000000000 1 hex-zero.debian.tar.xz diff --git a/front.html.in b/front.html.in index 705633a..d5c69ca 100644 --- a/front.html.in +++ b/front.html.in @@ -10,13 +10,14 @@ 6) {6} 7) {7} 8) {8} + 9) {9} APP_PATH --> <html lang="en"> <head> <title>{6}</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="description" content="Hex Zero" /> - <link rel="stylesheet" href="/hex-zero/static/styles.css"> + <link rel="stylesheet" href="{9}/static/styles.css"> </head> <body id="body"> <div id="sidebar"> @@ -127,7 +128,7 @@ please allow up to 24 hours for a response. <!-- UPLOAD --> <footer> <div id="footer"> - <pre class="clean">Adapted from <a href="https://github.com/envs-net/0x0">envs.net 0x0 app</a> + <pre class="clean">Drag-and-drop form <a href="{9}/upload/">here</a> </div> </footer> <!-- diff --git a/hex_zero.py b/hex_zero.py index 1f3c2ab..bcd8bb3 100755 --- a/hex_zero.py +++ b/hex_zero.py @@ -79,9 +79,12 @@ app.config.from_pyfile("hex-zero.conf", silent=True) dictConfig(app.config['WSGI_LOGGING']) # read html template file -with open(app.config["FHOST_FRONTPAGE"], "r") as j: +with open(app.config["FRONTPAGE"], "r") as j: frontpagestring = j.read() +with open(app.config["DRAG_AND_DROP_PAGE"], "r") as j: + ddpagestring = j.read() + if app.config["NSFW_DETECT"]: from nsfw_detect import NSFWDetector nsfw = NSFWDetector() @@ -376,6 +379,12 @@ def dump_urls(start=0): return Response(gen(), mimetype="text/plain") +@app.route("/upload/") +def dd_upload(): + return ddpagestring.format( + app.config["APP_PATH"] + ) + @app.route("/", methods=["GET", "POST"]) def fhost(): if request.method == "POST": @@ -415,11 +424,18 @@ def fhost(): maxsizehalf = int(maxsizehalf) # python-interpreted variables - return frontpagestring.format(fhost_url(), - maxsize, str(maxsizehalf).rjust(27), str(maxsizenum).rjust(27), - maxsizeunit.rjust(54), - ", ".join(app.config["FHOST_MIME_BLACKLIST"]),fhost_url().split("/",2)[2], - app.config["APP_URL"], app.config["ADMIN_EMAIL"]) + return frontpagestring.format( + fhost_url(), + maxsize, + str(maxsizehalf).rjust(27), + str(maxsizenum).rjust(27), + maxsizeunit.rjust(54), + ", ".join(app.config["FHOST_MIME_BLACKLIST"]), + fhost_url().split("/",2)[2], + app.config["APP_URL"], + app.config["ADMIN_EMAIL"], + app.config["APP_PATH"] + ) @app.route("/robots.txt") def robots(): diff --git a/static/dd-upload.css b/static/dd-upload.css new file mode 100644 index 0000000..39586eb --- /dev/null +++ b/static/dd-upload.css @@ -0,0 +1,17 @@ +/* (A) UPLOAD ZONE */
+/* Author: W.S. Toh */
+/* SPDX-License-Identifier: MIT */
+#upzone {
+ width: 300px;
+ height: 200px;
+ background: #cfd5ff;
+ padding: 10px;
+}
+#upzone.highlight {
+ background: #ff0;
+}
+
+/* (B) UPLOAD FORM */
+#upform {
+ display: none;
+}
diff --git a/static/dd-upload.js b/static/dd-upload.js new file mode 100644 index 0000000..51df214 --- /dev/null +++ b/static/dd-upload.js @@ -0,0 +1,103 @@ +/* Author: W.S. Toh */
+/* SPDX-License-Identifier: MIT */
+var ddup = {
+ // (A) ON PAGE LOAD
+ hzone: null, // HTML upload zone
+ hstat: null, // HTML upload status
+ hform: null, // HTML upload form
+ init : function () {
+ // (A1) GET HTML ELEMENTS
+ ddup.hzone = document.getElementById("upzone");
+ ddup.hstat = document.getElementById("upstat");
+ ddup.hform = document.getElementById("upform");
+
+ // (A2) DRAG-DROP SUPPORTED
+ if (window.File && window.FileReader && window.FileList && window.Blob) {
+ // HIGHLIGHT DROPZONE ON FILE HOVER
+ ddup.hzone.addEventListener("dragenter", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ ddup.hzone.classList.add('highlight');
+ });
+ ddup.hzone.addEventListener("dragleave", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ ddup.hzone.classList.remove('highlight');
+ });
+
+ // DROP TO UPLOAD FILE
+ ddup.hzone.addEventListener("dragover", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ });
+ ddup.hzone.addEventListener("drop", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ ddup.hzone.classList.remove('highlight');
+ ddup.queue(e.dataTransfer.files);
+ });
+ }
+
+ // (A3) DRAG-DROP UPLOAD NOT SUPPORTED
+ else {
+ ddup.hzone.style.display = "none";
+ ddup.hform.style.display = "block";
+ }
+ },
+
+ // (B) UPLOAD QUEUE + HANDLER
+ // NOTE: AJAX IS ASYNCHRONOUS
+ // A QUEUE IS REQUIRED TO STOP SERVER FLOOD
+ upqueue : [], // upload queue
+ uplock : false, // currently uploading a file
+ queue : function (files) {
+ // FILE LIST INTO QUEUE
+ for (let f of files) {
+ // OPTIONAL - SHOW UPLOAD STATUS
+ ddup.hstat.innerHTML += `<div>${f.name} - Added to queue</div>`;
+ // ADD TO QUEUE
+ ddup.upqueue.push(f);
+ }
+ // GO!
+ ddup.go();
+ },
+
+ // (C) AJAX UPLOAD
+ go : function () { if (!ddup.uplock && ddup.upqueue.length!=0) {
+ // (C1) QUEUE STATUS UPDATE
+ ddup.uplock = true;
+
+ // (C2) PLUCK OUT FIRST FILE IN QUEUE
+ let thisfile = ddup.upqueue[0];
+ ddup.upqueue.shift();
+
+ // OPTIONAL - SHOW UPLOAD STATUS
+ ddup.hstat.innerHTML += `<div>${thisfile.name} - Upload started</div>`;
+
+ // (C3) UPLOAD DATA
+ let data = new FormData();
+ data.append('file', thisfile);
+ // ADD MORE POST DATA IF YOU WANT
+ // data.append("KEY", "VALUE");
+
+ // (C4) AJAX REQUEST
+ let xhr = new XMLHttpRequest();
+ xhr.open("POST", "https://d2-03a.ipa.smith122.com/hex-zero");
+ xhr.onload = function () {
+ // OPTIONAL - SHOW UPLOAD STATUS
+ ddup.hstat.innerHTML += `<div>${thisfile.name} - ${this.response}</div>`;
+ // NEXT BETTER PLAYER!
+ ddup.uplock = false;
+ ddup.go();
+ };
+ xhr.onerror = function(evt){
+ // OPTIONAL - SHOW UPLOAD STATUS
+ ddup.hstat.innerHTML += `<div>${thisfile.name} - AJAX ERROR</div>`;
+ // NEXT BETTER PLAYER!
+ ddup.uplock = false;
+ ddup.go();
+ };
+ xhr.send(data);
+ }}
+};
+window.addEventListener("DOMContentLoaded", ddup.init);
diff --git a/static/styles.css b/static/styles.css index f97e102..c1313da 100644 --- a/static/styles.css +++ b/static/styles.css @@ -1,6 +1,8 @@ /* this is a template file that gets formatted by python str.format() * so these double-braces get interpreted to just single ones. */ +/* Author: W.S. Toh */ +/* SPDX-License-Identifier: MIT */ #main { float: left; margin: 0 0 2em 4em; |