# Copyright 2010 Le Coz Florent # # 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 . 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 from contact import Contact from message import Message from text_buffer import TextBuffer from keyboard import read_char from common import jid_get_domain, is_jid from common import debug # 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() def doupdate(): curses.doupdate() class Gui(object): """ User interface using ncurses """ def __init__(self, xmpp): 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) 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 \nWin: Go to the specified room.")), 'w': (self.command_win, _("Usage: /w \nW: Go to the specified room.")), 'ignore': (self.command_ignore, _("Usage: /ignore \nIgnore: Ignore a specified nickname.")), 'unignore': (self.command_unignore, _("Usage: /unignore \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 [status]\nShow: Change your availability and (optionaly) your status. The argument is one of \"avail, available, ok, here, chat, away, afk, dnd, busy, xa\" and the optional [message] 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