Mercurial > libervia-backend
annotate frontends/src/jp/base.py @ 853:c2f6ada7858f
core (sqlite): automatic database update:
- new Updater class check database consistency (by calculating a hash on the .schema), and updates base if necessary
- database now has a version (1 for current, 0 will be for 0.3's database), for each change this version will be increased
- creation statements and update statements are in the form of dict of dict with tuples. There is a help text at the top of the module to explain how it works
- if we are on a development version, the updater try to update the database automaticaly (without deleting table or columns). The Updater.generateUpdateData method can be used to ease the creation of update data (i.e. the dictionary at the top, see the one for the key 1 for an example).
- if there is an inconsistency, an exception is raised, and a message indicate the SQL statements that should fix the situation.
- well... this is rather complicated, a KISS method would maybe have been better. The future will say if we need to simplify it :-/
- new DatabaseError exception
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 23 Feb 2014 23:30:32 +0100 |
parents | 300b4de701a6 |
children | 241f6baa6687 |
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 | |
36 import gobject | |
37 from glob import iglob | |
38 from importlib import import_module | |
236 | 39 from sat.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 | |
0 | 43 try: |
817 | 44 import progressbar |
45 except ImportError: | |
46 info (_('ProgressBar not available, please download it at http://pypi.python.org/pypi/progressbar')) | |
47 info (_('Progress bar deactivated\n--\n')) | |
48 progressbar=None | |
49 | |
50 #consts | |
51 prog_name = u"jp" | |
52 description = """This software is a command line tool for XMPP. | |
53 Get the latest version at http://sat.goffi.org""" | |
54 | |
55 copyleft = u"""Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (aka Goffi) | |
56 This program comes with ABSOLUTELY NO WARRANTY; | |
57 This is free software, and you are welcome to redistribute it under certain conditions. | |
58 """ | |
0 | 59 |
60 | |
817 | 61 def unicode_decoder(arg): |
62 # Needed to have unicode strings from arguments | |
63 return arg.decode(locale.getpreferredencoding()) | |
814 | 64 |
0 | 65 |
817 | 66 class Jp(object): |
814 | 67 """ |
68 This class can be use to establish a connection with the | |
69 bridge. Moreover, it should manage a main loop. | |
70 | |
71 To use it, you mainly have to redefine the method run to perform | |
72 specify what kind of operation you want to perform. | |
73 | |
74 """ | |
817 | 75 def __init__(self): |
165
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
76 try: |
817 | 77 self.bridge = DBusBridgeFrontend() |
78 except exceptions.BridgeExceptionNoService: | |
165
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
79 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
|
80 sys.exit(1) |
817 | 81 except excpetions.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
|
82 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
|
83 sys.exit(1) |
814 | 84 |
817 | 85 self.parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, |
86 description=description) | |
87 | |
88 self._make_parents() | |
89 self.add_parser_options() | |
90 self.subparsers = self.parser.add_subparsers(title=_('Available commands'), dest='subparser_name') | |
91 self._auto_loop = False # when loop is used for internal reasons | |
92 self.need_loop = False # to set by commands when loop is needed | |
93 self._progress_id = None # TODO: manage several progress ids | |
94 self.quit_on_progress_end = True # set to False if you manage yourself exiting, or if you want the user to stop by himself | |
95 | |
96 @property | |
97 def version(self): | |
98 return self.bridge.getVersion() | |
814 | 99 |
817 | 100 @property |
101 def progress_id(self): | |
102 return self._progress_id | |
103 | |
104 @progress_id.setter | |
105 def progress_id(self, value): | |
106 self._progress_id = value | |
107 | |
108 def _make_parents(self): | |
109 self.parents = {} | |
110 | |
111 profile_parent = self.parents['profile'] = argparse.ArgumentParser(add_help=False) | |
112 profile_parent.add_argument("-p", "--profile", action="store", type=str, default='@DEFAULT@', help=_("Use PROFILE profile key (default: %(default)s)")) | |
113 profile_parent.add_argument("-c", "--connect", action="store_true", help=_("Connect the profile before doing anything else")) | |
114 | |
115 progress_parent = self.parents['progress'] = argparse.ArgumentParser(add_help=False) | |
116 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
|
117 progress_parent.add_argument("-P", "--progress", action="store_true", help=_("Show progress bar")) |
0 | 118 |
817 | 119 def add_parser_options(self): |
120 self.parser.add_argument('--version', action='version', version=("%(name)s %(version)s %(copyleft)s" % {'name': prog_name, 'version': self.version, 'copyleft': copyleft})) | |
121 | |
122 def import_commands(self): | |
123 """ Automaticaly import commands to jp | |
124 looks from modules names cmd_*.py in jp path and import them | |
125 | |
126 """ | |
127 path = os.path.dirname(sat_frontends.jp.__file__) | |
128 modules = (os.path.splitext(module)[0] for module in map(os.path.basename, iglob(os.path.join(path, "cmd_*.py")))) | |
129 for module_name in modules: | |
130 module = import_module("sat_frontends.jp."+module_name) | |
131 try: | |
132 self.import_command_module(module) | |
133 except ImportError: | |
134 continue | |
0 | 135 |
817 | 136 def import_command_module(self, module): |
137 """ Add commands from a module to jp | |
138 @param module: module containing commands | |
139 | |
140 """ | |
141 try: | |
142 for classname in module.__commands__: | |
143 cls = getattr(module, classname) | |
144 except AttributeError: | |
145 warning(_("Invalid module %s") % module) | |
146 raise ImportError | |
147 cls(self) | |
148 | |
149 | |
150 def run(self, args=None): | |
151 self.args = self.parser.parse_args(args) | |
152 self.args.func() | |
153 if self.need_loop or self._auto_loop: | |
154 self._start_loop() | |
155 | |
156 def _start_loop(self): | |
814 | 157 self.loop = gobject.MainLoop() |
158 try: | |
159 self.loop.run() | |
160 except KeyboardInterrupt: | |
161 info(_("User interruption: good bye")) | |
0 | 162 |
817 | 163 def stop_loop(self): |
164 try: | |
165 self.loop.quit() | |
166 except AttributeError: | |
167 pass | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
168 |
817 | 169 def quit(self, errcode=0): |
170 self.stop_loop() | |
171 if errcode: | |
172 sys.exit(errcode) | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
173 |
814 | 174 def check_jids(self, jids): |
175 """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
|
176 |
817 | 177 @param profile: profile name |
178 @param jids: list of jids | |
179 @return: List of jids | |
180 | |
814 | 181 """ |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
182 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
|
183 nodes2jid = {} |
393 | 184 |
814 | 185 for contact in self.bridge.getContacts(self.profile): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
186 _jid, attr, groups = contact |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
187 if attr.has_key("name"): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
188 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
|
189 nodes2jid[JID(_jid).node.lower()] = _jid |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
190 |
817 | 191 def expand_jid(jid): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
192 _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
|
193 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
|
194 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
|
195 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
|
196 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
|
197 else: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
198 expanded = jid |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
199 return unicode(expanded) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
200 |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
201 def check(jid): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
202 if not jid.is_valid: |
814 | 203 error (_("%s is not a valid JID !"), jid) |
817 | 204 self.quit(1) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
205 |
814 | 206 dest_jids=[] |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
207 try: |
814 | 208 for i in range(len(jids)): |
817 | 209 dest_jids.append(expand_jid(jids[i])) |
814 | 210 check(dest_jids[i]) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
211 except AttributeError: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
212 pass |
0 | 213 |
814 | 214 return dest_jids |
0 | 215 |
817 | 216 def connect_profile(self, callback): |
217 """ Check if the profile is connected | |
218 @param callback: method to call when profile is connected | |
219 @exit: - 1 when profile is not connected and --connect is not set | |
220 - 1 when the profile doesn't exists | |
221 - 1 when there is a connection error | |
222 """ | |
223 # FIXME: need better exit codes | |
224 | |
225 def cant_connect(): | |
814 | 226 error(_(u"Can't connect profile")) |
817 | 227 self.quit(1) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
228 |
817 | 229 self.profile = self.bridge.getProfileName(self.args.profile) |
0 | 230 |
817 | 231 if not self.profile: |
232 error(_("The profile [%s] doesn't exist") % self.args.profile) | |
233 self.quit(1) | |
234 | |
235 if self.args.connect: #if connection is asked, we connect the profile | |
236 self.bridge.asyncConnect(self.profile, callback, cant_connect) | |
237 self._auto_loop = True | |
814 | 238 return |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
239 |
817 | 240 elif not self.bridge.isConnected(self.profile): |
241 error(_(u"Profile [%(profile)s] is not connected, please connect it before using jp, or use --connect option") % { "profile": self.profile }) | |
242 self.quit(1) | |
0 | 243 |
817 | 244 callback() |
245 | |
246 def get_full_jid(self, param_jid): | |
247 """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
|
248 _jid = JID(param_jid) |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
249 if not _jid.resource: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
250 #if the resource is not given, we try to add the last known resource |
817 | 251 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
|
252 if last_resource: |
688
f7878ad3c846
tools: renamed tools.jid.JID attribute "short" to "bare"
souliane <souliane@mailoo.org>
parents:
657
diff
changeset
|
253 return "%s/%s" % (_jid.bare, last_resource) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
254 return param_jid |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
255 |
817 | 256 def watch_progress(self): |
257 self.pbar = None | |
258 gobject.timeout_add(10, self._progress_cb) | |
0 | 259 |
817 | 260 def _progress_cb(self): |
261 if self.progress_id: | |
262 data = self.bridge.getProgress(self.progress_id, self.profile) | |
263 if data: | |
264 if not data['position']: | |
265 data['position'] = '0' | |
266 if not self.pbar: | |
267 #first answer, we must construct the bar | |
268 self.pbar = progressbar.ProgressBar(int(data['size']), | |
269 [_("Progress: "),progressbar.Percentage(), | |
270 " ", | |
271 progressbar.Bar(), | |
272 " ", | |
273 progressbar.FileTransferSpeed(), | |
274 " ", | |
275 progressbar.ETA()]) | |
276 self.pbar.start() | |
277 | |
278 self.pbar.update(int(data['position'])) | |
279 | |
280 elif self.pbar: | |
281 self.pbar.finish() | |
282 if self.quit_on_progress_end: | |
283 self.quit() | |
284 return False | |
285 | |
286 return True | |
814 | 287 |
288 | |
817 | 289 class CommandBase(object): |
814 | 290 |
817 | 291 def __init__(self, host, name, use_profile=True, use_progress=False, help=None, **kwargs): |
292 """ Initialise CommandBase | |
293 @param host: Jp instance | |
294 @param name: name of the new command | |
295 @param use_profile: if True, add profile selection/connection commands | |
296 @param use_progress: if True, add progress bar activation commands | |
297 @param help: help message to display | |
298 @param **kwargs: args passed to ArgumentParser | |
299 | |
814 | 300 """ |
817 | 301 try: # If we have subcommands, host is a CommandBase and we need to use host.host |
302 self.host = host.host | |
303 except AttributeError: | |
304 self.host = host | |
305 | |
306 parents = kwargs.setdefault('parents', set()) | |
307 if use_profile: | |
308 #self.host.parents['profile'] is an ArgumentParser with profile connection arguments | |
309 parents.add(self.host.parents['profile']) | |
310 if use_progress: | |
311 parents.add(self.host.parents['progress']) | |
312 | |
313 self.parser = host.subparsers.add_parser(name, help=help, **kwargs) | |
314 if hasattr(self, "subcommands"): | |
315 self.subparsers = self.parser.add_subparsers() | |
316 else: | |
317 self.parser.set_defaults(func=self.run) | |
318 self.add_parser_options() | |
319 | |
320 @property | |
321 def args(self): | |
322 return self.host.args | |
323 | |
324 @property | |
325 def need_loop(self): | |
326 return self.host.need_loop | |
327 | |
328 @need_loop.setter | |
329 def need_loop(self, value): | |
330 self.host.need_loop = value | |
331 | |
332 @property | |
333 def profile(self): | |
334 return self.host.profile | |
335 | |
336 @property | |
337 def progress_id(self): | |
338 return self.host.progress_id | |
814 | 339 |
817 | 340 @progress_id.setter |
341 def progress_id(self, value): | |
342 self.host.progress_id = value | |
343 | |
344 def add_parser_options(self): | |
345 try: | |
346 subcommands = self.subcommands | |
347 except AttributeError: | |
348 # We don't have subcommands, the class need to implements add_parser_options | |
349 raise NotImplementedError | |
350 | |
351 # now we add subcommands to ourself | |
352 for cls in subcommands: | |
353 cls(self) | |
814 | 354 |
817 | 355 def run(self): |
356 try: | |
357 if self.args.profile: | |
358 self.host.connect_profile(self.connected) | |
359 except AttributeError: | |
360 # the command doesn't need to connect profile | |
361 pass | |
362 try: | |
363 if self.args.progress: | |
364 self.host.watch_progress() | |
365 except AttributeError: | |
366 # the command doesn't use progress bar | |
367 pass | |
368 | |
369 def connected(self): | |
370 if not self.need_loop: | |
371 self.host.stop_loop() | |
372 | |
373 | |
374 class CommandAnswering(CommandBase): | |
375 #FIXME: temp, will be refactored when progress_bar/confirmations will be refactored | |
376 | |
377 def _ask_confirmation(self, confirm_id, confirm_type, data, profile): | |
378 """ 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
|
379 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
|
380 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
|
381 return |
817 | 382 if confirm_type == self.confirm_type: |
383 if self.dest_jids and not JID(data['from']).bare in [JID(_jid).bare for _jid in self.dest_jids()]: | |
0 | 384 return #file is not sent by a filtered jid |
385 else: | |
817 | 386 self.ask(data, confirm_id) |
0 | 387 |
814 | 388 def ask(self): |
389 """ | |
390 The return value is used to answer to the bridge. | |
817 | 391 @return: bool or dict |
814 | 392 """ |
393 raise NotImplementedError | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
394 |
817 | 395 def connected(self): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
396 """Auto reply to confirmations requests""" |
817 | 397 self.need_loop = True |
398 super(CommandAnswering, self).connected() | |
399 # we watch confirmation signals | |
400 self.host.bridge.register("ask_confirmation", self._ask_confirmation) | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
401 |
542
3eeb6c865e4d
frontends: incoming files transfer management:
Goffi <goffi@goffi.org>
parents:
538
diff
changeset
|
402 #and we ask those we have missed |
817 | 403 for confirm_id, confirm_type, data in self.host.bridge.getWaitingConf(self.profile): |
404 self._ask_confirmation(confirm_id, confirm_type, data, self.profile) |