Closed Staars closed 4 months ago
Very simple demo to download the files from the root folder "/" in a HTML page:
class DL
var files
def init()
import path
self.files = path.listdir("/")
self.web_add_handler()
tasmota.add_driver(self)
end
def web_add_button()
import webserver
webserver.content_send(
"<form id='dl_demo' style='display: block;' action='Demo' method='get'><button>Download Demo</button></form><p></p>")
end
def download(args)
import webserver
var fpath = f"/{args}"
var f = open(fpath,"r")
var data = f.readbytes()
webserver.content_open(200,"application/octet-stream")
webserver.content_send(data)
f.close()
end
#######################################################################
# Display the complete page
#######################################################################
def getFileList()
var el = "<div id='files'>"
for file:self.files
el += f"<a href='/b_dl?dl={file}' download='{file}'>{file}</a><br><br>"
end
el += "</div>"
return el
end
def page_download()
import webserver
import json
if !webserver.check_privileged_access() return nil end
# regular web page
webserver.content_start("Downloads") #- title of the web page -#
webserver.content_send_style() #- send standard Tasmota styles -#
webserver.content_send("<div>Berry Demo")
webserver.content_send("<p>Download files from '/'</p></div><br>") #- close .parent div-#
webserver.content_send(self.getFileList())
webserver.content_button(webserver.BUTTON_MANAGEMENT) #- button back to management page -#
webserver.content_stop() #- end of web page -#
end
#######################################################################
# Web Controller, called by POST to `/b_dl`
#######################################################################
def page_download_ctl()
import webserver
if !webserver.check_privileged_access() return nil end
try
if webserver.has_arg("dl")
self.download(webserver.arg(0))
else
raise "value_error", "Unknown command"
end
except .. as e, m
print(format("BRY: Exception> '%s' - %s", e, m))
#- display error page -#
webserver.content_start("Parameter error") #- title of the web page -#
webserver.content_send_style() #- send standard Tasmota styles -#
webserver.content_send(format("<p style='width:340px;'><b>Exception:</b><br>'%s'<br>%s</p>", e, m))
webserver.content_button(webserver.BUTTON_MANAGEMENT) #- button back to management page -#
webserver.content_send("<p></p>")
webserver.content_stop() #- end of web page -#
end
end
def web_add_handler()
import webserver
#- we need to register a closure, not just a function, that captures the current instance -#
webserver.on("/Demo", / -> self.page_download(), webserver.HTTP_GET)
webserver.on("/b_dl", / -> self.page_download_ctl(), webserver.HTTP_GET)
end
end
dl = DL()
Nice that it seems to be possible now, since https://github.com/arendst/Tasmota/pull/15573
I read back my comment from this PR. We need to check that the underlying implementation does not convert to String anymore
Part of the context is also the not-really-documented #define UFILESYS_STATIC_SERVING
supporting the UFSServe
command to set up a web server from the file system, implying support for binary files. Not tested that....
Of course, that's not really equivalent to having Berry code able to directly serve binary data, which in some cases can be quite handy instead of needing to write such data to the file system first.
Anyway, if the webserver
module can now handle binary data without going via the file system, "for completeness" it would be nice if the webclient
module also could do it the other way, instead of needing to go via write_file
for binary data.
Description:
This small addition makes it possible to serve arbitrary data like images or any other file with binary data.
Typically prepended with a call to content_open to declare the MIME type:
Longer demo in the comments.
Checklist:
NOTE: The code change must pass CI tests. Your PR cannot be merged unless tests pass