From 6e4713238eda00e88af74f812cdbd642deca3c6b Mon Sep 17 00:00:00 2001 From: glenux Date: Tue, 16 Aug 2005 10:12:25 +0000 Subject: [PATCH] --- Makefile | 41 +++++++++++++++ TODO | 4 ++ account.py | 134 +++++++++++++++++++++++++++++++++++++++++++++++ config.py | 44 ++++++++++++++++ dot.jabsync | 14 +++++ start.py | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 385 insertions(+) create mode 100644 Makefile create mode 100644 TODO create mode 100644 account.py create mode 100644 config.py create mode 100644 dot.jabsync create mode 100755 start.py diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7e9223e --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +#-------------------------------------------------------------------% +# +# JABSYNC: Synchronizer +# +#-------------------------------------------------------------------% +# +# Author : +# Glenn ROLLAND +# +# Contributors: +# (none) +# +#-------------------------------------------------------------------% + +PRJNAME=JabSync +GDATE:= $(shell date +"%Y-%m-%d_r%H%M") +GFILENAME:= $(PRJNAME)-$(GDATE).tar.bz2 +PATH_GFILENAME:= ../$(GFILENAME) +GFILESIZE:= +LOCALDIR=$(shell pwd) + +all: usage + +usage: + @echo "Usage: make [package] [clean]" + +#doc: +# $(MAKE) -C doc/rapport + +clean: + @rm -f *.pyc + +package: clean createpackage sendtoarchives + +createpackage: + tar -cjvf $(PATH_GFILENAME) -C ../ $(PRJNAME) + +sendtoarchives: + mkdir -p ../Archives + mv $(PATH_GFILENAME) ../Archives + diff --git a/TODO b/TODO new file mode 100644 index 0000000..4ff8ea0 --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +- add something to remember servers (jabber/transports) that + were previously entered +- add the ability to modify an XML file (not the configuration file) to save the list of jabber servers +- add the ability to modify the XML configuration file to add the transports notincluded in the defaut "Service Browse" of servers. diff --git a/account.py b/account.py new file mode 100644 index 0000000..82b7529 --- /dev/null +++ b/account.py @@ -0,0 +1,134 @@ +#/usr/bin/env python + +import jabber +import sys + +def _gdisconnectHD(param=None): + if param: + print " Disconnecting : "+param + return None + +class Account: + def __init__(self): + self._host=None + self._login=None + self._password=None + self._rosterHash={} + self._proto2transport={} + self._transport2proto={} + self._cnx=None + + def setHost(self,hostName): + self._host=hostName + + def setLogin(self,userName): + self._login=userName + + def setPassword(self,passWord): + self._password=passWord + + def setProtocol(self,protocolName,transportName): + self._proto2transport[protocolName]=transportName + + def setTransport(self,transportName,protocolName): + self._transport2proto[transportName]=protocolName + + def getTransport(self,protocolName): + if self._proto2transport.has_key(protocolName): + return self._proto2transport[protocolName] + else: + return None + + def getProtocol(self,hostName): + if self._transport2proto.has_key(hostName): + return self._transport2proto[hostName] + else: + return None + + def connect(self): + # se connecte et choppe le roster + ## connexion au serveur + self._cnx=jabber.Client(host=self._host) + self._cnx.setDisconnectHandler(_gdisconnectHD) + if self._cnx: + try: + self._cnx.connect() + sys.stderr.write("* Connected to "+self._host+"\n") + ## authentification + if self._login and self._password \ + and self._cnx.auth(self._login, self._password, 'default'): + sys.stderr.write(" Authenticated\n") + else: + sys.stderr.write(" Not Athenticated. \n") + sys.stderr.write(" Disconnecting from "+self._host+"\n") + self._cnx=None + except IOError, e: + print e + self._cnx=None + + def disconnect(self): + if self._cnx: + self._cnx.disconnect() + sys.stderr.write(" Disconnected from"+self._host+"\n") + + + def getAgents(self): + if self._cnx: + agentsList=self._cnx.requestAgents() + sys.stderr.write(" Agents list downloaded:\n") + print agentsList + for agent in agentsList.keys(): + if agent: + self.setProtocol(agentsList[agent]["service"],agent) + self.setTransport(agent,agentsList[agent]["service"]) + print " - "+agent+" @ "+agentsList[agent]["service"] + return self._transport2proto + else: + return None + + def getRoster(self): + if self._cnx: + roster=self._cnx.requestRoster() + sys.stderr.write(" Roster downloaded\n") + jid_list=roster.getJIDs() + for jid in jid_list: + transport=jid.getDomain() + node=jid.getNode() + if not self._rosterHash.has_key(transport): + self._rosterHash[transport]={} + if not self._rosterHash[transport].has_key(node): + self._rosterHash[transport][node]=1 + return roster + else: + return None + + def setRoster(self,rosterHash): + # on se connecte + if self._cnx: + for trans_proto in rosterHash.keys(): + trans_host=self.getTransport(trans_proto) + if not trans_host: trans_host=trans_proto + # pour chaque id connue dans ce proto + for proto_id in rosterHash[trans_proto]: + if proto_id: + jid=jabber.JID() + jid.setNode(proto_id) + jid.setDomain(trans_host) + jid.setResource("") + jid_name,jid_groups=rosterHash[trans_proto][proto_id] + sys.stdout.write(" -> "+proto_id) + sys.stdout.write(" @ "+trans_host) + sys.stdout.write(" = "+jid_name.encode('iso-8859-1','replace')+"...") + sys.stdout.flush() + if not(self._rosterHash.has_key(trans_host) \ + and self._rosterHash[trans_host].has_key(proto_id)): + self._cnx.addRosterItem(jid) + sys.stdout.write(" [done]\n") + else: + #ne pas faire la mise a jour, le contact existe deja la-bas + sys.stdout.write(" [exists]\n") + # on met d'abord a jour le nom + self._cnx.updateRosterItem(jid,name=jid_name) + # puis le groupe + self._cnx.updateRosterItem(jid,name=jid_name,groups=jid_groups) + diff --git a/config.py b/config.py new file mode 100644 index 0000000..c871803 --- /dev/null +++ b/config.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +from xml.dom.ext import * +from xml.dom.ext.reader.Sax import * +import os +import sys +from account import Account + +class Config: + def __init__(self): + # create an empty list + self.account_list=None + # initialise xmlTree + self.xmlTree=None + + def loadFromFile(self,configFile): + self.xmlTree=FromXmlFile(configFile) + return 0 + + def getAccounts(self): + if self.xmlTree: + xmlAccountList = self.xmlTree.getElementsByTagName("account") + accountList=[] + for xmlAccount in xmlAccountList: + account=Account() + account.setHost(xmlAccount.getAttribute("host")) + account.setLogin(xmlAccount.getAttribute("login")) + account.setPassword(xmlAccount.getAttribute("password")) + xmlTransportList=xmlAccount.getElementsByTagName("transport") + for xmlTransport in xmlTransportList: + isdefault=xmlTransport.getAttribute("default") + if isdefault=="true": + account.setTransport(\ + xmlTransport.getAttribute("host"),\ + xmlTransport.getAttribute("protocol")) + account.setProtocol(\ + xmlTransport.getAttribute("protocol"),\ + xmlTransport.getAttribute("host")) + #TODO:add something to override servers' defaults + accountList.append(account) + return accountList + else: + return None + diff --git a/dot.jabsync b/dot.jabsync new file mode 100644 index 0000000..c69195b --- /dev/null +++ b/dot.jabsync @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/start.py b/start.py new file mode 100755 index 0000000..55164cd --- /dev/null +++ b/start.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +import sys +import os +import string +#from qt import * +from jabber import * +import StringIO +#import time +from account import Account +from config import Config +#from re import * +from optparse import OptionParser + +#from threading import * +from xml.sax import saxutils +from xml.sax import make_parser +# for prettyprint +from xml.dom.ext import * +from xml.dom.ext.reader.Sax import * + +class Answer: + def __init__(self,question,answerlist): + self._answer=None + while not self._answer: + sys.stderr.write(question) + tmp_ans=raw_input() + if tmp_ans in (answerlist): self._answer=tmp_ans + + def get(self): + return self._answer; + + +class JabSync: + def __init__(self): + # init des var + self._commonJIDs={} + self._commonTransports={} + self._configFile=None + self._config=None + self._accountList=None + self._jabservers={} + + def parseCmdLine(self): + parser=OptionParser() + parser.add_option("-c","--config",\ + action="store", type="string", dest="filename",\ + help="Use file a configuration file",metavar="config") + (options,args)=parser.parse_args() + if options.filename: + self._configFile=options.filename + else: + self._configFile=os.path.join(os.path.expanduser("~"),".jabsync") + print "Configuration file: "+self._configFile + def init(self): + self._config=Config() + self._config.loadFromFile(self._configFile) + self._accountList=self._config.getAccounts() + for account in self._accountList: + account.connect() + agents=account.getAgents() + self._commonTransports.update(agents) + for transport in self._commonTransports.keys(): + print "Transport: "+transport + + def giveTransport(self,hostName): + if self._jabservers.has_key(hostName): + trans_proto=hostName + return trans_proto + else: + if self._commonTransports.has_key(hostName): + trans_proto=self._commonTransports[hostName] + return trans_proto + else: + # TODO: ask user input + is_jabber=Answer(\ + "# ERR : is "+hostName+" a jabber server ? [y/n]\n",\ + ["y","n"]).get() + if is_jabber == "y": + self._jabservers[hostName]=1 + else: + what_tp_ans={\ + "a" : "aim",\ + "i" : "icq",\ + "r" : "irc",\ + "g" : "gadu",\ + "m" : "msn",\ + "p" : "public",\ + "v" : "private",\ + "y" : "yahoo",\ + "-" : "forget"} + what_transport=Answer(\ + " Select transport type :\n"+\ + " [a]im"+\ + " [i]cq"+\ + " i[r]c):"+\ + " [g]adu"+\ + " [m]sn"+\ + " [p]ublic:"+\ + " pri[v]ate:"+\ + " [y]ahoo"+\ + " [-] Forget JIDs using this host",\ + what_tp_ans.keys()) + trans_proto=what_tp_ans[what_transport] + if trans_proto == "forget": + # TODO: ajouter regles d'exclusion + zero=0 + else: + # TODO: ajouter transport a la config XML + zero=0 + return self.giveTransport(hostName) + + def get(self): + #get Roster + for account in self._accountList: + roster=account.getRoster() + # fusionner les roster + jid_list=roster.getJIDs() + for jid in jid_list: + transport=jid.getDomain() + trans_proto=self.giveTransport(transport) + if not self._commonJIDs.has_key(trans_proto): + self._commonJIDs[trans_proto]={} + jid_name=roster.getName(jid) + jid_groups=roster.getGroups(jid) + if not jid_name: jid_name=jid.getNode() + if not self._commonJIDs[trans_proto].has_key(jid.getNode()): + self._commonJIDs[trans_proto][jid.getNode()]=(jid_name,jid_groups) +# print " <- "+jid.getNode()+" @ "+trans_proto+" = "+jid_name + print "\x1B[G <- "+jid.getNode()+" @ "+trans_proto+" = "+jid_name + + #upload rosters + def set(self): + for account in self._accountList: + account.setRoster(self._commonJIDs) + + def stop(self): + for account in self._accountList: + account.disconnect() + +if __name__ == "__main__": + jabsync=JabSync() + jabsync.parseCmdLine() + jabsync.init() + jabsync.get() + jabsync.set() + jabsync.stop() +