fixed #1148
This commit is contained in:
parent
d2a4ecf9a5
commit
c638055b24
4 changed files with 99 additions and 42 deletions
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
77
src/gui.py
77
src/gui.py
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue