we now have groupchat configuration !! (and a Data Form Parser JEP 0004)
This commit is contained in:
parent
ba272a9553
commit
ebef428ae1
|
@ -107,7 +107,7 @@ class Connection:
|
|||
'SUBSCRIBED': [], 'UNSUBSCRIBED': [], 'SUBSCRIBE': [], \
|
||||
'AGENT_INFO': [], 'AGENT_INFO_ITEMS': [], 'AGENT_INFO_INFO': [], \
|
||||
'QUIT': [], 'ACC_OK': [], 'MYVCARD': [], 'OS_INFO': [], 'VCARD': [], \
|
||||
'GC_MSG': [], 'GC_SUBJECT': [], 'BAD_PASSPHRASE': [], \
|
||||
'GC_MSG': [], 'GC_SUBJECT': [], 'GC_CONFIG': [], 'BAD_PASSPHRASE': [],\
|
||||
'ROSTER_INFO': []}
|
||||
self.name = name
|
||||
self.connected = 0 # offline
|
||||
|
@ -286,6 +286,7 @@ class Connection:
|
|||
# END disconenctedCB
|
||||
|
||||
def _rosterSetCB(self, con, iq_obj):
|
||||
gajim.log.debug('rosterSetCB')
|
||||
for item in iq_obj.getQueryNode().getChildren():
|
||||
jid = item.getAttr('jid')
|
||||
name = item.getAttr('name')
|
||||
|
@ -297,6 +298,7 @@ class Connection:
|
|||
self.dispatch('ROSTER_INFO', (jid, name, sub, ask, groups))
|
||||
|
||||
def _BrowseResultCB(self, con, iq_obj):
|
||||
gajim.log.debug('BrowseResultCB')
|
||||
identities, features, items = [], [], []
|
||||
q = iq_obj.getTag('service')
|
||||
if not q:
|
||||
|
@ -318,6 +320,7 @@ class Connection:
|
|||
self.dispatch('AGENT_INFO', (jid, identities, features, items))
|
||||
|
||||
def _DiscoverItemsCB(self, con, iq_obj):
|
||||
gajim.log.debug('DiscoverItemsCB')
|
||||
qp = iq_obj.getQueryPayload()
|
||||
items = []
|
||||
if not qp:
|
||||
|
@ -331,10 +334,12 @@ class Connection:
|
|||
self.dispatch('AGENT_INFO_ITEMS', (jid, items))
|
||||
|
||||
def _DiscoverInfoErrorCB(self, con, iq_obj):
|
||||
gajim.log.debug('DiscoverInfoErrorCB')
|
||||
jid = str(iq_obj.getFrom())
|
||||
con.browseAgents(jid)
|
||||
|
||||
def _DiscoverInfoCB(self, con, iq_obj):
|
||||
gajim.log.debug('DiscoverInfoCB')
|
||||
# According to JEP-0030:
|
||||
# For identity: category, name is mandatory, type is optional.
|
||||
# For feature: var is mandatory
|
||||
|
@ -358,6 +363,7 @@ class Connection:
|
|||
self.connection.discoverItems(jid)
|
||||
|
||||
def _VersionCB(self, con, iq_obj):
|
||||
gajim.log.debug('VersionCB')
|
||||
f = iq_obj.getFrom()
|
||||
iq_obj.setFrom(iq_obj.getTo())
|
||||
iq_obj.setTo(f)
|
||||
|
@ -371,6 +377,7 @@ class Connection:
|
|||
self.connection.send(iq_obj)
|
||||
|
||||
def _VersionResultCB(self, con, iq_obj):
|
||||
gajim.log.debug('VersionResultCB')
|
||||
client_info = ''
|
||||
os_info = ''
|
||||
qp = iq_obj.getTag('query')
|
||||
|
@ -382,6 +389,70 @@ class Connection:
|
|||
os_info += qp.getTag('os').getData()
|
||||
jid = iq_obj.getFrom().getStripped()
|
||||
self.dispatch('OS_INFO', (jid, client_info, os_info))
|
||||
|
||||
def _MucOwnerCB(self, con, iq_obj):
|
||||
gajim.log.debug('MucOwnerCB')
|
||||
qp = iq_obj.getQueryPayload()
|
||||
node = None
|
||||
for q in qp:
|
||||
if q.getNamespace() == common.jabber.NS_XDATA:
|
||||
node = q
|
||||
if not node:
|
||||
return
|
||||
# Parse the form
|
||||
dic = {}
|
||||
tag = node.getTag('title')
|
||||
if tag:
|
||||
dic['title'] = tag.getData()
|
||||
tag = node.getTag('instructions')
|
||||
if tag:
|
||||
dic['instructions'] = tag.getData()
|
||||
i = 0
|
||||
for child in node.getChildren():
|
||||
if child.getName() != 'field':
|
||||
continue
|
||||
var = child.getAttr('var')
|
||||
ctype = child.getAttr('type')
|
||||
label = child.getAttr('label')
|
||||
if not var and ctype != 'fixed': # We must have var if type != fixed
|
||||
continue
|
||||
dic[i] = {}
|
||||
if var:
|
||||
dic[i]['var'] = var
|
||||
if ctype:
|
||||
dic[i]['type'] = ctype
|
||||
if label:
|
||||
dic[i]['label'] = label
|
||||
tags = child.getTags('value')
|
||||
if len(tags):
|
||||
dic[i]['values'] = []
|
||||
for tag in tags:
|
||||
data = tag.getData()
|
||||
if ctype == 'boolean':
|
||||
if data in ['yes', 'true', 'assent']:
|
||||
data = True
|
||||
else:
|
||||
data = False
|
||||
dic[i]['values'].append(data)
|
||||
tag = child.getTag('desc')
|
||||
if tag:
|
||||
dic[i]['desc'] = tag.getData()
|
||||
option_tags = child.getTags('option')
|
||||
if len(option_tags):
|
||||
dic[i]['options'] = {}
|
||||
j = 0
|
||||
for option_tag in option_tags:
|
||||
dic[i]['options'][j] = {}
|
||||
label = option_tag.getAttr('label')
|
||||
if label:
|
||||
dic[i]['options'][j]['label'] = label
|
||||
tags = option_tag.getTags('value')
|
||||
dic[i]['options'][j]['values'] = []
|
||||
for tag in tags:
|
||||
dic[i]['options'][j]['values'].append(tag.getData())
|
||||
j += 1
|
||||
i += 1
|
||||
self.dispatch('GC_CONFIG', (str(iq_obj.getFrom()), dic))
|
||||
|
||||
def connect(self):
|
||||
"""Connect and authentificate to the Jabber server"""
|
||||
|
@ -427,6 +498,8 @@ class Connection:
|
|||
common.jabber.NS_VERSION)
|
||||
con.registerHandler('iq',self._VersionResultCB,'result', \
|
||||
common.jabber.NS_VERSION)
|
||||
con.registerHandler('iq',self._MucOwnerCB,'result', \
|
||||
common.jabber.NS_P_MUC_OWNER)
|
||||
try:
|
||||
con.connect()
|
||||
except:
|
||||
|
@ -691,6 +764,7 @@ class Connection:
|
|||
if not self.connection:
|
||||
return
|
||||
p = common.jabber.Presence(to = '%s@%s/%s' % (room, server, nick))
|
||||
p.setX(common.jabber.NS_P_MUC)
|
||||
self.connection.send(p)
|
||||
|
||||
def send_gc_message(self, jid, msg):
|
||||
|
@ -709,6 +783,13 @@ class Connection:
|
|||
msg_iq.setSubject(subject)
|
||||
self.connection.send(msg_iq)
|
||||
|
||||
def request_gc_config(self, room_jid):
|
||||
iq = common.jabber.Iq(type = 'get', to = room_jid)
|
||||
iq.setQuery(common.jabber.NS_P_MUC_OWNER)
|
||||
id = self.connection.getAnID()
|
||||
iq.setID(id)
|
||||
self.connection.send(iq)
|
||||
|
||||
def send_gc_status(self, nick, jid, show, status):
|
||||
if not self.connection:
|
||||
return
|
||||
|
@ -742,6 +823,47 @@ class Connection:
|
|||
iq.setID(id)
|
||||
self.connection.send(iq)
|
||||
|
||||
def send_gc_config(self, room_jid, config):
|
||||
iq = common.jabber.Iq(type = 'set', to = room_jid)
|
||||
query = iq.setQuery(common.jabber.NS_P_MUC_OWNER)
|
||||
x = query.insertTag('x', attrs = {'xmlns': common.jabber.NS_XDATA, \
|
||||
'type': 'submit'})
|
||||
if config.has_key('title'):
|
||||
x.insertTag('title').insertData(config['title'])
|
||||
if config.has_key('instructions'):
|
||||
x.insertTag('instructions').insertData(config['instructions'])
|
||||
i = 0
|
||||
while config.has_key(i):
|
||||
tag = x.insertTag('field')
|
||||
if config[i].has_key('type'):
|
||||
tag.putAttr('type', config[i]['type'])
|
||||
if config[i].has_key('var'):
|
||||
tag.putAttr('var', config[i]['var'])
|
||||
if config[i].has_key('label'):
|
||||
tag.putAttr('label', config[i]['label'])
|
||||
if config[i].has_key('values'):
|
||||
for val in config[i]['values']:
|
||||
if val == False:
|
||||
val = 'false'
|
||||
elif val == True:
|
||||
val = 'true'
|
||||
tag.insertTag('value').insertData(val)
|
||||
if config[i].has_key('desc'):
|
||||
tag.insertTag('desc').insertData(config[i]['desc'])
|
||||
if config[i].has_key('options'):
|
||||
j = 0
|
||||
while config[i]['options'].has_key(j):
|
||||
opt_tag = tag.insertTag('option')
|
||||
if config[i]['options'][j].has_key('label'):
|
||||
opt_tag.putAttr('label', config[i]['options'][j]['label'])
|
||||
for val in config[i]['options'][j]['values']:
|
||||
opt_tag.insertTag('value').insertData(val)
|
||||
j += 1
|
||||
i += 1
|
||||
id = self.connection.getAnID()
|
||||
iq.setID(id)
|
||||
self.connection.send(iq)
|
||||
|
||||
def gpg_passphrase(self, passphrase):
|
||||
if USE_GPG:
|
||||
self.gpg.passphrase = passphrase
|
||||
|
|
125
src/config.py
125
src/config.py
|
@ -1087,7 +1087,7 @@ class Account_modification_window:
|
|||
self.plugin.sleeper_state[name] = \
|
||||
self.plugin.sleeper_state[self.account]
|
||||
#upgrade account variable in opened windows
|
||||
for kind in ['infos', 'chats', 'gc']:
|
||||
for kind in ['infos', 'chats', 'gc', 'gc_config']:
|
||||
for j in self.plugin.windows[name][kind]:
|
||||
self.plugin.windows[name][kind][j].account = name
|
||||
#upgrade account in systray
|
||||
|
@ -1167,7 +1167,8 @@ class Account_modification_window:
|
|||
if save_password:
|
||||
gajim.connections[name].password = password
|
||||
#update variables
|
||||
self.plugin.windows[name] = {'infos': {}, 'chats': {}, 'gc': {}}
|
||||
self.plugin.windows[name] = {'infos': {}, 'chats': {}, 'gc': {}, \
|
||||
'gc_config': {}}
|
||||
self.plugin.queues[name] = {}
|
||||
gajim.connections[name].connected = 0
|
||||
self.plugin.roster.groups[name] = {}
|
||||
|
@ -1904,6 +1905,126 @@ class Service_discovery_window:
|
|||
self.browse(server_address)
|
||||
self.plugin.save_config()
|
||||
|
||||
class Groupchat_config_window:
|
||||
'''Groupchat_config_window class'''
|
||||
def __init__(self, plugin, account, room_jid, config):
|
||||
self.plugin = plugin
|
||||
self.account = account
|
||||
self.room_jid = room_jid
|
||||
self.config = config
|
||||
self.xml = gtk.glade.XML(GTKGUI_GLADE, 'groupchat_config_window', APP)
|
||||
self.window = self.xml.get_widget('groupchat_config_window')
|
||||
self.config_table = self.xml.get_widget('config_table')
|
||||
self.fill_table()
|
||||
self.xml.signal_autoconnect(self)
|
||||
|
||||
def on_groupchat_config_window_destroy(self, widget):
|
||||
del self.plugin.windows[self.account]['gc_config'][self.room_jid]
|
||||
|
||||
def on_cancel_button_clicked(self, widget):
|
||||
self.window.destroy()
|
||||
|
||||
def on_apply_button_clicked(self, widget):
|
||||
gajim.connections[self.account].send_gc_config(self.room_jid, self.config)
|
||||
|
||||
def on_checkbutton_toggled(self, widget, index):
|
||||
self.config[index]['values'][0] = widget.get_active()
|
||||
|
||||
def on_combobox_changed(self, widget, index):
|
||||
self.config[index]['values'][0] = self.config[index]['options'][ \
|
||||
widget.get_active()]['values'][0]
|
||||
|
||||
def on_entry_changed(self, widget, index):
|
||||
self.config[index]['values'][0] = widget.get_text()
|
||||
|
||||
def on_textbuffer_changed(self, widget, index):
|
||||
begin, end = widget.get_bounds()
|
||||
self.config[index]['values'][0] = widget.get_text(begin, end)
|
||||
|
||||
def fill_table(self):
|
||||
if self.config.has_key('title'):
|
||||
self.window.set_title(self.config['title'])
|
||||
if self.config.has_key('instructions'):
|
||||
self.xml.get_widget('instructions_label').set_text(\
|
||||
self.config['instructions'])
|
||||
i = 0
|
||||
while self.config.has_key(i):
|
||||
if not self.config[i].has_key('type'):
|
||||
i += 1
|
||||
continue
|
||||
ctype = self.config[i]['type']
|
||||
if ctype == 'hidden':
|
||||
i += 1
|
||||
continue
|
||||
nbrows = self.config_table.get_property('n-rows')
|
||||
self.config_table.resize(nbrows + 1, 2)
|
||||
if self.config[i].has_key('label'):
|
||||
label = gtk.Label(self.config[i]['label'])
|
||||
label.set_alignment(0.0, 0.5)
|
||||
self.config_table.attach(label, 0, 1, nbrows, nbrows + 1, gtk.FILL \
|
||||
| gtk.SHRINK)
|
||||
desc = None
|
||||
if self.config[i].has_key('desc'):
|
||||
desc = self.config[i]['desc']
|
||||
max = 1
|
||||
if ctype == 'boolean':
|
||||
widget = gtk.CheckButton(desc, False)
|
||||
widget.set_active(self.config[i]['values'][0])
|
||||
widget.connect('toggled', self.on_checkbutton_toggled, i)
|
||||
max = 2
|
||||
elif ctype == 'fixed':
|
||||
widget = gtk.Label('\n'.join(self.config[i]['values']))
|
||||
widget.set_alignment(0.0, 0.5)
|
||||
max = 4
|
||||
elif ctype == 'jid-multi':
|
||||
#TODO
|
||||
widget = gtk.Label('')
|
||||
elif ctype == 'jid-single':
|
||||
#TODO
|
||||
widget = gtk.Label('')
|
||||
elif ctype == 'list-multi':
|
||||
#TODO
|
||||
widget = gtk.Label('')
|
||||
elif ctype == 'list-single':
|
||||
widget = gtk.combo_box_new_text()
|
||||
widget.connect('changed', self.on_combobox_changed, i)
|
||||
index = 0
|
||||
j = 0
|
||||
while self.config[i]['options'].has_key(j):
|
||||
if self.config[i]['options'][j]['values'][0] == \
|
||||
self.config[i]['values'][0]:
|
||||
index = j
|
||||
widget.append_text(self.config[i]['options'][j]['label'])
|
||||
j += 1
|
||||
widget.set_active(index)
|
||||
max = 3
|
||||
elif ctype == 'text-multi':
|
||||
widget = gtk.TextView()
|
||||
widget.get_buffer().connect('changed', self.on_textbuffer_changed, \
|
||||
i)
|
||||
widget.get_buffer().set_text('\n'.join(self.config[i]['values']))
|
||||
max = 4
|
||||
elif ctype == 'text-private':
|
||||
widget = gtk.Entry()
|
||||
widget.connect('changed', self.on_entry_changed, i)
|
||||
widget.set_text(self.config[i]['values'][0])
|
||||
widget.set_visibility(False)
|
||||
max = 3
|
||||
elif ctype == 'text-single':
|
||||
widget = gtk.Entry()
|
||||
widget.connect('changed', self.on_entry_changed, i)
|
||||
widget.set_text(self.config[i]['values'][0])
|
||||
max = 3
|
||||
i += 1
|
||||
if max < 4:
|
||||
self.config_table.attach(widget, 1, max, nbrows, nbrows + 1, \
|
||||
gtk.FILL | gtk.SHRINK)
|
||||
widget = gtk.Label()
|
||||
self.config_table.attach(widget, max, 4, nbrows, nbrows + 1)
|
||||
else:
|
||||
self.config_table.attach(widget, 1, max, nbrows, nbrows + 1)
|
||||
self.config_table.show_all()
|
||||
|
||||
class Remove_account_window:
|
||||
'''ask for removing from gajim only or from gajim and server too
|
||||
and do removing of the account given'''
|
||||
|
|
12
src/gajim.py
12
src/gajim.py
|
@ -374,7 +374,7 @@ class Interface:
|
|||
gajim.config.set_per('accounts', name, 'use_proxy', array[6])
|
||||
gajim.config.set_per('accounts', name, 'proxyhost', array[7])
|
||||
gajim.config.set_per('accounts', name, 'proxyport', array[8])
|
||||
self.windows[name] = {'infos': {}, 'chats': {}, 'gc': {}}
|
||||
self.windows[name] = {'infos': {}, 'chats': {}, 'gc': {}, 'gc_config': {}}
|
||||
self.queues[name] = {}
|
||||
gajim.connections[name].connected = 0
|
||||
self.nicks[name] = array[1]
|
||||
|
@ -433,6 +433,13 @@ class Interface:
|
|||
self.windows[account]['gc'][jid].print_conversation(\
|
||||
'%s has set the subject to %s' % (jids[1], array[1]), jid)
|
||||
|
||||
def handle_event_gc_config(self, account, array):
|
||||
#('GC_CONFIG', account, (jid, config)) config is a dict
|
||||
jid = array[0].split('/')[0]
|
||||
if not self.windows[account]['gc_config'].has_key(jid):
|
||||
self.windows[account]['gc_config'][jid] = \
|
||||
config.Groupchat_config_window(self, account, jid, array[1])
|
||||
|
||||
def handle_event_bad_passphrase(self, account, array):
|
||||
dialogs.Warning_dialog(_('Your GPG passphrase is wrong, so you are connected without your GPG key.'))
|
||||
|
||||
|
@ -612,6 +619,7 @@ class Interface:
|
|||
conn.register_handler('OS_INFO', self.handle_event_os_info)
|
||||
conn.register_handler('GC_MSG', self.handle_event_gc_msg)
|
||||
conn.register_handler('GC_SUBJECT', self.handle_event_gc_subject)
|
||||
conn.register_handler('GC_CONFIG', self.handle_event_gc_config)
|
||||
conn.register_handler('BAD_PASSPHRASE', self.handle_event_bad_passphrase)
|
||||
conn.register_handler('ROSTER_INFO', self.handle_event_roster_info)
|
||||
|
||||
|
@ -637,7 +645,7 @@ class Interface:
|
|||
self.nicks = {}
|
||||
self.sleeper_state = {} #whether we pass auto away / xa or not
|
||||
for a in gajim.connections:
|
||||
self.windows[a] = {'infos': {}, 'chats': {}, 'gc': {}}
|
||||
self.windows[a] = {'infos': {}, 'chats': {}, 'gc': {}, 'gc_config': {}}
|
||||
self.queues[a] = {}
|
||||
self.nicks[a] = gajim.config.get_per('accounts', a, 'name')
|
||||
self.sleeper_state[a] = 0 #0:don't use sleeper for this account
|
||||
|
|
|
@ -57,6 +57,8 @@ class Groupchat_window(chat.Chat):
|
|||
self.on_chat_notebook_switch_page)
|
||||
self.xml.signal_connect('on_set_button_clicked', \
|
||||
self.on_set_button_clicked)
|
||||
self.xml.signal_connect('on_configure_button_clicked', \
|
||||
self.on_configure_button_clicked)
|
||||
self.xml.signal_connect('on_groupchat_window_key_press_event', \
|
||||
self.on_groupchat_window_key_press_event)
|
||||
|
||||
|
@ -234,6 +236,10 @@ class Groupchat_window(chat.Chat):
|
|||
subject = self.xml.get_widget('subject_entry').get_text()
|
||||
gajim.connections[self.account].send_gc_subject(room_jid, subject)
|
||||
|
||||
def on_configure_button_clicked(self, widget):
|
||||
room_jid = self.get_active_jid()
|
||||
gajim.connections[self.account].request_gc_config(room_jid)
|
||||
|
||||
def on_message_textview_key_press_event(self, widget, event):
|
||||
"""When a key is pressed:
|
||||
if enter is pressed without the shit key, message (if not empty) is sent
|
||||
|
|
843
src/gtkgui.glade
843
src/gtkgui.glade
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue