This commit is contained in:
louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13 2010-02-11 04:59:58 +00:00
parent d2a4ecf9a5
commit c638055b24
4 changed files with 99 additions and 42 deletions

View file

@ -19,9 +19,9 @@
import sys
# disable any printout (this would mess the display)
STDERR = sys.stderr
sys.stderr = open('/dev/null', 'w')
stderr = sys.stderr
sys.stdout = open('/dev/null', 'w')
sys.stderr = open('/dev/null', 'w')
from connection import Connection
from multiuserchat import MultiUserChat
@ -43,7 +43,7 @@ def exception_handler(type_, value, trace):
"""
curses.echo()
curses.endwin()
traceback.print_exception(type_, value, trace, None, STDERR)
traceback.print_exception(type_, value, trace, None, stderr)
sys.exit()
sys.excepthook = exception_handler
@ -59,8 +59,8 @@ class Client(object):
self.resource = config.get('resource', 'poezio')
self.server = config.get('server', 'louiz.org')
self.connection = Connection(self.server, self.resource)
self.stdscr = initscr()
self.connection.start()
self.gui = Gui(self.stdscr, MultiUserChat(self.connection.client))

View file

@ -22,16 +22,16 @@ import sys
import xmpp
from config import config
from logging import logger
from threading import Thread
from handler import Handler
import threading
class Connection(Thread):
class Connection(threading.Thread):
"""
Receives everything from Jabber and emits the
appropriate signals
"""
def __init__(self, server, resource):
Thread.__init__(self)
threading.Thread.__init__(self)
self.handler = Handler()
self.server = server

View file

@ -58,9 +58,11 @@ class User(object):
class Room(object):
"""
"""
def __init__(self, name, nick):
def __init__(self, name, nick, number):
self.name = name
self.own_nick = nick
self.color_state = 11 # color used in RoomInfo
self.nb = number # number used in RoomInfo
self.joined = False # false until self presence is received
self.users = []
self.lines = [] # (time, nick, msg) or (time, info)
@ -71,6 +73,8 @@ class Room(object):
self.users = []
def add_message(self, nick, msg):
self.set_color_state(12)
# TODO check for highlight
if not msg:
logger.info('msg is None..., %s' % (nick))
return
@ -92,6 +96,9 @@ class Room(object):
return user
return None
def set_color_state(self, color):
self.color_state = color
def on_presence(self, stanza, nick):
"""
"""
@ -151,13 +158,14 @@ class Gui(object):
Graphical user interface using ncurses
"""
def __init__(self, stdscr=None, muc=None):
self.room_number = 0
self.init_curses(stdscr)
self.stdscr = stdscr
self.rooms = [Room('Info', '')] # current_room is self.rooms[0]
self.rooms = [Room('Info', '', self.next_room_number())] # current_room is self.rooms[0]
self.window = Window(stdscr)
self.window.text_win.new_win('Info')
self.window.refresh(self.rooms[0])
self.window.new_room(self.current_room())
self.window.refresh(self.rooms)
self.muc = muc
@ -210,13 +218,13 @@ class Gui(object):
key = stdscr.getkey()
except:
self.window.resize(stdscr)
self.window.refresh(self.current_room())
self.window.refresh(self.rooms)
continue
if str(key) in self.key_func.keys():
self.key_func[key]()
elif str(key) == 'KEY_RESIZE':
self.window.resize(stdscr)
self.window.refresh(self.current_room())
self.window.refresh(self.rooms)
elif len(key) >= 4:
continue
elif ord(key) == 10:
@ -238,6 +246,11 @@ class Gui(object):
key = key+stdscr.getkey()
self.window.do_command(key)
def next_room_number(self):
nb = self.room_number
self.room_number += 1
return nb
def current_room(self):
return self.rooms[0]
@ -260,6 +273,10 @@ class Gui(object):
curses.init_pair(7, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(8, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK)
curses.init_pair(10, curses.COLOR_WHITE, curses.COLOR_GREEN) # current room
curses.init_pair(11, curses.COLOR_WHITE, curses.COLOR_BLUE) # normal room
curses.init_pair(12, curses.COLOR_WHITE, curses.COLOR_CYAN) # new message room
curses.init_pair(13, curses.COLOR_WHITE, curses.COLOR_RED) # highlight room
def reset_curses(self):
curses.echo()
@ -270,17 +287,29 @@ class Gui(object):
self.information(_("Your JID is %s") % jid)
def join_room(self, room, nick):
self.window.text_win.new_win(room)
self.rooms.insert(0, Room(room, nick))
self.window.refresh(self.current_room())
def rotate_rooms_left(self, args=None):
self.rooms.append(self.rooms.pop(0))
self.window.refresh(self.current_room())
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)
def rotate_rooms_right(self, args=None):
self.current_room().set_color_state(11)
self.rooms.append(self.rooms.pop(0))
self.window.refresh(self.rooms)
def rotate_rooms_left(self, args=None):
self.current_room().set_color_state(11)
self.rooms.insert(0, self.rooms.pop())
self.window.refresh(self.current_room())
self.window.refresh(self.rooms)
def room_message(self, stanza):
if len(sys.argv) > 1:
@ -311,6 +340,8 @@ class Gui(object):
if room == self.current_room():
self.window.text_win.refresh(room.name)
self.window.input.refresh()
else:
self.window.info_win.refresh(self.rooms, self.current_room())
curses.doupdate()
def room_presence(self, stanza):
@ -385,20 +416,6 @@ class Gui(object):
roomname = self.current_room().name
self.muc.eject_user(roomname, 'kick', nick, reason)
# def command_ban(self, args):
# if len(args) < 1:
# self.command_help(['ban'])
# return
# nick = args[0]
# if len(args) >= 2:
# reason = ' '.join(args[1:])
# else:
# reason = None
# if self.current_room().name == 'Info' or not self.current_room().joined:
# return
# roomname = self.current_room().name
# self.muc.eject_user(roomname, 'ban', nick, reason)
def command_join(self, args):
if len(args) == 0:
r = self.current_room()
@ -512,7 +529,7 @@ class Gui(object):
if room.joined:
self.muc.quit_room(room.name, room.own_nick, msg)
self.rooms.remove(self.current_room())
self.window.refresh(self.current_room())
self.window.refresh(self.rooms)
def command_nick(self, args):
if len(args) != 1:

