Mercurial > libervia-backend
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frontends/src/jp/jp Wed Dec 29 01:06:29 2010 +0100 @@ -0,0 +1,272 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +""" +jp: a SAT command line tool +Copyright (C) 2009, 2010 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 = u"jp" +about = name+u""" v%s (c) Jérôme Poisson (aka Goffi) 2009, 2010 + +--- +"""+name+u""" Copyright (C) 2009, 2010 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 gettext +gettext.install('jp', "i18n", unicode=True) + +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,BridgeExceptionNoService +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): + try: + self.bridge=DBusBridgeFrontend() + except BridgeExceptionNoService: + print(_(u"Can't connect to SàT backend, are you sure it's launched ?")) + import sys + sys.exit(1) + 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 + """) + version = unicode(self.bridge.getVersion()) + parser = OptionParser(usage=usage,version=about % version) + + parser.add_option("-p", "--profile", action="store", type="string", default='@DEFAULT@', + help=_("Use PROFILE profile key (default: %default)")) + 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("-g", "--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)").encode('utf-8')) + + 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""" + + self.profile = self.bridge.getProfileName(self.options.profile) + if not self.profile: + error(_("The profile asked doesn't exist")) + exit(1) + + if not self.bridge.isConnected(self.profile): + error(_(u"SàT 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, profile_key=self.profile) + while (True): + line = sys.stdin.readline() + if not line: + break + self.bridge.sendMessage(self.dest_jid, line.replace("\n",""), profile_key=self.profile) + else: + self.bridge.sendMessage(self.dest_jid, header + "".join(sys.stdin.readlines()), profile_key=self.profile) + + 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, profile_key=self.profile) + else: + for file in self.files: + path = abspath(file) + self.transfert_id = self.bridge.sendFile(self.dest_jid, path, profile_key=self.profile) #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 [%(filename)s] from %(sender)s") % {'filename':data['filename'], 'sender':data['from']}) + self.transfert_id = id + else: + self.bridge.confirmationAnswer(id, False, answer_data) + warning(_("Refused file [%(filename)s] from %(sender)s: a file with the same name already exist") % {'filename':data['filename'], 'sender':data['from']}) + + + if not self.options.multiple and not self.options.progress: + #we just accept one file + self.loop.quit() + + def actionResult(self, type, id, data): + #FIXME + info (_("FIXME: actionResult not implemented")) + + 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()