here is the sock plugin
runCore can now recieve the -c option to be lunch as a client. In such a case, it connects to a gajim server (a sock plugin) and not to a jabber server
This commit is contained in:
parent
a910c276e1
commit
03aee33e25
|
@ -49,18 +49,14 @@ class GajimHub:
|
|||
""" Records a plugin from an event """
|
||||
qu = self.queues[name]
|
||||
if self.events.has_key(event) :
|
||||
self.events[event].append(qu)
|
||||
if not qu in self.events[event]:
|
||||
self.events[event].append(qu)
|
||||
else :
|
||||
self.events[event] = [qu]
|
||||
# END register
|
||||
|
||||
def sendPlugin(self, event, con, data):
|
||||
""" Sends an event to registered plugins
|
||||
NOTIFY : ('NOTIFY', (user, status, message))
|
||||
MSG : ('MSG', (user, msg))
|
||||
ROSTER : ('ROSTER', {jid:{'status':_, 'name':_, 'show':_, 'groups':[], 'online':_, 'ask':_, 'sub':_} ,jid:{}})
|
||||
SUBSCRIBED : ('SUBSCRIBED', {'jid':_, 'nom':_, 'server':_, 'resource':_, 'status':_, 'show':_})"""
|
||||
|
||||
""" Sends an event to registered plugins"""
|
||||
if self.events.has_key(event):
|
||||
for i in self.events[event]:
|
||||
i.put((event, con, data))
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
|
||||
import threading
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.append("..")
|
||||
|
||||
class GajimThread(threading.Thread):
|
||||
def __init__(self, name = None, queueIn = None, queueOut = None):
|
||||
self.queueIn = queueIn
|
||||
|
|
658
core/core.py
658
core/core.py
|
@ -17,16 +17,12 @@
|
|||
## GNU General Public License for more details.
|
||||
##
|
||||
|
||||
import sys, os
|
||||
import sys, os, time, string, logging
|
||||
|
||||
sys.path.append("..")
|
||||
import time
|
||||
import string
|
||||
import logging
|
||||
|
||||
import common.hub
|
||||
import common.hub, common.optparser
|
||||
import common.jabber
|
||||
import common.optparser
|
||||
import socket, select, pickle
|
||||
|
||||
|
||||
from common import i18n
|
||||
_ = i18n._
|
||||
|
@ -37,28 +33,75 @@ log.setLevel(logging.DEBUG)
|
|||
CONFPATH = "~/.gajim/config"
|
||||
LOGPATH = os.path.expanduser("~/.gajim/logs/")
|
||||
|
||||
def XMLescape(txt):
|
||||
"Escape XML entities"
|
||||
txt = txt.replace("&", "&")
|
||||
txt = txt.replace("<", "<")
|
||||
txt = txt.replace(">", ">")
|
||||
return txt
|
||||
|
||||
def XMLunescape(txt):
|
||||
"Unescape XML entities"
|
||||
txt = txt.replace(">", ">")
|
||||
txt = txt.replace("<", "<")
|
||||
txt = txt.replace("&", "&")
|
||||
return txt
|
||||
|
||||
class GajimCore:
|
||||
"""Core"""
|
||||
def __init__(self):
|
||||
def __init__(self, mode='client'):
|
||||
self.mode = mode
|
||||
self.log = 0
|
||||
self.init_cfg_file()
|
||||
self.cfgParser = common.optparser.OptionsParser(CONFPATH)
|
||||
if mode == 'client':
|
||||
self.data = ''
|
||||
self.connect_core()
|
||||
self.hub = common.hub.GajimHub()
|
||||
self.parse()
|
||||
if self.log:
|
||||
log.setLevel(logging.DEBUG)
|
||||
else:
|
||||
log.setLevel(None)
|
||||
self.connected = {}
|
||||
#connexions {con: name, ...}
|
||||
self.connexions = {}
|
||||
for a in self.accounts:
|
||||
self.connected[a] = 0
|
||||
self.myVCardID = []
|
||||
if mode == 'server':
|
||||
self.connected = {}
|
||||
#connexions {con: name, ...}
|
||||
self.connexions = {}
|
||||
for a in self.accounts:
|
||||
self.connected[a] = 0
|
||||
self.myVCardID = []
|
||||
self.loadPlugins(self.cfgParser.tab['Core']['modules'])
|
||||
else:
|
||||
self.loadPlugins(self.cfgParser.tab['Core_client']['modules'])
|
||||
# END __init__
|
||||
|
||||
def loadPlugins(self, moduleStr):
|
||||
"""Load defaults plugins : plugins in 'modules' option of Core section
|
||||
in ConfFile and register them to the hub"""
|
||||
if moduleStr:
|
||||
mods = string.split (moduleStr, ' ')
|
||||
|
||||
for mod in mods:
|
||||
modObj = self.hub.newPlugin(mod)
|
||||
modObj.load()
|
||||
# END loadPLugins
|
||||
|
||||
def connect_core(self):
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.socket.connect((self.cfgParser.tab['Core_client']['host'], \
|
||||
self.cfgParser.tab['Core_client']['port']))
|
||||
# END connect_core
|
||||
|
||||
def init_cfg_file(self):
|
||||
"""Initialize configuration file"""
|
||||
if self.mode == 'server':
|
||||
#TODO: only one should be needed
|
||||
default_file = "[Profile]\naccounts = \nlog = 0\n\n[Core]\ndelauth = 1\nalwaysauth = 0\nmodules = logger gtkgui\ndelroster = 1\n"
|
||||
default_tab = {'Profile': {'accounts': '', 'log': 0}, 'Core': \
|
||||
{'delauth': 1, 'alwaysauth': 0, 'modules': 'logger gtkgui', \
|
||||
'delroster': 1}}
|
||||
else:
|
||||
default_file = "[Profile]\nlog = 0\n\n[Core_client]\nhost = \nport = 8255\nmodules = gtkgui\n"
|
||||
default_tab = {'Profile': {'log': 0}, 'Core_client': {'host': \
|
||||
'localhost', 'port': 8255, 'modules': 'gtkgui'}}
|
||||
fname = os.path.expanduser(CONFPATH)
|
||||
reps = string.split(fname, '/')
|
||||
del reps[0]
|
||||
|
@ -79,23 +122,34 @@ class GajimCore:
|
|||
except:
|
||||
print _("creating %s") % fname
|
||||
fic = open(fname, "w")
|
||||
fic.write("[Profile]\naccounts = \nlog = 0\n\n[Core]\ndelauth = 1\nalwaysauth = 0\nmodules = logger gtkgui\ndelroster = 1\n")
|
||||
fic.write(default_file)
|
||||
fic.close()
|
||||
self.cfgParser = common.optparser.OptionsParser(CONFPATH)
|
||||
self.parse()
|
||||
for part in default_tab.keys():
|
||||
if not self.cfgParser.tab.has_key(part):
|
||||
self.cfgParser.tab[part] = {}
|
||||
self.cfgParser.writeCfgFile()
|
||||
for option in default_tab[part].keys():
|
||||
if not self.cfgParser.tab[part].has_key(option):
|
||||
self.cfgParser.tab[part][option] = default_tab[part][option]
|
||||
self.cfgParser.writeCfgFile()
|
||||
# END init_cfg_file
|
||||
|
||||
def parse(self):
|
||||
"""Parse configuratoin file and create self.accounts"""
|
||||
self.cfgParser.parseCfgFile()
|
||||
self.accounts = {}
|
||||
if self.cfgParser.tab.has_key('Profile'):
|
||||
if self.cfgParser.tab['Profile'].has_key('log'):
|
||||
self.log = self.cfgParser.tab['Profile']['log']
|
||||
if self.cfgParser.tab['Profile'].has_key('accounts'):
|
||||
accts = string.split(self.cfgParser.tab['Profile']['accounts'], ' ')
|
||||
if accts == ['']:
|
||||
accts = []
|
||||
for a in accts:
|
||||
self.accounts[a] = self.cfgParser.tab[a]
|
||||
if self.mode == 'server':
|
||||
self.accounts = {}
|
||||
if self.cfgParser.tab['Profile'].has_key('accounts'):
|
||||
accts = string.split(self.cfgParser.tab['Profile']['accounts'], ' ')
|
||||
if accts == ['']:
|
||||
accts = []
|
||||
for a in accts:
|
||||
self.accounts[a] = self.cfgParser.tab[a]
|
||||
|
||||
def vCardCB(self, con, vc):
|
||||
"""Called when we recieve a vCard
|
||||
|
@ -260,89 +314,92 @@ class GajimCore:
|
|||
return 0
|
||||
# END connect
|
||||
|
||||
def mainLoop(self):
|
||||
"""Main Loop : Read the incomming queue to execute commands comming from
|
||||
plugins and process Jabber"""
|
||||
while 1:
|
||||
if not self.hub.queueIn.empty():
|
||||
ev = self.hub.queueIn.get()
|
||||
if ev[1] and (ev[1] in self.connexions.values()):
|
||||
for con in self.connexions.keys():
|
||||
if ev[1] == self.connexions[con]:
|
||||
break
|
||||
else:
|
||||
con = None
|
||||
#('QUIT', account, ())
|
||||
if ev[0] == 'QUIT':
|
||||
for con in self.connexions.keys():
|
||||
if self.connected[self.connexions[con]] == 1:
|
||||
self.connected[self.connexions[con]] = 0
|
||||
con.disconnect()
|
||||
self.hub.sendPlugin('QUIT', None, ())
|
||||
return
|
||||
#('ASK_CONFIG', account, (who_ask, section, default_config))
|
||||
elif ev[0] == 'ASK_CONFIG':
|
||||
if ev[2][1] == 'accounts':
|
||||
self.hub.sendPlugin('CONFIG', None, (ev[2][0], self.accounts))
|
||||
else:
|
||||
if self.cfgParser.tab.has_key(ev[2][1]):
|
||||
config = self.cfgParser.__getattr__(ev[2][1])
|
||||
for item in ev[2][2].keys():
|
||||
if not config.has_key(item):
|
||||
config[item] = ev[2][2][item]
|
||||
self.hub.sendPlugin('CONFIG', None, (ev[2][0], config))
|
||||
else:
|
||||
self.cfgParser.tab[ev[2][1]] = ev[2][2]
|
||||
self.cfgParser.writeCfgFile()
|
||||
self.hub.sendPlugin('CONFIG', None, (ev[2][0], ev[2][2]))
|
||||
#('CONFIG', account, (section, config))
|
||||
elif ev[0] == 'CONFIG':
|
||||
if ev[2][0] == 'accounts':
|
||||
#Remove all old accounts
|
||||
accts = string.split(self.cfgParser.tab\
|
||||
['Profile']['accounts'], ' ')
|
||||
if accts == ['']:
|
||||
accts = []
|
||||
for a in accts:
|
||||
del self.cfgParser.tab[a]
|
||||
#Write all new accounts
|
||||
accts = ev[2][1].keys()
|
||||
self.cfgParser.tab['Profile']['accounts'] = \
|
||||
string.join(accts)
|
||||
for a in accts:
|
||||
self.cfgParser.tab[a] = ev[2][1][a]
|
||||
if not a in self.connected.keys():
|
||||
self.connected[a]= 0
|
||||
else:
|
||||
self.cfgParser.tab[ev[2][0]] = ev[2][1]
|
||||
self.cfgParser.writeCfgFile()
|
||||
#TODO: tell the changes to other plugins
|
||||
#('STATUS', account, (status, msg))
|
||||
elif ev[0] == 'STATUS':
|
||||
if (ev[2][0] != 'offline') and (self.connected[ev[1]] == 0):
|
||||
con = self.connect(ev[1])
|
||||
if self.connected[ev[1]]:
|
||||
#send our presence
|
||||
type = 'available'
|
||||
if ev[2][0] == 'invisible':
|
||||
type = 'invisible'
|
||||
prio = 0
|
||||
if self.cfgParser.tab[ev[1]].has_key('priority'):
|
||||
prio = str(self.cfgParser.tab[ev[1]]['priority'])
|
||||
con.sendPresence(type, prio, ev[2][0], ev[2][1])
|
||||
self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
|
||||
#ask our VCard
|
||||
iq = common.jabber.Iq(type="get")
|
||||
iq._setTag('vCard', common.jabber.NS_VCARD)
|
||||
id = con.getAnID()
|
||||
iq.setID(id)
|
||||
con.send(iq)
|
||||
self.myVCardID.append(id)
|
||||
elif (ev[2][0] == 'offline') and (self.connected[ev[1]] == 1):
|
||||
self.connected[ev[1]] = 0
|
||||
def send_to_socket(self, ev, sock):
|
||||
evp = pickle.dumps(ev)
|
||||
sock.send('<'+XMLescape(evp)+'>')
|
||||
|
||||
def unparse_socket(self):
|
||||
list_ev = []
|
||||
while self.data:
|
||||
deb = self.data.find('<')
|
||||
if deb == -1:
|
||||
break
|
||||
end = self.data.find('>', deb)
|
||||
if end == -1:
|
||||
break
|
||||
list_ev.append(pickle.loads(self.data[deb+1:end]))
|
||||
self.data = self.data[end+1:]
|
||||
return list_ev
|
||||
|
||||
def read_queue(self):
|
||||
while self.hub.queueIn.empty() == 0:
|
||||
ev = self.hub.queueIn.get()
|
||||
if self.mode == 'client':
|
||||
#('REG_MESSAGE', module, list_message)
|
||||
if ev[0] == 'REG_MESSAGE':
|
||||
for msg in ev[2]:
|
||||
self.hub.register(ev[1], msg)
|
||||
# ready_to_read, ready_to_write, in_error = select.select(
|
||||
# [], [self.socket], [])
|
||||
self.send_to_socket(ev, self.socket)
|
||||
return 0
|
||||
if ev[1] and (ev[1] in self.connexions.values()):
|
||||
for con in self.connexions.keys():
|
||||
if ev[1] == self.connexions[con]:
|
||||
break
|
||||
else:
|
||||
con = None
|
||||
#('QUIT', account, ())
|
||||
if ev[0] == 'QUIT':
|
||||
for con in self.connexions.keys():
|
||||
if self.connected[self.connexions[con]] == 1:
|
||||
self.connected[self.connexions[con]] = 0
|
||||
con.disconnect()
|
||||
self.hub.sendPlugin('STATUS', ev[1], 'offline')
|
||||
elif ev[2][0] != 'offline' and self.connected[ev[1]] == 1:
|
||||
self.hub.sendPlugin('QUIT', None, ())
|
||||
return 1
|
||||
#('ASK_CONFIG', account, (who_ask, section, default_config))
|
||||
elif ev[0] == 'ASK_CONFIG':
|
||||
if ev[2][1] == 'accounts':
|
||||
self.hub.sendPlugin('CONFIG', None, (ev[2][0], self.accounts))
|
||||
else:
|
||||
if self.cfgParser.tab.has_key(ev[2][1]):
|
||||
config = self.cfgParser.__getattr__(ev[2][1])
|
||||
for item in ev[2][2].keys():
|
||||
if not config.has_key(item):
|
||||
config[item] = ev[2][2][item]
|
||||
self.hub.sendPlugin('CONFIG', None, (ev[2][0], config))
|
||||
else:
|
||||
self.cfgParser.tab[ev[2][1]] = ev[2][2]
|
||||
self.cfgParser.writeCfgFile()
|
||||
self.hub.sendPlugin('CONFIG', None, (ev[2][0], ev[2][2]))
|
||||
#('CONFIG', account, (section, config))
|
||||
elif ev[0] == 'CONFIG':
|
||||
if ev[2][0] == 'accounts':
|
||||
#Remove all old accounts
|
||||
accts = string.split(self.cfgParser.tab\
|
||||
['Profile']['accounts'], ' ')
|
||||
if accts == ['']:
|
||||
accts = []
|
||||
for a in accts:
|
||||
del self.cfgParser.tab[a]
|
||||
#Write all new accounts
|
||||
accts = ev[2][1].keys()
|
||||
self.cfgParser.tab['Profile']['accounts'] = \
|
||||
string.join(accts)
|
||||
for a in accts:
|
||||
self.cfgParser.tab[a] = ev[2][1][a]
|
||||
if not a in self.connected.keys():
|
||||
self.connected[a]= 0
|
||||
else:
|
||||
self.cfgParser.tab[ev[2][0]] = ev[2][1]
|
||||
self.cfgParser.writeCfgFile()
|
||||
#TODO: tell the changes to other plugins
|
||||
#('STATUS', account, (status, msg))
|
||||
elif ev[0] == 'STATUS':
|
||||
if (ev[2][0] != 'offline') and (self.connected[ev[1]] == 0):
|
||||
con = self.connect(ev[1])
|
||||
if self.connected[ev[1]]:
|
||||
#send our presence
|
||||
type = 'available'
|
||||
if ev[2][0] == 'invisible':
|
||||
type = 'invisible'
|
||||
|
@ -351,188 +408,227 @@ class GajimCore:
|
|||
prio = str(self.cfgParser.tab[ev[1]]['priority'])
|
||||
con.sendPresence(type, prio, ev[2][0], ev[2][1])
|
||||
self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
|
||||
#('MSG', account, (jid, msg))
|
||||
elif ev[0] == 'MSG':
|
||||
msg = common.jabber.Message(ev[2][0], ev[2][1])
|
||||
msg.setType('chat')
|
||||
con.send(msg)
|
||||
self.hub.sendPlugin('MSGSENT', ev[1], ev[2])
|
||||
#('SUB', account, (jid, txt))
|
||||
elif ev[0] == 'SUB':
|
||||
log.debug('subscription request for %s' % ev[2][0])
|
||||
pres = common.jabber.Presence(ev[2][0], 'subscribe')
|
||||
if ev[2][1]:
|
||||
pres.setStatus(ev[2][1])
|
||||
else:
|
||||
pres.setStatus(_("I would like to add you to my roster."))
|
||||
con.send(pres)
|
||||
#('REQ', account, jid)
|
||||
elif ev[0] == 'AUTH':
|
||||
con.send(common.jabber.Presence(ev[2], 'subscribed'))
|
||||
#('DENY', account, jid)
|
||||
elif ev[0] == 'DENY':
|
||||
con.send(common.jabber.Presence(ev[2], 'unsubscribed'))
|
||||
#('UNSUB', account, jid)
|
||||
elif ev[0] == 'UNSUB':
|
||||
delauth = 1
|
||||
if self.cfgParser.Core.has_key('delauth'):
|
||||
delauth = self.cfgParser.Core['delauth']
|
||||
delroster = 1
|
||||
if self.cfgParser.Core.has_key('delroster'):
|
||||
delroster = self.cfgParser.Core['delroster']
|
||||
if delauth:
|
||||
con.send(common.jabber.Presence(ev[2], 'unsubscribe'))
|
||||
if delroster:
|
||||
con.removeRosterItem(ev[2])
|
||||
#('UNSUB_AGENT', account, agent)
|
||||
elif ev[0] == 'UNSUB_AGENT':
|
||||
con.removeRosterItem(ev[2])
|
||||
con.requestRegInfo(ev[2])
|
||||
agent_info = con.getRegInfo()
|
||||
key = agent_info['key']
|
||||
iq = common.jabber.Iq(to=ev[2], type="set")
|
||||
q = iq.setQuery(common.jabber.NS_REGISTER)
|
||||
q.insertTag('remove')
|
||||
q.insertTag('key').insertData(key)
|
||||
id = con.getAnID()
|
||||
iq.setID(id)
|
||||
con.send(iq)
|
||||
self.hub.sendPlugin('AGENT_REMOVED', ev[1], ev[2])
|
||||
#('UPDUSER', account, (jid, name, groups))
|
||||
elif ev[0] == 'UPDUSER':
|
||||
con.updateRosterItem(jid=ev[2][0], name=ev[2][1], \
|
||||
groups=ev[2][2])
|
||||
#('REQ_AGENTS', account, ())
|
||||
elif ev[0] == 'REQ_AGENTS':
|
||||
agents = con.requestAgents()
|
||||
self.hub.sendPlugin('AGENTS', ev[1], agents)
|
||||
#('REQ_AGENT_INFO', account, agent)
|
||||
elif ev[0] == 'REQ_AGENT_INFO':
|
||||
con.requestRegInfo(ev[2])
|
||||
agent_info = con.getRegInfo()
|
||||
self.hub.sendPlugin('AGENT_INFO', ev[1], (ev[2], agent_info))
|
||||
#('REG_AGENT', account, infos)
|
||||
elif ev[0] == 'REG_AGENT':
|
||||
con.sendRegInfo(ev[2])
|
||||
#('NEW_ACC', (hostname, login, password, name, ressource, prio, \
|
||||
# use_proxy, proxyhost, proxyport))
|
||||
elif ev[0] == 'NEW_ACC':
|
||||
if ev[2][6]:
|
||||
proxy = {'host': ev[2][7], 'port': ev[2][8]}
|
||||
else:
|
||||
proxy = None
|
||||
c = common.jabber.Client(host = ev[2][0], debug = [], \
|
||||
log = None, proxy = proxy)
|
||||
try:
|
||||
c.connect()
|
||||
except IOError, e:
|
||||
log.debug("Couldn't connect to %s %s" % (hostname, e))
|
||||
return 0
|
||||
else:
|
||||
log.debug("Connected to server")
|
||||
c.requestRegInfo()
|
||||
req = c.getRegInfo()
|
||||
c.setRegInfo( 'username', ev[2][1])
|
||||
c.setRegInfo( 'password', ev[2][2])
|
||||
#FIXME: if users already exist, no error message :(
|
||||
if not c.sendRegInfo():
|
||||
print "error " + c.lastErr
|
||||
else:
|
||||
self.hub.sendPlugin('ACC_OK', ev[1], ev[2])
|
||||
#('ACC_CHG', old_account, new_account)
|
||||
elif ev[0] == 'ACC_CHG':
|
||||
self.connected[ev[2]] = self.connected[ev[1]]
|
||||
del self.connected[ev[1]]
|
||||
if con:
|
||||
self.connexions[con] = self.connected[ev[2]]
|
||||
#('ASK_VCARD', account, jid)
|
||||
elif ev[0] == 'ASK_VCARD':
|
||||
iq = common.jabber.Iq(to=ev[2], type="get")
|
||||
iq._setTag('vCard', common.jabber.NS_VCARD)
|
||||
iq.setID(con.getAnID())
|
||||
con.send(iq)
|
||||
#('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...})
|
||||
elif ev[0] == 'VCARD':
|
||||
iq = common.jabber.Iq(type="set")
|
||||
iq.setID(con.getAnID())
|
||||
iq2 = iq._setTag('vCard', common.jabber.NS_VCARD)
|
||||
for i in ev[2].keys():
|
||||
if i != 'jid':
|
||||
if type(ev[2][i]) == type({}):
|
||||
iq3 = iq2.insertTag(i)
|
||||
for j in ev[2][i].keys():
|
||||
iq3.insertTag(j).putData(ev[2][i][j])
|
||||
else:
|
||||
iq2.insertTag(i).putData(ev[2][i])
|
||||
con.send(iq)
|
||||
#('AGENT_LOGGING', account, (agent, type))
|
||||
elif ev[0] == 'AGENT_LOGGING':
|
||||
t = ev[2][1];
|
||||
if not t:
|
||||
t='available';
|
||||
p = common.jabber.Presence(to=ev[2][0], type=t)
|
||||
con.send(p)
|
||||
#('LOG_NB_LINE', account, jid)
|
||||
elif ev[0] == 'LOG_NB_LINE':
|
||||
fic = open(LOGPATH + ev[2], "r")
|
||||
nb = 0
|
||||
while (fic.readline()):
|
||||
nb = nb+1
|
||||
fic.close()
|
||||
self.hub.sendPlugin('LOG_NB_LINE', ev[1], (ev[2], nb))
|
||||
#('LOG_GET_RANGE', account, (jid, line_begin, line_end))
|
||||
elif ev[0] == 'LOG_GET_RANGE':
|
||||
fic = open(LOGPATH + ev[2][0], "r")
|
||||
nb = 0
|
||||
while (nb < ev[2][1] and fic.readline()):
|
||||
nb = nb+1
|
||||
while nb < ev[2][2]:
|
||||
line = fic.readline()
|
||||
nb = nb+1
|
||||
if line:
|
||||
lineSplited = string.split(line, ':')
|
||||
if len(lineSplited) > 2:
|
||||
self.hub.sendPlugin('LOG_LINE', ev[1], (ev[2][0], nb, \
|
||||
lineSplited[0], lineSplited[1], lineSplited[2:]))
|
||||
fic.close()
|
||||
#('REG_MESSAGE', module, list_message)
|
||||
elif ev[0] == 'REG_MESSAGE':
|
||||
for msg in ev[2]:
|
||||
self.hub.register(ev[1], msg)
|
||||
#ask our VCard
|
||||
iq = common.jabber.Iq(type="get")
|
||||
iq._setTag('vCard', common.jabber.NS_VCARD)
|
||||
id = con.getAnID()
|
||||
iq.setID(id)
|
||||
con.send(iq)
|
||||
self.myVCardID.append(id)
|
||||
elif (ev[2][0] == 'offline') and (self.connected[ev[1]] == 1):
|
||||
self.connected[ev[1]] = 0
|
||||
con.disconnect()
|
||||
self.hub.sendPlugin('STATUS', ev[1], 'offline')
|
||||
elif ev[2][0] != 'offline' and self.connected[ev[1]] == 1:
|
||||
type = 'available'
|
||||
if ev[2][0] == 'invisible':
|
||||
type = 'invisible'
|
||||
prio = 0
|
||||
if self.cfgParser.tab[ev[1]].has_key('priority'):
|
||||
prio = str(self.cfgParser.tab[ev[1]]['priority'])
|
||||
con.sendPresence(type, prio, ev[2][0], ev[2][1])
|
||||
self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
|
||||
#('MSG', account, (jid, msg))
|
||||
elif ev[0] == 'MSG':
|
||||
msg = common.jabber.Message(ev[2][0], ev[2][1])
|
||||
msg.setType('chat')
|
||||
con.send(msg)
|
||||
self.hub.sendPlugin('MSGSENT', ev[1], ev[2])
|
||||
#('SUB', account, (jid, txt))
|
||||
elif ev[0] == 'SUB':
|
||||
log.debug('subscription request for %s' % ev[2][0])
|
||||
pres = common.jabber.Presence(ev[2][0], 'subscribe')
|
||||
if ev[2][1]:
|
||||
pres.setStatus(ev[2][1])
|
||||
else:
|
||||
log.debug(_("Unknown Command %s") % ev[0])
|
||||
pres.setStatus(_("I would like to add you to my roster."))
|
||||
con.send(pres)
|
||||
#('REQ', account, jid)
|
||||
elif ev[0] == 'AUTH':
|
||||
con.send(common.jabber.Presence(ev[2], 'subscribed'))
|
||||
#('DENY', account, jid)
|
||||
elif ev[0] == 'DENY':
|
||||
con.send(common.jabber.Presence(ev[2], 'unsubscribed'))
|
||||
#('UNSUB', account, jid)
|
||||
elif ev[0] == 'UNSUB':
|
||||
delauth = 1
|
||||
if self.cfgParser.Core.has_key('delauth'):
|
||||
delauth = self.cfgParser.Core['delauth']
|
||||
delroster = 1
|
||||
if self.cfgParser.Core.has_key('delroster'):
|
||||
delroster = self.cfgParser.Core['delroster']
|
||||
if delauth:
|
||||
con.send(common.jabber.Presence(ev[2], 'unsubscribe'))
|
||||
if delroster:
|
||||
con.removeRosterItem(ev[2])
|
||||
#('UNSUB_AGENT', account, agent)
|
||||
elif ev[0] == 'UNSUB_AGENT':
|
||||
con.removeRosterItem(ev[2])
|
||||
con.requestRegInfo(ev[2])
|
||||
agent_info = con.getRegInfo()
|
||||
key = agent_info['key']
|
||||
iq = common.jabber.Iq(to=ev[2], type="set")
|
||||
q = iq.setQuery(common.jabber.NS_REGISTER)
|
||||
q.insertTag('remove')
|
||||
q.insertTag('key').insertData(key)
|
||||
id = con.getAnID()
|
||||
iq.setID(id)
|
||||
con.send(iq)
|
||||
self.hub.sendPlugin('AGENT_REMOVED', ev[1], ev[2])
|
||||
#('UPDUSER', account, (jid, name, groups))
|
||||
elif ev[0] == 'UPDUSER':
|
||||
con.updateRosterItem(jid=ev[2][0], name=ev[2][1], \
|
||||
groups=ev[2][2])
|
||||
#('REQ_AGENTS', account, ())
|
||||
elif ev[0] == 'REQ_AGENTS':
|
||||
agents = con.requestAgents()
|
||||
self.hub.sendPlugin('AGENTS', ev[1], agents)
|
||||
#('REQ_AGENT_INFO', account, agent)
|
||||
elif ev[0] == 'REQ_AGENT_INFO':
|
||||
con.requestRegInfo(ev[2])
|
||||
agent_info = con.getRegInfo()
|
||||
self.hub.sendPlugin('AGENT_INFO', ev[1], (ev[2], agent_info))
|
||||
#('REG_AGENT', account, infos)
|
||||
elif ev[0] == 'REG_AGENT':
|
||||
con.sendRegInfo(ev[2])
|
||||
#('NEW_ACC', (hostname, login, password, name, ressource, prio, \
|
||||
# use_proxy, proxyhost, proxyport))
|
||||
elif ev[0] == 'NEW_ACC':
|
||||
if ev[2][6]:
|
||||
proxy = {'host': ev[2][7], 'port': ev[2][8]}
|
||||
else:
|
||||
proxy = None
|
||||
c = common.jabber.Client(host = ev[2][0], debug = [], \
|
||||
log = None, proxy = proxy)
|
||||
try:
|
||||
c.connect()
|
||||
except IOError, e:
|
||||
log.debug("Couldn't connect to %s %s" % (hostname, e))
|
||||
return 0
|
||||
else:
|
||||
log.debug("Connected to server")
|
||||
c.requestRegInfo()
|
||||
req = c.getRegInfo()
|
||||
c.setRegInfo( 'username', ev[2][1])
|
||||
c.setRegInfo( 'password', ev[2][2])
|
||||
#FIXME: if users already exist, no error message :(
|
||||
if not c.sendRegInfo():
|
||||
print "error " + c.lastErr
|
||||
else:
|
||||
self.hub.sendPlugin('ACC_OK', ev[1], ev[2])
|
||||
#('ACC_CHG', old_account, new_account)
|
||||
elif ev[0] == 'ACC_CHG':
|
||||
self.connected[ev[2]] = self.connected[ev[1]]
|
||||
del self.connected[ev[1]]
|
||||
if con:
|
||||
self.connexions[con] = self.connected[ev[2]]
|
||||
#('ASK_VCARD', account, jid)
|
||||
elif ev[0] == 'ASK_VCARD':
|
||||
iq = common.jabber.Iq(to=ev[2], type="get")
|
||||
iq._setTag('vCard', common.jabber.NS_VCARD)
|
||||
iq.setID(con.getAnID())
|
||||
con.send(iq)
|
||||
#('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...})
|
||||
elif ev[0] == 'VCARD':
|
||||
iq = common.jabber.Iq(type="set")
|
||||
iq.setID(con.getAnID())
|
||||
iq2 = iq._setTag('vCard', common.jabber.NS_VCARD)
|
||||
for i in ev[2].keys():
|
||||
if i != 'jid':
|
||||
if type(ev[2][i]) == type({}):
|
||||
iq3 = iq2.insertTag(i)
|
||||
for j in ev[2][i].keys():
|
||||
iq3.insertTag(j).putData(ev[2][i][j])
|
||||
else:
|
||||
iq2.insertTag(i).putData(ev[2][i])
|
||||
con.send(iq)
|
||||
#('AGENT_LOGGING', account, (agent, type))
|
||||
elif ev[0] == 'AGENT_LOGGING':
|
||||
t = ev[2][1];
|
||||
if not t:
|
||||
t='available';
|
||||
p = common.jabber.Presence(to=ev[2][0], type=t)
|
||||
con.send(p)
|
||||
#('LOG_NB_LINE', account, jid)
|
||||
elif ev[0] == 'LOG_NB_LINE':
|
||||
fic = open(LOGPATH + ev[2], "r")
|
||||
nb = 0
|
||||
while (fic.readline()):
|
||||
nb = nb+1
|
||||
fic.close()
|
||||
self.hub.sendPlugin('LOG_NB_LINE', ev[1], (ev[2], nb))
|
||||
#('LOG_GET_RANGE', account, (jid, line_begin, line_end))
|
||||
elif ev[0] == 'LOG_GET_RANGE':
|
||||
fic = open(LOGPATH + ev[2][0], "r")
|
||||
nb = 0
|
||||
while (nb < ev[2][1] and fic.readline()):
|
||||
nb = nb+1
|
||||
while nb < ev[2][2]:
|
||||
line = fic.readline()
|
||||
nb = nb+1
|
||||
if line:
|
||||
lineSplited = string.split(line, ':')
|
||||
if len(lineSplited) > 2:
|
||||
self.hub.sendPlugin('LOG_LINE', ev[1], (ev[2][0], nb, \
|
||||
lineSplited[0], lineSplited[1], lineSplited[2:]))
|
||||
fic.close()
|
||||
#('REG_MESSAGE', module, list_message)
|
||||
elif ev[0] == 'REG_MESSAGE':
|
||||
for msg in ev[2]:
|
||||
self.hub.register(ev[1], msg)
|
||||
else:
|
||||
log.debug(_("Unknown Command %s") % ev[0])
|
||||
if self.mode == 'server':
|
||||
for con in self.connexions:
|
||||
if self.connected[self.connexions[con]] == 1:
|
||||
con.process(1)
|
||||
#remove connexion that have been broken
|
||||
for acc in self.connected:
|
||||
if self.connected[acc]:
|
||||
break
|
||||
for con in self.connexions:
|
||||
if self.connected[self.connexions[con]] == 1:
|
||||
con.process(1)
|
||||
#remove connexion that have been broken
|
||||
for acc in self.connected:
|
||||
if self.connected[acc]:
|
||||
break
|
||||
for con in self.connexions:
|
||||
if self.connexions[con] == acc:
|
||||
del self.connexions[con]
|
||||
break
|
||||
if self.connexions[con] == acc:
|
||||
del self.connexions[con]
|
||||
break
|
||||
|
||||
time.sleep(0.1)
|
||||
return 0
|
||||
|
||||
# END read_queue
|
||||
|
||||
def read_socket(self):
|
||||
ready_to_read, ready_to_write, in_error = select.select(
|
||||
[self.socket], [], [], 0.1)
|
||||
for sock in ready_to_read:
|
||||
self.data += sock.recv(1024)
|
||||
if not self.data:
|
||||
continue
|
||||
while len(self.data) == 1024:
|
||||
self.data += sock.recv(1024)
|
||||
list_ev = self.unparse_socket()
|
||||
for ev in list_ev:
|
||||
self.hub.sendPlugin(ev[0], ev[1], ev[2])
|
||||
if ev[0] == 'QUIT':
|
||||
sock.close()
|
||||
return 1
|
||||
return 0
|
||||
# END read_socket
|
||||
|
||||
|
||||
def mainLoop(self):
|
||||
"""Main Loop : Read the incomming queue to execute commands comming from
|
||||
plugins and process Jabber"""
|
||||
end = 0
|
||||
while not end:
|
||||
end = self.read_queue()
|
||||
if self.mode == 'client':
|
||||
end = self.read_socket()
|
||||
# END main
|
||||
# END GajimCore
|
||||
|
||||
def loadPlugins(gc):
|
||||
"""Load defaults plugins : plugins in 'modules' option of Core section
|
||||
in ConfFile and register them to the hub"""
|
||||
modStr = gc.cfgParser.Core['modules']
|
||||
if modStr:
|
||||
mods = string.split (modStr, ' ')
|
||||
|
||||
for mod in mods:
|
||||
modObj = gc.hub.newPlugin(mod)
|
||||
modObj.load()
|
||||
# END loadPLugins
|
||||
|
||||
def start():
|
||||
def start(mode='server'):
|
||||
"""Start the Core"""
|
||||
gc = GajimCore()
|
||||
loadPlugins(gc)
|
||||
gc = GajimCore(mode)
|
||||
try:
|
||||
gc.mainLoop()
|
||||
except KeyboardInterrupt:
|
||||
|
|
|
@ -476,6 +476,7 @@ class accountPreference_Window:
|
|||
self.plugin.connected[name] = 0
|
||||
self.plugin.roster.groups[name] = {}
|
||||
self.plugin.roster.contacts[name] = {}
|
||||
self.plugin.nicks[name] = login
|
||||
#refresh accounts window
|
||||
if self.plugin.windows.has_key('accounts'):
|
||||
self.plugin.windows['accounts'].init_accounts()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
import sock
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env python
|
||||
## plugins/sock.py
|
||||
##
|
||||
## Gajim Team:
|
||||
## - Yann Le Boulanger <asterix@crans.org>
|
||||
## - Vincent Hanquez <tab@snarc.org>
|
||||
##
|
||||
## Copyright (C) 2003 Gajim Team
|
||||
##
|
||||
## 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; version 2 only.
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
|
||||
import socket, select
|
||||
import pickle
|
||||
import Queue
|
||||
|
||||
from common import i18n
|
||||
_ = i18n._
|
||||
|
||||
HOST = socket.gethostbyname(socket.gethostname())
|
||||
|
||||
def XMLescape(txt):
|
||||
"Escape XML entities"
|
||||
txt = txt.replace("&", "&")
|
||||
txt = txt.replace("<", "<")
|
||||
txt = txt.replace(">", ">")
|
||||
return txt
|
||||
|
||||
def XMLunescape(txt):
|
||||
"Unescape XML entities"
|
||||
txt = txt.replace(">", ">")
|
||||
txt = txt.replace("<", "<")
|
||||
txt = txt.replace("&", "&")
|
||||
return txt
|
||||
|
||||
class plugin:
|
||||
|
||||
def wait(self, what):
|
||||
"""Wait for a message from Core"""
|
||||
#TODO: timeout
|
||||
temp_q = Queue.Queue(50)
|
||||
while 1:
|
||||
if not self.queueIN.empty():
|
||||
ev = self.queueIN.get()
|
||||
if ev[0] == what and ev[2][0] == 'sock':
|
||||
#Restore messages
|
||||
while not temp_q.empty():
|
||||
ev2 = temp_q.get()
|
||||
self.queueIN.put(ev2)
|
||||
return ev[2][1]
|
||||
else:
|
||||
#Save messages
|
||||
temp_q.put(ev)
|
||||
|
||||
def send(self, event, account, data):
|
||||
self.queueOUT.put((event, account, data))
|
||||
|
||||
def handle_queue_quit(self, account, array):
|
||||
# for sock in self.active_socket:
|
||||
# if sock != self.active_socket:
|
||||
# sock.close()
|
||||
self.quit_recieved = 1
|
||||
|
||||
def handle_socket_reg_message(self, sock, array):
|
||||
for type in array:
|
||||
if self.message_types.has_key(type):
|
||||
if not sock in self.message_types[type]:
|
||||
self.message_types[type].append(sock)
|
||||
else:
|
||||
self.message_types[type] = [sock]
|
||||
|
||||
def send_to_socket(self, ev, sock):
|
||||
evp = pickle.dumps(ev)
|
||||
sock.send('<'+XMLescape(evp)+'>')
|
||||
|
||||
def unparse_socket(self, data):
|
||||
list_ev = []
|
||||
while data:
|
||||
deb = data.find('<')
|
||||
end = data.find('>', deb)
|
||||
list_ev.append(pickle.loads(data[deb+1:end]))
|
||||
data = data[end+1:]
|
||||
return list_ev
|
||||
|
||||
def read_queue(self):
|
||||
while self.queueIN.empty() == 0:
|
||||
ev = self.queueIN.get()
|
||||
# print 'sock recieved ', ev, ' from queue'
|
||||
if ev[0] in self.message_types:
|
||||
for sock in self.message_types[ev[0]]:
|
||||
self.send_to_socket(ev, sock)
|
||||
if ev[0] == 'QUIT':
|
||||
self.handle_queue_quit(ev[1], ev[2])
|
||||
# return 1
|
||||
return 0
|
||||
|
||||
def read_socket(self):
|
||||
ready_to_read, ready_to_write, in_error = select.select(
|
||||
self.active_socket, [], [], 0.1)
|
||||
|
||||
for sock in ready_to_read:
|
||||
if sock == self.socket:
|
||||
conn, addr = self.socket.accept()
|
||||
# Connected by addr
|
||||
self.active_socket.append(conn)
|
||||
else:
|
||||
try:
|
||||
data = sock.recv(1024)
|
||||
except:
|
||||
self.active_socket.remove(sock)
|
||||
break
|
||||
if not data:
|
||||
# disconnected
|
||||
self.active_socket.remove(sock)
|
||||
break
|
||||
while len(data) == 1024:
|
||||
data += sock.recv(1024)
|
||||
list_ev = self.unparse_socket(data)
|
||||
for ev in list_ev:
|
||||
# print 'sock recieved ', ev, ' from socket'
|
||||
if ev[0] == 'REG_MESSAGE':
|
||||
self.handle_socket_reg_message(sock, ev[2])
|
||||
ev = (ev[0], 'sock', ev[2])
|
||||
self.queueOUT.put(ev)
|
||||
return 0
|
||||
|
||||
def __init__(self, quIN, quOUT):
|
||||
self.queueIN = quIN
|
||||
self.queueOUT = quOUT
|
||||
self.send('REG_MESSAGE', 'sock', ['QUIT', 'CONFIG'])
|
||||
quOUT.put(('ASK_CONFIG', None, ('sock', 'sock', {\
|
||||
'port':8255})))
|
||||
self.config = self.wait('CONFIG')
|
||||
self.message_types = {}
|
||||
#create socket
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.socket.bind((HOST, self.config['port']))
|
||||
self.socket.listen(5)
|
||||
|
||||
self.active_socket = [self.socket]
|
||||
end = 0
|
||||
self.quit_recieved = 0
|
||||
|
||||
while not end:
|
||||
# listen to the socket
|
||||
end = self.read_socket()
|
||||
# listen to the input Queue
|
||||
end = self.read_queue()
|
||||
if self.quit_recieved:
|
||||
if len(self.active_socket) == 1:
|
||||
end = 1
|
||||
print _("plugin sock stopped")
|
||||
|
||||
if __name__ == "__main__":
|
||||
plugin(None, None)
|
||||
|
||||
print _("plugin sock loaded")
|
26
runCore.py
26
runCore.py
|
@ -19,9 +19,6 @@
|
|||
|
||||
import logging
|
||||
logging.basicConfig()
|
||||
import sys
|
||||
|
||||
sys.path.append("..")
|
||||
|
||||
import common
|
||||
import core
|
||||
|
@ -30,5 +27,26 @@ from common import i18n
|
|||
i18n.init()
|
||||
_ = i18n._
|
||||
|
||||
core.core.start()
|
||||
import getopt, sys
|
||||
|
||||
def usage():
|
||||
print "usage :", sys.argv[0], ' [OPTION]'
|
||||
print " -c\tlaunch Gajim as a client of a Gajim server"
|
||||
print " -h, --help\tdisplay this help and exit"
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "ch", ["help"])
|
||||
except getopt.GetoptError:
|
||||
# print help information and exit:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
mode = 'server'
|
||||
for o, a in opts:
|
||||
if o == '-c':
|
||||
mode = 'client'
|
||||
if o in ("-h", "--help"):
|
||||
usage()
|
||||
sys.exit()
|
||||
|
||||
core.core.start(mode)
|
||||
print _("Core Stopped")
|
||||
|
|
Loading…
Reference in New Issue