PGP support !

This commit is contained in:
Yann Leboulanger 2004-10-07 14:43:59 +00:00
parent c16544c059
commit 66d0415c40
4 changed files with 441 additions and 61 deletions

View file

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

View file

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

View file

@ -536,6 +536,34 @@
</packing>
</child>
<child>
<widget class="GtkToggleButton" id="toggle_gpg">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NONE</property>
<property name="focus_on_click">False</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<child>
<widget class="GtkImage" id="image169">
<property name="visible">True</property>
<property name="stock">gtk-dialog-authentication</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_contact">
<property name="visible">True</property>
@ -7752,4 +7780,123 @@ when NOT online</property>
</child>
</widget>
<widget class="GtkDialog" id="Passphrase">
<property name="visible">True</property>
<property name="title" translatable="yes">Passphrase</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">True</property>
<signal name="key_press_event" handler="on_Passphrase_key_press_event" last_modification_time="Thu, 07 Oct 2004 14:25:48 GMT"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox4">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancelbutton1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="okbutton2">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox30">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="label148">
<property name="visible">True</property>
<property name="label" translatable="yes">Enter your passphrase</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="editable">True</property>
<property name="visibility">False</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View file

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