summaryrefslogtreecommitdiff
path: root/src/gui.py
diff options
context:
space:
mode:
authorlouiz@4325f9fc-e183-4c21-96ce-0ab188b42d13 <louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13>2010-11-09 20:37:39 +0000
committerlouiz@4325f9fc-e183-4c21-96ce-0ab188b42d13 <louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13>2010-11-09 20:37:39 +0000
commit7fd6153720746edff4af900dc9c3579d3cde6e32 (patch)
tree41a6053716e059f24a9e4b9e3b935c28dac940c3 /src/gui.py
parentdf6d2fc2d3aa8b6ea396e96acddf6b695ec35197 (diff)
downloadpoezio-7fd6153720746edff4af900dc9c3579d3cde6e32.tar.gz
poezio-7fd6153720746edff4af900dc9c3579d3cde6e32.tar.bz2
poezio-7fd6153720746edff4af900dc9c3579d3cde6e32.tar.xz
poezio-7fd6153720746edff4af900dc9c3579d3cde6e32.zip
fix some little issues. Rename gui to core, use logging lib instead of the custom debug option. Add a -d option
Diffstat (limited to 'src/gui.py')
-rw-r--r--src/gui.py1393
1 files changed, 0 insertions, 1393 deletions
diff --git a/src/gui.py b/src/gui.py
deleted file mode 100644
index 01fa38c8..00000000
--- a/src/gui.py
+++ /dev/null
@@ -1,1393 +0,0 @@
-# Copyright 2010 Le Coz Florent <louiz@louiz.org>
-#
-# This file is part of Poezio.
-#
-# Poezio 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 3 of the License.
-#
-# Poezio 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.
-#
-# You should have received a copy of the GNU General Public License
-# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
-
-from gettext import (bindtextdomain, textdomain, bind_textdomain_codeset,
- gettext as _)
-from os.path import isfile
-
-from time import sleep
-
-import os
-import re
-import sys
-import shlex
-import curses
-import threading
-import webbrowser
-
-from datetime import datetime
-
-import common
-import theme
-
-import multiuserchat as muc
-from handler import Handler
-from config import config
-from tab import MucTab, InfoTab, PrivateTab, RosterInfoTab, ConversationTab
-from user import User
-from room import Room
-from roster import Roster, RosterGroup, roster
-from contact import Contact, Resource
-from message import Message
-from text_buffer import TextBuffer
-from keyboard import read_char
-from common import jid_get_domain, is_jid
-
-# http://xmpp.org/extensions/xep-0045.html#errorstatus
-ERROR_AND_STATUS_CODES = {
- '401': _('A password is required'),
- '403': _('You are banned from the room'),
- '404': _('The room does\'nt exist'),
- '405': _('Your are not allowed to create a new room'),
- '406': _('A reserved nick must be used'),
- '407': _('You are not in the member list'),
- '409': _('This nickname is already in use or has been reserved'),
- '503': _('The maximum number of users has been reached'),
- }
-
-SHOW_NAME = {
- 'dnd': _('busy'),
- 'away': _('away'),
- 'xa': _('not available'),
- 'chat': _('chatty'),
- '': _('available')
- }
-
-resize_lock = threading.Lock()
-
-class Gui(object):
- """
- User interface using ncurses
- """
- def __init__(self, xmpp):
- self.running = True
- self.stdscr = curses.initscr()
- self.init_curses(self.stdscr)
- self.xmpp = xmpp
- default_tab = InfoTab(self.stdscr, "Info") if self.xmpp.anon\
- else RosterInfoTab(self.stdscr)
- default_tab.on_gain_focus()
- self.tabs = [default_tab]
- # self.roster = Roster()
- # a unique buffer used to store global informations
- # that are displayed in almost all tabs, in an
- # information window.
- self.information_buffer = TextBuffer()
- self.information_win_size = 2 # Todo, get this from config
- self.ignores = {}
- self.resize_timer = None
- self.previous_tab_nb = 0
-
- self.commands = {
- 'help': (self.command_help, '\_o< KOIN KOIN KOIN'),
- 'join': (self.command_join, _("Usage: /join [room_name][@server][/nick] [password]\nJoin: Join the specified room. You can specify a nickname after a slash (/). If no nickname is specified, you will use the default_nick in the configuration file. You can omit the room name: you will then join the room you\'re looking at (useful if you were kicked). You can also provide a room_name without specifying a server, the server of the room you're currently in will be used. You can also provide a password to join the room.\nExamples:\n/join room@server.tld\n/join room@server.tld/John\n/join room2\n/join /me_again\n/join\n/join room@server.tld/my_nick password\n/join / password")),
- 'quit': (self.command_quit, _("Usage: /quit\nQuit: Just disconnect from the server and exit poezio.")),
- 'exit': (self.command_quit, _("Usage: /exit\nExit: Just disconnect from the server and exit poezio.")),
- 'next': (self.rotate_rooms_right, _("Usage: /next\nNext: Go to the next room.")),
- 'n': (self.rotate_rooms_right, _("Usage: /n\nN: Go to the next room.")),
- 'prev': (self.rotate_rooms_left, _("Usage: /prev\nPrev: Go to the previous room.")),
- 'p': (self.rotate_rooms_left, _("Usage: /p\nP: Go to the previous room.")),
- 'win': (self.command_win, _("Usage: /win <number>\nWin: Go to the specified room.")),
- 'w': (self.command_win, _("Usage: /w <number>\nW: Go to the specified room.")),
- 'ignore': (self.command_ignore, _("Usage: /ignore <nickname> \nIgnore: Ignore a specified nickname.")),
- 'unignore': (self.command_unignore, _("Usage: /unignore <nickname>\nUnignore: Remove the specified nickname from the ignore list.")),
- 'part': (self.command_part, _("Usage: /part [message]\n Part: disconnect from a room. You can specify an optional message.")),
- 'show': (self.command_show, _("Usage: /show <availability> [status]\nShow: Change your availability and (optionaly) your status. The <availability> argument is one of \"avail, available, ok, here, chat, away, afk, dnd, busy, xa\" and the optional [status] argument will be your status message")),
- 'away': (self.command_away, _("Usage: /away [message]\nAway: Sets your availability to away and (optional) sets your status message. This is equivalent to '/show away [message]'")),
- 'busy': (self.command_busy, _("Usage: /busy [message]\nBusy: Sets your availability to busy and (optional) sets your status message. This is equivalent to '/show busy [message]'")),
- 'avail': (self.command_avail, _("Usage: /avail [message]\nAvail: Sets your availability to available and (optional) sets your status message. This is equivalent to '/show available [message]'")),
- 'available': (self.command_avail, _("Usage: /available [message]\nAvailable: Sets your availability to available and (optional) sets your status message. This is equivalent to '/show available [message]'")),
- 'bookmark': (self.command_bookmark, _("Usage: /bookmark [roomname][/nick]\nBookmark: Bookmark the specified room (you will then auto-join it on each poezio start). This commands uses the same syntaxe as /join. Type /help join for syntaxe examples. Note that when typing \"/bookmark\" on its own, the room will be bookmarked with the nickname you\'re currently using in this room (instead of default_nick)")),
- 'unquery': (self.command_unquery, _("Usage: /unquery\nClose the private conversation window")),
- 'set': (self.command_set, _("Usage: /set <option> [value]\nSet: Sets the value to the option in your configuration file. You can, for example, change your default nickname by doing `/set default_nick toto` or your resource with `/set resource blabla`. You can also set an empty value (nothing) by providing no [value] after <option>.")),
- 'kick': (self.command_kick, _("Usage: /kick <nick> [reason]\nKick: Kick the user with the specified nickname. You also can give an optional reason.")),
- 'topic': (self.command_topic, _("Usage: /topic <subject> \nTopic: Change the subject of the room")),
- 'link': (self.command_link, _("Usage: /link [option] [number]\nLink: Interact with a link in the conversation. Available options are 'open', 'copy'. Open just opens the link in the browser if it's http://, Copy just copy the link in the clipboard. An optional number can be provided, it indicates which link to interact with.")),
- 'query': (self.command_query, _('Usage: /query <nick> [message]\nQuery: Open a private conversation with <nick>. This nick has to be present in the room you\'re currently in. If you specified a message after the nickname, it will immediately be sent to this user')),
- 'nick': (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room")),
- 'say': (self.command_say, _('Usage: /say <message>\nSay: Just send the message. Useful if you want your message to begin with a "/"')),
- 'whois': (self.command_whois, _('Usage: /whois <nickname>\nWhois: Request many informations about the user.')),
- 'theme': (self.command_theme, _('Usage: /theme\nTheme: Reload the theme defined in the config file.')),
- '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.')),
- }
-
- self.key_func = {
- "KEY_PPAGE": self.scroll_page_up,
- "KEY_NPAGE": self.scroll_page_down,
- "KEY_F(5)": self.rotate_rooms_left,
- "^P": self.rotate_rooms_left,
- "KEY_F(6)": self.rotate_rooms_right,
- "KEY_F(7)": self.shrink_information_win,
- "KEY_F(8)": self.grow_information_win,
- "^N": self.rotate_rooms_right,
- "KEY_RESIZE": self.call_for_resize,
- 'M-e': self.go_to_important_room,
- 'M-r': self.go_to_roster,
- 'M-z': self.go_to_previous_tab,
- 'M-v': self.move_separator,
- }
-
- # Add handlers
- self.xmpp.add_event_handler("session_start", self.on_connected)
- self.xmpp.add_event_handler("groupchat_presence", self.on_groupchat_presence)
- self.xmpp.add_event_handler("groupchat_message", self.on_groupchat_message)
- self.xmpp.add_event_handler("message", self.on_message)
- self.xmpp.add_event_handler("got_online" , self.on_got_online)
- self.xmpp.add_event_handler("got_offline" , self.on_got_offline)
- self.xmpp.add_event_handler("roster_update", self.on_roster_update)
- self.xmpp.add_event_handler("changed_status", self.on_presence)
-
- # self.__debug_fill_roster()
-
- def grow_information_win(self):
- """
- """
- if self.information_win_size == 14:
- return
- self.information_win_size += 1
- for tab in self.tabs:
- tab.on_info_win_size_changed(self.information_win_size, self.stdscr)
- self.refresh_window()
-
- def shrink_information_win(self):
- """
- """
- if self.information_win_size == 0:
- return
- self.information_win_size -= 1
- for tab in self.tabs:
- tab.on_info_win_size_changed(self.information_win_size, self.stdscr)
- self.refresh_window()
-
- def on_got_offline(self, presence):
- jid = presence['from']
- contact = roster.get_contact_by_jid(jid.bare)
- if not contact:
- return
- resource = contact.get_resource_by_fulljid(jid.full)
- assert resource
- self.information('%s is offline' % (resource.get_jid()), "Roster")
- contact.remove_resource(resource)
- if isinstance(self.current_tab(), RosterInfoTab):
- self.refresh_window()
-
- def on_got_online(self, presence):
- jid = presence['from']
- contact = roster.get_contact_by_jid(jid.bare)
- if not contact:
- # Todo, handle presence comming from contacts not in roster
- return
- resource = contact.get_resource_by_fulljid(jid.full)
- assert not resource
- resource = Resource(jid.full)
- status = presence['type']
- priority = presence.getPriority() or 0
- resource.set_presence(status)
- resource.set_priority(priority)
- contact.add_resource(resource)
- self.information("%s is online (%s)" % (resource.get_jid().full, status), "Roster")
-
- def on_connected(self, event):
- """
- Called when we are connected and authenticated
- """
- self.information(_("Welcome on Poezio \o/!"))
- self.information(_("Your JID is %s") % self.xmpp.boundjid.full)
-
- if not self.xmpp.anon:
- # request the roster
- self.xmpp.getRoster()
- # send initial presence
- self.xmpp.makePresence(pfrom=self.xmpp.boundjid.bare).send()
- rooms = config.get('rooms', '')
- if rooms == '' or not isinstance(rooms, str):
- return
- rooms = rooms.split(':')
- for room in rooms:
- args = room.split('/')
- if args[0] == '':
- return
- roomname = args[0]
- if len(args) == 2:
- nick = args[1]
- else:
- default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
- nick = config.get('default_nick', '')
- if nick == '':
- nick = default
- self.open_new_room(roomname, nick, False)
- muc.join_groupchat(self.xmpp, roomname, nick)
- # if not self.xmpp.anon:
- # Todo: SEND VCARD
- return
- if config.get('jid', '') == '': # Don't send the vcard if we're not anonymous
- self.vcard_sender.start() # because the user ALREADY has one on the server
-
- def on_groupchat_presence(self, presence):
- """
- Triggered whenever a presence stanza is received from a user in a multi-user chat room.
- Display the presence on the room window and update the
- presence information of the concerned user
- """
- from_nick = presence['from'].resource
- from_room = presence['from'].bare
- room = self.get_room_by_name(from_room)
- code = presence.find('{jabber:client}status')
- status_codes = set([s.attrib['code'] for s in presence.findall('{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}status')])
- # Check if it's not an error presence.
- if presence['type'] == 'error':
- return self.room_error(presence, from_room)
- if not room:
- return
- msg = None
- affiliation = presence['muc']['affiliation']
- show = presence['show']
- status = presence['status']
- role = presence['muc']['role']
- jid = presence['muc']['jid']
- typ = presence['type']
- if not room.joined: # user in the room BEFORE us.
- # ignore redondant presence message, see bug #1509
- if from_nick not in [user.nick for user in room.users]:
- new_user = User(from_nick, affiliation, show, status, role)
- room.users.append(new_user)
- if from_nick == room.own_nick:
- room.joined = True
- new_user.color = theme.COLOR_OWN_NICK
- self.add_message_to_text_buffer(room, _("Your nickname is %s") % (from_nick))
- if '170' in status_codes:
- self.add_message_to_text_buffer(room, 'Warning: this room is publicly logged')
- else:
- change_nick = '303' in status_codes
- kick = '307' in status_codes and typ == 'unavailable'
- user = room.get_user_by_name(from_nick)
- # New user
- if not user:
- self.on_user_join(room, from_nick, affiliation, show, status, role, jid)
- # nick change
- elif change_nick:
- self.on_user_nick_change(room, presence, user, from_nick, from_room)
- # kick
- elif kick:
- self.on_user_kicked(room, presence, user, from_nick)
- # user quit
- elif typ == 'unavailable':
- self.on_user_leave_groupchat(room, user, jid, status, from_nick, from_room)
- # status change
- else:
- self.on_user_change_status(room, user, from_nick, from_room, affiliation, role, show, status)
- self.refresh_window()
- self.doupdate()
-
- def on_user_join(self, room, from_nick, affiliation, show, status, role, jid):
- """
- When a new user joins a groupchat
- """
- room.users.append(User(from_nick, affiliation,
- show, status, role))
- hide_exit_join = config.get('hide_exit_join', -1)
- if hide_exit_join != 0:
- if not jid.full:
- self.add_message_to_text_buffer(room, _('%(spec)s "[%(nick)s]" joined the room') % {'nick':from_nick.replace('"', '\\"'), 'spec':theme.CHAR_JOIN.replace('"', '\\"')}, colorized=True)
- else:
- self.add_message_to_text_buffer(room, _('%(spec)s "[%(nick)s]" "(%(jid)s)" joined the room') % {'spec':theme.CHAR_JOIN.replace('"', '\\"'), 'nick':from_nick.replace('"', '\\"'), 'jid':jid.full}, colorized=True)
-
- def on_user_nick_change(self, room, presence, user, from_nick, from_room):
- new_nick = presence.find('{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}item').attrib['nick']
- if user.nick == room.own_nick:
- room.own_nick = new_nick
- # also change our nick in all private discussion of this room
- for _tab in self.tabs:
- if isinstance(_tab, PrivateTab) and _tab.get_name().split('/', 1)[0] == room.name:
- _tab.get_room().own_nick = new_nick
- user.change_nick(new_nick)
- self.add_message_to_text_buffer(room, _('"[%(old)s]" is now known as "[%(new)s]"') % {'old':from_nick.replace('"', '\\"'), 'new':new_nick.replace('"', '\\"')}, colorized=True)
- # rename the private tabs if needed
- private_room = self.get_room_by_name('%s/%s' % (from_room, from_nick))
- if private_room:
- self.add_message_to_text_buffer(private_room, _('"[%(old_nick)s]" is now known as "[%(new_nick)s]"') % {'old_nick':from_nick.replace('"', '\\"'), 'new_nick':new_nick.replace('"', '\\"')}, colorized=True)
- new_jid = private_room.name.split('/', 1)[0]+'/'+new_nick
- private_room.name = new_jid
-
- def on_user_kicked(self, room, presence, user, from_nick):
- """
- When someone is kicked
- """
- room.users.remove(user)
- by = presence.find('{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}item/{http://jabber.org/protocol/muc#user}actor')
- reason = presence.find('{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}item/{http://jabber.org/protocol/muc#user}reason')
- by = by.attrib['jid'] if by is not None else None
- reason = reason.text if reason else ''
- if from_nick == room.own_nick: # we are kicked
- room.disconnect()
- if by:
- kick_msg = _('%(spec)s [You] have been kicked by "[%(by)s]"') % {'spec': theme.CHAR_KICK.replace('"', '\\"'), 'by':by}
- else:
- kick_msg = _('%(spec)s [You] have been kicked.') % {'spec':theme.CHAR_KICK.replace('"', '\\"')}
- # try to auto-rejoin
- if config.get('autorejoin', 'false') == 'true':
- muc.join_groupchat(self.xmpp, room.name, room.own_nick)
- else:
- if by:
- kick_msg = _('%(spec)s "[%(nick)s]" has been kicked by "[%(by)s]"') % {'spec':theme.CHAR_KICK.replace('"', '\\"'), 'nick':from_nick.replace('"', '\\"'), 'by':by.replace('"', '\\"')}
- else:
- kick_msg = _('%(spec)s "[%(nick)s]" has been kicked') % {'spec':theme.CHAR_KICK, 'nick':from_nick.replace('"', '\\"')}
- if reason:
- kick_msg += _(' Reason: %(reason)s') % {'reason': reason}
- self.add_message_to_text_buffer(room, kick_msg, colorized=True)
-
- def on_user_leave_groupchat(self, room, user, jid, status, from_nick, from_room):
- """
- When an user leaves a groupchat
- """
- room.users.remove(user)
- if room.own_nick == user.nick:
- # We are now out of the room. Happens with some buggy (? not sure) servers
- room.disconnect()
- hide_exit_join = config.get('hide_exit_join', -1) if config.get('hide_exit_join', -1) >= -1 else -1
- if hide_exit_join == -1 or user.has_talked_since(hide_exit_join):
- if not jid.full:
- leave_msg = _('%(spec)s "[%(nick)s]" has left the room') % {'nick':from_nick.replace('"', '\\"'), 'spec':theme.CHAR_QUIT.replace('"', '\\"')}
- else:
- leave_msg = _('%(spec)s "[%(nick)s]" "(%(jid)s)" has left the room') % {'spec':theme.CHAR_QUIT.replace('"', '\\"'), 'nick':from_nick.replace('"', '\\"'), 'jid':jid.full.replace('"', '\\"')}
- if status:
- leave_msg += ' (%s)' % status
- self.add_message_to_text_buffer(room, leave_msg, colorized=True)
- private_room = self.get_room_by_name('%s/%s' % (from_room, from_nick))
- if private_room:
- if not status:
- self.add_message_to_text_buffer(private_room, _('%(spec)s "[%(nick)s]" has left the room') % {'nick':from_nick.replace('"', '\\"'), 'spec':theme.CHAR_QUIT.replace('"', '\\"')}, colorized=True)
- else:
- self.add_message_to_text_buffer(private_room, _('%(spec)s "[%(nick)s]" has left the room "(%(status)s)"') % {'nick':from_nick.replace('"', '\\"'), 'spec':theme.CHAR_QUIT, 'status': status.replace('"', '\\"')}, colorized=True)
-
- def on_user_change_status(self, room, user, from_nick, from_room, affiliation, role, show, status):
- """
- When an user changes her status
- """
- # build the message
- display_message = False # flag to know if something significant enough
- # to be displayed has changed
- msg = _('"%s" changed: ')% from_nick.replace('"', '\\"')
- if affiliation != user.affiliation:
- msg += _('affiliation: %s, ') % affiliation
- display_message = True
- if role != user.role:
- msg += _('role: %s, ') % role
- display_message = True
- if show != user.show and show in list(SHOW_NAME.keys()):
- msg += _('show: %s, ') % SHOW_NAME[show]
- display_message = True
- if status and status != user.status:
- msg += _('status: %s, ') % status
- display_message = True
- if not display_message:
- return
- msg = msg[:-2] # remove the last ", "
- hide_status_change = config.get('hide_status_change', -1) if config.get('hide_status_change', -1) >= -1 else -1
- if (hide_status_change == -1 or \
- user.has_talked_since(hide_status_change) or\
- user.nick == room.own_nick)\
- and\
- (affiliation != user.affiliation or\
- role != user.role or\
- show != user.show or\
- status != user.status):
- # display the message in the room
- self.add_message_to_text_buffer(room, msg, colorized=True)
- private_room = self.get_room_by_name('%s/%s' % (from_room, from_nick))
- if private_room: # display the message in private
- self.add_message_to_text_buffer(private_room, msg, colorized=True)
- # finally, effectively change the user status
- user.update(affiliation, show, status, role)
-
- def on_message(self, message):
- """
- When receiving private message from a muc OR a normal message
- (from one of our contacts)
- """
- if message['type'] == 'groupchat':
- return None
- # Differentiate both type of messages, and call the appropriate handler.
- jid_from = message['from']
- for tab in self.tabs:
- if isinstance(tab, MucTab) and tab.get_name() == jid_from.bare: # check all the MUC we are in
- if message['type'] == 'error':
- return self.room_error(message, tab.get_room().name)
- else:
- return self.on_groupchat_private_message(message)
- return self.on_normal_message(message)
-
- def on_groupchat_private_message(self, message):
- """
- We received a Private Message (from someone in a Muc)
- """
- jid = message['from']
- nick_from = jid.resource
- room_from = jid.bare
- room = self.get_room_by_name(jid.full) # get the tab with the private conversation
- if not room: # It's the first message we receive: create the tab
- room = self.open_private_window(room_from, nick_from, False)
- if not room:
- return
- body = message['body']
- self.add_message_to_text_buffer(room, body, None, nick_from)
- self.refresh_window()
- self.doupdate()
-
- def focus_tab_named(self, tab_name):
- for tab in self.tabs:
- if tab.get_name() == tab_name:
- self.command_win('%s' % (tab.nb,))
-
- def on_normal_message(self, message):
- """
- When receiving "normal" messages (from someone in our roster)
- """
- jid = message['from'].bare
- room = self.get_conversation_by_jid(jid)
- body = message['body']
- if not body:
- return
- if not room:
- room = self.open_conversation_window(jid, False)
- if not room:
- return
- self.add_message_to_text_buffer(room, body, None, jid)
- self.refresh_window()
- return
-
- def on_presence(self, presence):
- """
- """
- jid = presence['from']
- contact = roster.get_contact_by_jid(jid.bare)
- if not contact:
- return
- resource = contact.get_resource_by_fulljid(jid.full)
- if not resource:
- return
- status = presence['type']
- priority = presence.getPriority() or 0
- resource.set_presence(status)
- resource.set_priority(priority)
- if isinstance(self.current_tab(), RosterInfoTab):
- self.refresh_window()
-
- def __debug_fill_roster(self):
- for i in range(10):
- jid = 'contact%s@fion%s.org'%(i,i)
- contact = Contact(jid)
- contact.set_ask('wat')
- contact.set_subscription('both')
- roster.add_contact(contact, jid)
- contact.set_name('%s %s fion'%(i,i))
- roster.edit_groups_of_contact(contact, ['hello'])
- for i in range(10):
- jid = 'test%s@bernard%s.org'%(i,i)
- contact = Contact(jid)
- contact.set_ask('wat')
- contact.set_subscription('both')
- roster.add_contact(contact, jid)
- contact.set_name('%s test'%(i))
- roster.edit_groups_of_contact(contact, ['hello'])
- for i in range(10):
- jid = 'pouet@top%s.org'%(i)
- contact = Contact(jid)
- contact.set_ask('wat')
- contact.set_subscription('both')
- roster.add_contact(contact, jid)
- contact.set_name('%s oula'%(i))
- roster.edit_groups_of_contact(contact, ['hello'])
- if isinstance(self.current_tab(), RosterInfoTab):
- self.refresh_window()
-
- def on_roster_update(self, iq):
- """
- A subscription changed, or we received a roster item
- after a roster request, etc
- """
- for item in iq.findall('{jabber:iq:roster}query/{jabber:iq:roster}item'):
- jid = item.attrib['jid']
- contact = roster.get_contact_by_jid(jid)
- if not contact:
- contact = Contact(jid)
- roster.add_contact(contact, jid)
- if 'ask' in item.attrib:
- contact.set_ask(item.attrib['ask'])
- else:
- contact.set_ask(None)
- if 'name' in item.attrib:
- contact.set_name(item.attrib['name'])
- else:
- contact.set_name(None)
- if item.attrib['subscription']:
- contact.set_subscription(item.attrib['subscription'])
- groups = item.findall('{jabber:iq:roster}group')
- roster.edit_groups_of_contact(contact, [group.text for group in groups])
- if isinstance(self.current_tab(), RosterInfoTab):
- self.refresh_window()
-
- def call_for_resize(self):
- """
- Starts a very short timer. If no other terminal resize
- occured in this delay then poezio is REALLY resize.
- This is to avoid multiple unnecessary software resizes (this
- can be heavy on resource on slow computers or networks)
- """
- # with resize_lock:
- # if self.resize_timer:
- # # a recent terminal resize occured.
- # # Cancel the programmed software resize
- # self.resize_timer.cancel()
- # # add the new timer
- # self.resize_timer = threading.Timer(0.15, self.resize_window)
- # self.resize_timer.start()
- self.resize_window()
-
- def resize_window(self):
- """
- Resize the whole screen
- """
- with resize_lock:
- # self.resize_timer = None
- for tab in self.tabs:
- tab.resize(self.stdscr)
- self.refresh_window()
-
- def main_loop(self):
- """
- main loop waiting for the user to press a key
- """
- self.refresh_window()
- while self.running:
- self.doupdate()
- char=read_char(self.stdscr)
- # search for keyboard shortcut
- if char in list(self.key_func.keys()):
- self.key_func[char]()
- else:
- self.do_command(char)
-
- def current_tab(self):
- """
- returns the current room, the one we are viewing
- """
- return self.tabs[0]
-
- def get_conversation_by_jid(self, jid):
- """
- Return the room of the ConversationTab with the given jid
- """
- for tab in self.tabs:
- if isinstance(tab, ConversationTab):
- if tab.get_name() == jid:
- return tab.get_room()
- return None
-
- def get_room_by_name(self, name):
- """
- returns the room that has this name
- """
- for tab in self.tabs:
- if (isinstance(tab, MucTab) or
- isinstance(tab, PrivateTab)) and tab.get_name() == name:
- return tab.get_room()
- return None
-
- def init_curses(self, stdscr):
- """
- ncurses initialization
- """
- curses.curs_set(1)
- curses.noecho()
- # curses.raw()
- theme.init_colors()
- stdscr.keypad(True)
-
- def reset_curses(self):
- """
- Reset terminal capabilities to what they were before ncurses
- init
- """
- curses.echo()
- curses.nocbreak()
- curses.endwin()
-
- def refresh_window(self):
- """
- Refresh everything
- """
- self.current_tab().set_color_state(theme.COLOR_TAB_CURRENT)
- self.current_tab().refresh(self.tabs, self.information_buffer, roster)
- self.doupdate()
-
- def open_new_room(self, room, nick, focus=True):
- """
- Open a new MucTab containing a muc Room, using the specified nick
- """
- r = Room(room, nick)
- new_tab = MucTab(self.stdscr, r, self.information_win_size)
- if self.current_tab().nb == 0:
- self.tabs.append(new_tab)
- else:
- for ta in self.tabs:
- if ta.nb == 0:
- self.tabs.insert(self.tabs.index(ta), new_tab)
- break
- if focus:
- self.command_win("%s" % new_tab.nb)
- self.refresh_window()
-
- def go_to_roster(self):
- self.command_win('0')
-
- def go_to_previous_tab(self):
- self.command_win('%s' % (self.previous_tab_nb,))
-
- def go_to_important_room(self):
- """
- Go to the next room with activity, in this order:
- - A personal conversation with a new message
- - A Muc with an highlight
- - A Muc with any new message
- """
- for tab in self.tabs:
- if tab.get_color_state() == theme.COLOR_TAB_PRIVATE:
- self.command_win('%s' % tab.nb)
- return
- for tab in self.tabs:
- if tab.get_color_state() == theme.COLOR_TAB_HIGHLIGHT:
- self.command_win('%s' % tab.nb)
- return
- for tab in self.tabs:
- if tab.get_color_state() == theme.COLOR_TAB_NEW_MESSAGE:
- self.command_win('%s' % tab.nb)
- return
-
- def rotate_rooms_right(self, args=None):
- """
- rotate the rooms list to the right
- """
- self.current_tab().on_lose_focus()
- self.tabs.append(self.tabs.pop(0))
- self.current_tab().on_gain_focus()
- self.refresh_window()
-
- def rotate_rooms_left(self, args=None):
- """
- rotate the rooms list to the right
- """
- self.current_tab().on_lose_focus()
- self.tabs.insert(0, self.tabs.pop())
- self.current_tab().on_gain_focus()
- self.refresh_window()
-
- def scroll_page_down(self, args=None):
- self.current_tab().on_scroll_down()
- self.refresh_window()
-
- def scroll_page_up(self, args=None):
- self.current_tab().on_scroll_up()
- self.refresh_window()
-
- def room_error(self, error, room_name):
- """
- Display the error on the room window
- """
- room = self.get_room_by_name(room_name)
- msg = error['error']['type']
- condition = error['error']['condition']
- code = error['error']['code']
- body = error['error']['text']
- if not body:
- if code in list(ERROR_AND_STATUS_CODES.keys()):
- body = ERROR_AND_STATUS_CODES[code]
- else:
- body = condition or _('Unknown error')
- if code:
- msg = _('Error: %(code)s - %(msg)s: %(body)s') % {'msg':msg, 'body':body, 'code':code}
- self.add_message_to_text_buffer(room, msg)
- else:
- msg = _('Error: %(msg)s: %(body)s') % {'msg':msg, 'body':body}
- self.add_message_to_text_buffer(room, msg)
- if code == '401':
- msg = _('To provide a password in order to join the room, type "/join / password" (replace "password" by the real password)')
- self.add_message_to_text_buffer(room, msg)
- if code == '409':
- if config.get('alternative_nickname', '') != '':
- self.command_join('%s/%s'% (room.name, room.own_nick+config.get('alternative_nickname', '')))
- else:
- self.add_message_to_text_buffer(room, _('You can join the room with an other nick, by typing "/join /other_nick"'))
- self.refresh_window()
-
- def open_conversation_window(self, room_name, focus=True):
- """
- open a new conversation tab and focus it if needed
- """
- r = Room(room_name, self.xmpp.boundjid.full)
- new_tab = ConversationTab(self.stdscr, r, self.information_win_size)
- # insert it in the rooms
- if self.current_tab().nb == 0:
- self.tabs.append(new_tab)
- else:
- for ta in self.tabs:
- if ta.nb == 0:
- self.tabs.insert(self.tabs.index(ta), new_tab)
- break
- if focus: # focus the room if needed
- self.command_win('%s' % (new_tab.nb))
- # self.window.new_room(r)
- self.refresh_window()
- return r
-
- def open_private_window(self, room_name, user_nick, focus=True):
- complete_jid = room_name+'/'+user_nick
- for tab in self.tabs: # if the room exists, focus it and return
- if isinstance(tab, PrivateTab):
- if tab.get_name() == complete_jid:
- self.command_win('%s' % tab.nb)
- return
- # create the new tab
- room = self.get_room_by_name(room_name)
- if not room:
- return None
- own_nick = room.own_nick
- r = Room(complete_jid, own_nick) # PrivateRoom here
- new_tab = PrivateTab(self.stdscr, r, self.information_win_size)
- # insert it in the tabs
- if self.current_tab().nb == 0:
- self.tabs.append(new_tab)
- else:
- for ta in self.tabs:
- if ta.nb == 0:
- self.tabs.insert(self.tabs.index(ta), new_tab)
- break
- if focus: # focus the room if needed
- self.command_win('%s' % (new_tab.nb))
- # self.window.new_room(r)
- self.refresh_window()
- return r
-
- def on_groupchat_message(self, message):
- """
- Triggered whenever a message is received from a multi-user chat room.
- """
- delay_tag = message.find('{urn:xmpp:delay}delay')
- if delay_tag is not None:
- delayed = True
- date = common.datetime_tuple(delay_tag.attrib['stamp'])
- else:
- # We support the OLD and deprecated XEP: http://xmpp.org/extensions/xep-0091.html
- # But it sucks, please, Jabber servers, don't do this :(
- delay_tag = message.find('{jabber:x:delay}x')
- if delay_tag is not None:
- delayed = True
- date = common.datetime_tuple(delay_tag.attrib['stamp'])
- else:
- delayed = False
- date = None
- nick_from = message['mucnick']
- room_from = message.getMucroom()
- if message['type'] == 'error': # Check if it's an error
- return self.room_error(message, from_room)
- if nick_from == room_from:
- nick_from = None
- room = self.get_room_by_name(room_from)
- if (room_from in self.ignores) and (nick_from in self.ignores[room_from]):
- return
- room = self.get_room_by_name(room_from)
- if not room:
- self.information(_("message received for a non-existing room: %s") % (room_from))
- return
- body = message['body']
- subject = message['subject']
- if subject:
- if nick_from:
- self.add_message_to_text_buffer(room, _("%(nick)s changed the subject to: %(subject)s") % {'nick':nick_from, 'subject':subject}, time=date)
- else:
- self.add_message_to_text_buffer(room, _("The subject is: %(subject)s") % {'subject':subject}, time=date)
- room.topic = subject.replace('\n', '|')
- elif body:
- date = date if delayed == True else None
- self.add_message_to_text_buffer(room, body, date, nick_from)
- self.refresh_window()
- self.doupdate()
-
- def add_message_to_text_buffer(self, room, txt, time=None, nickname=None, colorized=False):
- """
- Add the message to the room if possible, else, add it to the Info window
- (in the Info tab of the info window in the RosterTab)
- """
- if not room:
- self.information('Error, trying to add a message in no room: %s' % txt)
- else:
- room.add_message(txt, time, nickname, colorized)
- self.refresh_window()
-
- def command_help(self, arg):
- """
- /help <command_name>
- """
- args = arg.split()
- if len(args) == 0:
- msg = _('Available commands are: ')
- for command in list(self.commands.keys()):
- msg += "%s " % command
- msg += _("\nType /help <command_name> to know what each command does")
- if len(args) >= 1:
- if args[0] in list(self.commands.keys()):
- msg = self.commands[args[0]][1]
- else:
- msg = _('Unknown command: %s') % args[0]
- self.information(msg)
-
- def command_whois(self, arg):
- """
- /whois <nickname>
- """
- # TODO
- return
- # check shlex here
- try:
- args = shlex.split(arg)
- except ValueError as error:
- return self.information(str(error), _("Error"))
- room = self.current_room()
- if len(args) != 1:
- self.add_message_to_text_buffer(room, _('whois command takes exactly one argument'))
- return
- # check if current room is a MUC
- if room.jid or room.name == 'Info':
- return
- nickname = args[0]
- self.muc.request_vcard(room.name, nickname)
-
- def command_theme(self, arg):
- """
- """
- theme.reload_theme()
- self.resize_window()
-
- def command_recolor(self, arg):
- """
- Re-assign color to the participants of the room
- """
- tab = self.current_tab()
- if not isinstance(tab, MucTab):
- return
- room = tab.get_room()
- i = 0
- compare_users = lambda x: x.last_talked
- users = list(room.users)
- # search our own user, to remove it from the room
- for user in users:
- if user.nick == room.own_nick:
- users.remove(user)
- nb_color = len(theme.LIST_COLOR_NICKNAMES)
- for user in sorted(users, key=compare_users, reverse=True):
- user.color = theme.LIST_COLOR_NICKNAMES[i % nb_color]
- i+= 1
- self.refresh_window()
-
- def command_win(self, arg):
- """
- /win <number>
- """
- args = arg.split()
- if len(args) != 1:
- self.command_help('win')
- return
- try:
- nb = int(args[0])
- except ValueError:
- self.command_help('win')
- return
- if self.current_tab().nb == nb:
- return
- self.previous_tab_nb = self.current_tab().nb
- self.current_tab().on_lose_focus()
- start = self.current_tab()
- self.tabs.append(self.tabs.pop(0))
- while self.current_tab().nb != nb:
- self.tabs.append(self.tabs.pop(0))
- if self.current_tab() == start:
- self.current_tab().set_color_state(theme.COLOR_TAB_CURRENT)
- self.refresh_window()
- return
- self.current_tab().on_gain_focus()
- self.refresh_window()
-
- def command_kick(self, arg):
- """
- /kick <nick> [reason]
- """
- try:
- args = shlex.split(arg)
- except ValueError as error:
- return self.information(str(error), _("Error"))
- if len(args) < 1:
- self.command_help('kick')
- return
- nick = args[0]
- if len(args) >= 2:
- reason = ' '.join(args[1:])
- else:
- reason = ''
- if not isinstance(self.current_tab(), MucTab) or not self.current_tab().get_room().joined:
- return
- roomname = self.current_tab().get_name()
- res = muc.eject_user(self.xmpp, roomname, nick, reason)
- if res['type'] == 'error':
- self.room_error(res, roomname)
-
- def command_join(self, arg):
- """
- /join [room][/nick] [password]
- """
- args = arg.split()
- password = None
- if len(args) == 0:
- t = self.current_tab()
- if not isinstance(t, MucTab) and not isinstance(t, PrivateTab):
- return
- room = t.get_name()
- nick = t.get_room().own_nick
- else:
- info = args[0].split('/')
- if len(info) == 1:
- default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
- nick = config.get('default_nick', '')
- if nick == '':
- nick = default
- else:
- nick = info[1]
- if info[0] == '': # happens with /join /nickname, which is OK
- t = self.current_tab()
- if not isinstance(t, MucTab):
- return
- room = t.get_name()
- if nick == '':
- nick = t.get_room().own_nick
- else:
- room = info[0]
- if not is_jid(room): # no server is provided, like "/join hello"
- # use the server of the current room if available
- # check if the current room's name has a server
- if isinstance(self.current_tab(), MucTab) and\
- is_jid(self.current_tab().get_name()):
- room += '@%s' % jid_get_domain(self.current_tab().get_name())
- else: # no server could be found, print a message and return
- self.information(_("You didn't specify a server for the room you want to join"), 'Error')
- return
- r = self.get_room_by_name(room)
- if len(args) == 2: # a password is provided
- password = args[1]
- if r and r.joined: # if we are already in the room
- self.focus_tab_named(r.name)
- return
- room = room.lower()
- if r and not r.joined:
- muc.join_groupchat(self.xmpp, room, nick, password)
- if not r: # if the room window exists, we don't recreate it.
- self.open_new_room(room, nick)
- muc.join_groupchat(self.xmpp, room, nick, password)
- else:
- r.own_nick = nick
- r.users = []
-
- def command_bookmark(self, arg):
- """
- /bookmark [room][/nick]
- """
- args = arg.split()
- nick = None
- if not isinstance(self.current_tab(), MucTab):
- return
- if len(args) == 0:
- room = self.current_tab().get_room()
- roomname = self.current_tab().get_name()
- if room.joined:
- nick = room.own_nick
- else:
- info = args[0].split('/')
- if len(info) == 2:
- nick = info[1]
- roomname = info[0]
- if roomname == '':
- roomname = self.current_tab().get_name()
- if nick:
- res = roomname+'/'+nick
- else:
- res = roomname
- bookmarked = config.get('rooms', '')
- # check if the room is already bookmarked.
- # if yes, replace it (i.e., update the associated nick)
- bookmarked = bookmarked.split(':')
- for room in bookmarked:
- if room.split('/')[0] == roomname:
- bookmarked.remove(room)
- break
- bookmarked = ':'.join(bookmarked)
- if bookmarked:
- bookmarks = bookmarked+':'+res
- else:
- bookmarks = res
- config.set_and_save('rooms', bookmarks)
- self.information(_('Your bookmarks are now: %s') % bookmarks)
-
- def command_set(self, arg):
- """
- /set <option> [value]
- """
- args = arg.split()
- if len(args) != 2 and len(args) != 1:
- self.command_help('set')
- return
- option = args[0]
- if len(args) == 2:
- value = args[1]
- else:
- value = ''
- config.set_and_save(option, value)
- msg = "%s=%s" % (option, value)
- self.information(msg)
-
- def command_show(self, arg):
- """
- /show <status> [msg]
- """
- args = arg.split()
- possible_show = {'avail':None,
- 'available':None,
- 'ok':None,
- 'here':None,
- 'chat':'chat',
- 'away':'away',
- 'afk':'away',
- 'dnd':'dnd',
- 'busy':'dnd',
- 'xa':'xa'
- }
- if len(args) < 1:
- return
- if not args[0] in list(possible_show.keys()):
- self.command_help('show')
- return
- show = possible_show[args[0]]
- if len(args) > 1:
- msg = ' '.join(args[1:])
- else:
- msg = None
- for tab in self.tabs:
- if isinstance(tab, MucTab) and tab.get_room().joined:
- muc.change_show(self.xmpp, tab.get_room().name, tab.get_room().own_nick, show, msg)
-
- def command_ignore(self, arg):
- """
- /ignore <nick>
- """
- try:
- args = shlex.split(arg)
- except ValueError as error:
- return self.information(str(error), _("Error"))
- if len(args) != 1:
- self.command_help('ignore')
- return
- if not isinstance(self.current_tab(), MucTab):
- return
- roomname = self.current_tab().get_name()
- nick = args[0]
- if roomname not in self.ignores:
- self.ignores[roomname] = set() # no need for any order
- if nick not in self.ignores[roomname]:
- self.ignores[roomname].add(nick)
- self.information(_("%s is now ignored") % nick, 'info')
- else:
- self.information(_("%s is alread ignored") % nick, 'info')
-
- def command_unignore(self, arg):
- """
- /unignore <nick>
- """
- try:
- args = shlex.split(arg)
- except ValueError as error:
- return self.information(str(error), _("Error"))
- if len(args) != 1:
- self.command_help('unignore')
- return
- if not isinstance(self.current_tab(), MucTab):
- return
- roomname = self.current_tab().get_name()
- nick = args[0]
- if roomname not in self.ignores or (nick not in self.ignores[roomname]):
- self.information(_("%s was not ignored") % nick, info)
- return
- self.ignores[roomname].remove(nick)
- if not self.ignores[roomname]:
- del self.ignores[roomname]
- self.information(_("%s is now unignored") % nick, 'info')
-
- def command_away(self, arg):
- """
- /away [msg]
- """
- self.command_show("away "+arg)
-
- def command_busy(self, arg):
- """
- /busy [msg]
- """
- self.command_show("busy "+arg)
-
- def command_avail(self, arg):
- """
- /avail [msg]
- """
- self.command_show("available "+arg)
-
- def command_part(self, arg):
- """
- /part [msg]
- """
- args = arg.split()
- reason = None
- if not isinstance(self.current_tab(), MucTab) and\
- not isinstance(self.current_tab(), PrivateTab):
- return
- room = self.current_tab().get_room()
- if len(args):
- msg = ' '.join(args)
- else:
- msg = None
- if isinstance(self.current_tab(), MucTab) and\
- self.current_tab().get_room().joined:
- muc.leave_groupchat(self.xmpp, room.name, room.own_nick, arg)
- self.tabs.remove(self.current_tab())
- self.refresh_window()
-
- def command_unquery(self, arg):
- """
- /unquery
- """
- tab = self.current_tab()
- if isinstance(tab, PrivateTab):
- self.tabs.remove(tab)
- self.refresh_window()
-
- def command_query(self, arg):
- """
- /query <nick> [message]
- """
- try:
- args = shlex.split(arg)
- except ValueError as error:
- return self.information(str(error), _("Error"))
- if len(args) < 1 or not isinstance(self.current_tab(), MucTab):
- return
- nick = args[0]
- room = self.current_tab().get_room()
- r = None
- for user in room.users:
- if user.nick == nick:
- r = self.open_private_window(room.name, user.nick)
- if r and len(args) > 1:
- msg = arg[len(nick)+1:]
- muc.send_private_message(self.xmpp, r.name, msg)
- self.add_message_to_text_buffer(r, msg, None, r.own_nick)
-
- def command_topic(self, arg):
- """
- /topic [new topic]
- """
- if not isinstance(self.current_tab(), MucTab):
- return
- room = self.current_tab().get_room()
- if not arg.strip():
- self.add_message_to_text_buffer(room, _("The subject of the room is: %s") % room.topic)
- return
- subject = arg
- muc.change_subject(self.xmpp, room.name, subject)
-
- def command_link(self, arg):
- """
- /link <option> <nb>
- Opens the link in a browser, or join the room, or add the JID, or
- copy it in the clipboard
- """
- if not isinstance(self.current_tab(), MucTab) and\
- not isinstance(self.current_tab(), PrivateTab):
- return
- args = arg.split()
- if len(args) > 2:
- # INFO
- # self.add_message_to_text_buffer(self.current_room(),
- # _("Link: This command takes at most 2 arguments"))
- return
- # set the default parameters
- option = "open"
- nb = 0
- # check the provided parameters
- if len(args) >= 1:
- try: # check if the argument is the number
- nb = int(args[0])
- except ValueError: # nope, it's the option
- option = args[0]
- if len(args) == 2:
- try:
- nb = int(args[0])
- except ValueError:
- # INFO
- # self.add_message_to_text_buffer(self.current_room(),
- # _("Link: 2nd parameter should be a number"))
- return
- # find the nb-th link in the current buffer
- i = 0
- link = None
- for msg in self.current_tab().get_room().messages[:-200:-1]:
- if not msg:
- continue
- matches = re.findall('"((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))"', msg.txt)
- for m in matches:
- if i == nb:
- url = m[0]
- self.link_open(url)
- return
-
- def url_open(self, url):
- """
- Use webbrowser to open the provided link
- """
- webbrowser.open(url)
-
- def move_separator(self):
- """
- Move the new-messages separator at the bottom on the current
- text.
- """
- try:
- room = self.current_tab().get_room()
- except:
- return
- room.remove_line_separator()
- room.add_line_separator()
- self.refresh_window()
-
- def command_nick(self, arg):
- """
- /nick <nickname>
- """
- try:
- args = shlex.split(arg)
- except ValueError as error:
- return self.information(str(error), _("Error"))
- if not isinstance(self.current_tab(), MucTab):
- return
- if len(args) != 1:
- return
- nick = args[0]
- room = self.current_tab().get_room()
- if not room.joined or room.name == "Info":
- return
- muc.change_nick(self.xmpp, room.name, nick)
-
- def information(self, msg, typ=''):
- """
- Displays an informational message in the "Info" room window
- """
- self.information_buffer.add_message(msg, nickname=typ)
- self.refresh_window()
-
- def command_quit(self, arg):
- """
- /quit
- """
- if len(arg.strip()) != 0:
- msg = arg
- else:
- msg = None
- for tab in self.tabs:
- if isinstance(tab, MucTab):
- muc.leave_groupchat(self.xmpp, tab.get_room().name, tab.get_room().own_nick, msg)
- self.xmpp.disconnect()
- self.running = False
- self.reset_curses()
-
- def do_command(self, key):
- if not key:
- return
- res = self.current_tab().on_input(key)
- if not res:
- return
- if key in ('^J', '\n') and isinstance(res, str):
- self.execute(res)
- else :
- # we did "enter" with an empty input in the roster
- self.on_roster_enter_key(res)
-
- def on_roster_enter_key(self, roster_row):
- """
- when enter is pressed on the roster window
- """
- if isinstance(roster_row, Contact):
- # roster_row.toggle_folded()
- if not self.get_conversation_by_jid(roster_row.get_bare_jid()):
- self.open_conversation_window(roster_row.get_bare_jid())
- else:
- self.focus_tab_named(roster_row.get_bare_jid())
- if isinstance(roster_row, Resource):
- if not self.get_conversation_by_jid(roster_row.get_jid().full):
- self.open_conversation_window(roster_row.get_jid().full)
- else:
- self.focus_tab_named(roster_row.get_jid().full)
- self.refresh_window()
-
- def execute(self,line):
- """
- Execute the /command or just send the line on the current room
- """
- if line == "":
- return
- if line.startswith('//'):
- self.command_say(line[1:])
- elif line.startswith('/') and not line.startswith('/me '):
- command = line.strip()[:].split()[0][1:]
- arg = line[2+len(command):] # jump the '/' and the ' '
- # example. on "/link 0 open", command = "link" and arg = "0 open"
- if command in list(self.commands.keys()):
- func = self.commands[command][0]
- func(arg)
- return
- else:
- self.information(_("unknown command (%s)") % (command), _('Error'))
- else:
- self.command_say(line)
-
- def command_say(self, line):
- if isinstance(self.current_tab(), PrivateTab):
- muc.send_private_message(self.xmpp, self.current_tab().get_name(), line)
- elif isinstance(self.current_tab(), ConversationTab): # todo, special case
- muc.send_private_message(self.xmpp, self.current_tab().get_name(), line)
- if isinstance(self.current_tab(), PrivateTab) or\
- isinstance(self.current_tab(), ConversationTab):
- self.add_message_to_text_buffer(self.current_tab().get_room(), line, None, self.current_tab().get_room().own_nick)
- elif isinstance(self.current_tab(), MucTab):
- muc.send_groupchat_message(self.xmpp, self.current_tab().get_name(), line)
- self.doupdate()
-
- def doupdate(self):
- self.current_tab().just_before_refresh()
- curses.doupdate()