a few renamings, and some other stuff
This commit is contained in:
parent
de7c007a22
commit
f4d4a205f1
16 changed files with 100 additions and 205 deletions
13
CHANGELOG
13
CHANGELOG
|
@ -3,15 +3,20 @@ For more detailed changelog, see the roadmap:
|
||||||
http://codingteam.net/project/poezio/roadmap
|
http://codingteam.net/project/poezio/roadmap
|
||||||
|
|
||||||
* Poezio 0.7 - dev
|
* Poezio 0.7 - dev
|
||||||
"Complete the MUC support"
|
"Roster"
|
||||||
- All poezio colors can be changed with a theme file
|
- Introduce the roster
|
||||||
- /say command
|
- One to one conversations
|
||||||
|
- Roster search
|
||||||
|
- Resizable mini-buffer displaying various informations
|
||||||
|
- All colors can be changed with a theme file
|
||||||
|
- /say and // commands
|
||||||
- Warn user about publicly logged rooms
|
- Warn user about publicly logged rooms
|
||||||
- Possibility to limit the number of history messages received from MUC
|
- Possibility to limit the number of history messages received from MUC
|
||||||
- auto-rejoin when kicked from a MUC
|
- auto-rejoin when kicked from a MUC
|
||||||
- The number of lines available to scroll down is displayed
|
- The number of lines available to scroll down is displayed
|
||||||
- Possibility to use a modified nickname automatically when a nick is reserved
|
- Possibility to use a modified nickname automatically when a nick is reserved
|
||||||
- A line indicates the new messages in the window
|
- A line separates the alread-read messages
|
||||||
|
from the new messages in a conversation
|
||||||
- Information messages are more colored
|
- Information messages are more colored
|
||||||
- bugfixes
|
- bugfixes
|
||||||
|
|
||||||
|
|
29
README
29
README
|
@ -10,24 +10,27 @@
|
||||||
Homepage: http://poezio.eu
|
Homepage: http://poezio.eu
|
||||||
Forge Page: http://codingteam.net/projet/poezio
|
Forge Page: http://codingteam.net/projet/poezio
|
||||||
|
|
||||||
Poezio is a console Jabber/XMPP client. Its goal is to use anonymous
|
Poezio is a console Jabber/XMPP client. Its goal is to use anonymous
|
||||||
connections to simply let the user join MultiUserChats. This way, the user
|
connections to simply let the user join MultiUserChats. This way, the user
|
||||||
doesn't have to create a Jabber account, exactly like people are using
|
doesn't have to create a Jabber account, exactly like people are using
|
||||||
IRC. Poezio's commands are designed to be (if possible) like IRC
|
IRC. Poezio's commands are designed to be (if possible) like IRC
|
||||||
clients (weechat, irssi, etc).
|
clients (weechat, irssi, etc).
|
||||||
Since version 0.7, poezio can handle real Jabber accounts along with
|
Since version 0.7, poezio can handle real Jabber accounts along with
|
||||||
roster and one to one conversation, making it a full-featured console
|
roster and one to one conversations, making it a full-featured console
|
||||||
Jabber client, but still MultiUserChats-centered.
|
Jabber client, but still MultiUserChats-centered.
|
||||||
|
In the futur, poezio should implement at a 100% level all XEP related to
|
||||||
|
MUCs, especially XEP 0045.
|
||||||
|
All other IM-related XEP (wherever possible) should be implemented through
|
||||||
|
plugins or directly in poezio's core.
|
||||||
|
|
||||||
=======================
|
=======================
|
||||||
Install
|
Install
|
||||||
=======================
|
=======================
|
||||||
You need python 3.0 or higher, and the SleekXMPP python library.
|
You need python 3.0 or higher, and the SleekXMPP python library.
|
||||||
You can find my patched version at http://github.com/louiz/SleekXMPP until
|
SleekXMPP can be found at http://github.com/fritzy/SleekXMPP.
|
||||||
my changes (required to properly run poezio) are merged upstream.
|
|
||||||
|
|
||||||
you can launch poezio with
|
you can launch poezio with
|
||||||
sh launch.sh
|
./launch.sh
|
||||||
|
|
||||||
or you can install it with (as root or with sudo)
|
or you can install it with (as root or with sudo)
|
||||||
make install
|
make install
|
||||||
|
@ -36,7 +39,7 @@ you can now simply launch `poezio'
|
||||||
|
|
||||||
You can edit the config file (~/.config/poezio/poezio.cfg by default)
|
You can edit the config file (~/.config/poezio/poezio.cfg by default)
|
||||||
or data/default_config.cfg (if you want to edit the config before the
|
or data/default_config.cfg (if you want to edit the config before the
|
||||||
first launch)
|
first launch). The default config file is fully commented.
|
||||||
|
|
||||||
Please, see the online documentation for more information on installing,
|
Please, see the online documentation for more information on installing,
|
||||||
configuring or using poezio:
|
configuring or using poezio:
|
||||||
|
@ -66,10 +69,10 @@ Report a bug: http://codingteam.net/project/poezio/bugs/add
|
||||||
Poezio is Free Software.
|
Poezio is Free Software.
|
||||||
(learn more: http://www.gnu.org/philosophy/free-sw.html)
|
(learn more: http://www.gnu.org/philosophy/free-sw.html)
|
||||||
|
|
||||||
Poezio is released under the Gnu GPLv3 license
|
Poezio is released under the Gnu GPLv3 license.
|
||||||
Please read the COPYING file for details
|
Please read the COPYING file for details.
|
||||||
|
|
||||||
The artwork logo is made by Gaëtan Ribémont and released under
|
The artwork logo was made by Gaëtan Ribémont and released under
|
||||||
the Creative Commons BY license (http://creativecommons.org/licenses/by/2.0/)
|
the Creative Commons BY license (http://creativecommons.org/licenses/by/2.0/)
|
||||||
|
|
||||||
=======================
|
=======================
|
||||||
|
@ -85,9 +88,3 @@ the Creative Commons BY license (http://creativecommons.org/licenses/by/2.0/)
|
||||||
FlashCode (weechat dev) - Useful advices on how to use ncurses efficiently
|
FlashCode (weechat dev) - Useful advices on how to use ncurses efficiently
|
||||||
= Project =
|
= Project =
|
||||||
Gajim - send_vcard method and common.py
|
Gajim - send_vcard method and common.py
|
||||||
|
|
||||||
=======================
|
|
||||||
Donate
|
|
||||||
=======================
|
|
||||||
If you're willing to thank me, or ask for an on-demand feature, please
|
|
||||||
see the page http://louiz.org/donate.html and contact me.
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ port = 5222
|
||||||
resource =
|
resource =
|
||||||
|
|
||||||
# the nick you will use when joining a room with no associated nick
|
# the nick you will use when joining a room with no associated nick
|
||||||
# If this is empty, the $USER variable will be used
|
# If this is empty, the $USER environn<ement variable will be used
|
||||||
default_nick =
|
default_nick =
|
||||||
|
|
||||||
# Jabber identifiant. Specify it only if you want to connect using an existing
|
# Jabber identifiant. Specify it only if you want to connect using an existing
|
||||||
|
@ -35,15 +35,6 @@ password =
|
||||||
# default_nick will be used if "/nickname" is not specified
|
# default_nick will be used if "/nickname" is not specified
|
||||||
rooms = poezio@conference.codingteam.net
|
rooms = poezio@conference.codingteam.net
|
||||||
|
|
||||||
# PROXY
|
|
||||||
# set to true if you want to use an http proxy server
|
|
||||||
# if false, no proxy will be used and the proxy_* settings will have no effect
|
|
||||||
use_proxy = false
|
|
||||||
proxy_server =
|
|
||||||
proxy_port =
|
|
||||||
proxy_user =
|
|
||||||
proxy_password =
|
|
||||||
|
|
||||||
# the completion type you will use to complete nicknames
|
# the completion type you will use to complete nicknames
|
||||||
# if "normal", complete the entire name to the first available completion
|
# if "normal", complete the entire name to the first available completion
|
||||||
# and then cycle through the possible completion with the next TABs
|
# and then cycle through the possible completion with the next TABs
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
Poezio \- a ncurses jabber client
|
Poezio \- a ncurses jabber client
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
.B poezio [\-f \fICONFIG_FILE\fR] [\-h]
|
.B poezio [\-f \fICONFIG_FILE\fR] [\-d \fIDEBUG_FILE\fR] [\-h]
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
.B Poezio
|
.B Poezio
|
||||||
is a console jabber (XMPP) client written in Python and using ncurses to draw its interface. It aims at being similar to the most famous IRC clients. For more information on XMPP see http://xmpp.org and on Poezio see http://poezio.eu
|
is a console jabber (XMPP) client written in Python and using ncurses to draw its interface. It aims at being similar to the most famous IRC clients. For more information on XMPP see http://xmpp.org and on Poezio see http://poezio.eu
|
||||||
|
@ -15,10 +15,13 @@ is a console jabber (XMPP) client written in Python and using ncurses to draw it
|
||||||
\fB\-f\fR, \fB\-\-file \fICONFIG_FILE\fR
|
\fB\-f\fR, \fB\-\-file \fICONFIG_FILE\fR
|
||||||
Run poezio using \fICONFIG_FILE\fR as the config file instead of ~/.config/poezio/poezio.cfg
|
Run poezio using \fICONFIG_FILE\fR as the config file instead of ~/.config/poezio/poezio.cfg
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-d\fR, \fB\-\-debug \fIDEBUG_FILE\fR
|
||||||
|
Log debug from both poezio and SleekXMPP in \fIDEBUG_FILE\fR. Debug contains incoming and outgoing stanzas in addition to various message helping poezio's debuging.
|
||||||
|
.TP
|
||||||
\fB\-h\fR
|
\fB\-h\fR
|
||||||
Display and help message
|
Display and help message
|
||||||
.SH "BUGS"
|
.SH "BUGS"
|
||||||
Sure, of course.
|
Sure.
|
||||||
.SH "FEEDBACK"
|
.SH "FEEDBACK"
|
||||||
You are encouraged to report bugs or feature requests on http://codingteam.net/project/poezio.
|
You are encouraged to report bugs or feature requests on http://codingteam.net/project/poezio.
|
||||||
You can also find us on the Jabber chatroom poezio@conference.codingteam.net
|
You can also find us on the Jabber chatroom poezio@conference.codingteam.net
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
python3 src/poezio.py "$@"
|
python3 src/poezio.py "$@"
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,14 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Define all the buffers.
|
||||||
|
A buffer is a little part of the screen, for example the input buffer,
|
||||||
|
the text bufferr, the roster buffer, etc.
|
||||||
|
A Tab (see tab.py) is composed of multiple Buffers
|
||||||
|
A buffer can also be called Window, even if it's not prefered.
|
||||||
|
"""
|
||||||
|
|
||||||
from gettext import (bindtextdomain, textdomain, bind_textdomain_codeset,
|
from gettext import (bindtextdomain, textdomain, bind_textdomain_codeset,
|
||||||
gettext as _)
|
gettext as _)
|
||||||
from os.path import isfile
|
from os.path import isfile
|
|
@ -15,12 +15,15 @@
|
||||||
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Defines the Resource and Contact classes
|
Defines the Resource and Contact classes, which are used in
|
||||||
|
the roster
|
||||||
"""
|
"""
|
||||||
from sleekxmpp.xmlstream.stanzabase import JID
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
from sleekxmpp.xmlstream.stanzabase import JID
|
||||||
|
|
||||||
class Resource(object):
|
class Resource(object):
|
||||||
"""
|
"""
|
||||||
Defines a roster item.
|
Defines a roster item.
|
||||||
|
@ -80,8 +83,7 @@ class Contact(object):
|
||||||
|
|
||||||
def get_highest_priority_resource(self):
|
def get_highest_priority_resource(self):
|
||||||
"""
|
"""
|
||||||
There must be, at any time, at least ONE resource.
|
Return the resource with the highest priority
|
||||||
And they always should be ordered by priority.
|
|
||||||
"""
|
"""
|
||||||
ret = None
|
ret = None
|
||||||
for resource in self._resources:
|
for resource in self._resources:
|
||||||
|
@ -94,8 +96,10 @@ class Contact(object):
|
||||||
Called, for example, when a new resource get offline
|
Called, for example, when a new resource get offline
|
||||||
(the first, or any subsequent one)
|
(the first, or any subsequent one)
|
||||||
"""
|
"""
|
||||||
# TODO sort by priority
|
def f(o):
|
||||||
|
return o.get_priority()
|
||||||
self._resources.append(resource)
|
self._resources.append(resource)
|
||||||
|
self._resources = sorted(self._resources, key=f, reverse=True)
|
||||||
|
|
||||||
def remove_resource(self, resource):
|
def remove_resource(self, resource):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -38,9 +38,9 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
import multiuserchat as muc
|
import multiuserchat as muc
|
||||||
from connection import connection
|
from connection import connection
|
||||||
from handler import Handler
|
|
||||||
from config import config
|
from config import config
|
||||||
from tab import MucTab, InfoTab, PrivateTab, RosterInfoTab, ConversationTab
|
from tab import MucTab, InfoTab, PrivateTab, RosterInfoTab, ConversationTab
|
||||||
|
from logger import logger
|
||||||
from user import User
|
from user import User
|
||||||
from room import Room
|
from room import Room
|
||||||
from roster import Roster, RosterGroup, roster
|
from roster import Roster, RosterGroup, roster
|
||||||
|
@ -822,6 +822,8 @@ class Core(object):
|
||||||
body = message['body']
|
body = message['body']
|
||||||
if body:
|
if body:
|
||||||
date = date if delayed == True else None
|
date = date if delayed == True else None
|
||||||
|
if not delayed:
|
||||||
|
logger.groupchat(room_from, nick_from, body)
|
||||||
self.add_message_to_text_buffer(room, body, date, nick_from)
|
self.add_message_to_text_buffer(room, body, date, nick_from)
|
||||||
self.refresh_window()
|
self.refresh_window()
|
||||||
self.doupdate()
|
self.doupdate()
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
# Copyright 2009, 2010 Erwan Briand
|
|
||||||
# Copyright 2010, Florent Le Coz <louiz@louiz.org>
|
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation version 3 of the License.
|
|
||||||
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from singleton import Singleton
|
|
||||||
|
|
||||||
#Todo, it's not a singleton. Oh, also, remove-me
|
|
||||||
|
|
||||||
class Handler(Singleton):
|
|
||||||
"""
|
|
||||||
This class is the global handler for the software's signals.
|
|
||||||
"""
|
|
||||||
__is_first_instance = True
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if Handler.__is_first_instance:
|
|
||||||
Handler.__is_first_instance = False
|
|
||||||
|
|
||||||
self.__signals__ = {
|
|
||||||
|
|
||||||
'on-connected': list(),
|
|
||||||
# At the end of a successful connection process.
|
|
||||||
# emitted when presence confirmation is received
|
|
||||||
# Args: jid
|
|
||||||
|
|
||||||
'join-room': list(),
|
|
||||||
# Join a room.
|
|
||||||
# Args: room, nick
|
|
||||||
|
|
||||||
'room-presence': list(),
|
|
||||||
# A presence is received
|
|
||||||
# Args: the stanza object
|
|
||||||
|
|
||||||
'room-message': list(),
|
|
||||||
# A message is received
|
|
||||||
# Args: the stanza object
|
|
||||||
|
|
||||||
'private-message': list(),
|
|
||||||
# A message is received
|
|
||||||
# Args: the stanza object
|
|
||||||
|
|
||||||
'room-delayed-message': list(),
|
|
||||||
# A message is received
|
|
||||||
# Args: the stanza object
|
|
||||||
|
|
||||||
'send-version': list(),
|
|
||||||
# We send our version
|
|
||||||
# Args: the stanza we reply to
|
|
||||||
|
|
||||||
'send-time': list(),
|
|
||||||
# We send our time
|
|
||||||
# Args: the stanza we reply to
|
|
||||||
|
|
||||||
'error-message': list(),
|
|
||||||
# We send our time
|
|
||||||
# Args: the stanza we reply to
|
|
||||||
|
|
||||||
'error': list()
|
|
||||||
# We send our time
|
|
||||||
# Args: the stanza we reply to
|
|
||||||
}
|
|
||||||
|
|
||||||
def connect(self, signal, func):
|
|
||||||
"""Connect a function to a signal."""
|
|
||||||
if func not in self.__signals__[signal]:
|
|
||||||
self.__signals__[signal].append(func)
|
|
||||||
|
|
||||||
def emit(self, signal, **kwargs):
|
|
||||||
"""Emit a signal."""
|
|
||||||
if signal in self.__signals__:
|
|
||||||
for func in self.__signals__[signal]:
|
|
||||||
func(**kwargs)
|
|
|
@ -29,32 +29,10 @@ class Logger(object):
|
||||||
"""
|
"""
|
||||||
def __init__(self):# , logfile, loglevel):
|
def __init__(self):# , logfile, loglevel):
|
||||||
self.logfile = config.get('logfile', 'logs')
|
self.logfile = config.get('logfile', 'logs')
|
||||||
self.loglevel = config.get('loglevel', 3)
|
|
||||||
# self.logfile = logfile
|
|
||||||
# self.loglevel = loglevel
|
|
||||||
|
|
||||||
def info(self, msg):
|
def groupchat(self, room, nick, msg):
|
||||||
if self.logfile and self.loglevel >= 3:
|
|
||||||
fd = open(self.logfile, 'a')
|
|
||||||
fd.write(datetime.now().strftime("%H:%M:%S") + ' Info [' + msg + ']\n')
|
|
||||||
fd.close()
|
|
||||||
|
|
||||||
def warning(self, msg):
|
|
||||||
if self.logfile and self.loglevel >= 2:
|
|
||||||
fd = open(self.logfile, 'a')
|
|
||||||
fd.write(datetime.now().strftime("%H:%M:%S") + ' Warning [' + msg + ']\n')
|
|
||||||
fd.close()
|
|
||||||
|
|
||||||
def error(self, msg):
|
|
||||||
if self.logfile and self.loglevel >= 1:
|
|
||||||
fd = open(self.logfile, 'a')
|
|
||||||
fd.write(datetime.now().strftime("%H:%M:%S") + ' Error [' + msg + ']\n')
|
|
||||||
fd.close()
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
def message(self, room, nick, msg):
|
|
||||||
"""
|
"""
|
||||||
log the message in the appropriate room
|
log the message in the appropriate room's file
|
||||||
"""
|
"""
|
||||||
if config.get('use_log', 'false') == 'false':
|
if config.get('use_log', 'false') == 'false':
|
||||||
return
|
return
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Define the Message class
|
||||||
|
"""
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
class Message(object):
|
class Message(object):
|
||||||
|
|
|
@ -46,7 +46,7 @@ def change_show(xmpp, jid, own_nick, show, status):
|
||||||
Change our 'Show'
|
Change our 'Show'
|
||||||
"""
|
"""
|
||||||
pres = xmpp.makePresence(pto='%s/%s' % (jid, own_nick))
|
pres = xmpp.makePresence(pto='%s/%s' % (jid, own_nick))
|
||||||
if show: # if show is None, don't put a <show /> tag. It means "online"
|
if show: # if show is None, don't put a <show /> tag. It means "available"
|
||||||
pres['type'] = show
|
pres['type'] = show
|
||||||
if status:
|
if status:
|
||||||
pres['status'] = status
|
pres['status'] = status
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Copyright 2009, 2010 Erwan Briand
|
|
||||||
# Copyright 2010, Florent Le Coz <louiz@louiz.org>
|
|
||||||
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation version 3 of the License.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
class Singleton(object):
|
|
||||||
""" Canonic Singleton implementation.
|
|
||||||
"""
|
|
||||||
_instance = None
|
|
||||||
def __new__(cls, *args, **kwargs):
|
|
||||||
if cls._instance is None:
|
|
||||||
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
|
|
||||||
return cls._instance
|
|
70
src/tab.py
70
src/tab.py
|
@ -15,11 +15,11 @@
|
||||||
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
a Tab object is a way to organize various Window (see window.py)
|
a Tab object is a way to organize various Buffers (see buffers.py)
|
||||||
around the screen at once.
|
around the screen at once.
|
||||||
A tab is then composed of multiple Window.
|
A tab is then composed of multiple Buffer.
|
||||||
Each Tab object has different refresh() and resize() methods, defining of its
|
Each Tab object has different refresh() and resize() methods, defining how its
|
||||||
Window are displayed, etc
|
Buffer are displayed, resized, etc
|
||||||
"""
|
"""
|
||||||
|
|
||||||
MIN_WIDTH = 50
|
MIN_WIDTH = 50
|
||||||
|
@ -28,7 +28,7 @@ MIN_HEIGHT = 16
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
import window
|
import buffers
|
||||||
import theme
|
import theme
|
||||||
import curses
|
import curses
|
||||||
import difflib
|
import difflib
|
||||||
|
@ -145,9 +145,9 @@ class InfoTab(Tab):
|
||||||
"""
|
"""
|
||||||
def __init__(self, stdscr, core, name):
|
def __init__(self, stdscr, core, name):
|
||||||
Tab.__init__(self, stdscr, core)
|
Tab.__init__(self, stdscr, core)
|
||||||
self.tab_win = window.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
self.tab_win = buffers.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
||||||
self.text_win = window.TextWin(self.height-2, self.width, 0, 0, stdscr, self.visible)
|
self.text_win = buffers.TextWin(self.height-2, self.width, 0, 0, stdscr, self.visible)
|
||||||
self.input = window.Input(1, self.width, self.height-1, 0, stdscr, self.visible)
|
self.input = buffers.Input(1, self.width, self.height-1, 0, stdscr, self.visible)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.color_state = theme.COLOR_TAB_NORMAL
|
self.color_state = theme.COLOR_TAB_NORMAL
|
||||||
|
|
||||||
|
@ -209,14 +209,14 @@ class MucTab(Tab):
|
||||||
"""
|
"""
|
||||||
Tab.__init__(self, stdscr, core)
|
Tab.__init__(self, stdscr, core)
|
||||||
self._room = room
|
self._room = room
|
||||||
self.topic_win = window.Topic(1, self.width, 0, 0, stdscr, self.visible)
|
self.topic_win = buffers.Topic(1, self.width, 0, 0, stdscr, self.visible)
|
||||||
self.text_win = window.TextWin(self.height-4-self.core.information_win_size, (self.width//10)*9, 1, 0, stdscr, self.visible)
|
self.text_win = buffers.TextWin(self.height-4-self.core.information_win_size, (self.width//10)*9, 1, 0, stdscr, self.visible)
|
||||||
self.v_separator = window.VerticalSeparator(self.height-3, 1, 1, 9*(self.width//10), stdscr, self.visible)
|
self.v_separator = buffers.VerticalSeparator(self.height-3, 1, 1, 9*(self.width//10), stdscr, self.visible)
|
||||||
self.user_win = window.UserList(self.height-3, (self.width//10), 1, 9*(self.width//10)+1, stdscr, self.visible)
|
self.user_win = buffers.UserList(self.height-3, (self.width//10), 1, 9*(self.width//10)+1, stdscr, self.visible)
|
||||||
self.info_header = window.MucInfoWin(1, (self.width//10)*9, self.height-3-self.core.information_win_size, 0, stdscr, self.visible)
|
self.info_header = buffers.MucInfoWin(1, (self.width//10)*9, self.height-3-self.core.information_win_size, 0, stdscr, self.visible)
|
||||||
self.info_win = window.TextWin(self.core.information_win_size, (self.width//10)*9, self.height-2-self.core.information_win_size, 0, stdscr, self.visible)
|
self.info_win = buffers.TextWin(self.core.information_win_size, (self.width//10)*9, self.height-2-self.core.information_win_size, 0, stdscr, self.visible)
|
||||||
self.tab_win = window.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
self.tab_win = buffers.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
||||||
self.input = window.MessageInput(1, self.width, self.height-1, 0, stdscr, self.visible)
|
self.input = buffers.MessageInput(1, self.width, self.height-1, 0, stdscr, self.visible)
|
||||||
|
|
||||||
def resize(self, stdscr):
|
def resize(self, stdscr):
|
||||||
"""
|
"""
|
||||||
|
@ -333,11 +333,11 @@ class PrivateTab(Tab):
|
||||||
def __init__(self, stdscr, core, room):
|
def __init__(self, stdscr, core, room):
|
||||||
Tab.__init__(self, stdscr, core)
|
Tab.__init__(self, stdscr, core)
|
||||||
self._room = room
|
self._room = room
|
||||||
self.text_win = window.TextWin(self.height-3-self.core.information_win_size, self.width, 0, 0, stdscr, self.visible)
|
self.text_win = buffers.TextWin(self.height-3-self.core.information_win_size, self.width, 0, 0, stdscr, self.visible)
|
||||||
self.info_header = window.PrivateInfoWin(1, self.width, self.height-3-self.core.information_win_size, 0, stdscr, self.visible)
|
self.info_header = buffers.PrivateInfoWin(1, self.width, self.height-3-self.core.information_win_size, 0, stdscr, self.visible)
|
||||||
self.info_win = window.TextWin(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, stdscr, self.visible)
|
self.info_win = buffers.TextWin(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, stdscr, self.visible)
|
||||||
self.tab_win = window.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
self.tab_win = buffers.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
||||||
self.input = window.MessageInput(1, self.width, self.height-1, 0, stdscr, self.visible)
|
self.input = buffers.MessageInput(1, self.width, self.height-1, 0, stdscr, self.visible)
|
||||||
|
|
||||||
def resize(self, stdscr):
|
def resize(self, stdscr):
|
||||||
Tab.resize(self, stdscr)
|
Tab.resize(self, stdscr)
|
||||||
|
@ -420,12 +420,12 @@ class RosterInfoTab(Tab):
|
||||||
self.name = "Roster"
|
self.name = "Roster"
|
||||||
roster_width = self.width//2
|
roster_width = self.width//2
|
||||||
info_width = self.width-roster_width-1
|
info_width = self.width-roster_width-1
|
||||||
self.v_separator = window.VerticalSeparator(self.height-2, 1, 0, roster_width, stdscr, self.visible)
|
self.v_separator = buffers.VerticalSeparator(self.height-2, 1, 0, roster_width, stdscr, self.visible)
|
||||||
self.tab_win = window.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
self.tab_win = buffers.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
||||||
self.info_win = window.TextWin(self.height-2, info_width, 0, roster_width+1, stdscr, self.visible)
|
self.info_win = buffers.TextWin(self.height-2, info_width, 0, roster_width+1, stdscr, self.visible)
|
||||||
self.roster_win = window.RosterWin(self.height-2-3, roster_width, 0, 0, stdscr, self.visible)
|
self.roster_win = buffers.RosterWin(self.height-2-3, roster_width, 0, 0, stdscr, self.visible)
|
||||||
self.contact_info_win = window.ContactInfoWin(3, roster_width, self.height-2-3, 0, stdscr, self.visible)
|
self.contact_info_win = buffers.ContactInfoWin(3, roster_width, self.height-2-3, 0, stdscr, self.visible)
|
||||||
self.default_help_message = window.HelpText(1, self.width, self.height-1, 0, stdscr, self.visible, "Enter commands with “/”. “o”: toggle offline show")
|
self.default_help_message = buffers.HelpText(1, self.width, self.height-1, 0, stdscr, self.visible, "Enter commands with “/”. “o”: toggle offline show")
|
||||||
self.input = self.default_help_message
|
self.input = self.default_help_message
|
||||||
self.set_color_state(theme.COLOR_TAB_NORMAL)
|
self.set_color_state(theme.COLOR_TAB_NORMAL)
|
||||||
|
|
||||||
|
@ -491,7 +491,7 @@ class RosterInfoTab(Tab):
|
||||||
'/' is pressed, we enter "input mode"
|
'/' is pressed, we enter "input mode"
|
||||||
"""
|
"""
|
||||||
curses.curs_set(1)
|
curses.curs_set(1)
|
||||||
self.input = window.CommandInput(1, self.width, self.height-1, 0, self.default_help_message, self.visible, "", self.reset_help_message, self.execute_slash_command)
|
self.input = buffers.CommandInput(1, self.width, self.height-1, 0, self.default_help_message, self.visible, "", self.reset_help_message, self.execute_slash_command)
|
||||||
self.input.do_command("/") # we add the slash
|
self.input.do_command("/") # we add the slash
|
||||||
|
|
||||||
def reset_help_message(self, _=None):
|
def reset_help_message(self, _=None):
|
||||||
|
@ -551,7 +551,7 @@ class RosterInfoTab(Tab):
|
||||||
in it.
|
in it.
|
||||||
"""
|
"""
|
||||||
curses.curs_set(1)
|
curses.curs_set(1)
|
||||||
self.input = window.CommandInput(1, self.width, self.height-1, 0, self.default_help_message, self.visible, "[Search]", self.on_search_terminate, self.on_search_terminate, self.set_roster_filter)
|
self.input = buffers.CommandInput(1, self.width, self.height-1, 0, self.default_help_message, self.visible, "[Search]", self.on_search_terminate, self.on_search_terminate, self.set_roster_filter)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def set_roster_filter(self, txt):
|
def set_roster_filter(self, txt):
|
||||||
|
@ -578,12 +578,12 @@ class ConversationTab(Tab):
|
||||||
self._text_buffer = text_buffer
|
self._text_buffer = text_buffer
|
||||||
self.color_state = theme.COLOR_TAB_NORMAL
|
self.color_state = theme.COLOR_TAB_NORMAL
|
||||||
self._name = jid # a conversation tab is linked to one specific full jid OR bare jid
|
self._name = jid # a conversation tab is linked to one specific full jid OR bare jid
|
||||||
self.text_win = window.TextWin(self.height-4-self.core.information_win_size, self.width, 1, 0, stdscr, self.visible)
|
self.text_win = buffers.TextWin(self.height-4-self.core.information_win_size, self.width, 1, 0, stdscr, self.visible)
|
||||||
self.upper_bar = window.ConversationStatusMessageWin(1, self.width, 0, 0, stdscr, self.visible)
|
self.upper_bar = buffers.ConversationStatusMessageWin(1, self.width, 0, 0, stdscr, self.visible)
|
||||||
self.info_header = window.ConversationInfoWin(1, self.width, self.height-3-self.core.information_win_size, 0, stdscr, self.visible)
|
self.info_header = buffers.ConversationInfoWin(1, self.width, self.height-3-self.core.information_win_size, 0, stdscr, self.visible)
|
||||||
self.info_win = window.TextWin(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, stdscr, self.visible)
|
self.info_win = buffers.TextWin(self.core.information_win_size, self.width, self.height-2-self.core.information_win_size, 0, stdscr, self.visible)
|
||||||
self.tab_win = window.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
self.tab_win = buffers.GlobalInfoBar(1, self.width, self.height-2, 0, stdscr, self.visible)
|
||||||
self.input = window.MessageInput(1, self.width, self.height-1, 0, stdscr, self.visible)
|
self.input = buffers.MessageInput(1, self.width, self.height-1, 0, stdscr, self.visible)
|
||||||
|
|
||||||
def resize(self, stdscr):
|
def resize(self, stdscr):
|
||||||
Tab.resize(self, stdscr)
|
Tab.resize(self, stdscr)
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Define the TextBuffer class
|
||||||
|
"""
|
||||||
|
|
||||||
from message import Message
|
from message import Message
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import theme
|
import theme
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
# along with Poezio. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Define the user class.
|
||||||
|
An user is a MUC participant, not a roster contact (see contact.py)
|
||||||
|
"""
|
||||||
|
|
||||||
from random import randrange, choice
|
from random import randrange, choice
|
||||||
from config import config
|
from config import config
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
|
@ -26,6 +31,7 @@ ROLE_DICT = {
|
||||||
'participant':2,
|
'participant':2,
|
||||||
'moderator':3
|
'moderator':3
|
||||||
}
|
}
|
||||||
|
|
||||||
class User(object):
|
class User(object):
|
||||||
"""
|
"""
|
||||||
keep trace of an user in a Room
|
keep trace of an user in a Room
|
||||||
|
|
Loading…
Reference in a new issue