Philipp Hörist pushed to branch gajim_1.1 at gajim / gajim
Commits: f51c6f6b by Philipp Hörist at 2018-10-22T17:09:12Z Make bookmark parsing more resilient
Fixes #9385
- - - - - b9e02f20 by Philipp Hörist at 2018-10-22T17:09:12Z DiscoveryWindow: Add default identity
Fixes #9386
- - - - - 2002c3cf by Philipp Hörist at 2018-10-22T17:09:12Z Use parse_datetime for parsing idle time
Fixes #9393
- - - - - defdb888 by Philipp Hörist at 2018-10-22T17:09:12Z Remove support for XEP-0091
- - - - - 186626ad by Philipp Hörist at 2018-10-22T17:09:12Z Use parse_delay also for presences
- - - - - 5568b970 by Philipp Hörist at 2018-10-22T17:09:12Z Fix missing declaration
Fixes #9322
- - - - - 968aae2c by Philipp Hörist at 2018-10-22T17:09:12Z Make idna and precis-18n required dependencys
- - - - - 664a96ce by Philipp Hörist at 2018-10-22T17:09:12Z Prepare for nbxmpp API change
- - - - - 117be487 by Philipp Hörist at 2018-10-22T17:09:13Z Fix flickering tooltips in 3.24.1
- - - - - ee982229 by André Apitzsch at 2018-10-22T17:09:13Z Flatpak: package new required dependency
- - - - - c8ca387f by Philipp Hörist at 2018-10-22T17:09:13Z Remove idna as dependency
We use the python inbuilt idna module
- - - - - ee7db4f7 by Daniel Brötzmann at 2018-10-22T17:09:13Z Remove ESessions leftovers
- - - - - ba82ab9d by Yann Leboulanger at 2018-10-22T17:09:13Z fix regression from [e265514d]: gupnp object is keept globally. Fixes #9398
- - - - - 3db2138e by Philipp Hörist at 2018-10-22T17:09:13Z Make var global
- - - - -
13 changed files:
- README.md - flatpak/org.gajim.Gajim.yaml - gajim/common/app.py - gajim/common/config.py - gajim/common/connection_handlers_events.py - gajim/common/modules/bookmarks.py - gajim/common/modules/misc.py - gajim/common/modules/util.py - − gajim/data/gui/esession_info_window.ui - gajim/disco.py - gajim/gajim.py - gajim/gtk/add_contact.py - setup.py
Changes:
===================================== README.md ===================================== @@ -11,7 +11,7 @@ - python3-openssl (>=0.14) - python3-cssutils (>=1.0.2) - python3-keyring - +- python3-precis-i18n
### Optional Runtime Requirements
@@ -25,7 +25,6 @@ - gir1.2-gupnpigd-1.0 for better NAT traversing - gir1.2-networkmanager-1.0 for network lose detection - gir1.2-geoclue-2.0 for sharing your location -- python3-idna and python3-precis-i18n for correctly parsing JIDs
### Compile-time Requirements
===================================== flatpak/org.gajim.Gajim.yaml ===================================== @@ -213,6 +213,15 @@ modules: url: https://files.pythonhosted.org/packages/6b/15/a9fb9010f58d1c55dd0b7779db2334... sha256: c74dbe19c92f5052774eadb15136263548dd013250f1ed1027988e7fef125c8d
+ - name: python3-precis_i18n + buildsystem: simple + build-commands: + - pip3 install --prefix=/app precis_i18n-1.0.0-py3-none-any.whl + sources: + - type: file + url: https://files.pythonhosted.org/packages/08/9d/d32f1b7c6d280c82a786b629ba89bd... + sha256: f6942bbffec698d0d7e30c42f589f3f6da13e723d047997d0761a41facf2986f + - name: gspell cleanup: - /bin
===================================== gajim/common/app.py ===================================== @@ -145,6 +145,8 @@ ZEROCONF_ACC_NAME = 'Local' idlequeue = None # type: nbxmpp.idlequeue.IdleQueue socks5queue = None
+gupnp_igd = None + gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'} gajim_common_features = [nbxmpp.NS_BYTESTREAM, nbxmpp.NS_SI, nbxmpp.NS_FILE, nbxmpp.NS_MUC, nbxmpp.NS_MUC_USER, nbxmpp.NS_MUC_ADMIN, nbxmpp.NS_MUC_OWNER, @@ -275,7 +277,8 @@ def detect_dependencies(): try: gi.require_version('GUPnPIgd', '1.0') from gi.repository import GUPnPIgd - GUPnPIgd.SimpleIgd() + global gupnp_igd + gupnp_igd = GUPnPIgd.SimpleIgd() _dependencies['UPNP'] = True except ValueError: pass
===================================== gajim/common/config.py ===================================== @@ -209,7 +209,6 @@ class Config: 'tabs_always_visible': [opt_bool, False, _('Show tab when only one conversation?')], 'tabs_border': [opt_bool, False, _('Show tabbed notebook border in chat windows?')], 'tabs_close_button': [opt_bool, True, _('Show close button in tab?')], - 'esession_modp': [opt_str, '15,16,14', _('A list of modp groups to use in a Diffie-Hellman, highest preference first, separated by commas. Valid groups are 1, 2, 5, 14, 15, 16, 17 and 18. Higher numbers are more secure, but take longer to calculate when you start a session.')], 'tooltip_status_online_color': [opt_color, '#73D216'], 'tooltip_status_free_for_chat_color': [opt_color, '#3465A4'], 'tooltip_status_away_color': [opt_color, '#EDD400'],
===================================== gajim/common/connection_handlers_events.py ===================================== @@ -17,7 +17,6 @@ # pylint: disable=no-init # pylint: disable=attribute-defined-outside-init
-from calendar import timegm import logging from time import time as time_time
@@ -30,6 +29,8 @@ from gajim.common import app from gajim.common import i18n from gajim.common.i18n import _ from gajim.common.modules import dataforms +from gajim.common.modules.misc import parse_idle +from gajim.common.modules.misc import parse_delay from gajim.common.const import KindConstant, SSLError from gajim.common.pep import SUPPORTED_PERSONAL_USER_EVENTS from gajim.common.jingle_transport import JingleTransportSocks5 @@ -87,18 +88,6 @@ class HelperEvent: minimized = app.interface.minimized_controls[self.conn.name] self.gc_control = minimized.get(self.jid)
- def _generate_timestamp(self, tag): - # Make sure we use only int/float Epoch time - if tag is None: - self.timestamp = time_time() - return - try: - tim = helpers.datetime_tuple(tag) - self.timestamp = timegm(tim) - except Exception: - log.error('wrong timestamp, ignoring it: %s', tag) - self.timestamp = time_time() - def get_oob_data(self, stanza): oob_node = stanza.getTag('x', namespace=nbxmpp.NS_X_OOB) if oob_node is not None: @@ -249,17 +238,14 @@ PresenceHelperEvent): self.user_nick = self.stanza.getTagData('nick') or '' self.contact_nickname = None self.transport_auto_auth = False + # XEP-0203 - delay_tag = self.stanza.getTag('delay', namespace=nbxmpp.NS_DELAY2) - if delay_tag: - self._generate_timestamp(self.stanza.timestamp) + self.timestamp = parse_delay(self.stanza) + if self.timestamp is None: + self.timestamp = time_time() + # XEP-0319 - self.idle_time = None - idle_tag = self.stanza.getTag('idle', namespace=nbxmpp.NS_IDLE) - if idle_tag: - time_str = idle_tag.getAttr('since') - tim = helpers.datetime_tuple(time_str) - self.idle_time = timegm(tim) + self.idle_time = parse_idle(self.stanza)
xtags = self.stanza.getTags('x') for x in xtags: @@ -268,9 +254,6 @@ PresenceHelperEvent): self.is_gc = True elif namespace == nbxmpp.NS_SIGNED: sig_tag = x - elif namespace == nbxmpp.NS_DELAY and not self.timestamp: - # XEP-0091 - self._generate_timestamp(self.stanza.timestamp)
self.status = self.stanza.getStatus() or '' self._generate_show()
===================================== gajim/common/modules/bookmarks.py ===================================== @@ -166,6 +166,7 @@ class Bookmarks: autojoin_val = conf.getAttr('autojoin') if not autojoin_val: # not there (it's optional) autojoin_val = False + minimize_val = conf.getTag('minimize', namespace=NS_GAJIM_BM) if not minimize_val: # not there, try old Gajim behaviour minimize_val = conf.getAttr('minimize') @@ -189,19 +190,27 @@ class Bookmarks: conf.getAttr('jid')) continue
+ bookmark = { + 'name': conf.getAttr('name'), + 'password': conf.getTagData('password'), + 'nick': conf.getTagData('nick'), + 'print_status': print_status + } + + try: + bookmark['autojoin'] = from_xs_boolean(autojoin_val) + bookmark['minimize'] = from_xs_boolean(minimize_val) + except ValueError as error: + log.warning(error) + continue + if check_merge: if jid in self.bookmarks: continue merged = True
log.debug('Found Bookmark: %s', jid) - self.bookmarks[jid] = { - 'name': conf.getAttr('name'), - 'autojoin': from_xs_boolean(autojoin_val), - 'minimize': from_xs_boolean(minimize_val), - 'password': conf.getTagData('password'), - 'nick': conf.getTagData('nick'), - 'print_status': print_status} + self.bookmarks[jid] = bookmark
return merged
===================================== gajim/common/modules/misc.py ===================================== @@ -139,3 +139,24 @@ def parse_xhtml(stanza): if app.config.get('ignore_incoming_xhtml'): return None return stanza.getXHTML() + + +# XEP-0319: Last User Interaction in Presence + +def parse_idle(stanza): + idle_tag = stanza.getTag('idle', namespace=nbxmpp.NS_IDLE) + if idle_tag is None: + return + + since = idle_tag.getAttr('since') + if since is None: + log.warning('No since attr in idle node') + log.warning(stanza) + return + + timestamp = parse_datetime(since, convert='utc', epoch=True) + if timestamp is None: + log.warning('Invalid timestamp received: %s', since) + log.warning(stanza) + + return timestamp
===================================== gajim/common/modules/util.py ===================================== @@ -47,20 +47,16 @@ def is_muc_pm(message: nbxmpp.Node,
def from_xs_boolean(value: Union[str, bool]) -> bool: - # Convert a xs:boolean ('true', 'false', '1', '0', '') - # to a python boolean (True, False) if isinstance(value, bool): return value
- if value in ('1', 'true'): + if value in ('1', 'true', 'True'): return True
- # '0', 'false' or empty - if value in ('0', 'false', ''): + if value in ('0', 'false', 'False', ''): return False
- raise ValueError( - 'Cant convert %s to python boolean' % value) + raise ValueError('Cant convert %s to python boolean' % value)
def to_xs_boolean(value: Union[bool, None]) -> str:
===================================== gajim/data/gui/esession_info_window.ui deleted ===================================== @@ -1,162 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> -<interface> - <requires lib="gtk+" version="3.12"/> - <object class="GtkDialog" id="esession_info_window"> - <property name="can_focus">False</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="border_width">5</property> - <property name="window_position">center-on-parent</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">2</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="verify_now_button"> - <property name="use_action_appearance">False</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <signal name="clicked" handler="on_verify_now_button_clicked" swapped="no"/> - <child> - <object class="GtkBox" id="hbox3"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">2</property> - <child> - <object class="GtkImage" id="image2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-apply</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="button_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">_Verify</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="close_button3"> - <property name="label">gtk-close</property> - <property name="use_action_appearance">False</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - <signal name="clicked" handler="on_close_button_clicked" swapped="no"/> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="title-hbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkImage" id="security_image"> - <property name="width_request">32</property> - <property name="height_request">32</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="verification_status_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkBox" id="hbox4"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">4</property> - <child> - <object class="GtkLabel" id="info_display"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">(<b>ESession</b> info)</property> - <property name="use_markup">True</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="padding">10</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-10">verify_now_button</action-widget> - <action-widget response="-7">close_button3</action-widget> - </action-widgets> - </object> -</interface>
===================================== gajim/disco.py ===================================== @@ -405,6 +405,10 @@ class ServicesCache: Callback for when we receive an agent's info array is (agent, node, identities, features, data) """ + if not identities: + # Ejabberd doesn't send identities when using admin nodes + identities = [{'category': 'server', 'type': 'im', 'name': node}] + self._on_agent_info(str(from_), node, identities, features, data)
def _disco_info_error(self, from_, error):
===================================== gajim/gajim.py ===================================== @@ -74,6 +74,11 @@ def _init_gtk():
from gajim.application import GajimApplication
+ # Fix bug in 3.24.1 with flickering tooltips + if sys.platform in ('darwin', 'win32'): + settings = Gtk.Settings.get_default() + settings.set_property('gtk-cursor-theme-size', 16) + application = GajimApplication() _install_sginal_handlers(application) application.run(sys.argv)
===================================== gajim/gtk/add_contact.py ===================================== @@ -126,6 +126,7 @@ class AddNewContactWindow(Gtk.ApplicationWindow): type_ = 'jabber' if type_ == 'jabber': self.uid_entry.set_text(jid) + transport = None else: uid, transport = app.get_name_and_server_from_jid(jid) self.uid_entry.set_text(uid.replace('%', '@', 1))
===================================== setup.py ===================================== @@ -285,8 +285,9 @@ setup( data_files=data_files, install_requires=[ 'keyring', - 'nbxmpp>=0.6.8', + 'nbxmpp>=0.6.8,<0.7.0', 'pyOpenSSL>=0.12', - 'cssutils>=1.0.2' + 'cssutils>=1.0.2', + 'precis-i18n>=1.0.0', ] )
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/479bfa56cb5b93268a8b2ac2a9b6a3496e...