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
|
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))
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
77
src/gui.py
77
src/gui.py
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue