summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client.py8
-rw-r--r--src/connection.py6
-rw-r--r--src/gui.py75
-rw-r--r--src/window.py50
4 files changed, 98 insertions, 41 deletions
diff --git a/src/client.py b/src/client.py
index f64dc5e6..9840d259 100644
--- a/src/client.py
+++ b/src/client.py
@@ -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))
diff --git a/src/connection.py b/src/connection.py
index c651032e..8a042502 100644
--- a/src/connection.py
+++ b/src/connection.py
@@ -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
diff --git a/src/gui.py b/src/gui.py
index d610435f..f6f0a5e2 100644
--- a/src/gui.py
+++ b/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())
+ 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_left(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.current_room())
+ self.window.refresh(self.rooms)
- def rotate_rooms_right(self, args=None):
+ 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:
diff --git a/src/window.py b/src/window.py
index 8aa95995..857d441e 100644
--- a/src/window.py
+++ b/src/window.py
@@ -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)