Mercurial > libervia-backend
annotate frontends/jp/jp @ 114:77f48939ad6e
primitivus: added Alert widget
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 01 Jul 2010 18:18:34 +0800 |
parents | cb904fa7de3c |
children | a216dfbb0d50 |
rev | line source |
---|---|
0 | 1 #! /usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 jp: a SAT command line tool | |
57 | 6 Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org) |
0 | 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 = "jp" | |
24 version = "0.0.1" | |
57 | 25 about = name+" v"+version+""" (c) Jérôme Poisson (aka Goffi) 2009, 2010 |
0 | 26 |
27 --- | |
57 | 28 """+name+""" Copyright (C) 2009, 2010 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 | |
70 | 48 import gettext |
49 gettext.install('jp', "i18n", unicode=True) | |
50 | |
0 | 51 import sys |
52 import os | |
53 from os.path import abspath, basename, dirname | |
54 from optparse import OptionParser | |
55 import pdb | |
56 from tools.jid import JID | |
57 import gobject | |
58 from sat_bridge_frontend.DBus import DBusBridgeFrontend | |
59 import tarfile | |
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 | |
68 | |
69 | |
70 class JP(): | |
71 def __init__(self): | |
72 self.bridge=DBusBridgeFrontend() | |
73 self.transfert_id = None | |
74 | |
75 def check_options(self): | |
76 """Check command line options""" | |
70 | 77 usage=_(""" |
0 | 78 %prog [options] [FILE1 FILE2 ...] JID |
79 %prog -w [options] [JID1 JID2 ...] | |
80 | |
81 %prog --help for options list | |
70 | 82 """) |
0 | 83 parser = OptionParser(usage=usage,version=about) |
84 | |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
85 parser.add_option("-p", "--profile", action="store", type="string", default='@DEFAULT@', |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
86 help=_("Use PROFILE profile key")) |
0 | 87 parser.add_option("-b", "--bz2", action="store_true", default=False, |
70 | 88 help=_("Make a bzip2 tarball")) |
0 | 89 parser.add_option("-w", "--wait-file", action="store_true", default=False, |
70 | 90 help=_("Wait for a file to be sent by a contact")) |
0 | 91 parser.add_option("-m", "--multiple", action="store_true", default=False, |
70 | 92 help=_("Accept multiple files (you'll have to stop manually)")) |
0 | 93 parser.add_option("-f", "--force", action="store_true", default=False, |
70 | 94 help=_("Force overwritting of existing files")) |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
95 parser.add_option("-g", "--progress", action="store_true", default=False, |
70 | 96 help=_("Show progress bar")) |
0 | 97 parser.add_option("-s", "--separate", action="store_true", default=False, |
70 | 98 help=_("Separate xmpp messages: send one message per line instead of one message alone.")) |
0 | 99 parser.add_option("-n", "--new-line", action="store_true", default=False, |
70 | 100 help=_("Add a new line at the beginning of the input (usefull for ascii art ;))")) |
0 | 101 |
102 (self.options, args) = parser.parse_args() | |
103 | |
104 if len(args) < 1 and not self.options.wait_file: | |
70 | 105 parser.error(_("You must specify the destination JID (Jabber ID)").encode('utf-8')) |
0 | 106 |
107 if self.options.wait_file: | |
108 #several jid | |
109 self.dest_jids = args | |
110 else: | |
111 #one dest_jid, other args are files | |
112 self.dest_jid = JID(args[-1]) | |
113 if not self.dest_jid.is_valid: | |
70 | 114 error (_("%s is not a valid JID !"), self.dest_jid) |
0 | 115 exit(1) |
116 self.files = args[:-1] | |
117 | |
118 if not pbar_available and self.options.progress: | |
119 self.options.progress = False | |
70 | 120 error (_("Option progress is not available, deactivated.")) |
0 | 121 |
122 if self.options.progress or self.options.wait_file: | |
123 self.start_loop = True #We have to use loop for these options | |
124 else: | |
125 self.start_loop = False | |
126 | |
127 | |
128 return args | |
129 | |
130 def check_jabber_status(self): | |
131 """Check that jabber status is allright""" | |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
132 |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
133 self.profile = self.bridge.getProfileName(self.options.profile) |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
134 if not self.profile: |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
135 error(_("The profile asked doesn't exist")) |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
136 exit(1) |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
137 |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
138 if not self.bridge.isConnected(self.profile): |
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
139 error(_(u"SàT is not conneted, please connect before using jp")) |
0 | 140 exit(1) |
141 | |
142 | |
143 def send_stdin(self): | |
144 """Send incomming data on stdin to jabber contact""" | |
145 header = "\n" if self.options.new_line else "" | |
146 | |
147 if self.options.separate: #we send stdin in several messages | |
148 if header: | |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
149 self.bridge.sendMessage(self.dest_jid, header, profile_key=self.profile) |
0 | 150 while (True): |
151 line = sys.stdin.readline() | |
152 if not line: | |
153 break | |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
154 self.bridge.sendMessage(self.dest_jid, line.replace("\n",""), profile_key=self.profile) |
0 | 155 else: |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
156 self.bridge.sendMessage(self.dest_jid, header + "".join(sys.stdin.readlines()), profile_key=self.profile) |
0 | 157 |
158 def send_files(self): | |
159 """Send files to jabber contact""" | |
160 | |
161 for file in self.files: | |
162 if not os.path.exists(file): | |
70 | 163 error (_("File [%s] doesn't exist !") % file) |
0 | 164 exit(1) |
165 if not self.options.bz2 and os.path.isdir(file): | |
70 | 166 error (_("[%s] is a dir ! Please send files inside or use compression") % file) |
0 | 167 exit(1) |
168 | |
169 if self.options.bz2: | |
170 tmpfile = (basename(self.files[0]) or basename(dirname(self.files[0])) ) + '.tar.bz2' #FIXME: tmp, need an algorithm to find a good name/path | |
171 if os.path.exists(tmpfile): | |
70 | 172 error (_("tmp file (%s) already exists ! Please remove it"), tmpfile) |
0 | 173 exit(1) |
70 | 174 warning(_("bz2 is an experimental option at an early dev stage, use with caution")) |
0 | 175 #FIXME: check free space, writting perm, tmp dir, filename (watch for OS used) |
70 | 176 info(_("Starting compression, please wait...")) |
0 | 177 sys.stdout.flush() |
178 bz2=tarfile.open(tmpfile, "w:bz2") | |
179 for file in self.files: | |
70 | 180 info(_("Adding %s"), file) |
0 | 181 bz2.add(file) |
182 bz2.close() | |
70 | 183 info(_("OK !")) |
0 | 184 path = abspath(tmpfile) |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
185 self.transfert_id = self.bridge.sendFile(self.dest_jid, path, profile_key=self.profile) |
0 | 186 else: |
187 for file in self.files: | |
188 path = abspath(file) | |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
189 self.transfert_id = self.bridge.sendFile(self.dest_jid, path, profile_key=self.profile) #FIXME: show progress only for last transfert_id |
0 | 190 |
191 #TODO: manage ProgressBar | |
192 | |
193 def askConfirmation(self, type, id, data): | |
194 """CB used for file transfert, accept files depending on parameters""" | |
195 answer_data={} | |
196 if type == "FILE_TRANSFERT": | |
197 if self.dest_jids and not data['from'] in self.dest_jids: | |
198 return #file is not sent by a filtered jid | |
199 | |
200 answer_data["dest_path"] = os.getcwd()+'/'+data['filename'] | |
201 | |
202 if self.options.force or not os.path.exists(answer_data["dest_path"]): | |
203 self.bridge.confirmationAnswer(id, True, answer_data) | |
70 | 204 info(_("Accepted file [%(filename)s] from %(sender)s") % {'filename':data['filename'], 'sender':data['from']}) |
0 | 205 self.transfert_id = id |
206 else: | |
207 self.bridge.confirmationAnswer(id, False, answer_data) | |
70 | 208 warning(_("Refused file [%(filename)s] from %(sender)s: a file with the same name already exist") % {'filename':data['filename'], 'sender':data['from']}) |
0 | 209 |
210 | |
211 if not self.options.multiple and not self.options.progress: | |
212 #we just accept one file | |
213 self.loop.quit() | |
214 | |
22
bb72c29f3432
added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
215 def actionResult(self, type, id, data): |
bb72c29f3432
added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents:
0
diff
changeset
|
216 #FIXME |
70 | 217 info (_("FIXME: actionResult not implemented")) |
0 | 218 |
219 def wait_file(self): | |
220 """Wait for a file and write it on local dir""" | |
221 self.bridge.register("askConfirmation", self.askConfirmation, "request") | |
222 | |
223 def progressCB(self): | |
224 if self.transfert_id: | |
225 data = self.bridge.getProgress(self.transfert_id) | |
226 if data: | |
227 if not data['position']: | |
228 data['position'] = '0' | |
229 if not self.pbar: | |
230 #first answer, we must construct the bar | |
70 | 231 self.pbar = ProgressBar(int(data['size']),[_("Progress: "),Percentage()," ",Bar()," ",FileTransferSpeed()," ",ETA()]) |
0 | 232 self.pbar.start() |
233 | |
234 self.pbar.update(int(data['position'])) | |
235 elif self.pbar: | |
236 self.pbar.finish() | |
237 if not self.options.multiple: | |
238 self.loop.quit() | |
239 return False | |
240 | |
241 return True | |
242 | |
243 def go(self): | |
244 self.check_options() | |
245 self.check_jabber_status() | |
246 if self.options.wait_file: | |
247 self.wait_file() | |
248 else: | |
249 if not self.files: #we send message only if there are no files to send | |
250 self.send_stdin() | |
251 else: | |
252 self.send_files() | |
253 | |
254 if self.start_loop: | |
255 self.loop = gobject.MainLoop() | |
256 if self.options.progress: | |
257 self.pbar = None | |
258 gobject.timeout_add(10, self.progressCB) | |
259 try: | |
260 self.loop.run() | |
261 except KeyboardInterrupt: | |
70 | 262 info(_("User interruption: good bye")) |
0 | 263 |
264 | |
265 if __name__ == "__main__": | |
266 jp = JP() | |
267 jp.go() |