annotate libervia/web/pages/_browser/file_uploader.py @ 1532:106945841fbc

_browser (album): moved code to upload file to a separate `file_uploader` module: this way, uploading logic can be re-used elsewhere.
author Goffi <goffi@goffi.org>
date Thu, 22 Jun 2023 16:36:01 +0200
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1532
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 import json
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 from bridge import Bridge
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 from browser import console as log, window
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 import dialog
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 from template import Template
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 bridge = Bridge()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
7
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 log.warning = log.warn
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
9
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 class FileUploader:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 """Class handling HTTP upload and progress display"""
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
13
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 def __init__(self, files_service, template_file, files_path=None, on_delete_cb=None):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 self.files_service = files_service
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 self.files_path = files_path
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 self.item_tpl = Template(template_file)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 self.on_delete_cb = on_delete_cb
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 self.uploaded = {}
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 def on_progress(self, ev, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 if ev.lengthComputable:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 percent = int(ev.loaded/ev.total*100)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 self.update_progress(item_elt, percent)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
25
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 def on_load(self, file_, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 self.update_progress(item_elt, 100)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 item_elt.classList.add("progress_finished")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 item_elt.classList.remove("progress_started")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 if self.on_delete_cb is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 delete_btn = item_elt.select_one('.action_delete')
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 if delete_btn is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 delete_btn.bind("click", self.on_delete_cb)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 log.info(f"file {file_.name} uploaded correctly")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
35
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 def on_error(self, failure, file_, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 dialog.notification.show(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 f"can't upload {file_.name}: {failure}",
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 level="error"
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 )
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 def update_progress(self, item_elt, new_value):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 progress_elt = item_elt.select_one("progress")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 if progress_elt is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 progress_elt.value = new_value
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 progress_elt.text = f"{new_value}%"
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
47
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 def on_slot_cb(self, file_, upload_slot, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 put_url, get_url, headers = upload_slot
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 xhr = window.XMLHttpRequest.new()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 xhr.open("PUT", put_url, True)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 xhr.upload.bind('progress', lambda ev: self.on_progress(ev, item_elt))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 xhr.upload.bind('load', lambda ev: self.on_load(file_, item_elt))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 xhr.upload.bind('error', lambda ev: self.on_error(xhr.response, file_, item_elt))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 if self.files_path is not None:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 xhr.setRequestHeader(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 'Xmpp-File-Path',
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 window.encodeURIComponent(self.files_path)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 )
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 xhr.setRequestHeader('Xmpp-File-No-Http', "true")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 xhr.send(file_)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
62
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 # we update file data with the get URL
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 file_data = json.loads(item_elt.getAttribute("data-file"))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 file_data["url"] = get_url
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 item_elt.setAttribute("data-file", json.dumps(file_data))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
67
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 def on_slot_eb(self, file_, failure, item_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 dialog.notification.show(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 f"Can't get upload slot: {failure['message']}",
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 level="error"
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 )
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 item_elt.remove()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
74
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 def upload_files(self, files, container_elt):
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 """Start file upload, and add item_tpl to container_elt"""
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 log.info(f"uploading {len(files)} files")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 for file_ in files:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 url = window.URL.createObjectURL(file_)
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
80
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 file_data = {
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 "name": file_.name,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 "mime_type": file_.type,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 }
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 template_file_data = file_data.copy()
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 # we don't want to open the file on click, it's not yet the
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 # uploaded URL
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 template_file_data["url"] = url
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 # we have no thumb yet, so we use the whole image
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 # TODO: reduce image for preview
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 template_file_data["thumb_url"] = url
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
92
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 item_elt = self.item_tpl.get_elt({
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 "file": template_file_data,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 "uploading": True,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 })
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 item_elt.setAttribute("data-file", json.dumps(file_data))
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 item_elt.classList.add("progress_started")
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 container_elt <= item_elt
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
100
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 bridge.file_http_upload_get_slot(
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 file_.name,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 file_.size,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 file_.type or '',
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 self.files_service,
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 callback=lambda upload_slot, file_=file_, item_elt=item_elt:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 self.on_slot_cb(file_, upload_slot, item_elt),
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 errback=lambda failure, file_=file_, item_elt=item_elt:
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 self.on_slot_eb(file_, failure, item_elt),
106945841fbc _browser (album): moved code to upload file to a separate `file_uploader` module:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 )