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>

Reply via email to