Commit 1b995e4b authored by louiz’'s avatar louiz’

Data form support.

supported yet:
text-single, text-private, list-single, boolean

The interface is really ugly, but, well, it works
parent 33c69df1
...@@ -54,6 +54,7 @@ class Connection(sleekxmpp.ClientXMPP): ...@@ -54,6 +54,7 @@ class Connection(sleekxmpp.ClientXMPP):
self.auto_authorize = None self.auto_authorize = None
self.register_plugin('xep_0030') self.register_plugin('xep_0030')
self.register_plugin('xep_0045') self.register_plugin('xep_0045')
self.register_plugin('xep_0004')
if config.get('send_poezio_info', 'true') == 'true': if config.get('send_poezio_info', 'true') == 'true':
info = {'name':'poezio', info = {'name':'poezio',
'version':'0.7'} 'version':'0.7'}
......
...@@ -42,6 +42,7 @@ import multiuserchat as muc ...@@ -42,6 +42,7 @@ import multiuserchat as muc
import tabs import tabs
import windows import windows
from data_forms import DataFormsTab
from connection import connection from connection import connection
from config import config from config import config
from logger import logger from logger import logger
...@@ -159,6 +160,8 @@ class Core(object): ...@@ -159,6 +160,8 @@ class Core(object):
self.xmpp.add_event_handler("roster_update", self.on_roster_update) self.xmpp.add_event_handler("roster_update", self.on_roster_update)
self.xmpp.add_event_handler("changed_status", self.on_presence) self.xmpp.add_event_handler("changed_status", self.on_presence)
self.xmpp.add_event_handler("changed_subscription", self.on_changed_subscription) self.xmpp.add_event_handler("changed_subscription", self.on_changed_subscription)
self.xmpp.add_event_handler("message_xform", self.on_data_form)
self.information(_('Welcome to poezio!')) self.information(_('Welcome to poezio!'))
self.refresh_window() self.refresh_window()
...@@ -196,6 +199,21 @@ class Core(object): ...@@ -196,6 +199,21 @@ class Core(object):
tab.on_info_win_size_changed() tab.on_info_win_size_changed()
self.refresh_window() self.refresh_window()
def on_data_form(self, message):
"""
When a data form is received
"""
self.information('%s' % messsage)
def open_new_form(self, form, on_cancel, on_send, **kwargs):
"""
Open a new tab containing the form
The callback are called with the completed form as parameter in
addition with kwargs
"""
form_tab = DataFormsTab(self, form, on_cancel, on_send, kwargs)
self.add_tab(form_tab, True)
def on_got_offline(self, presence): def on_got_offline(self, presence):
jid = presence['from'] jid = presence['from']
contact = roster.get_contact_by_jid(jid.bare) contact = roster.get_contact_by_jid(jid.bare)
...@@ -334,7 +352,7 @@ class Core(object): ...@@ -334,7 +352,7 @@ class Core(object):
if not room.joined: # user in the room BEFORE us. if not room.joined: # user in the room BEFORE us.
# ignore redondant presence message, see bug #1509 # ignore redondant presence message, see bug #1509
if from_nick not in [user.nick for user in room.users]: if from_nick not in [user.nick for user in room.users]:
new_user = User(from_nick, affiliation, show, status, role) new_user = User(from_nick, affiliation, show, status, role, jid)
room.users.append(new_user) room.users.append(new_user)
if from_nick == room.own_nick: if from_nick == room.own_nick:
room.joined = True room.joined = True
...@@ -700,6 +718,7 @@ class Core(object): ...@@ -700,6 +718,7 @@ class Core(object):
""" """
curses.curs_set(1) curses.curs_set(1)
curses.noecho() curses.noecho()
curses.nonl()
theme.init_colors() theme.init_colors()
stdscr.keypad(True) stdscr.keypad(True)
......
This diff is collapsed.
...@@ -51,6 +51,7 @@ class Tab(object): ...@@ -51,6 +51,7 @@ class Tab(object):
def __init__(self, core): def __init__(self, core):
self.core = core # a pointer to core, to access its attributes (ugly?) self.core = core # a pointer to core, to access its attributes (ugly?)
self._color_state = theme.COLOR_TAB_NORMAL
self.nb = Tab.number self.nb = Tab.number
Tab.number += 1 Tab.number += 1
self.size = (self.height, self.width) = self.core.stdscr.getmaxyx() self.size = (self.height, self.width) = self.core.stdscr.getmaxyx()
...@@ -133,7 +134,7 @@ class Tab(object): ...@@ -133,7 +134,7 @@ class Tab(object):
""" """
returns the color that should be used in the GlobalInfoBar returns the color that should be used in the GlobalInfoBar
""" """
return theme.COLOR_TAB_NORMAL return self._color_state
def set_color_state(self, color): def set_color_state(self, color):
""" """
...@@ -160,13 +161,13 @@ class Tab(object): ...@@ -160,13 +161,13 @@ class Tab(object):
""" """
called when this tab loses the focus. called when this tab loses the focus.
""" """
pass self._color_state = theme.COLOR_TAB_NORMAL
def on_gain_focus(self): def on_gain_focus(self):
""" """
called when this tab gains the focus. called when this tab gains the focus.
""" """
pass self._color_state = theme.COLOR_TAB_CURRENT
def add_message(self): def add_message(self):
""" """
...@@ -367,7 +368,8 @@ class MucTab(ChatTab): ...@@ -367,7 +368,8 @@ class MucTab(ChatTab):
self.commands['nick'] = (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room"), None) self.commands['nick'] = (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room"), None)
self.commands['recolor'] = (self.command_recolor, _('Usage: /recolor\nRecolor: Re-assign a color to all participants of the current room, based on the last time they talked. Use this if the participants currently talking have too many identical colors.'), None) self.commands['recolor'] = (self.command_recolor, _('Usage: /recolor\nRecolor: Re-assign a color to all participants of the current room, based on the last time they talked. Use this if the participants currently talking have too many identical colors.'), None)
self.commands['cycle'] = (self.command_cycle, _('Usage: /cycle [message]\nCycle: Leaves the current room and rejoin it immediately'), None) self.commands['cycle'] = (self.command_cycle, _('Usage: /cycle [message]\nCycle: Leaves the current room and rejoin it immediately'), None)
self.commands['info'] = (self.command_info, _('Usage: /info <nickname>\nInfoDisplay some information about the user in the MUC: his/here role, affiliation, status and status message.'), None) self.commands['info'] = (self.command_info, _('Usage: /info <nickname>\nInfo: Display some information about the user in the MUC: his/here role, affiliation, status and status message.'), None)
self.commands['configure'] = (self.command_configure, _('Usage: /configure\nConfigure: Configure the current room, through a form.'), None)
self.resize() self.resize()
def scroll_user_list_up(self): def scroll_user_list_up(self):
...@@ -388,9 +390,28 @@ class MucTab(ChatTab): ...@@ -388,9 +390,28 @@ class MucTab(ChatTab):
user = self.get_room().get_user_by_name(args[0]) user = self.get_room().get_user_by_name(args[0])
if not user: if not user:
return self.core.information("Unknown user: %s" % args[0]) return self.core.information("Unknown user: %s" % args[0])
self.get_room().add_message("%s: show: %s, affiliation: %s, role: %s\n%s"% (args[0], user.show or 'Available', user.role or 'None', user.affiliation or 'None', user.status)) self.get_room().add_message("%s%s: show: %s, affiliation: %s, role: %s\n%s"% (args[0], user.user.show or 'Available', user.role or 'None', user.affiliation or 'None', user.status))
self.core.refresh_window() self.core.refresh_window()
def command_configure(self, arg):
form = self.core.xmpp.plugin['xep_0045'].getRoomForm(self.get_name())
self.core.information('%s' % form)
self.core.open_new_form(form, self.cancel_config, self.send_config)
def cancel_config(self, form):
"""
The user do not want to send his/her config, send an iq cancel
"""
self.core.xmpp.plugin['xep_0045'].cancelConfig(self.get_name())
self.core.close_tab()
def send_config(self, form):
"""
The user sends his/her config to the server
"""
self.core.xmpp.plugin['xep_0045'].configureRoom(self.get_name(), form)
self.core.close_tab()
def command_cycle(self, arg): def command_cycle(self, arg):
if self.get_room().joined: if self.get_room().joined:
muc.leave_groupchat(self.core.xmpp, self.get_name(), self.get_room().own_nick, arg) muc.leave_groupchat(self.core.xmpp, self.get_name(), self.get_room().own_nick, arg)
......
...@@ -36,11 +36,12 @@ class User(object): ...@@ -36,11 +36,12 @@ class User(object):
""" """
keep trace of an user in a Room keep trace of an user in a Room
""" """
def __init__(self, nick, affiliation, show, status, role): def __init__(self, nick, affiliation, show, status, role, jid):
self.last_talked = datetime(1, 1, 1) # The oldest possible time self.last_talked = datetime(1, 1, 1) # The oldest possible time
self.update(affiliation, show, status, role) self.update(affiliation, show, status, role)
self.change_nick(nick) self.change_nick(nick)
self.color = choice(theme.LIST_COLOR_NICKNAMES) self.color = choice(theme.LIST_COLOR_NICKNAMES)
self.jid = jid
def update(self, affiliation, show, status, role): def update(self, affiliation, show, status, role):
self.affiliation = affiliation self.affiliation = affiliation
......
...@@ -695,19 +695,24 @@ class Input(Win): ...@@ -695,19 +695,24 @@ class Input(Win):
"KEY_BACKSPACE": self.key_backspace, "KEY_BACKSPACE": self.key_backspace,
'^?': self.key_backspace, '^?': self.key_backspace,
} }
Win.__init__(self) Win.__init__(self)
self.text = '' self.text = ''
self.pos = 0 # cursor position self.pos = 0 # cursor position
self.line_pos = 0 # position (in self.text) of self.line_pos = 0 # position (in self.text) of
self.on_input = None # callback called on any key pressed
self.color = None # use this color on addstr
def set_color(self, color):
self.color = color
self.rewrite_text()
def is_empty(self): def is_empty(self):
return len(self.text) == 0 return len(self.text) == 0
def resize(self, height, width, y, x, stdscr): def resize(self, height, width, y, x, stdscr=None): # TODO remove stdscr
self._resize(height, width, y, x, stdscr) self._resize(height, width, y, x, stdscr)
self._win.erase() # self._win.erase()
self.addnstr(0, 0, self.text, self.width-1) # self.addnstr(0, 0, self.text, self.width-1)
def jump_word_left(self): def jump_word_left(self):
""" """
...@@ -960,8 +965,12 @@ class Input(Win): ...@@ -960,8 +965,12 @@ class Input(Win):
self.key_end(False) self.key_end(False)
def do_command(self, key, reset=True): def do_command(self, key, reset=True):
log.debug('do_command: %s\n' % key)
if key in self.key_func: if key in self.key_func:
return self.key_func[key]() res = self.key_func[key]()
if self.on_input:
self.on_input(self.get_text())
return res
if not key or len(key) > 1: if not key or len(key) > 1:
return False # ignore non-handled keyboard shortcuts return False # ignore non-handled keyboard shortcuts
self.reset_completion() self.reset_completion()
...@@ -973,6 +982,8 @@ class Input(Win): ...@@ -973,6 +982,8 @@ class Input(Win):
self.pos += len(key) self.pos += len(key)
if reset: if reset:
self.rewrite_text() self.rewrite_text()
if self.on_input:
self.on_input(self.get_text())
return True return True
def get_text(self): def get_text(self):
...@@ -987,8 +998,16 @@ class Input(Win): ...@@ -987,8 +998,16 @@ class Input(Win):
""" """
with g_lock: with g_lock:
self._win.erase() self._win.erase()
if self.color:
self._win.attron(curses.color_pair(self.color))
self.addstr(self.text[self.line_pos:self.line_pos+self.width-1]) self.addstr(self.text[self.line_pos:self.line_pos+self.width-1])
if self.color:
(y, x) = self._win.getyx()
size = self.width-x
self.addnstr(' '*size, size, curses.color_pair(self.color))
self.addstr(0, self.pos, '') # WTF, this works but .move() doesn't… self.addstr(0, self.pos, '') # WTF, this works but .move() doesn't…
if self.color:
self._win.attroff(curses.color_pair(self.color))
self._refresh() self._refresh()
def refresh(self): def refresh(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment