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

View file

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

View file

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

View file

@ -65,7 +65,7 @@ class UserList(Win):
return return
self._resize(height, width, y, x, stdscr) self._resize(height, width, y, x, stdscr)
class Info(Win): class Topic(Win):
def __init__(self, height, width, y, x, parent_win, visible): def __init__(self, height, width, y, x, parent_win, visible):
self.visible = visible self.visible = visible
Win.__init__(self, height, width, y, x, parent_win) Win.__init__(self, height, width, y, x, parent_win)
@ -83,6 +83,40 @@ class Info(Win):
except:pass except:pass
self.win.refresh() 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): class TextWin(object):
""" """
keep a dict of {winname: window} 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.vline(1, 9*(self.width/10), curses.ACS_VLINE, self.height-2)
stdscr.attroff(curses.color_pair(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.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.topic_win = Topic(1, self.width, 0, 0, stdscr, visible)
self.info_win = Info(1, self.width, self.height-2, 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.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) 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.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) 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.redraw(room)
self.text_win.refresh(room.name) self.text_win.refresh(room.name)
self.user_win.refresh(room.users) self.user_win.refresh(room.users)
self.topic_win.refresh(room.topic) self.topic_win.refresh(room.topic)
self.info_win.refresh(room.name) self.info_win.refresh(rooms, room)
self.input.refresh() self.input.refresh()
def do_command(self, key): def do_command(self, key):
self.input.do_command(key) self.input.do_command(key)
self.input.refresh() self.input.refresh()
def new_room(self, room):
self.text_win.new_win(room.name)