This is a simple subflow that will allow you to upload files in the Dashboard and also select and delete them. The directory to upload to is defined by the UPLOAD_DIR
subflow environement variable. You can also specify allowed extensions in the EXTENSIONS
environement variable.
-
-
Save natcl/5805a1141b1212d2c55c1781b9dbd15b to your computer and use it in GitHub Desktop.
File upload and delete in Dashboard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"id":"4f6b87ae.7d3bb","type":"subflow","name":"List Files","info":"# List files\n\nWill list files in a directory.\n\nPath can be set in `msg.payload` or by setting the `DIRECTORY` environment variable.\n\nExtensions can be filtered by settings the `EXTENSIONS` environment variable to an Array of extensions.\n","category":"","in":[{"x":80,"y":80,"wires":[{"id":"cf0b484b.b70c9"}]}],"out":[{"x":840,"y":40,"wires":[{"id":"13486428.bcfc4c","port":0}]}],"env":[{"name":"DIRECTORY","type":"str","value":""},{"name":"EXTENSIONS","type":"json","value":"[]"}]},{"id":"208379c0.81563e","type":"exec","z":"4f6b87ae.7d3bb","command":"ls","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":510,"y":60,"wires":[["13486428.bcfc4c"],[],[]]},{"id":"13486428.bcfc4c","type":"change","z":"4f6b87ae.7d3bb","name":"split and filter","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t $files := [$split(payload, '\\n')[$ != \"\"]];\t $count($env('EXTENSIONS')) = 0 ? [$files] : [$files[$split($, '.')[-1] in $env('EXTENSIONS')]];\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":40,"wires":[[]]},{"id":"cf0b484b.b70c9","type":"switch","z":"4f6b87ae.7d3bb","name":"","property":"$env('DIRECTORY')","propertyType":"jsonata","rules":[{"t":"empty"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":210,"y":80,"wires":[["208379c0.81563e"],["56426a5a.fbc44c"]]},{"id":"56426a5a.fbc44c","type":"change","z":"4f6b87ae.7d3bb","name":"DIRECTORY","rules":[{"t":"set","p":"payload","pt":"msg","to":"DIRECTORY","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":120,"wires":[["208379c0.81563e"]]},{"id":"19ad2b6f.f11b85","type":"subflow","name":"FIle Upload","info":"","category":"","in":[],"out":[{"x":1140,"y":280,"wires":[{"id":"144a9c8f.af7e9b","port":0},{"id":"854a9fb8.a668a8","port":0}]}],"env":[{"name":"UPLOAD_DIR","type":"str","value":"."},{"name":"EXTENSIONS","type":"json","value":"[]"}],"outputLabels":["fileWritten"]},{"id":"954c0325.f4f63","type":"http in","z":"19ad2b6f.f11b85","name":"","url":"/fileupload","method":"post","upload":true,"swaggerDoc":"","x":140,"y":440,"wires":[["7433a631.a7f58","faf9ee8.6642a1"]]},{"id":"964d2a30.34e938","type":"http response","z":"19ad2b6f.f11b85","name":"","statusCode":"","headers":{},"x":850,"y":440,"wires":[]},{"id":"1617f361.5dac2d","type":"ui_template","z":"19ad2b6f.f11b85","group":"4178bf61.05d97","name":"Upload","order":1,"width":"6","height":"3","format":"<form id=\"upload_form\" enctype=\"multipart/form-data\" method=\"post\">\n <input type=\"file\" name=\"file1\" id=\"file1\"><br>\n <input type=\"button\" value=\"Upload File\" onclick=\"uploadFile()\">\n <progress id=\"progressBar\" value=\"0\" max=\"100\" style=\"width:300px;\"></progress>\n <p id=\"status\"></p>\n <p id=\"loaded_n_total\"></p>\n</form>\n\n<script>\n function _(el){\n return document.getElementById(el);\n}\nfunction uploadFile(){\n var file = _(\"file1\").files[0];\n // alert(file.name+\" | \"+file.size+\" | \"+file.type);\n var formdata = new FormData();\n formdata.append(\"file1\", file);\n var ajax = new XMLHttpRequest();\n ajax.upload.addEventListener(\"progress\", progressHandler, false);\n ajax.addEventListener(\"load\", completeHandler, false);\n ajax.addEventListener(\"error\", errorHandler, false);\n ajax.addEventListener(\"abort\", abortHandler, false);\n ajax.open(\"POST\", \"/fileupload\");\n ajax.send(formdata);\n}\nfunction progressHandler(event){\n _(\"loaded_n_total\").innerHTML = \"Uploaded \"+event.loaded+\" bytes of \"+event.total;\n var percent = (event.loaded / event.total) * 100;\n _(\"progressBar\").value = Math.round(percent);\n _(\"status\").innerHTML = Math.round(percent)+\"% uploaded... please wait\";\n}\nfunction completeHandler(event){\n _(\"status\").innerHTML = event.target.responseText;\n _(\"progressBar\").value = 0;\n}\nfunction errorHandler(event){\n _(\"status\").innerHTML = \"Upload Failed\";\n}\nfunction abortHandler(event){\n _(\"status\").innerHTML = \"Upload Aborted\";\n}\n</script>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":120,"y":400,"wires":[[]]},{"id":"ea605dad.7b36a8","type":"subflow:4f6b87ae.7d3bb","z":"19ad2b6f.f11b85","name":"","env":[{"name":"DIRECTORY","type":"env","value":"UPLOAD_DIR"},{"name":"EXTENSIONS","type":"env","value":"EXTENSIONS"}],"x":380,"y":140,"wires":[["b42b38bf.d5a548"]]},{"id":"a425ba62.ff1df","type":"ui_dropdown","z":"19ad2b6f.f11b85","name":"","label":"","tooltip":"","place":"Select option","group":"4178bf61.05d97","order":0,"width":0,"height":0,"passthru":true,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"","x":750,"y":140,"wires":[["62157c1a.4444bc"]]},{"id":"bdb6a329.8574b","type":"link in","z":"19ad2b6f.f11b85","name":"refreshFileDropdown","links":["15ae2641.f1cc7a","be23c76f.4a3988"],"x":75,"y":140,"wires":[["f0813c91.8c7838"]]},{"id":"51272d56.830874","type":"ui_button","z":"19ad2b6f.f11b85","name":"","group":"4178bf61.05d97","order":0,"width":0,"height":0,"passthru":false,"label":"Delete","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":110,"y":220,"wires":[["a0bbc93d.d6f6b8"]]},{"id":"62157c1a.4444bc","type":"change","z":"19ad2b6f.f11b85","name":"","rules":[{"t":"set","p":"selectedFile","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":960,"y":140,"wires":[[]]},{"id":"7433a631.a7f58","type":"change","z":"19ad2b6f.f11b85","name":"getFile","rules":[{"t":"set","p":"filename","pt":"msg","to":"$env('UPLOAD_DIR') & '/' & req.files[0].originalname","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"req.files[0].buffer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":360,"wires":[["63e6ebc1.1cc124"]]},{"id":"10c1284a.0e3f98","type":"file","z":"19ad2b6f.f11b85","name":"","filename":"","appendNewline":false,"createDir":true,"overwriteFile":"true","x":830,"y":340,"wires":[["144a9c8f.af7e9b"]]},{"id":"af0d1f9b.6eb468","type":"inject","z":"19ad2b6f.f11b85","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":80,"wires":[["f0813c91.8c7838"]]},{"id":"a0bbc93d.d6f6b8","type":"change","z":"19ad2b6f.f11b85","name":"getSelectedFile","rules":[{"t":"set","p":"filename","pt":"msg","to":"$env('UPLOAD_DIR') & '/' & $flowContext('selectedFile')","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"Delete File ?","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":220,"wires":[["3e909d09.b8b5f2"]]},{"id":"854a9fb8.a668a8","type":"file","z":"19ad2b6f.f11b85","name":"","filename":"","appendNewline":true,"createDir":false,"overwriteFile":"delete","x":830,"y":220,"wires":[["be23c76f.4a3988"]]},{"id":"3e909d09.b8b5f2","type":"ui_toast","z":"19ad2b6f.f11b85","position":"dialog","displayTime":"3","highlight":"","outputs":1,"ok":"OK","cancel":"Cancel","topic":"","name":"","x":470,"y":220,"wires":[["a33238b4.01cae"]]},{"id":"a33238b4.01cae","type":"switch","z":"19ad2b6f.f11b85","name":"OK ?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"OK","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":630,"y":220,"wires":[["854a9fb8.a668a8"]]},{"id":"b54a9427.62f75","type":"catch","z":"19ad2b6f.f11b85","name":"","scope":null,"x":120,"y":500,"wires":[["1a19fda8.e72fd2"]]},{"id":"563135cc.7b97e4","type":"ui_toast","z":"19ad2b6f.f11b85","position":"top right","displayTime":"5","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"","raw":false,"topic":"","name":"","x":530,"y":500,"wires":[]},{"id":"1a19fda8.e72fd2","type":"change","z":"19ad2b6f.f11b85","name":"getError","rules":[{"t":"set","p":"payload","pt":"msg","to":"error.message","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":500,"wires":[["563135cc.7b97e4"]]},{"id":"be23c76f.4a3988","type":"link out","z":"19ad2b6f.f11b85","name":"refreshAfterDelete","links":["bdb6a329.8574b"],"x":1135,"y":220,"wires":[]},{"id":"15ae2641.f1cc7a","type":"link out","z":"19ad2b6f.f11b85","name":"refreshAfterUpload","links":["bdb6a329.8574b"],"x":1135,"y":340,"wires":[]},{"id":"faf9ee8.6642a1","type":"change","z":"19ad2b6f.f11b85","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"'File ' & req.files[0].originalname & ' uploaded.'","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":440,"wires":[["964d2a30.34e938"]]},{"id":"f0813c91.8c7838","type":"delay","z":"19ad2b6f.f11b85","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":190,"y":140,"wires":[["ea605dad.7b36a8"]]},{"id":"a5f544d.69b9bb8","type":"watch","z":"19ad2b6f.f11b85","name":"","files":"$(UPLOAD_DIR)","recursive":"","x":140,"y":40,"wires":[["f0813c91.8c7838"]]},{"id":"b42b38bf.d5a548","type":"change","z":"19ad2b6f.f11b85","name":"options","rules":[{"t":"set","p":"options","pt":"msg","to":"payload","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":140,"wires":[["a425ba62.ff1df"]]},{"id":"63e6ebc1.1cc124","type":"switch","z":"19ad2b6f.f11b85","name":"extensionAllowed ?","property":"$env('EXTENSIONS')","propertyType":"jsonata","rules":[{"t":"cont","v":"$split(filename, '.')[-1]","vt":"jsonata"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":610,"y":360,"wires":[["10c1284a.0e3f98"],["e34d7e40.c64b5"]]},{"id":"e34d7e40.c64b5","type":"function","z":"19ad2b6f.f11b85","name":"Error","func":"node.error(`Error: only ${env.get('EXTENSIONS')} files are allowed.`, msg)\n","outputs":0,"noerr":0,"x":830,"y":380,"wires":[]},{"id":"144a9c8f.af7e9b","type":"change","z":"19ad2b6f.f11b85","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":340,"wires":[["15ae2641.f1cc7a"]]},{"id":"4178bf61.05d97","type":"ui_group","z":"","name":"File upload","tab":"f1b5a1b6.543fd8","order":4,"disp":true,"width":"6","collapse":false},{"id":"f1b5a1b6.543fd8","type":"ui_tab","z":"","name":"File Upload","icon":"dashboard","order":4},{"id":"3696af61.5b451","type":"subflow:19ad2b6f.f11b85","z":"c178a9c2.3fd318","name":"","env":[],"x":270,"y":700,"wires":[[]]}] |
@andreapx the "File Upload" SubFlow properties needs a correctly assigned array (the default array is blank), in my example its allowing for .json and .log files ["json","log"]
PS: it does not list hidden files or sub-directories, most possibly it's design intented.
Thanks!!!
Hi I seem to be getting a upload permission error on dietpi is there something I might be doing wrong
failed to write to file: Error: EACCES: permission denied, open './Leave the area with tone.wav'
Make sure you set UPLOAD_DIR to a directory you have write access to, seems like you’re trying to write at the root of the filesystem…
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, I've tried this subflow, but no metter what file I try to upload, it says: Error: only files are allowed.