2010-01-10 20:14:17 +00:00
#!/usr/bin/python
# -*- coding:utf-8 -*-
#
# Copyright 2010 Le Coz Florent <louizatakk@fedoraproject.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/>.
2010-01-31 05:33:54 +00:00
from gettext import ( bindtextdomain , textdomain , bind_textdomain_codeset ,
gettext as _ )
2010-01-10 20:14:17 +00:00
2010-01-31 14:23:14 +00:00
bindtextdomain ( ' poezio ' )
textdomain ( ' poezio ' )
bind_textdomain_codeset ( ' poezio ' , ' utf-8 ' )
2010-01-13 01:04:30 +00:00
import locale
2010-01-31 05:33:54 +00:00
locale . setlocale ( locale . LC_ALL , ' ' )
import sys
import curses
2010-01-21 01:54:50 +00:00
from datetime import datetime
2010-01-31 05:33:54 +00:00
from handler import Handler
2010-01-26 17:10:37 +00:00
from logging import logger
2010-01-26 19:33:40 +00:00
from random import randrange
2010-01-30 02:50:24 +00:00
from config import config
2010-01-21 01:54:50 +00:00
from window import Window
2010-01-12 14:57:58 +00:00
2010-01-21 01:54:50 +00:00
class User ( object ) :
2010-01-12 14:16:13 +00:00
"""
2010-01-21 01:54:50 +00:00
keep trace of an user in a Room
2010-01-12 14:16:13 +00:00
"""
2010-01-21 01:54:50 +00:00
def __init__ ( self , nick , affiliation , show , status , role ) :
self . update ( affiliation , show , status , role )
self . change_nick ( nick )
2010-01-26 19:33:40 +00:00
self . color = randrange ( 2 , 10 )
2010-01-13 01:04:30 +00:00
2010-01-21 01:54:50 +00:00
def update ( self , affiliation , show , status , role ) :
2010-02-10 16:47:43 +00:00
self . affiliation = affiliation
self . show = show
2010-01-21 01:54:50 +00:00
self . status = status
self . role = role
2010-01-13 01:04:30 +00:00
2010-01-21 01:54:50 +00:00
def change_nick ( self , nick ) :
2010-01-21 04:41:54 +00:00
self . nick = nick . encode ( ' utf-8 ' )
2010-01-13 01:04:30 +00:00
2010-01-21 01:54:50 +00:00
class Room ( object ) :
2010-01-11 13:28:57 +00:00
"""
"""
2010-02-11 04:59:58 +00:00
def __init__ ( self , name , nick , number ) :
2010-01-11 13:28:57 +00:00
self . name = name
2010-01-21 01:54:50 +00:00
self . own_nick = nick
2010-02-11 04:59:58 +00:00
self . color_state = 11 # color used in RoomInfo
self . nb = number # number used in RoomInfo
2010-01-21 01:54:50 +00:00
self . joined = False # false until self presence is received
self . users = [ ]
self . lines = [ ] # (time, nick, msg) or (time, info)
self . topic = ' '
2010-01-12 14:16:13 +00:00
2010-01-30 04:02:23 +00:00
def disconnect ( self ) :
self . joined = False
self . users = [ ]
2010-01-21 01:54:50 +00:00
def add_message ( self , nick , msg ) :
2010-02-12 03:30:40 +00:00
color = None
2010-02-11 04:59:58 +00:00
self . set_color_state ( 12 )
2010-02-12 03:30:40 +00:00
if nick != self . own_nick :
if self . own_nick in msg :
self . set_color_state ( 13 )
color = 3
else :
highlight_words = config . get ( ' highlight_on ' , ' ' ) . split ( ' : ' )
for word in highlight_words :
if word . lower ( ) in msg . lower ( ) and word != ' ' :
self . set_color_state ( 13 )
color = 3
2010-01-26 19:33:40 +00:00
if not msg :
logger . info ( ' msg is None..., %s ' % ( nick ) )
return
2010-02-10 16:47:43 +00:00
self . lines . append ( ( datetime . now ( ) , nick . encode ( ' utf-8 ' ) ,
2010-02-12 03:30:40 +00:00
msg . encode ( ' utf-8 ' ) , color ) )
return color
2010-01-12 14:16:13 +00:00
2010-01-21 01:54:50 +00:00
def add_info ( self , info ) :
""" info, like join/quit/status messages """
2010-01-31 14:23:14 +00:00
try :
self . lines . append ( ( datetime . now ( ) , info . encode ( ' utf-8 ' ) ) )
return info . encode ( ' utf-8 ' )
2010-02-10 16:47:43 +00:00
except :
2010-01-31 14:23:14 +00:00
self . lines . append ( ( datetime . now ( ) , info ) )
2010-01-31 19:01:18 +00:00
return info
2010-01-11 13:28:57 +00:00
2010-01-30 04:02:23 +00:00
def get_user_by_name ( self , nick ) :
for user in self . users :
2010-01-31 04:08:47 +00:00
if user . nick == nick . encode ( ' utf-8 ' ) :
2010-01-30 04:02:23 +00:00
return user
return None
2010-02-11 04:59:58 +00:00
def set_color_state ( self , color ) :
2010-02-12 03:30:40 +00:00
if self . color_state < color or color == 11 :
self . color_state = color
2010-02-11 04:59:58 +00:00
2010-01-21 01:54:50 +00:00
def on_presence ( self , stanza , nick ) :
2010-01-11 13:28:57 +00:00
"""
"""
2010-01-21 01:54:50 +00:00
affiliation = stanza . getAffiliation ( )
show = stanza . getShow ( )
status = stanza . getStatus ( )
role = stanza . getRole ( )
2010-01-30 04:02:23 +00:00
if not self . joined : # user in the room BEFORE us.
2010-02-10 16:47:43 +00:00
self . users . append ( User ( nick , affiliation , show , status , role ) )
if nick . encode ( ' utf-8 ' ) == self . own_nick :
self . joined = True
return self . add_info ( _ ( " Your nickname is %s " ) % ( nick ) )
return self . add_info ( _ ( " %s is in the room " ) % ( nick . encode - ( ' utf-8 ' ) ) )
2010-01-21 01:54:50 +00:00
change_nick = stanza . getStatusCode ( ) == ' 303 '
2010-01-28 00:55:02 +00:00
kick = stanza . getStatusCode ( ) == ' 307 '
2010-01-30 04:02:23 +00:00
user = self . get_user_by_name ( nick )
# New user
if not user :
self . users . append ( User ( nick , affiliation , show , status , role ) )
2010-02-13 01:08:44 +00:00
if not config . get ( ' hide_enter_join ' , " false " ) == " true " :
return self . add_info ( _ ( ' %(nick)s joined the room %(roomname)s ' ) % { ' nick ' : nick , ' roomname ' : self . name } )
return None
2010-01-30 04:02:23 +00:00
# nick change
if change_nick :
if user . nick == self . own_nick :
self . own_nick = stanza . getNick ( ) . encode ( ' utf-8 ' )
user . change_nick ( stanza . getNick ( ) )
2010-01-31 05:33:54 +00:00
return self . add_info ( _ ( ' %(old_nick)s is now known as %(new_nick)s ' ) % { ' old_nick ' : nick , ' new_nick ' : stanza . getNick ( ) } )
2010-01-30 04:02:23 +00:00
# kick
if kick :
self . users . remove ( user )
reason = stanza . getReason ( ) . encode ( ' utf-8 ' ) or ' '
try :
by = stanza . getActor ( ) . encode ( ' utf-8 ' )
except :
by = None
if nick == self . own_nick :
self . disconnect ( )
if by :
2010-01-31 05:33:54 +00:00
return self . add_info ( _ ( ' You have been kicked by %(by)s . Reason: %(reason)s ' ) % { ' by ' : by , ' reason ' : reason } )
2010-01-30 04:02:23 +00:00
else :
2010-01-31 05:33:54 +00:00
return self . add_info ( _ ( ' You have been kicked. Reason: %s ' ) % ( reason ) )
2010-01-30 04:02:23 +00:00
else :
if by :
2010-01-31 05:33:54 +00:00
return self . add_info ( _ ( ' %(nick)s has been kicked by %(by)s . Reason: %(reason)s ' ) % { ' nick ' : nick , ' by ' : by , ' reason ' : reason } )
2010-01-30 04:02:23 +00:00
else :
2010-01-31 05:33:54 +00:00
return self . add_info ( _ ( ' %(nick)s has been kicked. Reason: %(reason)s ' ) % { ' nick ' : nick , ' reason ' : reason } )
2010-01-30 04:02:23 +00:00
# user quit
if status == ' offline ' or role == ' none ' :
self . users . remove ( user )
2010-02-13 01:08:44 +00:00
if not config . get ( ' hide_enter_join ' , " false " ) == " true " :
return self . add_info ( _ ( ' %s has left the room ' ) % ( nick ) )
return None
2010-01-30 04:02:23 +00:00
# status change
user . update ( affiliation , show , status , role )
2010-02-13 01:08:44 +00:00
if not config . get ( ' hide_status_change ' , " false " ) == " true " :
return self . add_info ( _ ( ' %(nick)s changed his/her status : %(a)s , %(b)s , %(c)s , %(d)s ' ) % { ' nick ' : nick , ' a ' : affiliation , ' b ' : role , ' c ' : show , ' d ' : status } )
return None
2010-01-30 04:02:23 +00:00
2010-01-11 13:28:57 +00:00
2010-01-10 20:14:17 +00:00
class Gui ( object ) :
"""
Graphical user interface using ncurses
"""
2010-01-21 01:54:50 +00:00
def __init__ ( self , stdscr = None , muc = None ) :
2010-02-11 04:59:58 +00:00
self . room_number = 0
2010-01-21 01:54:50 +00:00
self . init_curses ( stdscr )
self . stdscr = stdscr
2010-02-11 04:59:58 +00:00
self . rooms = [ Room ( ' Info ' , ' ' , self . next_room_number ( ) ) ] # current_room is self.rooms[0]
2010-01-21 01:54:50 +00:00
self . window = Window ( stdscr )
2010-02-11 04:59:58 +00:00
self . window . new_room ( self . current_room ( ) )
self . window . refresh ( self . rooms )
2010-01-21 01:54:50 +00:00
self . muc = muc
2010-01-10 20:14:17 +00:00
2010-01-13 01:04:30 +00:00
self . commands = {
2010-01-31 05:33:54 +00:00
' help ' : ( self . command_help , _ ( ' OLOL, this is SOOO recursive ' ) ) ,
' join ' : ( self . command_join , _ ( ' Usage: /join [room_name][/nick] \n Join: 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). Examples: \n /join room@server.tld \n /join room@server.tld/John \n /join /me_again \n /join ' ) ) ,
' quit ' : ( self . command_quit , _ ( ' Usage: /quit \n Quit: Just disconnect from the server and exit poezio. ' ) ) ,
' exit ' : ( self . command_quit , _ ( ' Usage: /exit \n Exit: Just disconnect from the server and exit poezio. ' ) ) ,
2010-02-11 13:08:42 +00:00
' next ' : ( self . rotate_rooms_right , _ ( ' Usage: /next \n Next: Go to the next room. ' ) ) ,
2010-02-13 00:12:11 +00:00
' n ' : ( self . rotate_rooms_right , _ ( ' Usage: /n \n N: Go to the next room. ' ) ) ,
2010-02-11 13:08:42 +00:00
' prev ' : ( self . rotate_rooms_left , _ ( ' Usage: /prev \n Prev: Go to the previous room. ' ) ) ,
2010-02-13 00:12:11 +00:00
' p ' : ( self . rotate_rooms_left , _ ( ' Usage: /p \n P: Go to the previous room. ' ) ) ,
2010-02-12 02:50:07 +00:00
' win ' : ( self . command_win , _ ( ' Usage: /win <number> \n Win: Go to the specified room. ' ) ) ,
' w ' : ( self . command_win , _ ( ' Usage: /w <number> \n W: Go to the specified room. ' ) ) ,
2010-01-31 05:33:54 +00:00
' part ' : ( self . command_part , _ ( ' Usage: /part [message] \n Part: disconnect from a room. You can specify an optional message. ' ) ) ,
2010-01-31 14:23:14 +00:00
' show ' : ( self . command_show , _ ( u ' Usage: /show <availability> [status] \n Show: 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 [message] argument will be your status message ' ) ) ,
2010-01-31 05:33:54 +00:00
' away ' : ( self . command_away , _ ( ' Usage: /away [message] \n Away: 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] \n Busy: 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] \n Avail: Sets your availability to available and (optional) sets your status message. This is equivalent to " /show available [message] " ' ) ) ,
2010-02-16 13:37:08 +00:00
' available ' : ( self . command_avail , _ ( ' Usage: /available [message] \n Available: 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] \n Bookmark: 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) ' ) ) ,
2010-02-12 19:35:18 +00:00
' set ' : ( self . command_set , _ ( ' Usage: /set <option> [value] \n Set: 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>. ' ) ) ,
2010-02-02 23:57:32 +00:00
' kick ' : ( self . command_kick , _ ( ' Usage: /kick <nick> [reason] \n Kick: Kick the user with the specified nickname. You also can give an optional reason. ' ) ) ,
2010-01-31 05:33:54 +00:00
' nick ' : ( self . command_nick , _ ( ' Usage: /nick <nickname> \n Nick: Change your nickname in the current room ' ) )
2010-01-13 01:04:30 +00:00
}
2010-01-27 19:46:08 +00:00
self . key_func = {
" KEY_LEFT " : self . window . input . key_left ,
" KEY_RIGHT " : self . window . input . key_right ,
" KEY_UP " : self . window . input . key_up ,
" KEY_END " : self . window . input . key_end ,
" KEY_HOME " : self . window . input . key_home ,
" KEY_DOWN " : self . window . input . key_down ,
2010-01-27 22:29:28 +00:00
" KEY_DC " : self . window . input . key_dc ,
2010-01-28 00:55:02 +00:00
" KEY_F(5) " : self . rotate_rooms_left ,
" KEY_F(6) " : self . rotate_rooms_right ,
" kLFT5 " : self . rotate_rooms_left ,
" kRIT5 " : self . rotate_rooms_right ,
2010-02-12 02:32:50 +00:00
" \t " : self . auto_completion ,
2010-01-27 19:46:08 +00:00
" KEY_BACKSPACE " : self . window . input . key_backspace
}
2010-01-21 01:54:50 +00:00
self . handler = Handler ( )
self . handler . connect ( ' on-connected ' , self . on_connected )
self . handler . connect ( ' join-room ' , self . join_room )
self . handler . connect ( ' room-presence ' , self . room_presence )
self . handler . connect ( ' room-message ' , self . room_message )
2010-01-27 19:46:08 +00:00
def main_loop ( self , stdscr ) :
while 1 :
2010-02-17 03:47:54 +00:00
stdscr . leaveok ( 1 )
2010-01-27 19:46:08 +00:00
curses . doupdate ( )
2010-01-31 01:22:39 +00:00
try :
key = stdscr . getkey ( )
except :
self . window . resize ( stdscr )
2010-02-11 04:59:58 +00:00
self . window . refresh ( self . rooms )
2010-02-02 19:13:14 +00:00
continue
2010-01-27 21:44:48 +00:00
if str ( key ) in self . key_func . keys ( ) :
2010-01-27 19:46:08 +00:00
self . key_func [ key ] ( )
2010-01-31 01:22:39 +00:00
elif str ( key ) == ' KEY_RESIZE ' :
self . window . resize ( stdscr )
2010-02-11 04:59:58 +00:00
self . window . refresh ( self . rooms )
2010-01-27 21:44:48 +00:00
elif len ( key ) > = 4 :
continue
2010-01-27 19:46:08 +00:00
elif ord ( key ) == 10 :
self . execute ( )
2010-01-27 22:32:20 +00:00
elif ord ( key ) == 8 or ord ( key ) == 127 :
2010-01-27 22:29:28 +00:00
self . window . input . key_backspace ( )
2010-01-27 23:02:12 +00:00
elif ord ( key ) < 32 :
continue
2010-01-27 19:46:08 +00:00
else :
2010-01-28 00:55:02 +00:00
if ord ( key ) == 27 and ord ( stdscr . getkey ( ) ) == 91 :
last = ord ( stdscr . getkey ( ) ) # FIXME: ugly ugly workaroung.
if last == 51 :
self . window . input . key_dc ( )
continue
2010-01-27 22:37:40 +00:00
elif ord ( key ) > 190 and ord ( key ) < 225 :
2010-01-27 19:46:08 +00:00
key = key + stdscr . getkey ( )
elif ord ( key ) == 226 :
key = key + stdscr . getkey ( )
key = key + stdscr . getkey ( )
self . window . do_command ( key )
2010-02-11 04:59:58 +00:00
def next_room_number ( self ) :
nb = self . room_number
self . room_number + = 1
return nb
2010-01-26 17:10:37 +00:00
def current_room ( self ) :
2010-02-10 16:47:43 +00:00
return self . rooms [ 0 ]
2010-01-26 17:10:37 +00:00
def get_room_by_name ( self , name ) :
for room in self . rooms :
if room . name == name :
return room
return None
2010-01-21 01:54:50 +00:00
def init_curses ( self , stdscr ) :
curses . start_color ( )
curses . noecho ( )
2010-02-14 04:18:34 +00:00
curses . cbreak ( )
curses . raw ( )
curses . use_default_colors ( )
2010-01-27 19:46:08 +00:00
stdscr . keypad ( True )
2010-01-21 01:54:50 +00:00
curses . init_pair ( 1 , curses . COLOR_WHITE , curses . COLOR_BLUE )
2010-02-14 04:18:34 +00:00
curses . init_pair ( 2 , curses . COLOR_BLUE , - 1 )
curses . init_pair ( 3 , curses . COLOR_RED , - 1 ) # Admin
curses . init_pair ( 4 , curses . COLOR_BLUE , - 1 ) # Participant
curses . init_pair ( 5 , curses . COLOR_WHITE , - 1 ) # Visitor
curses . init_pair ( 6 , curses . COLOR_CYAN , - 1 )
curses . init_pair ( 7 , curses . COLOR_GREEN , - 1 )
curses . init_pair ( 8 , curses . COLOR_MAGENTA , - 1 )
curses . init_pair ( 9 , curses . COLOR_YELLOW , - 1 )
2010-02-12 03:30:40 +00:00
curses . init_pair ( 10 , curses . COLOR_WHITE , curses . COLOR_CYAN ) # current room
2010-02-11 04:59:58 +00:00
curses . init_pair ( 11 , curses . COLOR_WHITE , curses . COLOR_BLUE ) # normal room
2010-02-12 03:30:40 +00:00
curses . init_pair ( 12 , curses . COLOR_WHITE , curses . COLOR_MAGENTA ) # new message room
2010-02-11 04:59:58 +00:00
curses . init_pair ( 13 , curses . COLOR_WHITE , curses . COLOR_RED ) # highlight room
2010-02-12 22:32:58 +00:00
curses . init_pair ( 14 , curses . COLOR_WHITE , curses . COLOR_YELLOW )
curses . init_pair ( 15 , curses . COLOR_WHITE , curses . COLOR_GREEN )
2010-01-21 01:54:50 +00:00
2010-01-26 17:10:37 +00:00
def reset_curses ( self ) :
curses . echo ( )
2010-02-14 04:18:34 +00:00
curses . nocbreak ( )
2010-01-27 17:02:13 +00:00
curses . endwin ( )
2010-01-26 17:10:37 +00:00
2010-01-29 16:24:44 +00:00
def on_connected ( self , jid ) :
2010-01-31 05:33:54 +00:00
self . information ( _ ( " Welcome on Poezio \ o/! " ) )
self . information ( _ ( " Your JID is %s " ) % jid )
2010-01-21 01:54:50 +00:00
def join_room ( self , room , nick ) :
2010-02-11 04:59:58 +00:00
r = Room ( room , nick , self . next_room_number ( ) )
self . current_room ( ) . set_color_state ( 11 )
if self . current_room ( ) . nb == 0 :
self . rooms . append ( r )
else :
for ro in self . rooms :
if ro . nb == 0 :
self . rooms . insert ( self . rooms . index ( ro ) , r )
break
while self . current_room ( ) . nb != r . nb :
self . rooms . insert ( 0 , self . rooms . pop ( ) )
self . window . new_room ( r )
self . window . refresh ( self . rooms )
2010-01-21 01:54:50 +00:00
2010-02-12 02:32:50 +00:00
def auto_completion ( self ) :
self . window . input . auto_completion ( self . current_room ( ) . users )
2010-02-11 04:59:58 +00:00
def rotate_rooms_right ( self , args = None ) :
self . current_room ( ) . set_color_state ( 11 )
2010-01-21 01:54:50 +00:00
self . rooms . append ( self . rooms . pop ( 0 ) )
2010-02-11 04:59:58 +00:00
self . window . refresh ( self . rooms )
2010-01-21 01:54:50 +00:00
2010-02-11 04:59:58 +00:00
def rotate_rooms_left ( self , args = None ) :
self . current_room ( ) . set_color_state ( 11 )
2010-01-21 01:54:50 +00:00
self . rooms . insert ( 0 , self . rooms . pop ( ) )
2010-02-11 04:59:58 +00:00
self . window . refresh ( self . rooms )
2010-01-21 01:54:50 +00:00
def room_message ( self , stanza ) :
2010-01-29 16:24:44 +00:00
if len ( sys . argv ) > 1 :
2010-02-15 00:13:23 +00:00
self . information ( str ( stanza ) . encode ( ' utf-8 ' ) )
2010-01-21 01:54:50 +00:00
if stanza . getType ( ) != ' groupchat ' :
return # ignore all messages not comming from a MUC
room_from = stanza . getFrom ( ) . getStripped ( )
nick_from = stanza . getFrom ( ) . getResource ( )
2010-01-26 19:33:40 +00:00
if not nick_from :
nick_from = ' '
room = self . get_room_by_name ( room_from )
2010-01-26 17:10:37 +00:00
if not room :
2010-02-10 16:47:43 +00:00
self . information ( _ ( " message received for a non-existing room: %s " ) % ( room_from ) )
2010-01-28 00:55:02 +00:00
return
2010-01-26 19:33:40 +00:00
body = stanza . getBody ( )
2010-02-14 04:30:04 +00:00
subject = stanza . getSubject ( )
if subject :
2010-02-14 04:41:14 +00:00
if nick_from :
info = room . add_info ( _ ( " %(nick)s changed the subject to: %(subject)s " ) % { ' nick ' : nick_from , ' subject ' : subject } )
else :
info = room . add_info ( _ ( " The subject is: %(subject)s " ) % { ' subject ' : subject } )
2010-02-12 19:16:02 +00:00
self . window . text_win . add_line ( room , ( datetime . now ( ) , info ) )
2010-02-14 04:30:04 +00:00
room . topic = subject . encode ( ' utf-8 ' ) . replace ( ' \n ' , ' | ' )
2010-01-28 00:55:02 +00:00
if room == self . current_room ( ) :
self . window . topic_win . refresh ( room . topic )
2010-01-31 19:45:03 +00:00
self . window . text_win . refresh ( room . name )
2010-01-26 19:33:40 +00:00
else :
2010-02-14 13:33:33 +00:00
if body . startswith ( ' /me ' ) :
info = room . add_info ( nick_from + ' ' + body [ 4 : ] )
self . window . text_win . add_line ( room , ( datetime . now ( ) , info ) )
else :
color = room . add_message ( nick_from , body )
self . window . text_win . add_line ( room , ( datetime . now ( ) , nick_from . encode ( ' utf-8 ' ) , body . encode ( ' utf-8 ' ) , color ) )
2010-02-15 00:13:23 +00:00
if room . name == self . current_room ( ) . name :
2010-01-27 17:02:13 +00:00
self . window . text_win . refresh ( room . name )
2010-01-26 17:10:37 +00:00
self . window . input . refresh ( )
2010-02-11 04:59:58 +00:00
else :
self . window . info_win . refresh ( self . rooms , self . current_room ( ) )
2010-01-28 00:55:02 +00:00
curses . doupdate ( )
2010-01-21 01:54:50 +00:00
def room_presence ( self , stanza ) :
2010-01-28 00:55:02 +00:00
if len ( sys . argv ) > 1 :
self . information ( str ( stanza ) )
2010-01-21 01:54:50 +00:00
from_nick = stanza . getFrom ( ) . getResource ( )
from_room = stanza . getFrom ( ) . getStripped ( )
2010-01-26 19:33:40 +00:00
room = self . get_room_by_name ( from_room )
2010-01-26 17:10:37 +00:00
if not room :
2010-02-10 16:47:43 +00:00
self . information ( _ ( " presence received for a non-existing room: %s " ) % ( from_room ) )
2010-01-31 00:25:17 +00:00
if stanza . getType ( ) == ' error ' :
2010-01-31 05:33:54 +00:00
msg = _ ( " Error: %s " ) % stanza . getError ( )
2010-01-31 00:25:17 +00:00
else :
msg = room . on_presence ( stanza , from_nick )
2010-02-13 01:08:44 +00:00
if room == self . current_room ( ) :
self . window . user_win . refresh ( room . users )
if room == self . current_room ( ) and msg :
2010-02-12 19:16:02 +00:00
self . window . text_win . add_line ( room , ( datetime . now ( ) , msg ) )
2010-01-27 19:46:08 +00:00
self . window . text_win . refresh ( room . name )
2010-02-15 00:13:23 +00:00
self . window . input . refresh ( )
2010-02-13 01:08:44 +00:00
curses . doupdate ( )
2010-01-13 01:04:30 +00:00
def execute ( self ) :
2010-01-21 01:54:50 +00:00
line = self . window . input . get_text ( )
self . window . input . clear_text ( )
2010-01-30 03:06:38 +00:00
self . window . input . refresh ( )
2010-01-21 01:54:50 +00:00
if line == " " :
return
2010-01-28 17:14:37 +00:00
if line . startswith ( ' / ' ) :
2010-01-13 01:04:30 +00:00
command = line . strip ( ) [ : ] . split ( ) [ 0 ] [ 1 : ]
args = line . strip ( ) [ : ] . split ( ) [ 1 : ]
if command in self . commands . keys ( ) :
2010-01-30 04:42:29 +00:00
func = self . commands [ command ] [ 0 ]
2010-01-13 01:04:30 +00:00
func ( args )
2010-01-27 22:29:28 +00:00
return
2010-02-16 02:03:23 +00:00
else :
info = self . current_room ( ) . add_info ( _ ( " Error: unknown command ( %s ) " ) % ( command ) )
self . window . text_win . add_line ( self . current_room ( ) , ( datetime . now ( ) , info ) )
self . window . text_win . refresh ( self . current_room ( ) . name )
elif self . current_room ( ) . name != ' Info ' :
2010-01-26 17:10:37 +00:00
self . muc . send_message ( self . current_room ( ) . name , line )
2010-02-17 03:47:54 +00:00
curses . doupdate ( )
2010-01-26 17:10:37 +00:00
self . window . input . refresh ( )
2010-01-13 01:04:30 +00:00
2010-01-30 04:42:29 +00:00
def command_help ( self , args ) :
room = self . current_room ( )
if len ( args ) == 0 :
2010-01-31 05:33:54 +00:00
msg = _ ( ' Available commands are: ' )
2010-01-30 04:42:29 +00:00
for command in self . commands . keys ( ) :
msg + = " %s " % command
2010-01-31 05:33:54 +00:00
msg + = _ ( " \n Type /help <command_name> to know what each command does " )
2010-01-30 04:42:29 +00:00
if len ( args ) == 1 :
if args [ 0 ] in self . commands . keys ( ) :
msg = self . commands [ args [ 0 ] ] [ 1 ]
else :
2010-01-31 05:33:54 +00:00
msg = _ ( ' Unknown command: %s ' ) % args [ 0 ]
2010-01-31 19:07:22 +00:00
room . add_info ( msg )
2010-02-12 19:27:56 +00:00
self . window . text_win . add_line ( room , ( datetime . now ( ) , msg ) )
2010-01-30 04:42:29 +00:00
self . window . text_win . refresh ( room . name )
self . window . input . refresh ( )
2010-02-12 02:50:07 +00:00
def command_win ( self , args ) :
if len ( args ) != 1 :
self . command_help ( [ ' win ' ] )
return
try :
nb = int ( args [ 0 ] )
except ValueError :
self . command_help ( [ ' win ' ] )
return
if self . current_room ( ) . nb == nb :
return
self . current_room ( ) . set_color_state ( 11 )
start = self . current_room ( )
self . rooms . append ( self . rooms . pop ( 0 ) )
while self . current_room ( ) . nb != nb :
self . rooms . append ( self . rooms . pop ( 0 ) )
if self . current_room ( ) == start :
self . window . refresh ( self . rooms )
return
self . window . refresh ( self . rooms )
2010-02-02 23:57:32 +00:00
def command_kick ( self , args ) :
if len ( args ) < 1 :
self . command_help ( [ ' kick ' ] )
return
nick = args [ 0 ]
if len ( args ) > = 2 :
reason = ' ' . join ( args [ 1 : ] )
else :
reason = ' '
if self . current_room ( ) . name == ' Info ' or not self . current_room ( ) . joined :
return
roomname = self . current_room ( ) . name
self . muc . eject_user ( roomname , ' kick ' , nick , reason )
2010-01-13 01:04:30 +00:00
def command_join ( self , args ) :
2010-01-30 04:02:23 +00:00
if len ( args ) == 0 :
r = self . current_room ( )
if r . name == ' Info ' :
return
room = r . name
nick = r . own_nick
2010-01-30 02:50:24 +00:00
else :
2010-01-30 04:02:23 +00:00
info = args [ 0 ] . split ( ' / ' )
if len ( info ) == 1 :
nick = config . get ( ' default_nick ' , ' Poezio ' )
else :
nick = info [ 1 ]
2010-01-31 03:07:30 +00:00
if info [ 0 ] == ' ' : # happens with /join /nickname, which is OK
2010-01-30 04:02:23 +00:00
r = self . current_room ( )
if r . name == ' Info ' :
return
room = r . name
else :
room = info [ 0 ]
r = self . get_room_by_name ( room )
2010-01-30 02:50:24 +00:00
if r and r . joined : # if we are already in the room
2010-01-31 05:33:54 +00:00
self . information ( _ ( " already in room [ %s ] " ) % room )
2010-01-28 00:55:02 +00:00
return
2010-01-30 02:50:24 +00:00
self . muc . join_room ( room , nick )
2010-01-30 04:02:23 +00:00
if not r : # if the room window exists, we don't recreate it.
2010-01-30 02:50:24 +00:00
self . join_room ( room , nick )
2010-01-13 01:04:30 +00:00
2010-01-31 03:42:25 +00:00
def command_bookmark ( self , args ) :
nick = None
if len ( args ) == 0 :
room = self . current_room ( )
if room . name == ' Info ' :
return
roomname = room . name
if room . joined :
nick = room . own_nick
else :
info = args [ 0 ] . split ( ' / ' )
if len ( info ) == 2 :
nick = info [ 1 ]
roomname = info [ 0 ]
2010-02-14 04:10:13 +00:00
if roomname == ' ' :
roomname = self . current_room ( ) . name
2010-01-31 03:42:25 +00:00
if nick :
res = roomname + ' / ' + nick
else :
res = roomname
2010-02-14 04:10:13 +00:00
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 )
2010-02-10 16:47:43 +00:00
config . set_and_save ( ' rooms ' , bookmarked + ' : ' + res )
2010-01-31 03:42:25 +00:00
2010-02-02 23:35:01 +00:00
def command_set ( self , args ) :
2010-02-12 19:35:18 +00:00
if len ( args ) != 2 and len ( args ) != 1 :
2010-02-02 23:35:01 +00:00
self . command_help ( [ ' set ' ] )
return
option = args [ 0 ]
2010-02-12 19:35:18 +00:00
if len ( args ) == 2 :
value = args [ 1 ]
else :
value = ' '
2010-02-10 16:47:43 +00:00
config . set_and_save ( option , value )
2010-02-02 23:35:01 +00:00
msg = " %s = %s " % ( option , value )
room = self . current_room ( )
room . add_info ( msg )
2010-02-12 19:16:02 +00:00
self . window . text_win . add_line ( room , ( datetime . now ( ) , msg ) )
2010-02-02 23:35:01 +00:00
self . window . text_win . refresh ( room . name )
self . window . input . refresh ( )
2010-01-31 00:25:17 +00:00
def command_show ( self , args ) :
2010-01-31 03:07:30 +00:00
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 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 room in self . rooms :
if room . joined :
self . muc . change_show ( room . name , room . own_nick , show , msg )
def command_away ( self , args ) :
args . insert ( 0 , ' away ' )
self . command_show ( args )
def command_busy ( self , args ) :
args . insert ( 0 , ' busy ' )
self . command_show ( args )
def command_avail ( self , args ) :
args . insert ( 0 , ' available ' )
self . command_show ( args )
2010-01-31 00:25:17 +00:00
2010-01-30 04:02:23 +00:00
def command_part ( self , args ) :
reason = None
room = self . current_room ( )
if room . name == ' Info ' :
return
if len ( args ) :
msg = ' ' . join ( args )
else :
msg = None
2010-01-30 04:42:29 +00:00
if room . joined :
self . muc . quit_room ( room . name , room . own_nick , msg )
2010-01-30 04:02:23 +00:00
self . rooms . remove ( self . current_room ( ) )
2010-02-11 04:59:58 +00:00
self . window . refresh ( self . rooms )
2010-01-30 04:02:23 +00:00
2010-01-30 03:06:38 +00:00
def command_nick ( self , args ) :
if len ( args ) != 1 :
return
nick = args [ 0 ]
room = self . current_room ( )
if not room . joined or room . name == " Info " :
return
self . muc . change_nick ( room . name , nick )
2010-01-28 00:55:02 +00:00
def information ( self , msg ) :
room = self . get_room_by_name ( " Info " )
info = room . add_info ( msg )
2010-01-28 17:14:37 +00:00
if self . current_room ( ) == room :
2010-02-12 19:16:02 +00:00
self . window . text_win . add_line ( room , ( datetime . now ( ) , info ) )
2010-01-29 16:24:44 +00:00
self . window . text_win . refresh ( room . name )
curses . doupdate ( )
2010-01-28 00:55:02 +00:00
2010-01-13 01:04:30 +00:00
def command_quit ( self , args ) :
2010-01-26 17:10:37 +00:00
self . reset_curses ( )
2010-01-13 01:04:30 +00:00
sys . exit ( )