annotate libervia/desktop_kivy/core/file_chooser.py @ 514:d78728d7fd6a

plugin wid calls, core: implements WebRTC DataChannel file transfer: - Add a new "file" icon in call UI to send a file via WebRTC. - Handle new preflight mechanism, and WebRTC file transfer. - Native file chooser handling has been moved to new `core.file_chooser` module, and now supports "save" and "dir" modes (based on `plyer`). rel 442
author Goffi <goffi@goffi.org>
date Sat, 06 Apr 2024 13:37:27 +0200
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
514
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia Desktop-Kivy
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2016-2024 Jérôme Poisson (goffi@goffi.org)
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 import asyncio
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 import threading
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
21
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from libervia.backend.core import exceptions
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from libervia.backend.core.i18n import _
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
24
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from kivy import properties
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from kivy.clock import Clock
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from kivy.event import EventDispatcher
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from plyer import filechooser, storagepath
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
29
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
30
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 class FileChooser(EventDispatcher):
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 callback = properties.ObjectProperty()
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 cancel_cb = properties.ObjectProperty()
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 native_filechooser = True
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 default_path = properties.StringProperty(storagepath.get_home_dir())
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 mode = properties.OptionProperty("open", options=["open", "save", "dir"])
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 title = properties.StringProperty(_("Please select a file to upload"))
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 def open(self):
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 """Open the file selection dialog in a separate thread"""
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 thread = threading.Thread(target=self._native_file_chooser)
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 thread.start()
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
43
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 @classmethod
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 async def a_open(cls, **kwargs) -> str | None:
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 """Open the file selection dialog asynchronously
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
47
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 @return: The path of the selected file
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 None if the dialog has been cancelled.
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 """
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 future = asyncio.Future()
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
52
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 def on_success(file_path):
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 if not future.done():
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 future.set_result(file_path)
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
56
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 def on_cancel(__):
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 if not future.done():
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 future.set_result(None)
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
60
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 file_chooser = cls(
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 **kwargs,
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 callback=on_success,
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 cancel_cb=on_cancel
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 )
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
66
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 file_chooser.open()
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
68
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 return await future
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
70
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 def _native_file_chooser(self, *args, **kwargs):
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 match self.mode:
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 case "open":
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 method = filechooser.open_file
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 case "save":
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 method = filechooser.save_file
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 case "dir":
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 method = filechooser.choose_dir
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 case _:
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 raise exceptions.InternalError("Should never be reached.")
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 files = method(
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 title=self.title, path=self.default_path, multiple=False, preview=True
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 )
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 # we want to leave the thread when calling on_files, so we use Clock
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 Clock.schedule_once(lambda *args: self.on_files(files=files), 0)
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
86
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 def on_files(self, files):
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 if files:
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 self.callback(files[0])
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 else:
d78728d7fd6a plugin wid calls, core: implements WebRTC DataChannel file transfer:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 self.cancel_cb(self)