Mercurial > libervia-backend
annotate frontends/src/jp/base.py @ 1265:e3a9ea76de35 frontends_multi_profiles
quick_frontend, primitivus: multi-profiles refactoring part 1 (big commit, sorry :p):
This refactoring allow primitivus to manage correctly several profiles at once, with various other improvments:
- profile_manager can now plug several profiles at once, requesting password when needed. No more profile plug specific method is used anymore in backend, instead a "validated" key is used in actions
- Primitivus widget are now based on a common "PrimitivusWidget" classe which mainly manage the decoration so far
- all widgets are treated in the same way (contactList, Chat, Progress, etc), no more chat_wins specific behaviour
- widgets are created in a dedicated manager, with facilities to react on new widget creation or other events
- quick_frontend introduce a new QuickWidget class, which aims to be as generic and flexible as possible. It can manage several targets (jids or something else), and several profiles
- each widget class return a Hash according to its target. For example if given a target jid and a profile, a widget class return a hash like (target.bare, profile), the same widget will be used for all resources of the same jid
- better management of CHAT_GROUP mode for Chat widgets
- some code moved from Primitivus to QuickFrontend, the final goal is to have most non backend code in QuickFrontend, and just graphic code in subclasses
- no more (un)escapePrivate/PRIVATE_PREFIX
- contactList improved a lot: entities not in roster and special entities (private MUC conversations) are better managed
- resources can be displayed in Primitivus, and their status messages
- profiles are managed in QuickFrontend with dedicated managers
This is work in progress, other frontends are broken. Urwid SàText need to be updated. Most of features of Primitivus should work as before (or in a better way ;))
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 10 Dec 2014 19:00:09 +0100 |
parents | 75025461141f |
children | faa1129559b8 |
rev | line source |
---|---|
0 | 1 #! /usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
4 # jp: a SAT command line tool |
811 | 5 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org) |
0 | 6 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
7 # This program is free software: you can redistribute it and/or modify |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
8 # it under the terms of the GNU Affero General Public License as published by |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
9 # the Free Software Foundation, either version 3 of the License, or |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
10 # (at your option) any later version. |
0 | 11 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
12 # This program is distributed in the hope that it will be useful, |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
15 # GNU Affero General Public License for more details. |
0 | 16 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
17 # You should have received a copy of the GNU Affero General Public License |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
0 | 19 |
771 | 20 from sat.core.i18n import _ |
402
f03688bdb858
jp: use with statement to open fifo
Goffi <goffi@goffi.org>
parents:
401
diff
changeset
|
21 |
0 | 22 global pbar_available |
23 pbar_available = True #checked before using ProgressBar | |
24 | |
25 ### logging ### | |
26 import logging | |
27 from logging import debug, info, error, warning | |
28 logging.basicConfig(level=logging.DEBUG, | |
29 format='%(message)s') | |
30 ### | |
31 | |
32 import sys | |
817 | 33 import locale |
34 import os.path | |
35 import argparse | |
964 | 36 from gi.repository import GLib, GObject |
817 | 37 from glob import iglob |
38 from importlib import import_module | |
1139
75025461141f
move sat.tools.jid to sat_frontends.tools.jid
souliane <souliane@mailoo.org>
parents:
1033
diff
changeset
|
39 from sat_frontends.tools.jid import JID |
627
d207c2186519
core, bridge, jp, quick_frontend: SàT stop more gracefully if bridge can't be initialised:
Goffi <goffi@goffi.org>
parents:
613
diff
changeset
|
40 from sat_frontends.bridge.DBus import DBusBridgeFrontend |
817 | 41 from sat.core import exceptions |
42 import sat_frontends.jp | |
970
2e052998c7eb
jp: using C.APP_URL for application url
Goffi <goffi@goffi.org>
parents:
965
diff
changeset
|
43 from sat_frontends.jp.constants import Const as C |
0 | 44 try: |
817 | 45 import progressbar |
46 except ImportError: | |
47 info (_('ProgressBar not available, please download it at http://pypi.python.org/pypi/progressbar')) | |
48 info (_('Progress bar deactivated\n--\n')) | |
49 progressbar=None | |
50 | |
51 #consts | |
52 prog_name = u"jp" | |
53 description = """This software is a command line tool for XMPP. | |
970
2e052998c7eb
jp: using C.APP_URL for application url
Goffi <goffi@goffi.org>
parents:
965
diff
changeset
|
54 Get the latest version at """ + C.APP_URL |
817 | 55 |
56 copyleft = u"""Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (aka Goffi) | |
57 This program comes with ABSOLUTELY NO WARRANTY; | |
58 This is free software, and you are welcome to redistribute it under certain conditions. | |
59 """ | |
0 | 60 |
61 | |
817 | 62 def unicode_decoder(arg): |
63 # Needed to have unicode strings from arguments | |
64 return arg.decode(locale.getpreferredencoding()) | |
814 | 65 |
0 | 66 |
817 | 67 class Jp(object): |
814 | 68 """ |
69 This class can be use to establish a connection with the | |
70 bridge. Moreover, it should manage a main loop. | |
71 | |
72 To use it, you mainly have to redefine the method run to perform | |
73 specify what kind of operation you want to perform. | |
74 | |
75 """ | |
817 | 76 def __init__(self): |
165
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
77 try: |
817 | 78 self.bridge = DBusBridgeFrontend() |
79 except exceptions.BridgeExceptionNoService: | |
165
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
80 print(_(u"Can't connect to SàT backend, are you sure it's launched ?")) |
627
d207c2186519
core, bridge, jp, quick_frontend: SàT stop more gracefully if bridge can't be initialised:
Goffi <goffi@goffi.org>
parents:
613
diff
changeset
|
81 sys.exit(1) |
864
241f6baa6687
frontends: fix typos, do not use logging in the xmlui tools:
souliane <souliane@mailoo.org>
parents:
823
diff
changeset
|
82 except exceptions.BridgeInitError: |
627
d207c2186519
core, bridge, jp, quick_frontend: SàT stop more gracefully if bridge can't be initialised:
Goffi <goffi@goffi.org>
parents:
613
diff
changeset
|
83 print(_(u"Can't init bridge")) |
165
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
84 sys.exit(1) |
814 | 85 |
817 | 86 self.parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, |
87 description=description) | |
88 | |
89 self._make_parents() | |
90 self.add_parser_options() | |
91 self.subparsers = self.parser.add_subparsers(title=_('Available commands'), dest='subparser_name') | |
92 self._auto_loop = False # when loop is used for internal reasons | |
93 self.need_loop = False # to set by commands when loop is needed | |
94 self._progress_id = None # TODO: manage several progress ids | |
95 self.quit_on_progress_end = True # set to False if you manage yourself exiting, or if you want the user to stop by himself | |
96 | |
97 @property | |
98 def version(self): | |
99 return self.bridge.getVersion() | |
814 | 100 |
817 | 101 @property |
102 def progress_id(self): | |
103 return self._progress_id | |
104 | |
105 @progress_id.setter | |
106 def progress_id(self, value): | |
107 self._progress_id = value | |
108 | |
109 def _make_parents(self): | |
110 self.parents = {} | |
111 | |
112 profile_parent = self.parents['profile'] = argparse.ArgumentParser(add_help=False) | |
113 profile_parent.add_argument("-p", "--profile", action="store", type=str, default='@DEFAULT@', help=_("Use PROFILE profile key (default: %(default)s)")) | |
1033
d87aa6bdb0b4
jp: option '-c' is not longer a flag but a string to define the profile password:
souliane <souliane@mailoo.org>
parents:
971
diff
changeset
|
114 profile_parent.add_argument("-c", "--connect", action="store", type=str, nargs='?', const='', default=None, metavar='PASSWORD', help=_("Connect the profile before doing anything else")) |
817 | 115 |
116 progress_parent = self.parents['progress'] = argparse.ArgumentParser(add_help=False) | |
117 if progressbar: | |
823
300b4de701a6
jp: short option for progress is now -P instead of -g, so -g can be used for groups
Goffi <goffi@goffi.org>
parents:
817
diff
changeset
|
118 progress_parent.add_argument("-P", "--progress", action="store_true", help=_("Show progress bar")) |
0 | 119 |
817 | 120 def add_parser_options(self): |
121 self.parser.add_argument('--version', action='version', version=("%(name)s %(version)s %(copyleft)s" % {'name': prog_name, 'version': self.version, 'copyleft': copyleft})) | |
122 | |
123 def import_commands(self): | |
124 """ Automaticaly import commands to jp | |
125 looks from modules names cmd_*.py in jp path and import them | |
126 | |
127 """ | |
128 path = os.path.dirname(sat_frontends.jp.__file__) | |
129 modules = (os.path.splitext(module)[0] for module in map(os.path.basename, iglob(os.path.join(path, "cmd_*.py")))) | |
130 for module_name in modules: | |
131 module = import_module("sat_frontends.jp."+module_name) | |
132 try: | |
133 self.import_command_module(module) | |
134 except ImportError: | |
135 continue | |
0 | 136 |
817 | 137 def import_command_module(self, module): |
138 """ Add commands from a module to jp | |
139 @param module: module containing commands | |
140 | |
141 """ | |
142 try: | |
143 for classname in module.__commands__: | |
144 cls = getattr(module, classname) | |
145 except AttributeError: | |
146 warning(_("Invalid module %s") % module) | |
147 raise ImportError | |
148 cls(self) | |
149 | |
150 | |
151 def run(self, args=None): | |
152 self.args = self.parser.parse_args(args) | |
153 self.args.func() | |
154 if self.need_loop or self._auto_loop: | |
155 self._start_loop() | |
156 | |
157 def _start_loop(self): | |
898
9720d3d0a764
jp: updated main loop to gobject 3
Matteo Cypriani <mcy@lm7.fr>
parents:
864
diff
changeset
|
158 self.loop = GLib.MainLoop() |
814 | 159 try: |
160 self.loop.run() | |
161 except KeyboardInterrupt: | |
162 info(_("User interruption: good bye")) | |
0 | 163 |
817 | 164 def stop_loop(self): |
165 try: | |
166 self.loop.quit() | |
167 except AttributeError: | |
168 pass | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
169 |
817 | 170 def quit(self, errcode=0): |
171 self.stop_loop() | |
172 if errcode: | |
173 sys.exit(errcode) | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
174 |
814 | 175 def check_jids(self, jids): |
176 """Check jids validity, transform roster name to corresponding jids | |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
177 |
817 | 178 @param profile: profile name |
179 @param jids: list of jids | |
180 @return: List of jids | |
181 | |
814 | 182 """ |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
183 names2jid = {} |
493
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
184 nodes2jid = {} |
393 | 185 |
814 | 186 for contact in self.bridge.getContacts(self.profile): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
187 _jid, attr, groups = contact |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
188 if attr.has_key("name"): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
189 names2jid[attr["name"].lower()] = _jid |
493
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
190 nodes2jid[JID(_jid).node.lower()] = _jid |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
191 |
817 | 192 def expand_jid(jid): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
193 _jid = jid.lower() |
493
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
194 if _jid in names2jid: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
195 expanded = names2jid[_jid] |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
196 elif _jid in nodes2jid: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
197 expanded = nodes2jid[_jid] |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
198 else: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
199 expanded = jid |
965 | 200 return expanded.decode('utf-8') |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
201 |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
202 def check(jid): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
203 if not jid.is_valid: |
814 | 204 error (_("%s is not a valid JID !"), jid) |
817 | 205 self.quit(1) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
206 |
814 | 207 dest_jids=[] |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
208 try: |
814 | 209 for i in range(len(jids)): |
817 | 210 dest_jids.append(expand_jid(jids[i])) |
814 | 211 check(dest_jids[i]) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
212 except AttributeError: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
213 pass |
0 | 214 |
814 | 215 return dest_jids |
0 | 216 |
817 | 217 def connect_profile(self, callback): |
218 """ Check if the profile is connected | |
219 @param callback: method to call when profile is connected | |
220 @exit: - 1 when profile is not connected and --connect is not set | |
221 - 1 when the profile doesn't exists | |
222 - 1 when there is a connection error | |
223 """ | |
224 # FIXME: need better exit codes | |
225 | |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
970
diff
changeset
|
226 def cant_connect(failure): |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
970
diff
changeset
|
227 error(_(u"Can't connect profile [%s]") % failure) |
817 | 228 self.quit(1) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
229 |
817 | 230 self.profile = self.bridge.getProfileName(self.args.profile) |
0 | 231 |
817 | 232 if not self.profile: |
233 error(_("The profile [%s] doesn't exist") % self.args.profile) | |
234 self.quit(1) | |
235 | |
1033
d87aa6bdb0b4
jp: option '-c' is not longer a flag but a string to define the profile password:
souliane <souliane@mailoo.org>
parents:
971
diff
changeset
|
236 if self.args.connect is not None: # if connection is asked, we connect the profile |
d87aa6bdb0b4
jp: option '-c' is not longer a flag but a string to define the profile password:
souliane <souliane@mailoo.org>
parents:
971
diff
changeset
|
237 self.bridge.asyncConnect(self.profile, self.args.connect, lambda dummy: callback(), cant_connect) |
817 | 238 self._auto_loop = True |
814 | 239 return |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
240 |
817 | 241 elif not self.bridge.isConnected(self.profile): |
242 error(_(u"Profile [%(profile)s] is not connected, please connect it before using jp, or use --connect option") % { "profile": self.profile }) | |
243 self.quit(1) | |
0 | 244 |
817 | 245 callback() |
246 | |
247 def get_full_jid(self, param_jid): | |
248 """Return the full jid if possible (add last resource when find a bare jid)""" | |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
249 _jid = JID(param_jid) |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
250 if not _jid.resource: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
251 #if the resource is not given, we try to add the last known resource |
817 | 252 last_resource = self.bridge.getLastResource(param_jid, self.profile) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
253 if last_resource: |
688
f7878ad3c846
tools: renamed tools.jid.JID attribute "short" to "bare"
souliane <souliane@mailoo.org>
parents:
657
diff
changeset
|
254 return "%s/%s" % (_jid.bare, last_resource) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
255 return param_jid |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
256 |
817 | 257 def watch_progress(self): |
258 self.pbar = None | |
898
9720d3d0a764
jp: updated main loop to gobject 3
Matteo Cypriani <mcy@lm7.fr>
parents:
864
diff
changeset
|
259 GObject.timeout_add(10, self._progress_cb) |
0 | 260 |
817 | 261 def _progress_cb(self): |
262 if self.progress_id: | |
263 data = self.bridge.getProgress(self.progress_id, self.profile) | |
264 if data: | |
265 if not data['position']: | |
266 data['position'] = '0' | |
267 if not self.pbar: | |
268 #first answer, we must construct the bar | |
269 self.pbar = progressbar.ProgressBar(int(data['size']), | |
270 [_("Progress: "),progressbar.Percentage(), | |
271 " ", | |
272 progressbar.Bar(), | |
273 " ", | |
274 progressbar.FileTransferSpeed(), | |
275 " ", | |
276 progressbar.ETA()]) | |
277 self.pbar.start() | |
278 | |
279 self.pbar.update(int(data['position'])) | |
280 | |
281 elif self.pbar: | |
282 self.pbar.finish() | |
283 if self.quit_on_progress_end: | |
284 self.quit() | |
285 return False | |
286 | |
287 return True | |
814 | 288 |
289 | |
817 | 290 class CommandBase(object): |
814 | 291 |
817 | 292 def __init__(self, host, name, use_profile=True, use_progress=False, help=None, **kwargs): |
293 """ Initialise CommandBase | |
294 @param host: Jp instance | |
295 @param name: name of the new command | |
296 @param use_profile: if True, add profile selection/connection commands | |
297 @param use_progress: if True, add progress bar activation commands | |
298 @param help: help message to display | |
299 @param **kwargs: args passed to ArgumentParser | |
300 | |
814 | 301 """ |
817 | 302 try: # If we have subcommands, host is a CommandBase and we need to use host.host |
303 self.host = host.host | |
304 except AttributeError: | |
305 self.host = host | |
306 | |
307 parents = kwargs.setdefault('parents', set()) | |
308 if use_profile: | |
309 #self.host.parents['profile'] is an ArgumentParser with profile connection arguments | |
310 parents.add(self.host.parents['profile']) | |
311 if use_progress: | |
312 parents.add(self.host.parents['progress']) | |
313 | |
314 self.parser = host.subparsers.add_parser(name, help=help, **kwargs) | |
315 if hasattr(self, "subcommands"): | |
316 self.subparsers = self.parser.add_subparsers() | |
317 else: | |
318 self.parser.set_defaults(func=self.run) | |
319 self.add_parser_options() | |
320 | |
321 @property | |
322 def args(self): | |
323 return self.host.args | |
324 | |
325 @property | |
326 def need_loop(self): | |
327 return self.host.need_loop | |
328 | |
329 @need_loop.setter | |
330 def need_loop(self, value): | |
331 self.host.need_loop = value | |
332 | |
333 @property | |
334 def profile(self): | |
335 return self.host.profile | |
336 | |
337 @property | |
338 def progress_id(self): | |
339 return self.host.progress_id | |
814 | 340 |
817 | 341 @progress_id.setter |
342 def progress_id(self, value): | |
343 self.host.progress_id = value | |
344 | |
345 def add_parser_options(self): | |
346 try: | |
347 subcommands = self.subcommands | |
348 except AttributeError: | |
349 # We don't have subcommands, the class need to implements add_parser_options | |
350 raise NotImplementedError | |
351 | |
352 # now we add subcommands to ourself | |
353 for cls in subcommands: | |
354 cls(self) | |
814 | 355 |
817 | 356 def run(self): |
357 try: | |
358 if self.args.profile: | |
359 self.host.connect_profile(self.connected) | |
360 except AttributeError: | |
361 # the command doesn't need to connect profile | |
362 pass | |
363 try: | |
364 if self.args.progress: | |
365 self.host.watch_progress() | |
366 except AttributeError: | |
367 # the command doesn't use progress bar | |
368 pass | |
369 | |
370 def connected(self): | |
371 if not self.need_loop: | |
372 self.host.stop_loop() | |
373 | |
374 | |
375 class CommandAnswering(CommandBase): | |
376 #FIXME: temp, will be refactored when progress_bar/confirmations will be refactored | |
377 | |
378 def _ask_confirmation(self, confirm_id, confirm_type, data, profile): | |
379 """ Callback used for file transfer, accept files depending on parameters""" | |
538
2c4016921403
core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles
Goffi <goffi@goffi.org>
parents:
493
diff
changeset
|
380 if profile != self.profile: |
2c4016921403
core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles
Goffi <goffi@goffi.org>
parents:
493
diff
changeset
|
381 debug("Ask confirmation ignored: not our profile") |
2c4016921403
core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles
Goffi <goffi@goffi.org>
parents:
493
diff
changeset
|
382 return |
817 | 383 if confirm_type == self.confirm_type: |
384 if self.dest_jids and not JID(data['from']).bare in [JID(_jid).bare for _jid in self.dest_jids()]: | |
0 | 385 return #file is not sent by a filtered jid |
386 else: | |
817 | 387 self.ask(data, confirm_id) |
0 | 388 |
814 | 389 def ask(self): |
390 """ | |
391 The return value is used to answer to the bridge. | |
817 | 392 @return: bool or dict |
814 | 393 """ |
394 raise NotImplementedError | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
395 |
817 | 396 def connected(self): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
397 """Auto reply to confirmations requests""" |
817 | 398 self.need_loop = True |
399 super(CommandAnswering, self).connected() | |
400 # we watch confirmation signals | |
401 self.host.bridge.register("ask_confirmation", self._ask_confirmation) | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
402 |
542
3eeb6c865e4d
frontends: incoming files transfer management:
Goffi <goffi@goffi.org>
parents:
538
diff
changeset
|
403 #and we ask those we have missed |
817 | 404 for confirm_id, confirm_type, data in self.host.bridge.getWaitingConf(self.profile): |
405 self._ask_confirmation(confirm_id, confirm_type, data, self.profile) |