This commit is contained in:
glenux 2005-08-16 10:12:25 +00:00
parent 4eba9027ec
commit 6e4713238e
6 changed files with 385 additions and 0 deletions

41
Makefile Normal file
View file

@ -0,0 +1,41 @@
#-------------------------------------------------------------------%
#
# JABSYNC: Synchronizer
#
#-------------------------------------------------------------------%
#
# Author :
# Glenn ROLLAND <glenux@fr.st>
#
# 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

4
TODO Normal file
View file

@ -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.

134
account.py Normal file
View file

@ -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)

44
config.py Normal file
View file

@ -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

14
dot.jabsync Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<jabsync version="0.4">
<account host="jabber.dk" login="fooman" password="barpassword">
<transport host="icq.myjabber.net" protocol="icq" />
<transport host="aim.myjabber.net" protocol="aim"/>
</account>
<!-- <account host="jabber.freenet.de" login="fooman" password="barpassword" /> -->
<account host="jabber.ru" login="fooman" password="barpassword" >
<transport host="aim.jabber.ru" protocol="aim" default="true" />
<transport host="icq.jabber.ru" protocol="icq" default="true" />
<transport host="msn.jabber.ru" protocol="msn" default="true" />
<transport host="yahoo.jabber.ru" protocol="yahoo" default="true" />
</account>
</jabsync>

148
start.py Executable file
View file

@ -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()