Mercurial > libervia-desktop-kivy
annotate cagou/plugins/plugin_wid_file_sharing.py @ 406:03554ad70846
common (jidSelector): replace implitict_update mechanism by real-time update:
instead of having the possibility to (de)activate implicit update, real time update of
items is now done.
For now only the notifications and opened chat items are updated in real time.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 12 Feb 2020 20:02:58 +0100 |
parents | f7476818f9fb |
children | 3c9ba4a694ef |
rev | line source |
---|---|
379 | 1 #!/usr/bin/env python3 |
192 | 2 |
3 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client | |
378 | 4 # Copyright (C) 2016-2020 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 |
192 | 23 from sat.core import log as logging |
24 from sat.core import exceptions | |
25 from sat.core.i18n import _ | |
26 from sat.tools.common import files_utils | |
27 from sat_frontends.quick_frontend import quick_widgets | |
28 from sat_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) |
192 | 35 from cagou import G |
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 | |
110 def getMenuChoices(self): | |
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 | |
222 | 150 class FileSharing(quick_widgets.QuickWidget, cagou_widget.CagouWidget, 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) | |
164 cagou_widget.CagouWidget.__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) | |
169 self.headerInputAddExtra(self.mode_btn) | |
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 | |
217
286f14127f61
plugin file sharing: started to limit line to 90 chars as a test
Goffi <goffi@goffi.org>
parents:
214
diff
changeset
|
177 G.host.registerSignal("FISSharedPathNew", |
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") |
286f14127f61
plugin file sharing: started to limit line to 90 chars as a test
Goffi <goffi@goffi.org>
parents:
214
diff
changeset
|
180 G.host.registerSignal("FISSharedPathRemoved", |
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 |
184 G.host.bridge.FISLocalSharesGet(self.profile, | |
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 | |
194
a68c9baa6694
plugin file sharing: use header hint to show current path, and open new path:
Goffi <goffi@goffi.org>
parents:
192
diff
changeset
|
211 def onHeaderInput(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 |
196
519b3a29743c
utils, plugin file sharing: new utils module, with a FilterBehavior:
Goffi <goffi@goffi.org>
parents:
194
diff
changeset
|
215 def onHeaderInputComplete(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 | |
230 def _discoFindByFeaturesCb(self, data): | |
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) |
312 | 260 G.host.addNote(_("missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) |
192 | 261 return |
262 self.host.bridge.discoFindByFeatures( | |
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, |
192 | 264 callback=self._discoFindByFeaturesCb, |
265 errback=partial(G.host.errback, | |
312 | 266 title=_("shared folder error"), |
267 message=_("can't check sharing devices: {msg}"))) | |
192 | 268 |
269 def FISListCb(self, files_data): | |
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 | |
278 def FISListEb(self, failure_): | |
312 | 279 self.remote_dir = '' |
192 | 280 G.host.addNote( |
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) |
423d462ea739
file sharing: catch OS errors while trying to list files on a local dir
Goffi <goffi@goffi.org>
parents:
212
diff
changeset
|
305 G.host.addNote( |
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) | |
327 self.host.bridge.FISList( | |
312 | 328 str(self.remote_entity), |
192 | 329 self.remote_dir, |
330 {}, | |
331 self.profile, | |
332 callback=self.FISListCb, | |
333 errback=self.FISListEb) | |
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 |
192 | 344 G.host.bridge.FISSharePath( |
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, |
349 callback=lambda name: G.host.addNote( | |
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() | |
365 G.host.bridge.FISUnsharePath( | |
366 item.filepath, | |
367 self.profile, | |
368 callback=lambda: G.host.addNote( | |
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 |
375 def fileJingleRequestCb(self, progress_id, item, dest_path): | |
376 G.host.addNote( | |
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)) | |
312 | 392 G.host.bridge.fileJingleRequest(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, | |
399 callback=partial(self.fileJingleRequestCb, | |
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): | |
408 for wid in G.host.getVisibleList(cls): | |
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): | |
414 for wid in G.host.getVisibleList(cls): | |
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))) |