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 2026-11-10 14:44:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-nbxmpp (Old) and /work/SRC/openSUSE:Factory/.python-nbxmpp.new.3759290 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-nbxmpp" Tue Nov 10 14:44:18 2026 rev:60 rq:1396482 version:7.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-nbxmpp/python-nbxmpp.changes 2026-10-29 16:13:01.892898228 +0100 +++ /work/SRC/openSUSE:Factory/.python-nbxmpp.new.3759290/python-nbxmpp.changes 2026-11-10 14:45:53.390313404 +0100 @@ -1,0 +2,8 @@ +Mon Nov 9 08:10:23 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 7.5.0: + * New: Add Jabber Search (XEP-0055) + * Improvements: UserAvatar: Be more strict when parsing metadata node + * Bug Fixes: Dataform: Strip whitespace from single string fields + +------------------------------------------------------------------- Old: ---- python-nbxmpp-7.4.0.tar.bz2 New: ---- python-nbxmpp-7.5.0.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-nbxmpp.spec ++++++ --- /var/tmp/diff_new_pack.mzHMue/_old 2026-11-10 14:45:54.540361583 +0100 +++ /var/tmp/diff_new_pack.mzHMue/_new 2026-11-10 14:45:54.542361666 +0100 @@ -19,7 +19,7 @@ %define _name nbxmpp %{?sle15_python_module_pythons} Name: python-nbxmpp -Version: 7.4.0 +Version: 7.5.0 Release: 0 Summary: XMPP library by Gajim team License: GPL-3.0-or-later ++++++ python-nbxmpp-7.4.0.tar.bz2 -> python-nbxmpp-7.5.0.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/.chglog/config.yml new/python-nbxmpp-7.5.0/.chglog/config.yml --- old/python-nbxmpp-7.4.0/.chglog/config.yml 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/.chglog/config.yml 2026-11-01 19:50:06.000000000 +0100 @@ -2,7 +2,7 @@ template: CHANGELOG.tpl.md info: title: CHANGELOG - repository_url: https://dev.gajim.org/gajim/python-nbxmpp + repository_url: https://gitlab.com/gajim/python-nbxmpp options: commits: filters: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/.gitlab-ci.yml new/python-nbxmpp-7.5.0/.gitlab-ci.yml --- old/python-nbxmpp-7.4.0/.gitlab-ci.yml 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/.gitlab-ci.yml 2026-11-01 19:50:06.000000000 +0100 @@ -1,12 +1,12 @@ -image: nbxmpp-master:latest - stages: + - manual - test - build - deploy - publish test-isort: + image: registry.gitlab.com/gajim/python-nbxmpp/build-test:latest stage: test rules: - when: always @@ -16,6 +16,7 @@ interruptible: true test-black: + image: registry.gitlab.com/gajim/python-nbxmpp/build-test:latest stage: test rules: - when: always @@ -25,6 +26,7 @@ interruptible: true test-ruff: + image: registry.gitlab.com/gajim/python-nbxmpp/build-test:latest stage: test rules: - when: always @@ -34,6 +36,7 @@ interruptible: true test-pyright: + image: registry.gitlab.com/gajim/python-nbxmpp/build-test:latest stage: test rules: - when: always @@ -44,6 +47,7 @@ interruptible: true test-unittest: + image: registry.gitlab.com/gajim/python-nbxmpp/build-test:latest stage: test rules: - when: always @@ -52,12 +56,13 @@ interruptible: true build-unix: + image: registry.gitlab.com/gajim/python-nbxmpp/build-test:latest stage: build dependencies: [] rules: - when: always script: - - pip install git+https://dev.gajim.org/gajim/release-helper.git + - pip install git+https://gitlab.com/gajim/release-helper.git - pip install build - python3 -m build - release-helper build-debian-pkg "$(find dist/nbxmpp-*.tar.gz)" 1 --pkgprefix=python3 --pkgsuffix=nightly @@ -71,7 +76,7 @@ - debian_build/* deploy-pypi: - image: nbxmpp-deploy:latest + image: registry.gitlab.com/gajim/python-nbxmpp/deploy:latest stage: deploy dependencies: - "build-unix" @@ -81,7 +86,7 @@ - twine upload --username=__token__ --password=$PYPI_TOKEN dist/* deploy-debian-nightly: - image: nbxmpp-deploy:latest + image: registry.gitlab.com/gajim/python-nbxmpp/deploy:latest stage: deploy dependencies: - build-unix @@ -105,7 +110,7 @@ debian_build publish-release: - image: nbxmpp-publish:latest + image: registry.gitlab.com/gajim/python-nbxmpp/publish:latest stage: publish dependencies: [] rules: @@ -117,3 +122,19 @@ $CI_RELEASE_TOKEN \ --version=$CI_COMMIT_TAG \ --tag=$CI_COMMIT_TAG + +build-docker-image: + image: docker:29.9.1-cli-alpine3.24 + stage: manual + rules: + - if: '$DOCKER_IMAGE' + tags: + - docker + variables: + DOCKER_TLS_CERTDIR: "/certs" + services: + - docker:29.9.1-dind-alpine3.24 + script: + - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin + - docker build -t $CI_REGISTRY/gajim/python-nbxmpp/$DOCKER_IMAGE:latest docker/$DOCKER_IMAGE + - docker push $CI_REGISTRY/gajim/python-nbxmpp/$DOCKER_IMAGE:latest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/ChangeLog new/python-nbxmpp-7.5.0/ChangeLog --- old/python-nbxmpp-7.4.0/ChangeLog 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/ChangeLog 2026-11-01 19:50:06.000000000 +0100 @@ -1,3 +1,17 @@ +nbxmpp 7.5.0 (23 Oct 2026) + + New + + * Add Jabber Search (XEP-0055) + + Improvements + + * UserAvatar: Be more strict when parsing metadata node + + Bug Fixes + + * Dataform: Strip whitespace from single string fields + nbxmpp 7.4.0 (26 Aug 2026) New diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/debian/changelog new/python-nbxmpp-7.5.0/debian/changelog --- old/python-nbxmpp-7.4.0/debian/changelog 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/debian/changelog 2026-11-01 19:50:06.000000000 +0100 @@ -1,5 +1,5 @@ python3-nbxmpp-nightly ({DATE}) unstable; urgency=low - * https://dev.gajim.org/gajim/python-nbxmpp/-/commits/master + * https://gitlab.com/gajim/python-nbxmpp/-/commits/master -- nbxmpp CI <[email protected]> {DATE_TIME} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/debian/control new/python-nbxmpp-7.5.0/debian/control --- old/python-nbxmpp-7.4.0/debian/control 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/debian/control 2026-11-01 19:50:06.000000000 +0100 @@ -14,9 +14,9 @@ python3-setuptools (>= 65.0.0), Standards-Version: 4.1.4 Rules-Requires-Root: no -Homepage: https://dev.gajim.org/gajim/python-nbxmpp -Vcs-Git: https://dev.gajim.org/gajim/python-nbxmpp.git -Vcs-Browser: https://dev.gajim.org/gajim/python-nbxmpp/tree/master +Homepage: https://gitlab.com/gajim/python-nbxmpp +Vcs-Git: https://gitlab.com/gajim/python-nbxmpp.git +Vcs-Browser: https://gitlab.com/gajim/python-nbxmpp/tree/master Package: python3-nbxmpp-nightly Architecture: all diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/docker/build-test/Dockerfile new/python-nbxmpp-7.5.0/docker/build-test/Dockerfile --- old/python-nbxmpp-7.4.0/docker/build-test/Dockerfile 1970-01-01 01:00:00.000000000 +0100 +++ new/python-nbxmpp-7.5.0/docker/build-test/Dockerfile 2026-11-01 19:50:06.000000000 +0100 @@ -0,0 +1,36 @@ +FROM debian:unstable-slim + +COPY requirements.txt requirements.txt +RUN apt-get update +RUN apt-get -y install \ + python3 \ + build-essential \ + dh-python \ + debhelper-compat \ + pkg-config \ + python-is-python3 \ + python3-all \ + pybuild-plugin-pyproject \ + python3-venv \ + python3-gi \ + python3-gi-cairo \ + python3-gssapi \ + python3-idna \ + python3-pip \ + python3-packaging \ + python3-precis-i18n \ + python3-setuptools \ + python3-wheel \ + gir1.2-soup-3.0 \ + nodejs \ + npm + +RUN npm install -g [email protected] + +ENV VIRTUAL_ENV=/opt/venv +RUN python -m venv --system-site-packages $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +RUN pip install --no-cache-dir -r requirements.txt + +CMD bash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/docker/build-test/requirements.txt new/python-nbxmpp-7.5.0/docker/build-test/requirements.txt --- old/python-nbxmpp-7.4.0/docker/build-test/requirements.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/python-nbxmpp-7.5.0/docker/build-test/requirements.txt 2026-11-01 19:50:06.000000000 +0100 @@ -0,0 +1,12 @@ +setuptools +PyGObject +precis-i18n +packaging +gssapi +idna +isort==7.0.0 +twine +coverage +ruff==0.14.8 +black==24.10.0 +git+https://gitlab.com/gajim/release-helper.git diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/docker/deploy/Dockerfile new/python-nbxmpp-7.5.0/docker/deploy/Dockerfile --- old/python-nbxmpp-7.4.0/docker/deploy/Dockerfile 1970-01-01 01:00:00.000000000 +0100 +++ new/python-nbxmpp-7.5.0/docker/deploy/Dockerfile 2026-11-01 19:50:06.000000000 +0100 @@ -0,0 +1,8 @@ +FROM python:3.10-alpine + +RUN apk update +RUN apk add --no-cache git python3 py3-pip +RUN pip install --no-cache-dir git+https://gitlab.com/gajim/release-helper.git +RUN pip install --no-cache-dir twine + +CMD bash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/docker/publish/Dockerfile new/python-nbxmpp-7.5.0/docker/publish/Dockerfile --- old/python-nbxmpp-7.4.0/docker/publish/Dockerfile 1970-01-01 01:00:00.000000000 +0100 +++ new/python-nbxmpp-7.5.0/docker/publish/Dockerfile 2026-11-01 19:50:06.000000000 +0100 @@ -0,0 +1,8 @@ +FROM python:3.10-alpine + +RUN apk update +RUN apk add --no-cache git openssh +RUN pip install --no-cache-dir git+https://gitlab.com/gajim/release-helper.git +RUN pip install packaging + +CMD bash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/__init__.py new/python-nbxmpp-7.5.0/nbxmpp/__init__.py --- old/python-nbxmpp-7.4.0/nbxmpp/__init__.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/__init__.py 2026-11-01 19:50:06.000000000 +0100 @@ -4,4 +4,4 @@ from .protocol import * # noqa: F403, E402 -__version__: str = "7.4.0" +__version__: str = "7.5.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/client.py new/python-nbxmpp-7.5.0/nbxmpp/client.py --- old/python-nbxmpp-7.4.0/nbxmpp/client.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/client.py 2026-11-01 19:50:06.000000000 +0100 @@ -28,6 +28,8 @@ from nbxmpp.const import StreamError from nbxmpp.const import StreamState from nbxmpp.dispatcher import StanzaDispatcher +from nbxmpp.modules.ogp import OpenGraph +from nbxmpp.modules.search import Search from nbxmpp.namespaces import Namespace from nbxmpp.protocol import BindRequest from nbxmpp.protocol import Features @@ -260,7 +262,7 @@ def set_domain(self, domain: str | None) -> None: self._domain = domain - def set_resource(self, resource: str) -> None: + def set_resource(self, resource: str | None) -> None: self._resource = resource def set_mode(self, mode: Mode) -> None: @@ -762,6 +764,8 @@ @overload def get_module(self, name: Literal["OOB"]) -> OOB: ... @overload + def get_module(self, name: Literal["OpenGraph"]) -> OpenGraph: ... + @overload def get_module(self, name: Literal["OpenPGP"]) -> OpenPGP: ... @overload def get_module(self, name: Literal["PGPLegacy"]) -> PGPLegacy: ... @@ -784,6 +788,8 @@ @overload def get_module(self, name: Literal["Roster"]) -> Roster: ... @overload + def get_module(self, name: Literal["Search"]) -> Search: ... + @overload def get_module(self, name: Literal["SecurityLabels"]) -> SecurityLabels: ... @overload def get_module(self, name: Literal["SoftwareVersion"]) -> SoftwareVersion: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/dispatcher.py new/python-nbxmpp-7.5.0/nbxmpp/dispatcher.py --- old/python-nbxmpp-7.4.0/nbxmpp/dispatcher.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/dispatcher.py 2026-11-01 19:50:06.000000000 +0100 @@ -69,6 +69,7 @@ from nbxmpp.modules.replies import Replies from nbxmpp.modules.retraction import Retraction from nbxmpp.modules.roster import Roster +from nbxmpp.modules.search import Search from nbxmpp.modules.security_labels import SecurityLabels from nbxmpp.modules.software_version import SoftwareVersion from nbxmpp.modules.tune import Tune @@ -105,13 +106,12 @@ NBXMPPModuleNameT = Literal[ "Activity", - "Activity", "AdHoc", "Annotations", "Attention", - "BasePresence", - "BaseMessage", "BaseIq", + "BaseMessage", + "BasePresence", "Blocking", "Captcha", "ChatMarkers", @@ -140,6 +140,7 @@ "Nickname", "OMEMO", "OOB", + "OpenGraph", "OpenPGP", "PEPBookmarks", "PGPLegacy", @@ -152,22 +153,23 @@ "Replies", "Retraction", "Roster", + "Search", "SecurityLabels", "SoftwareVersion", "Tune", "UserAvatar", + "VCard4", "VCardAvatar", "VCardTemp", - "VCard4", ] NBXMPPModuleT = ( Activity | AdHoc | Annotations | Attention - | BasePresence - | BaseMessage | BaseIq + | BaseMessage + | BasePresence | Blocking | Captcha | ChatMarkers @@ -209,13 +211,14 @@ | Replies | Retraction | Roster + | Search | SecurityLabels | SoftwareVersion | Tune | UserAvatar + | VCard4 | VCardAvatar | VCardTemp - | VCard4 ) @@ -362,6 +365,8 @@ @overload def get_module(self, name: Literal["Roster"]) -> Roster: ... @overload + def get_module(self, name: Literal["Search"]) -> Search: ... + @overload def get_module(self, name: Literal["SecurityLabels"]) -> SecurityLabels: ... @overload def get_module(self, name: Literal["SoftwareVersion"]) -> SoftwareVersion: ... @@ -429,6 +434,7 @@ self._modules["Replies"] = Replies(self._client) self._modules["Retraction"] = Retraction(self._client) self._modules["Roster"] = Roster(self._client) + self._modules["Search"] = Search(self._client) self._modules["SecurityLabels"] = SecurityLabels(self._client) self._modules["SoftwareVersion"] = SoftwareVersion(self._client) self._modules["Tune"] = Tune(self._client) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/modules/dataforms.py new/python-nbxmpp-7.5.0/nbxmpp/modules/dataforms.py --- old/python-nbxmpp-7.4.0/nbxmpp/modules/dataforms.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/modules/dataforms.py 2026-11-01 19:50:06.000000000 +0100 @@ -360,7 +360,7 @@ def value(self, value: str) -> None: if value is None: # type: ignore value = "" - self.setTagData("value", value) + self.setTagData("value", value.strip()) @value.deleter def value(self) -> None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/modules/search.py new/python-nbxmpp-7.5.0/nbxmpp/modules/search.py --- old/python-nbxmpp-7.4.0/nbxmpp/modules/search.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-nbxmpp-7.5.0/nbxmpp/modules/search.py 2026-11-01 19:50:06.000000000 +0100 @@ -0,0 +1,104 @@ +# Copyright (C) 2019 Philipp Hörist <philipp AT hoerist.com> +# +# This file is part of nbxmpp. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import annotations + +from typing import Any +from typing import TYPE_CHECKING + +from nbxmpp.errors import MalformedStanzaError +from nbxmpp.errors import StanzaError +from nbxmpp.modules.base import BaseModule +from nbxmpp.modules.dataforms import MultipleDataForm +from nbxmpp.modules.dataforms import SimpleDataForm +from nbxmpp.modules.util import finalize +from nbxmpp.namespaces import Namespace +from nbxmpp.protocol import Iq +from nbxmpp.protocol import JID +from nbxmpp.protocol import Node +from nbxmpp.structs import SearchFields +from nbxmpp.task import iq_request_task + +if TYPE_CHECKING: + from nbxmpp.client import Client + + +FIELDS = [ + "instructions", + "first", + "last", + "nick", + "email", +] + + +class Search(BaseModule): + def __init__(self, client: Client) -> None: + BaseModule.__init__(self, client) + + self.handlers = [] + self._client = client + + @iq_request_task + def request_form(self, jid: JID) -> Any: + _task = yield + + iq = Iq(typ="get", to=jid, queryNS=Namespace.SEARCH) + + response = yield iq + if response.isError(): + raise StanzaError(response) + + query = response.getTag("query", namespace=Namespace.SEARCH) + if query is None: + raise MalformedStanzaError("no query node found", response) + + dataform = query.getTag("x", namespace=Namespace.DATA) + if dataform is None: + yield parse_simple_fields(query) + else: + yield finalize(_task, SimpleDataForm(extend=dataform)) + + @iq_request_task + def send_form(self, jid: JID, form: SimpleDataForm | SearchFields) -> Any: + _task = yield + + iq = Iq(typ="set", to=jid, queryNS=Namespace.SEARCH) + item = iq.setQuery() + if isinstance(form, SearchFields): + for field, value in form: + item.setTagData(field, value) + else: + item.addChild(node=form) + + response = yield iq + if response.isError(): + raise StanzaError(response) + + query = response.getTag("query", namespace=Namespace.SEARCH) + if query is None: + raise MalformedStanzaError("no query node found", response) + + dataform = query.getTag("x", namespace=Namespace.DATA) + if dataform is None: + yield finalize(_task, MultipleDataForm(extend=dataform)) + + else: + raise MalformedStanzaError("only dataforms supported", response) + + +def parse_simple_fields(query: Node) -> SearchFields: + data: dict[str, str] = {} + for child in query.getChildren(): + if not isinstance(child, Node): + continue + name = child.getName() + if name not in FIELDS: + continue + + data[name] = child.getData() + + return SearchFields(**data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/modules/user_avatar.py new/python-nbxmpp-7.5.0/nbxmpp/modules/user_avatar.py --- old/python-nbxmpp-7.4.0/nbxmpp/modules/user_avatar.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/modules/user_avatar.py 2026-11-01 19:50:06.000000000 +0100 @@ -10,6 +10,7 @@ from typing import TYPE_CHECKING import hashlib +import logging from collections.abc import Iterator from dataclasses import asdict from dataclasses import dataclass @@ -29,11 +30,15 @@ from nbxmpp.task import iq_request_task from nbxmpp.util import b64decode from nbxmpp.util import b64encode +from nbxmpp.util import normalize_sha1 if TYPE_CHECKING: from nbxmpp.client import Client +log = logging.getLogger("nbxmpp.m.user_avatar") + + class UserAvatar(BaseModule): _depends = { @@ -82,8 +87,14 @@ ) return + default_avatar_sha = normalize_sha1(item.getAttr("id") or "") + if default_avatar_sha is None: + self._log.warning("Received avatar with invalid sha") + self._log.warning(stanza) + raise NodeProcessed + try: - data = AvatarMetaData.from_node(metadata, item.getAttr("id")) + data = AvatarMetaData.from_node(metadata, default_avatar_sha) except Exception as error: self._log.warning("Malformed user avatar data: %s", error) self._log.warning(stanza) @@ -128,7 +139,11 @@ if not metadata.getChildren(): yield task.set_result(None) - yield AvatarMetaData.from_node(metadata, item.getAttr("id")) + default_avatar_sha = normalize_sha1(item.getAttr("id") or "") + if default_avatar_sha is None: + raise MalformedStanzaError("Invalid avatar sha", item) + + yield AvatarMetaData.from_node(metadata, default_avatar_sha) @iq_request_task def set_avatar(self, avatar: Avatar | None, public: bool = False): @@ -253,24 +268,6 @@ return item -def _get_info_attrs( - avatar: bytes, avatar_sha: str, height: int | None, width: int | None -) -> dict[str, str | int]: - info_attrs = { - "id": avatar_sha, - "bytes": len(avatar), - "type": "image/png", - } - - if height is not None: - info_attrs["height"] = height - - if width is not None: - info_attrs["width"] = width - - return info_attrs - - @dataclass class AvatarInfo: bytes: int @@ -280,21 +277,6 @@ height: int | None = None width: int | None = None - def __post_init__(self) -> None: - if self.bytes is None: - raise ValueError - if self.id is None: - raise ValueError - if self.type is None: - raise ValueError - - self.bytes = int(self.bytes) - - if self.height is not None: - self.height = int(self.height) - if self.width is not None: - self.width = int(self.width) - def to_dict(self) -> dict[str, str | int]: info_dict = asdict(self) if self.height is None: @@ -325,14 +307,41 @@ infos: list[AvatarInfo] = [] info_nodes = node.getTags("info") for info in info_nodes: + + sha = normalize_sha1(info.getAttr("id") or "") + if sha is None: + log.warning("Invalid sha on avatar metadata\n%s", node) + continue + + try: + bytes_ = int(info.getAttr("bytes") or "") + except Exception: + log.warning("Invalid bytes attribute on avatar metadata\n%s", node) + continue + + type_ = info.getAttr("type") + if not type_: + log.warning("Missing type attribute on avatar metadata\n%s", node) + continue + + try: + height = int(info.getAttr("height") or "") + except Exception: + height = None + + try: + width = int(info.getAttr("width") or "") + except Exception: + width = None + infos.append( AvatarInfo( - bytes=info.getAttr("bytes"), - id=info.getAttr("id"), - type=info.getAttr("type"), - url=info.getAttr("url"), - height=info.getAttr("height"), - width=info.getAttr("width"), + bytes=bytes_, + id=sha, + type=type_, + url=info.getAttr("url") or None, + height=height, + width=width, ) ) return cls(infos=infos, default=default) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/sasl.py new/python-nbxmpp-7.5.0/nbxmpp/sasl.py --- old/python-nbxmpp-7.4.0/nbxmpp/sasl.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/sasl.py 2026-11-01 19:50:06.000000000 +0100 @@ -13,7 +13,7 @@ import hashlib import hmac import logging -import os +import secrets from hashlib import pbkdf2_hmac from gi.repository import Gio @@ -384,7 +384,7 @@ BaseMechanism.__init__(self, *args, **kwargs) self._channel_binding_data: ChannelBindingData | None = None self._gs2_header = "n,," - self._client_nonce = "%x" % int(binascii.hexlify(os.urandom(24)), 16) + self._client_nonce = binascii.hexlify(secrets.token_bytes(32)).decode() self._client_first_message_bare = None self._server_signature = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/structs.py new/python-nbxmpp-7.5.0/nbxmpp/structs.py --- old/python-nbxmpp-7.4.0/nbxmpp/structs.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/structs.py 2026-11-01 19:50:06.000000000 +0100 @@ -11,6 +11,7 @@ from typing import NamedTuple from typing import TYPE_CHECKING +import dataclasses import logging import secrets import time @@ -1539,3 +1540,18 @@ uri: str landing_url: str | None expire: datetime | None + + +@dataclass +class SearchFields: + instructions: str + first: str + last: str + nick: str + email: str + + def __iter__(self): + for field_ in dataclasses.fields(self): + if field_.name == "instructions": + continue + yield (field_.name, getattr(self, field_.name)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/nbxmpp/util.py new/python-nbxmpp-7.5.0/nbxmpp/util.py --- old/python-nbxmpp-7.4.0/nbxmpp/util.py 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/nbxmpp/util.py 2026-11-01 19:50:06.000000000 +0100 @@ -11,10 +11,8 @@ from typing import TYPE_CHECKING import base64 -import binascii import hashlib import logging -import os import re import uuid import xml.etree.ElementTree as ET @@ -355,10 +353,6 @@ raise -def get_rand_number() -> int: - return int(binascii.hexlify(os.urandom(6)), 16) - - def get_invalid_xml_regex() -> re.Pattern[str]: # \ufddo -> \ufdef range c = "\ufdd0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/pyproject.toml new/python-nbxmpp-7.5.0/pyproject.toml --- old/python-nbxmpp-7.4.0/pyproject.toml 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/pyproject.toml 2026-11-01 19:50:06.000000000 +0100 @@ -36,7 +36,7 @@ ] [project.urls] -repository = "https://dev.gajim.org/gajim/python-nbxmpp" +repository = "https://gitlab.com/gajim/python-nbxmpp" [tool.setuptools.packages.find] include = ["nbxmpp*"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-nbxmpp-7.4.0/python-nbxmpp.doap new/python-nbxmpp-7.5.0/python-nbxmpp.doap --- old/python-nbxmpp-7.4.0/python-nbxmpp.doap 2026-08-26 18:54:51.000000000 +0200 +++ new/python-nbxmpp-7.5.0/python-nbxmpp.doap 2026-11-01 19:50:06.000000000 +0100 @@ -16,8 +16,8 @@ </description> <homepage rdf:resource="https://gajim.org/"/> - <wiki rdf:resource="https://dev.gajim.org/gajim/python-nbxmpp/-/wikis/home"/> - <bug-database rdf:resource="https://dev.gajim.org/gajim/python-nbxmpp/-/issues"/> + <wiki rdf:resource="https://gitlab.com/gajim/python-nbxmpp/-/wikis/home"/> + <bug-database rdf:resource="https://gitlab.com/gajim/python-nbxmpp/-/issues"/> <category rdf:resource="https://linkmauve.fr/ns/xmpp-doap#category-library"/> <category rdf:resource="http://api.gnome.org/doap-extensions#apps"/> <license rdf:resource="http://usefulinc.com/doap/licenses/gplv3"/> @@ -28,8 +28,8 @@ <repository> <GitRepository> - <location rdf:resource="https://dev.gajim.org/gajim/python-nbxmpp.git"/> - <browse rdf:resource="https://dev.gajim.org/gajim/python-nbxmpp"/> + <location rdf:resource="https://gitlab.com/gajim/python-nbxmpp.git"/> + <browse rdf:resource="https://gitlab.com/gajim/python-nbxmpp"/> </GitRepository> </repository> @@ -96,6 +96,13 @@ </xmpp:SupportedXep> </implements> <implements> + <xmpp:SupportedXep> + <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0055.html"/> + <xmpp:status>complete</xmpp:status> + <xmpp:version>1.3</xmpp:version> + </xmpp:SupportedXep> + </implements> + <implements> <xmpp:SupportedXep> <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0059.html"/> <xmpp:status>complete</xmpp:status>
