Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-nbxmpp for openSUSE:Factory checked in at 2023-08-13 19:17:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-nbxmpp (Old) and /work/SRC/openSUSE:Factory/.python-nbxmpp.new.11712 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-nbxmpp" Sun Aug 13 19:17:44 2023 rev:43 rq:1103600 version:4.3.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-nbxmpp/python-nbxmpp.changes 2023-06-05 18:06:15.603010476 +0200 +++ /work/SRC/openSUSE:Factory/.python-nbxmpp.new.11712/python-nbxmpp.changes 2023-08-13 19:17:52.896077391 +0200 @@ -1,0 +2,13 @@ +Mon Aug 7 23:17:29 UTC 2023 - Alexei Sorokin <sor.ale...@meowr.ru> + +- Update to version 4.3.2: + * SecurityLabels: Add get_label_hash(). + * JID: Add sqlite3 adapter magic method. + * MessageProperties: Add origin_id attribute. + * MessageProperties: Add remote_jid attribute. + * Client: Return only copy of ignored errors. + * CommonError: Add "by" attribute. + * Moderation: Parse more data. + * HTTP: Add set_accept_certificate(). + +------------------------------------------------------------------- Old: ---- python-nbxmpp-4.3.1.tar.bz2 New: ---- python-nbxmpp-4.3.2.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-nbxmpp.spec ++++++ --- /var/tmp/diff_new_pack.4yDDap/_old 2023-08-13 19:17:54.368086809 +0200 +++ /var/tmp/diff_new_pack.4yDDap/_new 2023-08-13 19:17:54.372086835 +0200 @@ -24,7 +24,7 @@ %endif %define _name nbxmpp Name: python-nbxmpp -Version: 4.3.1 +Version: 4.3.2 Release: 0 Summary: XMPP library by Gajim team License: GPL-3.0-or-later @@ -41,6 +41,7 @@ BuildRequires: %{python_module packaging} BuildRequires: %{python_module pip} BuildRequires: %{python_module precis-i18n} +BuildRequires: %{python_module sqlite3} BuildRequires: %{python_module wheel} BuildRequires: typelib(Soup) = 3.0 Recommends: python-gssapi ++++++ python-nbxmpp-4.3.1.tar.bz2 -> python-nbxmpp-4.3.2.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/ChangeLog new/python-nbxmpp-4.3.2/ChangeLog --- old/python-nbxmpp-4.3.1/ChangeLog 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/ChangeLog 2023-08-07 22:57:16.000000000 +0200 @@ -1,3 +1,22 @@ +nbxmpp 4.3.2 (04 Jul 2023) + + New + + * SecurityLabels: Add get_label_hash() + * JID: Add sqlite3 adapter magic method + * MessageProperties: Add origin_id attribute + * MessageProperties: Add remote_jid attribute + + Improvements + + * Client: Return only copy of ignored errors + * CommonError: Add 'by' attribute + * Moderation: Parse more data + + Bug Fixes + + * HTTP: Add set_accept_certificate() + nbxmpp 4.3.1 (28 May 2023) Bug Fixes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/__init__.py new/python-nbxmpp-4.3.2/nbxmpp/__init__.py --- old/python-nbxmpp-4.3.1/nbxmpp/__init__.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/__init__.py 2023-08-07 22:57:16.000000000 +0200 @@ -3,4 +3,4 @@ from .protocol import * # pylint: disable=wrong-import-position -__version__: str = '4.3.1' +__version__: str = '4.3.2' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/client.py new/python-nbxmpp-4.3.2/nbxmpp/client.py --- old/python-nbxmpp-4.3.1/nbxmpp/client.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/client.py 2023-08-07 22:57:16.000000000 +0200 @@ -203,7 +203,7 @@ @property def ignored_tls_errors(self): - return self._ignored_tls_errors + return set(self._ignored_tls_errors) def set_ignored_tls_errors(self, errors): if errors is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/http.py new/python-nbxmpp-4.3.2/nbxmpp/http.py --- old/python-nbxmpp-4.3.1/nbxmpp/http.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/http.py 2023-08-07 22:57:16.000000000 +0200 @@ -112,6 +112,7 @@ self._is_complete = False self._timeout_reached = False self._timeout_id = None + self._accept_certificate_func = None self._response_body_file: Optional[Gio.File] = None self._response_body_data = b'' @@ -183,6 +184,9 @@ self._log.info('Cancel requested') self._cancellable.cancel() + def set_accept_certificate_func(self, func: Any) -> None: + self._accept_certificate_func = func + def set_request_body_from_path(self, content_type: str, path: Path) -> None: if not path.exists(): raise ValueError('%s does not exist' % path) @@ -285,6 +289,8 @@ self._message.connect('restarted', self._on_restarted) self._message.connect('finished', self._on_finished) self._message.connect('got-headers', self._on_got_headers) + if self._accept_certificate_func is not None: + self._message.connect('accept-certificate', self._accept_certificate_func) soup_session = self._session.get_soup_session() soup_session.send_async(self._message, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/modules/date_and_time.py new/python-nbxmpp-4.3.2/nbxmpp/modules/date_and_time.py --- old/python-nbxmpp-4.3.1/nbxmpp/modules/date_and_time.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/modules/date_and_time.py 2023-08-07 22:57:16.000000000 +0200 @@ -124,7 +124,7 @@ return timezone(timedelta(hours=hours, minutes=minutes)) -def parse_datetime(timestring, check_utc=False, +def parse_datetime(timestring: str | None, check_utc=False, convert='utc', epoch=False): ''' Parse a XEP-0082 DateTime Profile String diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/modules/message.py new/python-nbxmpp-4.3.2/nbxmpp/modules/message.py --- old/python-nbxmpp-4.3.1/nbxmpp/modules/message.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/modules/message.py 2023-08-07 22:57:16.000000000 +0200 @@ -42,7 +42,6 @@ def _process_message_base(self, _client, stanza, properties): properties.type = self._parse_type(stanza) - # Determine remote JID if properties.is_carbon_message and properties.carbon.is_sent: properties.jid = stanza.getTo() @@ -56,16 +55,35 @@ else: properties.jid = stanza.getFrom() + self._parse_if_private_message(stanza, properties) + + properties.remote_jid = self._determine_remote_jid(properties) properties.from_ = stanza.getFrom() properties.to = stanza.getTo() properties.id = stanza.getID() properties.self_message = self._parse_self_message(stanza, properties) + properties.origin_id = stanza.getOriginID() properties.stanza_ids = self._parse_stanza_ids(stanza) if properties.type.is_error: properties.error = error_factory(stanza) + def _determine_remote_jid(self, properties): + if properties.is_muc_pm: + return properties.jid + return properties.jid.new_as_bare() + + def _parse_if_private_message(self, stanza, properties) -> None: + muc_user = stanza.getTag('x', namespace=Namespace.MUC_USER) + if muc_user is None: + return + + if (properties.type.is_chat or + properties.type.is_error and + not muc_user.getChildren()): + properties.muc_private_message = True + def _process_message_after_base(self, _client, stanza, properties): # This handler runs after decryption handlers had the chance # to decrypt the body diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/modules/misc.py new/python-nbxmpp-4.3.2/nbxmpp/modules/misc.py --- old/python-nbxmpp-4.3.1/nbxmpp/modules/misc.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/modules/misc.py 2023-08-07 22:57:16.000000000 +0200 @@ -103,7 +103,7 @@ # Timestamp parsing # Most servers dont set the 'from' attr, so we cant check for it - delay_timestamp = parse_delay(forwarded) + delay_timestamp = parse_delay(forwarded, epoch=True) if delay_timestamp is None: log.warning('No timestamp on MAM message') log.warning(stanza) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/modules/muc/moderation.py new/python-nbxmpp-4.3.2/nbxmpp/modules/muc/moderation.py --- old/python-nbxmpp-4.3.1/nbxmpp/modules/muc/moderation.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/modules/muc/moderation.py 2023-08-07 22:57:16.000000000 +0200 @@ -17,17 +17,18 @@ from typing import Optional -from nbxmpp.modules.base import BaseModule -from nbxmpp.modules.util import process_response - from nbxmpp import JID from nbxmpp.namespaces import Namespace from nbxmpp.protocol import Iq +from nbxmpp.protocol import NodeProcessed from nbxmpp.structs import StanzaHandler from nbxmpp.structs import MessageProperties from nbxmpp.structs import ModerationData from nbxmpp.simplexml import Node from nbxmpp.task import iq_request_task +from nbxmpp.modules.base import BaseModule +from nbxmpp.modules.date_and_time import parse_datetime +from nbxmpp.modules.util import process_response class Moderation(BaseModule): @@ -41,6 +42,11 @@ typ='groupchat', ns=Namespace.FASTEN, priority=20), + StanzaHandler(name='message', + callback=self._process_message_moderated_tombstone, + typ='groupchat', + ns=Namespace.MESSAGE_MODERATE, + priority=20), ] @iq_request_task @@ -52,9 +58,29 @@ yield process_response(response) - @staticmethod - def _process_message(_client, stanza: Node, - properties: MessageProperties) -> None: + def _process_message_moderated_tombstone( + self, + _client, + stanza: Node, + properties: MessageProperties + ) -> None: + + if not properties.is_mam_message: + return + + moderated = stanza.getTag( + 'moderated', namespace=Namespace.MESSAGE_MODERATE) + if moderated is None: + return + + properties.moderation = self._parse_moderated( + moderated, properties, properties.mam.id) + + def _process_message(self, + _client, + stanza: Node, + properties: MessageProperties) -> None: + if not properties.jid.is_bare: return @@ -68,21 +94,94 @@ if moderated is None: return - retract = moderated.getTag( - 'retract', namespace=Namespace.MESSAGE_RETRACT) - if retract is None: - # Tag can be 'retract' or 'retracted', depending on whether the - # server applies a tombstone for MAM messages or not. - retract = moderated.getTag( - 'retracted', namespace=Namespace.MESSAGE_RETRACT) + stanza_id = apply_to.getAttr('id') + if stanza_id is None: + self._log.warning('apply-to element without stanza-id') + self._log.warning(stanza) + raise NodeProcessed + + properties.moderation = self._parse_moderated(moderated, properties, stanza_id) + + def _parse_moderated( + self, + moderated: Node, + properties: MessageProperties, + stanza_id: str + ) -> ModerationData | None: + + retract, is_tombstone = _get_retract_element(moderated, properties) if retract is None: - return + self._log.warning('Failed to find <retract/ed> element') + return None - properties.moderation = ModerationData( - stanza_id=apply_to.getAttr('id'), - moderator_jid=moderated.getAttr('by'), + try: + by = _parse_by_attr(moderated) + except ValueError as error: + self._log.warning(error) + by = None + + stamp = _parse_moderation_timestamp(retract, is_tombstone, properties) + + occupant_id = moderated.getTagAttr('occupant-id', + 'id', + namespace=Namespace.OCCUPANT_ID) + + return ModerationData( + stanza_id=stanza_id, + moderator_jid=str(by), + by=by, + occupant_id=occupant_id, reason=moderated.getTagData('reason'), - timestamp=retract.getAttr('stamp')) + timestamp=retract.getAttr('stamp'), + stamp=stamp, + is_tombstone=is_tombstone) + + +def _get_retract_element( + moderated: Node, + properties: MessageProperties +) -> tuple[Node | None, bool]: + + retract = moderated.getTag( + 'retract', namespace=Namespace.MESSAGE_RETRACT) + if retract is not None: + return retract, False + + retracted = moderated.getTag( + 'retracted', namespace=Namespace.MESSAGE_RETRACT) + if retracted is not None: + return retracted, True and properties.is_mam_message + return None, False + + +def _parse_by_attr(moderated: Node) -> JID | None: + by_attr = moderated.getAttr('by') + if by_attr is None: + return None + + try: + return JID.from_string(by_attr) + except Exception as error: + raise ValueError('Invalid JID: %s, %s' % (by_attr, error)) + + +def _parse_moderation_timestamp( + retract: Node, + is_tombstone: bool, + properties: MessageProperties +) -> float: + + if is_tombstone: + stamp_attr = retract.getAttr('stamp') + stamp = parse_datetime( + stamp_attr, check_utc=True, convert='utc', epoch=True) + if stamp is not None: + return stamp + + if properties.is_mam_message: + return properties.mam.timestamp + + return properties.timestamp def _make_retract_request(muc_jid: JID, stanza_id: str, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/modules/muc/muc.py new/python-nbxmpp-4.3.2/nbxmpp/modules/muc/muc.py --- old/python-nbxmpp-4.3.1/nbxmpp/modules/muc/muc.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/modules/muc/muc.py 2023-08-07 22:57:16.000000000 +0200 @@ -245,13 +245,6 @@ properties.occupant_id = occupant_id - # MUC Private message - if (properties.type.is_chat or - properties.type.is_error and - not muc_user.getChildren()): - properties.muc_private_message = True - return - if properties.is_muc_invite_or_decline: return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/modules/security_labels.py new/python-nbxmpp-4.3.2/nbxmpp/modules/security_labels.py --- old/python-nbxmpp-4.3.1/nbxmpp/modules/security_labels.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/modules/security_labels.py 2023-08-07 22:57:16.000000000 +0200 @@ -18,6 +18,7 @@ from typing import Dict from dataclasses import dataclass +import hashlib from nbxmpp.protocol import Iq from nbxmpp.simplexml import Node @@ -150,6 +151,10 @@ return cls(displaymarking=displaymarking, label=label) + def get_label_hash(self) -> str: + sha = hashlib.sha512() + sha.update(str(self.label).encode()) + return sha.hexdigest() @dataclass class Catalog: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/protocol.py new/python-nbxmpp-4.3.2/nbxmpp/protocol.py --- old/python-nbxmpp-4.3.1/nbxmpp/protocol.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/protocol.py 2023-08-07 22:57:16.000000000 +0200 @@ -30,6 +30,7 @@ import time import hashlib import functools +import sqlite3 import warnings from base64 import b64encode from dataclasses import dataclass @@ -704,6 +705,11 @@ return f'{jid}/{self.resource}' return jid + def __conform__(self, protocol: sqlite3.PrepareProtocol): + if protocol is sqlite3.PrepareProtocol: + return str(self) + raise ValueError + def __hash__(self): return hash(str(self)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-4.3.1/nbxmpp/structs.py new/python-nbxmpp-4.3.2/nbxmpp/structs.py --- old/python-nbxmpp-4.3.1/nbxmpp/structs.py 2023-05-28 23:18:18.000000000 +0200 +++ new/python-nbxmpp-4.3.2/nbxmpp/structs.py 2023-08-07 22:57:16.000000000 +0200 @@ -299,9 +299,13 @@ class ModerationData(NamedTuple): stanza_id: str - moderator_jid: str - reason: Optional[str] = None - timestamp: Optional[str] = None + moderator_jid: Optional[str] + by: Optional[JID] + reason: Optional[str] + timestamp: Optional[str] + stamp: float + is_tombstone: bool + occupant_id: Optional[str] class DiscoItems(NamedTuple): @@ -769,10 +773,18 @@ self.condition_data = self._error_node.getTagData(self.condition) self.app_condition = stanza.getAppError() self.type = stanza.getErrorType() + self.by = None self.jid = stanza.getFrom() self.id = stanza.getID() self._text = {} + by = self._error_node.getAttr('by') + if by is not None: + try: + self.by = JID.from_string(by) + except Exception: + pass + text_elements = self._error_node.getTags('text', namespace=Namespace.STANZAS) for element in text_elements: lang = element.getXmlLang() @@ -917,7 +929,7 @@ query_id: str archive: JID namespace: str - timestamp: datetime + timestamp: float @property def is_ver_1(self) -> bool: @@ -964,9 +976,11 @@ type: MessageType = MessageType.NORMAL id: Optional[str] = None stanza_ids: list[StanzaIDData] = field(default_factory=list) + origin_id: Optional[str] = None from_: Optional[JID] = None to: Optional[JID] = None jid: Optional[JID] = None + remote_jid: Optional[JID] = None subject = None body: Optional[str] = None thread: Optional[str] = None