From 2275b61a4dadfa84dc1399a97908f8dc7c22d07b Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 27 Jul 2014 00:15:27 +0200 Subject: Add dummy on_delete handlers for input placeholders --- src/windows/input_placeholders.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/windows/input_placeholders.py b/src/windows/input_placeholders.py index 796cf0ad..6ede6b32 100644 --- a/src/windows/input_placeholders.py +++ b/src/windows/input_placeholders.py @@ -34,6 +34,9 @@ class HelpText(Win): def do_command(self, key, raw=False): return False + def on_delete(self): + return + class YesNoInput(Win): """ A Window just displaying a Yes/No input @@ -76,3 +79,6 @@ class YesNoInput(Win): self.key_func[cl[0]]() cl = self.core.read_keyboard() + def on_delete(self): + return + -- cgit v1.2.3 From fccf7f5af7a6a62ffb15cd7f37a23d52d0bbaf0d Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 28 Jul 2014 14:57:48 +0200 Subject: Do not traceback when we receive a message from a JID with no resource --- src/core/handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/handlers.py b/src/core/handlers.py index 119d9e74..462ba4d7 100644 --- a/src/core/handlers.py +++ b/src/core/handlers.py @@ -212,7 +212,7 @@ def on_normal_message(self, message): return conversation = self.get_conversation_by_jid(conv_jid, create=True) - if isinstance(conversation, tabs.DynamicConversationTab): + if isinstance(conversation, tabs.DynamicConversationTab) and conv_jid.resource: conversation.lock(conv_jid.resource) if not own and not conversation.nick: -- cgit v1.2.3 From d95ec953c3982fe70e6ba7116ae5b9df17f6ea7f Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 17 Sep 2014 17:17:47 +0200 Subject: Fix the doc for remote_fifo_path (fixes #2584) --- data/default_config.cfg | 3 ++- doc/source/configuration.rst | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/data/default_config.cfg b/data/default_config.cfg index ef863ee4..ed21eab0 100644 --- a/data/default_config.cfg +++ b/data/default_config.cfg @@ -461,8 +461,9 @@ show_useless_separator = false exec_remote = false # Path of the FIFO in which the remote commands will be sent. +# The "poezio.fifo" file will be created in this directory # Used with exec_remote set to true, see the documentation of /link for details -# Defaults to ./poezio.fifo +# Defaults to ./ remote_fifo_path = # Defines if all tabs are resized at the same time (if set to false) diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index cb2fbddb..b15d5140 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -860,9 +860,11 @@ Other remote_fifo_path - **Default value:** ``./poezio.fifo`` + **Default value:** ``./`` The path of the FIFO used to send the commands (see the :term:`exec_remote` option). + Poezio will try to create a :file:`poezio.fifo` file in this directory. + save_status -- cgit v1.2.3 From bec71fe38d76524cdf04866180f5e3eec4f13701 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 17 Sep 2014 18:51:56 +0200 Subject: Fix #2581 (fix /untell completion) --- plugins/tell.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/tell.py b/plugins/tell.py index 6aa8357d..cfa76e9c 100644 --- a/plugins/tell.py +++ b/plugins/tell.py @@ -61,7 +61,7 @@ class Plugin(BasePlugin): if not nick in self.tabs[tab]: self.tabs[tab][nick] = [] self.tabs[tab][nick].append(msg) - self.api.information('Will tell %s' % nick, 'Info') + self.api.information('Message for %s queued' % nick, 'Info') def command_untell(self, args): """/untell """ @@ -72,10 +72,11 @@ class Plugin(BasePlugin): if not nick in self.tabs[tab]: return del self.tabs[tab][nick] + self.api.information('Messages for %s unqueued' % nick, 'Info') def completion_untell(self, the_input): tab = self.api.current_tab() if not tab in self.tabs: return the_input.auto_completion([], '') - return the_input.auto_completion(list(self.tabs[tab]), '') + return the_input.auto_completion(list(self.tabs[tab]), '', quotify=False) -- cgit v1.2.3 From 41a89dc2acb98a2aa50d6fd9ab37a2be65f5cfa0 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 26 Sep 2014 13:54:50 +0200 Subject: Update OTR documentation --- plugins/otr.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/plugins/otr.py b/plugins/otr.py index 74b06cf1..47f1fc11 100644 --- a/plugins/otr.py +++ b/plugins/otr.py @@ -41,8 +41,8 @@ Install the python module: cd pure-python-otr python3 setup.py install --user -You can also use pip with the requirements.txt at the root of -the poezio directory. +You can also use pip in a virtualenv (built-in as pyvenv_ with python since 3.3) +with the requirements.txt at the root of the poezio directory. Usage @@ -148,20 +148,22 @@ Configuration Log conversations (OTR start/end marker, and messages). -The :term:`allow_v1`, :term:`allow_v2`, :term:`decode_html` +The :term:`allow_v1`, :term:`allow_v2`, :term:`decode_xhtml` and :term:`log` configuration parameters are tab-specific. Important details ----------------- -The OTR session is considered for a full jid, but the trust is considered -with a bare JID. This is important to know in the case of Private Chats, since -you cannot always get the real the JID of your contact (or check if the same -nick is used by different people). +The OTR session is considered for a full JID (e.g. toto@example/**client1**), +but the trust is set with a bare JID (e.g. toto@example). This is important +in the case of Private Chats (in a chatroom), since you cannot always get the +real JID of your contact (or check if the same nick is used by different people). .. _Off The Record messaging: http://wiki.xmpp.org/web/OTR +.. _pyvenv: https://docs.python.org/3/using/scripts.html#pyvenv-creating-virtual-environments """ + from gettext import gettext as _ import potr import logging -- cgit v1.2.3 From 2400b2c5d96732b3dbffd74647bc7e14ffc27abc Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 26 Sep 2014 14:18:21 +0200 Subject: Update the quickstart guide --- doc/source/keys.rst | 16 ++++++++++++++++ doc/source/usage.rst | 51 ++++++++++++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/doc/source/keys.rst b/doc/source/keys.rst index d0b06eed..c590fffb 100644 --- a/doc/source/keys.rst +++ b/doc/source/keys.rst @@ -15,6 +15,8 @@ Key bindings listing -------------------- Some key bindings are available only in some tabs, others are global. +.. _global-keys: + Global keys ~~~~~~~~~~~ These keys work in **any** tab. @@ -46,6 +48,8 @@ highlight > message > non-empty input). **Alt-C**: Scroll the information buffer down. +.. _input-keys: + Input keys ~~~~~~~~~~ These keys concern only the inputs. @@ -75,9 +79,11 @@ for example in conjunction with the bind command, to help you know how to bind something to a key combination without having to remember how to write them by hand. +.. _chattab-keys: Chat tab input keys ~~~~~~~~~~~~~~~~~~~ + These keys work in any conversation tab (MultiUserChat, Private or Conversation tabs). @@ -118,6 +124,8 @@ current conversation, if any. - u: Underlined - o: Stop formatting +.. _muctab-keys: + MultiUserChat tab input keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -133,8 +141,11 @@ These keys work only in the MultiUserChat tab. **tabulation**: Complete a nick. +.. _muclisttab-keys: + MultiUserChat List tab input keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + These keys work only in the MultiUserChat List tab (obtained with :term:`/list`). **Up**: Go up one row. @@ -152,6 +163,8 @@ These keys work only in the MultiUserChat List tab (obtained with :term:`/list`) **PageDown**: Scroll a page of chats down. +.. _rostertab-keys: + Roster tab input keys ~~~~~~~~~~~~~~~~~~~~~ @@ -184,8 +197,11 @@ These keys work only in the Roster tab (the tab number 0). **PageDown**: Scroll a page of contacts down. +.. _forms-keys: + Data Forms tab keys ~~~~~~~~~~~~~~~~~~~ + **Ctrl+y**: Validate the form, send it and close the tab. **Ctrl+g**: Cancel that form (do not send your changes) and close the diff --git a/doc/source/usage.rst b/doc/source/usage.rst index c4d49fde..726198e3 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -8,13 +8,13 @@ Poezio is composed of tabs which can be of various types. Each tab type has a distinct interface, list of commands and list of key shortcuts, in addition to the global commands and key shortcuts. -The Tab list -~~~~~~~~~~~~ +Tab list +~~~~~~~~ -Since Poezio 0.7.5, there are now two ways to show the available tabs: +There are two ways of showing the open tabs: -The old way: horizontal list -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Horizontal list +^^^^^^^^^^^^^^^ This is the default method. @@ -24,8 +24,8 @@ has a number, each time you open a new tab, it gets the next available number. .. figure:: ./images/tab_bar.png :alt: Example of 5 opened tabs -The new way: vertical list -^^^^^^^^^^^^^^^^^^^^^^^^^^ +Vertical list +^^^^^^^^^^^^^ On all tabs, you get a pane on the left side of the screen that shows a list of the opened tabs. As stated above, each tab has a number, and each time you @@ -57,6 +57,8 @@ Generalities :ref:`global-commands` +:ref:`Global shortcuts ` + The tab numbered **0** is always the **roster** tab, the other tabs can be of any type. @@ -65,11 +67,11 @@ type. The status of a tab is represented by its color: -* **blue** (tab **0**): an inactive tab of any type, nothing new to see +* **Blue** (tab **0**): an inactive tab of any type, nothing new to see there. -* **purple** (tab **1**): a :ref:`muctab` with at least one new +* **Purple** (tab **1**): a :ref:`muctab` with at least one new unread message. -* **green** (tab **2**): a tab of a private conversation (:ref:`privatetab` or :ref:`conversationtab`) +* **Green** (tab **2**): a tab of a private conversation (:ref:`privatetab` or :ref:`conversationtab`) with a new message to read. * **Cyan** (tab **3**): the current tab. * **Red** (tab **4**): a :ref:`muctab` with at least one new highlight @@ -92,19 +94,22 @@ Roster tab :ref:`Specific commands ` +:ref:`Specific shortcuts ` + This is a unique tab, always numbered **0**. It contains the list of your -contacts. You can add/remove/edit/search contacts from there, and you can open -a conversation with them. +contacts. You can add (:term:`/add`, :term:`/accept`), remove +(:term:`/remove`) and search contacts from there, and you can open +a conversation with them (``Enter`` key). -Use the **direction arrows** to browse the list, the ``Space`` key to fold or unfold a group -or a contact. +Use the **direction arrows** (↑↓) to browse the list, the ``Space`` key to +fold or unfold a group or a contact. .. figure:: ./images/roster.png :alt: The roster tab -#. The area where information messages are displayed. -#. The actual list of contacts. The first level is group, the second is the - contacts and the third is the resources of you online contacts. +#. Area where information messages are displayed. +#. Actual list of contacts. The first level is group, the second is the + contacts and the third is the resources of your online contacts. #. More informations about the selected contact. .. _muctab: @@ -114,6 +119,10 @@ MultiUserChat tab :ref:`Specific commands ` +:ref:`Specific shortcuts ` + +:ref:`Chat shortcuts ` + This tab contains a multi-user conversation. .. figure:: ./images/muc.png @@ -164,6 +173,8 @@ Private tab ~~~~~~~~~~~ :ref:`Specific commands ` +:ref:`Chat shortcuts ` + This is the tab opened with the :term:`/query` command in a :ref:`muctab`, letting you talk in private with a participant of a multi-user chat. @@ -180,6 +191,8 @@ Conversation tab :ref:`Specific commands ` +:ref:`Chat shortcuts ` + A tab opened from the roster or :term:`/message`, to talk in private with one of your contacts. .. figure:: ./images/conversation.png @@ -194,6 +207,8 @@ status message of the contact. Plugins may add some elements to the status line. Dataforms tab ~~~~~~~~~~~~~ +:ref:`Specific shortcuts ` + This tab lets you view a form received from a remote entity, edit the values and send everything back. It is mostly used to configure MUCs with the :term:`/configure` command but can actually be used for almost anything. @@ -211,6 +226,8 @@ You can then send the completed form using ``Ctrl+y`` or cancel using ``Ctrl+g`` List tab ~~~~~~~~ +:ref:`Specific shortcuts ` + This tab lists all public rooms on a MUC service (with the :term:`/list` command). It is currently very limited but will be improved in the future. There currently is no way to search a room. -- cgit v1.2.3 From dc4f9cc35a180aff708c9693f6cef8ab992d0fa5 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 3 Oct 2014 22:46:21 +0200 Subject: Fix #2692 (ad-hoc mistakes show /help list) --- src/core/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/commands.py b/src/core/commands.py index c2e453e9..7c0f56fa 100644 --- a/src/core/commands.py +++ b/src/core/commands.py @@ -943,7 +943,7 @@ def command_xml_tab(self, arg=''): def command_adhoc(self, arg): arg = arg.split() if len(arg) > 1: - return self.command_help('list') + return self.command_help('ad-hoc') elif arg: jid = safeJID(arg[0]).server else: -- cgit v1.2.3 From 8d2408c16943ca3c7beb70905690e3b1e24079b2 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 8 Oct 2014 12:55:22 +0200 Subject: Use SHA-2 (SHA-512) to store the certificate fingerprint instead of SHA-1 Because SHA-1 is not really relevant anymore. Too bad it's significantly longer and tiring to check, even if that is to be expected. --- doc/source/configuration.rst | 7 +++++-- src/core/handlers.py | 35 +++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index b15d5140..419e1880 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -62,8 +62,11 @@ and certificate validation. **Default value:** ``[empty]`` - The fingerprint of the SSL certificate as a hexadecimal string, you should - not touch it, except if know what you are doing. + The SHA-2 fingerprint of the SSL certificate as a hexadecimal string, + you should not touch it, except if know what you are doing. + + .. note:: the fingerprint was previously stored in SHA-1, and has been + silently upgraded to SHA-2 if the SHA-1 still matched. ciphers diff --git a/src/core/handlers.py b/src/core/handlers.py index 462ba4d7..96a0f7e8 100644 --- a/src/core/handlers.py +++ b/src/core/handlers.py @@ -8,7 +8,7 @@ log = logging.getLogger(__name__) import curses import ssl import time -from hashlib import sha1 +from hashlib import sha1, sha512 from gettext import gettext as _ from sleekxmpp import InvalidJID @@ -1069,16 +1069,27 @@ def validate_ssl(self, pem): config.set_and_save('certificate', cert) der = ssl.PEM_cert_to_DER_cert(pem) - digest = sha1(der).hexdigest().upper() - found_cert = ':'.join(i + j for i, j in zip(digest[::2], digest[1::2])) + sha1_digest = sha1(der).hexdigest().upper() + sha1_found_cert = ':'.join(i + j for i, j in zip(sha1_digest[::2], sha1_digest[1::2])) + sha2_digest = sha512(der).hexdigest().upper() + sha2_found_cert = ':'.join(i + j for i, j in zip(sha2_digest[::2], sha2_digest[1::2])) if cert: - if found_cert == cert: - log.debug('Cert %s OK', found_cert) + if sha1_found_cert == cert: + log.debug('Cert %s OK', sha1_found_cert) + log.debug('Current hash is SHA-1, moving to SHA-2 (%s)', + sha2_found_cert) + config.set_and_save('certificate', sha2_found_cert) + return + elif sha2_found_cert == cert: + log.debug('Cert %s OK', sha2_found_cert) return else: saved_input = self.current_tab().input - log.debug('\nWARNING: CERTIFICATE CHANGED old: %s, new: %s\n', cert, found_cert) - input = windows.YesNoInput(text="WARNING! Server certificate has changed, accept? (y/n) (%s)" % found_cert) + log.debug('\nWARNING: CERTIFICATE CHANGED old: %s, new: %s\n', cert, sha2_found_cert) + self.information('New certificate found (sha-2 hash:' + ' %s)\nPlease validate or abort' % sha2_found_cert, + 'Warning') + input = windows.YesNoInput(text="WARNING! Server certificate has changed, accept? (y/n)") self.current_tab().input = input input.resize(1, self.current_tab().width, self.current_tab().height-1, 0) input.refresh() @@ -1089,16 +1100,16 @@ def validate_ssl(self, pem): self.current_tab().input = saved_input self.paused = False if input.value: - self.information('Setting new certificate: old: %s, new: %s' % (cert, found_cert), 'Info') - log.debug('Setting certificate to %s', found_cert) - if not config.silent_set('certificate', found_cert): + self.information('Setting new certificate: old: %s, new: %s' % (cert, sha2_found_cert), 'Info') + log.debug('Setting certificate to %s', sha2_found_cert) + if not config.silent_set('certificate', sha2_found_cert): self.information(_('Unable to write in the config file'), 'Error') else: self.information('You refused to validate the certificate. You are now disconnected', 'Info') self.xmpp.disconnect() else: - log.debug('First time. Setting certificate to %s', found_cert) - if not config.silent_set('certificate', found_cert): + log.debug('First time. Setting certificate to %s', sha2_found_cert) + if not config.silent_set('certificate', sha2_found_cert): self.information(_('Unable to write in the config file'), 'Error') def _composing_tab_state(tab, state): -- cgit v1.2.3 From 8f6ab25fc96e54e2e717fd9ccaf3c07fe6fb9a98 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 10 Oct 2014 14:20:59 +0200 Subject: Fix /me display in delayed messages --- src/tabs/muctab.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tabs/muctab.py b/src/tabs/muctab.py index 4dc7a2cf..5167dffd 100644 --- a/src/tabs/muctab.py +++ b/src/tabs/muctab.py @@ -1523,11 +1523,11 @@ class MucTab(ChatTab): config.get_by_tabname('notify_messages', True, self.name)): self.state = 'message' - if time: + if time and not txt.startswith('/me'): txt = '\x19%(info_col)s}%(txt)s' % { 'txt': txt, 'info_col': dump_tuple(get_theme().COLOR_LOG_MSG)} - elif (not nickname or time) and not txt.startswith('/me '): + elif not nickname: txt = '\x19%(info_col)s}%(txt)s' % { 'txt': txt, 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)} -- cgit v1.2.3 From 8e29f6d1ff8402f7d2e2381d2d33b05dcc28503a Mon Sep 17 00:00:00 2001 From: mathieui Date: Sat, 11 Oct 2014 16:52:41 +0200 Subject: Add a /dump command to the XML tab --- doc/source/commands.rst | 6 ++++++ src/tabs/xmltab.py | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/doc/source/commands.rst b/doc/source/commands.rst index fc3aefa4..449d4095 100644 --- a/doc/source/commands.rst +++ b/doc/source/commands.rst @@ -541,10 +541,16 @@ XML tab commands ~~~~~~~~~~~~~~~~ .. glossary:: + :sorted: /clear [XML tab version] Clear the current buffer. + /dump + **Usage:** ``/dump `` + + Write the content of the XML buffer into a file. + /reset Reset the stanza filter. diff --git a/src/tabs/xmltab.py b/src/tabs/xmltab.py index 57b55103..d33f4d48 100644 --- a/src/tabs/xmltab.py +++ b/src/tabs/xmltab.py @@ -11,12 +11,14 @@ import logging log = logging.getLogger(__name__) import curses +import os from sleekxmpp.xmlstream import matcher from sleekxmpp.xmlstream.handler import Callback from . import Tab import windows +from xhtml import clean_text class XMLTab(Tab): def __init__(self): @@ -45,6 +47,10 @@ class XMLTab(Tab): usage=_(''), desc=_('Show only the stanzas matching the given xml mask.'), shortdesc=_('Filter by xml mask.')) + self.register_command('dump', self.command_dump, + usage=_(''), + desc=_('Writes the content of the XML buffer into a file.'), + shortdesc=_('Write in a file.')) self.input = self.default_help_message self.key_func['^T'] = self.close self.key_func['^I'] = self.completion @@ -111,6 +117,17 @@ class XMLTab(Tab): self.filter = '' self.refresh() + def command_dump(self, arg): + """/dump """ + xml = self.core.xml_buffer.messages[:] + text = '\n'.join(('%s %s' % (msg.str_time, clean_text(msg.txt)) for msg in xml)) + filename = os.path.expandvars(os.path.expanduser(arg)) + try: + with open(filename, 'w') as fd: + fd.write(text) + except Exception as e: + self.core.information('Could not write the XML dump: %s' % e, 'Error') + def on_slash(self): """ '/' is pressed, activate the input -- cgit v1.2.3 From a0c5f958819444035894b665a1ef10ddab91dd0b Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 12 Oct 2014 22:08:28 +0200 Subject: Add a notification in the OTR plugin if the session isn't established With a timeout option that lets the user choose the timeout and if they want this notification. --- plugins/otr.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plugins/otr.py b/plugins/otr.py index 47f1fc11..88967b75 100644 --- a/plugins/otr.py +++ b/plugins/otr.py @@ -143,6 +143,13 @@ Configuration Allow OTRv1 + timeout + **Default:** ``3`` + + The number of seconds poezio will wait until notifying you + that the OTR session was not established. A negative or null + value will disable this notification. + log **Default:** false @@ -599,8 +606,27 @@ class Plugin(BasePlugin): context.disconnect() elif arg == 'start' or arg == 'refresh': otr = self.get_context(name) + secs = self.config.get('timeout', 3) + def notify_otr_timeout(): + if otr.state != STATE_ENCRYPTED: + text = _('%(jid_c)s%(jid)s%(info)s did not enable' + ' OTR after %(sec)s seconds.') % { + 'jid': tab.name, + 'info': color_info, + 'jid_c': color_jid, + 'sec': secs} + tab.add_message(text, typ=0) + self.core.refresh_window() + if secs > 0: + event = self.api.create_delayed_event(secs, notify_otr_timeout) + self.api.add_timed_event(event) self.core.xmpp.send_message(mto=name, mtype='chat', mbody=self.contexts[name].sendMessage(0, b'?OTRv?').decode()) + text = _('%(info)sOTR request to %(jid_c)s%(jid)s%(info)s sent') % { + 'jid': tab.name, + 'info': color_info, + 'jid_c': color_jid} + tab.add_message(text, typ=0) elif arg == 'ourfpr': fpr = self.account.getPrivkey() self.api.information('Your OTR key fingerprint is %s' % fpr, 'OTR') -- cgit v1.2.3 From 25e91b0c9453cc235b539c39caf33853d618a51d Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 12 Oct 2014 22:23:45 +0200 Subject: Give feedback on the OTR commands in the current tab instead of the global info buffer --- plugins/otr.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/plugins/otr.py b/plugins/otr.py index 88967b75..c2e5a663 100644 --- a/plugins/otr.py +++ b/plugins/otr.py @@ -597,6 +597,7 @@ class Plugin(BasePlugin): name = tab.name color_jid = '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID) color_info = '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT) + color_normal = '\x19%s}' % dump_tuple(get_theme().COLOR_NORMAL_TEXT) if isinstance(tab, DynamicConversationTab) and tab.locked_resource: name = safeJID(tab.name) name.resource = tab.locked_resource @@ -622,18 +623,38 @@ class Plugin(BasePlugin): self.api.add_timed_event(event) self.core.xmpp.send_message(mto=name, mtype='chat', mbody=self.contexts[name].sendMessage(0, b'?OTRv?').decode()) - text = _('%(info)sOTR request to %(jid_c)s%(jid)s%(info)s sent') % { + text = _('%(info)sOTR request to %(jid_c)s%(jid)s%(info)s sent.') % { 'jid': tab.name, 'info': color_info, 'jid_c': color_jid} tab.add_message(text, typ=0) elif arg == 'ourfpr': fpr = self.account.getPrivkey() - self.api.information('Your OTR key fingerprint is %s' % fpr, 'OTR') + text = _('%(info)sYour OTR key fingerprint is %(norm)s%(fpr)s.') % { + 'jid': tab.name, + 'info': color_info, + 'norm': color_normal, + 'fpr': fpr} + tab.add_message(text, typ=0) elif arg == 'fpr': if name in self.contexts: ctx = self.contexts[name] - self.api.information('The key fingerprint for %s is %s' % (name, ctx.getCurrentKey()) , 'OTR') + if ctx.getCurrentKey() is not None: + text = _('%(info)sThe key fingerprint for %(jid_c)s' + '%(jid)s%(info)s is %(norm)s%(fpr)s%(info)s.') % { + 'jid': tab.name, + 'info': color_info, + 'norm': color_normal, + 'jid_c': color_jid, + 'fpr': ctx.getCurrentKey()} + tab.add_message(text, typ=0) + else: + text = _('%(jid_c)s%(jid)s%(info)s has no' + ' key currently in use.') % { + 'jid': tab.name, + 'info': color_info, + 'jid_c': color_jid} + tab.add_message(text, typ=0) elif arg == 'drop': # drop the privkey (and obviously, end the current conversations before that) for context in self.contexts.values(): -- cgit v1.2.3 From 577d6ea87bf7b5c96fbf307dbf921e1b5f594cbe Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 12 Oct 2014 22:28:10 +0200 Subject: Output the result of the /info command in the MUC window and not the global info buffer --- src/tabs/muctab.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tabs/muctab.py b/src/tabs/muctab.py index 5167dffd..c36a533d 100644 --- a/src/tabs/muctab.py +++ b/src/tabs/muctab.py @@ -355,7 +355,8 @@ class MucTab(ChatTab): dump_tuple(theme.color_role(user.role)), user.role or 'None', '\n%s' % user.status if user.status else '') - self.core.information(info, 'Info') + self.add_message(info, typ=0) + self.core.refresh_window() def command_configure(self, arg): """ -- cgit v1.2.3 From 6c62f624024e954217b7217a691469484ffb70d2 Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 12 Oct 2014 22:34:41 +0200 Subject: Color the JID in locking/unlocking messages --- src/tabs/conversationtab.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/tabs/conversationtab.py b/src/tabs/conversationtab.py index e6324182..94cfd305 100644 --- a/src/tabs/conversationtab.py +++ b/src/tabs/conversationtab.py @@ -385,11 +385,15 @@ class DynamicConversationTab(ConversationTab): assert(resource) if resource != self.locked_resource: self.locked_resource = resource - - message = _('\x19%s}Conversation locked to %s/%s.') % ( - dump_tuple(get_theme().COLOR_INFORMATION_TEXT), - self.name, - resource) + info = '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT) + jid_c = '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID) + + message = _('%(info)sConversation locked to ' + '%(jid_c)s%(jid)s/%(resource)s%(info)s.') % { + 'info': info, + 'jid_c': jid_c, + 'jid': self.name, + 'resource': resource} self.add_message(message, typ=0) self.check_features() @@ -405,16 +409,18 @@ class DynamicConversationTab(ConversationTab): self.remote_wants_chatstates = None if self.locked_resource != None: self.locked_resource = None + info = '\x19%s}' % dump_tuple(get_theme().COLOR_INFORMATION_TEXT) + jid_c = '\x19%s}' % dump_tuple(get_theme().COLOR_MUC_JID) if from_: - message = _('\x19%s}Conversation unlocked ' - '(received activity from %s).') % ( - dump_tuple(get_theme().COLOR_INFORMATION_TEXT), - from_) + message = _('%(info)sConversation unlocked (received activity' + ' from %(jid_c)s%(jid)s%(info)s).') % { + 'info': info, + 'jid_c': jid_c, + 'jid': from_} self.add_message(message, typ=0) else: - message = _('\x19%s}Conversation unlocked.') % ( - dump_tuple(get_theme().COLOR_INFORMATION_TEXT)) + message = _('%sConversation unlocked.') % info self.add_message(message, typ=0) def get_dest_jid(self): -- cgit v1.2.3 From 5a5d5812edeb852232ea22f8b10e6d2073ca05d1 Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 12 Oct 2014 23:06:44 +0200 Subject: Add an open_all_bookmarks option this option determines if the non-autojoin bookmarks will be opened on startup or not. It is false by default. --- data/default_config.cfg | 5 ++++- doc/source/configuration.rst | 7 +++++++ src/core/handlers.py | 37 +++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/data/default_config.cfg b/data/default_config.cfg index ed21eab0..c1f766b0 100644 --- a/data/default_config.cfg +++ b/data/default_config.cfg @@ -116,9 +116,12 @@ use_bookmarks_method = # use this option to force the use of local bookmarks # possible values are: anything/false - use_remote_bookmarks = true +# Whether you want all bookmarks, even those without +# autojoin, to be open on startup +open_all_bookmarks = false + # What will be put after the name, when using autocompletion at the # beginning of the input. A space will always be added after that after_completion = , diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index 419e1880..32d82f7a 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -197,6 +197,13 @@ Options related to account configuration, nickname… The status message poezio will send when connecting. + open_all_bookmarks + + **Default value:** ``false`` + + If this option is set to ``true``, all remote bookmarks, even + those that do not have autojoin, will be opened on startup. + (the tabs without autojoin will not be joined) diff --git a/src/core/handlers.py b/src/core/handlers.py index 96a0f7e8..ea67eaa6 100644 --- a/src/core/handlers.py +++ b/src/core/handlers.py @@ -869,24 +869,25 @@ def on_session_start(self, event): if not self.xmpp.anon and config.get('use_remote_bookmarks', True): bookmark.get_remote(self.xmpp) for bm in bookmark.bookmarks: - tab = self.get_tab_by_name(bm.jid, tabs.MucTab) - nick = bm.nick if bm.nick else self.own_nick - if not tab: - self.open_new_room(bm.jid, nick, False) - self.initial_joins.append(bm.jid) - histo_length = config.get('muc_history_length', 20) - if histo_length == -1: - histo_length = None - if histo_length is not None: - histo_length = str(histo_length) - # do not join rooms that do not have autojoin - # but display them anyway - if bm.autojoin: - muc.join_groupchat(self, bm.jid, nick, - passwd=bm.password, - maxhistory=histo_length, - status=self.status.message, - show=self.status.show) + if bm.autojoin or config.get('open_all_bookmarks', False): + tab = self.get_tab_by_name(bm.jid, tabs.MucTab) + nick = bm.nick if bm.nick else self.own_nick + if not tab: + self.open_new_room(bm.jid, nick, False) + self.initial_joins.append(bm.jid) + histo_length = config.get('muc_history_length', 20) + if histo_length == -1: + histo_length = None + if histo_length is not None: + histo_length = str(histo_length) + # do not join rooms that do not have autojoin + # but display them anyway + if bm.autojoin: + muc.join_groupchat(self, bm.jid, nick, + passwd=bm.password, + maxhistory=histo_length, + status=self.status.message, + show=self.status.show) if config.get('enable_user_nick', True): self.xmpp.plugin['xep_0172'].publish_nick(nick=self.own_nick, callback=dumb_callback, block=False) -- cgit v1.2.3 From 8305f3bd53412cd694baffadbca645227c9c883f Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 13 Oct 2014 00:39:55 +0200 Subject: Document the before_quote and the after_quote options of the quote plugin --- plugins/quote.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/plugins/quote.py b/plugins/quote.py index 3236ef4d..8a4fd95c 100644 --- a/plugins/quote.py +++ b/plugins/quote.py @@ -19,6 +19,28 @@ Usage If there is a message at 21:12:23, it will be put in the input. If there isn’t, you will get a warning. + +Options +------- + +.. glossary:: + :sorted: + + before_quote + + **Default value:** ``[empty]`` + + Text to insert before the quote. ``%(nick)s`` and ``%(time)s`` can + be used to insert the nick of the user who sent the message or the + time of the message. + + after_quote + + **Default value:** ``[empty]`` + + Text to insert after the quote. ``%(nick)s`` and ``%(time)s`` can + be used to insert the nick of the user who sent the message or the + time of the message. """ from plugin import BasePlugin from xhtml import clean_text -- cgit v1.2.3 From 2b10325be47e87637cbd6ff43a310016a5522764 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 13 Oct 2014 19:01:22 +0200 Subject: Document the changing_nick plugin event --- doc/source/dev/events.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/source/dev/events.rst b/doc/source/dev/events.rst index 7092d66b..93832e4a 100644 --- a/doc/source/dev/events.rst +++ b/doc/source/dev/events.rst @@ -112,6 +112,12 @@ The following events are poezio-only events, for SleekXMPP events, check out Triggered when joining a MUC. The presence can thus be modified before being sent. + changing_nick + - **presence:** :py:class:`~~sleekxmpp.Presence` to be sent + + Triggered when the user changes his/her nickname on a MUC. The + presence can thus be modified before being sent. + send_normal_presence - **presence:** :py:class:`~sleekxmpp.Presence` sent -- cgit v1.2.3 From 088c6c6a0b46309d17c4b0ba5939a2dd200c7002 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 13 Oct 2014 19:03:47 +0200 Subject: Trivial line wrapping of the events.rst doc page --- doc/source/dev/events.rst | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/doc/source/dev/events.rst b/doc/source/dev/events.rst index 93832e4a..770445a0 100644 --- a/doc/source/dev/events.rst +++ b/doc/source/dev/events.rst @@ -53,10 +53,11 @@ The following events are poezio-only events, for SleekXMPP events, check out - **message:** :py:class:`~sleekxmpp.Message` that will be sent - **tab:** :py:class:`~tabs.ConversationTab` source - Same thing than :term:`conversation_say`, but after XHTML generation of the body, if needed. - This means you must not insert any colors in the body in the handler, since - it may lead to send invalid XML. This hook is less safe than :term:`conversation_say` and - you should probably not need it. + Same thing than :term:`conversation_say`, but after XHTML generation + of the body, if needed. This means you must not insert any colors + in the body in the handler, since it may lead to send + invalid XML. This hook is less safe than :term:`conversation_say` + and you should probably not need it. muc_msg - **message:** :py:class:`~sleekxmpp.Message` received @@ -96,7 +97,7 @@ The following events are poezio-only events, for SleekXMPP events, check out normal_presence - **presence:** :py:class:`~sleekxmpp.Presence` received - - **resource:** :py:class:`Resource ` that emitted the :py:class:`~sleekxmpp.Presence` + - **resource:** :py:class:`Resource ` that emitted the :py:class:`~sleekxmpp.Presence` Triggered when a presence is received from a contact. @@ -104,13 +105,14 @@ The following events are poezio-only events, for SleekXMPP events, check out - **presence:** :py:class:`~sleekxmpp.Presence` received - **tab:** :py:class:`~tabs.MucTab` source - Triggered when a presence is received from someone in a :py:class:`~tabs.MucTab`. + Triggered when a presence is received from someone in a + :py:class:`~tabs.MucTab`. joining_muc - **presence:** :py:class:`~~sleekxmpp.Presence` to be sent - - Triggered when joining a MUC. The presence can thus be modified before being sent. + Triggered when joining a MUC. The presence can thus be modified + before being sent. changing_nick - **presence:** :py:class:`~~sleekxmpp.Presence` to be sent @@ -121,7 +123,8 @@ The following events are poezio-only events, for SleekXMPP events, check out send_normal_presence - **presence:** :py:class:`~sleekxmpp.Presence` sent - Triggered when poezio sends a new :py:class:`~sleekxmpp.Presence` stanza. The presence can thus be modified before being sent. + Triggered when poezio sends a new :py:class:`~sleekxmpp.Presence` + stanza. The presence can thus be modified before being sent. muc_join - **presence:** :py:class:`~sleekxmpp.Presence` received @@ -154,7 +157,8 @@ The following events are poezio-only events, for SleekXMPP events, check out - **message**:py:class:`~sleekxmpp.Message` received - **tab:** :py:class:`~tabs.PrivateTab` source - Triggered when a private message (that goes in a :py:class:`~tabs.PrivateTab`) - is ignored automatically by poezio. + Triggered when a private message (that goes in a + :py:class:`~tabs.PrivateTab`) is ignored automatically by poezio. - **tab** is always ``None``, except when a tab has already been opened. + **tab** is always ``None``, except when a tab has already been + opened. -- cgit v1.2.3