Mercurial > libervia-backend
comparison frontends/src/jp/jp @ 223:86d249b6d9b7
Files reorganisation
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 29 Dec 2010 01:06:29 +0100 |
parents | frontends/jp/jp@1438a1337732 |
children | fd9b7834d98a |
comparison
equal
deleted
inserted
replaced
222:3198bfd66daa | 223:86d249b6d9b7 |
---|---|
1 #! /usr/bin/python | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 jp: a SAT command line tool | |
6 Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org) | |
7 | |
8 This program is free software: you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation, either version 3 of the License, or | |
11 (at your option) any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 """ | |
21 | |
22 #consts | |
23 name = u"jp" | |
24 about = name+u""" v%s (c) Jérôme Poisson (aka Goffi) 2009, 2010 | |
25 | |
26 --- | |
27 """+name+u""" Copyright (C) 2009, 2010 Jérôme Poisson (aka Goffi) | |
28 This program comes with ABSOLUTELY NO WARRANTY; | |
29 This is free software, and you are welcome to redistribute it | |
30 under certain conditions. | |
31 --- | |
32 | |
33 This software is a command line tool for jabber | |
34 Get the latest version at http://www.goffi.org | |
35 """ | |
36 | |
37 global pbar_available | |
38 pbar_available = True #checked before using ProgressBar | |
39 | |
40 ### logging ### | |
41 import logging | |
42 from logging import debug, info, error, warning | |
43 logging.basicConfig(level=logging.DEBUG, | |
44 format='%(message)s') | |
45 ### | |
46 | |
47 import gettext | |
48 gettext.install('jp', "i18n", unicode=True) | |
49 | |
50 import sys | |
51 import os | |
52 from os.path import abspath, basename, dirname | |
53 from optparse import OptionParser | |
54 import pdb | |
55 from tools.jid import JID | |
56 import gobject | |
57 from sat_bridge_frontend.DBus import DBusBridgeFrontend,BridgeExceptionNoService | |
58 import tarfile | |
59 try: | |
60 from progressbar import ProgressBar, Percentage, Bar, ETA, FileTransferSpeed | |
61 except ImportError, e: | |
62 info (_('ProgressBar not available, please download it at http://pypi.python.org/pypi/progressbar')) | |
63 info (_('Progress bar deactivated\n--\n')) | |
64 pbar_available=False | |
65 | |
66 | |
67 | |
68 | |
69 class JP(): | |
70 def __init__(self): | |
71 try: | |
72 self.bridge=DBusBridgeFrontend() | |
73 except BridgeExceptionNoService: | |
74 print(_(u"Can't connect to SàT backend, are you sure it's launched ?")) | |
75 import sys | |
76 sys.exit(1) | |
77 self.transfert_id = None | |
78 | |
79 def check_options(self): | |
80 """Check command line options""" | |
81 usage=_(""" | |
82 %prog [options] [FILE1 FILE2 ...] JID | |
83 %prog -w [options] [JID1 JID2 ...] | |
84 | |
85 %prog --help for options list | |
86 """) | |
87 version = unicode(self.bridge.getVersion()) | |
88 parser = OptionParser(usage=usage,version=about % version) | |
89 | |
90 parser.add_option("-p", "--profile", action="store", type="string", default='@DEFAULT@', | |
91 help=_("Use PROFILE profile key (default: %default)")) | |
92 parser.add_option("-b", "--bz2", action="store_true", default=False, | |
93 help=_("Make a bzip2 tarball")) | |
94 parser.add_option("-w", "--wait-file", action="store_true", default=False, | |
95 help=_("Wait for a file to be sent by a contact")) | |
96 parser.add_option("-m", "--multiple", action="store_true", default=False, | |
97 help=_("Accept multiple files (you'll have to stop manually)")) | |
98 parser.add_option("-f", "--force", action="store_true", default=False, | |
99 help=_("Force overwritting of existing files")) | |
100 parser.add_option("-g", "--progress", action="store_true", default=False, | |
101 help=_("Show progress bar")) | |
102 parser.add_option("-s", "--separate", action="store_true", default=False, | |
103 help=_("Separate xmpp messages: send one message per line instead of one message alone.")) | |
104 parser.add_option("-n", "--new-line", action="store_true", default=False, | |
105 help=_("Add a new line at the beginning of the input (usefull for ascii art ;))")) | |
106 | |
107 (self.options, args) = parser.parse_args() | |
108 | |
109 if len(args) < 1 and not self.options.wait_file: | |
110 parser.error(_("You must specify the destination JID (Jabber ID)").encode('utf-8')) | |
111 | |
112 if self.options.wait_file: | |
113 #several jid | |
114 self.dest_jids = args | |
115 else: | |
116 #one dest_jid, other args are files | |
117 self.dest_jid = JID(args[-1]) | |
118 if not self.dest_jid.is_valid: | |
119 error (_("%s is not a valid JID !"), self.dest_jid) | |
120 exit(1) | |
121 self.files = args[:-1] | |
122 | |
123 if not pbar_available and self.options.progress: | |
124 self.options.progress = False | |
125 error (_("Option progress is not available, deactivated.")) | |
126 | |
127 if self.options.progress or self.options.wait_file: | |
128 self.start_loop = True #We have to use loop for these options | |
129 else: | |
130 self.start_loop = False | |
131 | |
132 | |
133 return args | |
134 | |
135 def check_jabber_status(self): | |
136 """Check that jabber status is allright""" | |
137 | |
138 self.profile = self.bridge.getProfileName(self.options.profile) | |
139 if not self.profile: | |
140 error(_("The profile asked doesn't exist")) | |
141 exit(1) | |
142 | |
143 if not self.bridge.isConnected(self.profile): | |
144 error(_(u"SàT is not conneted, please connect before using jp")) | |
145 exit(1) | |
146 | |
147 | |
148 def send_stdin(self): | |
149 """Send incomming data on stdin to jabber contact""" | |
150 header = "\n" if self.options.new_line else "" | |
151 | |
152 if self.options.separate: #we send stdin in several messages | |
153 if header: | |
154 self.bridge.sendMessage(self.dest_jid, header, profile_key=self.profile) | |
155 while (True): | |
156 line = sys.stdin.readline() | |
157 if not line: | |
158 break | |
159 self.bridge.sendMessage(self.dest_jid, line.replace("\n",""), profile_key=self.profile) | |
160 else: | |
161 self.bridge.sendMessage(self.dest_jid, header + "".join(sys.stdin.readlines()), profile_key=self.profile) | |
162 | |
163 def send_files(self): | |
164 """Send files to jabber contact""" | |
165 | |
166 for file in self.files: | |
167 if not os.path.exists(file): | |
168 error (_("File [%s] doesn't exist !") % file) | |
169 exit(1) | |
170 if not self.options.bz2 and os.path.isdir(file): | |
171 error (_("[%s] is a dir ! Please send files inside or use compression") % file) | |
172 exit(1) | |
173 | |
174 if self.options.bz2: | |
175 tmpfile = (basename(self.files[0]) or basename(dirname(self.files[0])) ) + '.tar.bz2' #FIXME: tmp, need an algorithm to find a good name/path | |
176 if os.path.exists(tmpfile): | |
177 error (_("tmp file (%s) already exists ! Please remove it"), tmpfile) | |
178 exit(1) | |
179 warning(_("bz2 is an experimental option at an early dev stage, use with caution")) | |
180 #FIXME: check free space, writting perm, tmp dir, filename (watch for OS used) | |
181 info(_("Starting compression, please wait...")) | |
182 sys.stdout.flush() | |
183 bz2=tarfile.open(tmpfile, "w:bz2") | |
184 for file in self.files: | |
185 info(_("Adding %s"), file) | |
186 bz2.add(file) | |
187 bz2.close() | |
188 info(_("OK !")) | |
189 path = abspath(tmpfile) | |
190 self.transfert_id = self.bridge.sendFile(self.dest_jid, path, profile_key=self.profile) | |
191 else: | |
192 for file in self.files: | |
193 path = abspath(file) | |
194 self.transfert_id = self.bridge.sendFile(self.dest_jid, path, profile_key=self.profile) #FIXME: show progress only for last transfert_id | |
195 | |
196 #TODO: manage ProgressBar | |
197 | |
198 def askConfirmation(self, type, id, data): | |
199 """CB used for file transfert, accept files depending on parameters""" | |
200 answer_data={} | |
201 if type == "FILE_TRANSFERT": | |
202 if self.dest_jids and not data['from'] in self.dest_jids: | |
203 return #file is not sent by a filtered jid | |
204 | |
205 answer_data["dest_path"] = os.getcwd()+'/'+data['filename'] | |
206 | |
207 if self.options.force or not os.path.exists(answer_data["dest_path"]): | |
208 self.bridge.confirmationAnswer(id, True, answer_data) | |
209 info(_("Accepted file [%(filename)s] from %(sender)s") % {'filename':data['filename'], 'sender':data['from']}) | |
210 self.transfert_id = id | |
211 else: | |
212 self.bridge.confirmationAnswer(id, False, answer_data) | |
213 warning(_("Refused file [%(filename)s] from %(sender)s: a file with the same name already exist") % {'filename':data['filename'], 'sender':data['from']}) | |
214 | |
215 | |
216 if not self.options.multiple and not self.options.progress: | |
217 #we just accept one file | |
218 self.loop.quit() | |
219 | |
220 def actionResult(self, type, id, data): | |
221 #FIXME | |
222 info (_("FIXME: actionResult not implemented")) | |
223 | |
224 def wait_file(self): | |
225 """Wait for a file and write it on local dir""" | |
226 self.bridge.register("askConfirmation", self.askConfirmation, "request") | |
227 | |
228 def progressCB(self): | |
229 if self.transfert_id: | |
230 data = self.bridge.getProgress(self.transfert_id) | |
231 if data: | |
232 if not data['position']: | |
233 data['position'] = '0' | |
234 if not self.pbar: | |
235 #first answer, we must construct the bar | |
236 self.pbar = ProgressBar(int(data['size']),[_("Progress: "),Percentage()," ",Bar()," ",FileTransferSpeed()," ",ETA()]) | |
237 self.pbar.start() | |
238 | |
239 self.pbar.update(int(data['position'])) | |
240 elif self.pbar: | |
241 self.pbar.finish() | |
242 if not self.options.multiple: | |
243 self.loop.quit() | |
244 return False | |
245 | |
246 return True | |
247 | |
248 def go(self): | |
249 self.check_options() | |
250 self.check_jabber_status() | |
251 if self.options.wait_file: | |
252 self.wait_file() | |
253 else: | |
254 if not self.files: #we send message only if there are no files to send | |
255 self.send_stdin() | |
256 else: | |
257 self.send_files() | |
258 | |
259 if self.start_loop: | |
260 self.loop = gobject.MainLoop() | |
261 if self.options.progress: | |
262 self.pbar = None | |
263 gobject.timeout_add(10, self.progressCB) | |
264 try: | |
265 self.loop.run() | |
266 except KeyboardInterrupt: | |
267 info(_("User interruption: good bye")) | |
268 | |
269 | |
270 if __name__ == "__main__": | |
271 jp = JP() | |
272 jp.go() |