Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-matrix-nio for openSUSE:Factory checked in at 2023-09-04 22:53:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-matrix-nio (Old) and /work/SRC/openSUSE:Factory/.python-matrix-nio.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-matrix-nio" Mon Sep 4 22:53:16 2023 rev:3 rq:1108788 version:0.21.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-matrix-nio/python-matrix-nio.changes 2023-07-19 19:10:30.648522905 +0200 +++ /work/SRC/openSUSE:Factory/.python-matrix-nio.new.1766/python-matrix-nio.changes 2023-09-04 22:53:49.812293463 +0200 @@ -1,0 +2,19 @@ +Mon Sep 4 03:30:04 UTC 2023 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 0.21.2: + * Breaking Changes + + [#416] Drop support for end-of-life python3.7 + + [#413] Drop usage of logbook in favor of standard library logging + * Features + + [#409] Support m.space.parent and m.space.child events + + [#418] Add ability to knock on a room, and enable knocking for a room + * Miscellaneous Tasks + + [#401] Removing skip for passing test + + [#406] [#407] [#414] Add content to built-with-nio + * Bug Fixes + + [#422] async_client.whoami will alter the state of async_client + correctly, and accept all spec-compliant fields. + + [#408] Properly generate code coverage +- Add patch remove-future-requirement.patch, dropping dependency on future. + +------------------------------------------------------------------- Old: ---- matrix_nio-0.20.2.tar.gz New: ---- matrix_nio-0.21.2.tar.gz remove-future-requirement.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-matrix-nio.spec ++++++ --- /var/tmp/diff_new_pack.IxLNsL/_old 2023-09-04 22:53:51.560355254 +0200 +++ /var/tmp/diff_new_pack.IxLNsL/_new 2023-09-04 22:53:51.564355395 +0200 @@ -17,23 +17,23 @@ Name: python-matrix-nio -Version: 0.20.2 +Version: 0.21.2 Release: 0 Summary: A Python Matrix client library, designed according to sans I/O principles License: ISC URL: https://github.com/poljar/matrix-nio Source: https://files.pythonhosted.org/packages/source/m/matrix_nio/matrix_nio-%{version}.tar.gz +# PATCH-FIX-UPSTREAM gh#poljar/matrix-nio#440 +Patch0: remove-future-requirement.patch BuildRequires: %{python_module pip} BuildRequires: %{python_module poetry-core} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: python-Logbook >= 1.5.3 Requires: python-aiofiles >= 0.6.0 Requires: python-aiohttp >= 3.7.4 Requires: python-aiohttp-socks >= 0.7.0 -Requires: python-future >= 0.18.2 Requires: python-h11 >= 0.12.0 Requires: python-h2 >= 4.0.0 Requires: python-jsonschema >= 3.2.0 @@ -46,11 +46,9 @@ Suggests: python-python-olm >= 3.1.3 BuildArch: noarch # SECTION test requirements -BuildRequires: %{python_module Logbook >= 1.5.3} BuildRequires: %{python_module aiofiles >= 0.6.0} BuildRequires: %{python_module aiohttp >= 3.7.4} BuildRequires: %{python_module aiohttp-socks >= 0.7.0} -BuildRequires: %{python_module future >= 0.18.2} BuildRequires: %{python_module h11 >= 0.12.0} BuildRequires: %{python_module h2 >= 4.0.0} BuildRequires: %{python_module jsonschema >= 3.2.0} ++++++ matrix_nio-0.20.2.tar.gz -> matrix_nio-0.21.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/PKG-INFO new/matrix_nio-0.21.2/PKG-INFO --- old/matrix_nio-0.20.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/matrix_nio-0.21.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +1,14 @@ Metadata-Version: 2.1 Name: matrix-nio -Version: 0.20.2 +Version: 0.21.2 Summary: A Python Matrix client library, designed according to sans I/O principles. Home-page: https://github.com/poljar/matrix-nio License: ISC Author: Damir JeliÄ Author-email: pol...@termina.org.uk -Requires-Python: >=3.7.0,<4.0.0 +Requires-Python: >=3.8.0,<4.0.0 Classifier: License :: OSI Approved Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 @@ -20,12 +19,10 @@ Requires-Dist: aiohttp-socks (>=0.7.0,<0.8.0) Requires-Dist: atomicwrites (>=1.4.0,<2.0.0) ; extra == "e2e" Requires-Dist: cachetools (>=4.2.1,<5.0.0) ; extra == "e2e" -Requires-Dist: dataclasses (>=0.7,<0.8) ; python_version >= "3.6" and python_version < "3.7" Requires-Dist: future (>=0.18.2,<0.19.0) Requires-Dist: h11 (>=0.14.0,<0.15.0) Requires-Dist: h2 (>=4.0.0,<5.0.0) Requires-Dist: jsonschema (>=4.4.0,<5.0.0) -Requires-Dist: logbook (>=1.5.3,<2.0.0) Requires-Dist: peewee (>=3.14.4,<4.0.0) ; extra == "e2e" Requires-Dist: pycryptodome (>=3.10.1,<4.0.0) Requires-Dist: python-olm (>=3.1.3,<4.0.0) ; extra == "e2e" @@ -45,7 +42,7 @@ nio is a multilayered [Matrix](https://matrix.org/) client library. The underlying base layer doesn't do any network IO on its own, but on top of that -is a full fledged batteries-included asyncio layer using +is a full-fledged batteries-included asyncio layer using [aiohttp](https://github.com/aio-libs/aiohttp/). File IO is only done if you enable end-to-end encryption (E2EE). @@ -62,10 +59,11 @@ - â transparent end-to-end encryption (EE2E) - â encrypted file uploads & downloads +- â space parents/children - â manual and emoji verification - â custom [authentication types](https://matrix.org/docs/spec/client_server/r0.6.0#id183) - â well-integrated type system -- â kick, ban and unban +- â knocking, kick, ban and unban - â typing notifications - â message redaction - â token based login @@ -73,12 +71,11 @@ - â read receipts - â live syncing - â `m.tag`s -- â python 2.7 support - â cross-signing support - â server-side key backups (room key backup, "Secure Backup") - â user deactivation ([#112](https://github.com/poljar/matrix-nio/issues/112)) +- â threading support - â in-room emoji verification -- â room upgrades and `m.room.tombstone` events ([#47](https://github.com/poljar/matrix-nio/issues/47)) Installation ------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/README.md new/matrix_nio-0.21.2/README.md --- old/matrix_nio-0.20.2/README.md 2023-03-28 04:30:52.188544800 +0200 +++ new/matrix_nio-0.21.2/README.md 2023-07-14 12:03:32.938272500 +0200 @@ -9,7 +9,7 @@ nio is a multilayered [Matrix](https://matrix.org/) client library. The underlying base layer doesn't do any network IO on its own, but on top of that -is a full fledged batteries-included asyncio layer using +is a full-fledged batteries-included asyncio layer using [aiohttp](https://github.com/aio-libs/aiohttp/). File IO is only done if you enable end-to-end encryption (E2EE). @@ -26,10 +26,11 @@ - â transparent end-to-end encryption (EE2E) - â encrypted file uploads & downloads +- â space parents/children - â manual and emoji verification - â custom [authentication types](https://matrix.org/docs/spec/client_server/r0.6.0#id183) - â well-integrated type system -- â kick, ban and unban +- â knocking, kick, ban and unban - â typing notifications - â message redaction - â token based login @@ -37,12 +38,11 @@ - â read receipts - â live syncing - â `m.tag`s -- â python 2.7 support - â cross-signing support - â server-side key backups (room key backup, "Secure Backup") - â user deactivation ([#112](https://github.com/poljar/matrix-nio/issues/112)) +- â threading support - â in-room emoji verification -- â room upgrades and `m.room.tombstone` events ([#47](https://github.com/poljar/matrix-nio/issues/47)) Installation ------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/__init__.py new/matrix_nio-0.21.2/nio/__init__.py --- old/matrix_nio-0.20.2/nio/__init__.py 2023-03-28 04:30:52.188544800 +0200 +++ new/matrix_nio-0.21.2/nio/__init__.py 2023-07-14 11:44:32.557834100 +0200 @@ -10,7 +10,6 @@ from .event_builders import * from .events import * from .exceptions import * -from .log import logger_group from .monitors import * from .responses import * from .rooms import * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/api.py new/matrix_nio-0.21.2/nio/api.py --- old/matrix_nio-0.20.2/nio/api.py 2023-03-28 04:30:52.188544800 +0200 +++ new/matrix_nio-0.21.2/nio/api.py 2023-07-14 11:44:32.557834100 +0200 @@ -778,6 +778,36 @@ ) @staticmethod + def room_knock( + access_token: str, + room_id: str, + reason: Optional[str] = None, + ) -> Tuple[str, str, str]: + """Knocks on a room for the user. + + Returns the HTTP method, HTTP path and data for the request. + + Args: + access_token (str): The access token to be used with the request. + room_id (str): The room id of the room that the user will be + knocking on. + reason (str, optional): The reason the user is knocking. + """ + + path = ["knock", room_id] + query_parameters = {"access_token": access_token} + body = {} + + if reason: + body["reason"] = reason + + return ( + "POST", + Api._build_path(path, query_parameters), + Api.to_json(body), + ) + + @staticmethod def room_invite(access_token, room_id, user_id): # type (str, str, str) -> Tuple[str, str, str] """Invite a user to a room. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/client/async_client.py new/matrix_nio-0.21.2/nio/client/async_client.py --- old/matrix_nio-0.20.2/nio/client/async_client.py 2023-03-28 04:30:52.191878300 +0200 +++ new/matrix_nio-0.21.2/nio/client/async_client.py 2023-07-17 10:39:25.072212500 +0200 @@ -173,6 +173,8 @@ RoomKeyRequestResponse, RoomKickError, RoomKickResponse, + RoomKnockError, + RoomKnockResponse, RoomLeaveError, RoomLeaveResponse, RoomMessagesError, @@ -187,6 +189,7 @@ RoomRedactResponse, RoomResolveAliasError, RoomResolveAliasResponse, + RoomSendError, RoomSendResponse, RoomTypingError, RoomTypingResponse, @@ -1545,7 +1548,7 @@ content: Dict[Any, Any], tx_id: Optional[str] = None, ignore_unverified_devices: bool = False, - ): + ) -> Union[RoomSendResponse, RoomSendError]: """Send a message to a room. Calls receive_response() to update the client state if necessary. @@ -2235,6 +2238,50 @@ return await self._send(JoinResponse, method, path, data) @logged_in_async + async def room_knock( + self, + room_id: str, + reason: Optional[str] = None, + ) -> Union[RoomKnockResponse, RoomKnockError]: + """Knock on a room. + + Calls receive_response() to update the client state if necessary. + + Returns either a `RoomKnockResponse` if the request was successful or + a `RoomKnockError` if there was an error with the request. + + Args: + room_id (str): The room id of the room that the user is + knocking on. + reason (str, optional): The reason for the knock. + """ + method, path, data = Api.room_knock( + self.access_token, + room_id, + reason, + ) + return await self._send(RoomKnockResponse, method, path, data) + + @logged_in_async + async def room_enable_knocking( + self, + room_id: str, + ) -> Union[RoomPutStateResponse, RoomPutStateError]: + """Enables knocking for a room. + + Returns either a `RoomPutStateResponse` if the request was successful + or a `RoomPutStateError` if there was an error with the request. + + Args: + room_id (str): The room id of the room to enable knocking for. + """ + return await self.room_put_state( + room_id, + event_type="m.room.join_rules", + content={"join_rule": "knock"}, + ) + + @logged_in_async async def room_invite( self, room_id: str, @@ -3205,7 +3252,15 @@ return await self._send(UploadFilterResponse, method, path, data) - async def whoami(self): + async def whoami(self) -> Union[WhoamiResponse, WhoamiError]: + """Get information about the logged-in user from the homeserver. + + Returns either a `WhoamiResponse` if the request was successful + or a `WhoamiError` if there was an error with the request. + + On a successful response, the client's state will be updated with + the user_id and device_id returned, if different from the current state. + """ if self.access_token is None: raise ValueError("No access_token is set.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/client/base_client.py new/matrix_nio-0.21.2/nio/client/base_client.py --- old/matrix_nio-0.20.2/nio/client/base_client.py 2023-03-28 04:30:52.191878300 +0200 +++ new/matrix_nio-0.21.2/nio/client/base_client.py 2023-07-17 10:39:25.072212500 +0200 @@ -14,6 +14,7 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import logging from collections import defaultdict from dataclasses import dataclass, field from functools import wraps @@ -31,8 +32,6 @@ Union, ) -from logbook import Logger - from ..crypto import ENCRYPTION_ENABLED, DeviceStore, OlmDevice, OutgoingKeyRequest from ..events import ( AccountDataEvent, @@ -50,7 +49,6 @@ UnknownBadEvent, ) from ..exceptions import EncryptionError, LocalProtocolError, MembersSyncError -from ..log import logger_group from ..responses import ( ErrorResponse, JoinedMembersResponse, @@ -71,6 +69,7 @@ ShareGroupSessionResponse, SyncResponse, ToDeviceResponse, + WhoamiResponse, ) from ..rooms import MatrixInvitedRoom, MatrixRoom @@ -80,17 +79,13 @@ from ..event_builders import ToDeviceMessage -if False: - from ..crypto import Sas - try: from json.decoder import JSONDecodeError except ImportError: JSONDecodeError = ValueError # type: ignore -logger = Logger("nio.client") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) def logged_in(func): @@ -1028,6 +1023,11 @@ ) self.rooms[room_id].users[response.user_id].status_msg = response.status_msg + def _handle_whoami_response(self, response: WhoamiResponse): + self.user_id = response.user_id + self.device_id = response.device_id or self.device_id + # self.is_guest = response.is_guest + def receive_response( self, response: Response ) -> Union[None, Coroutine[Any, Any, None]]: @@ -1079,6 +1079,8 @@ pass elif isinstance(response, PresenceGetResponse): self._handle_presence_response(response) + elif isinstance(response, WhoamiResponse): + self._handle_whoami_response(response) elif isinstance(response, ErrorResponse): if response.soft_logout: self.access_token = "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/client/http_client.py new/matrix_nio-0.21.2/nio/client/http_client.py --- old/matrix_nio-0.20.2/nio/client/http_client.py 2023-03-28 04:30:52.191878300 +0200 +++ new/matrix_nio-0.21.2/nio/client/http_client.py 2023-07-14 11:44:32.557834100 +0200 @@ -16,6 +16,7 @@ import cgi import json +import logging import pprint from builtins import str, super from collections import deque @@ -26,7 +27,6 @@ import h2 import h11 -from logbook import Logger try: from urllib.parse import urlparse @@ -45,7 +45,6 @@ TransportResponse, TransportType, ) -from ..log import logger_group from ..responses import ( DeleteDevicesAuthResponse, DeleteDevicesResponse, @@ -88,18 +87,13 @@ from . import Client, ClientConfig from .base_client import logged_in, store_loaded -if False: - from .crypto import OlmDevice - from .event_builders import ToDeviceMessage - try: from json.decoder import JSONDecodeError except ImportError: JSONDecodeError = ValueError # type: ignore -logger = Logger("nio.client") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) def connected(func): @@ -1187,7 +1181,7 @@ logger.info(f"Received response of type: {request_info.request_class}") else: logger.info( - ("Error with response of type type: {}, " "error code {}").format( + "Error with response of type type: {}, error code {}".format( request_info.request_class, response.status_code ) ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/crypto/log.py new/matrix_nio-0.21.2/nio/crypto/log.py --- old/matrix_nio-0.20.2/nio/crypto/log.py 2023-03-28 04:30:52.191878300 +0200 +++ new/matrix_nio-0.21.2/nio/crypto/log.py 2023-07-14 11:44:32.557834100 +0200 @@ -14,9 +14,6 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from logbook import Logger +import logging -from ..log import logger_group - -logger = Logger("nio.encryption") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/crypto/olm_machine.py new/matrix_nio-0.21.2/nio/crypto/olm_machine.py --- old/matrix_nio-0.20.2/nio/crypto/olm_machine.py 2023-03-28 04:30:52.191878300 +0200 +++ new/matrix_nio-0.21.2/nio/crypto/olm_machine.py 2023-07-14 11:44:32.561834000 +0200 @@ -438,7 +438,7 @@ if event.algorithm == Olm._megolm_algorithm: self.received_key_requests[event.request_id] = event else: - logger.warn( + logger.warning( f"Received key request from {event.sender} via {event.requesting_device_id} " f"with an unknown algorithm: {event.algorithm}" ) @@ -618,13 +618,13 @@ try: self.share_with_ourselves(event) except KeyShareError as error: - logger.warn(error) + logger.warning(error) except EncryptionError as error: # We can safely ignore this, the share_with_ourselves # method will queue up the device for a key claiming # request when that is done the event will be put back # in the received_key_requests queue. - logger.warn(error) + logger.warning(error) except OlmTrustError: return False @@ -672,7 +672,7 @@ try: device = self.device_store[user_id][device_id] except KeyError: - logger.warn( + logger.warning( f"Curve key for user {user_id} and device {device_id} not found, failed to start Olm session" ) continue @@ -708,7 +708,7 @@ self.received_key_requests.update(events) else: - logger.warn( + logger.warning( "Signature verification for one-time key of " f"device {device_id} of user {user_id} failed, could not start " "Olm session." @@ -732,7 +732,7 @@ continue if payload["user_id"] != user_id or payload["device_id"] != device_id: - logger.warn( + logger.warning( "Mismatch in keys payload of device " f"{payload['device_id']} " f"({device_id}) of user {payload['user_id']} " @@ -976,7 +976,7 @@ ) except OlmSessionError as e: - logger.warn(e) + logger.warning(e) return self.inbound_group_store.add(session) @@ -1007,7 +1007,7 @@ continue if not self.session_store.get(device.curve25519): - logger.warn(f"Missing session for device {device.id}") + logger.warning(f"Missing session for device {device.id}") missing[user_id].append(device.id) return missing @@ -1042,7 +1042,7 @@ if not device: # TODO we should probably mark this user for a key query. - logger.warn( + logger.warning( "Attempted to mark a device for Olm session " f"unwedging, but no device was found for user {sender} with " f"sender key {sender_key}" @@ -1056,7 +1056,7 @@ if session: session_age = datetime.now() - session.creation_time if session_age < self._unwedging_interval: - logger.warn( + logger.warning( f"Attempted to mark device {device.device_id} of user " f"{device.user_id} for Olm session unwedging, but a new " "session was created recently." @@ -1216,7 +1216,7 @@ # Only accept forwarded room keys from our own trusted devices if not device or not device.verified or not device.user_id == self.user_id: - logger.warn( + logger.warning( "Received a forwarded room key from a untrusted device " f"{event.sender}, {sender_key}" ) @@ -1291,7 +1291,7 @@ return DummyEvent.from_dict(payload, sender, sender_key) else: - logger.warn(f"Received unsupported Olm event of type {payload['type']}") + logger.warning(f"Received unsupported Olm event of type {payload['type']}") return None def message_index_ok(self, message_index, event): @@ -1332,7 +1332,7 @@ try: device = self.device_store[event.sender][event.device_id] except KeyError: - logger.warn( + logger.warning( f"Received a undecryptable Megolm event from a unknown " f"device: {event.sender} {event.device_id}" ) @@ -1342,7 +1342,7 @@ session = self.session_store.get(device.curve25519) if not session: - logger.warn( + logger.warning( f"Received a undecryptable Megolm event from a device " f"with no Olm sessions: {event.sender} {event.device_id}" ) @@ -1405,14 +1405,14 @@ f"with session id {event.session_id} for room {room_id}" ) self.check_if_wedged(event) - logger.warn(message) + logger.warning(message) raise EncryptionError(message) try: plaintext, message_index = session.decrypt(event.ciphertext) except OlmGroupSessionError as e: message = f"Error decrypting megolm event: {str(e)}" - logger.warn(message) + logger.warning(message) raise EncryptionError(message) if not self.message_index_ok(message_index, event): @@ -1449,7 +1449,7 @@ message = ( f"Device keys mismatch in event sent by device {device.id}." ) - logger.warn(message) + logger.warning(message) raise EncryptionError(message) logger.info(f"Event {event.event_id} successfully verified") @@ -1506,7 +1506,7 @@ own_key = self.account.identity_keys["curve25519"] own_ciphertext = event.ciphertext[own_key] except KeyError: - logger.warn("Olm event doesn't contain ciphertext for our key") + logger.warning("Olm event doesn't contain ciphertext for our key") return None if own_ciphertext["type"] == 0: @@ -1514,7 +1514,9 @@ elif own_ciphertext["type"] == 1: message = OlmMessage(own_ciphertext["body"]) else: - logger.warn(f"Unsupported olm message type: {own_ciphertext['type']}") + logger.warning( + f"Unsupported olm message type: {own_ciphertext['type']}" + ) return None return self.decrypt(event.sender, event.sender_key, message) @@ -1709,7 +1711,7 @@ session = self.session_store.get(device.curve25519) if not session: - logger.warn( + logger.warning( f"Missing Olm session for user {user_id} and device " f"{device.id}, skipping" ) @@ -1967,7 +1969,7 @@ forwarding_chain, ) except OlmSessionError as e: - logger.warn(f"Error importing inbound group session: {e}") + logger.warning(f"Error importing inbound group session: {e}") return None @staticmethod @@ -2120,7 +2122,7 @@ try: device = self.device_store[event.sender][event.from_device] except KeyError: - logger.warn( + logger.warning( f"Received key verification event from unknown device: {event.sender} {event.from_device}" ) self.users_for_key_query.add(event.sender) @@ -2135,7 +2137,7 @@ ) if new_sas.canceled: - logger.warn( + logger.warning( f"Received malformed key verification event from {event.sender} {event.from_device}" ) message = new_sas.get_cancellation() @@ -2165,7 +2167,7 @@ sas = self.key_verifications.get(event.transaction_id, None) if not sas: - logger.warn( + logger.warning( "Received key verification event with an unknown " f"transaction id from {event.sender}" ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/misc.py new/matrix_nio-0.21.2/nio/events/misc.py --- old/matrix_nio-0.20.2/nio/events/misc.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/events/misc.py 2023-07-14 11:44:32.561834000 +0200 @@ -1,4 +1,12 @@ # -*- coding: utf-8 -*- +import logging +from dataclasses import dataclass, field +from functools import wraps +from typing import Any, Dict, Optional, Union + +from jsonschema.exceptions import SchemaError, ValidationError + +from ..schemas import validate_json # Copyright © 2018-2019 Damir JeliÄ <pol...@termina.org.uk> # @@ -14,18 +22,8 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from dataclasses import dataclass, field -from functools import wraps -from typing import Any, Dict, Optional, Union - -from jsonschema.exceptions import SchemaError, ValidationError -from logbook import Logger - -from ..log import logger_group -from ..schemas import validate_json -logger = Logger("nio.events") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) def validate_or_badevent( @@ -36,7 +34,7 @@ try: validate_json(parsed_dict, schema) except (ValidationError, SchemaError) as e: - logger.warn(f"Error validating event: {str(e)}") + logger.warning(f"Error validating event: {str(e)}") try: return BadEvent.from_dict(parsed_dict) except KeyError: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/presence.py new/matrix_nio-0.21.2/nio/events/presence.py --- old/matrix_nio-0.20.2/nio/events/presence.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/events/presence.py 2023-07-14 11:44:32.561834000 +0200 @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +import logging +from dataclasses import dataclass, field +from typing import Optional + +from ..schemas import Schemas +from .misc import verify # Copyright © 2018-2019 Damir JeliÄ <pol...@termina.org.uk> # @@ -14,17 +20,8 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from dataclasses import dataclass, field -from typing import Optional - -from logbook import Logger - -from ..log import logger_group -from ..schemas import Schemas -from .misc import verify -logger = Logger("nio.events") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) @dataclass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/room_events.py new/matrix_nio-0.21.2/nio/events/room_events.py --- old/matrix_nio-0.20.2/nio/events/room_events.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/events/room_events.py 2023-07-14 11:44:32.561834000 +0200 @@ -161,6 +161,10 @@ return RedactionEvent.from_dict(event_dict) elif event_dict["type"] == "m.room.tombstone": return RoomUpgradeEvent.from_dict(event_dict) + elif event_dict["type"] == "m.space.parent": + return RoomSpaceParentEvent.from_dict(event_dict) + elif event_dict["type"] == "m.space.child": + return RoomSpaceChildEvent.from_dict(event_dict) elif event_dict["type"] == "m.room.encrypted": return Event.parse_encrypted_event(event_dict) elif event_dict["type"] == "m.sticker": @@ -815,6 +819,48 @@ @dataclass +class RoomSpaceParentEvent(Event): + """Event holding the parent space of a room. + + Attributes: + state_key (str): The parent space's room + + """ + + state_key: str = field() + canonical: bool = False + + @classmethod + @verify(Schemas.room_space_parent) + def from_dict(cls, parsed_dict): + content_dict = parsed_dict["content"] + return cls( + parsed_dict, parsed_dict["state_key"], content_dict.get("canonical", False) + ) + + +@dataclass +class RoomSpaceChildEvent(Event): + """Event holding the child rooms of a space. + + Attributes: + state_key (str): The child room of a space + + """ + + state_key: str = field() + suggested: bool = False + + @classmethod + @verify(Schemas.room_space_child) + def from_dict(cls, parsed_dict): + content_dict = parsed_dict["content"] + return cls( + parsed_dict, parsed_dict["state_key"], content_dict.get("suggested", False) + ) + + +@dataclass class RoomMessage(Event): """Abstract room message class. @@ -1437,7 +1483,7 @@ cases except for when membership is join, the user ID in the sender attribute does not need to match the user ID in the state_key. membership (str): The membership state of the user. One of "invite", - "join", "leave", "ban". + "join", "leave", "ban", "knock". prev_membership (str, optional): The previous membership state that this one is overwriting. Can be None in which case the membership state is assumed to have been "leave". diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/events/to_device.py new/matrix_nio-0.21.2/nio/events/to_device.py --- old/matrix_nio-0.20.2/nio/events/to_device.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/events/to_device.py 2023-07-14 11:44:32.561834000 +0200 @@ -116,7 +116,7 @@ if content["algorithm"] == "m.olm.v1.curve25519-aes-sha2": return OlmEvent.from_dict(event_dict) - logger.warn( + logger.warning( f"Received an encrypted event with an unknown algorithm {content['algorithm']}." ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/http.py new/matrix_nio-0.21.2/nio/http.py --- old/matrix_nio-0.20.2/nio/http.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/http.py 2023-07-14 11:44:32.561834000 +0200 @@ -17,6 +17,7 @@ from __future__ import unicode_literals import json +import logging import pprint import time from builtins import bytes, super @@ -28,12 +29,8 @@ import h2.connection import h2.events import h11 -from logbook import Logger -from .log import logger_group - -logger = Logger("nio.http") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) USER_AGENT = "nio" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/log.py new/matrix_nio-0.21.2/nio/log.py --- old/matrix_nio-0.20.2/nio/log.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/log.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright © 2018 Damir JeliÄ <pol...@termina.org.uk> -# -# Permission to use, copy, modify, and/or distribute this software for -# any purpose with or without fee is hereby granted, provided that the -# above copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -import logbook - -logger_group = logbook.LoggerGroup() -logger_group.level = logbook.CRITICAL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/responses.py new/matrix_nio-0.21.2/nio/responses.py --- old/matrix_nio-0.20.2/nio/responses.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/responses.py 2023-07-17 08:15:09.032432800 +0200 @@ -17,6 +17,7 @@ from __future__ import unicode_literals +import logging from builtins import str from dataclasses import dataclass, field from datetime import datetime @@ -24,7 +25,6 @@ from typing import Any, Dict, Generator, List, Optional, Set, Tuple, Union from jsonschema.exceptions import SchemaError, ValidationError -from logbook import Logger from .event_builders import ToDeviceMessage from .events import ( @@ -37,11 +37,9 @@ ) from .events.presence import PresenceEvent from .http import TransportResponse -from .log import logger_group from .schemas import Schemas, validate_json -logger = Logger("nio.responses") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) __all__ = [ @@ -99,6 +97,8 @@ "RoomInviteError", "RoomKickResponse", "RoomKickError", + "RoomKnockResponse", + "RoomKnockError", "RoomLeaveResponse", "RoomLeaveError", "RoomForgetResponse", @@ -180,10 +180,10 @@ @wraps(f) def wrapper(cls, parsed_dict, *args, **kwargs): try: - logger.info("Validating response schema") + logger.debug("Validating response schema %r: %s", schema, parsed_dict) validate_json(parsed_dict, schema) except (SchemaError, ValidationError) as e: - logger.warn("Error validating response: " + str(e.message)) + logger.warning("Error validating response: " + str(e.message)) if pass_arguments: return error_class.from_dict(parsed_dict, *args, **kwargs) @@ -507,6 +507,12 @@ pass +class RoomKnockError(ErrorResponse): + """A response representing a unsuccessful room knock request.""" + + pass + + class RoomLeaveError(ErrorResponse): pass @@ -1265,6 +1271,12 @@ return JoinError.from_dict(parsed_dict) +class RoomKnockResponse(RoomIdResponse): + @staticmethod + def create_error(parsed_dict): + return RoomKnockError.from_dict(parsed_dict) + + class RoomLeaveResponse(EmptyResponse): @staticmethod def create_error(parsed_dict): @@ -1900,6 +1912,8 @@ @dataclass class WhoamiResponse(Response): user_id: str = field() + device_id: Optional[str] = field() + is_guest: Optional[bool] = field() @classmethod @verify(Schemas.whoami, WhoamiError) @@ -1907,7 +1921,11 @@ cls, parsed_dict: Dict[Any, Any], ) -> Union["WhoamiResponse", WhoamiError]: - return cls(parsed_dict["user_id"]) + return cls( + parsed_dict["user_id"], + parsed_dict.get("device_id"), + parsed_dict.get("is_guest", False), + ) @dataclass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/rooms.py new/matrix_nio-0.21.2/nio/rooms.py --- old/matrix_nio-0.20.2/nio/rooms.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/rooms.py 2023-07-14 11:44:32.561834000 +0200 @@ -17,13 +17,13 @@ from __future__ import unicode_literals +import logging from builtins import super from collections import defaultdict from enum import Enum -from typing import Any, DefaultDict, Dict, List, NamedTuple, Optional, Tuple, Union +from typing import Any, DefaultDict, Dict, List, NamedTuple, Optional, Set, Tuple, Union from jsonschema.exceptions import SchemaError, ValidationError -from logbook import Logger from .events import ( AccountDataEvent, @@ -46,16 +46,16 @@ RoomJoinRulesEvent, RoomMemberEvent, RoomNameEvent, + RoomSpaceChildEvent, + RoomSpaceParentEvent, RoomTopicEvent, RoomUpgradeEvent, TagEvent, TypingNoticeEvent, ) -from .log import logger_group from .responses import RoomSummary, UnreadNotifications -logger = Logger("nio.rooms") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) __all__ = [ "MatrixRoom", @@ -82,6 +82,8 @@ self.canonical_alias = None # type: Optional[str] self.topic = None # type: Optional[str] self.name = None # type: Optional[str] + self.parents = set() # type: Set[str] + self.children = set() # type: Set[str] self.users = dict() # type: Dict[str, MatrixUser] self.invited_users = dict() # type: Dict[str, MatrixUser] self.names = defaultdict(list) # type: DefaultDict[str, List[str]] @@ -409,6 +411,12 @@ ) self.users[user_id].power_level = level + elif isinstance(event, RoomSpaceParentEvent): + self.parents.add(event.state_key) + + elif isinstance(event, RoomSpaceChildEvent): + self.children.add(event.state_key) + def handle_account_data(self, event: AccountDataEvent) -> None: if isinstance(event, FullyReadEvent): self.fully_read_marker = event.event_id diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/schemas.py new/matrix_nio-0.21.2/nio/schemas.py --- old/matrix_nio-0.20.2/nio/schemas.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/schemas.py 2023-07-17 08:15:09.032432800 +0200 @@ -924,6 +924,43 @@ "required": ["type", "sender", "content", "state_key"], } + room_space_parent = { + "type": "object", + "properties": { + "sender": {"type": "string", "format": "user_id"}, + "state_key": {"type": "string"}, + "type": {"type": "string"}, + "content": { + "type": "object", + "properties": { + "canonical": {"type": "boolean", "default": False}, + "via": {"type": "array", "items": {"type": "string"}}, + }, + "required": ["via"], + }, + }, + "required": ["type", "sender", "content", "state_key"], + } + + room_space_child = { + "type": "object", + "properties": { + "sender": {"type": "string", "format": "user_id"}, + "state_key": {"type": "string"}, + "type": {"type": "string"}, + "content": { + "type": "object", + "properties": { + "suggested": {"type": "boolean", "default": False}, + "via": {"type": "array", "items": {"type": "string"}}, + "order": {"type": "string"}, + }, + "required": ["via"], + }, + }, + "required": ["type", "sender", "content", "state_key"], + } + room_avatar = { "type": "object", "properties": { @@ -1856,7 +1893,11 @@ whoami = { "type": "object", - "user_id": "string", + "properties": { + "user_id": {"type": "string", "format": "user_id"}, + "device_id": {"type": "string"}, + "is_guest": {"type": "boolean"}, + }, "required": ["user_id"], } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/nio/store/log.py new/matrix_nio-0.21.2/nio/store/log.py --- old/matrix_nio-0.20.2/nio/store/log.py 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/nio/store/log.py 2023-07-14 11:44:32.565834000 +0200 @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import logging # Copyright © 2019 Damir JeliÄ <pol...@termina.org.uk> # @@ -14,9 +15,5 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from logbook import Logger -from ..log import logger_group - -logger = Logger("nio.cryptostore") -logger_group.add_logger(logger) +logger = logging.getLogger(__name__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/matrix_nio-0.20.2/pyproject.toml new/matrix_nio-0.21.2/pyproject.toml --- old/matrix_nio-0.20.2/pyproject.toml 2023-03-28 04:30:52.195211600 +0200 +++ new/matrix_nio-0.21.2/pyproject.toml 2023-07-17 10:42:00.347297200 +0200 @@ -4,7 +4,7 @@ [tool.poetry] name = "matrix-nio" -version = "0.20.2" +version = "0.21.2" description = "A Python Matrix client library, designed according to sans I/O principles." authors = ["Damir JeliÄ <pol...@termina.org.uk>"] license = "ISC" @@ -16,14 +16,12 @@ ] [tool.poetry.dependencies] -python = "^3.7.0" +python = "^3.8.0" future = "^0.18.2" aiohttp = "^3.8.3" aiofiles = "^23.1.0" -dataclasses = { version = "^0.7", python = ">= 3.6, <3.7" } h11 = "^0.14.0" h2 = "^4.0.0" -logbook = "^1.5.3" jsonschema = "^4.4.0" unpaddedbase64 = "^2.1.0" pycryptodome = "^3.10.1" ++++++ remove-future-requirement.patch ++++++ >From 572180f38c3c4da74e5cc0dde5cb5bd9581bbbef Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdc...@users.noreply.github.com> Date: Sat, 2 Sep 2023 23:32:57 +0200 Subject: [PATCH] Remove future dependency --- nio/crypto/sas.py | 2 +- pyproject.toml | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/nio/crypto/sas.py b/nio/crypto/sas.py index 32f04375..51f383ec 100644 --- a/nio/crypto/sas.py +++ b/nio/crypto/sas.py @@ -19,11 +19,11 @@ from builtins import bytes, super from datetime import datetime, timedelta from enum import Enum +from itertools import zip_longest from typing import List, Optional, Tuple from uuid import uuid4 import olm -from future.moves.itertools import zip_longest from ..api import Api from ..event_builders import ToDeviceMessage diff --git a/pyproject.toml b/pyproject.toml index 3048b26d..29c9d551 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ packages = [ [tool.poetry.dependencies] python = "^3.8.0" -future = "^0.18.2" aiohttp = "^3.8.3" aiofiles = "^23.1.0" h11 = "^0.14.0"