Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
d85cb5e5 by Philipp Hörist at 2019-01-21T21:33:26Z
Add Blocking (XEP-0191) module
- - - - -
f90126ec by Philipp Hörist at 2019-01-21T21:33:26Z
BOSH: Fix setting language on stream
- - - - -
4 changed files:
- nbxmpp/bosh.py
- nbxmpp/dispatcher_nb.py
- + nbxmpp/modules/blocking.py
- nbxmpp/structs.py
Changes:
=====================================
nbxmpp/bosh.py
=====================================
@@ -45,7 +45,6 @@ class NonBlockingBOSH(NonBlockingTransport):
idlequeue, estabilish_tls, certs, tls_version, cipher_list)
self.bosh_sid = None
- self.bosh_xml_lang = self._owner.lang
self.http_version = 'HTTP/1.1'
self.http_persistent = True
@@ -414,7 +413,7 @@ class NonBlockingBOSH(NonBlockingTransport):
t = BOSHBody(
attrs={ 'to': self.bosh_to,
'sid': self.bosh_sid,
- 'xml:lang': self.bosh_xml_lang,
+ 'xml:lang': self._owner.lang,
'xmpp:restart': 'true',
'secure': self.bosh_secure,
'xmlns:xmpp': 'urn:xmpp:xbosh'})
@@ -425,7 +424,7 @@ class NonBlockingBOSH(NonBlockingTransport):
'route': 'xmpp:%s:%s' % (self.route_host, self.route_port),
'to': self.bosh_to,
'wait': str(self.bosh_wait),
- 'xml:lang': self.bosh_xml_lang,
+ 'xml:lang': self._owner.lang,
'xmpp:version': '1.0',
'ver': '1.6',
'xmlns:xmpp': 'urn:xmpp:xbosh'})
=====================================
nbxmpp/dispatcher_nb.py
=====================================
@@ -55,6 +55,7 @@ from nbxmpp.modules.signed import Signed
from nbxmpp.modules.vcard_avatar import VCardAvatar
from nbxmpp.modules.captcha import Captcha
from nbxmpp.modules.entity_caps import EntityCaps
+from nbxmpp.modules.blocking import Blocking
from nbxmpp.modules.misc import unwrap_carbon
from nbxmpp.modules.misc import unwrap_mam
from nbxmpp.util import get_properties_struct
@@ -177,6 +178,7 @@ class XMPPDispatcher(PlugIn):
self._modules['Signed'] = Signed(self._owner)
self._modules['VCardAvatar'] = VCardAvatar(self._owner)
self._modules['EntityCaps'] = EntityCaps(self._owner)
+ self._modules['Blocking'] = Blocking(self._owner)
for instance in self._modules.values():
for handler in instance.handlers:
=====================================
nbxmpp/modules/blocking.py
=====================================
@@ -0,0 +1,81 @@
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
+#
+# This file is part of nbxmpp.
+#
+# 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; either version 3
+# of the License, or (at your option) any later version.
+#
+# 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/>.
+
+import logging
+
+from nbxmpp.protocol import NS_BLOCKING
+from nbxmpp.protocol import Iq
+from nbxmpp.protocol import isResultNode
+from nbxmpp.structs import BlockingListResult
+from nbxmpp.structs import CommonResult
+from nbxmpp.util import call_on_response
+from nbxmpp.util import callback
+
+log = logging.getLogger('nbxmpp.m.blocking')
+
+
+class Blocking:
+ def __init__(self, client):
+ self._client = client
+ self.handlers = []
+
+ @call_on_response('_blocking_list_received')
+ def get_blocking_list(self):
+ iq = Iq('get', NS_BLOCKING)
+ iq.setQuery('blocklist')
+ return iq
+
+ @callback
+ def _blocking_list_received(self, stanza):
+ blocked = []
+ if not isResultNode(stanza):
+ log.info('Error: %s', stanza.getErrorMsg())
+ return BlockingListResult(blocking_list=blocked,
+ error=stanza.getErrorMsg())
+
+ blocklist = stanza.getTag('blocklist', namespace=NS_BLOCKING)
+ for item in blocklist.getTags('item'):
+ blocked.append(item.getAttr('jid'))
+
+ log.info('Received blocking list: %s', blocked)
+ return BlockingListResult(blocking_list=blocked)
+
+ @call_on_response('_default_response')
+ def block(self, jids):
+ log.info('Block: %s', jids)
+ iq = Iq('set', NS_BLOCKING)
+ query = iq.setQuery(name='block')
+ for jid in jids:
+ query.addChild(name='item', attrs={'jid': jid})
+ return iq
+
+ @call_on_response('_default_response')
+ def unblock(self, jids):
+ log.info('Unblock: %s', jids)
+ iq = Iq('set', NS_BLOCKING)
+ query = iq.setQuery(name='unblock')
+ for jid in jids:
+ query.addChild(name='item', attrs={'jid': jid})
+ return iq
+
+ @callback
+ def _default_response(self, stanza):
+ if not isResultNode(stanza):
+ log.info('Error: %s', stanza.getErrorMsg())
+ return CommonResult(jid=stanza.getFrom(),
+ error=stanza.getErrorMsg())
+ return CommonResult(jid=stanza.getFrom())
=====================================
nbxmpp/structs.py
=====================================
@@ -294,14 +294,23 @@ class CommonResult(BaseResult, namedtuple('CommonResult', 'jid error')):
CommonResult.__new__.__defaults__ = (None,)
+
class AffiliationResult(BaseResult, namedtuple('AffiliationResult',
'jid affiliation users error')):
pass
AffiliationResult.__new__.__defaults__ = (None, None)
+
class MucConfigResult(BaseResult, namedtuple('MucConfigResult',
'jid form error')):
pass
MucConfigResult.__new__.__defaults__ = (None, None)
+
+
+class BlockingListResult(BaseResult, namedtuple('BlockingListResult',
+ 'blocking_list error')):
+ pass
+
+BlockingListResult.__new__.__defaults__ = (None,)
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/00189cbbcfd51063c2bb3ebe0…
--
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/00189cbbcfd51063c2bb3ebe0…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
31d9b397 by Philipp Hörist at 2019-01-19T20:35:58Z
Deal with stanza-id not added by a mam archive
Fixes #9550
- - - - -
1 changed file:
- gajim/common/modules/message.py
Changes:
=====================================
gajim/common/modules/message.py
=====================================
@@ -331,6 +331,8 @@ class Message:
if archive.bareMatch(properties.stanza_id.by):
return properties.stanza_id.id, None
+ # stanza-id not added by the archive, ignore it.
+ return None, None
class MessageReceivedEvent(NetworkIncomingEvent):
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/31d9b397441b8c239d4094022827b514aa…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/31d9b397441b8c239d4094022827b514aa…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
7c7df9d4 by Philipp Hörist at 2019-01-19T20:21:16Z
Detect invalid user mood
Fixes #9546, #9547
- - - - -
3e362874 by Philipp Hörist at 2019-01-19T20:21:20Z
Detect invalid user activity
- - - - -
2 changed files:
- gajim/common/modules/user_activity.py
- gajim/common/modules/user_mood.py
Changes:
=====================================
gajim/common/modules/user_activity.py
=====================================
@@ -65,6 +65,9 @@ class UserActivity(AbstractPEPModule):
if activity_tag is None:
raise StanzaMalformed('No activity node')
+ if not activity_tag.getChildren():
+ return None
+
for child in activity_tag.getChildren():
name = child.getName().strip()
data = child.getData().strip()
@@ -76,17 +79,22 @@ class UserActivity(AbstractPEPModule):
subactivity_name = subactivity.getName().strip()
activity_dict['subactivity'] = subactivity_name
- return activity_dict or None
+ if 'activity' not in activity_dict:
+ raise StanzaMalformed('No activity value found')
+ return activity_dict
def _build_node(self, data):
item = nbxmpp.Node('activity', {'xmlns': self.namespace})
if data is None:
return item
+
activity, subactivity, message = data
- if activity:
- i = item.addChild(activity)
- if subactivity:
- i.addChild(subactivity)
+ if not activity:
+ return item
+
+ i = item.addChild(activity)
+ if subactivity:
+ i.addChild(subactivity)
if message:
i = item.addChild('text')
i.addData(message)
=====================================
gajim/common/modules/user_mood.py
=====================================
@@ -67,6 +67,9 @@ class UserMood(AbstractPEPModule):
if mood_tag is None:
raise StanzaMalformed('No mood node')
+ if not mood_tag.getChildren():
+ return None
+
for child in mood_tag.getChildren():
name = child.getName().strip()
if name == 'text':
@@ -74,15 +77,20 @@ class UserMood(AbstractPEPModule):
else:
mood_dict['mood'] = name
- return mood_dict or None
+ if 'mood' not in mood_dict:
+ raise StanzaMalformed('No mood value found')
+ return mood_dict
def _build_node(self, data: Optional[Tuple[str, str]]) -> nbxmpp.Node:
item = nbxmpp.Node('mood', {'xmlns': nbxmpp.NS_MOOD})
if data is None:
return item
+
mood, text = data
- if mood:
- item.addChild(mood)
+ if not mood:
+ return item
+ item.addChild(mood)
+
if text:
item.addChild('text', payload=text)
return item
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/cf8eafffb28fa4acb48e4eda44be35b7d…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/cf8eafffb28fa4acb48e4eda44be35b7d…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
cf8eafff by Philipp Hörist at 2019-01-19T19:40:06Z
Detect full language code
Previously we only used short language codes (en, de, fr)
- Add conversion method to rfc5646 format
- - - - -
3 changed files:
- gajim/common/connection.py
- gajim/common/i18n.py
- gajim/conversation_textview.py
Changes:
=====================================
gajim/common/connection.py
=====================================
@@ -1059,11 +1059,14 @@ class Connection(CommonConnection, ConnectionHandlers):
secure_tuple = (self._current_type, cacerts, mycerts, tls_version,
cipher_list, self._current_host['alpn'])
+ lang = i18n.get_rfc5646_lang()
+ log.info('Set stream language: %s', lang)
+
con = nbxmpp.NonBlockingClient(
domain=self._hostname,
caller=self,
idlequeue=app.idlequeue,
- lang=i18n.LANG)
+ lang=lang)
if self._sm_resume_data:
con.set_resume_data(self._sm_resume_data)
=====================================
gajim/common/i18n.py
=====================================
@@ -69,21 +69,33 @@ def iter_locale_dirs():
if locale_dir.is_dir():
yield str(locale_dir)
+
def get_default_lang():
if os.name == "nt":
import ctypes
windll = ctypes.windll.kernel32
- lang = locale.windows_locale[windll.GetUserDefaultUILanguage()]
- return lang[:2]
+ return locale.windows_locale[windll.GetUserDefaultUILanguage()]
if sys.platform == "darwin":
from AppKit import NSLocale
+ # FIXME: This returns a two letter language code (en, de, fr)
+ # We need a way to get en_US, de_DE etc.
return NSLocale.currentLocale().languageCode()
- default = locale.getdefaultlocale()[0]
- if default is not None:
- return default[:2]
- return 'en'
+ return locale.getdefaultlocale()[0] or 'en'
+
+
+def get_rfc5646_lang(lang=None):
+ if lang is None:
+ lang = LANG
+ return lang.replace('_', '-')
+
+
+def get_short_lang_code(lang=None):
+ if lang is None:
+ lang = LANG
+ return lang[:2]
+
def initialize_direction_mark():
from gi.repository import Gtk
=====================================
gajim/conversation_textview.py
=====================================
@@ -553,7 +553,7 @@ class ConversationTextview(GObject.GObject):
% phrase_for_url
else:
link = 'http://%s.wikipedia.org/wiki/Special:Search?search=%s'\
- % (i18n.LANG, phrase_for_url)
+ % (i18n.get_short_lang_code(), phrase_for_url)
item = Gtk.MenuItem.new_with_mnemonic(_('Read _Wikipedia Article'))
id_ = item.connect('activate', self.visit_url_from_menuitem, link)
self.handlers[id_] = item
@@ -569,7 +569,7 @@ class ConversationTextview(GObject.GObject):
% phrase_for_url
else:
link = 'http://%s.wiktionary.org/wiki/Special:Search?search=%s'\
- % (i18n.LANG, phrase_for_url)
+ % (i18n.get_short_lang_code(), phrase_for_url)
id_ = item.connect('activate', self.visit_url_from_menuitem, link)
self.handlers[id_] = item
else:
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/cf8eafffb28fa4acb48e4eda44be35b7db…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/cf8eafffb28fa4acb48e4eda44be35b7db…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch gajim_1.1 at gajim / gajim
Commits:
14fb0857 by Philipp Hörist at 2019-01-19T18:58:15Z
Windows: Fix language detection
- - - - -
1 changed file:
- gajim/common/i18n.py
Changes:
=====================================
gajim/common/i18n.py
=====================================
@@ -155,6 +155,10 @@ except locale.Error as error:
try:
LANG = get_default_lang()
+ if os.name == 'nt':
+ # Set the env var on Windows because gettext.find() uses it to
+ # find the translation
+ os.environ['LANG'] = LANG
print('Found default language: %s' % LANG)
except Exception as error:
print('Failed to determine default language')
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/14fb0857665e353f4a2155c5c4807c2a77…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/14fb0857665e353f4a2155c5c4807c2a77…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
a9994b79 by Philipp Hörist at 2019-01-19T18:41:52Z
Windows: Fix language detection
- - - - -
1 changed file:
- gajim/common/i18n.py
Changes:
=====================================
gajim/common/i18n.py
=====================================
@@ -155,6 +155,10 @@ except locale.Error as error:
try:
LANG = get_default_lang()
+ if os.name == 'nt':
+ # Set the env var on Windows because gettext.find() uses it to
+ # find the translation
+ os.environ['LANG'] = LANG
print('Found default language: %s' % LANG)
except Exception as error:
print('Failed to determine default language')
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/a9994b791b2ed17f551d031d9f84238154…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/a9994b791b2ed17f551d031d9f84238154…
You're receiving this email because of your account on dev.gajim.org.