View file

@ -65,7 +65,7 @@ class UserList(Win):
return
self._resize(height, width, y, x, stdscr)
class Info(Win):
class Topic(Win):
def __init__(self, height, width, y, x, parent_win, visible):
self.visible = visible
Win.__init__(self, height, width, y, x, parent_win)
@ -83,6 +83,40 @@ class Info(Win):
except:pass
self.win.refresh()
class RoomInfo(Win):
def __init__(self, height, width, y, x, parent_win, visible):
self.visible = visible
Win.__init__(self, height, width, y, x, parent_win)
def resize(self, height, width, y, x, stdscr, visible):
self._resize(height, width, y, x, stdscr)
def refresh(self, rooms, current):
if not self.visible:
return
def compare_room(a, b):
return a.nb - b.nb
self.win.clear()
self.win.addnstr(0, 0, current.name+" [", self.width-1
,curses.color_pair(1))
sorted_rooms = sorted(rooms, compare_room)
for room in sorted_rooms:
if current == room:
color = 10
else:
color = room.color_state
try:
self.win.addstr(str(room.nb), curses.color_pair(color))
self.win.addstr(",", curses.color_pair(1))
except: # end of line
break
(y, x) = self.win.getyx()
try:
self.win.addstr(y, x-1, ']'+(' '*((self.width-1)-x)), curses.color_pair(1))
except:
pass
self.win.refresh()
class TextWin(object):
"""
keep a dict of {winname: window}
@ -341,8 +375,8 @@ class Window(object):
stdscr.vline(1, 9*(self.width/10), curses.ACS_VLINE, self.height-2)
stdscr.attroff(curses.color_pair(2))
self.user_win = UserList(self.height-3, (self.width/10)-1, 1, 9*(self.width/10)+1, stdscr, visible)
self.topic_win = Info(1, self.width, 0, 0, stdscr, visible)
self.info_win = Info(1, self.width, self.height-2, 0, stdscr, visible)
self.topic_win = Topic(1, self.width, 0, 0, stdscr, visible)
self.info_win = RoomInfo(1, self.width, self.height-2, 0, stdscr, visible)
self.text_win = TextWin(self.height-3, (self.width/10)*9, 1, 0, stdscr, visible)
self.input = Input(1, self.width, self.height-1, 0, stdscr, visible)
@ -365,15 +399,21 @@ class Window(object):
self.text_win.resize(self.height-3, (self.width/10)*9, 1, 0, stdscr, visible)
self.input.resize(1, self.width, self.height-1, 0, stdscr, visible)
def refresh(self, room):
def refresh(self, rooms):
"""
'room' is the current one
"""
room = rooms[0] # get current room
self.text_win.redraw(room)
self.text_win.refresh(room.name)
self.user_win.refresh(room.users)
self.topic_win.refresh(room.topic)
self.info_win.refresh(room.name)
self.info_win.refresh(rooms, room)
self.input.refresh()
def do_command(self, key):
self.input.do_command(key)
self.input.refresh()
def new_room(self, room):
self.text_win.new_win(room.name)