From 51003f471221c139afc7653f18ba727ea79929d0 Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Tue, 12 Apr 2005 11:46:20 +0000
Subject: [PATCH] remove the old plugin system new connection and GnuPG class

---
 Core/GnuPG.py      |  194 +++++++
 Core/connection.py |  746 +++++++++++++++++++++++++++
 Core/core.py       | 1226 --------------------------------------------
 common/hub.py      |  104 ----
 common/plugin.py   |   36 --
 common/thread.py   |   40 --
 6 files changed, 940 insertions(+), 1406 deletions(-)
 create mode 100644 Core/GnuPG.py
 create mode 100644 Core/connection.py
 delete mode 100644 Core/core.py
 delete mode 100644 common/hub.py
 delete mode 100644 common/plugin.py
 delete mode 100644 common/thread.py

diff --git a/Core/GnuPG.py b/Core/GnuPG.py
new file mode 100644
index 0000000000..c637f7154d
--- /dev/null
+++ b/Core/GnuPG.py
@@ -0,0 +1,194 @@
+##	Core/GnuPG.py
+##
+## Gajim Team:
+##	- Yann Le Boulanger <asterix@lagaule.org>
+##	- Vincent Hanquez <tab@snarc.org>
+##	- Nikos Kouremenos <nkour@jabber.org>
+##
+##	Copyright (C) 2003-2005 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.
+##
+
+from tempfile import *
+
+USE_GPG = 1
+
+try:
+	import GnuPGInterface
+except:
+	USE_GPG = 0
+
+class  GnuPG(GnuPGInterface.GnuPG):
+	def __init__(self):
+		GnuPGInterface.GnuPG.__init__(self)
+		self._setup_my_options()
+
+	def _setup_my_options(self):
+		self.options.armor = 1
+		self.options.meta_interactive = 0
+		self.options.extra_args.append('--no-secmem-warning')
+		# Nolith's patch - prevent crashs on non fully-trusted keys
+		self.options.extra_args.append('--always-trust')
+
+	def _read_response(self, child_stdout):
+		# Internal method: reads all the output from GPG, taking notice
+		# only of lines that begin with the magic [GNUPG:] prefix.
+		# (See doc/DETAILS in the GPG distribution for info on GPG's
+		# output when --status-fd is specified.)
+		#
+		# Returns a dictionary, mapping GPG's keywords to the arguments
+		# for that keyword.
+
+		resp = {}
+		while 1:
+			line = child_stdout.readline()
+			if line == "": break
+			line = line.rstrip()
+			if line[0:9] == '[GNUPG:] ':
+				# Chop off the prefix
+				line = line[9:]
+				L = line.split(None, 1)
+				keyword = L[0]
+				if len(L) > 1:
+					resp[ keyword ] = L[1]
+				else:
+					resp[ keyword ] = ""
+		return resp
+
+	def encrypt(self, str, recipients):
+		if not USE_GPG:
+			return str
+		self.options.recipients = recipients   # a list!
+
+		proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout'])
+		proc.handles['stdin'].write(str)
+		proc.handles['stdin'].close()
+
+		output = proc.handles['stdout'].read()
+		proc.handles['stdout'].close()
+
+		try: proc.wait()
+		except IOError: pass
+		return self._stripHeaderFooter(output)
+
+	def decrypt(self, str, keyID):
+		if not USE_GPG:
+			return str
+		proc = self.run(['--decrypt', '-q', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status'])
+		enc = self._addHeaderFooter(str, 'MESSAGE')
+		proc.handles['stdin'].write(enc)
+		proc.handles['stdin'].close()
+	
+		output = proc.handles['stdout'].read()
+		proc.handles['stdout'].close()
+
+		resp = proc.handles['status'].read()
+		proc.handles['status'].close()
+
+		try: proc.wait()
+		except IOError: pass
+		return output
+
+	def sign(self, str, keyID):
+		if not USE_GPG:
+			return str
+		proc = self.run(['-b', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status', 'stderr'])
+		proc.handles['stdin'].write(str)
+		proc.handles['stdin'].close()
+
+		output = proc.handles['stdout'].read()
+		proc.handles['stdout'].close()
+		proc.handles['stderr'].close()
+
+		stat = proc.handles['status']
+		resp = self._read_response(stat)
+		proc.handles['status'].close()
+
+		try: proc.wait()
+		except IOError: pass
+		if resp.has_key('BAD_PASSPHRASE'):
+			return 'BAD_PASSPHRASE'
+		elif resp.has_key('GOOD_PASSPHRASE'):
+			return self._stripHeaderFooter(output)
+
+	def verify(self, str, sign):
+		if not USE_GPG:
+			return str
+		if not str:
+			return ''
+		file = TemporaryFile(prefix='gajim')
+		fd = file.fileno()
+		file.write(str)
+		file.seek(0)
+	
+		proc = self.run(['--verify', '--enable-special-filenames', '-', '-&%s'%fd], create_fhs=['stdin', 'status', 'stderr'])
+
+		file.close()
+		sign = self._addHeaderFooter(sign, 'SIGNATURE')
+		proc.handles['stdin'].write(sign)
+		proc.handles['stdin'].close()
+		proc.handles['stderr'].close()
+
+		stat = proc.handles['status']
+		resp = self._read_response(stat)
+		proc.handles['status'].close()
+
+		try: proc.wait()
+		except IOError: pass
+
+		keyid = ''
+		if resp.has_key('GOODSIG'):
+			keyid = resp['GOODSIG'].split()[0]
+		elif resp.has_key('BADSIG'):
+			keyid = resp['BADSIG'].split()[0]
+		return keyid
+
+	def get_secret_keys(self):
+		if not USE_GPG:
+			return
+		proc = self.run(['--with-colons', '--list-secret-keys'], \
+			create_fhs=['stdout'])
+		output = proc.handles['stdout'].read()
+		proc.handles['stdout'].close()
+
+		keys = {}
+		lines = output.split('\n')
+		for line in lines:
+			sline = line.split(':')
+			if sline[0] == 'sec':
+				keys[sline[4][8:]] = sline[9]
+		return keys
+		try: proc.wait()
+		except IOError: pass
+
+	def _stripHeaderFooter(self, data):
+		"""Remove header and footer from data"""
+		lines = data.split('\n')
+		while lines[0] != '':
+			lines.remove(lines[0])
+		while lines[0] == '':
+			lines.remove(lines[0])
+		i = 0
+		for line in lines:
+			if line:
+				if line[0] == '-': break
+			i = i+1
+		line = '\n'.join(lines[0:i])
+		return line
+
+	def _addHeaderFooter(self, data, type):
+		"""Add header and footer from data"""
+		out = "-----BEGIN PGP %s-----\n" % type
+		out = out + "Version: PGP\n"
+		out = out + "\n"
+		out = out + data + "\n"
+		out = out + "-----END PGP %s-----\n" % type
+		return out
diff --git a/Core/connection.py b/Core/connection.py
new file mode 100644
index 0000000000..a794b9d587
--- /dev/null
+++ b/Core/connection.py
@@ -0,0 +1,746 @@
+##	Core/connection.py
+##
+## Gajim Team:
+##	- Yann Le Boulanger <asterix@lagaule.org>
+##	- Vincent Hanquez <tab@snarc.org>
+##	- Nikos Kouremenos <nkour@jabber.org>
+##
+##	Copyright (C) 2003-2005 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 sys
+import os
+import time
+
+import common.jabber
+
+from Core import GnuPG
+
+from common import i18n
+_ = i18n._
+
+
+STATUS_LIST = ['offline', 'connecting', 'online', 'away', 'xa', 'dnd', \
+	'invisible']
+
+distro_info = {
+	'Arch Linux': '/etc/arch-release',\
+	'Aurox Linux': '/etc/aurox-release',\
+	'Conectiva Linux': '/etc/conectiva-release',\
+	'Debian GNU/Linux': '/etc/debian_release',\
+	'Debian GNU/Linux': '/etc/debian_version',\
+	'Fedora Linux': '/etc/fedora-release',\
+	'Gentoo Linux': '/etc/gentoo-release',\
+	'Mandrake Linux': '/etc/mandrake-release',\
+	'Slackware Linux': '/etc/slackware-release',\
+	'Slackware Linux': '/etc/slackware-version',\
+	'Solaris/Sparc': '/etc/release',\
+	'Sun JDS': '/etc/sun-release',\
+	'Novell SUSE Linux': '/etc/SuSE-release',\
+	'PLD Linux': '/etc/pld-release',\
+	'SUSE Linux': '/etc/SuSE-release',\
+	'Yellow Dog Linux': '/etc/yellowdog-release',\
+	# many distros use the /etc/redhat-release for compatibility
+	# so Redhat is the last
+	'Redhat Linux': '/etc/redhat-release'\
+}
+
+def get_os_info():
+	if os.name =='nt':
+		return 'windows'
+	elif os.name =='posix':
+		executable = 'lsb_release'
+		params = ' --id --codename --release --short'
+		for path in os.environ['PATH'].split(':'):
+			full_path_to_executable = os.path.join(path, executable)
+			if os.path.exists(full_path_to_executable):
+				command = executable + params
+				child_stdin, child_stdout = os.popen2(command)
+				output = child_stdout.readline().strip()
+				child_stdout.close()
+				child_stdin.close()
+				return output
+		# lsb_release executable not available, so parse files
+		for distro in distro_info:
+			path_to_file = distro_info[distro]
+			if os.path.exists(path_to_file):
+				fd = open(path_to_file)
+				text = fd.read().strip()
+				fd.close()
+				if path_to_file.endswith('version'):
+					text = distro + ' ' + text
+				return text
+	return ''
+
+class connection:
+	"""connection"""
+	def __init__(self, name = None):
+		# dict of function to be calledfor each event
+		self.handlers = {'ROSTER': [], 'WARNING': [], 'ERROR': [], 'STATUS': [], \
+			'NOTIFY': [], 'MSG': [], 'MSGERROR': [], 'SUBSCRIBED': [], \
+			'UNSUBSCRIBED': [], 'SUBSCRIBE': [], 'AGENTS': [], 'AGENT_INFO': [], \
+			'AGENT_INFO_ITEMS': [], 'AGENT_INFO_INFO': [], 'REG_AGENT_INFO': [], \
+			'QUIT': [], 'ACC_OK': [], 'CONFIG': [], 'MYVCARD': [], 'OS_INFO': [], \
+			'VCARD': [], 'LOG_NB_LINE': [], 'LOG_LINE': [], 'VISUAL': [], \
+			'GC_MSG': [], 'GC_SUBJECT': [], 'BAD_PASSPHRASE': [], \
+			'GPG_SECRETE_KEYS': [], 'ROSTER_INFO': [], 'MSGSENT': []}
+		self.name = name
+		self.connected = 0 # offline
+		self.connection = None # Jabber.py instance
+		self.gpg = None
+		self.myVCardID = []
+		if name:
+			self.password = gajim.config.get_per('accounts', name, 'hostname')
+			if USE_GPG:
+				self.gpg = GnuPG.GnuPG()
+	# END __init__
+
+	def dispatch(self, event, data):
+		if not event in self.handlers:
+			return
+		for handler in self.handlers[event]:
+			handler(self.name, data)
+
+	def _vCardCB(self, con, vc):
+		"""Called when we recieve a vCard
+		Parse the vCard and send it to plugins"""
+		vcard = {'jid': vc.getFrom().getStripped()}
+		if vc._getTag('vCard') == common.jabber.NS_VCARD:
+			card = vc.getChildren()[0]
+			for info in card.getChildren():
+				if info.getChildren() == []:
+					vcard[info.getName()] = info.getData()
+				else:
+					vcard[info.getName()] = {}
+					for c in info.getChildren():
+						 vcard[info.getName()][c.getName()] = c.getData()
+			if vc.getID() in self.myVCardID:
+				self.myVCardID.remove(vc.getID())
+				self.dispatch('MYVCARD', vcard)
+			else:
+				self.dispatch('VCARD', vcard)
+
+	def _messageCB(self, con, msg):
+		"""Called when we recieve a message"""
+		typ = msg.getType()
+		tim = msg.getTimestamp()
+		tim = time.strptime(tim, '%Y%m%dT%H:%M:%S')
+		msgtxt = msg.getBody()
+		xtags = msg.getXNodes()
+		encTag = None
+		decmsg = ''
+		for xtag in xtags:
+			if xtag.getNamespace() == common.jabber.NS_XENCRYPTED:
+				encTag = xtag
+				break
+		if encTag and USE_GPG:
+			#decrypt
+			encmsg = encTag.getData()
+			
+			keyID = gajim.config.get_per('accounts', self.name, 'keyid')
+			if keyID:
+				decmsg = self.gpg.decrypt(encmsg, keyID)
+		if decmsg:
+			msgtxt = decmsg
+		if typ == 'error':
+			self.dispatch('MSGERROR', (str(msg.getFrom()), \
+				msg.getErrorCode(), msg.getError(), msgtxt, tim))
+		elif typ == 'groupchat':
+			subject = msg.getSubject()
+			if subject:
+				self.dispatch('GC_SUBJECT', (str(msg.getFrom()), subject))
+			else:
+				self.dispatch('GC_MSG', (str(msg.getFrom()), msgtxt, tim))
+		else:
+			self.dispatch('MSG', (str(msg.getFrom()), msgtxt, tim))
+	# END messageCB
+
+	def _presenceCB(self, con, prs):
+		"""Called when we recieve a presence"""
+#		if prs.getXNode(common.jabber.NS_DELAY): return
+		who = str(prs.getFrom())
+		prio = prs.getPriority()
+		if not prio:
+			prio = 0
+		typ = prs.getType()
+		if typ == None: typ = 'available'
+		gajim.log.debug('PresenceCB : %s' % typ)
+		xtags = prs.getXNodes()
+		sigTag = None
+		keyID = ''
+		status = prs.getStatus()
+		for xtag in xtags:
+			if xtag.getNamespace() == common.jabber.NS_XSIGNED:
+				sigTag = xtag
+				break
+		if sigTag and USE_GPG:
+			#verify
+			sigmsg = sigTag.getData()
+			keyID = self.gpg.verify(status, sigmsg)
+		if typ == 'available':
+			show = prs.getShow()
+			if not show:
+				show = 'online'
+			self.dispatch('NOTIFY', (prs.getFrom().getStripped(), show, status, \
+				prs.getFrom().getResource(), prio, keyID, prs.getRole(), \
+				prs.getAffiliation(), prs.getJid(), prs.getReason(), \
+				prs.getActor(), prs.getStatusCode()))
+		elif typ == 'unavailable':
+			self.dispatch('NOTIFY', (prs.getFrom().getStripped(), 'offline', \
+				status, prs.getFrom().getResource(), prio, keyID, prs.getRole(), \
+				prs.getAffiliation(), prs.getJid(), prs.getReason(), \
+				prs.getActor(), prs.getStatusCode()))
+		elif typ == 'subscribe':
+			gajim.log.debug('subscribe request from %s' % who)
+			if gajim.config.get('alwaysauth') or who.find("@") <= 0:
+				if self.connection:
+					self.connection.send(common.jabber.Presence(who, 'subscribed'))
+				if who.find("@") <= 0:
+					self.dispatch('NOTIFY', (prs.getFrom().getStripped(), \
+						'offline', 'offline', prs.getFrom().getResource(), prio, \
+						keyID, None, None, None, None, None, None))
+			else:
+				if not status:
+					status = _('I would like to add you to my roster.')
+				self.dispatch('SUBSCRIBE', (who, status))
+		elif typ == 'subscribed':
+			jid = prs.getFrom()
+			self.dispatch('SUBSCRIBED', (jid.getStripped(), jid.getResource()))
+			self.dispatch('UPDUSER', (jid.getStripped(), jid.getNode(), \
+				['General'])))
+			#BE CAREFUL : no con.updateRosterItem() in a callback
+			gajim.log.debug('we are now subscribed to %s' % who)
+		elif typ == 'unsubscribe':
+			gajim.log.debug('unsubscribe request from %s' % who)
+		elif typ == 'unsubscribed':
+			gajim.log.debug('we are now unsubscribed to %s' % who)
+			self.dispatch('UNSUBSCRIBED', prs.getFrom().getStripped())
+		elif typ == 'error':
+			errmsg = prs.getError()
+			errcode = prs.getErrorCode()
+			if errcode == '400': #Bad Request: JID Malformed or Private message when not allowed
+				pass
+			elif errcode == '401': #No Password Provided
+				pass
+			elif errcode == '403':	#forbidden :	User is Banned
+											#					Unauthorized Subject Change
+											#					Attempt by Mere Member to Invite Others to a Members-Only Room
+											#					Configuration Access to Non-Owner
+											#					Attempt by Non-Owner to Modify Owner List
+											#					Attempt by Non-Owner to Modify Admin List
+											#					Destroy Request Submitted by Non-Owner
+				pass
+			elif errcode == '404':	#item not found :	Room Does Not Exist
+				pass
+			elif errcode == '405':	#Not allowed :	Attempt to Kick Moderator, Admin, or Owner
+											#					Attempt to Ban an Admin or Owner
+											#					Attempt to Revoke Voice from an Admin, Owner, or User with a Higher Affiliation
+											#					Attempt to Revoke Moderator Privileges from an Admin or Owner
+				pass
+			elif errcode == '407':	#registration required :	User Is Not on Member List
+											#									
+				pass
+			elif errcode == '409':	#conflict :	Nick Conflict
+				self.dispatch('ERROR', errmsg)
+			else:
+				self.dispatch('NOTIFY', (prs.getFrom().getStripped(), 'error', \
+					errmsg, prs.getFrom().getResource(), prio, keyID, None, None, \
+					None,  None, None, None))
+	# END presenceCB
+
+	def _disconnectedCB(self, con):
+		"""Called when we are disconnected"""
+		gajim.log.debug('disconnectedCB')
+		if self.connection:
+			self.connected = 0
+			self.dispatch('STATUS', 'offline')
+	# END disconenctedCB
+
+	def _rosterSetCB(self, con, iq_obj):
+		for item in iq_obj.getQueryNode().getChildren():
+			jid  = item.getAttr('jid')
+			name = item.getAttr('name')
+			sub  = item.getAttr('subscription')
+			ask  = item.getAttr('ask')
+			groups = []
+			for group in item.getTags('group'):
+				groups.append(group.getData())
+			self.dispatch('ROSTER_INFO', (jid, name, sub, ask, groups))
+
+	def _BrowseResultCB(self, con, iq_obj):
+		identities, features, items = [], [], []
+		q = iq_obj.getTag('service')
+		if not q:
+			return identities, features, items
+		attr = {}
+		for key in q.attrs:
+			attr[key.encode('utf8')] = q.attrs[key].encode('utf8')
+		identities = [attr]
+		for node in q.kids:
+			if node.getName() == 'ns':
+				features.append(node.getData())
+			else:
+				infos = {}
+				for key in node.attrs:
+					infos[key.encode('utf8')] = node.attrs[key].encode('utf8')
+				infos['category'] = node.getName()
+				items.append(infos)
+		jid = str(iq_obj.getFrom())
+		self.dispatch('AGENT_INFO', (jid, identities, features, items))
+
+	def _DiscoverItemsCB(self, con, iq_obj):
+		qp = iq_obj.getQueryPayload()
+		items = []
+		if not qp:
+			qp = []
+		for i in qp:
+			attr = {}
+			for key in i.attrs:
+				attr[key.encode('utf8')] = i.attrs[key].encode('utf8')
+			items.append(attr)
+		jid = str(iq_obj.getFrom())
+		self.dispatch('AGENT_INFO_ITEMS', (jid, items))
+
+	def _DiscoverInfoErrorCB(self, con, iq_obj):
+		jid = str(iq_obj.getFrom())
+		con.browseAgents(jid)
+
+	def _DiscoverInfoCB(self, con, iq_obj):
+		# According to JEP-0030:
+		# For identity: category, name is mandatory, type is optional.
+		# For feature: var is mandatory
+		identities, features = [], []
+		qp = iq_obj.getQueryPayload()
+		if not qp:
+			qp = []
+		for i in qp:
+			if i.getName() == 'identity':
+				attr = {}
+				for key in i.attrs:
+					attr[key.encode('utf8')] = i.attrs[key].encode('utf8')
+				identities.append(attr)
+			elif i.getName() == 'feature':
+				features.append(i.getAttr('var'))
+		jid = str(iq_obj.getFrom())
+		if not identities:
+			self.connection.browseAgents(jid)
+		else:
+			self.dispatch('AGENT_INFO_INFO', (jid, identities, features))
+			self.connection.discoverItems(jid)
+
+	def _VersionCB(self, con, iq_obj):
+		f = iq_obj.getFrom()
+		iq_obj.setFrom(iq_obj.getTo())
+		iq_obj.setTo(f)
+		iq_obj.setType('result')
+		qp = iq_obj.getTag('query')
+		qp.insertTag('name').insertData('Gajim')
+		qp.insertTag('version').insertData(version.version)
+		no_send_os = gajim.config.get('do_not_send_os_info')
+		if not no_send_os:
+			qp.insertTag('os').insertData(get_os_info())
+		self.connection.send(iq_obj)
+
+	def _VersionResultCB(self, con, iq_obj):
+		client_info = ''
+		os_info = ''
+		qp = iq_obj.getTag('query')
+		if qp.getTag('name'):
+			client_info += qp.getTag('name').getData()
+		if qp.getTag('version'):
+			client_info += ' ' + qp.getTag('version').getData()
+		if qp.getTag('os'):
+			os_info += qp.getTag('os').getData()
+		jid = iq_obj.getFrom().getStripped()
+		self.dispatch('OS_INFO', (jid, client_info, os_info))
+
+	def connect(self):
+		"""Connect and authentificate to the Jabber server"""
+		self.connected = 1
+		hostname = gajim.config.get_per('accounts', self.name, 'hostname')
+		resource = gajim.config.get_per('accounts', self.name, 'resource')
+
+		#create connexion if it doesn't already existe
+		if not self.connection:
+			if gajim.config.get_per('accounts', self.name, 'use_proxy')
+				proxy = {'host': gajim.config.get_per('accounts', self.name, \
+					'proxyhost')
+				proxy['port'] = gajim.config.get_per('accounts', self.name, \
+					'proxyport')
+			else:
+				proxy = None
+			if gajim.log:
+				self.connection = common.jabber.Client(host = hostname, debug = [],\
+				log = sys.stderr, connection=common.xmlstream.TCP, port=5222, \
+				proxy = proxy)
+			else:
+				con = common.jabber.Client(host = hostname, debug = [], log = None,\
+				connection=common.xmlstream.TCP, port=5222, proxy = proxy)
+				#debug = [common.jabber.DBG_ALWAYS], log = sys.stderr, \
+				#connection=common.xmlstream.TCP_SSL, port=5223, proxy = proxy)
+			self.connection.setDisconnectHandler(self.disconnectedCB)
+			self.connection.registerHandler('message', self.messageCB)
+			self.connection.registerHandler('presence', self.presenceCB)
+			self.connection.registerHandler('iq',self.vCardCB,'result')
+			self.connection.registerHandler('iq',self.rosterSetCB,'set', \
+				common.jabber.NS_ROSTER)
+			self.connection.registerHandler('iq',self.BrowseResultCB,'result', \
+				common.jabber.NS_BROWSE)
+			self.connection.registerHandler('iq',self.DiscoverItemsCB,'result', \
+				common.jabber.NS_P_DISC_ITEMS)
+			self.connection.registerHandler('iq',self.DiscoverInfoCB,'result', \
+				common.jabber.NS_P_DISC_INFO)
+			self.connection.registerHandler('iq',self.DiscoverInfoErrorCB,'error',\
+				common.jabber.NS_P_DISC_INFO)
+			self.connection.registerHandler('iq',self.VersionCB,'get', \
+				common.jabber.NS_VERSION)
+			self.connection.registerHandler('iq',self.VersionResultCB,'result', \
+				common.jabber.NS_VERSION)
+		try:
+			self.connection.connect()
+		except:
+			gajim.log.debug("Couldn't connect to %s %s" % (hostname, e))
+			self.dispatch('STATUS', 'offline')
+			self.dispatch('ERROR', _('Couldn\'t connect to %s') \
+				% hostname)
+			self.connected = 0
+			return -1
+
+		gajim.log.debug('Connected to server')
+
+		if self.connection.auth(self.name, self.password, resource):
+			self.connection.requestRoster()
+			roster = self.connection.getRoster().getRaw()
+			if not roster :
+				roster = {}
+			self.dispatch('ROSTER', (0, roster))
+			self.connected = 2
+			return 0
+		else:
+			log.debug('Couldn\'t authentificate to %s' % hostname)
+			self.dispatch('STATUS', 'offline')
+			self.dispatch('ERROR', _('Authentification failed with %s, check your login and password') % hostname)
+			self.connected = 0
+			return -1
+# END connect
+
+	def register_handler(self, event, funtion):
+		if event in self.handlers:
+			self.handlers[event].append(function)
+
+	def unregister_handler(self, event, funtion):
+		if event in self.handlers:
+			if function in self.handlers[event]:
+				self.handlers[event].remove(function)
+
+	def quit(self, kill_core):
+		if kill_core:
+			if self.connected > 1:
+				self.connected = 0
+				self.connection.disconnect('Disconnected')
+			self.dispatch('QUIT', ())
+			return
+
+	def ask_roster(self):
+		roster = {}
+		if self.connection:
+			roster = self.connection.getRoster().getRaw()
+		return roster
+	
+	def change_status(self, status, msg):
+		if not status in STATUS_LIST:
+			return -1
+		if not msg:
+			msg = status
+		signed = ''
+		keyID = gajim.config.get_per('accounts', self.name, 'keyid')
+		if keyID and USE_GPG:
+			signed = self.gpg.sign(msg, keyID)
+			if signed == 'BAD_PASSPHRASE':
+				signed = ''
+				if self.connected < 2:
+					self.dispatch('BAD_PASSPHRASE', ())
+		if (status != 'offline') and (self.connected == 0):
+			self.connect()
+			if self.connected == 2:
+				self.connected = STATUS_LIST.index(status)
+				#send our presence
+				typ = 'available'
+				if status == 'invisible':
+					typ = 'invisible'
+				prio = gajim.config.get_per('accounts', self.name, 'priority')
+				self.connection.sendPresence(typ, prio, status, msg, signed)
+				self.dispatch('STATUS', status)
+				#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 (status == 'offline') and self.connected:
+			self.connected = 0
+			self.connection.disconnect(msg)
+			self.dispatch('STATUS', 'offline')
+		elif status != 'offline' and self.connected:
+			self.connected = STATUS_LIST.index(status)
+			typ = 'available'
+			if status == 'invisible':
+				typ = 'invisible'
+			prio = gajim.config.get_per('accounts', self.name, 'priority')
+			self.connection.sendPresence(typ, prio, status, msg, signed)
+			self.dispatch('STATUS', status)
+
+	def send_message(jid, msg, keyID)
+		if inot self.connection:
+			return
+		msgtxt = msg
+		msgenc = ''
+		if keyID and USE_GPG:
+			#encrypt
+			msgenc = self.gpg.encrypt(msg, keyID)
+			if msgenc: msgtxt = _('[this message is encrypted]')
+		msg_iq = common.jabber.Message(to = jid, body = msgtxt, type = 'chat')
+		if msgenc:
+			msg_iq.setX(common.jabber.NS_XENCRYPTED).insertData(msgenc)
+		self.connection.send(msg_iq)
+		self.dispatch('MSGSENT', (jid, msg, keyID))
+
+	def request_subscription(self, jid, msg)
+		if not self.connection:
+			return
+		gajim.log.debug('subscription request for %s' % jid)
+		pres = common.jabber.Presence(jid, 'subscribe')
+		if not msg:
+			msg = _('I would like to add you to my roster.')
+		pres.setStatus(msg)
+		self.connection.send(pres)
+
+	def send_authorization(self, jid)
+		if not self.connection:
+			return
+		self.connection.send(common.jabber.Presence(jid, 'subscribed'))
+
+	def refuse_authorization(self, jid)
+		if not self.connection:
+			return
+		self.connection.send(common.jabber.Presence(jid, 'unsubscribed'))
+
+	def unsubscribe(self, jid):
+		if not self.connection:
+			return
+		delauth = gajim.config.get('delauth')
+		delroster = gajim.config.get('delroster')
+		if delauth:
+			self.connection.send(common.jabber.Presence(jid, 'unsubscribe'))
+		if delroster:
+			self.connection.removeRosterItem(jid)
+
+	def unsubscribe_agent(self, agent):
+		if not self.connection:
+			return
+		self.connection.removeRosterItem(agent)
+		self.connection.requestRegInfo(agent)
+		agent_info = self.connection.getRegInfo()
+		if not agent_info:
+			return
+		key = agent_info['key']
+		iq = common.jabber.Iq(to=agent, type='set')
+		q = iq.setQuery(common.jabber.NS_REGISTER)
+		q.insertTag('remove')
+		q.insertTag('key').insertData(key)
+		id = self.connection.getAnID()
+		iq.setID(id)
+		self.connection.send(iq)
+		self.dispatch('AGENT_REMOVED', agent)
+
+	def update_user(self, jid, name, groups):
+		if self.connection:
+			self.connection.updateRosterItem(jid=jid, name=name, groups=groups)
+
+	def request_agents(self, jid):
+		if self.connection:
+			self.connection.discoverInfo(jid)
+
+	def ask_register_agent_info(self, agent):
+		if not self.connection:
+			return None
+		self.connection.requestRegInfo(agent)
+		agent_info = self.connection.getRegInfo()
+		return agent_info
+
+	def register_agent(self, info):
+		if not self.connection:
+			return
+		self.connection.sendRegInfo(info)
+
+	def new_account(self, hostname, login, password, name, resource, prio, \
+		use_proxy, proxyhost, proxyport):
+		# If a connection already exist we cannot create a new account
+		if self.connection:
+			return
+		if use_proxy:
+			proxy = {'host': proxyhost, 'port': proxyport}
+		else:
+			proxy = None
+		c = common.jabber.Client(host = hostname, debug = [], \
+			log = None, proxy = proxy)
+		try:
+			c.connect()
+		except:
+			gajim.log.debug('Couldn\'t connect to %s' % hostname)
+			self.dispatch('ERROR', _('Couldn\'t connect to ') + hostname)
+			return 0
+		else:
+			gajim.log.debug(_('Connected to server'))
+			c.requestRegInfo()
+			req = c.getRegInfo()
+			c.setRegInfo( 'username', login)
+			c.setRegInfo( 'password', password)
+			if not c.sendRegInfo():
+				self.dispatch('ERROR', _('Error: ') + c.lastErr)
+			else:
+				self.name = name
+				self.connected = 0
+				self.password = ''
+				if USE_GPG:
+					self.gpg = Core.GnuPG()
+				self.dispatch('ACC_OK', (hostname, login, password, name, \
+					resource, prio, use_proxy, proxyhost, proxyport))
+
+	def account_changed(self, new_name):
+		self.name = new_name
+
+	def request_os_info(self, jid, resource):
+		if not self.connection:
+			return
+		iq = common.jabber.Iq(to=jid + '/' + resource, type = 'get', \
+			query = common.jabber.NS_VERSION)
+		iq.setID(self.connection.getAnID())
+		self.connection.send(iq)
+
+	def request_vcard(self, jid):
+		if not self.connection:
+			return
+		iq = common.jabber.Iq(to = jid, type = 'get')
+		iq._setTag('vCard', common.jabber.NS_VCARD)
+		iq.setID(self.connection.getAnID())
+		self.connection.send(iq)
+			#('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...})
+	
+	def send_vcard(self, vcard):
+		if not self.connection:
+			return
+		iq = common.jabber.Iq(type = 'set')
+		iq.setID(self.connection.getAnID())
+		iq2 = iq._setTag('vCard', common.jabber.NS_VCARD)
+		for i in vcard.keys():
+			if i != 'jid':
+				if type(vcard[i]) == type({}):
+					iq3 = iq2.insertTag(i)
+					for j in vcard[i].keys():
+						iq3.insertTag(j).putData(vcard[i][j])
+				else:
+					iq2.insertTag(i).putData(vcard[i])
+		self.connection.send(iq)
+
+	def send_agent_status(self, agent, typ):
+		if not self.connection:
+			return
+		if not typ:
+			typ = 'available';
+		p = common.jabber.Presence(to = agent, type = typ)
+		self.connection.send(p)
+
+	def join_gc(self, nick, room, server, passwd):
+		if not self.connection:
+			return
+		p = common.jabber.Presence(to = '%s@%s/%s' % (room, server, password))
+		self.connection.send(p)
+
+	def send_gc_message(self, jid, msg):
+		if not self.connection:
+			return
+		msg_iq = common.jabber.Message(jid, msg)
+		msg_iq.setType('groupchat')
+		self.connection.send(msg_iq)
+		self.dispatch('MSGSENT', (jid, msg))
+
+	def send_gc_subject(self, jid, subject):
+		if not self.connection:
+			return
+		msg_iq = common.jabber.Message(jid)
+		msg_iq.setType('groupchat')
+		msg_iq.setSubject(subject)
+		self.connection.send(msg_iq)
+
+	def send_gc_status(self, nick, jid, show, status):
+		if not self.connection:
+			return
+		if show == 'offline':
+			typ = 'unavailable'
+			show = None
+		else:
+			typ = 'available'
+		self.connection.send(common.jabber.Presence(to = '%s/%s' % (jid, nick), \
+			type = typ, show = show, status = status))
+
+	def gc_set_role(self, room_jid, nick, role):
+		if not self.connection:
+			return
+		iq = common.jabber.Iq(type = 'set', to = room_jid)
+		item = iq.setQuery(common.jabber.NS_P_MUC_ADMIN).insertTag('item')
+		item.putAttr('nick', nick)
+		item.putAttr('role', role)
+		id = self.connection.getAnID()
+		iq.setID(id)
+		self.connection.send(iq)
+
+	def gc_set_affiliation(self, room_jid, jid, affiliation):
+		if not self.connection:
+			return
+		iq = common.jabber.Iq(type = 'set', to = room_jid)
+		item = iq.setQuery(common.jabber.NS_P_MUC_ADMIN).insertTag('item')
+		item.putAttr('jid', jid)
+		item.putAttr('affiliation', affiliation)
+		id = self.connection.getAnID()
+		iq.setID(id)
+		self.connection.send(iq)
+
+	def gpg_passphrase(self, passphrase):
+		if USE_GPG:
+			self.gpg.passphrase = passphrase
+
+	def ask_gpg_secrete_keys(self):
+		if USE_GPG:
+			keys = self.gpg.get_secret_keys()
+			return keys
+		return None
+
+	def change_password(self, password, username):
+		if not self.connection:
+			return
+		hostname = gajim.config.get_per('accounts', self.name, 'hostname')
+		iq = common.jabber.Iq(type = 'set', to = hostname)
+		q = iq.setQuery(common.jabber.NS_REGISTER)
+		q.insertTag('username').insertData(username)
+		q.insertTag('password').insertData(password)
+		id = self.connection.getAnID()
+		iq.setID(id)
+		self.connection.send(iq)
+
+	def process(self):
+		if not self.connection:
+			return
+		if self.connected:
+			self.connection.process(1)
+# END GajimCore
diff --git a/Core/core.py b/Core/core.py
deleted file mode 100644
index 50cae4baaf..0000000000
--- a/Core/core.py
+++ /dev/null
@@ -1,1226 +0,0 @@
-##	core/core.py
-##
-## Gajim Team:
-##	- Yann Le Boulanger <asterix@lagaule.org>
-##	- Vincent Hanquez <tab@snarc.org>
-##	- Nikos Kouremenos <nkour@jabber.org>
-##
-##	Copyright (C) 2003-2005 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 sys
-import os
-import time
-import logging
-
-import common.hub
-import common.optparser
-import common.jabber
-import socket
-import select
-import pickle
-import version
-from tempfile import *
-
-from common import i18n
-_ = i18n._
-
-log = logging.getLogger('core.core')
-log.setLevel(logging.DEBUG)
-
-CONFPATH = "~/.gajim/config"
-LOGPATH = os.path.expanduser("~/.gajim/logs/")
-
-distro_info = {
-	'Arch Linux': '/etc/arch-release',\
-	'Aurox Linux': '/etc/aurox-release',\
-	'Conectiva Linux': '/etc/conectiva-release',\
-	'Debian GNU/Linux': '/etc/debian_release',\
-	'Debian GNU/Linux': '/etc/debian_version',\
-	'Fedora Linux': '/etc/fedora-release',\
-	'Gentoo Linux': '/etc/gentoo-release',\
-	'Mandrake Linux': '/etc/mandrake-release',\
-	'Slackware Linux': '/etc/slackware-release',\
-	'Slackware Linux': '/etc/slackware-version',\
-	'Solaris/Sparc': '/etc/release',\
-	'Sun JDS': '/etc/sun-release',\
-	'Novell SUSE Linux': '/etc/SuSE-release',\
-	'PLD Linux': '/etc/pld-release',\
-	'SUSE Linux': '/etc/SuSE-release',\
-	'Yellow Dog Linux': '/etc/yellowdog-release',\
-	# many distros use the /etc/redhat-release for compatibility
-	# so Redhat is the last
-	'Redhat Linux': '/etc/redhat-release'\
-}
-
-def get_os_info():
-	if os.name =='nt':
-		return 'windows'
-	elif os.name =='posix':
-		executable = 'lsb_release'
-		params = ' --id --codename --release --short'
-		for path in os.environ['PATH'].split(':'):
-			full_path_to_executable = os.path.join(path, executable)
-			if os.path.exists(full_path_to_executable):
-				command = executable + params
-				child_stdin, child_stdout = os.popen2(command)
-				output = child_stdout.readline().strip()
-				child_stdout.close()
-				child_stdin.close()
-				return output
-		# lsb_release executable not available, so parse files
-		for distro in distro_info:
-			path_to_file = distro_info[distro]
-			if os.path.exists(path_to_file):
-				fd = open(path_to_file)
-				text = fd.read().strip()
-				fd.close()
-				if path_to_file.endswith('version'):
-					text = distro + ' ' + text
-				return text
-	return ''
-
-def XMLescape(txt):
-	"Escape XML entities"
-	txt = txt.replace("&", "&amp;")
-	txt = txt.replace("<", "&lt;")
-	txt = txt.replace(">", "&gt;")
-	return txt
-
-def XMLunescape(txt):
-	"Unescape XML entities"
-	txt = txt.replace("&gt;", ">")
-	txt = txt.replace("&lt;", "<")
-	txt = txt.replace("&amp;", "&")
-	return txt
-
-USE_GPG = 1
-try:
-	import GnuPGInterface
-except:
-	USE_GPG = 0
-else:	
-	class  MyGnuPG(GnuPGInterface.GnuPG):
-		def __init__(self):
-			GnuPGInterface.GnuPG.__init__(self)
-			self.setup_my_options()
-
-		def setup_my_options(self):
-			self.options.armor = 1
-			self.options.meta_interactive = 0
-			self.options.extra_args.append('--no-secmem-warning')
-			# Nolith's patch - prevent crashs on non fully-trusted keys
-			self.options.extra_args.append('--always-trust')
-
-		def _read_response(self, child_stdout):
-			# Internal method: reads all the output from GPG, taking notice
-			# only of lines that begin with the magic [GNUPG:] prefix.
-			# (See doc/DETAILS in the GPG distribution for info on GPG's
-			# output when --status-fd is specified.)
-			#
-			# Returns a dictionary, mapping GPG's keywords to the arguments
-			# for that keyword.
-
-			resp = {}
-			while 1:
-				line = child_stdout.readline()
-				if line == "": break
-				line = line.rstrip()
-				if line[0:9] == '[GNUPG:] ':
-					# Chop off the prefix
-					line = line[9:]
-					L = line.split(None, 1)
-					keyword = L[0]
-					if len(L) > 1:
-						resp[ keyword ] = L[1]
-					else:
-						resp[ keyword ] = ""
-			return resp
-
-		def encrypt(self, string, recipients):
-			self.options.recipients = recipients   # a list!
-
-			proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout'])
-			proc.handles['stdin'].write(string)
-			proc.handles['stdin'].close()
-
-			output = proc.handles['stdout'].read()
-			proc.handles['stdout'].close()
-
-			try: proc.wait()
-			except IOError: pass
-			return self.stripHeaderFooter(output)
-
-		def decrypt(self, string, keyID):
-			proc = self.run(['--decrypt', '-q', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status'])
-			enc = self.addHeaderFooter(string, 'MESSAGE')
-			proc.handles['stdin'].write(enc)
-			proc.handles['stdin'].close()
-		
-			output = proc.handles['stdout'].read()
-			proc.handles['stdout'].close()
-
-			resp = proc.handles['status'].read()
-			proc.handles['status'].close()
-
-			try: proc.wait()
-			except IOError: pass
-			return output
-	
-		def sign(self, string, keyID):
-			proc = self.run(['-b', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status', 'stderr'])
-			proc.handles['stdin'].write(string)
-			proc.handles['stdin'].close()
-
-			output = proc.handles['stdout'].read()
-			proc.handles['stdout'].close()
-			proc.handles['stderr'].close()
-
-			stat = proc.handles['status']
-			resp = self._read_response(stat)
-			proc.handles['status'].close()
-
-			try: proc.wait()
-			except IOError: pass
-			if resp.has_key('BAD_PASSPHRASE'):
-				return 'BAD_PASSPHRASE'
-			elif resp.has_key('GOOD_PASSPHRASE'):
-				return self.stripHeaderFooter(output)
-
-		def verify(self, str, sign):
-			if not str:
-				return ''
-			file = TemporaryFile(prefix='gajim')
-			fd = file.fileno()
-			file.write(str)
-			file.seek(0)
-		
-			proc = self.run(['--verify', '--enable-special-filenames', '-', '-&%s'%fd], create_fhs=['stdin', 'status', 'stderr'])
-
-			file.close()
-			sign = self.addHeaderFooter(sign, 'SIGNATURE')
-			proc.handles['stdin'].write(sign)
-			proc.handles['stdin'].close()
-			proc.handles['stderr'].close()
-
-			stat = proc.handles['status']
-			resp = self._read_response(stat)
-			proc.handles['status'].close()
-
-			try: proc.wait()
-			except IOError: pass
-
-			keyid = ''
-			if resp.has_key('GOODSIG'):
-				keyid = resp['GOODSIG'].split()[0]
-			elif resp.has_key('BADSIG'):
-				keyid = resp['BADSIG'].split()[0]
-			return keyid
-
-		def get_secret_keys(self):
-			proc = self.run(['--with-colons', '--list-secret-keys'], \
-				create_fhs=['stdout'])
-			output = proc.handles['stdout'].read()
-			proc.handles['stdout'].close()
-
-			keys = {}
-			lines = output.split('\n')
-			for line in lines:
-				sline = line.split(':')
-				if sline[0] == 'sec':
-					keys[sline[4][8:]] = sline[9]
-			return keys
-			try: proc.wait()
-			except IOError: pass
-
-		def stripHeaderFooter(self, data):
-			"""Remove header and footer from data"""
-			lines = data.split('\n')
-			while lines[0] != '':
-				lines.remove(lines[0])
-			while lines[0] == '':
-				lines.remove(lines[0])
-			i = 0
-			for line in lines:
-				if line:
-					if line[0] == '-': break
-				i = i+1
-			line = '\n'.join(lines[0:i])
-			return line
-
-		def addHeaderFooter(self, data, type):
-			"""Add header and footer from data"""
-			out = "-----BEGIN PGP %s-----\n" % type
-			out = out + "Version: PGP\n"
-			out = out + "\n"
-			out = out + data + "\n"
-			out = out + "-----END PGP %s-----\n" % type
-			return out
-
-class GajimCore:
-	"""Core"""
-	def __init__(self, mode='client'):
-		self.mode = mode
-		self.log = 0
-		self.init_cfg_file()
-		if mode == 'client':
-			self.data = ''
-			self.connect_core()
-		self.hub = common.hub.GajimHub()
-		if self.log:
-			log.setLevel(logging.DEBUG)
-		else:
-			log.setLevel(None)
-		if mode == 'server':
-			self.connected = {}
-			#connections {con: name, ...}
-			self.connections = {}
-			self.gpg = {}
-			self.passwords = {}
-			if USE_GPG:
-				self.gpg_common = MyGnuPG()
-			for a in self.accounts:
-				self.connected[a] = 0 #0:offline, 1:online, 2:away,
-											 #3:xa, 4:dnd, 5:invisible
-				if self.cfgParser.tab[a].has_key("password"):
-					self.passwords[a] = self.cfgParser.tab[a]["password"]
-				else:
-					self.passwords[a] = ' '
-				if USE_GPG:
-					self.gpg[a] = MyGnuPG()
-			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 = moduleStr.split(' ')
-
-			for mod in mods:
-				try:
-					modObj = self.hub.newPlugin(mod)
-				except:
-					print _("The plugin %s cannot be launched" % mod)
-				if not modObj:
-					print _("The plugin %s is already launched" % mod)
-					return
-				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':
-			default_tab = {'Profile': {'accounts': '', 'log': 0}, 'Core': \
-				{'delauth': 1, 'alwaysauth': 0, 'modules': 'logger gtkgui', \
-				'delroster': 1}}
-		else:
-			default_tab = {'Profile': {'log': 0}, 'Core_client': {'host': \
-			'localhost', 'port': 8255, 'modules': 'gtkgui'}}
-		fname = os.path.expanduser(CONFPATH)
-		reps = fname.split('/')
-		path = ''
-		while len(reps) > 1:
-			path = path + reps[0] + '/'
-			del reps[0]
-			try:
-				os.stat(os.path.expanduser(path))
-			except OSError:
-				try:
-					os.mkdir(os.path.expanduser(path))
-				except:
-					print _("Can't create %s") % path
-					sys.exit
-		try:
-			os.stat(fname)
-		except:
-			print _("creating %s") % fname
-			fic = open(fname, "w")
-			import stat
-			os.chmod(fname, stat.S_IRUSR | stat.S_IWUSR)
-			fic.close()
-		self.cfgParser = common.optparser.OptionsParser(CONFPATH)
-		for part in default_tab.keys():
-			if not self.cfgParser.tab.has_key(part):
-				self.cfgParser.tab[part] = {}
-			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.parse()
-	# END init_cfg_file
-
-	def parse(self):
-		"""Parse configuratoin file and create self.accounts"""
-		self.cfgParser.parseCfgFile()
-		if self.cfgParser.tab.has_key('Profile'):
-			if self.cfgParser.tab['Profile'].has_key('log'):
-				self.log = self.cfgParser.tab['Profile']['log']
-			if self.mode == 'server':
-				self.accounts = {}
-				if self.cfgParser.tab['Profile'].has_key('accounts'):
-					accts = self.cfgParser.tab['Profile']['accounts'].split(' ')
-					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
-		Parse the vCard and send it to plugins"""
-		vcard = {'jid': vc.getFrom().getStripped()}
-		if vc._getTag('vCard') == common.jabber.NS_VCARD:
-			card = vc.getChildren()[0]
-			for info in card.getChildren():
-				if info.getChildren() == []:
-					vcard[info.getName()] = info.getData()
-				else:
-					vcard[info.getName()] = {}
-					for c in info.getChildren():
-						 vcard[info.getName()][c.getName()] = c.getData()
-			if vc.getID() in self.myVCardID:
-				self.myVCardID.remove(vc.getID())
-				self.hub.sendPlugin('MYVCARD', self.connections[con], vcard)
-			else:
-				self.hub.sendPlugin('VCARD', self.connections[con], vcard)
-
-	def messageCB(self, con, msg):
-		"""Called when we recieve a message"""
-		typ = msg.getType()
-		tim = msg.getTimestamp()
-		tim = time.strptime(tim, "%Y%m%dT%H:%M:%S")
-		msgtxt = msg.getBody()
-		xtags = msg.getXNodes()
-		encTag = None
-		decmsg = ''
-		for xtag in xtags:
-			if xtag.getNamespace() == common.jabber.NS_XENCRYPTED:
-				encTag = xtag
-				break
-		if encTag and USE_GPG:
-			#decrypt
-			encmsg = encTag.getData()
-			keyID = ''
-			if self.cfgParser.tab[self.connections[con]].has_key("keyid"):
-				keyID = self.cfgParser.tab[self.connections[con]]["keyid"]
-			if keyID:
-				decmsg = self.gpg[self.connections[con]].decrypt(encmsg, keyID)
-		if decmsg:
-			msgtxt = decmsg
-		if typ == 'error':
-			self.hub.sendPlugin('MSGERROR', self.connections[con], \
-				(str(msg.getFrom()), msg.getErrorCode(), msg.getError(), msgtxt, tim))
-		elif typ == 'groupchat':
-			subject = msg.getSubject()
-			if subject:
-				self.hub.sendPlugin('GC_SUBJECT', self.connections[con], \
-					(str(msg.getFrom()), subject))
-			else:
-				self.hub.sendPlugin('GC_MSG', self.connections[con], \
-					(str(msg.getFrom()), msgtxt, tim))
-		else:
-			self.hub.sendPlugin('MSG', self.connections[con], \
-				(str(msg.getFrom()), msgtxt, tim))
-	# END messageCB
-
-	def presenceCB(self, con, prs):
-		"""Called when we recieve a presence"""
-#		if prs.getXNode(common.jabber.NS_DELAY): return
-		who = str(prs.getFrom())
-		prio = prs.getPriority()
-		if not prio:
-			prio = 0
-		typ = prs.getType()
-		if typ == None: typ = 'available'
-		log.debug("PresenceCB : %s" % typ)
-		xtags = prs.getXNodes()
-		sigTag = None
-		keyID = ''
-		status = prs.getStatus()
-		for xtag in xtags:
-			if xtag.getNamespace() == common.jabber.NS_XSIGNED:
-				sigTag = xtag
-				break
-		if sigTag and USE_GPG:
-			#verify
-			sigmsg = sigTag.getData()
-			keyID = self.gpg[self.connections[con]].verify(status, sigmsg)
-		if typ == 'available':
-			show = prs.getShow()
-			if not show:
-				show = 'online'
-			self.hub.sendPlugin('NOTIFY', self.connections[con], \
-				(prs.getFrom().getStripped(), show, status, \
-				prs.getFrom().getResource(), prio, keyID, prs.getRole(), \
-				prs.getAffiliation(), prs.getJid(), prs.getReason(), \
-				prs.getActor(), prs.getStatusCode()))
-		elif typ == 'unavailable':
-			self.hub.sendPlugin('NOTIFY', self.connections[con], \
-				(prs.getFrom().getStripped(), 'offline', status, \
-				prs.getFrom().getResource(), prio, keyID, prs.getRole(), \
-				prs.getAffiliation(), prs.getJid(), prs.getReason(), \
-				prs.getActor(), prs.getStatusCode()))
-		elif typ == 'subscribe':
-			log.debug("subscribe request from %s" % who)
-			if self.cfgParser.Core['alwaysauth'] == 1 or \
-				who.find("@") <= 0:
-				if con:
-					con.send(common.jabber.Presence(who, 'subscribed'))
-				if who.find("@") <= 0:
-					self.hub.sendPlugin('NOTIFY', self.connections[con], \
-						(prs.getFrom().getStripped(), 'offline', 'offline', \
-						prs.getFrom().getResource(), prio, keyID, None, None, None, \
-						None, None, None))
-			else:
-				if not status:
-					status = _("I would like to add you to my roster.")
-				self.hub.sendPlugin('SUBSCRIBE', self.connections[con], (who, \
-					status))
-		elif typ == 'subscribed':
-			jid = prs.getFrom()
-			self.hub.sendPlugin('SUBSCRIBED', self.connections[con],\
-				(jid.getStripped(), jid.getResource()))
-			self.hub.queueIn.put(('UPDUSER', self.connections[con], \
-				(jid.getStripped(), jid.getNode(), ['General'])))
-			#BE CAREFUL : no con.updateRosterItem() in a callback
-			log.debug("we are now subscribed to %s" % who)
-		elif typ == 'unsubscribe':
-			log.debug("unsubscribe request from %s" % who)
-		elif typ == 'unsubscribed':
-			log.debug("we are now unsubscribed to %s" % who)
-			self.hub.sendPlugin('UNSUBSCRIBED', self.connections[con], \
-				prs.getFrom().getStripped())
-		elif typ == 'error':
-			errmsg = prs.getError()
-			errcode = prs.getErrorCode()
-			if errcode == '400': #Bad Request: JID Malformed or Private message when not allowed
-				pass
-			elif errcode == '401': #No Password Provided
-				pass
-			elif errcode == '403':	#forbidden :	User is Banned
-											#					Unauthorized Subject Change
-											#					Attempt by Mere Member to Invite Others to a Members-Only Room
-											#					Configuration Access to Non-Owner
-											#					Attempt by Non-Owner to Modify Owner List
-											#					Attempt by Non-Owner to Modify Admin List
-											#					Destroy Request Submitted by Non-Owner
-				pass
-			elif errcode == '404':	#item not found :	Room Does Not Exist
-				pass
-			elif errcode == '405':	#Not allowed :	Attempt to Kick Moderator, Admin, or Owner
-											#					Attempt to Ban an Admin or Owner
-											#					Attempt to Revoke Voice from an Admin, Owner, or User with a Higher Affiliation
-											#					Attempt to Revoke Moderator Privileges from an Admin or Owner
-				pass
-			elif errcode == '407':	#registration required :	User Is Not on Member List
-											#									
-				pass
-			elif errcode == '409':	#conflict :	Nick Conflict
-				self.hub.sendPlugin('ERROR', None, errmsg)
-			else:
-				self.hub.sendPlugin('NOTIFY', self.connections[con], \
-					(prs.getFrom().getStripped(), 'error', errmsg, \
-					prs.getFrom().getResource(), prio, keyID, None, None, None, \
-					None, None, None))
-	# END presenceCB
-
-	def disconnectedCB(self, con):
-		"""Called when we are disconnected"""
-		log.debug("disconnectedCB")
-		if self.connections.has_key(con):
-			self.connected[self.connections[con]] = 0
-			self.hub.sendPlugin('STATUS', self.connections[con], 'offline')
-	# END disconenctedCB
-
-	def rosterSetCB(self, con, iq_obj):
-		for item in iq_obj.getQueryNode().getChildren():
-			jid  = item.getAttr('jid')
-			name = item.getAttr('name')
-			sub  = item.getAttr('subscription')
-			ask  = item.getAttr('ask')
-			groups = []
-			for group in item.getTags("group"):
-				groups.append(group.getData())
-			self.hub.sendPlugin('ROSTER_INFO', self.connections[con], (jid, name, sub, ask, groups))
-
-	def BrowseResultCB(self, con, iq_obj):
-		identities, features, items = [], [], []
-		q = iq_obj.getTag('service')
-		if not q:
-			return identities, features, items
-		attr = {}
-		for key in q.attrs:
-			attr[key.encode('utf8')] = q.attrs[key].encode('utf8')
-		identities = [attr]
-		for node in q.kids:
-			if node.getName() == 'ns':
-				features.append(node.getData())
-			else:
-				infos = {}
-				for key in node.attrs:
-					infos[key.encode('utf8')] = node.attrs[key].encode('utf8')
-				infos['category'] = node.getName()
-				items.append(infos)
-		jid = str(iq_obj.getFrom())
-		self.hub.sendPlugin('AGENT_INFO', self.connections[con], \
-			(jid, identities, features, items))
-
-	def DiscoverItemsCB(self, con, iq_obj):
-		qp = iq_obj.getQueryPayload()
-		items = []
-		if not qp:
-			qp = []
-		for i in qp:
-			attr = {}
-			for key in i.attrs:
-				attr[key.encode('utf8')] = i.attrs[key].encode('utf8')
-			items.append(attr)
-		jid = str(iq_obj.getFrom())
-		self.hub.sendPlugin('AGENT_INFO_ITEMS', self.connections[con],\
-			(jid, items))
-
-	def DiscoverInfoErrorCB(self, con, iq_obj):
-		jid = str(iq_obj.getFrom())
-		con.browseAgents(jid)
-
-	def DiscoverInfoCB(self, con, iq_obj):
-		# According to JEP-0030:
-		# For identity: category, name is mandatory, type is optional.
-		# For feature: var is mandatory
-		identities, features = [], []
-		qp = iq_obj.getQueryPayload()
-		if not qp:
-			qp = []
-		for i in qp:
-			if i.getName() == 'identity':
-				attr = {}
-				for key in i.attrs:
-					attr[key.encode('utf8')] = i.attrs[key].encode('utf8')
-				identities.append(attr)
-			elif i.getName() == 'feature':
-				features.append(i.getAttr('var'))
-		jid = str(iq_obj.getFrom())
-		if not identities:
-			con.browseAgents(jid)
-		else:
-			self.hub.sendPlugin('AGENT_INFO_INFO', self.connections[con],\
-				(jid, identities, features))
-			con.discoverItems(jid)
-
-	def VersionCB(self, con, iq_obj):
-		f = iq_obj.getFrom()
-		iq_obj.setFrom(iq_obj.getTo())
-		iq_obj.setTo(f)
-		iq_obj.setType('result')
-		qp = iq_obj.getTag('query')
-		qp.insertTag('name').insertData('Gajim')
-		qp.insertTag('version').insertData(version.version)
-		no_send_os = True
-		if self.cfgParser.tab['GtkGui'].has_key('do_not_send_os_info'):
-			no_send_os = self.cfgParser.tab['GtkGui']['do_not_send_os_info']
-		if not no_send_os:
-			qp.insertTag('os').insertData(get_os_info())
-		con.send(iq_obj)
-
-	def VersionResultCB(self, con, iq_obj):
-		client_info = ''
-		os_info = ''
-		qp = iq_obj.getTag('query')
-		if qp.getTag('name'):
-			client_info += qp.getTag('name').getData()
-		if qp.getTag('version'):
-			client_info += ' ' + qp.getTag('version').getData()
-		if qp.getTag('os'):
-			os_info += qp.getTag('os').getData()
-		jid = iq_obj.getFrom().getStripped()
-		self.hub.sendPlugin('OS_INFO', self.connections[con],\
-			(jid, client_info, os_info))
-
-	def connect(self, account):
-		"""Connect and authentificate to the Jabber server"""
-		hostname = self.cfgParser.tab[account]['hostname']
-		name = self.cfgParser.tab[account]["name"]
-		password = self.passwords[account]
-		if not self.cfgParser.tab[account].has_key('resource'):
-			if not self.cfgParser.tab[account].has_key('ressource'):
-				resource = 'Gajim'
-			else:
-				resource = self.cfgParser.tab[account]['ressource']
-				self.cfgParser.tab[account]['resource'] = resource
-				del self.cfgParser.tab[account]['ressource']
-		else:
-			resource = self.cfgParser.tab[account]['resource']
-
-		#create connexion if it doesn't already existe
-		con = None
-		for conn in self.connections:
-			if self.connections[conn] == account:
-				con = conn
-		if not con:
-			if self.cfgParser.tab[account]["use_proxy"]:
-				proxy = {"host":self.cfgParser.tab[account]["proxyhost"]}
-				proxy["port"] = self.cfgParser.tab[account]["proxyport"]
-			else:
-				proxy = None
-			if self.log:
-				con = common.jabber.Client(host = hostname, debug = [], \
-				log = sys.stderr, connection=common.xmlstream.TCP, port=5222, \
-				proxy = proxy)
-			else:
-				con = common.jabber.Client(host = hostname, debug = [], log = None,\
-				connection=common.xmlstream.TCP, port=5222, proxy = proxy)
-				#debug = [common.jabber.DBG_ALWAYS], log = sys.stderr, \
-				#connection=common.xmlstream.TCP_SSL, port=5223, proxy = proxy)
-			con.setDisconnectHandler(self.disconnectedCB)
-			con.registerHandler('message', self.messageCB)
-			con.registerHandler('presence', self.presenceCB)
-			con.registerHandler('iq',self.vCardCB,'result')#common.jabber.NS_VCARD)
-			con.registerHandler('iq',self.rosterSetCB,'set', \
-				common.jabber.NS_ROSTER)
-			con.registerHandler('iq',self.BrowseResultCB,'result', \
-				common.jabber.NS_BROWSE)
-			con.registerHandler('iq',self.DiscoverItemsCB,'result', \
-				common.jabber.NS_P_DISC_ITEMS)
-			con.registerHandler('iq',self.DiscoverInfoCB,'result', \
-				common.jabber.NS_P_DISC_INFO)
-			con.registerHandler('iq',self.DiscoverInfoErrorCB,'error', \
-				common.jabber.NS_P_DISC_INFO)
-			con.registerHandler('iq',self.VersionCB,'get', \
-				common.jabber.NS_VERSION)
-			con.registerHandler('iq',self.VersionResultCB,'result', \
-				common.jabber.NS_VERSION)
-		try:
-			con.connect()
-		except IOError, e:
-			log.debug("Couldn't connect to %s %s" % (hostname, e))
-			self.hub.sendPlugin('STATUS', account, 'offline')
-			self.hub.sendPlugin('ERROR', None, _("Couldn't connect to %s") \
-				% hostname)
-			return 0
-		except common.xmlstream.socket.error, e:
-			log.debug("Couldn't connect to %s %s" % (hostname, e))
-			self.hub.sendPlugin('STATUS', account, 'offline')
-			self.hub.sendPlugin('ERROR', None, _("Couldn't connect to %s: %s") \
-				% (hostname, e))
-			return 0
-		except common.xmlstream.error, e:
-			log.debug("Couldn't connect to %s %s" % (hostname, e))
-			self.hub.sendPlugin('STATUS', account, 'offline')
-			self.hub.sendPlugin('ERROR', None, _("Couldn't connect to %s: %s") \
-				% (hostname, e))
-			return 0
-#		except:
-#			print sys.exc_info()[1]
-		else:
-			log.debug("Connected to server")
-
-			#BUG in jabberpy library : if hostname is wrong : "boucle"
-			if con.auth(name, password, resource):
-				self.connections[con] = account
-				con.requestRoster()
-				roster = con.getRoster().getRaw()
-				if not roster :
-					roster = {}
-				self.hub.sendPlugin('ROSTER', account, (0, roster))
-				self.connected[account] = 1
-				return con
-			else:
-				log.debug("Couldn't authentificate to %s" % hostname)
-				self.hub.sendPlugin('STATUS', account, 'offline')
-				self.hub.sendPlugin('ERROR', None, \
-					_("Authentification failed with %s, check your login and password") % hostname)
-				return 0
-	# END connect
-
-	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 request_infos(self, account, con, jid):
-		if con:
-			con.discoverInfo(jid)
-
-	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.connections.values()):
-				for con in self.connections.keys():
-					if ev[1] == self.connections[con]:
-						break
-			else:
-				con = None
-			#('QUIT', None, (plugin, kill_core ?))   kill core : 0 or 1
-			if ev[0] == 'QUIT':
-				self.hub.unregister(ev[2][0])
-				if ev[2][1]:
-					for con in self.connections.keys():
-						if self.connected[self.connections[con]]:
-							self.connected[self.connections[con]] = 0
-							con.disconnect('Disconnected')
-					self.hub.sendPlugin('QUIT', None, ())
-					return 1
-			#('ASK_ROSTER', account, queue_for_response)
-			elif ev[0] == 'ASK_ROSTER':
-				roster = {}
-				if con:
-					roster = con.getRoster().getRaw()
-				self.hub.sendPlugin('ROSTER', ev[1], (self.connected[ev[1]], \
-					roster), ev[2])
-			#('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]
-					else:
-						config = ev[2][2]
-						self.cfgParser.tab[ev[2][1]] = config
-						self.cfgParser.writeCfgFile()
-					config['usegpg'] = USE_GPG
-					self.hub.sendPlugin('CONFIG', None, (ev[2][0], config))
-			#('CONFIG', account, (section, config, who_sent))
-			elif ev[0] == 'CONFIG':
-				if ev[2][0] == 'accounts':
-					#Remove all old accounts
-					accts = self.cfgParser.tab['Profile']['accounts'].split(' ')
-					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'] = \
-						' '.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
-						if not self.gpg.has_key(a) and USE_GPG:
-							self.gpg[a] = MyGnuPG()
-						if not self.passwords.keys():
-							self.passwords[a] = ''
-				else:
-					self.cfgParser.tab[ev[2][0]] = ev[2][1]
-				if ev[2][0] != ev[2][2]:
-					self.hub.sendPlugin('CONFIG', None, (ev[2][0], ev[2][1]))
-				self.cfgParser.writeCfgFile()
-			#('STATUS', account, (status, msg))
-			elif ev[0] == 'STATUS':
-				msg = ev[2][1]
-				if not msg:
-					msg = ev[2][0]
-				signed = ''
-				keyID = ''
-				if self.cfgParser.tab[ev[1]].has_key('keyid'):
-					keyID = self.cfgParser.tab[ev[1]]['keyid']
-				if keyID and USE_GPG:
-					signed = self.gpg[ev[1]].sign(msg, keyID)
-					if signed == 'BAD_PASSPHRASE':
-						signed = ''
-						if self.connected[ev[1]] == 0:
-							self.hub.sendPlugin('BAD_PASSPHRASE', ev[1], ())
-				if (ev[2][0] != 'offline') and (self.connected[ev[1]] == 0):
-					con = self.connect(ev[1])
-					if self.connected[ev[1]]:
-						statuss = ['offline', 'online', 'away', 'xa', 'dnd', \
-								'invisible']
-						self.connected[ev[1]] = statuss.index(ev[2][0])
-						#send our presence
-						typ = 'available'
-						if ev[2][0] == 'invisible':
-							typ = 'invisible'
-						prio = 0
-						if self.cfgParser.tab[ev[1]].has_key('priority'):
-							prio = str(self.cfgParser.tab[ev[1]]['priority'])
-						con.sendPresence(typ, prio, ev[2][0], msg, signed)
-						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]]):
-					self.connected[ev[1]] = 0
-					con.disconnect(msg)
-					self.hub.sendPlugin('STATUS', ev[1], 'offline')
-				elif ev[2][0] != 'offline' and self.connected[ev[1]]:
-					statuss = ['offline', 'online', 'away', 'xa', 'dnd', \
-							'invisible']
-					self.connected[ev[1]] = statuss.index(ev[2][0])
-					typ = 'available'
-					if ev[2][0] == 'invisible':
-						typ = 'invisible'
-					prio = 0
-					if self.cfgParser.tab[ev[1]].has_key('priority'):
-						prio = str(self.cfgParser.tab[ev[1]]['priority'])
-					con.sendPresence(typ, prio, ev[2][0], msg, signed)
-					self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
-			#('MSG', account, (jid, msg, keyID))
-			elif ev[0] == 'MSG':
-				if con:
-					msgtxt = ev[2][1]
-					msgenc = ''
-					if ev[2][2] and USE_GPG:
-						#encrypt
-						msgenc = self.gpg[ev[1]].encrypt(ev[2][1], [ev[2][2]])
-						if msgenc: msgtxt = '[this message is encrypted]'
-					msg = common.jabber.Message(ev[2][0], msgtxt)
-					msg.setType('chat')
-					if msgenc:
-						msg.setX(common.jabber.NS_XENCRYPTED).insertData(msgenc)
-					con.send(msg)
-					self.hub.sendPlugin('MSGSENT', ev[1], ev[2])
-			#('SUB', account, (jid, txt))
-			elif ev[0] == 'SUB':
-				if con:
-					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':
-				if con:
-					con.send(common.jabber.Presence(ev[2], 'subscribed'))
-			#('DENY', account, jid)
-			elif ev[0] == 'DENY':
-				if con:
-					con.send(common.jabber.Presence(ev[2], 'unsubscribed'))
-			#('UNSUB', account, jid)
-			elif ev[0] == 'UNSUB':
-				if con:
-					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':
-				if con:
-					con.removeRosterItem(ev[2])
-					con.requestRegInfo(ev[2])
-					agent_info = con.getRegInfo()
-					if not agent_info:
-						return
-					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':
-				if con:
-					con.updateRosterItem(jid=ev[2][0], name=ev[2][1], \
-						groups=ev[2][2])
-			#('REQ_AGENTS', account, jid)
-			elif ev[0] == 'REQ_AGENTS':
-				self.request_infos(ev[1], con, ev[2])
-			#('REG_AGENT_INFO', account, agent)
-			elif ev[0] == 'REG_AGENT_INFO':
-				if con:
-					con.requestRegInfo(ev[2])
-					agent_info = con.getRegInfo()
-					self.hub.sendPlugin('REG_AGENT_INFO', ev[1], (ev[2], agent_info))
-			#('REG_AGENT', account, infos)
-			elif ev[0] == 'REG_AGENT':
-				if con:
-					con.sendRegInfo(ev[2])
-			#('NEW_ACC', (hostname, login, password, name, resource, 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:
-					log.debug("Couldn't connect to %s" % ev[2][0])
-					self.hub.sendPlugin('ERROR', None, \
-						_('Couldn\'t connect to ')+ev[2][0])
-					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])
-					if not c.sendRegInfo():
-						self.hub.sendPlugin('ERROR', None, _('Error: ')+c.lastErr)
-					else:
-						self.connected[ev[2][3]] = 0
-						self.passwords[ev[2][3]] = ''
-						if USE_GPG:
-							self.gpg[ev[2][3]] = MyGnuPG()
-						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]]
-				self.passwords[ev[2]] = self.passwords[ev[1]]
-				del self.connected[ev[1]]
-				del self.passwords[ev[1]]
-				if USE_GPG:
-					self.gpg[ev[2]] = self.gpg[ev[1]]
-					del self.gpg[ev[1]]
-				if con:
-					self.connections[con] = ev[2]
-			#('ASK_OS_INFO', account, (jid, resource))
-			elif ev[0] == 'ASK_OS_INFO':
-				if con:
-					iq = common.jabber.Iq(to=ev[2][0]+'/'+ev[2][1], type="get", \
-						query=common.jabber.NS_VERSION)
-					iq.setID(con.getAnID())
-					con.send(iq)
-			#('ASK_VCARD', account, jid)
-			elif ev[0] == 'ASK_VCARD':
-				if con:
-					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':
-				if con:
-					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, typ))
-			elif ev[0] == 'AGENT_LOGGING':
-				if con:
-					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 = line.split(':')
-						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)
-			elif ev[0] == 'EXEC_PLUGIN':
-				self.loadPlugins(ev[2])
-			#('GC_JOIN', account, (nick, room, server, passwd))
-			elif ev[0] == 'GC_JOIN':
-				if con:
-					p = common.jabber.Presence(to='%s@%s/%s' % (ev[2][1], ev[2][2], \
-						ev[2][0]))
-					con.send(p)
-			#('GC_MSG', account, (jid, msg))
-			elif ev[0] == 'GC_MSG':
-				if con:
-					msg = common.jabber.Message(ev[2][0], ev[2][1])
-					msg.setType('groupchat')
-					con.send(msg)
-					self.hub.sendPlugin('MSGSENT', ev[1], ev[2])
-			#('GC_SUBJECT', account, (jid, subject))
-			elif ev[0] == 'GC_SUBJECT':
-				if con:
-					msg = common.jabber.Message(ev[2][0])
-					msg.setType('groupchat')
-					msg.setSubject(ev[2][1])
-					con.send(msg)
-			#('GC_STATUS', account, (nick, jid, show, status))
-			elif ev[0] == 'GC_STATUS':
-				if con:
-					if ev[2][2] == 'offline':
-						con.send(common.jabber.Presence(to = '%s/%s' % (ev[2][1], \
-							ev[2][0]), type = 'unavailable', status = ev[2][3]))
-					else:
-						con.send(common.jabber.Presence(to = '%s/%s' % (ev[2][1], \
-							ev[2][0]), type = 'available', show = ev[2][2], status = \
-							ev[2][3]))
-			#('GC_SET_ROLE', account, (room_jid, nick, role))
-			elif ev[0] == 'GC_SET_ROLE':
-				if con:
-					iq = common.jabber.Iq(type='set', to=ev[2][0])
-					item = iq.setQuery(common.jabber.NS_P_MUC_ADMIN).\
-						insertTag('item')
-					item.putAttr('nick', ev[2][1])
-					item.putAttr('role', ev[2][2])
-					id = con.getAnID()
-					iq.setID(id)
-					con.send(iq)
-			#('GC_SET_AFFILIATION', account, (room_jid, jid, affiliation))
-			elif ev[0] == 'GC_SET_AFFILIATION':
-				if con:
-					iq = common.jabber.Iq(type='set', to=ev[2][0])
-					item = iq.setQuery(common.jabber.NS_P_MUC_ADMIN).\
-						insertTag('item')
-					item.putAttr('jid', ev[2][1])
-					item.putAttr('affiliation', ev[2][2])
-					id = con.getAnID()
-					iq.setID(id)
-					con.send(iq)
-			#('GPGPASSPHRASE', account, passphrase)
-			elif ev[0] == 'GPGPASSPHRASE':
-				if USE_GPG:
-					self.gpg[ev[1]].passphrase = ev[2]
-			elif ev[0] == 'GPG_SECRETE_KEYS':
-				if USE_GPG:
-					keys = self.gpg_common.get_secret_keys()
-					self.hub.sendPlugin('GPG_SECRETE_KEYS', ev[1], keys)
-			elif ev[0] == 'PASSPHRASE':
-				self.passwords[ev[1]] = ev[2]
-			#('CHANGE_PASSWORD', account, (new_password, username))
-			elif ev[0] == 'CHANGE_PASSWORD':
-				if con:
-					hostname = self.cfgParser.tab[ev[1]]['hostname']
-					iq = common.jabber.Iq(type='set', to=hostname)
-					q = iq.setQuery(common.jabber.NS_REGISTER)
-					q.insertTag('username').insertData(ev[2][1])
-					q.insertTag('password').insertData(ev[2][0])
-					id = con.getAnID()
-					iq.setID(id)
-					con.send(iq)
-			else:
-				log.debug(_("Unknown Command %s") % ev[0])
-		if self.mode == 'server':
-			for con in self.connections:
-				if self.connected[self.connections[con]]:
-					con.process(1)
-			#remove connexion that have been broken
-			for acc in self.connected:
-				if self.connected[acc]:
-					break
-				for con in self.connections:
-						if self.connections[con] == acc:
-							del self.connections[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 start(mode='server'):
-	"""Start the Core"""
-	gc = GajimCore(mode)
-	try:
-		gc.mainLoop()
-	except KeyboardInterrupt:
-		print _("Keyboard Interrupt : Bye!")
-		gc.hub.sendPlugin('QUIT', None, ())
-		return 0
-#	except:
-#		print "Erreur survenue"
-#		gc.hub.sendPlugin('QUIT', ())
-# END start
diff --git a/common/hub.py b/common/hub.py
deleted file mode 100644
index c0178b1f94..0000000000
--- a/common/hub.py
+++ /dev/null
@@ -1,104 +0,0 @@
-##	common/hub.py
-##
-## Gajim Team:
-## 	- Yann Le Boulanger <asterix@lagaule.org>
-## 	- Vincent Hanquez <tab@snarc.org>
-##
-##	Copyright (C) 2003-2005 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 Queue
-import common.plugin
-import common.thread
-
-""" Hub definitions """
-
-class GajimHub:
-	def __init__(self):
-		self.queues = {}
-		# {event1:[queue1, queue2]}
-		self.events = {}
-		self.queueIn = self.newQueue('in', 100)
-		self.saveQueue = Queue.Queue(100)
-		self.events_to_store = ['WARNING', 'MSG', 'MSGERROR', 'SUBSCRIBED', 'UNSUBSCRIBED', 'SUBSCRIBE']
-		self.queue_to_send = None
-	# END __init__
-
-	def newQueue(self, name, size):
-		""" Creates a new queue """
-		qu = Queue.Queue(size)
-		self.queues[name] = qu
-		return qu
-	# END newQueue
-
-	def newPlugin(self, name):
-		"""Creates a new Plugin """
-		if name in self.queues.keys():
-			return 0
-		qu = self.newQueue(name, 100)
-		pl = common.plugin.GajimPlugin(name, qu, self.queueIn)
-		return pl
-	# END newPlugin
-
-	def register(self, name, event):
-		""" Records a plugin from an event """
-		if not self.queues.has_key(name):
-			return
-		qu = self.queues[name]
-		if event == 'VISUAL' and not self.saveQueue.empty():
-			# we save the queue in whitch we must send saved events
-			# after the roster is sent
-			self.queue_to_send = qu
-		if self.events.has_key(event):
-			if not qu in self.events[event]:
-				self.events[event].append(qu)
-		else :
-			self.events[event] = [qu]
-	# END register
-
-	def unregisterEvents(self, name, event):
-		""" Records a plugin from an event """
-		if not self.queues.has_key(name):
-			return
-		qu = self.queues[name]
-		if self.events.has_key(event) :
-			if qu in self.events[event]:
-				self.events[event].remove(qu)
-	# END register
-
-	def unregister(self, name):
-		if not self.queues.has_key(name):
-			return
-		qu = self.queues[name]
-		for event in self.events:
-			if qu in self.events[event]:
-				self.events[event].remove(qu)
-		del self.queues[name]
-	# END unregister
-
-	def sendPlugin(self, event, con, data, qu=None):
-		""" Sends an event to registered plugins"""
-		if self.events.has_key(event):
-			if event in self.events_to_store and len(self.events['VISUAL']) == 0:
-				# Save event if no visual plugin is registered
-				self.saveQueue.put((event, con, data))
-			for queue in self.events[event]:
-				if qu == None or qu == queue:
-					queue.put((event, con, data))
-			if event == 'ROSTER' and self.queue_to_send in self.events[event]:
-				# send saved events
-				while not self.saveQueue.empty():
-					ev = self.saveQueue.get()
-					self.queue_to_send.put(ev)
-				self.queue_to_send = None
-	# END sendPlugin
-# END GajimHub
diff --git a/common/plugin.py b/common/plugin.py
deleted file mode 100644
index e7a8a3c220..0000000000
--- a/common/plugin.py
+++ /dev/null
@@ -1,36 +0,0 @@
-##	common/plugin.py
-##
-## Gajim Team:
-## 	- Yann Le Boulanger <asterix@lagaule.org>
-## 	- Vincent Hanquez <tab@snarc.org>
-##
-##	Copyright (C) 2003-2005 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 common.thread
-
-""" Plugin definitions """
-
-class GajimPlugin:
-	def __init__(self, name, queueIn, queueOut):
-		""" queueIn is a queue to interact from the hub to the plugin """
-		self.name = name
-		self.queueIn = queueIn
-		self.queueOut= queueOut
-	# END __init__
-
-	def load(self):
-		thr = common.thread.GajimThread(self.name, self.queueIn, self.queueOut)
-#		thr.setDaemon(1)
-		thr.start()
-	# END load
-# END GajimPlugin
diff --git a/common/thread.py b/common/thread.py
deleted file mode 100644
index 1bc680e541..0000000000
--- a/common/thread.py
+++ /dev/null
@@ -1,40 +0,0 @@
-##	common/thread.py
-##
-## Gajim Team:
-## 	- Yann Le Boulanger <asterix@lagaule.org>
-## 	- Vincent Hanquez <tab@snarc.org>
-##
-##	Copyright (C) 2003-2005 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 threading
-import socket
-import time
-import sys
-from common import i18n
-_ = i18n._
-
-class GajimThread(threading.Thread): 
-	def __init__(self, name = None, queueIn = None, queueOut = None): 
-		self.queueIn = queueIn
-		self.queueOut = queueOut
-		threading.Thread.__init__(self, target = self.run, name = name) 
-	# END __init__
- 
-	def run(self):
-		mod = compile('import plugins.%s' % self.getName(), self.getName(), 'exec')
-		res = eval(mod)
-		mod = compile('plugins.%s.%s.plugin(self.queueIn, self.queueOut)' 
-		% (self.getName(), self.getName()), self.getName(), 'exec')
-		res = eval(mod)
-	# END run
-# END GajimThread
-- 
GitLab