Mercurial > libervia-desktop-kivy
annotate libervia/desktop_kivy/plugins/plugin_wid_file_sharing.py @ 499:f387992d8e37
plugins: new "call" plugin for A/V calls:
this is the base implementation for calls plugin, handling one2one calls.
For now, the interface is very basic, call is done by specifying the bare jid of the
destinee, then press the "call" button. Incoming calls are automatically accepted.
rel 424
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 04 Oct 2023 22:54:36 +0200 |
parents | b3cedbee561d |
children | 196483685a63 |
rev | line source |
---|---|
379 | 1 #!/usr/bin/env python3 |
192 | 2 |
493
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
3 #Libervia Desktop-Kivy |
461 | 4 # Copyright (C) 2016-2021 Jérôme Poisson (goffi@goffi.org) |
192 | 5 |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 | |
383
a90f26e89a4a
share widget: fixed crash when a text content is shared without `text` in data:
Goffi <goffi@goffi.org>
parents:
379
diff
changeset
|
20 from functools import partial |
a90f26e89a4a
share widget: fixed crash when a text content is shared without `text` in data:
Goffi <goffi@goffi.org>
parents:
379
diff
changeset
|
21 import os.path |
a90f26e89a4a
share widget: fixed crash when a text content is shared without `text` in data:
Goffi <goffi@goffi.org>
parents:
379
diff
changeset
|
22 import json |
493
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
23 from libervia.backend.core import log as logging |
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
24 from libervia.backend.core import exceptions |
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
25 from libervia.backend.core.i18n import _ |
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
26 from libervia.backend.tools.common import files_utils |
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
27 from libervia.frontends.quick_frontend import quick_widgets |
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
28 from libervia.frontends.tools import jid |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
29 from ..core.constants import Const as C |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
30 from ..core import cagou_widget |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
31 from ..core.menu import EntitiesSelectorMenu |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
32 from ..core.behaviors import TouchMenuBehavior, FilterBehavior |
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
33 from ..core.common_widgets import (Identities, ItemWidget, DeviceWidget, |
237
059c5b39032d
plugin file sharing: moved common discovery widgets to new core.common_widgets module
Goffi <goffi@goffi.org>
parents:
222
diff
changeset
|
34 CategorySeparator) |
493
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
35 from libervia.desktop_kivy import G |
192 | 36 from kivy import properties |
37 from kivy.uix.label import Label | |
38 from kivy.uix.button import Button | |
205
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
39 from kivy import utils as kivy_utils |
383
a90f26e89a4a
share widget: fixed crash when a text content is shared without `text` in data:
Goffi <goffi@goffi.org>
parents:
379
diff
changeset
|
40 |
a90f26e89a4a
share widget: fixed crash when a text content is shared without `text` in data:
Goffi <goffi@goffi.org>
parents:
379
diff
changeset
|
41 log = logging.getLogger(__name__) |
192 | 42 |
43 | |
44 PLUGIN_INFO = { | |
312 | 45 "name": _("file sharing"), |
192 | 46 "main": "FileSharing", |
312 | 47 "description": _("share/transfer files between devices"), |
48 "icon_symbol": "exchange", | |
192 | 49 } |
312 | 50 MODE_VIEW = "view" |
51 MODE_LOCAL = "local" | |
52 SELECT_INSTRUCTIONS = _("Please select entities to share with") | |
192 | 53 |
205
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
54 if kivy_utils.platform == "android": |
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
55 from jnius import autoclass |
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
56 Environment = autoclass("android.os.Environment") |
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
57 base_dir = Environment.getExternalStorageDirectory().getAbsolutePath() |
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
58 def expanduser(path): |
312 | 59 if path == '~' or path.startswith('~/'): |
60 return path.replace('~', base_dir, 1) | |
205
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
61 return path |
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
62 else: |
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
63 expanduser = os.path.expanduser |
192 | 64 |
65 | |
66 class ModeBtn(Button): | |
67 | |
68 def __init__(self, parent, **kwargs): | |
69 super(ModeBtn, self).__init__(**kwargs) | |
70 parent.bind(mode=self.on_mode) | |
71 self.on_mode(parent, parent.mode) | |
72 | |
73 def on_mode(self, parent, new_mode): | |
74 if new_mode == MODE_VIEW: | |
312 | 75 self.text = _("view shared files") |
192 | 76 elif new_mode == MODE_LOCAL: |
312 | 77 self.text = _("share local files") |
192 | 78 else: |
312 | 79 exceptions.InternalError("Unknown mode: {mode}".format(mode=new_mode)) |
192 | 80 |
81 | |
82 class PathWidget(ItemWidget): | |
83 | |
222 | 84 def __init__(self, filepath, main_wid, **kw): |
192 | 85 name = os.path.basename(filepath) |
86 self.filepath = os.path.normpath(filepath) | |
312 | 87 if self.filepath == '.': |
88 self.filepath = '' | |
222 | 89 super(PathWidget, self).__init__(name=name, main_wid=main_wid, **kw) |
192 | 90 |
91 @property | |
92 def is_dir(self): | |
93 raise NotImplementedError | |
94 | |
95 def do_item_action(self, touch): | |
96 if self.is_dir: | |
222 | 97 self.main_wid.current_dir = self.filepath |
192 | 98 |
99 def open_menu(self, touch, dt): | |
312 | 100 log.debug(_("opening menu for {path}").format(path=self.filepath)) |
192 | 101 super(PathWidget, self).open_menu(touch, dt) |
102 | |
103 | |
104 class LocalPathWidget(PathWidget): | |
105 | |
106 @property | |
107 def is_dir(self): | |
108 return os.path.isdir(self.filepath) | |
109 | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
110 def get_menu_choices(self): |
192 | 111 choices = [] |
112 if self.shared: | |
312 | 113 choices.append(dict(text=_('unshare'), |
192 | 114 index=len(choices)+1, |
222 | 115 callback=self.main_wid.unshare)) |
192 | 116 else: |
312 | 117 choices.append(dict(text=_('share'), |
192 | 118 index=len(choices)+1, |
222 | 119 callback=self.main_wid.share)) |
192 | 120 return choices |
121 | |
122 | |
123 class RemotePathWidget(PathWidget): | |
124 | |
222 | 125 def __init__(self, main_wid, filepath, type_, **kw): |
192 | 126 self.type_ = type_ |
222 | 127 super(RemotePathWidget, self).__init__(filepath, main_wid=main_wid, **kw) |
192 | 128 |
129 @property | |
130 def is_dir(self): | |
131 return self.type_ == C.FILE_TYPE_DIRECTORY | |
132 | |
133 def do_item_action(self, touch): | |
134 if self.is_dir: | |
312 | 135 if self.filepath == '..': |
136 self.main_wid.remote_entity = '' | |
192 | 137 else: |
138 super(RemotePathWidget, self).do_item_action(touch) | |
139 else: | |
222 | 140 self.main_wid.request_item(self) |
192 | 141 return True |
142 | |
237
059c5b39032d
plugin file sharing: moved common discovery widgets to new core.common_widgets module
Goffi <goffi@goffi.org>
parents:
222
diff
changeset
|
143 class SharingDeviceWidget(DeviceWidget): |
206
890b48e41998
plugin file sharing: use appropriate symbol when discovering devices
Goffi <goffi@goffi.org>
parents:
205
diff
changeset
|
144 |
192 | 145 def do_item_action(self, touch): |
222 | 146 self.main_wid.remote_entity = self.entity_jid |
312 | 147 self.main_wid.remote_dir = '' |
192 | 148 |
149 | |
493
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
150 class FileSharing(quick_widgets.QuickWidget, cagou_widget.LiberviaDesktopKivyWidget, FilterBehavior, |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
151 TouchMenuBehavior): |
192 | 152 SINGLE=False |
153 layout = properties.ObjectProperty() | |
254 | 154 mode = properties.OptionProperty(MODE_VIEW, options=[MODE_VIEW, MODE_LOCAL]) |
312 | 155 local_dir = properties.StringProperty(expanduser('~')) |
156 remote_dir = properties.StringProperty('') | |
157 remote_entity = properties.StringProperty('') | |
192 | 158 shared_paths = properties.ListProperty() |
387
d61bbbac4160
cagou widget: don't add header_input systematically anymore:
Goffi <goffi@goffi.org>
parents:
383
diff
changeset
|
159 use_header_input = True |
192 | 160 signals_registered = False |
161 | |
162 def __init__(self, host, target, profiles): | |
163 quick_widgets.QuickWidget.__init__(self, host, target, profiles) | |
493
b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
Goffi <goffi@goffi.org>
parents:
491
diff
changeset
|
164 cagou_widget.LiberviaDesktopKivyWidget.__init__(self) |
196
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
165 FilterBehavior.__init__(self) |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
166 TouchMenuBehavior.__init__(self) |
192 | 167 self.mode_btn = ModeBtn(self) |
168 self.mode_btn.bind(on_release=self.change_mode) | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
169 self.header_input_add_extra(self.mode_btn) |
192 | 170 self.bind(local_dir=self.update_view, |
171 remote_dir=self.update_view, | |
172 remote_entity=self.update_view) | |
173 self.update_view() | |
174 if not FileSharing.signals_registered: | |
175 # FIXME: we use this hack (registering the signal for the whole class) now | |
176 # as there is currently no unregisterSignal available in bridges | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
177 G.host.register_signal("fis_shared_path_new", |
217
286f14127f61
plugin file sharing: started to limit line to 90 chars as a test
Goffi <goffi@goffi.org>
parents:
214
diff
changeset
|
178 handler=FileSharing.shared_path_new, |
286f14127f61
plugin file sharing: started to limit line to 90 chars as a test
Goffi <goffi@goffi.org>
parents:
214
diff
changeset
|
179 iface="plugin") |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
180 G.host.register_signal("fis_shared_path_removed", |
217
286f14127f61
plugin file sharing: started to limit line to 90 chars as a test
Goffi <goffi@goffi.org>
parents:
214
diff
changeset
|
181 handler=FileSharing.shared_path_removed, |
286f14127f61
plugin file sharing: started to limit line to 90 chars as a test
Goffi <goffi@goffi.org>
parents:
214
diff
changeset
|
182 iface="plugin") |
192 | 183 FileSharing.signals_registered = True |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
184 G.host.bridge.fis_local_shares_get(self.profile, |
192 | 185 callback=self.fill_paths, |
186 errback=G.host.errback) | |
187 | |
188 @property | |
189 def current_dir(self): | |
190 return self.local_dir if self.mode == MODE_LOCAL else self.remote_dir | |
191 | |
192 @current_dir.setter | |
193 def current_dir(self, new_dir): | |
194 if self.mode == MODE_LOCAL: | |
195 self.local_dir = new_dir | |
196 else: | |
197 self.remote_dir = new_dir | |
198 | |
199 def fill_paths(self, shared_paths): | |
200 self.shared_paths.extend(shared_paths) | |
201 | |
202 def change_mode(self, mode_btn): | |
203 self.clear_menu() | |
204 opt = self.__class__.mode.options | |
205 new_idx = (opt.index(self.mode)+1) % len(opt) | |
206 self.mode = opt[new_idx] | |
207 | |
208 def on_mode(self, instance, new_mode): | |
209 self.update_view(None, self.local_dir) | |
210 | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
211 def on_header_wid_input(self): |
312 | 212 if '/' in self.header_input.text or self.header_input.text == '~': |
205
9cefc9f8efc9
plugin file sharing: use external storage directory instead of home (which is "/data") on Android when expanding "~"
Goffi <goffi@goffi.org>
parents:
202
diff
changeset
|
213 self.current_dir = expanduser(self.header_input.text) |
194
a68c9baa6694
plugin file sharing: use header hint to show current path, and open new path:
Goffi <goffi@goffi.org>
parents:
192
diff
changeset
|
214 |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
215 def on_header_wid_input_complete(self, wid, text, **kwargs): |
192 | 216 """we filter items when text is entered in input box""" |
312 | 217 if '/' in text: |
194
a68c9baa6694
plugin file sharing: use header hint to show current path, and open new path:
Goffi <goffi@goffi.org>
parents:
192
diff
changeset
|
218 return |
404
f7476818f9fb
core (common): JidSelector + behaviors various improvments:
Goffi <goffi@goffi.org>
parents:
387
diff
changeset
|
219 self.do_filter(self.layout, |
196
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
220 text, |
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
221 lambda c: c.name, |
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
222 width_cb=lambda c: c.base_width, |
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
223 height_cb=lambda c: c.minimum_height, |
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
224 continue_tests=[lambda c: not isinstance(c, ItemWidget), |
312 | 225 lambda c: c.name == '..']) |
196
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
226 |
192 | 227 |
228 ## remote sharing callback ## | |
229 | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
230 def _disco_find_by_features_cb(self, data): |
192 | 231 entities_services, entities_own, entities_roster = data |
232 for entities_map, title in ((entities_services, | |
312 | 233 _('services')), |
192 | 234 (entities_own, |
312 | 235 _('your devices')), |
192 | 236 (entities_roster, |
312 | 237 _('your contacts devices'))): |
192 | 238 if entities_map: |
239 self.layout.add_widget(CategorySeparator(text=title)) | |
312 | 240 for entity_str, entity_ids in entities_map.items(): |
192 | 241 entity_jid = jid.JID(entity_str) |
237
059c5b39032d
plugin file sharing: moved common discovery widgets to new core.common_widgets module
Goffi <goffi@goffi.org>
parents:
222
diff
changeset
|
242 item = SharingDeviceWidget( |
059c5b39032d
plugin file sharing: moved common discovery widgets to new core.common_widgets module
Goffi <goffi@goffi.org>
parents:
222
diff
changeset
|
243 self, entity_jid, Identities(entity_ids)) |
192 | 244 self.layout.add_widget(item) |
214
6a98d70a3a66
file sharing: display a message when not sharing device has been found
Goffi <goffi@goffi.org>
parents:
213
diff
changeset
|
245 if not entities_services and not entities_own and not entities_roster: |
6a98d70a3a66
file sharing: display a message when not sharing device has been found
Goffi <goffi@goffi.org>
parents:
213
diff
changeset
|
246 self.layout.add_widget(Label( |
6a98d70a3a66
file sharing: display a message when not sharing device has been found
Goffi <goffi@goffi.org>
parents:
213
diff
changeset
|
247 size_hint=(1, 1), |
6a98d70a3a66
file sharing: display a message when not sharing device has been found
Goffi <goffi@goffi.org>
parents:
213
diff
changeset
|
248 halign='center', |
6a98d70a3a66
file sharing: display a message when not sharing device has been found
Goffi <goffi@goffi.org>
parents:
213
diff
changeset
|
249 text_size=self.size, |
312 | 250 text=_("No sharing device found"))) |
192 | 251 |
252 def discover_devices(self): | |
253 """Looks for devices handling file "File Information Sharing" and display them""" | |
254 try: | |
255 namespace = self.host.ns_map['fis'] | |
256 except KeyError: | |
312 | 257 msg = _("can't find file information sharing namespace, " |
258 "is the plugin running?") | |
192 | 259 log.warning(msg) |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
260 G.host.add_note(_("missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) |
192 | 261 return |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
262 self.host.bridge.disco_find_by_features( |
199
b80d275e437f
plugin file sharing: use new local_device argument of discoFindByFeatures
Goffi <goffi@goffi.org>
parents:
198
diff
changeset
|
263 [namespace], [], False, True, True, True, False, self.profile, |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
264 callback=self._disco_find_by_features_cb, |
192 | 265 errback=partial(G.host.errback, |
312 | 266 title=_("shared folder error"), |
267 message=_("can't check sharing devices: {msg}"))) | |
192 | 268 |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
269 def fis_list_cb(self, files_data): |
192 | 270 for file_data in files_data: |
312 | 271 filepath = os.path.join(self.current_dir, file_data['name']) |
192 | 272 item = RemotePathWidget( |
273 filepath=filepath, | |
222 | 274 main_wid=self, |
312 | 275 type_=file_data['type']) |
192 | 276 self.layout.add_widget(item) |
277 | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
278 def fis_list_eb(self, failure_): |
312 | 279 self.remote_dir = '' |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
280 G.host.add_note( |
312 | 281 _("shared folder error"), |
282 _("can't list files for {remote_entity}: {msg}").format( | |
192 | 283 remote_entity=self.remote_entity, |
284 msg=failure_), | |
285 level=C.XMLUI_DATA_LVL_WARNING) | |
286 | |
287 ## view generation ## | |
288 | |
289 def update_view(self, *args): | |
290 """update items according to current mode, entity and dir""" | |
312 | 291 log.debug('updating {}, {}'.format(self.current_dir, args)) |
192 | 292 self.layout.clear_widgets() |
312 | 293 self.header_input.text = '' |
194
a68c9baa6694
plugin file sharing: use header hint to show current path, and open new path:
Goffi <goffi@goffi.org>
parents:
192
diff
changeset
|
294 self.header_input.hint_text = self.current_dir |
a68c9baa6694
plugin file sharing: use header hint to show current path, and open new path:
Goffi <goffi@goffi.org>
parents:
192
diff
changeset
|
295 |
192 | 296 if self.mode == MODE_LOCAL: |
312 | 297 filepath = os.path.join(self.local_dir, '..') |
222 | 298 self.layout.add_widget(LocalPathWidget(filepath=filepath, main_wid=self)) |
213
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
299 try: |
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
300 files = sorted(os.listdir(self.local_dir)) |
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
301 except OSError as e: |
312 | 302 msg = _("can't list files in \"{local_dir}\": {msg}").format( |
213
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
303 local_dir=self.local_dir, |
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
304 msg=e) |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
305 G.host.add_note( |
312 | 306 _("shared folder error"), |
213
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
307 msg, |
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
308 level=C.XMLUI_DATA_LVL_WARNING) |
312 | 309 self.local_dir = expanduser('~') |
213
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
310 return |
192 | 311 for f in files: |
312 filepath = os.path.join(self.local_dir, f) | |
222 | 313 self.layout.add_widget(LocalPathWidget(filepath=filepath, |
314 main_wid=self)) | |
192 | 315 elif self.mode == MODE_VIEW: |
316 if not self.remote_entity: | |
317 self.discover_devices() | |
318 else: | |
319 # we always a way to go back | |
320 # so user can return to previous list even in case of error | |
312 | 321 parent_path = os.path.join(self.remote_dir, '..') |
192 | 322 item = RemotePathWidget( |
323 filepath = parent_path, | |
222 | 324 main_wid=self, |
192 | 325 type_ = C.FILE_TYPE_DIRECTORY) |
326 self.layout.add_widget(item) | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
327 self.host.bridge.fis_list( |
312 | 328 str(self.remote_entity), |
192 | 329 self.remote_dir, |
330 {}, | |
331 self.profile, | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
332 callback=self.fis_list_cb, |
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
333 errback=self.fis_list_eb) |
192 | 334 |
335 ## Share methods ## | |
336 | |
198
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
337 def do_share(self, entities_jids, item): |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
338 if entities_jids: |
312 | 339 access = {'read': {'type': 'whitelist', |
340 'jids': entities_jids}} | |
198
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
341 else: |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
342 access = {} |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
343 |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
344 G.host.bridge.fis_share_path( |
192 | 345 item.name, |
346 item.filepath, | |
198
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
347 json.dumps(access, ensure_ascii=False), |
192 | 348 self.profile, |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
349 callback=lambda name: G.host.add_note( |
312 | 350 _("sharing folder"), |
351 _("{name} is now shared").format(name=name)), | |
192 | 352 errback=partial(G.host.errback, |
312 | 353 title=_("sharing folder"), |
354 message=_("can't share folder: {msg}"))) | |
192 | 355 |
198
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
356 def share(self, menu): |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
357 item = self.menu_item |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
358 self.clear_menu() |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
359 EntitiesSelectorMenu(instructions=SELECT_INSTRUCTIONS, |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
360 callback=partial(self.do_share, item=item)).show() |
60b63c3e63a1
plugin file sharing: use new EntitiesSelectorMenu to select entities which can access shared files
Goffi <goffi@goffi.org>
parents:
196
diff
changeset
|
361 |
192 | 362 def unshare(self, menu): |
363 item = self.menu_item | |
364 self.clear_menu() | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
365 G.host.bridge.fis_unshare_path( |
192 | 366 item.filepath, |
367 self.profile, | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
368 callback=lambda: G.host.add_note( |
312 | 369 _("sharing folder"), |
370 _("{name} is not shared anymore").format(name=item.name)), | |
192 | 371 errback=partial(G.host.errback, |
312 | 372 title=_("sharing folder"), |
373 message=_("can't unshare folder: {msg}"))) | |
192 | 374 |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
375 def file_jingle_request_cb(self, progress_id, item, dest_path): |
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
376 G.host.add_note( |
312 | 377 _("file request"), |
378 _("{name} download started at {dest_path}").format( | |
192 | 379 name = item.name, |
380 dest_path = dest_path)) | |
381 | |
382 def request_item(self, item): | |
383 """Retrieve an item from remote entity | |
384 | |
385 @param item(RemotePathWidget): item to retrieve | |
386 """ | |
387 path, name = os.path.split(item.filepath) | |
388 assert name | |
389 assert self.remote_entity | |
390 extra = {'path': path} | |
391 dest_path = files_utils.get_unique_name(os.path.join(G.host.downloads_dir, name)) | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
392 G.host.bridge.file_jingle_request(str(self.remote_entity), |
328
dddea9684a8e
plugin file sharing: convert `dest_path` to string when sending to bridge:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
393 str(dest_path), |
192 | 394 name, |
312 | 395 '', |
396 '', | |
192 | 397 extra, |
398 self.profile, | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
399 callback=partial(self.file_jingle_request_cb, |
192 | 400 item=item, |
401 dest_path=dest_path), | |
402 errback=partial(G.host.errback, | |
312 | 403 title = _("file request error"), |
404 message = _("can't request file: {msg}"))) | |
192 | 405 |
406 @classmethod | |
407 def shared_path_new(cls, shared_path, name, profile): | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
408 for wid in G.host.get_visible_list(cls): |
192 | 409 if shared_path not in wid.shared_paths: |
410 wid.shared_paths.append(shared_path) | |
411 | |
412 @classmethod | |
413 def shared_path_removed(cls, shared_path, profile): | |
491
203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents:
461
diff
changeset
|
414 for wid in G.host.get_visible_list(cls): |
192 | 415 if shared_path in wid.shared_paths: |
416 wid.shared_paths.remove(shared_path) | |
417 else: | |
312 | 418 log.warning(_("shared path {path} not found in {widget}".format( |
192 | 419 path = shared_path, widget = wid))) |