From c3c67b5e0afec8b322b8f08aa76b8e35c24bc23b Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 6 Nov 2011 21:10:09 +0100 Subject: [PATCH 01/17] =?UTF-8?q?Code=20cleanup=20(unused=20import,=20vari?= =?UTF-8?q?ables,=20undefined=20names,=20etc=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common.py | 1 - src/connection.py | 1 - src/core.py | 6 +----- src/keyboard.py | 2 -- src/logger.py | 1 - src/multiuserchat.py | 2 -- src/roster.py | 2 +- src/tabs.py | 9 ++++----- src/user.py | 5 +---- src/windows.py | 11 +++-------- 10 files changed, 10 insertions(+), 30 deletions(-) diff --git a/src/common.py b/src/common.py index 11a09b93..7e1c0642 100644 --- a/src/common.py +++ b/src/common.py @@ -15,7 +15,6 @@ import os import mimetypes import hashlib import subprocess -import curses import time import shlex diff --git a/src/connection.py b/src/connection.py index 7246ae1e..f407dfe9 100644 --- a/src/connection.py +++ b/src/connection.py @@ -15,7 +15,6 @@ log = logging.getLogger(__name__) from gettext import (bindtextdomain, textdomain, bind_textdomain_codeset, gettext as _) -import sys import getpass import sleekxmpp diff --git a/src/core.py b/src/core.py index dd320022..30935330 100644 --- a/src/core.py +++ b/src/core.py @@ -8,7 +8,6 @@ from gettext import gettext as _ import os -import re import sys import time import curses @@ -39,8 +38,7 @@ import timed_events from data_forms import DataFormsTab from config import config, options from logger import logger -from user import User -from roster import Roster, RosterGroup, roster +from roster import roster from contact import Contact, Resource from text_buffer import TextBuffer from keyboard import read_char @@ -1237,7 +1235,6 @@ class Core(object): the_input.auto_completion(items, '') else: # we are writing the server: complete the server - serv = jid.server serv_list = [] for tab in self.tabs: if isinstance(tab, tabs.MucTab): @@ -1246,7 +1243,6 @@ class Core(object): return True def completion_list(self, the_input): - txt = the_input.get_text() muc_serv_list = [] for tab in self.tabs: # TODO, also from an history if isinstance(tab, tabs.MucTab) and\ diff --git a/src/keyboard.py b/src/keyboard.py index 99173f40..c8f4b60c 100644 --- a/src/keyboard.py +++ b/src/keyboard.py @@ -12,8 +12,6 @@ of the time ONE char, but may be longer if it's a keyboard shortcut, like ^A, M-a or KEY_RESIZE) """ -import time - def get_next_byte(s): """ Read the next byte of the utf-8 char diff --git a/src/logger.py b/src/logger.py index e8a29a3f..bd24eb3b 100644 --- a/src/logger.py +++ b/src/logger.py @@ -5,7 +5,6 @@ # Poezio is free software: you can redistribute it and/or modify # it under the terms of the zlib license. See the COPYING file. -import sys from os import environ, makedirs import os from datetime import datetime diff --git a/src/multiuserchat.py b/src/multiuserchat.py index ac910837..0527c1ed 100644 --- a/src/multiuserchat.py +++ b/src/multiuserchat.py @@ -11,8 +11,6 @@ Add some facilities that are not available on the XEP_0045 sleek plugin """ -import sleekxmpp - from xml.etree import cElementTree as ET import logging diff --git a/src/roster.py b/src/roster.py index 4ef2da1b..df84d4d8 100644 --- a/src/roster.py +++ b/src/roster.py @@ -14,7 +14,7 @@ log = logging.getLogger(__name__) from config import config from os import path as p -from contact import Contact, Resource +from contact import Contact from sleekxmpp.xmlstream.stanzabase import JID class Roster(object): diff --git a/src/tabs.py b/src/tabs.py index afc93a9d..71063007 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -24,7 +24,6 @@ from gettext import gettext as _ import windows import curses import difflib -import text_buffer import string import common import core @@ -40,7 +39,7 @@ from theming import get_theme from sleekxmpp.xmlstream.stanzabase import JID from config import config from roster import RosterGroup, roster -from contact import Contact, Resource +from contact import Contact from text_buffer import TextBuffer from user import User from os import getenv, path @@ -565,9 +564,9 @@ class MucTab(ChatTab): """ args = arg.split() if len(args): - msg = ' '.join(args) + arg = ' '.join(args) else: - msg = None + arg = None if self.joined: muc.leave_groupchat(self.core.xmpp, self.name, self.own_nick, arg) self.add_message(_("\x195}You left the chatroom\x193}")) @@ -932,7 +931,7 @@ class MucTab(ChatTab): self.add_message('\x194}%(spec)s \x19%(color)d}%(nick)s\x195} joined the room' % {'nick':from_nick, 'color':color, 'spec':get_theme().CHAR_JOIN}) else: self.add_message('\x194}%(spec)s \x19%(color)d}%(nick)s \x195}(\x194}%(jid)s\x195}) joined the room' % {'spec':get_theme().CHAR_JOIN, 'nick':from_nick, 'color':color, 'jid':jid.full}) - self.core.on_user_rejoined_private_conversation(room.name, from_nick) + self.core.on_user_rejoined_private_conversation(self.name, from_nick) def on_user_nick_change(self, presence, user, from_nick, from_room): new_nick = presence.find('{%s}x/{%s}item' % (NS_MUC_USER, NS_MUC_USER)).attrib['nick'] diff --git a/src/user.py b/src/user.py index 5867e1f3..0d29569f 100644 --- a/src/user.py +++ b/src/user.py @@ -10,10 +10,7 @@ Define the user class. An user is a MUC participant, not a roster contact (see contact.py) """ -import curses - -from random import randrange, choice -from config import config +from random import choice from datetime import timedelta, datetime from theming import get_theme diff --git a/src/windows.py b/src/windows.py index 790dd858..612f78ec 100644 --- a/src/windows.py +++ b/src/windows.py @@ -14,26 +14,23 @@ A Tab (see tab.py) is composed of multiple Windows from gettext import (bindtextdomain, textdomain, bind_textdomain_codeset, gettext as _) -from os.path import isfile import logging log = logging.getLogger(__name__) -import shlex import curses import string from config import config from threading import RLock -from contact import Contact, Resource -from roster import RosterGroup, roster +from contact import Contact +from roster import RosterGroup from poopt import cut_text from sleekxmpp.xmlstream.stanzabase import JID import core -import common import wcwidth import singleton import collections @@ -1471,11 +1468,9 @@ class RosterWin(Win): if not resource: # There's no online resource presence = 'unavailable' - folder = ' ' nb = '' else: presence = resource.get_presence() - folder = '[+]' if contact._folded else '[-]' nb = ' (%s)' % (contact.get_nb_resources(),) color = RosterWin.color_show[presence] if contact.get_name(): @@ -1519,11 +1514,11 @@ class ContactInfoWin(Win): """ draw the contact information """ + resource = contact.get_highest_priority_resource() if contact: jid = contact.get_bare_jid() else: jid = jid or resource.get_jid().full - resource = contact.get_highest_priority_resource() if resource: presence = resource.get_presence() else: From 14c05b2deeaeb56c1f14dcfeecfcfff2a67fe835 Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 6 Nov 2011 21:22:59 +0100 Subject: [PATCH 02/17] Make private join/parts work properly --- src/tabs.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tabs.py b/src/tabs.py index 71063007..e40a8f05 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1345,12 +1345,12 @@ class PrivateTab(ChatTab): """ self.activate() tab = self.core.get_tab_by_name(JID(self.name).bare, MucTab) - color = None - if tab: + color = 3 + if tab and config.get('display_user_color_in_join_part', ''): user = tab.get_user_by_name(nick) if user: - color = user.color - self.add_message('\x194}%(spec)s \x19%(color)d}%(nick)s\x195} joined the room' % {'nick':nick, 'color': color or 3, 'spec':get_theme().CHAR_JOIN}) + color = user.color[0] + self.add_message('\x194}%(spec)s \x19%(color)d}%(nick)s\x195} joined the room' % {'nick':nick, 'color': color, 'spec':get_theme().CHAR_JOIN}) if self.core.current_tab() is self: self.refresh() self.core.doupdate() From 78174a6eae75e14295e501563d7744401d2f4e11 Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 7 Nov 2011 13:47:23 +0100 Subject: [PATCH 03/17] Move a space (for perfectionnists) --- src/windows.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/windows.py b/src/windows.py index 612f78ec..f399d940 100644 --- a/src/windows.py +++ b/src/windows.py @@ -1527,10 +1527,11 @@ class ContactInfoWin(Win): self.finish_line(get_theme().COLOR_INFORMATION_BAR) self.addstr(1, 0, 'Subscription: %s' % (contact.get_subscription(),)) if contact.get_ask(): + self.addstr(' ') if contact.get_ask() == 'asked': - self.addstr(' Ask: %s' % (contact.get_ask(),), to_curses_attr(get_theme().COLOR_HIGHLIGHT_NICK)) + self.addstr('Ask: %s' % (contact.get_ask(),), to_curses_attr(get_theme().COLOR_HIGHLIGHT_NICK)) else: - self.addstr(' Ask: %s' % (contact.get_ask(),)) + self.addstr('Ask: %s' % (contact.get_ask(),)) self.finish_line() From 10fe12086d1dceab3d3796938aa0414877e79e63 Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 7 Nov 2011 14:33:37 +0100 Subject: [PATCH 04/17] =?UTF-8?q?Fix=20subscriptions=20(/add=20=E2=86=92?= =?UTF-8?q?=20/accept=20instead=20of=20/add=20=E2=86=92=20/accept=20?= =?UTF-8?q?=E2=86=92=20/accept)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tabs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tabs.py b/src/tabs.py index e40a8f05..9f37190a 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1448,6 +1448,7 @@ class RosterInfoTab(Tab): self.core.information(_('No JID specified'), 'Error') return self.core.xmpp.sendPresence(pto=jid, ptype='subscribe') + self.core.xmpp.sendPresence(pto=jid, ptype='subscribed') def command_name(self, args): """ @@ -1675,7 +1676,6 @@ class RosterInfoTab(Tab): else: jid = args[0] self.core.xmpp.sendPresence(pto=jid, ptype='subscribed') - self.core.xmpp.sendPresence(pto=jid, ptype='subscribe') def refresh(self): if self.need_resize: From 70a809a7b4e5c4585b31e7ed023ae0b91d65c7a4 Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 7 Nov 2011 19:28:12 +0100 Subject: [PATCH 05/17] Refresh the RosterInfoTab on got_offline and got_online --- src/core.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core.py b/src/core.py index 30935330..9a36b370 100644 --- a/src/core.py +++ b/src/core.py @@ -361,6 +361,8 @@ class Core(object): if not contact.get_highest_priority_resource(): # No resource left: that was the last one self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x191}offline' % (jid.bare)) self.information('\x193}%s \x195}is \x191}offline' % (resource.get_jid().bare), "Roster") + if isinstance(self.current_tab(), tabs.RosterInfoTab): + self.refresh_window() def on_got_online(self, presence): jid = presence['from'] @@ -386,6 +388,8 @@ class Core(object): self.information("\x193}%s \x195}is \x194}online\x195} (\x190}%s\x195})" % (resource.get_jid().bare, status), "Roster") self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x194}online' % (jid.bare)) contact.add_resource(resource) + if isinstance(self.current_tab(), tabs.RosterInfoTab): + self.refresh_window() def add_information_message_to_conversation_tab(self, jid, msg): """ From 153137e5d2e610afa4a7ca0ce2e3855ff1dec253 Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 7 Nov 2011 19:38:37 +0100 Subject: [PATCH 06/17] Removed "WARNING" debug messages, because they are irrelevant --- src/multiuserchat.py | 2 +- src/tabs.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/multiuserchat.py b/src/multiuserchat.py index 0527c1ed..f537c2c1 100644 --- a/src/multiuserchat.py +++ b/src/multiuserchat.py @@ -66,7 +66,7 @@ def leave_groupchat(xmpp, jid, own_nick, msg): try: xmpp.plugin['xep_0045'].leaveMUC(jid, own_nick, msg) except KeyError: - log.debug("WARNING: in muc.leave_groupchat: could not leave the room") + log.debug("muc.leave_groupchat: could not leave the room %s" % jid) def set_user_role(xmpp, jid, nick, reason, role): """ diff --git a/src/tabs.py b/src/tabs.py index 9f37190a..f80abdf7 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -118,13 +118,12 @@ class Tab(object): @state.setter def state(self, value): if not value in STATE_COLORS: - log.debug("WARNING: invalid value for tab state") - return + log.debug("Invalid value for tab state: %s" % value) elif STATE_PRIORITY[value] < STATE_PRIORITY[self._state] and \ value != 'current': - log.debug("WARNING: did not set status because of lower priority") - return - self._state = value + log.debug("Did not set status because of lower priority, asked: %s, kept: %s" % (value, self.state)) + else: + self._state = value @staticmethod def resize(scr): From 7e78353621f530cdfa0c5280386512aa40a36048 Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 7 Nov 2011 19:56:59 +0100 Subject: [PATCH 07/17] Add a warning in case of theme not found, and now unsetting 'theme', setting it to 'default' or a number of spaces has the same effect --- src/core.py | 4 +++- src/theming.py | 11 ++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/core.py b/src/core.py index 9a36b370..481fb1c2 100644 --- a/src/core.py +++ b/src/core.py @@ -1172,7 +1172,9 @@ class Core(object): self.xmpp.plugin['xep_0030'].get_items(jid=server, block=False, callback=list_tab.on_muc_list_item_received) def command_theme(self, arg): - theming.reload_theme() + warning = theming.reload_theme() + if warning: + self.information(warning, 'Warning') self.refresh_window() def command_win(self, arg): diff --git a/src/theming.py b/src/theming.py index 4bfdad42..0a7ab22d 100644 --- a/src/theming.py +++ b/src/theming.py @@ -240,16 +240,17 @@ def reload_theme(): os.makedirs(themes_dir) except OSError: pass - theme_name = config.get('theme', '') - if not theme_name: + theme_name = config.get('theme', 'default') + global theme + if theme_name == 'default' or not theme_name.strip(): + theme = Theme() return try: file_path = os.path.join(themes_dir, theme_name)+'.py' log.debug('Theme file to load: %s' %(file_path,)) new_theme = imp.load_source('theme', os.path.join(themes_dir, theme_name)+'.py') - except: # TODO warning: theme not found - return - global theme + except: + return 'Theme not found' theme = new_theme.theme if __name__ == '__main__': From 27f28f26243c2310dcfd3540e2b736a634b48faf Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 7 Nov 2011 23:07:32 +0100 Subject: [PATCH 08/17] Display actual status message on contact connection instead of unreadable status type --- src/core.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core.py b/src/core.py index 481fb1c2..a9c97022 100644 --- a/src/core.py +++ b/src/core.py @@ -385,7 +385,10 @@ class Core(object): # No connected resource yet: the user's just connecting if time.time() - self.connection_time > 12: # We do not display messages if we recently logged in - self.information("\x193}%s \x195}is \x194}online\x195} (\x190}%s\x195})" % (resource.get_jid().bare, status), "Roster") + if status_message: + self.information("\x193}%s \x195}is \x194}online\x195} (\x19o%s\x195})" % (resource.get_jid().bare, status_message), "Roster") + else: + self.information("\x193}%s \x195}is \x194}online\x195}" % resource.get_jid().bare, "Roster") self.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x194}online' % (jid.bare)) contact.add_resource(resource) if isinstance(self.current_tab(), tabs.RosterInfoTab): From 2c9cbc9f58cd167ba6a77932a57f50ca219b60a8 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 7 Nov 2011 19:54:12 +0100 Subject: [PATCH 09/17] avoid a crash on invalid colors (cherry picked from commit 15780364cf13de0bd4c2a40d895fe77273f00ab9) --- src/windows.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/windows.py b/src/windows.py index f399d940..9fa3e705 100644 --- a/src/windows.py +++ b/src/windows.py @@ -135,7 +135,8 @@ class Win(object): self._win.attron(curses.A_BOLD) if attr_char in string.digits and attr_char != '': color_str = text[next_attr_char+1:text.find('}', next_attr_char)] - self._win.attron(to_curses_attr((int(color_str), -1))) + if color_str: + self._win.attron(to_curses_attr((int(color_str), -1))) text = text[next_attr_char+len(color_str)+2:] else: text = text[next_attr_char+2:] From f271ef0620ab91573bfebb196ef5db54296bab4b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 7 Nov 2011 19:43:13 +0100 Subject: [PATCH 10/17] Add a function to convert ncurses colors to HTML color code. (cherry picked from commit 04f103b9e67ccd1de7376be4f7b5156ec425e99c) --- src/xhtml.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/xhtml.py b/src/xhtml.py index f6487905..2cedba7d 100644 --- a/src/xhtml.py +++ b/src/xhtml.py @@ -14,6 +14,7 @@ poezio colors to xhtml code import re import subprocess +import curses from sleekxmpp.xmlstream import ET from xml.etree.ElementTree import ElementTree from sys import version_info @@ -192,6 +193,29 @@ def get_body_from_message_stanza(message): return xhtml_to_poezio_colors(xhtml_body) return message['body'] +def ncurses_color_to_html(color): + """ + Takes an int between 0 and 256 and returns + a string of the form #XXXXXX representing an + html color. + """ + if color <= 15: + (r, g, b) = curses.color_content(color) + r = r / 1000 * 6 + g = g / 1000 * 6 + b = b / 1000 * 6 + elif color <= 231: + color = color - 16 + r = color % 6 + color = color / 6 + g = color % 6 + color = color / 6 + b = color % 6 + else: + color -= 232 + r = g = b = color / 24 * 6 + return '#%X%X%X' % (r*256/6, g*256/6, b*256/6) + def xhtml_to_poezio_colors(text): def parse_css(css): def get_color(value): @@ -324,7 +348,6 @@ def xhtml_to_poezio_colors(text): message += trim(elem.tail) return message - def clean_text(s): """ Remove all xhtml-im attributes (\x19etc) from the string with the From 24043586893ecfa599379c15fd7ae5fa531d2a14 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 7 Nov 2011 19:55:16 +0100 Subject: [PATCH 11/17] Fix the curses -> html color conversion (cherry picked from commit 689f17cfd79b152d3ca75e570f9f13f70aa6c425) --- src/xhtml.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xhtml.py b/src/xhtml.py index 2cedba7d..748c9080 100644 --- a/src/xhtml.py +++ b/src/xhtml.py @@ -201,9 +201,9 @@ def ncurses_color_to_html(color): """ if color <= 15: (r, g, b) = curses.color_content(color) - r = r / 1000 * 6 - g = g / 1000 * 6 - b = b / 1000 * 6 + r = r / 1000 * 6 - 0.01 + g = g / 1000 * 6 - 0.01 + b = b / 1000 * 6 - 0.01 elif color <= 231: color = color - 16 r = color % 6 @@ -214,7 +214,7 @@ def ncurses_color_to_html(color): else: color -= 232 r = g = b = color / 24 * 6 - return '#%X%X%X' % (r*256/6, g*256/6, b*256/6) + return '#%02X%02X%02X' % (r*256/6, g*256/6, b*256/6) def xhtml_to_poezio_colors(text): def parse_css(css): From f13d03c149a94a8316b9acb5944454357a395636 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 7 Nov 2011 19:56:03 +0100 Subject: [PATCH 12/17] poezio_colors_to_html now takes full colors (\x19xxx}) to generate the xhtml code (cherry picked from commit 2b9a43ce6a5fa6ad93ab570a99d4d92337a40110) --- src/xhtml.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/xhtml.py b/src/xhtml.py index 748c9080..5eda635b 100644 --- a/src/xhtml.py +++ b/src/xhtml.py @@ -402,7 +402,6 @@ def poezio_colors_to_html(string): 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': for elem in opened_elements[::-1]: res += '' % (elem,) @@ -411,17 +410,20 @@ def poezio_colors_to_html(string): if 'strong' not in opened_elements: opened_elements.append('strong') res += '' - elif attr_char in digits: - number = int(attr_char) - if number in number_to_color_names: - if 'strong' in opened_elements: - res += '' - opened_elements.remove('strong') - if 'span' in opened_elements: - res += '' - else: - opened_elements.append('span') - res += "" % (number_to_color_names[number]) + if attr_char in digits: + number_str = string[next_attr_char+1:string.find('}', next_attr_char)] + number = int(number_str) + if 'strong' in opened_elements: + res += '' + opened_elements.remove('strong') + if 'span' in opened_elements: + res += '' + else: + opened_elements.append('span') + res += "" % (ncurses_color_to_html(number),) + string = string[next_attr_char+len(number_str)+2:] + else: + string = string[next_attr_char+2:] next_attr_char = string.find('\x19') res += string for elem in opened_elements[::-1]: From 4610a1d6e3de68cedb2cd61d270b92ec714c44c7 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 8 Nov 2011 00:19:31 +0100 Subject: [PATCH 13/17] trigger events *_say BEFORE generating the xhtml, making it possible to add colors in the hook Conflicts: src/tabs.py --- src/tabs.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/tabs.py b/src/tabs.py index f80abdf7..506d1de9 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -710,11 +710,10 @@ class MucTab(ChatTab): needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg = self.core.xmpp.make_message(self.get_name()) msg['type'] = 'groupchat' - if line.find('\x19') == -1: - msg['body'] = line - else: - msg['body'] = xhtml.clean_text_simple(line) - msg['xhtml_im'] = xhtml.poezio_colors_to_html(line) + msg['body'] = line + if msg['body'].find('\x19') != -1: + msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) + msg['body'] = xhtml.clean_text(msg['body']) if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: msg['chat_state'] = needed self.cancel_paused_delay() @@ -1202,11 +1201,10 @@ class PrivateTab(ChatTab): return msg = self.core.xmpp.make_message(self.get_name()) msg['type'] = 'chat' - if line.find('\x19') == -1: - msg['body'] = line - else: - msg['body'] = xhtml.clean_text_simple(line) - msg['xhtml_im'] = xhtml.poezio_colors_to_html(line) + msg['body'] = line + if msg['body'].find('\x19') != -1: + msg['body'] = xhtml.clean_text(msg['body']) + msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed @@ -1865,11 +1863,10 @@ class ConversationTab(ChatTab): def command_say(self, line): msg = self.core.xmpp.make_message(self.get_name()) msg['type'] = 'chat' - if line.find('\x19') == -1: - msg['body'] = line - else: - msg['body'] = xhtml.clean_text_simple(line) - msg['xhtml_im'] = xhtml.poezio_colors_to_html(line) + msg['body'] = line + if msg['body'].find('\x19') != -1: + msg['body'] = xhtml.clean_text(msg['body']) + msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed From 52599f9b8cbd37e922d959e482521a4e16121582 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 7 Nov 2011 19:47:16 +0100 Subject: [PATCH 14/17] use only full color mode when sending messages. Simple color mode should never be used in any part of the code except inside the input. (cherry picked from commit 17e5411d8f050a3c5e5bcd010551eecac96b5911) Conflicts: src/tabs.py --- src/tabs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tabs.py b/src/tabs.py index 506d1de9..08105a58 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -321,7 +321,7 @@ class ChatTab(Tab): if not self.execute_command(clean_text): if txt.startswith('//'): txt = txt[1:] - self.command_say(txt) + self.command_say(xhtml.convert_simple_to_full_colors(txt)) self.cancel_paused_delay() def send_chat_state(self, state, always_send=False): @@ -596,7 +596,7 @@ class MucTab(ChatTab): r = self.core.open_private_window(self.name, user.nick) if r and len(args) > 1: msg = arg[len(nick)+1:] - self.core.current_tab().command_say(msg) + self.core.current_tab().command_say(xhtml.convert_simple_to_full_colors(msg)) if not r: self.core.information(_("Cannot find user: %s" % nick), 'Error') From 9c5cab09d40d45a115a233ba17cec4387c63c893 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 8 Nov 2011 00:41:32 +0100 Subject: [PATCH 15/17] =?UTF-8?q?fix=20the=20last=20errors=20that=20are=20?= =?UTF-8?q?in=20another=20commit=20that=20I=20don=E2=80=99t=20want=20to=20?= =?UTF-8?q?cherry-pick.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tabs.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tabs.py b/src/tabs.py index 08105a58..5d7f2286 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -1202,14 +1202,14 @@ class PrivateTab(ChatTab): msg = self.core.xmpp.make_message(self.get_name()) msg['type'] = 'chat' msg['body'] = line + self.core.add_message_to_text_buffer(self._text_buffer, msg['body'], None, self.core.own_nick or self.own_nick) if msg['body'].find('\x19') != -1: - msg['body'] = xhtml.clean_text(msg['body']) msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) + msg['body'] = xhtml.clean_text(msg['body']) if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed msg.send() - 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() @@ -1864,14 +1864,14 @@ class ConversationTab(ChatTab): msg = self.core.xmpp.make_message(self.get_name()) msg['type'] = 'chat' msg['body'] = line + self.core.add_message_to_text_buffer(self._text_buffer, msg['body'], None, self.core.own_nick) if msg['body'].find('\x19') != -1: - msg['body'] = xhtml.clean_text(msg['body']) msg['xhtml_im'] = xhtml.poezio_colors_to_html(msg['body']) + msg['body'] = xhtml.clean_text(msg['body']) if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates is not False: needed = 'inactive' if self.core.status.show in ('xa', 'away') else 'active' msg['chat_state'] = needed msg.send() - 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() From 1ccfd09552a3ee6fa1feb4181bccf862ca21417e Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 8 Nov 2011 01:52:39 +0100 Subject: [PATCH 16/17] poopt now handles correctly the size of the chars by jumping the color attributes properly and ignoring their length. --- src/pooptmodule.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/pooptmodule.c b/src/pooptmodule.c index b696fe4e..8a021379 100644 --- a/src/pooptmodule.c +++ b/src/pooptmodule.c @@ -44,6 +44,8 @@ static PyObject *poopt_cut_text(PyObject *self, PyObject *args) int last_space = -1; int start_pos = 0; + int w = width; /* this is a width that increases to make the length of char + of colors attribute be ignored */ PyObject* retlist = PyList_New(0); while (buffer[bpos]) @@ -57,7 +59,7 @@ static PyObject *poopt_cut_text(PyObject *self, PyObject *args) start_pos = spos + 1; last_space = -1; } - else if ((spos - start_pos) >= width) + else if ((spos - start_pos) >= w) { if (last_space == -1) { @@ -72,11 +74,24 @@ static PyObject *poopt_cut_text(PyObject *self, PyObject *args) start_pos = last_space + 1; last_space = -1; } + w = width; } if (buffer[bpos] == 25) /* \x19 */ { - spos++; - bpos += 2; + while (buffer[bpos] && + buffer[bpos] != 'u' && + buffer[bpos] != 'b' && + buffer[bpos] != 'o' && + buffer[bpos] != '}') + { + bpos++; + spos++; + w++; + } + bpos++; + spos++; + w++; + spos--; } else if (buffer[bpos] <= 127) /* ASCII char on one byte */ From d83eda6fd4fc74d5bedb1ca860c1015e7e0d3732 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 8 Nov 2011 02:07:40 +0100 Subject: [PATCH 17/17] escape <, > and & in xhtml-im bodies. --- src/xhtml.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/xhtml.py b/src/xhtml.py index 5eda635b..44195f90 100644 --- a/src/xhtml.py +++ b/src/xhtml.py @@ -16,7 +16,11 @@ import re import subprocess import curses from sleekxmpp.xmlstream import ET + +import xml.sax.saxutils + from xml.etree.ElementTree import ElementTree + from sys import version_info from config import config @@ -401,7 +405,7 @@ def poezio_colors_to_html(string): while next_attr_char != -1: attr_char = string[next_attr_char+1].lower() if next_attr_char != 0: - res += string[:next_attr_char] + res += xml.sax.saxutils.escape(string[:next_attr_char]) if attr_char == 'o': for elem in opened_elements[::-1]: res += '' % (elem,) @@ -425,7 +429,7 @@ def poezio_colors_to_html(string): else: string = string[next_attr_char+2:] next_attr_char = string.find('\x19') - res += string + res += xml.sax.saxutils.escape(string) for elem in opened_elements[::-1]: res += '' % (elem,) res += "

"