Mercurial > libervia-web
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 |
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 ) |