Mercurial > libervia-web
comparison libervia/pages/photos/album/_browser/__init__.py @ 1352:d100d3a07dd7
browser (photos/album): change cover on "cover" button click:
when "cover" button is clicked, image thumbnail is downloaded with ajax to get a blob, which
is then uploaded via HTTP Upload and used as cover.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 05 Sep 2020 21:59:38 +0200 |
parents | 2c3bc7284992 |
children | dbd573b0bc9c |
comparison
equal
deleted
inserted
replaced
1351:2c3bc7284992 | 1352:d100d3a07dd7 |
---|---|
1 from browser import document, window, bind, html, DOMNode | 1 from browser import document, window, bind, html, DOMNode, aio |
2 from javascript import JSON | 2 from javascript import JSON |
3 from bridge import Bridge | 3 from bridge import Bridge |
4 from aio_bridge import Bridge as AIOBridge | |
4 from template import Template | 5 from template import Template |
5 import dialog | 6 import dialog |
6 from slideshow import SlideShow | 7 from slideshow import SlideShow |
7 from invitation import InvitationManager | 8 from invitation import InvitationManager |
8 import alt_media_player | 9 import alt_media_player |
10 # we use tmp_aio because `blob` is not handled in Brython's aio | |
11 import tmp_aio | |
12 | |
9 | 13 |
10 cache_path = window.cache_path | 14 cache_path = window.cache_path |
11 files_service = window.files_service | 15 files_service = window.files_service |
12 files_path = window.files_path | 16 files_path = window.files_path |
13 try: | 17 try: |
14 affiliations = window.affiliations.to_dict() | 18 affiliations = window.affiliations.to_dict() |
15 except AttributeError: | 19 except AttributeError: |
16 pass | 20 pass |
17 bridge = Bridge() | 21 bridge = Bridge() |
22 aio_bridge = AIOBridge() | |
18 | 23 |
19 alt_media_player.install_if_needed() | 24 alt_media_player.install_if_needed() |
20 | 25 |
21 photo_tpl = Template('photo/item.html') | 26 photo_tpl = Template('photo/item.html') |
22 player_tpl = Template('components/media_player.html') | 27 player_tpl = Template('components/media_player.html') |
164 ok_color="danger", | 169 ok_color="danger", |
165 ).show( | 170 ).show( |
166 ok_cb=lambda evt, notif_elt: delete_ok(evt, notif_elt, item_elt, item), | 171 ok_cb=lambda evt, notif_elt: delete_ok(evt, notif_elt, item_elt, item), |
167 cancel_cb=lambda evt, notif_elt: delete_cancel(evt, notif_elt, item_elt, item), | 172 cancel_cb=lambda evt, notif_elt: delete_cancel(evt, notif_elt, item_elt, item), |
168 ) | 173 ) |
174 | |
175 # cover | |
176 | |
177 async def cover_ok(evt, notif_elt, item_elt, item): | |
178 # we first need to get a blob of the image | |
179 img_elt = item_elt.select_one("img") | |
180 # the simplest way is to download it | |
181 r = await tmp_aio.ajax("GET", img_elt.src, "blob") | |
182 if r.status != 200: | |
183 dialog.notification.show( | |
184 f"can't retrieve cover: {r.status}: {r.statusText}", | |
185 level="error" | |
186 ) | |
187 return | |
188 img_blob = r.response | |
189 # now we'll upload it via HTTP Upload, we need a slow | |
190 img_name = img_elt.src.rsplit('/', 1)[-1] | |
191 img_size = img_blob.size | |
192 | |
193 slot = await aio_bridge.fileHTTPUploadGetSlot( | |
194 img_name, | |
195 img_size, | |
196 '', | |
197 files_service | |
198 ) | |
199 get_url, put_url, headers = slot | |
200 # we have the slot, we can upload image | |
201 r = await tmp_aio.ajax("PUT", put_url, "", img_blob) | |
202 if r.status != 201: | |
203 dialog.notification.show( | |
204 f"can't upload cover: {r.status}: {r.statusText}", | |
205 level="error" | |
206 ) | |
207 return | |
208 extra = {"thumb_url": get_url} | |
209 album_name = files_path.rsplit('/', 1)[-1] | |
210 await aio_bridge.interestsRegisterFileSharing( | |
211 files_service, | |
212 "photos", | |
213 "", | |
214 files_path, | |
215 album_name, | |
216 JSON.stringify(extra), | |
217 ) | |
218 dialog.notification.show("Album cover has been changed") | |
219 | |
220 | |
221 def cover_cancel(evt, notif_elt, item_elt, item): | |
222 notif_elt.remove() | |
223 item_elt.classList.remove("selected_for_action") | |
224 | |
225 | |
226 def on_cover(evt): | |
227 evt.stopPropagation() | |
228 target = evt.currentTarget | |
229 item_elt = DOMNode(target.elt.closest('.item')) | |
230 item_elt.classList.add("selected_for_action") | |
231 item = JSON.parse(item_elt.dataset.item) | |
232 dialog.Confirm( | |
233 f"use {item['name']!r} for this album cover?", | |
234 ok_label="use as cover", | |
235 ).show( | |
236 ok_cb=lambda evt, notif_elt: aio.run(cover_ok(evt, notif_elt, item_elt, item)), | |
237 cancel_cb=lambda evt, notif_elt: cover_cancel(evt, notif_elt, item_elt, item), | |
238 ) | |
239 | |
169 | 240 |
170 # slideshow | 241 # slideshow |
171 | 242 |
172 @bind(".photo_thumb_click", "click") | 243 @bind(".photo_thumb_click", "click") |
173 def photo_click(evt): | 244 def photo_click(evt): |
208 slideshow.index = idx | 279 slideshow.index = idx |
209 | 280 |
210 | 281 |
211 for elt in document.select('.action_delete'): | 282 for elt in document.select('.action_delete'): |
212 elt.bind("click", on_delete) | 283 elt.bind("click", on_delete) |
284 for elt in document.select('.action_cover'): | |
285 elt.bind("click", on_cover) | |
213 | 286 |
214 # manage | 287 # manage |
215 | 288 |
216 | 289 |
217 @bind("#button_manage", "click") | 290 @bind("#button_manage", "click") |