From badcb48cd279f0e2a0ed7eae2661171f2411e647 Mon Sep 17 00:00:00 2001 From: B Stack Date: Thu, 7 Jan 2021 20:52:38 -0500 Subject: initial commit --- templates/index.html.j2 | 83 ++++++++++++++++++++++++++++ templates/upload.html.j2 | 53 ++++++++++++++++++ templates/upload.js.j2 | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 275 insertions(+) create mode 100644 templates/index.html.j2 create mode 100644 templates/upload.html.j2 create mode 100644 templates/upload.js.j2 (limited to 'templates') diff --git a/templates/index.html.j2 b/templates/index.html.j2 new file mode 100644 index 0000000..75f97ee --- /dev/null +++ b/templates/index.html.j2 @@ -0,0 +1,83 @@ +{% set prefix_s = prefix | trim('/') ~ '/' %}{% set s_prefix_s = ( '/' ~ prefix | trim('/') ~ '/' ) | replace ("//","/") %}{% set ulp_s = ulp | trim('/') ~ '/' %}{% set server_prefix = ( server | replace("//","##") ~ '/' ~ prefix ~ '/' ) | replace("///","/") | replace("//", "/") | replace("##","//") %}{% set prefix_ulp = ( '/' ~ prefix ~ '/' ~ ulp ~ '/' ) | replace("///","/") | replace("//", "/") %}{% set server_prefix_ulp = ( server | replace("//","##") ~ '/' ~ prefix ~ '/' ~ ulp ~ '/' ) | replace("///","/") | replace("//", "/") | replace("##","//") %} + + +FUSS: File Upload and Storage Service + + + + + +

FUSS

+ +
+
+FUSS is a simple file upload and storage web app. +Features include: +
    +
  • Maximum upload size
  • +
  • Accept original file modification timestamp
  • +
  • Filter out mimetypes
  • +
  • Handle duplicate files gracefully
  • +
  • Handle up to so many dissimilar files with same name
  • +
  • Drag and drop upload
  • +
  • Display mimetype icons
  • +
+

source (GPL-3.0)

+
+
+ +
+
+{% if ulp != "" %}Visit the upload form at {{ ulp_s }}. +Or f{% else %}F{% endif %}rom the command line: +
+curl -F 'file=@/path/to/file' {{ server_prefix_ulp }}
+
+To save the original last modified timestamp from the command line, use script fuss-upload. +
+./fuss-upload /path/to/file {{ server_prefix_ulp }}
+
+
+
+ +
+
+
    +
  • Max file size: {{ max_size }}
  • +
  • Files stored: {{ file_count }} +(json +html +html details) +
  • +
  • Mimetype blacklist +{% if mimetype_blacklist %} +
      {% endif %} +{% for m in mimetype_blacklist %}
    • {{ m }}
    • {% endfor %} +{% if mimetype_blacklist %}
    {% endif %} +
  • Max duplicate filenames: {{ max_dupe }}
  • +
  • Metadata{% if not meta %} is disabled{% endif %} +{% if meta %} +
      +
    • User queriable: {% if meta_visible %}yes{% else %}no{% endif %}
    • +
    • Add to headers: {% if meta_visible and (meta_headers|length) > 0 %}yes{% else %}no{% endif %}
    • +
    • Mimetype icons: {% if icons %}yes{% else %}no{% endif %}
    • +{% endif %} +
    +
+

dump config (json) +

+
+ + + diff --git a/templates/upload.html.j2 b/templates/upload.html.j2 new file mode 100644 index 0000000..35673b7 --- /dev/null +++ b/templates/upload.html.j2 @@ -0,0 +1,53 @@ +{% set prefix_s = prefix | trim('/') ~ '/' %}{% set s_prefix_s = ( '/' ~ prefix | trim('/') ~ '/' ) | replace ("//","/") %}{% set ulp_s = ulp | trim('/') ~ '/' %}{% set server_prefix = ( server | replace("//","##") ~ '/' ~ prefix ~ '/' ) | replace("///","/") | replace("//", "/") | replace("##","//") %}{% set prefix_ulp = ( '/' ~ prefix ~ '/' ~ ulp ~ '/' ) | replace("///","/") | replace("//", "/") %}{% set server_prefix_ulp = ( server | replace("//","##") ~ '/' ~ prefix ~ '/' ~ ulp ~ '/' ) | replace("///","/") | replace("//", "/") | replace("##","//") %} + + + + FUSS upload page + + + + + + + + + + + + +
+ Drop Files Here +
+ + +
+
+ + +
+ + +
+ +
+
+
+
+
+ + + diff --git a/templates/upload.js.j2 b/templates/upload.js.j2 new file mode 100644 index 0000000..28fe892 --- /dev/null +++ b/templates/upload.js.j2 @@ -0,0 +1,139 @@ +{% set prefix_s = prefix | trim('/') ~ '/' %}{% set s_prefix_s = ( '/' ~ prefix | trim('/') ~ '/' ) | replace ("//","/") %}{% set ulp_s = ulp | trim('/') ~ '/' %}{% set server_prefix = ( server | replace("//","##") ~ '/' ~ prefix ~ '/' ) | replace("///","/") | replace("//", "/") | replace("##","//") %}{% set prefix_ulp = ( '/' ~ prefix ~ '/' ~ ulp ~ '/' ) | replace("///","/") | replace("//", "/") %}{% set server_prefix_ulp = ( server | replace("//","##") ~ '/' ~ prefix ~ '/' ~ ulp ~ '/' ) | replace("///","/") | replace("//", "/") | replace("##","//") %} +/* vim:set syntax=javascript ts=2 sw=2 sts=2 et: */ +var ddup = { + // (A) ON PAGE LOAD + hzone: null, // HTML upload zone + hstat: null, // HTML upload status + hform: null, // HTML upload form + hiddenfirst: null, + init : function () { + // (A1) GET HTML ELEMENTS + ddup.hzone = document.getElementById("upzone"); + ddup.hstat = document.getElementById("upstat"); + ddup.hform = document.getElementById("upform"); + ddup.hiddenfirst = document.getElementById("hiddenfirst"); + + // (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.innerHTML = "Release to upload"; + }); + ddup.hzone.addEventListener("dragleave", function (e) { + e.preventDefault(); + e.stopPropagation(); + ddup.hzone.classList.remove('highlight'); + ddup.hzone.innerHTML = "Drop Files Here"; + }); + + // 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.hiddenfirst.style.display = "block" ; + if (e.dataTransfer.files.length > 0) { + ddup.hzone.classList.add('processing'); + ddup.hzone.innerHTML = "Uploading..."; + ddup.queue(e.dataTransfer.files); + } else { + ddup.hzone.classList.add('invalid'); + ddup.hzone.innerHTML = "Input is not recognized!"; + ddup.reset_text_timer(1500); + } + }); + } + + // (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.thisdiv = document.getElementById(f.name); + if (!ddup.thisdiv) { + // add new div with filename as id + ddup.hstat.innerHTML += `
${f.name} - Added to queue
`; + } else { + // change contents of existing div + ddup.thisdiv.innerHTML = `${f.name} - Added to queue`; + } + // 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.thisdiv = document.getElementById(thisfile.name); + ddup.thisdiv.innerHTML = `${thisfile.name} - Upload started`; + // at start of queue, change color + ddup.hzone.classList.add('processing'); + ddup.hzone.innerHTML = "Uploading..."; + + // (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", "{{ server_prefix_ulp }}"); + xhr.setRequestHeader("lastModified", thisfile.lastModified/1000); + xhr.onload = function () { + // OPTIONAL - SHOW UPLOAD STATUS + ddup.thisdiv.innerHTML = `${thisfile.name} - ${this.response}`; + // NEXT BETTER PLAYER! + ddup.hzone.classList.remove('processing'); + ddup.hzone.innerHTML = "Drop Files Here"; + ddup.uplock = false; + ddup.go(); + }; + xhr.onerror = function(evt){ + // OPTIONAL - SHOW UPLOAD STATUS + ddup.thisdiv.innerHTML = `${thisfile.name} - AJAX ERROR`; + // NEXT BETTER PLAYER! + ddup.hzone.classList.remove('processing'); + ddup.hzone.innerHTML = "Drop Files Here"; + ddup.uplock = false; + ddup.go(); + }; + xhr.send(data); + } }, + + reset_text_timer : function (delay_ms) { + setTimeout(function (){ + ddup.hzone.classList.remove('invalid'); + ddup.hzone.innerHTML = "Drop Files Here"; + }, delay_ms); + } +}; +window.addEventListener("DOMContentLoaded", ddup.init); -- cgit