Merge branch 'master' into plugins
Conflicts: src/core.py
This commit is contained in:
commit
8911f85a42
4 changed files with 50 additions and 50 deletions
16
src/core.py
16
src/core.py
|
@ -51,6 +51,7 @@ from text_buffer import TextBuffer
|
|||
from keyboard import read_char
|
||||
from theming import get_theme
|
||||
from fifo import Fifo
|
||||
from windows import g_lock
|
||||
|
||||
# http://xmpp.org/extensions/xep-0045.html#errorstatus
|
||||
ERROR_AND_STATUS_CODES = {
|
||||
|
@ -73,8 +74,6 @@ possible_show = {'available':None,
|
|||
'xa':'xa'
|
||||
}
|
||||
|
||||
resize_lock = threading.Lock()
|
||||
|
||||
Status = collections.namedtuple('Status', 'show message')
|
||||
|
||||
class Core(object):
|
||||
|
@ -208,18 +207,21 @@ class Core(object):
|
|||
'Just press Ctrl-n.' \
|
||||
))
|
||||
self.refresh_window()
|
||||
|
||||
def resize_global_information_win(self):
|
||||
"""
|
||||
Resize the global_information_win only once at each resize.
|
||||
"""
|
||||
self.information_win.resize(self.information_win_size, tabs.Tab.width,
|
||||
tabs.Tab.height - 2 - self.information_win_size, 0)
|
||||
with g_lock:
|
||||
self.information_win.resize(self.information_win_size, tabs.Tab.width,
|
||||
tabs.Tab.height - 2 - self.information_win_size, 0)
|
||||
|
||||
def resize_global_info_bar(self):
|
||||
"""
|
||||
Resize the GlobalInfoBar only once at each resize
|
||||
"""
|
||||
self.tab_win.resize(1, tabs.Tab.width, tabs.Tab.height - 2, 0)
|
||||
with g_lock:
|
||||
self.tab_win.resize(1, tabs.Tab.width, tabs.Tab.height - 2, 0)
|
||||
|
||||
def on_exception(self, typ, value, trace):
|
||||
"""
|
||||
|
@ -559,7 +561,7 @@ class Core(object):
|
|||
if not body:
|
||||
return
|
||||
tab.add_message(body, time=None, nickname=nick_from,
|
||||
forced_user=self.get_tab_by_name(room_from, tabs.MucTab).get_user_by_name(nick_from))
|
||||
forced_user=self.get_tab_by_name(room_from, tabs.MucTab).get_user_by_name(nick_from))
|
||||
conversation = self.get_tab_by_name(jid.full, tabs.PrivateTab)
|
||||
if conversation and conversation.remote_wants_chatstates is None:
|
||||
if message['chat_state']:
|
||||
|
@ -706,7 +708,7 @@ class Core(object):
|
|||
tabs.Tab.resize(self.stdscr)
|
||||
self.resize_global_information_win()
|
||||
self.resize_global_info_bar()
|
||||
with resize_lock:
|
||||
with g_lock:
|
||||
for tab in self.tabs:
|
||||
if config.get('lazy_resize', 'true') == 'true':
|
||||
tab.need_resize = True
|
||||
|
|
22
src/tabs.py
22
src/tabs.py
|
@ -305,7 +305,7 @@ class ChatTab(Tab):
|
|||
# build the list of the recent words
|
||||
char_we_dont_want = string.punctuation+' '
|
||||
words = list()
|
||||
for msg in self.messages[:-40:-1]:
|
||||
for msg in self._text_buffer.messages[:-40:-1]:
|
||||
if not msg:
|
||||
continue
|
||||
txt = xhtml.clean_text(msg.txt)
|
||||
|
@ -497,7 +497,7 @@ class MucTab(ChatTab):
|
|||
"""
|
||||
/clear
|
||||
"""
|
||||
self.messages = []
|
||||
self._text_buffer.messages = []
|
||||
self.text_win.rebuild_everything(self._text_buffer)
|
||||
self.refresh()
|
||||
self.core.doupdate()
|
||||
|
@ -1218,7 +1218,7 @@ class PrivateTab(ChatTab):
|
|||
msg['chat_state'] = needed
|
||||
self.core.events.trigger('private_say', msg)
|
||||
msg.send()
|
||||
self.core.add_message_to_text_buffer(self._text_buffer, line, None, self.core.own_nick or self.own_nick)
|
||||
self.core.add_message_to_text_buffer(self._text_buffer, xhtml.convert_simple_to_full_colors(line), None, self.core.own_nick or self.own_nick)
|
||||
self.cancel_paused_delay()
|
||||
self.text_win.refresh()
|
||||
self.input.refresh()
|
||||
|
@ -1580,7 +1580,6 @@ class RosterInfoTab(Tab):
|
|||
self.command_add(jid.lstrip('\n'))
|
||||
self.core.information('Contacts imported from %s' % filepath, 'Info')
|
||||
|
||||
|
||||
def command_export(self, arg):
|
||||
"""
|
||||
Export the contacts
|
||||
|
@ -1864,6 +1863,7 @@ class ConversationTab(ChatTab):
|
|||
self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: close the tab"), None)
|
||||
self.commands['close'] = (self.command_unquery, _("Usage: /close\Close: close the tab"), None)
|
||||
self.commands['version'] = (self.command_version, _('Usage: /version\nVersion: get the software version of the current interlocutor (usually its XMPP client and Operating System)'), None)
|
||||
self.commands['info'] = (self.command_info, _('Usage: /info\nInfo: get the status of the contact.'), None)
|
||||
self.resize()
|
||||
|
||||
def completion(self):
|
||||
|
@ -1882,12 +1882,24 @@ class ConversationTab(ChatTab):
|
|||
msg['chat_state'] = needed
|
||||
self.core.events.trigger('conversation_say', msg)
|
||||
msg.send()
|
||||
self.core.add_message_to_text_buffer(self._text_buffer, line, None, self.core.own_nick)
|
||||
self.core.add_message_to_text_buffer(self._text_buffer, xhtml.convert_simple_to_full_colors(line), None, self.core.own_nick)
|
||||
logger.log_message(JID(self.get_name()).bare, self.core.own_nick, line)
|
||||
self.cancel_paused_delay()
|
||||
self.text_win.refresh()
|
||||
self.input.refresh()
|
||||
|
||||
def command_info(self, arg):
|
||||
contact = roster.get_contact_by_jid(self.get_name())
|
||||
jid = JID(self.get_name())
|
||||
if jid.resource:
|
||||
resource = contact.get_resource_by_fulljid(jid.full)
|
||||
else:
|
||||
resource = contact.get_highest_priority_resource()
|
||||
if resource:
|
||||
self._text_buffer.add_message("\x195}Status: %s\x193}" %resource.get_status(), None, None, None, None, None)
|
||||
self.refresh()
|
||||
self.core.doupdate()
|
||||
|
||||
def command_unquery(self, arg):
|
||||
self.core.close_tab()
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import curses
|
|||
import string
|
||||
from config import config
|
||||
|
||||
from threading import Lock
|
||||
from threading import RLock
|
||||
|
||||
from contact import Contact, Resource
|
||||
from roster import RosterGroup, roster
|
||||
|
@ -46,7 +46,7 @@ allowed_color_digits = ('0', '1', '2', '3', '4', '5', '6', '7')
|
|||
# first is a bool telling if this is the first line of the message.
|
||||
Line = collections.namedtuple('Line', 'msg start_pos end_pos')
|
||||
|
||||
g_lock = Lock()
|
||||
g_lock = RLock()
|
||||
|
||||
LINES_NB_LIMIT = 4096
|
||||
|
||||
|
@ -79,7 +79,8 @@ class Win(object):
|
|||
"""
|
||||
Override if something has to be done on resize
|
||||
"""
|
||||
self._resize(height, width, y, x)
|
||||
with g_lock:
|
||||
self._resize(height, width, y, x)
|
||||
|
||||
def _refresh(self):
|
||||
self._win.noutrefresh()
|
||||
|
@ -255,10 +256,11 @@ class UserList(Win):
|
|||
self._refresh()
|
||||
|
||||
def resize(self, height, width, y, x):
|
||||
self._resize(height, width, y, x)
|
||||
self._win.attron(to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR))
|
||||
self._win.vline(0, 0, curses.ACS_VLINE, self.height)
|
||||
self._win.attroff(to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR))
|
||||
with g_lock:
|
||||
self._resize(height, width, y, x)
|
||||
self._win.attron(to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR))
|
||||
self._win.vline(0, 0, curses.ACS_VLINE, self.height)
|
||||
self._win.attroff(to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR))
|
||||
|
||||
class Topic(Win):
|
||||
def __init__(self):
|
||||
|
@ -674,9 +676,10 @@ class TextWin(Win):
|
|||
self.addstr(' ')
|
||||
|
||||
def resize(self, height, width, y, x, room=None):
|
||||
self._resize(height, width, y, x)
|
||||
if room:
|
||||
self.rebuild_everything(room)
|
||||
with g_lock:
|
||||
self._resize(height, width, y, x)
|
||||
if room:
|
||||
self.rebuild_everything(room)
|
||||
|
||||
def rebuild_everything(self, room):
|
||||
self.built_lines = []
|
||||
|
|
39
src/xhtml.py
39
src/xhtml.py
|
@ -178,6 +178,8 @@ whitespace_re = re.compile(r'\s+')
|
|||
|
||||
xhtml_attr_re = re.compile(r'\x19\d{0,3}\}|\x19[buaio]')
|
||||
|
||||
xhtml_simple_attr_re = re.compile(r'\x19\d')
|
||||
|
||||
def get_body_from_message_stanza(message):
|
||||
"""
|
||||
Returns a string with xhtml markups converted to
|
||||
|
@ -342,6 +344,15 @@ def clean_text_simple(string):
|
|||
pos = string.find('\x19')
|
||||
return string
|
||||
|
||||
def convert_simple_to_full_colors(text):
|
||||
"""
|
||||
takes a \x19n formatted string and returns
|
||||
a \x19n} formatted one.
|
||||
"""
|
||||
def add_curly_bracket(match):
|
||||
return match.group(0) + '}'
|
||||
return re.sub(xhtml_simple_attr_re, add_curly_bracket, text)
|
||||
|
||||
number_to_color_names = {
|
||||
1: 'red',
|
||||
2: 'green',
|
||||
|
@ -394,31 +405,3 @@ def poezio_colors_to_html(string):
|
|||
res += '</%s>' % (elem,)
|
||||
res += "</p></body>"
|
||||
return res.replace('\n', '<br />')
|
||||
|
||||
def poezio_colors_to_xhtml(string):
|
||||
"""
|
||||
Generate a valid xhtml string from
|
||||
the poezio colors in the given string
|
||||
"""
|
||||
res = "<body xmlns='http://www.w3.org/1999/xhtml'>"
|
||||
next_attr_char = string.find('\x19')
|
||||
open_elements = []
|
||||
while next_attr_char != -1:
|
||||
attr_char = string[next_attr_char+1].lower()
|
||||
if next_attr_char != 0:
|
||||
res += string[:next_attr_char]
|
||||
string = string[next_attr_char+2:]
|
||||
if attr_char == 'o':
|
||||
# close all opened elements
|
||||
for elem in open_elements:
|
||||
res += '</%s>'
|
||||
open_elements = []
|
||||
elif attr_char == 'b':
|
||||
if 'strong' not in open_elements:
|
||||
res += '<strong>'
|
||||
open_elements.append('strong')
|
||||
elif attr_char in digits:
|
||||
self._win.attron(common.curses_color_pair(int(attr_char)))
|
||||
next_attr_char = string.find('\x19')
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue