Mercurial > libervia-backend
view frontends/src/jp/base.py @ 814:59c7bc51c323
jp: refactoring using ArgParse
author | Dal <kedals0@gmail.com> |
---|---|
date | Wed, 05 Feb 2014 14:35:26 +0100 |
parents | frontends/src/jp/jp@1fe00f0c9a91 |
children | c39117d00f35 |
line wrap: on
line source
#! /usr/bin/python # -*- coding: utf-8 -*- # jp: a SAT command line tool # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 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 Affero 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 Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from __future__ import with_statement from sat.core.i18n import _ #consts name = u"jp" about = name+u""" v%s (c) Jérôme Poisson (aka Goffi) 2009, 2010, 2011, 2012, 2013, 2014 --- """+name+u""" Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 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 argparse import ArgumentParser from sat.tools.jid import JID import gobject from sat_frontends.bridge.DBus import DBusBridgeFrontend from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError from sat.tools.utils import clean_ustr import tarfile import tempfile import shutil 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 #version = unicode(self.bridge.getVersion()) version = "undefined" parser = ArgumentParser() parser.add_argument('--version', action='version', version=about % version) subparser = parser.add_subparsers(dest='subparser_name') # File managment class JP(object): """ This class can be use to establish a connection with the bridge. Moreover, it should manage a main loop. To use it, you mainly have to redefine the method run to perform specify what kind of operation you want to perform. """ def __init__(self, start_mainloop = False): try: self.bridge=DBusBridgeFrontend() except BridgeExceptionNoService: print(_(u"Can't connect to SàT backend, are you sure it's launched ?")) sys.exit(1) except BridgeInitError: print(_(u"Can't init bridge")) sys.exit(1) self._start_loop = start_mainloop def run(self): raise NotImplementedError def _run(self): """Call run and lauch a loop if needed""" print "You are connected!" self.run() if self._start_loop: print "Exiting loop..." self.loop.quit() def _loop_start(self): self.loop = gobject.MainLoop() try: self.loop.run() except KeyboardInterrupt: info(_("User interruption: good bye")) def start_mainloop(self): self._start_loop = True def go(self): self.run() if self._start_loop: self._loop_start() class JPWithProfile(JP): """Manage a bridge (inherit from :class:`JP`), but it also adds profile managment, ie, connection to the profile. Moreover, some useful methods are predefined such as :py:meth:`check_jids`. The connection to XMPP is automatically managed. """ def __init__(self, profile_name, start_mainloop = False): JP.__init__(self, start_mainloop) self.profile_name = profile_name def check_jids(self, jids): """Check jids validity, transform roster name to corresponding jids :param profile: A profile name :param jids: A list of jids :rtype: A list of jids """ names2jid = {} nodes2jid = {} for contact in self.bridge.getContacts(self.profile): _jid, attr, groups = contact if attr.has_key("name"): names2jid[attr["name"].lower()] = _jid nodes2jid[JID(_jid).node.lower()] = _jid def expandJid(jid): _jid = jid.lower() if _jid in names2jid: expanded = names2jid[_jid] elif _jid in nodes2jid: expanded = nodes2jid[_jid] else: expanded = jid return unicode(expanded) def check(jid): if not jid.is_valid: error (_("%s is not a valid JID !"), jid) exit(1) dest_jids=[] try: for i in range(len(jids)): dest_jids.append(expandJid(jids[i])) check(dest_jids[i]) except AttributeError: pass return dest_jids def check_jabber_connection(self): """Check that jabber status is allright""" def cantConnect(arg): print arg error(_(u"Can't connect profile")) exit(1) self.profile = self.bridge.getProfileName(self.profile_name) if not self.profile: error(_("The profile asked doesn't exist")) exit(1) if self.bridge.isConnected(self.profile): print "Already connected" else: self._start_loop = True self.bridge.asyncConnect(self.profile, self._run, cantConnect) return self.run() def _getFullJid(self, param_jid): """Return the full jid if possible (add last resource when find a bare jid""" _jid = JID(param_jid) if not _jid.resource: #if the resource is not given, we try to add the last known resource last_resource = self.bridge.getLastResource(param_jid, self.profile_name) if last_resource: return "%s/%s" % (_jid.bare, last_resource) return param_jid def go(self): self.check_jabber_connection() if self._start_loop: self._loop_start() class JPAsk(JPWithProfile): def confirm_type(self): """Must return a string containing the confirm type. For instance, FILE_TRANSFER or PIPE_TRANSFER, etc. :rtype: str """ raise NotImplemented def dest_jids(self): return None def _askConfirmation(self, confirm_id, confirm_type, data, profile): if profile != self.profile: debug("Ask confirmation ignored: not our profile") return if confirm_type == self.confirm_type(): self._confirm_id = confirm_id if self.dest_jids() and not JID(data['from']).bare in [JID(_jid).bare for _jid in self.dest_jids()]: return #file is not sent by a filtered jid else: self.ask(data) def ask(self): """ The return value is used to answer to the bridge. :rtype: (bool, dict) """ raise NotImplementedError def answer(self, accepted, answer_data): """ :param accepted: boolean :param aswer_data: dict of answer datas """ self.bridge.confirmationAnswer(self._confirm_id, False, answer_data, self.profile) def run(self): """Auto reply to confirmations requests""" #we register incoming confirmation self.bridge.register("askConfirmation", self._askConfirmation) #and we ask those we have missed for confirm_id, confirm_type, data in self.bridge.getWaitingConf(self.profile): self._askConfirmation(confirm_id, confirm_type, data, self.profile)