diff --git a/core/core.py b/core/core.py
index df500d0b4..20a4e8aeb 100644
--- a/core/core.py
+++ b/core/core.py
@@ -22,6 +22,7 @@ import sys, os, time, string, logging
import common.hub, common.optparser
import common.jabber
import socket, select, pickle
+import GnuPGInterface
from common import i18n
@@ -47,6 +48,142 @@ def XMLunescape(txt):
txt = txt.replace("&", "&")
return txt
+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')
+
+ 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 = string.rstrip( line )
+ if line[0:9] == '[GNUPG:] ':
+ # Chop off the prefix
+ line = line[9:]
+ L = string.split(line, 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):
+ file = open('gpg_data', 'w+r')
+ os.remove('gpg_data')
+ 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 = string.split(resp['GOODSIG'])[0]
+ return keyid
+
+ def stripHeaderFooter(self, data):
+ """Remove header and footer from data"""
+ lines = string.split(data, '\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 = string.join(lines[0:i], '\n')
+ 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'):
@@ -65,9 +202,11 @@ class GajimCore:
self.connected = {}
#connexions {con: name, ...}
self.connexions = {}
+ self.gpg = {}
for a in self.accounts:
self.connected[a] = 0 #0:offline, 1:online, 2:away,
#3:xa, 4:dnd, 5:invisible
+ self.gpg[a] = MyGnuPG()
self.myVCardID = []
self.loadPlugins(self.cfgParser.tab['Core']['modules'])
else:
@@ -158,7 +297,7 @@ class GajimCore:
def vCardCB(self, con, vc):
"""Called when we recieve a vCard
Parse the vCard and send it to plugins"""
- vcard = {'jid': vc.getFrom().getBasic()}
+ vcard = {'jid': vc.getFrom().getStripped()}
if vc._getTag('vCard') == common.jabber.NS_VCARD:
card = vc.getChildren()[0]
for info in card.getChildren():
@@ -179,16 +318,33 @@ class GajimCore:
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:
+ #decrypt
+ encmsg = encTag.getData()
+ keyID = ''
+ if self.cfgParser.tab[self.connexions[con]].has_key("keyid"):
+ keyID = self.cfgParser.tab[self.connexions[con]]["keyid"]
+ if keyID:
+ decmsg = self.gpg[self.connexions[con]].decrypt(encmsg, keyID)
+ if decmsg:
+ msgtxt = decmsg
if typ == 'error':
self.hub.sendPlugin('MSGERROR', self.connexions[con], \
- (str(msg.getFrom()), msg.getErrorCode(), msg.getError(), \
- msg.getBody(), tim))
+ (str(msg.getFrom()), msg.getErrorCode(), msg.getError(), msgtxt, tim))
elif typ == 'groupchat':
self.hub.sendPlugin('GC_MSG', self.connexions[con], \
- (str(msg.getFrom()), msg.getBody(), tim))
+ (str(msg.getFrom()), msgtxt, tim))
else:
self.hub.sendPlugin('MSG', self.connexions[con], \
- (str(msg.getFrom()), msg.getBody(), tim))
+ (str(msg.getFrom()), msgtxt, tim))
# END messageCB
def presenceCB(self, con, prs):
@@ -200,19 +356,31 @@ class GajimCore:
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:
+ #verify
+ sigmsg = sigTag.getData()
+ keyID = self.gpg[self.connexions[con]].verify(status, sigmsg)
if typ == 'available':
show = prs.getShow()
if not show:
show = 'online'
self.hub.sendPlugin('NOTIFY', self.connexions[con], \
- (prs.getFrom().getBasic(), show, prs.getStatus(), \
- prs.getFrom().getResource(), prio, prs.getRole(), \
+ (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.connexions[con], \
- (prs.getFrom().getBasic(), 'offline', prs.getStatus(), \
- prs.getFrom().getResource(), prio, prs.getRole(), \
+ (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':
@@ -222,20 +390,20 @@ class GajimCore:
con.send(common.jabber.Presence(who, 'subscribed'))
if string.find(who, "@") <= 0:
self.hub.sendPlugin('NOTIFY', self.connexions[con], \
- (prs.getFrom().getBasic(), 'offline', 'offline', \
- prs.getFrom().getResource(), prio, None, None, None, None, \
- None, None))
+ (prs.getFrom().getStripped(), 'offline', 'offline', \
+ prs.getFrom().getResource(), prio, keyID, None, None, None, \
+ None, None, None))
else:
- txt = prs.getStatus()
- if not txt:
- txt = _("I would like to add you to my roster.")
- self.hub.sendPlugin('SUBSCRIBE', self.connexions[con], (who, txt))
+ if not status:
+ status = _("I would like to add you to my roster.")
+ self.hub.sendPlugin('SUBSCRIBE', self.connexions[con], (who, \
+ status))
elif typ == 'subscribed':
jid = prs.getFrom()
self.hub.sendPlugin('SUBSCRIBED', self.connexions[con],\
- (jid.getBasic(), jid.getNode(), jid.getResource()))
+ (jid.getStripped(), jid.getNode(), jid.getResource()))
self.hub.queueIn.put(('UPDUSER', self.connexions[con], \
- (jid.getBasic(), jid.getNode(), ['general'])))
+ (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':
@@ -243,7 +411,7 @@ class GajimCore:
elif typ == 'unsubscribed':
log.debug("we are now unsubscribed to %s" % who)
self.hub.sendPlugin('UNSUBSCRIBED', self.connexions[con], \
- prs.getFrom().getBasic())
+ prs.getFrom().getStripped())
elif typ == 'error':
errmsg = prs.getError()
errcode = prs.getErrorCode()
@@ -273,9 +441,9 @@ class GajimCore:
self.hub.sendPlugin('WARNING', None, errmsg)
else:
self.hub.sendPlugin('NOTIFY', self.connexions[con], \
- (prs.getFrom().getBasic(), 'error', errmsg, \
- prs.getFrom().getResource(), prio, None, None, None, None, None,\
- None))
+ (prs.getFrom().getStripped(), 'error', errmsg, \
+ prs.getFrom().getResource(), prio, keyID, None, None, None, \
+ None, None, None))
# END presenceCB
def disconnectedCB(self, con):
@@ -463,6 +631,16 @@ class GajimCore:
#('STATUS', account, (status, msg))
elif ev[0] == 'STATUS':
activ = 1
+ signed = ''
+ keyID = ''
+ if self.cfgParser.tab[ev[1]].has_key("keyid"):
+ keyID = self.cfgParser.tab[ev[1]]["keyid"]
+ if keyID:
+ signed = self.gpg[ev[1]].sign(ev[2][0], keyID)
+ if signed == 'BAD_PASSPHRASE':
+ signed = ''
+ if self.connected[ev[1]] == 0:
+ self.hub.sendPlugin('BAD_PASSPHRASE', ev[1], ())
if self.cfgParser.tab[ev[1]].has_key('active'):
activ = self.cfgParser.tab[ev[1]]['active']
if (ev[2][0] != 'offline') and (self.connected[ev[1]] == 0) and \
@@ -479,7 +657,7 @@ class GajimCore:
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], ev[2][1])
+ con.sendPresence(typ, prio, ev[2][0], ev[2][1], signed)
self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
#ask our VCard
iq = common.jabber.Iq(type="get")
@@ -502,12 +680,20 @@ class GajimCore:
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], ev[2][1])
+ con.sendPresence(typ, prio, ev[2][0], ev[2][1], signed)
self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
- #('MSG', account, (jid, msg))
+ #('MSG', account, (jid, msg, keyID))
elif ev[0] == 'MSG':
- msg = common.jabber.Message(ev[2][0], ev[2][1])
+ msgtxt = ev[2][1]
+ msgenc = ''
+ if ev[2][2]:
+ #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))
@@ -678,6 +864,9 @@ class GajimCore:
else:
con.send(common.jabber.Presence('%s/%s' % (ev[2][1], ev[2][0]), \
'available', show=ev[2][2], status = ev[2][3]))
+ #('PASSPHRASE', account, passphrase)
+ elif ev[0] == 'PASSPHRASE':
+ self.gpg[ev[1]].passphrase = ev[2]
else:
log.debug(_("Unknown Command %s") % ev[0])
if self.mode == 'server':
diff --git a/plugins/gtkgui/dialogs.py b/plugins/gtkgui/dialogs.py
index 997ca13ff..edbb12094 100644
--- a/plugins/gtkgui/dialogs.py
+++ b/plugins/gtkgui/dialogs.py
@@ -183,7 +183,28 @@ class infoUser_Window:
self.xml.signal_connect('on_remove_clicked', self.on_remove)
self.xml.signal_connect('on_entry_new_key_press_event', \
self.on_new_key_pressed)
-
+
+class passphrase_Window:
+ """Class for Passphrase Window"""
+ def run(self):
+ """Wait for Ok button to be pressed and return passphrase"""
+ rep = self.xml.get_widget("Passphrase").run()
+ if rep == gtk.RESPONSE_OK:
+ msg = self.entry.get_text()
+ else:
+ msg = -1
+ self.xml.get_widget("Passphrase").destroy()
+ return msg
+
+ def on_key_pressed(self, widget, event):
+ if event.keyval == gtk.keysyms.Return:
+ self.xml.get_widget("Passphrase").response(gtk.RESPONSE_OK)
+
+ def __init__(self):
+ self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Passphrase', APP)
+ self.entry = self.xml.get_widget("entry")
+ self.xml.signal_connect('on_Passphrase_key_press_event', \
+ self.on_key_pressed)
class awayMsg_Window:
"""Class for Away Message Window"""
diff --git a/plugins/gtkgui/gtkgui.glade b/plugins/gtkgui/gtkgui.glade
index 7c78a66dc..f27ead55a 100644
--- a/plugins/gtkgui/gtkgui.glade
+++ b/plugins/gtkgui/gtkgui.glade
@@ -536,6 +536,34 @@
+
+
+ True
+ True
+ GTK_RELIEF_NONE
+ False
+ False
+ False
+
+
+
+ True
+ gtk-dialog-authentication
+ 4
+ 0.5
+ 0.5
+ 0
+ 0
+
+
+
+
+ 0
+ False
+ False
+
+
+
True
@@ -7752,4 +7780,123 @@ when NOT online
+
+ True
+ Passphrase
+ GTK_WINDOW_TOPLEVEL
+ GTK_WIN_POS_NONE
+ False
+ True
+ False
+ True
+ False
+ False
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ GDK_GRAVITY_NORTH_WEST
+ True
+
+
+
+
+ True
+ False
+ 0
+
+
+
+ True
+ GTK_BUTTONBOX_END
+
+
+
+ True
+ True
+ True
+ gtk-cancel
+ True
+ GTK_RELIEF_NORMAL
+ True
+ -6
+
+
+
+
+
+ True
+ True
+ True
+ True
+ gtk-ok
+ True
+ GTK_RELIEF_NORMAL
+ True
+ -5
+
+
+
+
+ 0
+ False
+ True
+ GTK_PACK_END
+
+
+
+
+
+ True
+ False
+ 0
+
+
+
+ True
+ Enter your passphrase
+ False
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0.5
+ 0.5
+ 0
+ 0
+
+
+ 5
+ False
+ False
+
+
+
+
+
+ True
+ True
+ True
+ True
+ False
+ 0
+
+ True
+ *
+ False
+
+
+ 0
+ False
+ False
+
+
+
+
+ 0
+ True
+ True
+
+
+
+
+
+
diff --git a/plugins/gtkgui/gtkgui.py b/plugins/gtkgui/gtkgui.py
index 2d2c0c887..3390f6015 100644
--- a/plugins/gtkgui/gtkgui.py
+++ b/plugins/gtkgui/gtkgui.py
@@ -163,7 +163,8 @@ class user:
self.sub = ''
self.resource = ''
self.priority = 0
- elif len(args) == 8:
+ self.keyID = ''
+ elif len(args) == 9:
self.jid = args[0]
self.name = args[1]
self.groups = args[2]
@@ -172,6 +173,7 @@ class user:
self.sub = args[5]
self.resource = args[6]
self.priority = args[7]
+ self.keyID = args[8]
else: raise TypeError, _('bad arguments')
@@ -248,7 +250,10 @@ class message_Window:
end_iter = txt_buffer.get_end_iter()
txt = txt_buffer.get_text(start_iter, end_iter, 0)
if txt != '':
- self.plugin.send('MSG', self.account, (self.user.jid, txt))
+ keyID = ''
+ if self.xml.get_widget('toggle_gpg').get_active():
+ keyID = self.keyID
+ self.plugin.send('MSG', self.account, (self.user.jid, txt, keyID))
txt_buffer.set_text('', -1)
self.print_conversation(txt, self.user.jid)
widget.grab_focus()
@@ -275,6 +280,7 @@ class message_Window:
self.user = user
self.plugin = plugin
self.account = account
+ self.keyID = self.user.keyID
self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Chat', APP)
self.window = self.xml.get_widget('Chat')
self.window.set_title('Chat with ' + user.name + " (" + account + ")")
@@ -287,6 +293,8 @@ class message_Window:
self.xml.get_widget('button_contact').set_label(user.name + ' <'\
+ user.jid + '>')
self.xml.get_widget('button_contact').set_resize_mode(gtk.RESIZE_QUEUE)
+ if not self.keyID:
+ self.xml.get_widget('toggle_gpg').set_sensitive(False)
message = self.xml.get_widget('message')
message.grab_focus()
conversation = self.xml.get_widget('conversation')
@@ -419,7 +427,6 @@ class gc:
start_iter = txt_buffer.get_start_iter()
end_iter = txt_buffer.get_end_iter()
txt = txt_buffer.get_text(start_iter, end_iter, 0)
- print self.jid
if txt != '':
self.plugin.send('GC_MSG', self.account, (self.jid, txt))
txt_buffer.set_text('', -1)
@@ -878,7 +885,7 @@ class roster_Window:
model.append(None, (self.pixbufs[status], account, 'account', account,\
FALSE))
- def add_user_to_roster(self, jid, account):
+ def add_user_to_roster(self, jid, account, keyID):
"""Add a user to the roster and add groups if they aren't in roster"""
showOffline = self.plugin.config['showoffline']
if not self.contacts[account].has_key(jid):
@@ -1009,7 +1016,8 @@ class roster_Window:
for acct in self.contacts.keys():
self.add_account_to_roster(acct)
for jid in self.contacts[acct].keys():
- self.add_user_to_roster(jid, acct)
+ #TODO: get the good keyID
+ self.add_user_to_roster(jid, acct, '')
def mklists(self, array, account):
"""fill self.contacts and self.groups"""
@@ -1038,7 +1046,7 @@ class roster_Window:
show = 'offline'
user1 = user(ji, name, array[jid]['groups'], show, \
- array[jid]['status'], array[jid]['sub'], resource, 0)
+ array[jid]['status'], array[jid]['sub'], resource, 0, '')
#when we draw the roster, we can't have twice the same user with
# 2 resources
self.contacts[account][ji] = [user1]
@@ -1067,13 +1075,14 @@ class roster_Window:
iters = []
else:
if not self.get_user_iter(user.jid, account):
- self.add_user_to_roster(user.jid, account)
+ self.add_user_to_roster(user.jid, account, user.keyID)
self.redraw_jid(user.jid, account)
users = self.contacts[account][user.jid]
for u in users:
if u.resource == user.resource:
u.show = show
u.status = status
+ u.keyID = user.keyID
break
#Print status in chat window
if self.plugin.windows[account]['chats'].has_key(user.jid):
@@ -1299,9 +1308,9 @@ class roster_Window:
self.plugin.send('SUB', account, (jid, txt))
if not self.contacts[account].has_key(jid):
user1 = user(jid, jid, ['general'], 'requested', \
- 'requested', 'sub', '', 0)
+ 'requested', 'sub', '', 0, '')
self.contacts[account][jid] = [user1]
- self.add_user_to_roster(jid, account)
+ self.add_user_to_roster(jid, account, '')
def on_treeview_event(self, widget, event):
"""popup user's group's or agent menu"""
@@ -1345,20 +1354,35 @@ class roster_Window:
self.remove_user(u, account)
del self.contacts[account][u.jid]
- def change_status(self, widget, account, status):
- if status != 'online' and status != 'offline':
- w = awayMsg_Window()
- txt = w.run()
- if txt != -1:
- self.plugin.send('STATUS', account, (status, txt))
- else:
- txt = status
- self.plugin.send('STATUS', account, (status, txt))
+ def send_status(self, account, status, txt):
+ if status != 'offline':
+ keyid = None
+ if self.plugin.accounts[account].has_key("keyid"):
+ keyid = self.plugin.accounts[account]["keyid"]
+ if keyid and not self.plugin.connected[account]:
+ passphrase = ''
+ #TODO: ask passphrase
+ w = passphrase_Window()
+ passphrase = w.run()
+ if passphrase == -1:
+ passphrase = ''
+ self.plugin.send('PASSPHRASE', account, passphrase)
+ self.plugin.send('STATUS', account, (status, txt))
if status == 'online':
self.plugin.sleeper_state[account] = 1
else:
self.plugin.sleeper_state[account] = 0
+ def change_status(self, widget, account, status):
+ if status != 'online' and status != 'offline':
+ w = awayMsg_Window()
+ txt = w.run()
+ if txt == -1:
+ return
+ else:
+ txt = status
+ self.send_status(account, status, txt)
+
def on_optionmenu_changed(self, widget):
"""When we change our status"""
optionmenu = self.xml.get_widget('optionmenu')
@@ -1377,11 +1401,7 @@ class roster_Window:
warning_Window(_("You must setup an account before connecting to jabber network."))
return
for acct in accounts:
- self.plugin.send('STATUS', acct, (status, txt))
- if status == 'online':
- self.plugin.sleeper_state[acct] = 1
- else:
- self.plugin.sleeper_state[acct] = 0
+ self.send_status(acct, status, txt)
def set_optionmenu(self):
#table to change index in plugin.connected to index in optionmenu
@@ -1423,9 +1443,9 @@ class roster_Window:
"""when we receive a message"""
if not self.contacts[account].has_key(jid):
user1 = user(jid, jid, ['not in list'], \
- 'not in list', 'not in list', 'none', '', 0)
+ 'not in list', 'not in list', 'none', '', 0, '')
self.contacts[account][jid] = [user1]
- self.add_user_to_roster(jid, account)
+ self.add_user_to_roster(jid, account, '')
iters = self.get_user_iter(jid, account)
if iters:
path = self.tree.get_model().get_path(iters[0])
@@ -1445,7 +1465,7 @@ class roster_Window:
# tim = time.strftime("[%H:%M:%S]")
self.plugin.queues[account][jid].put((msg, tim))
if not path:
- self.add_user_to_roster(jid, account)
+ self.add_user_to_roster(jid, account, '')
iters = self.get_user_iter(jid, account)
path = self.tree.get_model().get_path(iters[0])
self.tree.expand_row(path[0:1], FALSE)
@@ -1747,7 +1767,8 @@ class roster_Window:
parent_i = model.iter_parent(iter_source)
if model.iter_n_children(parent_i) == 1: #this was the only child
model.remove(parent_i)
- self.add_user_to_roster(data, account)
+ #TODO: get the good keyID
+ self.add_user_to_roster(data, account, '')
if context.action == gtk.gdk.ACTION_MOVE:
context.finish(True, True, etime)
return
@@ -2060,9 +2081,10 @@ class plugin:
self.roster.on_status_changed(account, status)
def handle_event_notify(self, account, array):
- #('NOTIFY', account, (jid, status, message, resource, priority, role, \
- #affiliation, real_jid, reason, actor, statusCode))
+ #('NOTIFY', account, (jid, status, message, resource, priority, keyID,
+ # role, affiliation, real_jid, reason, actor, statusCode))
jid = string.split(array[0], '/')[0]
+ keyID = array[5]
resource = array[3]
if not resource:
resource = ''
@@ -2088,12 +2110,13 @@ class plugin:
luser[0].show != 'offline')) and not string.find(jid, "@") <= 0:
user1 = user(user1.jid, user1.name, user1.groups, \
user1.show, user1.status, user1.sub, user1.resource, \
- user1.priority)
+ user1.priority, user1.keyID)
luser.append(user1)
user1.resource = resource
user1.show = array[1]
user1.status = array[2]
user1.priority = priority
+ user1.keyID = keyID
if string.find(jid, "@") <= 0:
#It must be an agent
if self.roster.contacts[account].has_key(ji):
@@ -2105,8 +2128,8 @@ class plugin:
elif self.windows[account]['gc'].has_key(ji):
#it is a groupchat presence
self.windows[account]['gc'][ji].chg_user_status(resource, array[1],\
- array[2], array[5], array[6], array[7], array[8], array[9], \
- array[10], account)
+ array[2], array[6], array[7], array[8], array[9], array[10], \
+ array[11], account)
def handle_event_msg(self, account, array):
#('MSG', account, (user, msg, time))
@@ -2137,9 +2160,9 @@ class plugin:
self.roster.redraw_jid(u.jid, account)
else:
user1 = user(jid, jid, ['general'], 'online', \
- 'online', 'to', array[2], 0)
+ 'online', 'to', array[2], 0, '')
self.roster.contacts[account][jid] = [user1]
- self.roster.add_user_to_roster(jid, account)
+ self.roster.add_user_to_roster(jid, account, '')
warning_Window(_("You are now authorized by %s") % jid)
def handle_event_unsubscribed(self, account, jid):