Mercurial > libervia-backend
diff frontends/jp/jp @ 0:c4bc297b82f0
sat:
- first public release, initial commit
author | goffi@necton2 |
---|---|
date | Sat, 29 Aug 2009 13:34:59 +0200 |
parents | |
children | bb72c29f3432 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frontends/jp/jp Sat Aug 29 13:34:59 2009 +0200 @@ -0,0 +1,253 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +""" +jp: a SAT command line tool +Copyright (C) 2009 Jérôme Poisson (goffi@goffi.org) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +""" + +#consts +name = "jp" +version = "0.0.1" +about = name+" v"+version+""" (c) Jérôme Poisson (aka Goffi) 2009 + +--- +"""+name+""" Copyright (C) 2009 Jérôme Poisson (aka Goffi) +This program comes with ABSOLUTELY NO WARRANTY; +This is free software, and you are welcome to redistribute it +under certain conditions. +--- + +This software is a command line tool for jabber +Get the latest version at http://www.goffi.org +""" + +global pbar_available +pbar_available = True #checked before using ProgressBar + +### logging ### +import logging +from logging import debug, info, error, warning +logging.basicConfig(level=logging.DEBUG, + format='%(message)s') +### + +import sys +import os +from os.path import abspath, basename, dirname +from optparse import OptionParser +import pdb +from tools.jid import JID +import gobject +from sat_bridge_frontend.DBus import DBusBridgeFrontend +import tarfile +try: + from progressbar import ProgressBar, Percentage, Bar, ETA, FileTransferSpeed +except ImportError, e: + info ('ProgressBar not available, please download it at http://pypi.python.org/pypi/progressbar') + info ('Progress bar deactivated\n--\n') + pbar_available=False + + + + +class JP(): + def __init__(self): + self.bridge=DBusBridgeFrontend() + self.transfert_id = None + + def check_options(self): + """Check command line options""" + usage=""" + %prog [options] [FILE1 FILE2 ...] JID + %prog -w [options] [JID1 JID2 ...] + + %prog --help for options list + """ + parser = OptionParser(usage=usage,version=about) + + parser.add_option("-b", "--bz2", action="store_true", default=False, + help="Make a bzip2 tarball") + parser.add_option("-w", "--wait-file", action="store_true", default=False, + help="Wait for a file to be sent by a contact") + parser.add_option("-m", "--multiple", action="store_true", default=False, + help="Accept multiple files (you'll have to stop manually)") + parser.add_option("-f", "--force", action="store_true", default=False, + help="Force overwritting of existing files") + parser.add_option("-p", "--progress", action="store_true", default=False, + help="Show progress bar") + parser.add_option("-s", "--separate", action="store_true", default=False, + help="Separate xmpp messages: send one message per line instead of one message alone.") + parser.add_option("-n", "--new-line", action="store_true", default=False, + help="Add a new line at the beginning of the input (usefull for ascii art ;))") + + (self.options, args) = parser.parse_args() + + if len(args) < 1 and not self.options.wait_file: + parser.error("You must specify the destination JID (Jabber ID)") + + if self.options.wait_file: + #several jid + self.dest_jids = args + else: + #one dest_jid, other args are files + self.dest_jid = JID(args[-1]) + if not self.dest_jid.is_valid: + error ("%s is not a valid JID !", self.dest_jid) + exit(1) + self.files = args[:-1] + + if not pbar_available and self.options.progress: + self.options.progress = False + error ("Option progress is not available, deactivated.") + + if self.options.progress or self.options.wait_file: + self.start_loop = True #We have to use loop for these options + else: + self.start_loop = False + + + return args + + def check_jabber_status(self): + """Check that jabber status is allright""" + if not self.bridge.isConnected(): + error("SAT is not conneted, please connect before using jp") + exit(1) + + + def send_stdin(self): + """Send incomming data on stdin to jabber contact""" + header = "\n" if self.options.new_line else "" + + if self.options.separate: #we send stdin in several messages + if header: + self.bridge.sendMessage(self.dest_jid, header) + while (True): + line = sys.stdin.readline() + if not line: + break + self.bridge.sendMessage(self.dest_jid, line.replace("\n","")) + else: + self.bridge.sendMessage(self.dest_jid, header + "".join(sys.stdin.readlines())) + + def send_files(self): + """Send files to jabber contact""" + + for file in self.files: + if not os.path.exists(file): + error ("File [%s] doesn't exist !" % file) + exit(1) + if not self.options.bz2 and os.path.isdir(file): + error ("[%s] is a dir ! Please send files inside or use compression" % file) + exit(1) + + if self.options.bz2: + tmpfile = (basename(self.files[0]) or basename(dirname(self.files[0])) ) + '.tar.bz2' #FIXME: tmp, need an algorithm to find a good name/path + if os.path.exists(tmpfile): + error ("tmp file (%s) already exists ! Please remove it", tmpfile) + exit(1) + warning("bz2 is an experimental option at an early dev stage, use with caution") + #FIXME: check free space, writting perm, tmp dir, filename (watch for OS used) + info("Starting compression, please wait...") + sys.stdout.flush() + bz2=tarfile.open(tmpfile, "w:bz2") + for file in self.files: + info("Adding %s", file) + bz2.add(file) + bz2.close() + info("OK !") + path = abspath(tmpfile) + self.transfert_id = self.bridge.sendFile(self.dest_jid, path) + else: + for file in self.files: + path = abspath(file) + self.transfert_id = self.bridge.sendFile(self.dest_jid, path) #FIXME: show progress only for last transfert_id + + #TODO: manage ProgressBar + + def askConfirmation(self, type, id, data): + """CB used for file transfert, accept files depending on parameters""" + answer_data={} + if type == "FILE_TRANSFERT": + if self.dest_jids and not data['from'] in self.dest_jids: + return #file is not sent by a filtered jid + + answer_data["dest_path"] = os.getcwd()+'/'+data['filename'] + + if self.options.force or not os.path.exists(answer_data["dest_path"]): + self.bridge.confirmationAnswer(id, True, answer_data) + info("Accepted file [%s] from %s", data['filename'], data['from']) + self.transfert_id = id + else: + self.bridge.confirmationAnswer(id, False, answer_data) + warning("Refused file [%s] from %s: a file with the same name already exist", data['filename'], data['from']) + + + if not self.options.multiple and not self.options.progress: + #we just accept one file + self.loop.quit() + + + def wait_file(self): + """Wait for a file and write it on local dir""" + self.bridge.register("askConfirmation", self.askConfirmation, "request") + + def progressCB(self): + if self.transfert_id: + data = self.bridge.getProgress(self.transfert_id) + if data: + if not data['position']: + data['position'] = '0' + if not self.pbar: + #first answer, we must construct the bar + self.pbar = ProgressBar(int(data['size']),["Progress: ",Percentage()," ",Bar()," ",FileTransferSpeed()," ",ETA()]) + self.pbar.start() + + self.pbar.update(int(data['position'])) + elif self.pbar: + self.pbar.finish() + if not self.options.multiple: + self.loop.quit() + return False + + return True + + def go(self): + self.check_options() + self.check_jabber_status() + if self.options.wait_file: + self.wait_file() + else: + if not self.files: #we send message only if there are no files to send + self.send_stdin() + else: + self.send_files() + + if self.start_loop: + self.loop = gobject.MainLoop() + if self.options.progress: + self.pbar = None + gobject.timeout_add(10, self.progressCB) + try: + self.loop.run() + except KeyboardInterrupt: + info("User interruption: good bye") + + +if __name__ == "__main__": + jp = JP() + jp.go()