summaryrefslogtreecommitdiff
path: root/src/gui.py
diff options
context:
space:
mode:
authorlouiz@4325f9fc-e183-4c21-96ce-0ab188b42d13 <louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13>2010-01-21 01:54:50 +0000
committerlouiz@4325f9fc-e183-4c21-96ce-0ab188b42d13 <louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13>2010-01-21 01:54:50 +0000
commitf36fefdce5d9369516a7d88528902b5081080876 (patch)
treee9f017cf7f2f7bd92cc134874cc907fe056d944a /src/gui.py
parent6a2917fca8d2c15ac63967a033f001b021623510 (diff)
downloadpoezio-f36fefdce5d9369516a7d88528902b5081080876.tar.gz
poezio-f36fefdce5d9369516a7d88528902b5081080876.tar.bz2
poezio-f36fefdce5d9369516a7d88528902b5081080876.tar.xz
poezio-f36fefdce5d9369516a7d88528902b5081080876.zip
on peut parler, recevoir des messages, rejoindre des salons (/join), changer de tab (/next, /prev), mais ca blink et c'est nul
Diffstat (limited to 'src/gui.py')
-rw-r--r--src/gui.py351
1 files changed, 129 insertions, 222 deletions
diff --git a/src/gui.py b/src/gui.py
index e41ec5a9..c69b5901 100644
--- a/src/gui.py
+++ b/src/gui.py
@@ -22,222 +22,162 @@ import curses
from curses import textpad
import locale
+from datetime import datetime
+
locale.setlocale(locale.LC_ALL, '')
code = locale.getpreferredencoding()
import sys
from connection import *
+from window import Window
-class Win(object):
- def __init__(self, height, width, y, x, parent_win):
- self._resize(height, width, y, x, parent_win)
-
- def _resize(self, height, width, y, x, parent_win):
- self.height, self.width, self.x, self.y = height, width, x, y
- try:
- self.win = parent_win.subwin(height, width, y, x)
- except:
- pass
-
-class UserList(Win):
- def __init__(self, height, width, y, x, parent_win):
- Win.__init__(self, height, width, y, x, parent_win)
- self.win.attron(curses.color_pair(2))
- self.win.vline(0, 0, curses.ACS_VLINE, self.height)
- self.win.attroff(curses.color_pair(2))
- self.list = []
-
- def add_user(self, name):
- """
- add an user to the list
- """
- self.list.append(name)
-
- def refresh(self):
- self.win.clear()
- self.win.attron(curses.color_pair(2))
- self.win.vline(0, 0, curses.ACS_VLINE, self.height)
- self.win.attroff(curses.color_pair(2))
- y = 0
- for name in self.list:
- self.win.addstr(y, 1, name)
- y += 1
- self.win.refresh()
-
- def resize(self, height, width, y, x, stdscr):
- self._resize(height, width, y, x, stdscr)
- self.refresh()
-
-class Info(Win):
- def __init__(self, height, width, y, x, parent_win):
- Win.__init__(self, height, width, y, x, parent_win)
- self.txt = ""
-# self.win.bkgd(ord('p'), curses.COLOR_BLUE)
-
- def set_info(self, text):
- self.txt = text
- self.refresh()
-
- def resize(self, height, width, y, x, stdscr):
- self._resize(height, width, y, x, stdscr)
- self.refresh()
-
- def refresh(self):
- self.win.clear()
- try:
- self.win.addstr(0, 0, self.txt + " "*(self.width-len(self.txt)-1)
- , curses.color_pair(1))
- except:
- pass
-
-class TextWin(Win):
- def __init__(self, height, width, y, x, parent_win):
- Win.__init__(self, height, width, y, x, parent_win)
- self.lines = []
-
- def add_line(self, time, nick, text):
- self.lines.append((time, nick, text))
- self.refresh()
-
- def refresh(self):
- self.win.clear()
- y = 0
- for line in self.lines[-self.height:]:
- self.win.addstr(y, 0, line[0] + " : " + line[1] + ": " + line[2])
- y += 1
- self.win.refresh()
-
- def resize(self, height, width, y, x, stdscr):
- self._resize(height, width, y, x, stdscr)
- self.refresh()
-
-class Input(Win):
+class User(object):
"""
+ keep trace of an user in a Room
"""
- def __init__(self, height, width, y, x, stdscr):
- Win.__init__(self, height, width, y, x, stdscr)
- self.input = curses.textpad.Textbox(self.win)
- self.input.stripspaces = False
- self.input.insert_mode = True
- self.txt = ''
-
- def resize(self, height, width, y, x, stdscr):
- self._resize(height, width, y, x, stdscr)
- self.input = curses.textpad.Textbox(self.win)
- self.input.insert_mode = True
- self.input.stripspaces = False
- self.win.clear()
- self.win.addstr(self.txt)
-
- def do_command(self, key):
- self.input.do_command(key)
-# self.win.refresh()
-# self.text = self.input.gather()
+ def __init__(self, nick, affiliation, show, status, role):
+ self.update(affiliation, show, status, role)
+ self.change_nick(nick)
- # def insert_char(self, key):
- # if self.insert:
- # self.text = self.text[:self.pos]+key+self.text[self.pos:]
- # else:
- # self.text = self.text[:self.pos]+key+self.text[self.pos+1:]
- # self.pos += 1
- # pass
+ def update(self, affiliation, show, status, role):
+ self.affiliation = None
+ self.show = None
+ self.status = status
+ self.role = role
- def get_text(self):
- return self.input.gather()
+ def change_nick(self, nick):
+ self.nick = nick
- def save_text(self):
- self.txt = self.input.gather()
-# self.win.clear()
-# self.win.addstr(self.txt)
-
- def refresh(self):
-# self.win.clear()
-# self.win.addstr(self.text)
-# self.win.move(0, len(self.text)-1)
- self.win.refresh()
-
- def clear_text(self):
- self.win.clear()
- self.txt = ''
- self.pos = 0
- self.refresh()
-
-class Tab(object):
+class Room(object):
"""
- The whole "screen" that can be seen at once in the terminal.
- It contains an userlist, an input zone and a chat zone, all
- related to one single chat room.
"""
- def __init__(self, stdscr, name='info'):
- """
- name is the name of the Tab, and it's also
- the JID of the chatroom.
- A particular tab is the "Info" tab which has no
- name (None). This info tab should be unique.
- The stdscr should be passed to know the size of the
- terminal
- """
+ def __init__(self, name, nick):
self.name = name
- self.size = (self.height, self.width) = stdscr.getmaxyx()
+ self.own_nick = nick
+ self.joined = False # false until self presence is received
+ self.users = []
+ self.lines = [] # (time, nick, msg) or (time, info)
+ self.topic = ''
- self.user_win = UserList(self.height-3, self.width/7, 1, 6*(self.width/7), stdscr)
- self.topic_win = Info(1, self.width, 0, 0, stdscr)
- self.info_win = Info(1, self.width, self.height-2, 0, stdscr)
- self.text_win = TextWin(self.height-3, (self.width/7)*6, 1, 0, stdscr)
- self.input = Input(1, self.width, self.height-1, 0, stdscr)
+ def add_message(self, nick, msg):
+ self.lines.append((datetime.now(), nick, msg.encode('utf-8')))
- self.info_win.set_info(name)
- # debug
- self.refresh()
+ def add_info(self, info):
+ """ info, like join/quit/status messages"""
+ self.lines.append((datetime.now(), info.encode('utf-8')))
- def resize(self, stdscr):
+ def on_presence(self, stanza, nick):
"""
- Resize the whole tabe. i.e. all its sub-windows
"""
- self.size = (self.height, self.width) = stdscr.getmaxyx()
- self.user_win.resize(self.height-3, self.width/7, 1, 6*(self.width/7), stdscr)
- self.topic_win.resize(1, self.width, 0, 0, stdscr)
- self.info_win.resize(1, self.width, self.height-2, 0, stdscr)
- self.text_win.resize(self.height-3, (self.width/7)*6, 1, 0, stdscr)
- self.input.resize(1, self.width, self.height-1, 0, stdscr)
- self.refresh()
-
- def refresh(self):
- self.text_win.add_line("fion", "fion", "refresh")
- self.text_win.refresh()
- self.user_win.refresh()
- self.topic_win.refresh()
- self.info_win.refresh()
- self.input.refresh()
-
- def do_command(self, key):
- self.input.do_command(key)
-# self.input.save_text()
- self.input.refresh()
+ affiliation = stanza.getAffiliation()
+ show = stanza.getShow()
+ status = stanza.getStatus()
+ role = stanza.getRole()
+ if not self.joined:
+ self.users.append(User(nick, affiliation, show, status, role))
+ if nick == self.own_nick:
+ self.joined = True
+ self.add_info("%s is in the room" % (nick))
+ return
+ change_nick = stanza.getStatusCode() == '303'
+ for user in self.users:
+ if user.nick == nick:
+ if change_nick:
+ user.change_nick(stanza.getNick())
+ self.add_info('%s is now known as %s' % (nick, stanza.getNick()))
+ return
+ if status == 'offline':
+ self.users.remove(user)
+ self.add_info('%s has left the room' % (nick))
+ return
+ user.update(affiliation, show, status, role)
+ self.add_info('%s, status : %s, %s, %s, %s' % (nick, affiliation, role, show, status))
+ return
+ self.users.append(User(nick, affiliation, show, status, role))
+ self.add_info('%s joined the room %s' % (nick, self.name))
class Gui(object):
"""
Graphical user interface using ncurses
"""
- def __init__(self, stdscr):
- self.handler = Handler()
+ def __init__(self, stdscr=None, muc=None):
+
+ self.init_curses(stdscr)
+ self.stdscr = stdscr
+ self.stdscr.leaveok(True)
+ self.rooms = [Room('Info', '')] # current_room is self.rooms[0]
+ self.window = Window(stdscr)
+ self.window.refresh(self.rooms[0])
+
+ self.muc = muc
self.commands = {
'join': self.command_join,
'quit': self.command_quit,
+ 'next': self.rotate_rooms_left,
+ 'prev': self.rotate_rooms_right,
}
- self.handler.connect('on-muc-message-received', self.on_message)
- self.handler.connect('gui-join-room', self.on_join_room)
- self.handler.connect('on-muc-presence-changed', self.on_presence)
- self.init_curses(stdscr)
- self.stdscr = stdscr
+ self.handler = Handler()
+ self.handler.connect('on-connected', self.on_connected)
+ self.handler.connect('join-room', self.join_room)
+ self.handler.connect('room-presence', self.room_presence)
+ self.handler.connect('room-message', self.room_message)
+
+ def init_curses(self, stdscr):
+ curses.start_color()
+ curses.noecho()
+ curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)
+ curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
+
+ def on_connected(self):
+ pass
+
+ def join_room(self, room, nick):
+ self.rooms.insert(0, Room(room, nick))
+ self.window.refresh(self.rooms[0])
+
+ def rotate_rooms_left(self, args):
+ self.rooms.append(self.rooms.pop(0))
+ self.window.refresh(self.rooms[0])
+
+ def rotate_rooms_right(self, args):
+ self.rooms.insert(0, self.rooms.pop())
+ self.window.refresh(self.rooms[0])
+
+ def room_message(self, stanza):
+ if stanza.getType() != 'groupchat':
+ return # ignore all messages not comming from a MUC
+ room_from = stanza.getFrom().getStripped()
+ nick_from = stanza.getFrom().getResource()
+ for room in self.rooms:
+ if room_from == room.name:
+ room.add_message(nick_from, stanza.getBody())
+ if room == self.rooms[0]:
+ # self.window.text_win.refresh(room.lines)
+ # self.window.user_win.refresh(room.users)
+ # self.window.input.refresh()
+ self.window.refresh(self.rooms[0])
+ break
+
+ def room_presence(self, stanza):
+ from_nick = stanza.getFrom().getResource()
+ from_room = stanza.getFrom().getStripped()
+ for room in self.rooms:
+ if from_room == room.name:
+ room.on_presence(stanza, from_nick)
+ if room == self.rooms[0]:
+ self.window.text_win.refresh(room.lines)
+ self.window.user_win.refresh(room.users)
+ break
def execute(self):
- line = self.current_tab.input.get_text()
- self.current_tab.input.clear_text()
+ line = self.window.input.get_text()
+ self.window.input.clear_text()
+ if line == "":
+ return
if line.strip().startswith('/'):
command = line.strip()[:].split()[0][1:]
args = line.strip()[:].split()[1:]
@@ -245,58 +185,25 @@ class Gui(object):
func = self.commands[command]
func(args)
return
- self.current_tab.text_win.add_line("NOW", "louiz'", line)
- # TODO, send message to jabber
+ if self.rooms[0].name != 'Info':
+ self.muc.send_message(self.rooms[0].name, line)
def command_join(self, args):
room = args[0]
- self.on_join_room(room, "poezio")
+ self.muc.join_room(room, "poezio")
+ self.join_room(room, 'poezio')
def command_quit(self, args):
sys.exit()
- def init_curses(self, stdscr):
- stdscr.leaveok(True)
- curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)
- curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
- self.current_tab = Tab(stdscr)
- self.tabs = [self.current_tab]
-
def main_loop(self, stdscr):
while 1:
stdscr.refresh()
+ # self.window.input.refresh()
key = stdscr.getch()
if key == curses.KEY_RESIZE:
- self.current_tab.resize(stdscr)
+ self.window.resize(stdscr)
elif key == 10:
self.execute()
else:
- self.current_tab.do_command(key)
-
- def on_message(self, jid, msg, subject, typ, stanza):
- print "on_message", jid, msg, subject, typ
-
- def on_join_room(self, room, nick):
- sys.stderr.write(room)
- self.current_tab = Tab(self.stdscr, room)
- self.tabs.append(self.current_tab)
-# self.current_tab.resize()
- self.current_tab.refresh()
- print "on_join_room", room, nick
-
- def on_presence(self, jid, priority, show, status, stanza):
- print "on presence", jid, priority, show, status
-
-def main(stdscr):
- gui = Gui(stdscr)
- gui.main_loop(stdscr)
-
-if __name__ == '__main__':
- resource = config.get('resource')
- server = config.get('server')
- connection = Connection(server, resource)
- connection.start()
- curses.wrapper(main)
- # rooms = config.get('rooms').split(':')
- # for room in rooms:
- # connection.send_join_room(room.split('/')[0], room.split('/')[1])
+ self.window.do_command(key)