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