Mercurial > libervia-backend
annotate frontends/src/jp/base.py @ 814:59c7bc51c323
jp: refactoring using ArgParse
author | Dal <kedals0@gmail.com> |
---|---|
date | Wed, 05 Feb 2014 14:35:26 +0100 |
parents | frontends/src/jp/jp@1fe00f0c9a91 |
children | c39117d00f35 |
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 |
402
f03688bdb858
jp: use with statement to open fifo
Goffi <goffi@goffi.org>
parents:
401
diff
changeset
|
20 from __future__ import with_statement |
771 | 21 from sat.core.i18n import _ |
402
f03688bdb858
jp: use with statement to open fifo
Goffi <goffi@goffi.org>
parents:
401
diff
changeset
|
22 |
0 | 23 #consts |
191 | 24 name = u"jp" |
814 | 25 about = name+u""" v%s (c) Jérôme Poisson (aka Goffi) 2009, 2010, 2011, 2012, 2013, 2014 |
0 | 26 |
27 --- | |
811 | 28 """+name+u""" Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (aka Goffi) |
0 | 29 This program comes with ABSOLUTELY NO WARRANTY; |
30 This is free software, and you are welcome to redistribute it | |
31 under certain conditions. | |
32 --- | |
33 | |
34 This software is a command line tool for jabber | |
35 Get the latest version at http://www.goffi.org | |
36 """ | |
37 | |
38 global pbar_available | |
39 pbar_available = True #checked before using ProgressBar | |
40 | |
41 ### logging ### | |
42 import logging | |
43 from logging import debug, info, error, warning | |
44 logging.basicConfig(level=logging.DEBUG, | |
45 format='%(message)s') | |
46 ### | |
47 | |
48 import sys | |
49 import os | |
50 from os.path import abspath, basename, dirname | |
814 | 51 from argparse import ArgumentParser |
236 | 52 from sat.tools.jid import JID |
0 | 53 import gobject |
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
|
54 from sat_frontends.bridge.DBus import DBusBridgeFrontend |
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
|
55 from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError |
601
a4f6f78f0620
jp, core: jp's clean_ustr moved to a new general utils module
Goffi <goffi@goffi.org>
parents:
588
diff
changeset
|
56 from sat.tools.utils import clean_ustr |
0 | 57 import tarfile |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
58 import tempfile |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
59 import shutil |
0 | 60 try: |
61 from progressbar import ProgressBar, Percentage, Bar, ETA, FileTransferSpeed | |
62 except ImportError, e: | |
70 | 63 info (_('ProgressBar not available, please download it at http://pypi.python.org/pypi/progressbar')) |
64 info (_('Progress bar deactivated\n--\n')) | |
0 | 65 pbar_available=False |
66 | |
67 | |
814 | 68 #version = unicode(self.bridge.getVersion()) |
69 version = "undefined" | |
70 parser = ArgumentParser() | |
71 parser.add_argument('--version', action='version', version=about % version) | |
72 subparser = parser.add_subparsers(dest='subparser_name') | |
73 # File managment | |
74 | |
0 | 75 |
76 | |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
587
diff
changeset
|
77 class JP(object): |
814 | 78 """ |
79 This class can be use to establish a connection with the | |
80 bridge. Moreover, it should manage a main loop. | |
81 | |
82 To use it, you mainly have to redefine the method run to perform | |
83 specify what kind of operation you want to perform. | |
84 | |
85 """ | |
86 def __init__(self, start_mainloop = False): | |
165
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
87 try: |
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
88 self.bridge=DBusBridgeFrontend() |
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
89 except BridgeExceptionNoService: |
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
90 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
|
91 sys.exit(1) |
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
|
92 except BridgeInitError: |
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
|
93 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
|
94 sys.exit(1) |
814 | 95 |
96 self._start_loop = start_mainloop | |
97 | |
98 def run(self): | |
99 raise NotImplementedError | |
0 | 100 |
814 | 101 def _run(self): |
102 """Call run and lauch a loop if needed""" | |
103 print "You are connected!" | |
104 self.run() | |
105 if self._start_loop: | |
106 print "Exiting loop..." | |
107 self.loop.quit() | |
0 | 108 |
814 | 109 def _loop_start(self): |
110 self.loop = gobject.MainLoop() | |
111 try: | |
112 self.loop.run() | |
113 except KeyboardInterrupt: | |
114 info(_("User interruption: good bye")) | |
0 | 115 |
814 | 116 def start_mainloop(self): |
117 self._start_loop = True | |
0 | 118 |
814 | 119 def go(self): |
120 self.run() | |
121 if self._start_loop: | |
122 self._loop_start() | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
123 |
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
124 |
814 | 125 class JPWithProfile(JP): |
126 """Manage a bridge (inherit from :class:`JP`), but it also adds | |
127 profile managment, ie, connection to the profile. | |
657 | 128 |
814 | 129 Moreover, some useful methods are predefined such as |
130 :py:meth:`check_jids`. The connection to XMPP is automatically | |
131 managed. | |
132 """ | |
657 | 133 |
814 | 134 def __init__(self, profile_name, start_mainloop = False): |
135 JP.__init__(self, start_mainloop) | |
136 self.profile_name = profile_name | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
137 |
814 | 138 def check_jids(self, jids): |
139 """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
|
140 |
814 | 141 :param profile: A profile name |
142 :param jids: A list of jids | |
143 :rtype: A list of jids | |
144 """ | |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
145 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
|
146 nodes2jid = {} |
393 | 147 |
814 | 148 for contact in self.bridge.getContacts(self.profile): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
149 _jid, attr, groups = contact |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
150 if attr.has_key("name"): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
151 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
|
152 nodes2jid[JID(_jid).node.lower()] = _jid |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
153 |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
154 def expandJid(jid): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
155 _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
|
156 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
|
157 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
|
158 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
|
159 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
|
160 else: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
161 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
|
162 return unicode(expanded) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
163 |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
164 def check(jid): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
165 if not jid.is_valid: |
814 | 166 error (_("%s is not a valid JID !"), jid) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
167 exit(1) |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
168 |
814 | 169 dest_jids=[] |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
170 try: |
814 | 171 for i in range(len(jids)): |
172 dest_jids.append(expandJid(jids[i])) | |
173 check(dest_jids[i]) | |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
174 except AttributeError: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
175 pass |
0 | 176 |
814 | 177 return dest_jids |
0 | 178 |
814 | 179 def check_jabber_connection(self): |
180 """Check that jabber status is allright""" | |
181 def cantConnect(arg): | |
182 print arg | |
183 error(_(u"Can't connect profile")) | |
184 exit(1) | |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
185 |
814 | 186 self.profile = self.bridge.getProfileName(self.profile_name) |
187 if not self.profile: | |
188 error(_("The profile asked doesn't exist")) | |
189 exit(1) | |
0 | 190 |
814 | 191 if self.bridge.isConnected(self.profile): |
192 print "Already connected" | |
0 | 193 else: |
814 | 194 self._start_loop = True |
195 self.bridge.asyncConnect(self.profile, self._run, cantConnect) | |
196 return | |
197 self.run() | |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
198 |
0 | 199 |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
200 def _getFullJid(self, param_jid): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
201 """Return the full jid if possible (add last resource when find a bare jid""" |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
202 _jid = JID(param_jid) |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
203 if not _jid.resource: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
204 #if the resource is not given, we try to add the last known resource |
814 | 205 last_resource = self.bridge.getLastResource(param_jid, self.profile_name) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
206 if last_resource: |
688
f7878ad3c846
tools: renamed tools.jid.JID attribute "short" to "bare"
souliane <souliane@mailoo.org>
parents:
657
diff
changeset
|
207 return "%s/%s" % (_jid.bare, last_resource) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
208 return param_jid |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
209 |
814 | 210 def go(self): |
211 self.check_jabber_connection() | |
212 if self._start_loop: | |
213 self._loop_start() | |
0 | 214 |
814 | 215 |
216 | |
217 class JPAsk(JPWithProfile): | |
218 def confirm_type(self): | |
219 """Must return a string containing the confirm type. For instance, | |
220 FILE_TRANSFER or PIPE_TRANSFER, etc. | |
221 | |
222 :rtype: str | |
223 """ | |
224 raise NotImplemented | |
225 | |
226 def dest_jids(self): | |
227 return None | |
228 | |
229 def _askConfirmation(self, confirm_id, confirm_type, data, profile): | |
538
2c4016921403
core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles
Goffi <goffi@goffi.org>
parents:
493
diff
changeset
|
230 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
|
231 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
|
232 return |
814 | 233 if confirm_type == self.confirm_type(): |
234 self._confirm_id = confirm_id | |
235 if self.dest_jids() and not JID(data['from']).bare in [JID(_jid).bare for _jid in self.dest_jids()]: | |
0 | 236 return #file is not sent by a filtered jid |
237 else: | |
814 | 238 self.ask(data) |
0 | 239 |
814 | 240 def ask(self): |
241 """ | |
242 The return value is used to answer to the bridge. | |
243 :rtype: (bool, dict) | |
244 """ | |
245 raise NotImplementedError | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
246 |
814 | 247 def answer(self, accepted, answer_data): |
248 """ | |
249 :param accepted: boolean | |
250 :param aswer_data: dict of answer datas | |
251 """ | |
252 self.bridge.confirmationAnswer(self._confirm_id, False, answer_data, self.profile) | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
253 |
814 | 254 def run(self): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
255 """Auto reply to confirmations requests""" |
542
3eeb6c865e4d
frontends: incoming files transfer management:
Goffi <goffi@goffi.org>
parents:
538
diff
changeset
|
256 #we register incoming confirmation |
814 | 257 self.bridge.register("askConfirmation", self._askConfirmation) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
258 |
542
3eeb6c865e4d
frontends: incoming files transfer management:
Goffi <goffi@goffi.org>
parents:
538
diff
changeset
|
259 #and we ask those we have missed |
3eeb6c865e4d
frontends: incoming files transfer management:
Goffi <goffi@goffi.org>
parents:
538
diff
changeset
|
260 for confirm_id, confirm_type, data in self.bridge.getWaitingConf(self.profile): |
814 | 261 self._askConfirmation(confirm_id, confirm_type, data, self.profile) |
0 | 262 |
263 |