Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 91e65700bd | |||
| 3bcb6a059f | |||
| 3a0aa6fe76 | |||
| 12ca87f5ea | |||
| 478a6c65eb | |||
| f835ab8de5 | |||
| 786b614fb2 | |||
| a8026209d2 | |||
| 2d12163cb4 | |||
| 9171bf3b35 | |||
| d2eab22de7 | |||
| e9069c9f91 | |||
| 49c9745b45 | |||
| bcff01b406 | |||
| 8841db4d27 | |||
| 19033313e6 | |||
| 68d9559fef | |||
| c81908bcd9 | |||
| 6e6d611f55 | |||
| 6ad1f9eac2 | |||
| 77dfc1f939 | |||
| aae2a38671 | |||
| c1878cd4ae | |||
| 7291c68eea | |||
| e3e0ae4ab1 | |||
| 4fe73f8f2f | |||
| 7154724671 | |||
| 37d9edcef2 | |||
| eee6474bce | |||
| 9be4db29f2 | |||
| aaca9773e3 | |||
| b220f8224e | |||
| a832212d4f | |||
| 109882230c | |||
| 166ffc0f23 | |||
| 4cc729d480 | |||
| f710d5480b | |||
| cc865fffc0 | |||
| a4904dcb04 | |||
| d6b7d49a61 | |||
| f1e43018b7 | |||
| b6cb610d50 | |||
| 5f12090fd7 | |||
| 336b0b9e89 | |||
| 4f87edc6e8 | |||
| b52ad6e4fa | |||
| 25c412b3c5 | |||
| 28fd28e92e | |||
| 8902b3031d | |||
| a6abee36bc | |||
| 0a67743d9e | |||
| 3727b84a51 | |||
| 6fb0c43106 | |||
| 45738e2739 | |||
| 3d2f5332c0 | |||
| 32fd9bc673 | |||
| 1f10c20806 | |||
| 06bbf1029c | |||
| 7615e2bf48 | |||
| cabd577460 | |||
| fc31b495b3 | |||
| ae5b997cfa | |||
| 694802eecd | |||
| 26b960b08b | |||
| 5946074d69 | |||
| 3555790b27 | |||
| fa907025f4 | |||
| 4e302b30b6 | |||
| 009b47badf | |||
| ab9c1e8f39 | |||
| 80ec81dcc5 | |||
| a01ee24734 | |||
| 8b50a9d01d | |||
| cce9484452 | |||
| 1e67191a79 | |||
| b22a14c828 | |||
| 127b940dc0 | |||
| 1026776380 | |||
| 5725712d47 | |||
| d40a939ff6 | |||
| 891f42f8c8 | |||
| 0a59372d9d | |||
| 36c8b66403 | |||
| 18b453488f | |||
| 451c08d868 | |||
| 20fb08ec80 | |||
| 79eb6c0cdc | |||
| 75576c151c | |||
| c26d6ffd3f | |||
| e1813f21ce | |||
| 1c69449179 | |||
| fb664cf159 | |||
| cdb89dcefe | |||
| c690fd16c4 |
@@ -47,7 +47,7 @@ if not IS_PR:
|
||||
"database": "sqlite",
|
||||
"extras": "all",
|
||||
}
|
||||
for version in ("3.9", "3.10", "3.11", "3.12.0-rc.2")
|
||||
for version in ("3.9", "3.10", "3.11", "3.12")
|
||||
)
|
||||
|
||||
trial_postgres_tests = [
|
||||
@@ -62,7 +62,7 @@ trial_postgres_tests = [
|
||||
if not IS_PR:
|
||||
trial_postgres_tests.append(
|
||||
{
|
||||
"python-version": "3.11",
|
||||
"python-version": "3.12",
|
||||
"database": "postgres",
|
||||
"postgres-version": "16",
|
||||
"extras": "all",
|
||||
|
||||
@@ -37,15 +37,18 @@ jobs:
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- '.rustfmt.toml'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
trial:
|
||||
- 'synapse/**'
|
||||
- 'tests/**'
|
||||
- 'rust/**'
|
||||
- '.ci/scripts/calculate_jobs.py'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
integration:
|
||||
- 'synapse/**'
|
||||
@@ -56,6 +59,9 @@ jobs:
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- 'docker/**'
|
||||
- '.ci/**'
|
||||
- 'scripts-dev/complement.sh'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
linting:
|
||||
- 'synapse/**'
|
||||
@@ -69,6 +75,7 @@ jobs:
|
||||
- 'mypy.ini'
|
||||
- 'pyproject.toml'
|
||||
- 'poetry.lock'
|
||||
- '.github/workflows/tests.yml'
|
||||
|
||||
check-sampleconfig:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -280,7 +287,6 @@ jobs:
|
||||
- check-lockfile
|
||||
- lint-clippy
|
||||
- lint-rustfmt
|
||||
- check-signoff
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: "true"
|
||||
|
||||
+118
@@ -1,3 +1,121 @@
|
||||
# Synapse 1.95.0rc1 (2023-10-17)
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- Remove legacy unspecced `knock_state_events` field returned in some responses. ([\#16403](https://github.com/matrix-org/synapse/issues/16403))
|
||||
- Fix a bug introduced in Synapse 1.81.0 where an `AttributeError` would be raised when `_matrix/client/v3/account/whoami` is called over a unix socket. Contributed by @Sir-Photch. ([\#16404](https://github.com/matrix-org/synapse/issues/16404))
|
||||
- Properly return inline media when content types have parameters. ([\#16440](https://github.com/matrix-org/synapse/issues/16440))
|
||||
- Prevent the purging of large rooms from timing out when Postgres is in use. The timeout which causes this issue was introduced in Synapse 1.88.0. ([\#16455](https://github.com/matrix-org/synapse/issues/16455))
|
||||
- Improve the performance of purging rooms, particularly encrypted rooms. ([\#16457](https://github.com/matrix-org/synapse/issues/16457))
|
||||
- Fix a bug introduced in Synapse 1.59.0 where servers could be incorrectly marked as available after an error response was received. ([\#16506](https://github.com/matrix-org/synapse/issues/16506))
|
||||
|
||||
### Improved Documentation
|
||||
|
||||
- Document internal background update mechanism. ([\#16420](https://github.com/matrix-org/synapse/issues/16420))
|
||||
- Fix a typo in the sql for [useful SQL for admins document](https://matrix-org.github.io/synapse/latest/usage/administration/useful_sql_for_admins.html). ([\#16477](https://github.com/matrix-org/synapse/issues/16477))
|
||||
|
||||
### Internal Changes
|
||||
|
||||
- Bump pyo3 from 0.17.1 to 0.19.2. ([\#16162](https://github.com/matrix-org/synapse/issues/16162))
|
||||
- Update registration of media repository URLs. ([\#16419](https://github.com/matrix-org/synapse/issues/16419))
|
||||
- Improve type hints. ([\#16421](https://github.com/matrix-org/synapse/issues/16421), [\#16468](https://github.com/matrix-org/synapse/issues/16468), [\#16469](https://github.com/matrix-org/synapse/issues/16469), [\#16507](https://github.com/matrix-org/synapse/issues/16507))
|
||||
- Refactor some code to simplify and better type receipts stream adjacent code. ([\#16426](https://github.com/matrix-org/synapse/issues/16426))
|
||||
- Factor out `MultiWriter` token from `RoomStreamToken`. ([\#16427](https://github.com/matrix-org/synapse/issues/16427))
|
||||
- Improve code comments. ([\#16428](https://github.com/matrix-org/synapse/issues/16428))
|
||||
- Reduce memory allocations. ([\#16429](https://github.com/matrix-org/synapse/issues/16429), [\#16431](https://github.com/matrix-org/synapse/issues/16431), [\#16433](https://github.com/matrix-org/synapse/issues/16433), [\#16434](https://github.com/matrix-org/synapse/issues/16434), [\#16438](https://github.com/matrix-org/synapse/issues/16438), [\#16444](https://github.com/matrix-org/synapse/issues/16444))
|
||||
- Remove unused method. ([\#16435](https://github.com/matrix-org/synapse/issues/16435))
|
||||
- Improve rate limiting logic. ([\#16441](https://github.com/matrix-org/synapse/issues/16441))
|
||||
- Do not block running of CI behind the check for sign-off on PRs. ([\#16454](https://github.com/matrix-org/synapse/issues/16454))
|
||||
- Update the release script to remind releaser to check for special release notes. ([\#16461](https://github.com/matrix-org/synapse/issues/16461))
|
||||
- Update complement.sh to match new public API shape. ([\#16466](https://github.com/matrix-org/synapse/issues/16466))
|
||||
- Clean up logging on event persister endpoints. ([\#16488](https://github.com/matrix-org/synapse/issues/16488))
|
||||
- Remove useless async job to delete device messages on sync, since we only deliver (and hence delete) up to 100 device messages at a time. ([\#16491](https://github.com/matrix-org/synapse/issues/16491))
|
||||
|
||||
### Updates to locked dependencies
|
||||
|
||||
* Bump bleach from 6.0.0 to 6.1.0. ([\#16451](https://github.com/matrix-org/synapse/issues/16451))
|
||||
* Bump jsonschema from 4.19.0 to 4.19.1. ([\#16500](https://github.com/matrix-org/synapse/issues/16500))
|
||||
* Bump netaddr from 0.8.0 to 0.9.0. ([\#16453](https://github.com/matrix-org/synapse/issues/16453))
|
||||
* Bump packaging from 23.1 to 23.2. ([\#16497](https://github.com/matrix-org/synapse/issues/16497))
|
||||
* Bump pillow from 10.0.1 to 10.1.0. ([\#16498](https://github.com/matrix-org/synapse/issues/16498))
|
||||
* Bump psycopg2 from 2.9.8 to 2.9.9. ([\#16452](https://github.com/matrix-org/synapse/issues/16452))
|
||||
* Bump pyo3-log from 0.8.3 to 0.8.4. ([\#16495](https://github.com/matrix-org/synapse/issues/16495))
|
||||
* Bump ruff from 0.0.290 to 0.0.292. ([\#16449](https://github.com/matrix-org/synapse/issues/16449))
|
||||
* Bump sentry-sdk from 1.31.0 to 1.32.0. ([\#16496](https://github.com/matrix-org/synapse/issues/16496))
|
||||
* Bump serde from 1.0.188 to 1.0.189. ([\#16494](https://github.com/matrix-org/synapse/issues/16494))
|
||||
* Bump types-bleach from 6.0.0.4 to 6.1.0.0. ([\#16450](https://github.com/matrix-org/synapse/issues/16450))
|
||||
* Bump types-jsonschema from 4.17.0.10 to 4.19.0.3. ([\#16499](https://github.com/matrix-org/synapse/issues/16499))
|
||||
|
||||
# Synapse 1.94.0 (2023-10-10)
|
||||
|
||||
No significant changes since 1.94.0rc1.
|
||||
However, please take note of the security advisory that follows.
|
||||
|
||||
## Security advisory
|
||||
|
||||
The following issue is fixed in 1.94.0 (and RC).
|
||||
|
||||
- [GHSA-5chr-wjw5-3gq4](https://github.com/matrix-org/synapse/security/advisories/GHSA-5chr-wjw5-3gq4) / [CVE-2023-45129](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-45129) — Moderate Severity
|
||||
|
||||
A malicious server ACL event can impact performance temporarily or permanently leading to a persistent denial of service.
|
||||
|
||||
Homeservers running on a closed federation (which presumably do not need to use server ACLs) are not affected.
|
||||
|
||||
See the advisory for more details. If you have any questions, email security@matrix.org.
|
||||
|
||||
|
||||
# Synapse 1.94.0rc1 (2023-10-03)
|
||||
|
||||
### Features
|
||||
|
||||
- Render plain, CSS, CSV, JSON and common image formats in the browser (inline) when requested through the /download endpoint. ([\#15988](https://github.com/matrix-org/synapse/issues/15988))
|
||||
- Add experimental support for [MSC4028](https://github.com/matrix-org/matrix-spec-proposals/pull/4028) to push all encrypted events to clients. ([\#16361](https://github.com/matrix-org/synapse/issues/16361))
|
||||
- Minor performance improvement when sending presence to federated servers. ([\#16385](https://github.com/matrix-org/synapse/issues/16385))
|
||||
- Minor performance improvement by caching server ACL checking. ([\#16360](https://github.com/matrix-org/synapse/issues/16360))
|
||||
|
||||
### Improved Documentation
|
||||
|
||||
- Add developer documentation concerning gradual schema migrations with column alterations. ([\#15691](https://github.com/matrix-org/synapse/issues/15691))
|
||||
- Improve documentation of the user directory search algorithm. ([\#16320](https://github.com/matrix-org/synapse/issues/16320))
|
||||
- Fix rendering of user admin API documentation around deactivation. This was broken in Synapse 1.91.0. ([\#16355](https://github.com/matrix-org/synapse/issues/16355))
|
||||
- Update documentation around message retention policies. ([\#16382](https://github.com/matrix-org/synapse/issues/16382))
|
||||
- Add note to `federation_domain_whitelist` config option to clarify its usage. ([\#16416](https://github.com/matrix-org/synapse/issues/16416))
|
||||
- Improve legacy release notes. ([\#16418](https://github.com/matrix-org/synapse/issues/16418))
|
||||
|
||||
### Deprecations and Removals
|
||||
|
||||
- Remove Python version from `/_synapse/admin/v1/server_version`. ([\#16380](https://github.com/matrix-org/synapse/issues/16380))
|
||||
|
||||
### Internal Changes
|
||||
|
||||
- Avoid running CI steps when the files they check have not been changed. ([\#14745](https://github.com/matrix-org/synapse/issues/14745), [\#16387](https://github.com/matrix-org/synapse/issues/16387))
|
||||
- Improve type hints. ([\#14911](https://github.com/matrix-org/synapse/issues/14911), [\#16350](https://github.com/matrix-org/synapse/issues/16350), [\#16356](https://github.com/matrix-org/synapse/issues/16356), [\#16395](https://github.com/matrix-org/synapse/issues/16395))
|
||||
- Added support for pydantic v2 in addition to pydantic v1. Contributed by Maxwell G (@gotmax23). ([\#16332](https://github.com/matrix-org/synapse/issues/16332))
|
||||
- Get CI to check PRs have been signed-off. ([\#16348](https://github.com/matrix-org/synapse/issues/16348))
|
||||
- Add missing licence header. ([\#16359](https://github.com/matrix-org/synapse/issues/16359))
|
||||
- Improve type hints, and bump types-psycopg2 from 2.9.21.11 to 2.9.21.14. ([\#16381](https://github.com/matrix-org/synapse/issues/16381))
|
||||
- Improve comments in `StateGroupBackgroundUpdateStore`. ([\#16383](https://github.com/matrix-org/synapse/issues/16383))
|
||||
- Update maturin configuration. ([\#16394](https://github.com/matrix-org/synapse/issues/16394))
|
||||
- Downgrade replication stream time out error log lines to warning. ([\#16401](https://github.com/matrix-org/synapse/issues/16401))
|
||||
|
||||
### Updates to locked dependencies
|
||||
|
||||
* Bump actions/checkout from 3 to 4. ([\#16250](https://github.com/matrix-org/synapse/issues/16250))
|
||||
* Bump cryptography from 41.0.3 to 41.0.4. ([\#16362](https://github.com/matrix-org/synapse/issues/16362))
|
||||
* Bump dawidd6/action-download-artifact from 2.27.0 to 2.28.0. ([\#16374](https://github.com/matrix-org/synapse/issues/16374))
|
||||
* Bump docker/setup-buildx-action from 2 to 3. ([\#16375](https://github.com/matrix-org/synapse/issues/16375))
|
||||
* Bump gitpython from 3.1.35 to 3.1.37. ([\#16376](https://github.com/matrix-org/synapse/issues/16376))
|
||||
* Bump msgpack from 1.0.5 to 1.0.6. ([\#16377](https://github.com/matrix-org/synapse/issues/16377))
|
||||
* Bump msgpack from 1.0.6 to 1.0.7. ([\#16412](https://github.com/matrix-org/synapse/issues/16412))
|
||||
* Bump phonenumbers from 8.13.19 to 8.13.22. ([\#16413](https://github.com/matrix-org/synapse/issues/16413))
|
||||
* Bump psycopg2 from 2.9.7 to 2.9.8. ([\#16409](https://github.com/matrix-org/synapse/issues/16409))
|
||||
* Bump pydantic from 2.3.0 to 2.4.2. ([\#16410](https://github.com/matrix-org/synapse/issues/16410))
|
||||
* Bump regex from 1.9.5 to 1.9.6. ([\#16408](https://github.com/matrix-org/synapse/issues/16408))
|
||||
* Bump sentry-sdk from 1.30.0 to 1.31.0. ([\#16378](https://github.com/matrix-org/synapse/issues/16378))
|
||||
* Bump types-netaddr from 0.8.0.9 to 0.9.0.1. ([\#16411](https://github.com/matrix-org/synapse/issues/16411))
|
||||
* Bump types-psycopg2 from 2.9.21.11 to 2.9.21.14. ([\#16381](https://github.com/matrix-org/synapse/issues/16381))
|
||||
* Bump urllib3 from 1.26.15 to 1.26.17. ([\#16422](https://github.com/matrix-org/synapse/issues/16422))
|
||||
|
||||
# Synapse 1.93.0 (2023-09-26)
|
||||
|
||||
No significant changes since 1.93.0rc1.
|
||||
|
||||
Generated
+24
-24
@@ -144,9 +144,9 @@ checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@@ -191,9 +191,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.17.3"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "268be0c73583c183f2b14052337465768c07726936a260f480f0857cb95ba543"
|
||||
checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
@@ -209,9 +209,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.17.3"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28fcd1e73f06ec85bf3280c48c67e731d8290ad3d730f8be9dc07946923005c8"
|
||||
checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
@@ -219,9 +219,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.17.3"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f6cb136e222e49115b3c51c32792886defbfb0adead26a688142b346a0b9ffc"
|
||||
checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
@@ -229,9 +229,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-log"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f47b0777feb17f61eea78667d61103758b243a871edc09a7786500a50467b605"
|
||||
checksum = "c09c2b349b6538d8a73d436ca606dab6ce0aaab4dad9e6b7bdd57a4f556c3bc3"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"log",
|
||||
@@ -240,9 +240,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.17.3"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94144a1266e236b1c932682136dc35a9dee8d3589728f68130c7c3861ef96b28"
|
||||
checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
@@ -252,9 +252,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.17.3"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8df9be978a2d2f0cdebabb03206ed73b11314701a5bfe71b0d753b81997777f"
|
||||
checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -263,9 +263,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pythonize"
|
||||
version = "0.17.0"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f7f0c136f5fbc01868185eef462800e49659eb23acca83b9e884367a006acb6"
|
||||
checksum = "8e35b716d430ace57e2d1b4afb51c9e5b7c46d2bce72926e07f9be6a98ced03e"
|
||||
dependencies = [
|
||||
"pyo3",
|
||||
"serde",
|
||||
@@ -291,9 +291,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.5"
|
||||
version = "1.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
|
||||
checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -303,9 +303,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
|
||||
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -332,18 +332,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.188"
|
||||
version = "1.0.189"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||
checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.188"
|
||||
version = "1.0.189"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Avoid running CI steps when the files they check have not been changed.
|
||||
@@ -1 +0,0 @@
|
||||
Add developer documentation concerning gradual schema migrations with column alterations.
|
||||
@@ -1 +0,0 @@
|
||||
Improve documentation of the user directory search algorithm.
|
||||
@@ -1 +0,0 @@
|
||||
Added support for pydantic v2 in addition to pydantic v1. Contributed by Maxwell G (@gotmax23).
|
||||
@@ -1 +0,0 @@
|
||||
Get CI to check PRs have been signed-off.
|
||||
@@ -1 +0,0 @@
|
||||
Improve type hints.
|
||||
@@ -1 +0,0 @@
|
||||
Fix rendering of user admin API documentation around deactivation. This was broken in Synapse 1.91.0.
|
||||
@@ -1 +0,0 @@
|
||||
Improve type hints.
|
||||
@@ -1 +0,0 @@
|
||||
Add missing licence header.
|
||||
@@ -1 +0,0 @@
|
||||
Cache server ACL checking.
|
||||
@@ -1 +0,0 @@
|
||||
Experimental support for [MSC4028](https://github.com/matrix-org/matrix-spec-proposals/pull/4028) to push all encrypted events to clients.
|
||||
@@ -1 +0,0 @@
|
||||
Improve type hints, and bump types-psycopg2 from 2.9.21.11 to 2.9.21.14.
|
||||
@@ -1 +0,0 @@
|
||||
Improve comments in `StateGroupBackgroundUpdateStore`.
|
||||
@@ -1 +0,0 @@
|
||||
Minor performance improvement when sending presence to federated servers.
|
||||
@@ -1 +0,0 @@
|
||||
Avoid running CI steps when the files they check have not been changed.
|
||||
@@ -0,0 +1 @@
|
||||
Enforce that old background updates have run when starting Synapse.
|
||||
@@ -0,0 +1 @@
|
||||
Fix long-standing bug where `/sync` incorrectly did not mark a room as `limited` in a sync requests when there were missing remote events.
|
||||
@@ -0,0 +1 @@
|
||||
Improve performance of delete device messages query, cf issue [16479](https://github.com/matrix-org/synapse/issues/16479).
|
||||
@@ -0,0 +1 @@
|
||||
Improve replication performance when purging rooms.
|
||||
@@ -0,0 +1 @@
|
||||
Run tests against Python 3.12.
|
||||
@@ -0,0 +1 @@
|
||||
Run trial & integration tests in continuous integration when `.ci` directory is modified.
|
||||
@@ -0,0 +1 @@
|
||||
Stop deleting from an unused table.
|
||||
@@ -0,0 +1 @@
|
||||
Improve documentation of presence router.
|
||||
@@ -0,0 +1 @@
|
||||
Force TLS certificate verification in user registration script.
|
||||
@@ -0,0 +1 @@
|
||||
Add a sentence to the opentracing docs on how you can have jaeger in a different place than synapse.
|
||||
@@ -0,0 +1 @@
|
||||
Bump matrix-synapse-ldap3 from 0.2.2 to 0.3.0.
|
||||
Vendored
+18
@@ -1,3 +1,21 @@
|
||||
matrix-synapse-py3 (1.95.0~rc1) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.95.0rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 17 Oct 2023 15:50:17 +0000
|
||||
|
||||
matrix-synapse-py3 (1.94.0) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.94.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 10 Oct 2023 10:57:41 +0100
|
||||
|
||||
matrix-synapse-py3 (1.94.0~rc1) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.94.0rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 03 Oct 2023 11:48:18 +0100
|
||||
|
||||
matrix-synapse-py3 (1.93.0) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.93.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Version API
|
||||
|
||||
This API returns the running Synapse version and the Python version
|
||||
on which Synapse is being run. This is useful when a Synapse instance
|
||||
This API returns the running Synapse version.
|
||||
This is useful when a Synapse instance
|
||||
is behind a proxy that does not forward the 'Server' header (which also
|
||||
contains Synapse version information).
|
||||
|
||||
@@ -15,7 +15,9 @@ It returns a JSON body like the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"server_version": "0.99.2rc1 (b=develop, abcdef123)",
|
||||
"python_version": "3.7.8"
|
||||
"server_version": "0.99.2rc1 (b=develop, abcdef123)"
|
||||
}
|
||||
```
|
||||
|
||||
*Changed in Synapse 1.94.0:* The `python_version` key was removed from the
|
||||
response body.
|
||||
|
||||
+134
-133
@@ -1186,9 +1186,9 @@ Synapse 0.33.0rc1 (2018-07-18)
|
||||
Features
|
||||
--------
|
||||
|
||||
- Enforce the specified API for report\_event. ([\#3316](https://github.com/matrix-org/synapse/issues/3316))
|
||||
- Enforce the specified API for `report_event`. ([\#3316](https://github.com/matrix-org/synapse/issues/3316))
|
||||
- Include CPU time from database threads in request/block metrics. ([\#3496](https://github.com/matrix-org/synapse/issues/3496), [\#3501](https://github.com/matrix-org/synapse/issues/3501))
|
||||
- Add CPU metrics for \_fetch\_event\_list. ([\#3497](https://github.com/matrix-org/synapse/issues/3497))
|
||||
- Add CPU metrics for `_fetch_event_list`. ([\#3497](https://github.com/matrix-org/synapse/issues/3497))
|
||||
- Optimisation to make handling incoming federation requests more efficient. ([\#3541](https://github.com/matrix-org/synapse/issues/3541))
|
||||
|
||||
Bugfixes
|
||||
@@ -1238,19 +1238,19 @@ Features
|
||||
- Add metrics to track appservice transactions ([\#3344](https://github.com/matrix-org/synapse/issues/3344))
|
||||
- Try to log more helpful info when a sig verification fails ([\#3372](https://github.com/matrix-org/synapse/issues/3372))
|
||||
- Synapse now uses the best performing JSON encoder/decoder according to your runtime (simplejson on CPython, stdlib json on PyPy). ([\#3462](https://github.com/matrix-org/synapse/issues/3462))
|
||||
- Add optional ip\_range\_whitelist param to AS registration files to lock AS IP access ([\#3465](https://github.com/matrix-org/synapse/issues/3465))
|
||||
- Add optional `ip_range_whitelist` param to AS registration files to lock AS IP access ([\#3465](https://github.com/matrix-org/synapse/issues/3465))
|
||||
- Reject invalid server names in federation requests ([\#3480](https://github.com/matrix-org/synapse/issues/3480))
|
||||
- Reject invalid server names in homeserver.yaml ([\#3483](https://github.com/matrix-org/synapse/issues/3483))
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Strip access\_token from outgoing requests ([\#3327](https://github.com/matrix-org/synapse/issues/3327))
|
||||
- Strip `access_token` from outgoing requests ([\#3327](https://github.com/matrix-org/synapse/issues/3327))
|
||||
- Redact AS tokens in logs ([\#3349](https://github.com/matrix-org/synapse/issues/3349))
|
||||
- Fix federation backfill from SQLite servers ([\#3355](https://github.com/matrix-org/synapse/issues/3355))
|
||||
- Fix event-purge-by-ts admin API ([\#3363](https://github.com/matrix-org/synapse/issues/3363))
|
||||
- Fix event filtering in get\_missing\_events handler ([\#3371](https://github.com/matrix-org/synapse/issues/3371))
|
||||
- Synapse is now stricter regarding accepting events which it cannot retrieve the prev\_events for. ([\#3456](https://github.com/matrix-org/synapse/issues/3456))
|
||||
- Fix event filtering in `get_missing_events` handler ([\#3371](https://github.com/matrix-org/synapse/issues/3371))
|
||||
- Synapse is now stricter regarding accepting events which it cannot retrieve the `prev_events` for. ([\#3456](https://github.com/matrix-org/synapse/issues/3456))
|
||||
- Fix bug where synapse would explode when receiving unicode in HTTP User-Agent header ([\#3470](https://github.com/matrix-org/synapse/issues/3470))
|
||||
- Invalidate cache on correct thread to avoid race ([\#3473](https://github.com/matrix-org/synapse/issues/3473))
|
||||
|
||||
@@ -1262,7 +1262,7 @@ Improved Documentation
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Remove was\_forgotten\_at ([\#3324](https://github.com/matrix-org/synapse/issues/3324))
|
||||
- Remove `was_forgotten_at` ([\#3324](https://github.com/matrix-org/synapse/issues/3324))
|
||||
|
||||
Misc
|
||||
----
|
||||
@@ -1285,7 +1285,7 @@ We are not aware of it being actively exploited but please upgrade asap.
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
- Fix event filtering in get\_missing\_events handler (PR #3371)
|
||||
- Fix event filtering in `get_missing_events` handler (PR #3371)
|
||||
|
||||
Changes in synapse v0.31.0 (2018-06-06)
|
||||
=======================================
|
||||
@@ -1309,7 +1309,7 @@ Features:
|
||||
Changes:
|
||||
|
||||
- daily user type phone home stats (PR #3264)
|
||||
- Use iter\* methods for \_filter\_events\_for\_server (PR #3267)
|
||||
- Use `iter*` methods for `_filter_events_for_server` (PR #3267)
|
||||
- Docs on consent bits (PR #3268)
|
||||
- Remove users from user directory on deactivate (PR #3277)
|
||||
- Avoid sending consent notice to guest users (PR #3288)
|
||||
@@ -1323,10 +1323,10 @@ Changes, python 3 migration:
|
||||
|
||||
- Replace some more comparisons with six (PR #3243) Thanks to @NotAFile!
|
||||
- replace some iteritems with six (PR #3244) Thanks to @NotAFile!
|
||||
- Add batch\_iter to utils (PR #3245) Thanks to @NotAFile!
|
||||
- Add `batch_iter` to utils (PR #3245) Thanks to @NotAFile!
|
||||
- use repr, not str (PR #3246) Thanks to @NotAFile!
|
||||
- Misc Python3 fixes (PR #3247) Thanks to @NotAFile!
|
||||
- Py3 storage/\_base.py (PR #3278) Thanks to @NotAFile!
|
||||
- Py3 `storage/_base.py` (PR #3278) Thanks to @NotAFile!
|
||||
- more six iteritems (PR #3279) Thanks to @NotAFile!
|
||||
- More Misc. py3 fixes (PR #3280) Thanks to @NotAFile!
|
||||
- remaining isintance fixes (PR #3281) Thanks to @NotAFile!
|
||||
@@ -1342,7 +1342,7 @@ Bugs:
|
||||
Changes in synapse v0.30.0 (2018-05-24)
|
||||
=======================================
|
||||
|
||||
\'Server Notices\' are a new feature introduced in Synapse 0.30. They provide a channel whereby server administrators can send messages to users on the server.
|
||||
"Server Notices" are a new feature introduced in Synapse 0.30. They provide a channel whereby server administrators can send messages to users on the server.
|
||||
|
||||
They are used as part of communication of the server policies (see `docs/consent_tracking.md`), however the intention is that they may also find a use for features such as "Message of the day".
|
||||
|
||||
@@ -1350,9 +1350,9 @@ This feature is specific to Synapse, but uses standard Matrix communication mech
|
||||
|
||||
Further Server Notices/Consent Tracking Support:
|
||||
|
||||
- Allow overriding the server\_notices user's avatar (PR #3273)
|
||||
- Allow overriding the `server_notices` user's avatar (PR #3273)
|
||||
- Use the localpart in the consent uri (PR #3272)
|
||||
- Support for putting %(consent\_uri)s in messages (PR #3271)
|
||||
- Support for putting `%(consent_uri)s` in messages (PR #3271)
|
||||
- Block attempts to send server notices to remote users (PR #3270)
|
||||
- Docs on consent bits (PR #3268)
|
||||
|
||||
@@ -1366,7 +1366,7 @@ Server Notices/Consent Tracking Support:
|
||||
- Infrastructure for a server notices room (PR #3232)
|
||||
- Send users a server notice about consent (PR #3236)
|
||||
- Reject attempts to send event before privacy consent is given (PR #3257)
|
||||
- Add a \'has\_consented\' template var to consent forms (PR #3262)
|
||||
- Add a `has_consented` template var to consent forms (PR #3262)
|
||||
- Fix dependency on jinja2 (PR #3263)
|
||||
|
||||
Features:
|
||||
@@ -1377,9 +1377,9 @@ Features:
|
||||
|
||||
Changes:
|
||||
|
||||
- Remove unused update\_external\_syncs (PR #3233)
|
||||
- Remove unused `update_external_syncs` (PR #3233)
|
||||
- Use stream rather depth ordering for push actions (PR #3212)
|
||||
- Make purge\_history operate on tokens (PR #3221)
|
||||
- Make `purge_history` operate on tokens (PR #3221)
|
||||
- Don't support limitless pagination (PR #3265)
|
||||
|
||||
Bug Fixes:
|
||||
@@ -1421,29 +1421,29 @@ Changes - General:
|
||||
|
||||
- nuke-room-from-db.sh: added postgresql option and help (PR #2337) Thanks to @rubo77!
|
||||
- Part user from rooms on account deactivate (PR #3201)
|
||||
- Make \'unexpected logging context\' into warnings (PR #3007)
|
||||
- Make "unexpected logging context" into warnings (PR #3007)
|
||||
- Set Server header in SynapseRequest (PR #3208)
|
||||
- remove duplicates from groups tables (PR #3129)
|
||||
- Improve exception handling for background processes (PR #3138)
|
||||
- Add missing consumeErrors to improve exception handling (PR #3139)
|
||||
- reraise exceptions more carefully (PR #3142)
|
||||
- Remove redundant call to preserve\_fn (PR #3143)
|
||||
- Trap exceptions thrown within run\_in\_background (PR #3144)
|
||||
- Remove redundant call to `preserve_fn` (PR #3143)
|
||||
- Trap exceptions thrown within `run_in_background` (PR #3144)
|
||||
|
||||
Changes - Refactors:
|
||||
|
||||
- Refactor /context to reuse pagination storage functions (PR #3193)
|
||||
- Refactor recent events func to use pagination func (PR #3195)
|
||||
- Refactor pagination DB API to return concrete type (PR #3196)
|
||||
- Refactor get\_recent\_events\_for\_room return type (PR #3198)
|
||||
- Refactor `get_recent_events_for_room` return type (PR #3198)
|
||||
- Refactor sync APIs to reuse pagination API (PR #3199)
|
||||
- Remove unused code path from member change DB func (PR #3200)
|
||||
- Refactor request handling wrappers (PR #3203)
|
||||
- transaction\_id, destination defined twice (PR #3209) Thanks to @damir-manapov!
|
||||
- `transaction_id`, destination defined twice (PR #3209) Thanks to @damir-manapov!
|
||||
- Refactor event storage to prepare for changes in state calculations (PR #3141)
|
||||
- Set Server header in SynapseRequest (PR #3208)
|
||||
- Use deferred.addTimeout instead of time\_bound\_deferred (PR #3127, #3178)
|
||||
- Use run\_in\_background in preference to preserve\_fn (PR #3140)
|
||||
- Use deferred.addTimeout instead of `time_bound_deferred` (PR #3127, #3178)
|
||||
- Use `run_in_background` in preference to `preserve_fn` (PR #3140)
|
||||
|
||||
Changes - Python 3 migration:
|
||||
|
||||
@@ -1463,29 +1463,29 @@ Changes - Python 3 migration:
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
- synapse fails to start under Twisted \>= 18.4 (PR #3157)
|
||||
- synapse fails to start under Twisted >= 18.4 (PR #3157)
|
||||
- Fix a class of logcontext leaks (PR #3170)
|
||||
- Fix a couple of logcontext leaks in unit tests (PR #3172)
|
||||
- Fix logcontext leak in media repo (PR #3174)
|
||||
- Escape label values in prometheus metrics (PR #3175, #3186)
|
||||
- Fix \'Unhandled Error\' logs with Twisted 18.4 (PR #3182) Thanks to @Half-Shot!
|
||||
- Fix "Unhandled Error" logs with Twisted 18.4 (PR #3182) Thanks to @Half-Shot!
|
||||
- Fix logcontext leaks in rate limiter (PR #3183)
|
||||
- notifications: Convert next\_token to string according to the spec (PR #3190) Thanks to @mujx!
|
||||
- notifications: Convert `next_token` to string according to the spec (PR #3190) Thanks to @mujx!
|
||||
- nuke-room-from-db.sh: fix deletion from search table (PR #3194) Thanks to @rubo77!
|
||||
- add guard for None on purge\_history api (PR #3160) Thanks to @krombel!
|
||||
- add guard for None on `purge_history` api (PR #3160) Thanks to @krombel!
|
||||
|
||||
Changes in synapse v0.28.1 (2018-05-01)
|
||||
=======================================
|
||||
|
||||
SECURITY UPDATE
|
||||
|
||||
- Clamp the allowed values of event depth received over federation to be \[0, 2\^63 - 1\]. This mitigates an attack where malicious events injected with depth = 2\^63 - 1 render rooms unusable. Depth is used to determine the cosmetic ordering of events within a room, and so the ordering of events in such a room will default to using stream\_ordering rather than depth (topological\_ordering).
|
||||
- Clamp the allowed values of event depth received over federation to be `[0, 2^63 - 1]`. This mitigates an attack where malicious events injected with `depth = 2^63 - 1` render rooms unusable. Depth is used to determine the cosmetic ordering of events within a room, and so the ordering of events in such a room will default to using `stream_ordering` rather than `depth` (topological ordering).
|
||||
|
||||
This is a temporary solution to mitigate abuse in the wild, whilst a long term solution is being implemented to improve how the depth parameter is used.
|
||||
|
||||
Full details at <https://docs.google.com/document/d/1I3fi2S-XnpO45qrpCsowZv8P8dHcNZ4fsBsbOW7KABI>
|
||||
|
||||
- Pin Twisted to \<18.4 until we stop using the private \_OpenSSLECCurve API.
|
||||
- Pin Twisted to <18.4 until we stop using the private `_OpenSSLECCurve` API.
|
||||
|
||||
Changes in synapse v0.28.0 (2018-04-26)
|
||||
=======================================
|
||||
@@ -1510,7 +1510,7 @@ Features:
|
||||
Changes:
|
||||
|
||||
- Synapse on PyPy (PR #2760) Thanks to @Valodim!
|
||||
- move handling of auto\_join\_rooms to RegisterHandler (PR #2996) Thanks to @krombel!
|
||||
- move handling of `auto_join_rooms` to RegisterHandler (PR #2996) Thanks to @krombel!
|
||||
- Improve handling of SRV records for federation connections (PR #3016) Thanks to @silkeh!
|
||||
- Document the behaviour of ResponseCache (PR #3059)
|
||||
- Preparation for py3 (PR #3061, #3073, #3074, #3075, #3103, #3104, #3106, #3107, #3109, #3110) Thanks to @NotAFile!
|
||||
@@ -1524,15 +1524,15 @@ Changes:
|
||||
- Clarify that SRV may not point to a CNAME (PR #3100) Thanks to @silkeh!
|
||||
- Use str(e) instead of e.message (PR #3103) Thanks to @NotAFile!
|
||||
- Use six.itervalues in some places (PR #3106) Thanks to @NotAFile!
|
||||
- Refactor store.have\_events (PR #3117)
|
||||
- Refactor `store.have_events` (PR #3117)
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
- Return 401 for invalid access\_token on logout (PR #2938) Thanks to @dklug!
|
||||
- Return 401 for invalid `access_token` on logout (PR #2938) Thanks to @dklug!
|
||||
- Return a 404 rather than a 500 on rejoining empty rooms (PR #3080)
|
||||
- fix federation\_domain\_whitelist (PR #3099)
|
||||
- Avoid creating events with huge numbers of prev\_events (PR #3113)
|
||||
- Reject events which have lots of prev\_events (PR #3118)
|
||||
- fix `federation_domain_whitelist` (PR #3099)
|
||||
- Avoid creating events with huge numbers of `prev_events` (PR #3113)
|
||||
- Reject events which have lots of `prev_events` (PR #3118)
|
||||
|
||||
Changes in synapse v0.27.4 (2018-04-13)
|
||||
=======================================
|
||||
@@ -1556,12 +1556,13 @@ v0.27.3-rc1 used a stale version of the develop branch so the changelog overstat
|
||||
Changes in synapse v0.27.3-rc1 (2018-04-09)
|
||||
===========================================
|
||||
|
||||
Notable changes include API support for joinability of groups. Also new metrics and phone home stats. Phone home stats include better visibility of system usage so we can tweak synpase to work better for all users rather than our own experience with matrix.org. Also, recording \'r30\' stat which is the measure we use to track overall growth of the Matrix ecosystem. It is defined as:-
|
||||
Notable changes include API support for joinability of groups. Also new metrics and phone home stats. Phone home stats include better visibility of system usage so we can tweak synpase to work better for all users rather than our own experience with matrix.org. Also, recording "r30" stat which is the measure we use to track overall growth of the Matrix ecosystem. It is defined as:-
|
||||
|
||||
Counts the number of native 30 day retained users, defined as:- \* Users who have created their accounts more than 30 days
|
||||
Counts the number of native 30 day retained users, defined as:
|
||||
|
||||
: - Where last seen at most 30 days ago
|
||||
- Where account creation and last\_seen are \> 30 days\"
|
||||
- Users who have created their accounts more than 30 days
|
||||
- Where last seen at most 30 days ago
|
||||
- Where account creation and `last_seen` are > 30 days
|
||||
|
||||
Features:
|
||||
|
||||
@@ -1577,9 +1578,9 @@ Features:
|
||||
Changes:
|
||||
|
||||
- Add a blurb explaining the main synapse worker (PR #2886) Thanks to @turt2live!
|
||||
- Replace old style error catching with \'as\' keyword (PR #3000) Thanks to @NotAFile!
|
||||
- Use .iter\* to avoid copies in StateHandler (PR #3006)
|
||||
- Linearize calls to \_generate\_user\_id (PR #3029)
|
||||
- Replace old style error catching with `as` keyword (PR #3000) Thanks to @NotAFile!
|
||||
- Use `.iter*` to avoid copies in StateHandler (PR #3006)
|
||||
- Linearize calls to `_generate_user_id` (PR #3029)
|
||||
- Remove last usage of ujson (PR #3030)
|
||||
- Use simplejson throughout (PR #3048)
|
||||
- Use static JSONEncoders (PR #3049)
|
||||
@@ -1588,13 +1589,13 @@ Changes:
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Add room\_id to the response of rooms/{roomId}/join (PR #2986) Thanks to @jplatte!
|
||||
- Add `room_id` to the response of rooms/{roomId}/join (PR #2986) Thanks to @jplatte!
|
||||
- Fix replication after switch to simplejson (PR #3015)
|
||||
- 404 correctly on missing paths via NoResource (PR #3022)
|
||||
- Fix error when claiming e2e keys from offline servers (PR #3034)
|
||||
- fix tests/storage/test\_user\_directory.py (PR #3042)
|
||||
- use PUT instead of POST for federating groups/m.join\_policy (PR #3070) Thanks to @krombel!
|
||||
- postgres port script: fix state\_groups\_pkey error (PR #3072)
|
||||
- fix `tests/storage/test_user_directory.py` (PR #3042)
|
||||
- use `PUT` instead of `POST` for federating `groups`/`m.join_policy` (PR #3070) Thanks to @krombel!
|
||||
- postgres port script: fix `state_groups_pkey` error (PR #3072)
|
||||
|
||||
Changes in synapse v0.27.2 (2018-03-26)
|
||||
=======================================
|
||||
@@ -1640,7 +1641,7 @@ Features:
|
||||
|
||||
- Add ability for ASes to override message send time (PR #2754)
|
||||
- Add support for custom storage providers for media repository (PR #2867, #2777, #2783, #2789, #2791, #2804, #2812, #2814, #2857, #2868, #2767)
|
||||
- Add purge API features, see [docs/admin\_api/purge\_history\_api.rst](docs/admin_api/purge_history_api.rst) for full details (PR #2858, #2867, #2882, #2946, #2962, #2943)
|
||||
- Add purge API features, see [docs/admin_api/purge_history_api.rst](docs/admin_api/purge_history_api.rst) for full details (PR #2858, #2867, #2882, #2946, #2962, #2943)
|
||||
- Add support for whitelisting 3PIDs that users can register. (PR #2813)
|
||||
- Add `/room/{id}/event/{id}` API (PR #2766)
|
||||
- Add an admin API to get all the media in a room (PR #2818) Thanks to @turt2live!
|
||||
@@ -1669,8 +1670,8 @@ Bug fixes:
|
||||
- Fix publicised groups GET API (singular) over federation (PR #2772)
|
||||
- Fix user directory when using `user_directory_search_all_users` config option (PR #2803, #2831)
|
||||
- Fix error on `/publicRooms` when no rooms exist (PR #2827)
|
||||
- Fix bug in quarantine\_media (PR #2837)
|
||||
- Fix url\_previews when no Content-Type is returned from URL (PR #2845)
|
||||
- Fix bug in `quarantine_media` (PR #2837)
|
||||
- Fix `url_previews` when no `Content-Type` is returned from URL (PR #2845)
|
||||
- Fix rare race in sync API when joining room (PR #2944)
|
||||
- Fix slow event search, switch back from GIST to GIN indexes (PR #2769, #2848)
|
||||
|
||||
@@ -1685,27 +1686,27 @@ Changes in synapse v0.26.0-rc1 (2017-12-13)
|
||||
Features:
|
||||
|
||||
- Add ability for ASes to publicise groups for their users (PR #2686)
|
||||
- Add all local users to the user\_directory and optionally search them (PR #2723)
|
||||
- Add all local users to the `user_directory` and optionally search them (PR #2723)
|
||||
- Add support for custom login types for validating users (PR #2729)
|
||||
|
||||
Changes:
|
||||
|
||||
- Update example Prometheus config to new format (PR #2648) Thanks to @krombel!
|
||||
- Rename redact\_content option to include\_content in Push API (PR #2650)
|
||||
- Rename `redact_content` option to `include_content` in Push API (PR #2650)
|
||||
- Declare support for r0.3.0 (PR #2677)
|
||||
- Improve upserts (PR #2684, #2688, #2689, #2713)
|
||||
- Improve documentation of workers (PR #2700)
|
||||
- Improve tracebacks on exceptions (PR #2705)
|
||||
- Allow guest access to group APIs for reading (PR #2715)
|
||||
- Support for posting content in federation\_client script (PR #2716)
|
||||
- Support for posting content in `federation_client` script (PR #2716)
|
||||
- Delete devices and pushers on logouts etc (PR #2722)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix database port script (PR #2673)
|
||||
- Fix internal server error on login with ldap\_auth\_provider (PR #2678) Thanks to @jkolo!
|
||||
- Fix internal server error on login with `ldap_auth_provider` (PR #2678) Thanks to @jkolo!
|
||||
- Fix error on sqlite 3.7 (PR #2697)
|
||||
- Fix OPTIONS on preview\_url (PR #2707)
|
||||
- Fix `OPTIONS` on `preview_url` (PR #2707)
|
||||
- Fix error handling on dns lookup (PR #2711)
|
||||
- Fix wrong avatars when inviting multiple users when creating room (PR #2717)
|
||||
- Fix 500 when joining matrix-dev (PR #2719)
|
||||
@@ -1729,7 +1730,7 @@ Changes in synapse v0.25.0-rc1 (2017-11-14)
|
||||
|
||||
Features:
|
||||
|
||||
- Add is\_public to groups table to allow for private groups (PR #2582)
|
||||
- Add `is_public` to groups table to allow for private groups (PR #2582)
|
||||
- Add a route for determining who you are (PR #2668) Thanks to @turt2live!
|
||||
- Add more features to the password providers (PR #2608, #2610, #2620, #2622, #2623, #2624, #2626, #2628, #2629)
|
||||
- Add a hook for custom rest endpoints (PR #2627)
|
||||
@@ -1737,7 +1738,7 @@ Features:
|
||||
|
||||
Changes:
|
||||
|
||||
- Ignore \<noscript\> tags when generating URL preview descriptions (PR #2576) Thanks to @maximevaillancourt!
|
||||
- Ignore `<noscript\>` tags when generating URL preview descriptions (PR #2576) Thanks to @maximevaillancourt!
|
||||
- Register some /unstable endpoints in /r0 as well (PR #2579) Thanks to @krombel!
|
||||
- Support /keys/upload on /r0 as well as /unstable (PR #2585)
|
||||
- Front-end proxy: pass through auth header (PR #2586)
|
||||
@@ -1745,9 +1746,9 @@ Changes:
|
||||
- Remove refresh tokens (PR #2613)
|
||||
- Automatically set default displayname on register (PR #2617)
|
||||
- Log login requests (PR #2618)
|
||||
- Always return is\_public in the /groups/:group\_id/rooms API (PR #2630)
|
||||
- Always return `is_public` in the `/groups/:group_id/rooms` API (PR #2630)
|
||||
- Avoid no-op media deletes (PR #2637) Thanks to @spantaleev!
|
||||
- Fix various embarrassing typos around user\_directory and add some doc. (PR #2643)
|
||||
- Fix various embarrassing typos around `user_directory` and add some doc. (PR #2643)
|
||||
- Return whether a user is an admin within a group (PR #2647)
|
||||
- Namespace visibility options for groups (PR #2657)
|
||||
- Downcase UserIDs on registration (PR #2662)
|
||||
@@ -1760,7 +1761,7 @@ Bug fixes:
|
||||
- Fix UI auth when deleting devices (PR #2591)
|
||||
- Fix typo when checking if user is invited to group (PR #2599)
|
||||
- Fix the port script to drop NUL values in all tables (PR #2611)
|
||||
- Fix appservices being backlogged and not receiving new events due to a bug in notify\_interested\_services (PR #2631) Thanks to @xyzz!
|
||||
- Fix appservices being backlogged and not receiving new events due to a bug in `notify_interested_services` (PR #2631) Thanks to @xyzz!
|
||||
- Fix updating rooms avatar/display name when modified by admin (PR #2636) Thanks to @farialima!
|
||||
- Fix bug in state group storage (PR #2649)
|
||||
- Fix 500 on invalid utf-8 in request (PR #2663)
|
||||
@@ -1794,7 +1795,7 @@ Changes:
|
||||
- Ignore incoming events for rooms that we have left (PR #2490)
|
||||
- Allow spam checker to reject invites too (PR #2492)
|
||||
- Add room creation checks to spam checker (PR #2495)
|
||||
- Spam checking: add the invitee to user\_may\_invite (PR #2502)
|
||||
- Spam checking: add the invitee to `user_may_invite` (PR #2502)
|
||||
- Process events from federation for different rooms in parallel (PR #2520)
|
||||
- Allow error strings from spam checker (PR #2531)
|
||||
- Improve error handling for missing files in config (PR #2551)
|
||||
@@ -1805,7 +1806,7 @@ Bug fixes:
|
||||
- Fix incompatibility with newer versions of ujson (PR #2483) Thanks to @jeremycline!
|
||||
- Fix notification keywords that start/end with non-word chars (PR #2500)
|
||||
- Fix stack overflow and logcontexts from linearizer (PR #2532)
|
||||
- Fix 500 error when fields missing from power\_levels event (PR #2552)
|
||||
- Fix 500 error when fields missing from `power_levels` event (PR #2552)
|
||||
- Fix 500 error when we get an error handling a PDU (PR #2553)
|
||||
|
||||
Changes in synapse v0.23.1 (2017-10-02)
|
||||
@@ -1813,7 +1814,7 @@ Changes in synapse v0.23.1 (2017-10-02)
|
||||
|
||||
Changes:
|
||||
|
||||
- Make \'affinity\' package optional, as it is not supported on some platforms
|
||||
- Make `affinity` package optional, as it is not supported on some platforms
|
||||
|
||||
Changes in synapse v0.23.0 (2017-10-02)
|
||||
=======================================
|
||||
@@ -1833,7 +1834,7 @@ Changes in synapse v0.23.0-rc1 (2017-09-25)
|
||||
Features:
|
||||
|
||||
- Add a frontend proxy worker (PR #2344)
|
||||
- Add support for event\_id\_only push format (PR #2450)
|
||||
- Add support for `event_id_only` push format (PR #2450)
|
||||
- Add a PoC for filtering spammy events (PR #2456)
|
||||
- Add a config option to block all room invites (PR #2457)
|
||||
|
||||
@@ -1897,12 +1898,12 @@ Changes:
|
||||
- Deduplicate sync filters (PR #2219) Thanks to @krombel!
|
||||
- Correct a typo in UPGRADE.rst (PR #2231) Thanks to @aaronraimist!
|
||||
- Add count of one time keys to sync stream (PR #2237)
|
||||
- Only store event\_auth for state events (PR #2247)
|
||||
- Only store `event_auth` for state events (PR #2247)
|
||||
- Store URL cache preview downloads separately (PR #2299)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix users not getting notifications when AS listened to that user\_id (PR #2216) Thanks to @slipeer!
|
||||
- Fix users not getting notifications when AS listened to that `user_id` (PR #2216) Thanks to @slipeer!
|
||||
- Fix users without push set up not getting notifications after joining rooms (PR #2236)
|
||||
- Fix preview url API to trim long descriptions (PR #2243)
|
||||
- Fix bug where we used cached but unpersisted state group as prev group, resulting in broken state of restart (PR #2263)
|
||||
@@ -1935,7 +1936,7 @@ Changes:
|
||||
- Update username availability checker API (PR #2209, #2213)
|
||||
- When purging, Don't de-delta state groups we're about to delete (PR #2214)
|
||||
- Documentation to check synapse version (PR #2215) Thanks to @hamber-dick!
|
||||
- Add an index to event\_search to speed up purge history API (PR #2218)
|
||||
- Add an index to `event_search` to speed up purge history API (PR #2218)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
@@ -2004,7 +2005,7 @@ Changes in synapse v0.20.0-rc1 (2017-03-30)
|
||||
|
||||
Features:
|
||||
|
||||
- Add delete\_devices API (PR #1993)
|
||||
- Add `delete_devices` API (PR #1993)
|
||||
- Add phone number registration/login support (PR #1994, #2055)
|
||||
|
||||
Changes:
|
||||
@@ -2024,12 +2025,12 @@ Changes:
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix bug where current\_state\_events renamed to current\_state\_ids (PR #1849)
|
||||
- Fix bug where `current_state_events` renamed to `current_state_ids` (PR #1849)
|
||||
- Fix routing loop when fetching remote media (PR #1992)
|
||||
- Fix current\_state\_events table to not lie (PR #1996)
|
||||
- Fix `current_state_events` table to not lie (PR #1996)
|
||||
- Fix CAS login to handle PartialDownloadError (PR #1997)
|
||||
- Fix assertion to stop transaction queue getting wedged (PR #2010)
|
||||
- Fix presence to fallback to last\_active\_ts if it beats the last sync time. Thanks @Half-Shot! (PR #2014)
|
||||
- Fix presence to fallback to `last_active_ts` if it beats the last sync time. Thanks @Half-Shot! (PR #2014)
|
||||
- Fix bug when federation received a PDU while a room join is in progress (PR #2016)
|
||||
- Fix resetting state on rejected events (PR #2025)
|
||||
- Fix installation issues in readme. Thanks @ricco386 (PR #2037)
|
||||
@@ -2064,7 +2065,7 @@ Changes:
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix synapse\_port\_db failure. Thanks to Pneumaticat! (PR #1904)
|
||||
- Fix synapse_port_db failure. Thanks to Pneumaticat! (PR #1904)
|
||||
- Fix caching to not cache error responses (PR #1913)
|
||||
- Fix APIs to make kick & ban reasons work (PR #1917)
|
||||
- Fix bugs in the /keys/changes api (PR #1921)
|
||||
@@ -2099,7 +2100,7 @@ Changes in synapse v0.19.0-rc3 (2017-02-02)
|
||||
===========================================
|
||||
|
||||
- Fix email push in pusher worker (PR #1875)
|
||||
- Make presence.get\_new\_events a bit faster (PR #1876)
|
||||
- Make `presence.get_new_events` a bit faster (PR #1876)
|
||||
- Make /keys/changes a bit more performant (PR #1877)
|
||||
|
||||
Changes in synapse v0.19.0-rc2 (2017-02-02)
|
||||
@@ -2122,14 +2123,14 @@ Features:
|
||||
Changes:
|
||||
|
||||
- Improve IPv6 support (PR #1696). Thanks to @kyrias and @glyph!
|
||||
- Log which files we saved attachments to in the media\_repository (PR #1791)
|
||||
- Log which files we saved attachments to in the `media_repository` (PR #1791)
|
||||
- Linearize updates to membership via PUT /state/ to better handle multiple joins (PR #1787)
|
||||
- Limit number of entries to prefill from cache on startup (PR #1792)
|
||||
- Remove full\_twisted\_stacktraces option (PR #1802)
|
||||
- Remove `full_twisted_stacktraces` option (PR #1802)
|
||||
- Measure size of some caches by sum of the size of cached values (PR #1815)
|
||||
- Measure metrics of string\_cache (PR #1821)
|
||||
- Measure metrics of `string_cache` (PR #1821)
|
||||
- Reduce logging verbosity (PR #1822, #1823, #1824)
|
||||
- Don't clobber a displayname or avatar\_url if provided by an m.room.member event (PR #1852)
|
||||
- Don't clobber a displayname or `avatar_url` if provided by an m.room.member event (PR #1852)
|
||||
- Better handle 401/404 response for federation /send/ (PR #1866, #1871)
|
||||
|
||||
Fixes:
|
||||
@@ -2142,7 +2143,7 @@ Fixes:
|
||||
Performance:
|
||||
|
||||
- Don't block messages sending on bumping presence (PR #1789)
|
||||
- Change device\_inbox stream index to include user (PR #1793)
|
||||
- Change `device_inbox` stream index to include user (PR #1793)
|
||||
- Optimise state resolution (PR #1818)
|
||||
- Use DB cache of joined users for presence (PR #1862)
|
||||
- Add an index to make membership queries faster (PR #1867)
|
||||
@@ -2225,7 +2226,7 @@ Changes:
|
||||
- Enable guest access for private rooms by default (PR #653)
|
||||
- Limit the number of events that can be created on a given room concurrently (PR #1620)
|
||||
- Log the args that we have on UI auth completion (PR #1649)
|
||||
- Stop generating refresh\_tokens (PR #1654)
|
||||
- Stop generating `refresh_tokens` (PR #1654)
|
||||
- Stop putting a time caveat on access tokens (PR #1656)
|
||||
- Remove unspecced GET endpoints for e2e keys (PR #1694)
|
||||
|
||||
@@ -2250,7 +2251,7 @@ Changes in synapse v0.18.5-rc1 (2016-11-24)
|
||||
|
||||
Features:
|
||||
|
||||
- Implement \"event\_fields\" in filters (PR #1638)
|
||||
- Implement `event_fields` in filters (PR #1638)
|
||||
|
||||
Changes:
|
||||
|
||||
@@ -2279,7 +2280,7 @@ Bug fixes:
|
||||
|
||||
- Fix media repo to set CORs headers on responses (PR #1190)
|
||||
- Fix registration to not error on non-ascii passwords (PR #1191)
|
||||
- Fix create event code to limit the number of prev\_events (PR #1615)
|
||||
- Fix create event code to limit the number of `prev_events` (PR #1615)
|
||||
- Fix bug in transaction ID deduplication (PR #1624)
|
||||
|
||||
Changes in synapse v0.18.3 (2016-11-08)
|
||||
@@ -2338,10 +2339,10 @@ Changes in synapse v0.18.2-rc1 (2016-10-17)
|
||||
|
||||
Changes:
|
||||
|
||||
- Remove redundant event\_auth index (PR #1113)
|
||||
- Remove redundant `event_auth` index (PR #1113)
|
||||
- Reduce DB hits for replication (PR #1141)
|
||||
- Implement pluggable password auth (PR #1155)
|
||||
- Remove rate limiting from app service senders and fix get\_or\_create\_user requester, thanks to Patrik Oldsberg (PR #1157)
|
||||
- Remove rate limiting from app service senders and fix `get_or_create_user` requester, thanks to Patrik Oldsberg (PR #1157)
|
||||
- window.postmessage for Interactive Auth fallback (PR #1159)
|
||||
- Use sys.executable instead of hardcoded python, thanks to Pedro Larroy (PR #1162)
|
||||
- Add config option for adding additional TLS fingerprints (PR #1167)
|
||||
@@ -2349,7 +2350,7 @@ Changes:
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix not being allowed to set your own state\_key, thanks to Patrik Oldsberg (PR #1150)
|
||||
- Fix not being allowed to set your own `state_key`, thanks to Patrik Oldsberg (PR #1150)
|
||||
- Fix interactive auth to return 401 from for incorrect password (PR #1160, #1166)
|
||||
- Fix email push notifs being dropped (PR #1169)
|
||||
|
||||
@@ -2363,7 +2364,7 @@ Changes in synapse v0.18.1-rc1 (2016-09-30)
|
||||
|
||||
Features:
|
||||
|
||||
- Add total\_room\_count\_estimate to `/publicRooms` (PR #1133)
|
||||
- Add `total_room_count_estimate` to `/publicRooms` (PR #1133)
|
||||
|
||||
Changes:
|
||||
|
||||
@@ -2398,17 +2399,17 @@ Features:
|
||||
- Add `only=highlight` on `/notifications` (PR #1081)
|
||||
- Add server param to /publicRooms (PR #1082)
|
||||
- Allow clients to ask for the whole of a single state event (PR #1094)
|
||||
- Add is\_direct param to /createRoom (PR #1108)
|
||||
- Add `is_direct` param to /createRoom (PR #1108)
|
||||
- Add pagination support to publicRooms (PR #1121)
|
||||
- Add very basic filter API to /publicRooms (PR #1126)
|
||||
- Add basic direct to device messaging support for E2E (PR #1074, #1084, #1104, #1111)
|
||||
|
||||
Changes:
|
||||
|
||||
- Move to storing state\_groups\_state as deltas, greatly reducing DB size (PR #1065)
|
||||
- Move to storing `state_groups_state` as deltas, greatly reducing DB size (PR #1065)
|
||||
- Reduce amount of state pulled out of the DB during common requests (PR #1069)
|
||||
- Allow PDF to be rendered from media repo (PR #1071)
|
||||
- Reindex state\_groups\_state after pruning (PR #1085)
|
||||
- Reindex `state_groups_state` after pruning (PR #1085)
|
||||
- Clobber EDUs in send queue (PR #1095)
|
||||
- Conform better to the CAS protocol specification (PR #1100)
|
||||
- Limit how often we ask for keys from dead servers (PR #1114)
|
||||
@@ -2442,22 +2443,22 @@ Changes:
|
||||
- Avoid pulling the full state of a room out so often (PR #1047, #1049, #1063, #1068)
|
||||
- Don't notify for online to online presence transitions. (PR #1054)
|
||||
- Occasionally persist unpersisted presence updates (PR #1055)
|
||||
- Allow application services to have an optional \'url\' (PR #1056)
|
||||
- Allow application services to have an optional `url` (PR #1056)
|
||||
- Clean up old sent transactions from DB (PR #1059)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix None check in backfill (PR #1043)
|
||||
- Fix membership changes to be idempotent (PR #1067)
|
||||
- Fix bug in get\_pdu where it would sometimes return events with incorrect signature
|
||||
- Fix bug in `get_pdu` where it would sometimes return events with incorrect signature
|
||||
|
||||
Changes in synapse v0.17.1 (2016-08-24)
|
||||
=======================================
|
||||
|
||||
Changes:
|
||||
|
||||
- Delete old received\_transactions rows (PR #1038)
|
||||
- Pass through user-supplied content in /join/\$room\_id (PR #1039)
|
||||
- Delete old `received_transactions` rows (PR #1038)
|
||||
- Pass through user-supplied content in `/join/$room_id` (PR #1039)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
@@ -2478,15 +2479,15 @@ Changes:
|
||||
- Move default display name push rule (PR #1011, #1023)
|
||||
- Fix up preview URL API. Add tests. (PR #1015)
|
||||
- Set `Content-Security-Policy` on media repo (PR #1021)
|
||||
- Make notify\_interested\_services faster (PR #1022)
|
||||
- Make `notify_interested_services` faster (PR #1022)
|
||||
- Add usage stats to prometheus monitoring (PR #1037)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix token login (PR #993)
|
||||
- Fix CAS login (PR #994, #995)
|
||||
- Fix /sync to not clobber status\_msg (PR #997)
|
||||
- Fix redacted state events to include prev\_content (PR #1003)
|
||||
- Fix /sync to not clobber `status_msg` (PR #997)
|
||||
- Fix redacted state events to include `prev_content` (PR #1003)
|
||||
- Fix some bugs in the auth/ldap handler (PR #1007)
|
||||
- Fix backfill request to limit URI length, so that remotes Don't reject the requests due to path length limits (PR #1012)
|
||||
- Fix AS push code to not send duplicate events (PR #1025)
|
||||
@@ -2527,7 +2528,7 @@ Changes in synapse v0.17.0-rc3 (2016-08-02)
|
||||
|
||||
Changes:
|
||||
|
||||
- Forbid non-ASes from registering users whose names begin with \'\_\' (PR #958)
|
||||
- Forbid non-ASes from registering users whose names begin with `_` (PR #958)
|
||||
- Add some basic admin API docs (PR #963)
|
||||
|
||||
Bug fixes:
|
||||
@@ -2549,16 +2550,16 @@ This release changes the LDAP configuration format in a backwards incompatible w
|
||||
|
||||
Features:
|
||||
|
||||
- Add purge\_media\_cache admin API (PR #902)
|
||||
- Add `purge_media_cache` admin API (PR #902)
|
||||
- Add deactivate account admin API (PR #903)
|
||||
- Add optional pepper to password hashing (PR #907, #910 by KentShikama)
|
||||
- Add an admin option to shared secret registration (breaks backwards compat) (PR #909)
|
||||
- Add purge local room history API (PR #911, #923, #924)
|
||||
- Add requestToken endpoints (PR #915)
|
||||
- Add an /account/deactivate endpoint (PR #921)
|
||||
- Add filter param to /messages. Add \'contains\_url\' to filter. (PR #922)
|
||||
- Add device\_id support to /login (PR #929)
|
||||
- Add device\_id support to /v2/register flow. (PR #937, #942)
|
||||
- Add filter param to /messages. Add `contains_url` to filter. (PR #922)
|
||||
- Add `device_id` support to /login (PR #929)
|
||||
- Add `device_id` support to /v2/register flow. (PR #937, #942)
|
||||
- Add GET /devices endpoint (PR #939, #944)
|
||||
- Add GET /device/{deviceId} (PR #943)
|
||||
- Add update and delete APIs for devices (PR #949)
|
||||
@@ -2566,14 +2567,14 @@ Features:
|
||||
Changes:
|
||||
|
||||
- Rewrite LDAP Authentication against ldap3 (PR #843 by mweinelt)
|
||||
- Linearize some federation endpoints based on (origin, room\_id) (PR #879)
|
||||
- Linearize some federation endpoints based on `(origin, room_id)` (PR #879)
|
||||
- Remove the legacy v0 content upload API. (PR #888)
|
||||
- Use similar naming we use in email notifs for push (PR #894)
|
||||
- Optionally include password hash in createUser endpoint (PR #905 by KentShikama)
|
||||
- Use a query that postgresql optimises better for get\_events\_around (PR #906)
|
||||
- Fall back to \'username\' if \'user\' is not given for appservice registration. (PR #927 by Half-Shot)
|
||||
- Use a query that postgresql optimises better for `get_events_around` (PR #906)
|
||||
- Fall back to '`username` if `user` is not given for appservice registration. (PR #927 by Half-Shot)
|
||||
- Add metrics for psutil derived memory usage (PR #936)
|
||||
- Record device\_id in client\_ips (PR #938)
|
||||
- Record `device_id` in `client_ips` (PR #938)
|
||||
- Send the correct host header when fetching keys (PR #941)
|
||||
- Log the hostname the reCAPTCHA was completed on (PR #946)
|
||||
- Make the device id on e2e key upload optional (PR #956)
|
||||
@@ -2586,8 +2587,8 @@ Bug fixes:
|
||||
- Put most recent 20 messages in email notif (PR #892)
|
||||
- Ensure that the guest user is in the database when upgrading accounts (PR #914)
|
||||
- Fix various edge cases in auth handling (PR #919)
|
||||
- Fix 500 ISE when sending alias event without a state\_key (PR #925)
|
||||
- Fix bug where we stored rejections in the state\_group, persist all rejections (PR #948)
|
||||
- Fix 500 ISE when sending alias event without a `state_key` (PR #925)
|
||||
- Fix bug where we stored rejections in the `state_group`, persist all rejections (PR #948)
|
||||
- Fix lack of check of if the user is banned when handling 3pid invites (PR #952)
|
||||
- Fix a couple of bugs in the transaction and keyring code (PR #954, #955)
|
||||
|
||||
@@ -2656,7 +2657,7 @@ Changes:
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix \'From\' header in email notifications (PR #843)
|
||||
- Fix `From` header in email notifications (PR #843)
|
||||
- Fix presence where timeouts were not being fired for the first 8h after restarts (PR #842)
|
||||
- Fix bug where synapse sent malformed transactions to AS's when retrying transactions (Commits 310197b, 8437906)
|
||||
|
||||
@@ -2677,22 +2678,22 @@ Features:
|
||||
- Add a `url_preview_ip_range_whitelist` config param (PR #760)
|
||||
- Add /report endpoint (PR #762)
|
||||
- Add basic ignore user API (PR #763)
|
||||
- Add an openidish mechanism for proving that you own a given user\_id (PR #765)
|
||||
- Allow clients to specify a server\_name to avoid \'No known servers\' (PR #794)
|
||||
- Add secondary\_directory\_servers option to fetch room list from other servers (PR #808, #813)
|
||||
- Add an openidish mechanism for proving that you own a given `user_id` (PR #765)
|
||||
- Allow clients to specify a `server_name` to avoid "No known servers" (PR #794)
|
||||
- Add `secondary_directory_servers` option to fetch room list from other servers (PR #808, #813)
|
||||
|
||||
Changes:
|
||||
|
||||
- Report per request metrics for all of the things using request\_handler (PR #756)
|
||||
- Report per request metrics for all of the things using `request_handler` (PR #756)
|
||||
- Correctly handle `NULL` password hashes from the database (PR #775)
|
||||
- Allow receipts for events we haven't seen in the db (PR #784)
|
||||
- Make synctl read a cache factor from config file (PR #785)
|
||||
- Increment badge count per missed convo, not per msg (PR #793)
|
||||
- Special case m.room.third\_party\_invite event auth to match invites (PR #814)
|
||||
- Special case `m.room.third_party_invite` event auth to match invites (PR #814)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix typo in event\_auth servlet path (PR #757)
|
||||
- Fix typo in `event_auth` servlet path (PR #757)
|
||||
- Fix password reset (PR #758)
|
||||
|
||||
Performance improvements:
|
||||
@@ -2708,7 +2709,7 @@ Performance improvements:
|
||||
- Add `get_users_with_read_receipts_in_room` cache (PR #809)
|
||||
- Use state to calculate `get_users_in_room` (PR #811)
|
||||
- Load push rules in storage layer so that they get cached (PR #825)
|
||||
- Make `get_joined_hosts_for_room` use get\_users\_in\_room (PR #828)
|
||||
- Make `get_joined_hosts_for_room` use `get_users_in_room` (PR #828)
|
||||
- Poke notifier on next reactor tick (PR #829)
|
||||
- Change CacheMetrics to be quicker (PR #830)
|
||||
|
||||
@@ -2772,19 +2773,19 @@ Changes in synapse v0.14.0-rc1 (2016-03-14)
|
||||
|
||||
Features:
|
||||
|
||||
- Add event\_id to response to state event PUT (PR #581)
|
||||
- Add `event_id` to response to state event PUT (PR #581)
|
||||
- Allow guest users access to messages in rooms they have joined (PR #587)
|
||||
- Add config for what state is included in a room invite (PR #598)
|
||||
- Send the inviter's member event in room invite state (PR #607)
|
||||
- Add error codes for malformed/bad JSON in /login (PR #608)
|
||||
- Add support for changing the actions for default rules (PR #609)
|
||||
- Add environment variable SYNAPSE\_CACHE\_FACTOR, default it to 0.1 (PR #612)
|
||||
- Add environment variable `SYNAPSE_CACHE_FACTOR`, default it to 0.1 (PR #612)
|
||||
- Add ability for alias creators to delete aliases (PR #614)
|
||||
- Add profile information to invites (PR #624)
|
||||
|
||||
Changes:
|
||||
|
||||
- Enforce user\_id exclusivity for AS registrations (PR #572)
|
||||
- Enforce `user_id` exclusivity for AS registrations (PR #572)
|
||||
- Make adding push rules idempotent (PR #587)
|
||||
- Improve presence performance (PR #582, #586)
|
||||
- Change presence semantics for `last_active_ago` (PR #582, #586)
|
||||
@@ -2792,7 +2793,7 @@ Changes:
|
||||
- Add 800x600 to default list of valid thumbnail sizes (PR #616)
|
||||
- Always include kicks and bans in full /sync (PR #625)
|
||||
- Send history visibility on boundary changes (PR #626)
|
||||
- Register endpoint now returns a refresh\_token (PR #637)
|
||||
- Register endpoint now returns a `refresh_token` (PR #637)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
@@ -2963,7 +2964,7 @@ Changes in synapse v0.11.0-rc1 (2015-11-11)
|
||||
===========================================
|
||||
|
||||
- Add Search API (PR #307, #324, #327, #336, #350, #359)
|
||||
- Add \'archived\' state to v2 /sync API (PR #316)
|
||||
- Add `archived` state to v2 /sync API (PR #316)
|
||||
- Add ability to reject invites (PR #317)
|
||||
- Add config option to disable password login (PR #322)
|
||||
- Add the login fallback API (PR #330)
|
||||
@@ -3028,7 +3029,7 @@ Changes in synapse v0.10.0-rc3 (2015-08-25)
|
||||
===========================================
|
||||
|
||||
- Add `--keys-directory` config option to specify where files such as certs and signing keys should be stored in, when using `--generate-config` or `--generate-keys`. (PR #250)
|
||||
- Allow `--config-path` to specify a directory, causing synapse to use all \*.yaml files in the directory as config files. (PR #249)
|
||||
- Allow `--config-path` to specify a directory, causing synapse to use all `*.yaml` files in the directory as config files. (PR #249)
|
||||
- Add `web_client_location` config option to specify static files to be hosted by synapse under `/_matrix/client`. (PR #245)
|
||||
- Add helper utility to synapse to read and parse the config files and extract the value of a given key. For example:
|
||||
|
||||
@@ -3060,7 +3061,7 @@ General:
|
||||
- Batch various storage request (PR #226, #228)
|
||||
- Fix bug where we didn't correctly log the entity that triggered the request if the request came in via an application service (PR #230)
|
||||
- Fix bug where we needlessly regenerated the full list of rooms an AS is interested in. (PR #232)
|
||||
- Add support for AS's to use v2\_alpha registration API (PR #210)
|
||||
- Add support for AS's to use `v2_alpha` registration API (PR #210)
|
||||
|
||||
Configuration:
|
||||
|
||||
@@ -3207,7 +3208,7 @@ Configuration:
|
||||
Application services:
|
||||
|
||||
- Reliably retry sending of events from Synapse to application services, as per [Application Services](https://github.com/matrix-org/matrix-doc/blob/0c6bd9/specification/25_application_service_api.rst#home-server---application-service-api) spec.
|
||||
- Application services can no longer register via the `/register` API, instead their configuration should be saved to a file and listed in the synapse `app_service_config_files` config option. The AS configuration file has the same format as the old `/register` request. See [docs/application\_services.rst](docs/application_services.rst) for more information.
|
||||
- Application services can no longer register via the `/register` API, instead their configuration should be saved to a file and listed in the synapse `app_service_config_files` config option. The AS configuration file has the same format as the old `/register` request. See [docs/application_services.rst](docs/application_services.rst) for more information.
|
||||
|
||||
Changes in synapse v0.8.1 (2015-03-18)
|
||||
======================================
|
||||
@@ -3289,7 +3290,7 @@ Changes in synapse 0.6.0 (2014-12-16)
|
||||
=====================================
|
||||
|
||||
- Add new API for media upload and download that supports thumbnailing.
|
||||
- Replicate media uploads over multiple homeservers so media is always served to clients from their local homeserver. This obsoletes the \--content-addr parameter and confusion over accessing content directly from remote homeservers.
|
||||
- Replicate media uploads over multiple homeservers so media is always served to clients from their local homeserver. This obsoletes the `--content-addr` parameter and confusion over accessing content directly from remote homeservers.
|
||||
- Implement exponential backoff when retrying federation requests when sending to remote homeservers which are offline.
|
||||
- Implement typing notifications.
|
||||
- Fix bugs where we sent events with invalid signatures due to bugs where we incorrectly persisted events.
|
||||
@@ -3304,13 +3305,13 @@ Changes in synapse 0.5.4 (2014-12-03)
|
||||
=====================================
|
||||
|
||||
- Fix presence bug where some rooms did not display presence updates for remote users.
|
||||
- Do not log SQL timing log lines when started with \"-v\"
|
||||
- Do not log SQL timing log lines when started with `-v`
|
||||
- Fix potential memory leak.
|
||||
|
||||
Changes in synapse 0.5.3c (2014-12-02)
|
||||
======================================
|
||||
|
||||
- Change the default value for the content\_addr option to use the HTTP listener, as by default the HTTPS listener will be using a self-signed certificate.
|
||||
- Change the default value for the `content_addr` option to use the HTTP listener, as by default the HTTPS listener will be using a self-signed certificate.
|
||||
|
||||
Changes in synapse 0.5.3 (2014-11-27)
|
||||
=====================================
|
||||
@@ -3391,7 +3392,7 @@ You will also need an updated syutil and config. See UPGRADES.rst.
|
||||
Homeserver:
|
||||
|
||||
- Sign federation transactions to assert strong identity over federation.
|
||||
- Rename timestamp keys in PDUs and events from \'ts\' and \'hsob\_ts\' to \'origin\_server\_ts\'.
|
||||
- Rename timestamp keys in PDUs and events from `ts` and `hsob_ts` to `origin_server_ts`.
|
||||
|
||||
Changes in synapse 0.3.4 (2014-09-25)
|
||||
=====================================
|
||||
@@ -3461,9 +3462,9 @@ See UPGRADE for information about changes to the client server API, including br
|
||||
Homeserver:
|
||||
|
||||
- When a user changes their displayname or avatar the server will now update all their join states to reflect this.
|
||||
- The server now adds \"age\" key to events to indicate how old they are. This is clock independent, so at no point does any server or webclient have to assume their clock is in sync with everyone else.
|
||||
- The server now adds `age` key to events to indicate how old they are. This is clock independent, so at no point does any server or webclient have to assume their clock is in sync with everyone else.
|
||||
- Fix bug where we didn't correctly pull in missing PDUs.
|
||||
- Fix bug where prev\_content key wasn't always returned.
|
||||
- Fix bug where `prev_content` key wasn't always returned.
|
||||
- Add support for password resets.
|
||||
|
||||
Webclient:
|
||||
@@ -3481,9 +3482,9 @@ Webclient:
|
||||
|
||||
Registration API:
|
||||
|
||||
- The registration API has been overhauled to function like the login API. In practice, this means registration requests must now include the following: \'type\':\'m.login.password\'. See UPGRADE for more information on this.
|
||||
- The \'user\_id\' key has been renamed to \'user\' to better match the login API.
|
||||
- There is an additional login type: \'m.login.email.identity\'.
|
||||
- The registration API has been overhauled to function like the login API. In practice, this means registration requests must now include the following: `type`:`m.login.password`. See UPGRADE for more information on this.
|
||||
- The `user_id` key has been renamed to `user` to better match the login API.
|
||||
- There is an additional login type: `m.login.email.identity`.
|
||||
- The command client and web client have been updated to reflect these changes.
|
||||
|
||||
Changes in synapse 0.2.3 (2014-09-12)
|
||||
@@ -3516,7 +3517,7 @@ Homeserver:
|
||||
- When the server returns state events it now also includes the previous content.
|
||||
- Add support for inviting people when creating a new room.
|
||||
- Make the homeserver inform the room via m.room.aliases when a new alias is added for a room.
|
||||
- Validate m.room.power\_level events.
|
||||
- Validate `m.room.power_level` events.
|
||||
|
||||
Webclient:
|
||||
|
||||
@@ -3559,7 +3560,7 @@ Homeserver:
|
||||
- Add support for kicking/banning and power levels.
|
||||
- Allow setting of room names and topics on creation.
|
||||
- Change presence to include last seen time of the user.
|
||||
- Change url path prefix to /\_matrix/\...
|
||||
- Change url path prefix to `/_matrix/...`
|
||||
- Bug fixes to presence.
|
||||
|
||||
Webclient:
|
||||
|
||||
@@ -25,20 +25,37 @@ updated. They work as follows:
|
||||
|
||||
* The Synapse codebase defines a constant `synapse.storage.schema.SCHEMA_VERSION`
|
||||
which represents the expectations made about the database by that version. For
|
||||
example, as of Synapse v1.36, this is `59`.
|
||||
example, as of Synapse v1.36, this is `59`. This version should be incremented
|
||||
whenever a backwards-incompatible change is made to the database format (normally
|
||||
via a `delta` file)
|
||||
|
||||
* The database stores a "compatibility version" in
|
||||
* The Synapse codebase defines a constant `synapse.storage.schema.SCHEMA_COMPAT_VERSION`
|
||||
which represents the minimum database versions the current code supports.
|
||||
Whenever the Synapse code is updated to assume backwards-incompatible changes
|
||||
made to the database format, `synapse.storage.schema.SCHEMA_COMPAT_VERSION` is also updated
|
||||
so that administrators can not accidentally roll back to a too-old version of Synapse.
|
||||
|
||||
The database stores a "compatibility version" in
|
||||
`schema_compat_version.compat_version` which defines the `SCHEMA_VERSION` of the
|
||||
oldest version of Synapse which will work with the database. On startup, if
|
||||
`compat_version` is found to be newer than `SCHEMA_VERSION`, Synapse will refuse to
|
||||
start.
|
||||
|
||||
Synapse automatically updates this field from
|
||||
`synapse.storage.schema.SCHEMA_COMPAT_VERSION`.
|
||||
Synapse automatically updates `schema_compat_version.compat_version` from
|
||||
`synapse.storage.schema.SCHEMA_COMPAT_VERSION` during start-up.
|
||||
|
||||
* Whenever a backwards-incompatible change is made to the database format (normally
|
||||
via a `delta` file), `synapse.storage.schema.SCHEMA_COMPAT_VERSION` is also updated
|
||||
so that administrators can not accidentally roll back to a too-old version of Synapse.
|
||||
* The Synapse codebase defines a constant `synapse.storage.schema.BACKGROUND_UPDATES_COMPAT_VERSION`
|
||||
which represents the earliest supported background updates.
|
||||
|
||||
On startup, if there exists any background update (via the
|
||||
`background_updates.ordering` column) older than `BACKGROUND_UPDATES_COMPAT_VERSION`,
|
||||
Synpase will refuse to start.
|
||||
|
||||
This is useful for adding delta files which assume background updates have
|
||||
finished; overall maintenance of Synapse (by allowing for removal of code
|
||||
supporting old background updates); among other things.
|
||||
|
||||
`BACKGROUND_UPDATES_COMPAT_VERSION` must be < the latest [full schema dump](#full-schema-dumps).
|
||||
|
||||
Generally, the goal is to maintain compatibility with at least one or two previous
|
||||
releases of Synapse, so any substantial change tends to require multiple releases and a
|
||||
@@ -150,6 +167,67 @@ def run_upgrade(
|
||||
...
|
||||
```
|
||||
|
||||
## Background updates
|
||||
|
||||
It is sometimes appropriate to perform database migrations as part of a background
|
||||
process (instead of blocking Synapse until the migration is done). In particular,
|
||||
this is useful for migrating data when adding new columns or tables.
|
||||
|
||||
Pending background updates stored in the `background_updates` table and are denoted
|
||||
by a unique name, the current status (stored in JSON), and some dependency information:
|
||||
|
||||
* Whether the update requires a previous update to be complete.
|
||||
* A rough ordering for which to complete updates.
|
||||
|
||||
A new background updates needs to be added to the `background_updates` table:
|
||||
|
||||
```sql
|
||||
INSERT INTO background_updates (ordering, update_name, depends_on, progress_json) VALUES
|
||||
(7706, 'my_background_update', 'a_previous_background_update' '{}');
|
||||
```
|
||||
|
||||
And then needs an associated handler in the appropriate datastore:
|
||||
|
||||
```python
|
||||
self.db_pool.updates.register_background_update_handler(
|
||||
"my_background_update",
|
||||
update_handler=self._my_background_update,
|
||||
)
|
||||
```
|
||||
|
||||
There are a few types of updates that can be performed, see the `BackgroundUpdater`:
|
||||
|
||||
* `register_background_update_handler`: A generic handler for custom SQL
|
||||
* `register_background_index_update`: Create an index in the background
|
||||
* `register_background_validate_constraint`: Validate a constraint in the background
|
||||
(PostgreSQL-only)
|
||||
* `register_background_validate_constraint_and_delete_rows`: Similar to
|
||||
`register_background_validate_constraint`, but deletes rows which don't fit
|
||||
the constraint.
|
||||
|
||||
For `register_background_update_handler`, the generic handler must track progress
|
||||
and then finalize the background update:
|
||||
|
||||
```python
|
||||
async def _my_background_update(self, progress: JsonDict, batch_size: int) -> int:
|
||||
def _do_something(txn: LoggingTransaction) -> int:
|
||||
...
|
||||
self.db_pool.updates._background_update_progress_txn(
|
||||
txn, "my_background_update", {"last_processed": last_processed}
|
||||
)
|
||||
return last_processed - prev_last_processed
|
||||
|
||||
num_processed = await self.db_pool.runInteraction("_do_something", _do_something)
|
||||
await self.db_pool.updates._end_background_update("my_background_update")
|
||||
|
||||
return num_processed
|
||||
```
|
||||
|
||||
Synapse will attempt to rate-limit how often background updates are run via the
|
||||
given batch-size and the returned number of processed entries (and how long the
|
||||
function took to run). See
|
||||
[background update controller callbacks](../modules/background_update_controller_callbacks.md).
|
||||
|
||||
## Boolean columns
|
||||
|
||||
Boolean columns require special treatment, since SQLite treats booleans the
|
||||
|
||||
@@ -8,8 +8,7 @@ and allow server and room admins to configure how long messages should
|
||||
be kept in a homeserver's database before being purged from it.
|
||||
**Please note that, as this feature isn't part of the Matrix
|
||||
specification yet, this implementation is to be considered as
|
||||
experimental. There are known bugs which may cause database corruption.
|
||||
Proceed with caution.**
|
||||
experimental.**
|
||||
|
||||
A message retention policy is mainly defined by its `max_lifetime`
|
||||
parameter, which defines how long a message can be kept around after
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
# Presence router callbacks
|
||||
|
||||
Presence router callbacks allow module developers to specify additional users (local or remote)
|
||||
to receive certain presence updates from local users. Presence router callbacks can be
|
||||
registered using the module API's `register_presence_router_callbacks` method.
|
||||
Presence router callbacks allow module developers to define additional users
|
||||
which receive presence updates from local users. The additional users
|
||||
can be local or remote.
|
||||
|
||||
For example, it could be used to direct all of `@alice:example.com` (a local user)'s
|
||||
presence updates to `@bob:matrix.org` (a remote user), even though they don't share a
|
||||
room. (Note that those presence updates might not make it to `@bob:matrix.org`'s client
|
||||
unless a similar presence router is running on that homeserver.)
|
||||
|
||||
Presence router callbacks can be registered using the module API's
|
||||
`register_presence_router_callbacks` method.
|
||||
|
||||
## Callbacks
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ docker run -d --name jaeger \
|
||||
jaegertracing/all-in-one:1
|
||||
```
|
||||
|
||||
By default, Synapse will publish traces to Jaeger on localhost.
|
||||
If Jaeger is hosted elsewhere, point Synapse to the correct host by setting
|
||||
`opentracing.jaeger_config.local_agent.reporting_host` [in the Synapse configuration](usage/configuration/config_documentation.md#opentracing-1)
|
||||
or by setting the `JAEGER_AGENT_HOST` environment variable to the desired address.
|
||||
|
||||
Latest documentation is probably at
|
||||
https://www.jaegertracing.io/docs/latest/getting-started.
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ SELECT rss.room_id, rss.name, rss.canonical_alias, rss.topic, rss.encryption,
|
||||
rsc.joined_members, rsc.local_users_in_room, rss.join_rules
|
||||
FROM room_stats_state rss
|
||||
LEFT JOIN room_stats_current rsc USING (room_id)
|
||||
WHERE room_id IN ( WHERE room_id IN (
|
||||
WHERE room_id IN (
|
||||
'!OGEhHVWSdvArJzumhm:matrix.org',
|
||||
'!YTvKGNlinIzlkMTVRl:matrix.org'
|
||||
);
|
||||
|
||||
@@ -1026,11 +1026,8 @@ which are older than the room's maximum retention period. Synapse will also
|
||||
filter events received over federation so that events that should have been
|
||||
purged are ignored and not stored again.
|
||||
|
||||
The message retention policies feature is disabled by default. Please be advised
|
||||
that enabling this feature carries some risk. There are known bugs with the implementation
|
||||
which can cause database corruption. Setting retention to delete older history
|
||||
is less risky than deleting newer history but in general caution is advised when enabling this
|
||||
experimental feature. You can read more about this feature [here](../../message_retention_policies.md).
|
||||
The message retention policies feature is disabled by default. You can read more
|
||||
about this feature [here](../../message_retention_policies.md).
|
||||
|
||||
This setting has the following sub-options:
|
||||
* `default_policy`: Default retention policy. If set, Synapse will apply it to rooms that lack the
|
||||
@@ -1193,6 +1190,11 @@ inbound federation traffic as early as possible, rather than relying
|
||||
purely on this application-layer restriction. If not specified, the
|
||||
default is to whitelist everything.
|
||||
|
||||
Note: this does not stop a server from joining rooms that servers not on the
|
||||
whitelist are in. As such, this option is really only useful to establish a
|
||||
"private federation", where a group of servers all whitelist each other and have
|
||||
the same whitelist.
|
||||
|
||||
Example configuration:
|
||||
```yaml
|
||||
federation_domain_whitelist:
|
||||
|
||||
@@ -83,7 +83,7 @@ The search term is then split into words:
|
||||
available, then the system's [default locale](https://unicode-org.github.io/icu/userguide/locale/#default-locales)
|
||||
will be used to break the search term into words. (See the
|
||||
[installation instructions](setup/installation.md) for how to install ICU.)
|
||||
* If unavailable, then runs of ASCII characters, numbers, underscores, and hypens
|
||||
* If unavailable, then runs of ASCII characters, numbers, underscores, and hyphens
|
||||
are considered words.
|
||||
|
||||
The queries for PostgreSQL and SQLite are detailed below, by their overall goal
|
||||
|
||||
@@ -32,6 +32,7 @@ files =
|
||||
docker/,
|
||||
scripts-dev/,
|
||||
synapse/,
|
||||
synmark/,
|
||||
tests/,
|
||||
build_rust.py
|
||||
|
||||
@@ -80,6 +81,9 @@ ignore_missing_imports = True
|
||||
[mypy-pympler.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pyperf.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-rust_python_jaeger_reporter.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
|
||||
Generated
+362
-349
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "alabaster"
|
||||
@@ -162,33 +162,29 @@ lxml = ["lxml"]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "23.9.1"
|
||||
version = "23.10.0"
|
||||
description = "The uncompromising code formatter."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71"},
|
||||
{file = "black-23.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7"},
|
||||
{file = "black-23.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186"},
|
||||
{file = "black-23.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f"},
|
||||
{file = "black-23.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204"},
|
||||
{file = "black-23.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377"},
|
||||
{file = "black-23.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393"},
|
||||
{file = "black-23.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9"},
|
||||
{file = "black-23.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f"},
|
||||
{file = "black-23.9.1-py3-none-any.whl", hash = "sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9"},
|
||||
{file = "black-23.9.1.tar.gz", hash = "sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d"},
|
||||
{file = "black-23.10.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"},
|
||||
{file = "black-23.10.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd"},
|
||||
{file = "black-23.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3d9129ce05b0829730323bdcb00f928a448a124af5acf90aa94d9aba6969604"},
|
||||
{file = "black-23.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:960c21555be135c4b37b7018d63d6248bdae8514e5c55b71e994ad37407f45b8"},
|
||||
{file = "black-23.10.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:30b78ac9b54cf87bcb9910ee3d499d2bc893afd52495066c49d9ee6b21eee06e"},
|
||||
{file = "black-23.10.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:0e232f24a337fed7a82c1185ae46c56c4a6167fb0fe37411b43e876892c76699"},
|
||||
{file = "black-23.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31946ec6f9c54ed7ba431c38bc81d758970dd734b96b8e8c2b17a367d7908171"},
|
||||
{file = "black-23.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:c870bee76ad5f7a5ea7bd01dc646028d05568d33b0b09b7ecfc8ec0da3f3f39c"},
|
||||
{file = "black-23.10.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:6901631b937acbee93c75537e74f69463adaf34379a04eef32425b88aca88a23"},
|
||||
{file = "black-23.10.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:481167c60cd3e6b1cb8ef2aac0f76165843a374346aeeaa9d86765fe0dd0318b"},
|
||||
{file = "black-23.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74892b4b836e5162aa0452393112a574dac85e13902c57dfbaaf388e4eda37c"},
|
||||
{file = "black-23.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:47c4510f70ec2e8f9135ba490811c071419c115e46f143e4dce2ac45afdcf4c9"},
|
||||
{file = "black-23.10.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:76baba9281e5e5b230c9b7f83a96daf67a95e919c2dfc240d9e6295eab7b9204"},
|
||||
{file = "black-23.10.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:a3c2ddb35f71976a4cfeca558848c2f2f89abc86b06e8dd89b5a65c1e6c0f22a"},
|
||||
{file = "black-23.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db451a3363b1e765c172c3fd86213a4ce63fb8524c938ebd82919bf2a6e28c6a"},
|
||||
{file = "black-23.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:7fb5fc36bb65160df21498d5a3dd330af8b6401be3f25af60c6ebfe23753f747"},
|
||||
{file = "black-23.10.0-py3-none-any.whl", hash = "sha256:e223b731a0e025f8ef427dd79d8cd69c167da807f5710add30cdf131f13dd62e"},
|
||||
{file = "black-23.10.0.tar.gz", hash = "sha256:31b9f87b277a68d0e99d2905edae08807c007973eaa609da5f0c62def6b7c0bd"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -208,13 +204,13 @@ uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "bleach"
|
||||
version = "6.0.0"
|
||||
version = "6.1.0"
|
||||
description = "An easy safelist-based HTML-sanitizing tool."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"},
|
||||
{file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"},
|
||||
{file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"},
|
||||
{file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -222,7 +218,7 @@ six = ">=1.9.0"
|
||||
webencodings = "*"
|
||||
|
||||
[package.extras]
|
||||
css = ["tinycss2 (>=1.1.0,<1.2)"]
|
||||
css = ["tinycss2 (>=1.1.0,<1.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "canonicaljson"
|
||||
@@ -600,20 +596,20 @@ smmap = ">=3.0.1,<6"
|
||||
|
||||
[[package]]
|
||||
name = "gitpython"
|
||||
version = "3.1.37"
|
||||
version = "3.1.40"
|
||||
description = "GitPython is a Python library used to interact with Git repositories"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "GitPython-3.1.37-py3-none-any.whl", hash = "sha256:5f4c4187de49616d710a77e98ddf17b4782060a1788df441846bddefbb89ab33"},
|
||||
{file = "GitPython-3.1.37.tar.gz", hash = "sha256:f9b9ddc0761c125d5780eab2d64be4873fc6817c2899cbcb34b02344bdc7bc54"},
|
||||
{file = "GitPython-3.1.40-py3-none-any.whl", hash = "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a"},
|
||||
{file = "GitPython-3.1.40.tar.gz", hash = "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
gitdb = ">=4.0.1,<5"
|
||||
|
||||
[package.extras]
|
||||
test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-sugar"]
|
||||
test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"]
|
||||
|
||||
[[package]]
|
||||
name = "hiredis"
|
||||
@@ -767,6 +763,17 @@ files = [
|
||||
{file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"},
|
||||
{file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"},
|
||||
{file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"},
|
||||
{file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"},
|
||||
{file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"},
|
||||
{file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"},
|
||||
{file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"},
|
||||
@@ -987,13 +994,13 @@ i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "4.19.0"
|
||||
version = "4.19.1"
|
||||
description = "An implementation of JSON Schema validation for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"},
|
||||
{file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"},
|
||||
{file = "jsonschema-4.19.1-py3-none-any.whl", hash = "sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e"},
|
||||
{file = "jsonschema-4.19.1.tar.gz", hash = "sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1330,13 +1337,13 @@ test = ["aiounittest", "tox", "twisted"]
|
||||
|
||||
[[package]]
|
||||
name = "matrix-synapse-ldap3"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
description = "An LDAP3 auth provider for Synapse"
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "matrix-synapse-ldap3-0.2.2.tar.gz", hash = "sha256:b388d95693486eef69adaefd0fd9e84463d52fe17b0214a00efcaa669b73cb74"},
|
||||
{file = "matrix_synapse_ldap3-0.2.2-py3-none-any.whl", hash = "sha256:66ee4c85d7952c6c27fd04c09cdfdf4847b8e8b7d6a7ada6ba1100013bda060f"},
|
||||
{file = "matrix-synapse-ldap3-0.3.0.tar.gz", hash = "sha256:8bb6517173164d4b9cc44f49de411d8cebdb2e705d5dd1ea1f38733c4a009e1d"},
|
||||
{file = "matrix_synapse_ldap3-0.3.0-py3-none-any.whl", hash = "sha256:8b4d701f8702551e98cc1d8c20dbed532de5613584c08d0df22de376ba99159d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1390,67 +1397,67 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "msgpack"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
description = "MessagePack serializer"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "msgpack-1.0.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f4321692e7f299277e55f322329b2c972d93bb612d85f3fda8741bec5c6285ce"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f0e36a5fa7a182cde391a128a64f437657d2b9371dfa42eda3436245adccbf5"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b5c8dd9a386a66e50bd7fa22b7a49fb8ead2b3574d6bd69eb1caced6caea0803"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f85200ea102276afdd3749ca94747f057bbb868d1c52921ee2446730b508d0f"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a006c300e82402c0c8f1ded11352a3ba2a61b87e7abb3054c845af2ca8d553c"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33bbf47ea5a6ff20c23426106e81863cdbb5402de1825493026ce615039cc99d"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:04450e4b5e1e662e7c86b6aafb7c230af9334fd0becf5e6b80459a507884241c"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b06a5095a79384760625b5de3f83f40b3053a385fb893be8a106fbbd84c14980"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3910211b0ab20be3a38e0bb944ed45bd4265d8d9f11a3d1674b95b298e08dd5c"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-win32.whl", hash = "sha256:1dc67b40fe81217b308ab12651adba05e7300b3a2ccf84d6b35a878e308dd8d4"},
|
||||
{file = "msgpack-1.0.6-cp310-cp310-win_amd64.whl", hash = "sha256:885de1ed5ea01c1bfe0a34c901152a264c3c1f8f1d382042b92ea354bd14bb0e"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:099c3d8a027367e1a6fc55d15336f04ff65c60c4f737b5739f7db4525c65fe9e"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b88dc97ba86c96b964c3745a445d9a65f76fe21955a953064fe04adb63e9367"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:00ce5f827d4f26fc094043e6f08b6069c1b148efa2631c47615ae14fb6cafc89"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd6af61388be65a8701f5787362cb54adae20007e0cc67ca9221a4b95115583b"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:652e4b7497825b0af6259e2c54700e6dc33d2fc4ed92b8839435090d4c9cc911"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b08676a17e3f791daad34d5fcb18479e9c85e7200d5a17cbe8de798643a7e37"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:229ccb6713c8b941eaa5cf13dc7478eba117f21513b5893c35e44483e2f0c9c8"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:95ade0bd4cf69e04e8b8f8ec2d197d9c9c4a9b6902e048dc7456bf6d82e12a80"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5b16344032a27b2ccfd341f89dadf3e4ef6407d91e4b93563c14644a8abb3ad7"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-win32.whl", hash = "sha256:55bb4a1bf94e39447bc08238a2fb8a767460388a8192f67c103442eb36920887"},
|
||||
{file = "msgpack-1.0.6-cp311-cp311-win_amd64.whl", hash = "sha256:ae97504958d0bc58c1152045c170815d5c4f8af906561ce044b6358b43d0c97e"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7ecf431786019a7bfedc28281531d706627f603e3691d64eccdbce3ecd353823"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a635aecf1047255576dbb0927cbf9a7aa4a68e9d54110cc3c926652d18f144e0"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:102cfb54eaefa73e8ca1e784b9352c623524185c98e057e519545131a56fb0af"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c5e05e4f5756758c58a8088aa10dc70d851c89f842b611fdccfc0581c1846bc"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68569509dd015fcdd1e6b2b3ccc8c51fd27d9a97f461ccc909270e220ee09685"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf652839d16de91fe1cfb253e0a88db9a548796939533894e07f45d4bdf90a5f"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14db7e1b7a7ed362b2f94897bf2486c899c8bb50f6e34b2db92fe534cdab306f"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:159cfec18a6e125dd4723e2b1de6f202b34b87c850fb9d509acfd054c01135e9"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6a01a072b2219b65a6ff74df208f20b2cac9401c60adb676ee34e53b4c651077"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-win32.whl", hash = "sha256:e36560d001d4ba469d469b02037f2dd404421fd72277d9474efe9f03f83fced5"},
|
||||
{file = "msgpack-1.0.6-cp312-cp312-win_amd64.whl", hash = "sha256:5e7fae9ca93258a956551708cf60dc6c8145574e32ce8c8c4d894e63bcb04341"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:40b801b768f5a765e33c68f30665d3c6ee1c8623a2d2bb78e6e59f2db4e4ceb7"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:da057d3652e698b00746e47f06dbb513314f847421e857e32e1dc61c46f6c052"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f75114c05ec56566da6b55122791cf5bb53d5aada96a98c016d6231e03132f76"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61213482b5a387ead9e250e9e3cb290292feca39dc83b41c3b1b7b8ffc8d8ecb"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae6c561f11b444b258b1b4be2bdd1e1cf93cd1d80766b7e869a79db4543a8a8"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:619a63753ba9e792fe3c6c0fc2b9ee2cfbd92153dd91bee029a89a71eb2942cd"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:70843788c85ca385846a2d2f836efebe7bb2687ca0734648bf5c9dc6c55602d2"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:fb4571efe86545b772a4630fee578c213c91cbcfd20347806e47fd4e782a18fe"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bbb4448a05d261fae423d5c0b0974ad899f60825bc77eabad5a0c518e78448c2"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-win32.whl", hash = "sha256:5cd67674db3c73026e0a2c729b909780e88bd9cbc8184256f9567640a5d299a8"},
|
||||
{file = "msgpack-1.0.6-cp38-cp38-win_amd64.whl", hash = "sha256:a1cf98afa7ad5e7012454ca3fde254499a13f9d92fd50cb46118118a249a1355"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d6d25b8a5c70e2334ed61a8da4c11cd9b97c6fbd980c406033f06e4463fda006"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:88cdb1da7fdb121dbb3116910722f5acab4d6e8bfcacab8fafe27e2e7744dc6a"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3b5658b1f9e486a2eec4c0c688f213a90085b9cf2fec76ef08f98fdf6c62f4b9"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76820f2ece3b0a7c948bbb6a599020e29574626d23a649476def023cbb026787"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c780d992f5d734432726b92a0c87bf1857c3d85082a8dea29cbf56e44a132b3"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0ed35d6d6122d0baa9a1b59ebca4ee302139f4cfb57dab85e4c73ab793ae7ed"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:32c0aff31f33033f4961abc01f78497e5e07bac02a508632aef394b384d27428"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:35ad5aed9b52217d4cea739d0ea3a492a18dd86fecb4b132668a69f27fb0363b"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47275ff73005a3e5e146e50baa2378e1730cba6e292f0222bc496a8e4c4adfc8"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-win32.whl", hash = "sha256:7baf16fd8908a025c4a8d7b699103e72d41f967e2aee5a2065432bcdbd9fd06e"},
|
||||
{file = "msgpack-1.0.6-cp39-cp39-win_amd64.whl", hash = "sha256:fc97aa4b4fb928ff4d3b74da7c30b360d0cb3ede49a5a6e1fd9705f49aea1deb"},
|
||||
{file = "msgpack-1.0.6.tar.gz", hash = "sha256:25d3746da40f3c8c59c3b1d001e49fd2aa17904438f980d9a391370366df001e"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"},
|
||||
{file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"},
|
||||
{file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"},
|
||||
{file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5b6ccc0c85916998d788b295765ea0e9cb9aac7e4a8ed71d12e7d8ac31c23c95"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:235a31ec7db685f5c82233bddf9858748b89b8119bf4538d514536c485c15fe0"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cab3db8bab4b7e635c1c97270d7a4b2a90c070b33cbc00c99ef3f9be03d3e1f7"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bfdd914e55e0d2c9e1526de210f6fe8ffe9705f2b1dfcc4aecc92a4cb4b533d"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36e17c4592231a7dbd2ed09027823ab295d2791b3b1efb2aee874b10548b7524"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38949d30b11ae5f95c3c91917ee7a6b239f5ec276f271f28638dec9156f82cfc"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ff1d0899f104f3921d94579a5638847f783c9b04f2d5f229392ca77fba5b82fc"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc43f1ec66eb8440567186ae2f8c447d91e0372d793dfe8c222aec857b81a8cf"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd632777ff3beaaf629f1ab4396caf7ba0bdd075d948a69460d13d44357aca4c"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-win32.whl", hash = "sha256:4e71bc4416de195d6e9b4ee93ad3f2f6b2ce11d042b4d7a7ee00bbe0358bd0c2"},
|
||||
{file = "msgpack-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8f5b234f567cf76ee489502ceb7165c2a5cecec081db2b37e35332b537f8157c"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"},
|
||||
{file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"},
|
||||
{file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1557,13 +1564,13 @@ testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4,
|
||||
|
||||
[[package]]
|
||||
name = "netaddr"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
description = "A network address manipulation library for Python"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"},
|
||||
{file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"},
|
||||
{file = "netaddr-0.9.0-py3-none-any.whl", hash = "sha256:5148b1055679d2a1ec070c521b7db82137887fabd6d7e37f5199b44f775c3bb1"},
|
||||
{file = "netaddr-0.9.0.tar.gz", hash = "sha256:7b46fa9b1a2d71fd5de9e4a3784ef339700a53a08c8040f08baf5f1194da0128"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1581,13 +1588,13 @@ tests = ["Sphinx", "doubles", "flake8", "flake8-quotes", "gevent", "mock", "pyte
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.1"
|
||||
version = "23.2"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
|
||||
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
|
||||
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1617,76 +1624,76 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "phonenumbers"
|
||||
version = "8.13.19"
|
||||
version = "8.13.22"
|
||||
description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "phonenumbers-8.13.19-py2.py3-none-any.whl", hash = "sha256:ba542f20f6dc83be8f127f240f9b5b7e7c1dec42aceff1879400d4dc0c781d81"},
|
||||
{file = "phonenumbers-8.13.19.tar.gz", hash = "sha256:38180247697240ccedd74dec4bfbdbc22bb108b9c5f991f270ca3e41395e6f96"},
|
||||
{file = "phonenumbers-8.13.22-py2.py3-none-any.whl", hash = "sha256:85ceeba9e67984ba98182c77e8e4c70093d38c0c6a0cb2bd392e0694ddaeb1f6"},
|
||||
{file = "phonenumbers-8.13.22.tar.gz", hash = "sha256:001664c90f59b8954766c2db85adafc8dbc96177efeb49607ca4e64a7acaf569"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "10.0.1"
|
||||
version = "10.1.0"
|
||||
description = "Python Imaging Library (Fork)"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "Pillow-10.0.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:8f06be50669087250f319b706decf69ca71fdecd829091a37cc89398ca4dc17a"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50bd5f1ebafe9362ad622072a1d2f5850ecfa44303531ff14353a4059113b12d"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6a90167bcca1216606223a05e2cf991bb25b14695c518bc65639463d7db722d"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11c9102c56ffb9ca87134bd025a43d2aba3f1155f508eff88f694b33a9c6d19"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:186f7e04248103482ea6354af6d5bcedb62941ee08f7f788a1c7707bc720c66f"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0462b1496505a3462d0f35dc1c4d7b54069747d65d00ef48e736acda2c8cbdff"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d889b53ae2f030f756e61a7bff13684dcd77e9af8b10c6048fb2c559d6ed6eaf"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:552912dbca585b74d75279a7570dd29fa43b6d93594abb494ebb31ac19ace6bd"},
|
||||
{file = "Pillow-10.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:787bb0169d2385a798888e1122c980c6eff26bf941a8ea79747d35d8f9210ca0"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d7e91b4379f7a76b31c2dda84ab9e20c6220488e50f7822e59dac36b0cd92b1"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e9adb3f22d4c416e7cd79b01375b17159d6990003633ff1d8377e21b7f1b21"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93139acd8109edcdeffd85e3af8ae7d88b258b3a1e13a038f542b79b6d255c54"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:92a23b0431941a33242b1f0ce6c88a952e09feeea9af4e8be48236a68ffe2205"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cbe68deb8580462ca0d9eb56a81912f59eb4542e1ef8f987405e35a0179f4ea2"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:522ff4ac3aaf839242c6f4e5b406634bfea002469656ae8358644fc6c4856a3b"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:84efb46e8d881bb06b35d1d541aa87f574b58e87f781cbba8d200daa835b42e1"},
|
||||
{file = "Pillow-10.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:898f1d306298ff40dc1b9ca24824f0488f6f039bc0e25cfb549d3195ffa17088"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:bcf1207e2f2385a576832af02702de104be71301c2696d0012b1b93fe34aaa5b"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d6c9049c6274c1bb565021367431ad04481ebb54872edecfcd6088d27edd6ed"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28444cb6ad49726127d6b340217f0627abc8732f1194fd5352dec5e6a0105635"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de596695a75496deb3b499c8c4f8e60376e0516e1a774e7bc046f0f48cd620ad"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:2872f2d7846cf39b3dbff64bc1104cc48c76145854256451d33c5faa55c04d1a"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4ce90f8a24e1c15465048959f1e94309dfef93af272633e8f37361b824532e91"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ee7810cf7c83fa227ba9125de6084e5e8b08c59038a7b2c9045ef4dde61663b4"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1be1c872b9b5fcc229adeadbeb51422a9633abd847c0ff87dc4ef9bb184ae08"},
|
||||
{file = "Pillow-10.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:98533fd7fa764e5f85eebe56c8e4094db912ccbe6fbf3a58778d543cadd0db08"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:764d2c0daf9c4d40ad12fbc0abd5da3af7f8aa11daf87e4fa1b834000f4b6b0a"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fcb59711009b0168d6ee0bd8fb5eb259c4ab1717b2f538bbf36bacf207ef7a68"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:697a06bdcedd473b35e50a7e7506b1d8ceb832dc238a336bd6f4f5aa91a4b500"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f665d1e6474af9f9da5e86c2a3a2d2d6204e04d5af9c06b9d42afa6ebde3f21"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:2fa6dd2661838c66f1a5473f3b49ab610c98a128fc08afbe81b91a1f0bf8c51d"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:3a04359f308ebee571a3127fdb1bd01f88ba6f6fb6d087f8dd2e0d9bff43f2a7"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:723bd25051454cea9990203405fa6b74e043ea76d4968166dfd2569b0210886a"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:71671503e3015da1b50bd18951e2f9daf5b6ffe36d16f1eb2c45711a301521a7"},
|
||||
{file = "Pillow-10.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:44e7e4587392953e5e251190a964675f61e4dae88d1e6edbe9f36d6243547ff3"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:3855447d98cced8670aaa63683808df905e956f00348732448b5a6df67ee5849"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed2d9c0704f2dc4fa980b99d565c0c9a543fe5101c25b3d60488b8ba80f0cce1"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5bb289bb835f9fe1a1e9300d011eef4d69661bb9b34d5e196e5e82c4cb09b37"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0d3e54ab1df9df51b914b2233cf779a5a10dfd1ce339d0421748232cea9876"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:2cc6b86ece42a11f16f55fe8903595eff2b25e0358dec635d0a701ac9586588f"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ca26ba5767888c84bf5a0c1a32f069e8204ce8c21d00a49c90dabeba00ce0145"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f0b4b06da13275bc02adfeb82643c4a6385bd08d26f03068c2796f60d125f6f2"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bc2e3069569ea9dbe88d6b8ea38f439a6aad8f6e7a6283a38edf61ddefb3a9bf"},
|
||||
{file = "Pillow-10.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8b451d6ead6e3500b6ce5c7916a43d8d8d25ad74b9102a629baccc0808c54971"},
|
||||
{file = "Pillow-10.0.1-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:32bec7423cdf25c9038fef614a853c9d25c07590e1a870ed471f47fb80b244db"},
|
||||
{file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cf63d2c6928b51d35dfdbda6f2c1fddbe51a6bc4a9d4ee6ea0e11670dd981e"},
|
||||
{file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f6d3d4c905e26354e8f9d82548475c46d8e0889538cb0657aa9c6f0872a37aa4"},
|
||||
{file = "Pillow-10.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:847e8d1017c741c735d3cd1883fa7b03ded4f825a6e5fcb9378fd813edee995f"},
|
||||
{file = "Pillow-10.0.1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7f771e7219ff04b79e231d099c0a28ed83aa82af91fd5fa9fdb28f5b8d5addaf"},
|
||||
{file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459307cacdd4138edee3875bbe22a2492519e060660eaf378ba3b405d1c66317"},
|
||||
{file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b059ac2c4c7a97daafa7dc850b43b2d3667def858a4f112d1aa082e5c3d6cf7d"},
|
||||
{file = "Pillow-10.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6caf3cd38449ec3cd8a68b375e0c6fe4b6fd04edb6c9766b55ef84a6e8ddf2d"},
|
||||
{file = "Pillow-10.0.1.tar.gz", hash = "sha256:d72967b06be9300fed5cfbc8b5bafceec48bf7cdc7dab66b1d2549035287191d"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818"},
|
||||
{file = "Pillow-10.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992"},
|
||||
{file = "Pillow-10.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f"},
|
||||
{file = "Pillow-10.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212"},
|
||||
{file = "Pillow-10.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2"},
|
||||
{file = "Pillow-10.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256"},
|
||||
{file = "Pillow-10.1.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7"},
|
||||
{file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba"},
|
||||
{file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4"},
|
||||
{file = "Pillow-10.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9"},
|
||||
{file = "Pillow-10.1.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e"},
|
||||
{file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412"},
|
||||
{file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b"},
|
||||
{file = "Pillow-10.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f"},
|
||||
{file = "Pillow-10.1.0.tar.gz", hash = "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@@ -1749,22 +1756,22 @@ twisted = ["twisted"]
|
||||
|
||||
[[package]]
|
||||
name = "psycopg2"
|
||||
version = "2.9.7"
|
||||
version = "2.9.9"
|
||||
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||
optional = true
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "psycopg2-2.9.7-cp310-cp310-win32.whl", hash = "sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084"},
|
||||
{file = "psycopg2-2.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5"},
|
||||
{file = "psycopg2-2.9.7-cp311-cp311-win32.whl", hash = "sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1"},
|
||||
{file = "psycopg2-2.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9"},
|
||||
{file = "psycopg2-2.9.7-cp37-cp37m-win32.whl", hash = "sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2"},
|
||||
{file = "psycopg2-2.9.7-cp37-cp37m-win_amd64.whl", hash = "sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8"},
|
||||
{file = "psycopg2-2.9.7-cp38-cp38-win32.whl", hash = "sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2"},
|
||||
{file = "psycopg2-2.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866"},
|
||||
{file = "psycopg2-2.9.7-cp39-cp39-win32.whl", hash = "sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5"},
|
||||
{file = "psycopg2-2.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723"},
|
||||
{file = "psycopg2-2.9.7.tar.gz", hash = "sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8"},
|
||||
{file = "psycopg2-2.9.9-cp310-cp310-win32.whl", hash = "sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516"},
|
||||
{file = "psycopg2-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3"},
|
||||
{file = "psycopg2-2.9.9-cp311-cp311-win32.whl", hash = "sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372"},
|
||||
{file = "psycopg2-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981"},
|
||||
{file = "psycopg2-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa"},
|
||||
{file = "psycopg2-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a"},
|
||||
{file = "psycopg2-2.9.9-cp38-cp38-win32.whl", hash = "sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"},
|
||||
{file = "psycopg2-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e"},
|
||||
{file = "psycopg2-2.9.9-cp39-cp39-win32.whl", hash = "sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59"},
|
||||
{file = "psycopg2-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913"},
|
||||
{file = "psycopg2-2.9.9.tar.gz", hash = "sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1832,18 +1839,18 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.3.0"
|
||||
version = "2.4.2"
|
||||
description = "Data validation using Python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pydantic-2.3.0-py3-none-any.whl", hash = "sha256:45b5e446c6dfaad9444819a293b921a40e1db1aa61ea08aede0522529ce90e81"},
|
||||
{file = "pydantic-2.3.0.tar.gz", hash = "sha256:1607cc106602284cd4a00882986570472f193fde9cb1259bceeaedb26aa79a6d"},
|
||||
{file = "pydantic-2.4.2-py3-none-any.whl", hash = "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1"},
|
||||
{file = "pydantic-2.4.2.tar.gz", hash = "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
annotated-types = ">=0.4.0"
|
||||
pydantic-core = "2.6.3"
|
||||
pydantic-core = "2.10.1"
|
||||
typing-extensions = ">=4.6.1"
|
||||
|
||||
[package.extras]
|
||||
@@ -1851,117 +1858,117 @@ email = ["email-validator (>=2.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.6.3"
|
||||
version = "2.10.1"
|
||||
description = ""
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:1a0ddaa723c48af27d19f27f1c73bdc615c73686d763388c8683fe34ae777bad"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5cfde4fab34dd1e3a3f7f3db38182ab6c95e4ea91cf322242ee0be5c2f7e3d2f"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5493a7027bfc6b108e17c3383959485087d5942e87eb62bbac69829eae9bc1f7"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84e87c16f582f5c753b7f39a71bd6647255512191be2d2dbf49458c4ef024588"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:522a9c4a4d1924facce7270c84b5134c5cabcb01513213662a2e89cf28c1d309"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaafc776e5edc72b3cad1ccedb5fd869cc5c9a591f1213aa9eba31a781be9ac1"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a750a83b2728299ca12e003d73d1264ad0440f60f4fc9cee54acc489249b728"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e8b374ef41ad5c461efb7a140ce4730661aadf85958b5c6a3e9cf4e040ff4bb"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b594b64e8568cf09ee5c9501ede37066b9fc41d83d58f55b9952e32141256acd"},
|
||||
{file = "pydantic_core-2.6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2a20c533cb80466c1d42a43a4521669ccad7cf2967830ac62c2c2f9cece63e7e"},
|
||||
{file = "pydantic_core-2.6.3-cp310-none-win32.whl", hash = "sha256:04fe5c0a43dec39aedba0ec9579001061d4653a9b53a1366b113aca4a3c05ca7"},
|
||||
{file = "pydantic_core-2.6.3-cp310-none-win_amd64.whl", hash = "sha256:6bf7d610ac8f0065a286002a23bcce241ea8248c71988bda538edcc90e0c39ad"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:6bcc1ad776fffe25ea5c187a028991c031a00ff92d012ca1cc4714087e575973"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:df14f6332834444b4a37685810216cc8fe1fe91f447332cd56294c984ecbff1c"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b7486d85293f7f0bbc39b34e1d8aa26210b450bbd3d245ec3d732864009819"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a892b5b1871b301ce20d40b037ffbe33d1407a39639c2b05356acfef5536d26a"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:883daa467865e5766931e07eb20f3e8152324f0adf52658f4d302242c12e2c32"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4eb77df2964b64ba190eee00b2312a1fd7a862af8918ec70fc2d6308f76ac64"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce8c84051fa292a5dc54018a40e2a1926fd17980a9422c973e3ebea017aa8da"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:22134a4453bd59b7d1e895c455fe277af9d9d9fbbcb9dc3f4a97b8693e7e2c9b"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:02e1c385095efbd997311d85c6021d32369675c09bcbfff3b69d84e59dc103f6"},
|
||||
{file = "pydantic_core-2.6.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d79f1f2f7ebdb9b741296b69049ff44aedd95976bfee38eb4848820628a99b50"},
|
||||
{file = "pydantic_core-2.6.3-cp311-none-win32.whl", hash = "sha256:430ddd965ffd068dd70ef4e4d74f2c489c3a313adc28e829dd7262cc0d2dd1e8"},
|
||||
{file = "pydantic_core-2.6.3-cp311-none-win_amd64.whl", hash = "sha256:84f8bb34fe76c68c9d96b77c60cef093f5e660ef8e43a6cbfcd991017d375950"},
|
||||
{file = "pydantic_core-2.6.3-cp311-none-win_arm64.whl", hash = "sha256:5a2a3c9ef904dcdadb550eedf3291ec3f229431b0084666e2c2aa8ff99a103a2"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:8421cf496e746cf8d6b677502ed9a0d1e4e956586cd8b221e1312e0841c002d5"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bb128c30cf1df0ab78166ded1ecf876620fb9aac84d2413e8ea1594b588c735d"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a822f630712817b6ecc09ccc378192ef5ff12e2c9bae97eb5968a6cdf3b862"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:240a015102a0c0cc8114f1cba6444499a8a4d0333e178bc504a5c2196defd456"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f90e5e3afb11268628c89f378f7a1ea3f2fe502a28af4192e30a6cdea1e7d5e"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:340e96c08de1069f3d022a85c2a8c63529fd88709468373b418f4cf2c949fb0e"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1480fa4682e8202b560dcdc9eeec1005f62a15742b813c88cdc01d44e85308e5"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f14546403c2a1d11a130b537dda28f07eb6c1805a43dae4617448074fd49c282"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a87c54e72aa2ef30189dc74427421e074ab4561cf2bf314589f6af5b37f45e6d"},
|
||||
{file = "pydantic_core-2.6.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f93255b3e4d64785554e544c1c76cd32f4a354fa79e2eeca5d16ac2e7fdd57aa"},
|
||||
{file = "pydantic_core-2.6.3-cp312-none-win32.whl", hash = "sha256:f70dc00a91311a1aea124e5f64569ea44c011b58433981313202c46bccbec0e1"},
|
||||
{file = "pydantic_core-2.6.3-cp312-none-win_amd64.whl", hash = "sha256:23470a23614c701b37252618e7851e595060a96a23016f9a084f3f92f5ed5881"},
|
||||
{file = "pydantic_core-2.6.3-cp312-none-win_arm64.whl", hash = "sha256:1ac1750df1b4339b543531ce793b8fd5c16660a95d13aecaab26b44ce11775e9"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:a53e3195f134bde03620d87a7e2b2f2046e0e5a8195e66d0f244d6d5b2f6d31b"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:f2969e8f72c6236c51f91fbb79c33821d12a811e2a94b7aa59c65f8dbdfad34a"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:672174480a85386dd2e681cadd7d951471ad0bb028ed744c895f11f9d51b9ebe"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:002d0ea50e17ed982c2d65b480bd975fc41086a5a2f9c924ef8fc54419d1dea3"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ccc13afee44b9006a73d2046068d4df96dc5b333bf3509d9a06d1b42db6d8bf"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:439a0de139556745ae53f9cc9668c6c2053444af940d3ef3ecad95b079bc9987"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63b7545d489422d417a0cae6f9898618669608750fc5e62156957e609e728a5"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b44c42edc07a50a081672e25dfe6022554b47f91e793066a7b601ca290f71e42"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1c721bfc575d57305dd922e6a40a8fe3f762905851d694245807a351ad255c58"},
|
||||
{file = "pydantic_core-2.6.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5e4a2cf8c4543f37f5dc881de6c190de08096c53986381daebb56a355be5dfe6"},
|
||||
{file = "pydantic_core-2.6.3-cp37-none-win32.whl", hash = "sha256:d9b4916b21931b08096efed090327f8fe78e09ae8f5ad44e07f5c72a7eedb51b"},
|
||||
{file = "pydantic_core-2.6.3-cp37-none-win_amd64.whl", hash = "sha256:a8acc9dedd304da161eb071cc7ff1326aa5b66aadec9622b2574ad3ffe225525"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:5e9c068f36b9f396399d43bfb6defd4cc99c36215f6ff33ac8b9c14ba15bdf6b"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e61eae9b31799c32c5f9b7be906be3380e699e74b2db26c227c50a5fc7988698"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85463560c67fc65cd86153a4975d0b720b6d7725cf7ee0b2d291288433fc21b"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9616567800bdc83ce136e5847d41008a1d602213d024207b0ff6cab6753fe645"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e9b65a55bbabda7fccd3500192a79f6e474d8d36e78d1685496aad5f9dbd92c"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f468d520f47807d1eb5d27648393519655eadc578d5dd862d06873cce04c4d1b"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9680dd23055dd874173a3a63a44e7f5a13885a4cfd7e84814be71be24fba83db"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a718d56c4d55efcfc63f680f207c9f19c8376e5a8a67773535e6f7e80e93170"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8ecbac050856eb6c3046dea655b39216597e373aa8e50e134c0e202f9c47efec"},
|
||||
{file = "pydantic_core-2.6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:788be9844a6e5c4612b74512a76b2153f1877cd845410d756841f6c3420230eb"},
|
||||
{file = "pydantic_core-2.6.3-cp38-none-win32.whl", hash = "sha256:07a1aec07333bf5adebd8264047d3dc518563d92aca6f2f5b36f505132399efc"},
|
||||
{file = "pydantic_core-2.6.3-cp38-none-win_amd64.whl", hash = "sha256:621afe25cc2b3c4ba05fff53525156d5100eb35c6e5a7cf31d66cc9e1963e378"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:813aab5bfb19c98ae370952b6f7190f1e28e565909bfc219a0909db168783465"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:50555ba3cb58f9861b7a48c493636b996a617db1a72c18da4d7f16d7b1b9952b"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e20f8baedd7d987bd3f8005c146e6bcbda7cdeefc36fad50c66adb2dd2da48"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0a5d7edb76c1c57b95df719af703e796fc8e796447a1da939f97bfa8a918d60"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f06e21ad0b504658a3a9edd3d8530e8cea5723f6ea5d280e8db8efc625b47e49"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea053cefa008fda40f92aab937fb9f183cf8752e41dbc7bc68917884454c6362"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:171a4718860790f66d6c2eda1d95dd1edf64f864d2e9f9115840840cf5b5713f"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ed7ceca6aba5331ece96c0e328cd52f0dcf942b8895a1ed2642de50800b79d3"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:acafc4368b289a9f291e204d2c4c75908557d4f36bd3ae937914d4529bf62a76"},
|
||||
{file = "pydantic_core-2.6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1aa712ba150d5105814e53cb141412217146fedc22621e9acff9236d77d2a5ef"},
|
||||
{file = "pydantic_core-2.6.3-cp39-none-win32.whl", hash = "sha256:44b4f937b992394a2e81a5c5ce716f3dcc1237281e81b80c748b2da6dd5cf29a"},
|
||||
{file = "pydantic_core-2.6.3-cp39-none-win_amd64.whl", hash = "sha256:9b33bf9658cb29ac1a517c11e865112316d09687d767d7a0e4a63d5c640d1b17"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d7050899026e708fb185e174c63ebc2c4ee7a0c17b0a96ebc50e1f76a231c057"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:99faba727727b2e59129c59542284efebbddade4f0ae6a29c8b8d3e1f437beb7"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fa159b902d22b283b680ef52b532b29554ea2a7fc39bf354064751369e9dbd7"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:046af9cfb5384f3684eeb3f58a48698ddab8dd870b4b3f67f825353a14441418"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:930bfe73e665ebce3f0da2c6d64455098aaa67e1a00323c74dc752627879fc67"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:85cc4d105747d2aa3c5cf3e37dac50141bff779545ba59a095f4a96b0a460e70"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b25afe9d5c4f60dcbbe2b277a79be114e2e65a16598db8abee2a2dcde24f162b"},
|
||||
{file = "pydantic_core-2.6.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e49ce7dc9f925e1fb010fc3d555250139df61fa6e5a0a95ce356329602c11ea9"},
|
||||
{file = "pydantic_core-2.6.3-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:2dd50d6a1aef0426a1d0199190c6c43ec89812b1f409e7fe44cb0fbf6dfa733c"},
|
||||
{file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6595b0d8c8711e8e1dc389d52648b923b809f68ac1c6f0baa525c6440aa0daa"},
|
||||
{file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ef724a059396751aef71e847178d66ad7fc3fc969a1a40c29f5aac1aa5f8784"},
|
||||
{file = "pydantic_core-2.6.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3c8945a105f1589ce8a693753b908815e0748f6279959a4530f6742e1994dcb6"},
|
||||
{file = "pydantic_core-2.6.3-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c8c6660089a25d45333cb9db56bb9e347241a6d7509838dbbd1931d0e19dbc7f"},
|
||||
{file = "pydantic_core-2.6.3-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:692b4ff5c4e828a38716cfa92667661a39886e71136c97b7dac26edef18767f7"},
|
||||
{file = "pydantic_core-2.6.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:f1a5d8f18877474c80b7711d870db0eeef9442691fcdb00adabfc97e183ee0b0"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:3796a6152c545339d3b1652183e786df648ecdf7c4f9347e1d30e6750907f5bb"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b962700962f6e7a6bd77e5f37320cabac24b4c0f76afeac05e9f93cf0c620014"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56ea80269077003eaa59723bac1d8bacd2cd15ae30456f2890811efc1e3d4413"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c0ebbebae71ed1e385f7dfd9b74c1cff09fed24a6df43d326dd7f12339ec34"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:252851b38bad3bfda47b104ffd077d4f9604a10cb06fe09d020016a25107bf98"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6656a0ae383d8cd7cc94e91de4e526407b3726049ce8d7939049cbfa426518c8"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d9140ded382a5b04a1c030b593ed9bf3088243a0a8b7fa9f071a5736498c5483"},
|
||||
{file = "pydantic_core-2.6.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d38bbcef58220f9c81e42c255ef0bf99735d8f11edef69ab0b499da77105158a"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c9d469204abcca28926cbc28ce98f28e50e488767b084fb3fbdf21af11d3de26"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48c1ed8b02ffea4d5c9c220eda27af02b8149fe58526359b3c07eb391cb353a2"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2b1bfed698fa410ab81982f681f5b1996d3d994ae8073286515ac4d165c2e7"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf9d42a71a4d7a7c1f14f629e5c30eac451a6fc81827d2beefd57d014c006c4a"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4292ca56751aebbe63a84bbfc3b5717abb09b14d4b4442cc43fd7c49a1529efd"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7dc2ce039c7290b4ef64334ec7e6ca6494de6eecc81e21cb4f73b9b39991408c"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:615a31b1629e12445c0e9fc8339b41aaa6cc60bd53bf802d5fe3d2c0cda2ae8d"},
|
||||
{file = "pydantic_core-2.6.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1fa1f6312fb84e8c281f32b39affe81984ccd484da6e9d65b3d18c202c666149"},
|
||||
{file = "pydantic_core-2.6.3.tar.gz", hash = "sha256:1508f37ba9e3ddc0189e6ff4e2228bd2d3c3a4641cbe8c07177162f76ed696c7"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e"},
|
||||
{file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6"},
|
||||
{file = "pydantic_core-2.10.1-cp310-none-win32.whl", hash = "sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b"},
|
||||
{file = "pydantic_core-2.10.1-cp310-none-win_amd64.whl", hash = "sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607"},
|
||||
{file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f"},
|
||||
{file = "pydantic_core-2.10.1-cp311-none-win32.whl", hash = "sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6"},
|
||||
{file = "pydantic_core-2.10.1-cp311-none-win_amd64.whl", hash = "sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27"},
|
||||
{file = "pydantic_core-2.10.1-cp311-none-win_arm64.whl", hash = "sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f"},
|
||||
{file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c"},
|
||||
{file = "pydantic_core-2.10.1-cp312-none-win32.whl", hash = "sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f"},
|
||||
{file = "pydantic_core-2.10.1-cp312-none-win_amd64.whl", hash = "sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430"},
|
||||
{file = "pydantic_core-2.10.1-cp312-none-win_arm64.whl", hash = "sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15"},
|
||||
{file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f"},
|
||||
{file = "pydantic_core-2.10.1-cp37-none-win32.whl", hash = "sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c"},
|
||||
{file = "pydantic_core-2.10.1-cp37-none-win_amd64.whl", hash = "sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561"},
|
||||
{file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de"},
|
||||
{file = "pydantic_core-2.10.1-cp38-none-win32.whl", hash = "sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee"},
|
||||
{file = "pydantic_core-2.10.1-cp38-none-win_amd64.whl", hash = "sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7"},
|
||||
{file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595"},
|
||||
{file = "pydantic_core-2.10.1-cp39-none-win32.whl", hash = "sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a"},
|
||||
{file = "pydantic_core-2.10.1-cp39-none-win_amd64.whl", hash = "sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357"},
|
||||
{file = "pydantic_core-2.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada"},
|
||||
{file = "pydantic_core-2.10.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a"},
|
||||
{file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f"},
|
||||
{file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e"},
|
||||
{file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55"},
|
||||
{file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514"},
|
||||
{file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2"},
|
||||
{file = "pydantic_core-2.10.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132"},
|
||||
{file = "pydantic_core-2.10.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7"},
|
||||
{file = "pydantic_core-2.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776"},
|
||||
{file = "pydantic_core-2.10.1.tar.gz", hash = "sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1969,20 +1976,23 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "pygithub"
|
||||
version = "1.59.1"
|
||||
version = "2.1.1"
|
||||
description = "Use the full Github API v3"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "PyGithub-1.59.1-py3-none-any.whl", hash = "sha256:3d87a822e6c868142f0c2c4bf16cce4696b5a7a4d142a7bd160e1bdf75bc54a9"},
|
||||
{file = "PyGithub-1.59.1.tar.gz", hash = "sha256:c44e3a121c15bf9d3a5cc98d94c9a047a5132a9b01d22264627f58ade9ddc217"},
|
||||
{file = "PyGithub-2.1.1-py3-none-any.whl", hash = "sha256:4b528d5d6f35e991ea5fd3f942f58748f24938805cb7fcf24486546637917337"},
|
||||
{file = "PyGithub-2.1.1.tar.gz", hash = "sha256:ecf12c2809c44147bce63b047b3d2e9dac8a41b63e90fcb263c703f64936b97c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
deprecated = "*"
|
||||
Deprecated = "*"
|
||||
pyjwt = {version = ">=2.4.0", extras = ["crypto"]}
|
||||
pynacl = ">=1.4.0"
|
||||
python-dateutil = "*"
|
||||
requests = ">=2.14.0"
|
||||
typing-extensions = ">=4.0.0"
|
||||
urllib3 = ">=1.26.0"
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
@@ -2126,7 +2136,7 @@ s2repoze = ["paste", "repoze.who", "zope.interface"]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
optional = true
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||
@@ -2170,6 +2180,7 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
|
||||
@@ -2177,8 +2188,15 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
|
||||
@@ -2195,6 +2213,7 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
|
||||
@@ -2202,6 +2221,7 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
|
||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||
@@ -2417,28 +2437,28 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.290"
|
||||
version = "0.0.292"
|
||||
description = "An extremely fast Python linter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.0.290-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:0e2b09ac4213b11a3520221083866a5816616f3ae9da123037b8ab275066fbac"},
|
||||
{file = "ruff-0.0.290-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:4ca6285aa77b3d966be32c9a3cd531655b3d4a0171e1f9bf26d66d0372186767"},
|
||||
{file = "ruff-0.0.290-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35e3550d1d9f2157b0fcc77670f7bb59154f223bff281766e61bdd1dd854e0c5"},
|
||||
{file = "ruff-0.0.290-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d748c8bd97874f5751aed73e8dde379ce32d16338123d07c18b25c9a2796574a"},
|
||||
{file = "ruff-0.0.290-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:982af5ec67cecd099e2ef5e238650407fb40d56304910102d054c109f390bf3c"},
|
||||
{file = "ruff-0.0.290-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bbd37352cea4ee007c48a44c9bc45a21f7ba70a57edfe46842e346651e2b995a"},
|
||||
{file = "ruff-0.0.290-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d9be6351b7889462912e0b8185a260c0219c35dfd920fb490c7f256f1d8313e"},
|
||||
{file = "ruff-0.0.290-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75cdc7fe32dcf33b7cec306707552dda54632ac29402775b9e212a3c16aad5e6"},
|
||||
{file = "ruff-0.0.290-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb07f37f7aecdbbc91d759c0c09870ce0fb3eed4025eebedf9c4b98c69abd527"},
|
||||
{file = "ruff-0.0.290-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2ab41bc0ba359d3f715fc7b705bdeef19c0461351306b70a4e247f836b9350ed"},
|
||||
{file = "ruff-0.0.290-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:150bf8050214cea5b990945b66433bf9a5e0cef395c9bc0f50569e7de7540c86"},
|
||||
{file = "ruff-0.0.290-py3-none-musllinux_1_2_i686.whl", hash = "sha256:75386ebc15fe5467248c039f5bf6a0cfe7bfc619ffbb8cd62406cd8811815fca"},
|
||||
{file = "ruff-0.0.290-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ac93eadf07bc4ab4c48d8bb4e427bf0f58f3a9c578862eb85d99d704669f5da0"},
|
||||
{file = "ruff-0.0.290-py3-none-win32.whl", hash = "sha256:461fbd1fb9ca806d4e3d5c745a30e185f7cf3ca77293cdc17abb2f2a990ad3f7"},
|
||||
{file = "ruff-0.0.290-py3-none-win_amd64.whl", hash = "sha256:f1f49f5ec967fd5778813780b12a5650ab0ebcb9ddcca28d642c689b36920796"},
|
||||
{file = "ruff-0.0.290-py3-none-win_arm64.whl", hash = "sha256:ae5a92dfbdf1f0c689433c223f8dac0782c2b2584bd502dfdbc76475669f1ba1"},
|
||||
{file = "ruff-0.0.290.tar.gz", hash = "sha256:949fecbc5467bb11b8db810a7fa53c7e02633856ee6bd1302b2f43adcd71b88d"},
|
||||
{file = "ruff-0.0.292-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:02f29db018c9d474270c704e6c6b13b18ed0ecac82761e4fcf0faa3728430c96"},
|
||||
{file = "ruff-0.0.292-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:69654e564342f507edfa09ee6897883ca76e331d4bbc3676d8a8403838e9fade"},
|
||||
{file = "ruff-0.0.292-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c3c91859a9b845c33778f11902e7b26440d64b9d5110edd4e4fa1726c41e0a4"},
|
||||
{file = "ruff-0.0.292-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f4476f1243af2d8c29da5f235c13dca52177117935e1f9393f9d90f9833f69e4"},
|
||||
{file = "ruff-0.0.292-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be8eb50eaf8648070b8e58ece8e69c9322d34afe367eec4210fdee9a555e4ca7"},
|
||||
{file = "ruff-0.0.292-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9889bac18a0c07018aac75ef6c1e6511d8411724d67cb879103b01758e110a81"},
|
||||
{file = "ruff-0.0.292-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6bdfabd4334684a4418b99b3118793f2c13bb67bf1540a769d7816410402a205"},
|
||||
{file = "ruff-0.0.292-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7c77c53bfcd75dbcd4d1f42d6cabf2485d2e1ee0678da850f08e1ab13081a8"},
|
||||
{file = "ruff-0.0.292-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e087b24d0d849c5c81516ec740bf4fd48bf363cfb104545464e0fca749b6af9"},
|
||||
{file = "ruff-0.0.292-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f160b5ec26be32362d0774964e218f3fcf0a7da299f7e220ef45ae9e3e67101a"},
|
||||
{file = "ruff-0.0.292-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ac153eee6dd4444501c4bb92bff866491d4bfb01ce26dd2fff7ca472c8df9ad0"},
|
||||
{file = "ruff-0.0.292-py3-none-musllinux_1_2_i686.whl", hash = "sha256:87616771e72820800b8faea82edd858324b29bb99a920d6aa3d3949dd3f88fb0"},
|
||||
{file = "ruff-0.0.292-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b76deb3bdbea2ef97db286cf953488745dd6424c122d275f05836c53f62d4016"},
|
||||
{file = "ruff-0.0.292-py3-none-win32.whl", hash = "sha256:e854b05408f7a8033a027e4b1c7f9889563dd2aca545d13d06711e5c39c3d003"},
|
||||
{file = "ruff-0.0.292-py3-none-win_amd64.whl", hash = "sha256:f27282bedfd04d4c3492e5c3398360c9d86a295be00eccc63914438b4ac8a83c"},
|
||||
{file = "ruff-0.0.292-py3-none-win_arm64.whl", hash = "sha256:7f67a69c8f12fbc8daf6ae6d36705037bde315abf8b82b6e1f4c9e74eb750f68"},
|
||||
{file = "ruff-0.0.292.tar.gz", hash = "sha256:1093449e37dd1e9b813798f6ad70932b57cf614e5c2b5c51005bf67d55db33ac"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2473,13 +2493,13 @@ doc = ["Sphinx", "sphinx-rtd-theme"]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "1.31.0"
|
||||
version = "1.32.0"
|
||||
description = "Python client for Sentry (https://sentry.io)"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "sentry-sdk-1.31.0.tar.gz", hash = "sha256:6de2e88304873484207fed836388e422aeff000609b104c802749fd89d56ba5b"},
|
||||
{file = "sentry_sdk-1.31.0-py2.py3-none-any.whl", hash = "sha256:64a7141005fb775b9db298a30de93e3b83e0ddd1232dc6f36eb38aebc1553291"},
|
||||
{file = "sentry-sdk-1.32.0.tar.gz", hash = "sha256:935e8fbd7787a3702457393b74b13d89a5afb67185bc0af85c00cb27cbd42e7c"},
|
||||
{file = "sentry_sdk-1.32.0-py2.py3-none-any.whl", hash = "sha256:eeb0b3550536f3bbc05bb1c7e0feb3a78d74acb43b607159a606ed2ec0a33a4d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -3027,13 +3047,13 @@ twisted = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-bleach"
|
||||
version = "6.0.0.4"
|
||||
version = "6.1.0.0"
|
||||
description = "Typing stubs for bleach"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "types-bleach-6.0.0.4.tar.gz", hash = "sha256:357b0226f65c4f20ab3b13ca8d78a6b91c78aad256d8ec168d4e90fc3303ebd4"},
|
||||
{file = "types_bleach-6.0.0.4-py3-none-any.whl", hash = "sha256:2b8767eb407c286b7f02803678732e522e04db8d56cbc9f1270bee49627eae92"},
|
||||
{file = "types-bleach-6.1.0.0.tar.gz", hash = "sha256:3cf0e55d4618890a00af1151f878b2e2a7a96433850b74e12bede7663d774532"},
|
||||
{file = "types_bleach-6.1.0.0-py3-none-any.whl", hash = "sha256:f0bc75d0f6475036ac69afebf37c41d116dfba78dae55db80437caf0fcd35c28"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3049,24 +3069,27 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "types-jsonschema"
|
||||
version = "4.17.0.10"
|
||||
version = "4.19.0.3"
|
||||
description = "Typing stubs for jsonschema"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "types-jsonschema-4.17.0.10.tar.gz", hash = "sha256:8e979db34d69bc9f9b3d6e8b89bdbc60b3a41cfce4e1fb87bf191d205c7f5098"},
|
||||
{file = "types_jsonschema-4.17.0.10-py3-none-any.whl", hash = "sha256:3aa2a89afbd9eaa6ce0c15618b36f02692a621433889ce73014656f7d8caf971"},
|
||||
{file = "types-jsonschema-4.19.0.3.tar.gz", hash = "sha256:e0fc0f5d51fd0988bf193be42174a5376b0096820ff79505d9c1b66de23f0581"},
|
||||
{file = "types_jsonschema-4.19.0.3-py3-none-any.whl", hash = "sha256:5cedbb661e5ca88d95b94b79902423e3f97a389c245e5fe0ab384122f27d56b9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
referencing = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-netaddr"
|
||||
version = "0.8.0.9"
|
||||
version = "0.9.0.1"
|
||||
description = "Typing stubs for netaddr"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-netaddr-0.8.0.9.tar.gz", hash = "sha256:68900c267fd31627c1721c5c52b32a257657ac2777457dca49b6b096ba2faf74"},
|
||||
{file = "types_netaddr-0.8.0.9-py3-none-any.whl", hash = "sha256:63e871f064cd59473cec1177f372526f0fa3d565050247d5305bdc325be5c3f6"},
|
||||
{file = "types-netaddr-0.9.0.1.tar.gz", hash = "sha256:e04638435abad3e3b13a4a6b1b07f36619a47597fd5c10f330474196c058dfb3"},
|
||||
{file = "types_netaddr-0.9.0.1-py3-none-any.whl", hash = "sha256:81b98c959d14de96eb53507ac606e8876c91413d273554a59fd42b34e3811fe0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3082,13 +3105,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "types-pillow"
|
||||
version = "10.0.0.3"
|
||||
version = "10.1.0.0"
|
||||
description = "Typing stubs for Pillow"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "types-Pillow-10.0.0.3.tar.gz", hash = "sha256:ae0c877d363da349bbb82c5463c9e78037290cc07d3714cb0ceaf5d2f7f5c825"},
|
||||
{file = "types_Pillow-10.0.0.3-py3-none-any.whl", hash = "sha256:54a49f3c6a3f5e95ebeee396d7773dde22ce2515d594f9c0596c0a983558f0d4"},
|
||||
{file = "types-Pillow-10.1.0.0.tar.gz", hash = "sha256:0f5e7cf010ed226800cb5821e87781e5d0e81257d948a9459baa74a8c8b7d822"},
|
||||
{file = "types_Pillow-10.1.0.0-py3-none-any.whl", hash = "sha256:f97f596b6a39ddfd26da3eb67421062193e10732d2310f33898d36f9694331b5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3129,17 +3152,17 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "types-requests"
|
||||
version = "2.31.0.2"
|
||||
version = "2.31.0.10"
|
||||
description = "Typing stubs for requests"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "types-requests-2.31.0.2.tar.gz", hash = "sha256:6aa3f7faf0ea52d728bb18c0a0d1522d9bfd8c72d26ff6f61bfc3d06a411cf40"},
|
||||
{file = "types_requests-2.31.0.2-py3-none-any.whl", hash = "sha256:56d181c85b5925cbc59f4489a57e72a8b2166f18273fd8ba7b6fe0c0b986f12a"},
|
||||
{file = "types-requests-2.31.0.10.tar.gz", hash = "sha256:dc5852a76f1eaf60eafa81a2e50aefa3d1f015c34cf0cba130930866b1b22a92"},
|
||||
{file = "types_requests-2.31.0.10-py3-none-any.whl", hash = "sha256:b32b9a86beffa876c0c3ac99a4cd3b8b51e973fb8e3bd4e0a6bb32c7efad80fc"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
types-urllib3 = "*"
|
||||
urllib3 = ">=2"
|
||||
|
||||
[[package]]
|
||||
name = "types-setuptools"
|
||||
@@ -3152,17 +3175,6 @@ files = [
|
||||
{file = "types_setuptools-68.2.0.0-py3-none-any.whl", hash = "sha256:77edcc843e53f8fc83bb1a840684841f3dc804ec94562623bfa2ea70d5a2ba1b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-urllib3"
|
||||
version = "1.26.25.8"
|
||||
description = "Typing stubs for urllib3"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-urllib3-1.26.25.8.tar.gz", hash = "sha256:ecf43c42d8ee439d732a1110b4901e9017a79a38daca26f08e42c8460069392c"},
|
||||
{file = "types_urllib3-1.26.25.8-py3-none-any.whl", hash = "sha256:95ea847fbf0bf675f50c8ae19a665baedcf07e6b4641662c4c3c72e7b2edf1a9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.8.0"
|
||||
@@ -3187,19 +3199,20 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.26.15"
|
||||
version = "2.0.7"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"},
|
||||
{file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"},
|
||||
{file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"},
|
||||
{file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
|
||||
secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
||||
secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "webencodings"
|
||||
@@ -3434,4 +3447,4 @@ user-search = ["pyicu"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8.0"
|
||||
content-hash = "364c309486e9d93d4da8a1a3784d5ecd7d2a9734cf84dcd4a991f2cd54f0b5b5"
|
||||
content-hash = "a08543c65f18cc7e9dea648e89c18ab88fc1747aa2e029aa208f777fc3db06dd"
|
||||
|
||||
+3
-2
@@ -92,10 +92,11 @@ skip_gitignore = true
|
||||
|
||||
[tool.maturin]
|
||||
manifest-path = "rust/Cargo.toml"
|
||||
module-name = "synapse.synapse_rust"
|
||||
|
||||
[tool.poetry]
|
||||
name = "matrix-synapse"
|
||||
version = "1.93.0"
|
||||
version = "1.95.0rc1"
|
||||
description = "Homeserver for the Matrix decentralised comms protocol"
|
||||
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
|
||||
license = "Apache-2.0"
|
||||
@@ -320,7 +321,7 @@ all = [
|
||||
# This helps prevents merge conflicts when running a batch of dependabot updates.
|
||||
isort = ">=5.10.1"
|
||||
black = ">=22.7.0"
|
||||
ruff = "0.0.290"
|
||||
ruff = "0.0.292"
|
||||
# Type checking only works with the pydantic.v1 compat module from pydantic v2
|
||||
pydantic = "^2"
|
||||
|
||||
|
||||
+5
-3
@@ -15,6 +15,8 @@ name = "synapse"
|
||||
# tests/benchmarks.
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
||||
# This is deprecated, see tool.maturin in pyproject.toml.
|
||||
# It is left here for compatibilty with maturin < 0.15.
|
||||
[package.metadata.maturin]
|
||||
# This is where we tell maturin where to place the built library.
|
||||
name = "synapse.synapse_rust"
|
||||
@@ -23,14 +25,14 @@ name = "synapse.synapse_rust"
|
||||
anyhow = "1.0.63"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.17"
|
||||
pyo3 = { version = "0.17.1", features = [
|
||||
pyo3 = { version = "0.19.2", features = [
|
||||
"macros",
|
||||
"anyhow",
|
||||
"abi3",
|
||||
"abi3-py37",
|
||||
"abi3-py38",
|
||||
] }
|
||||
pyo3-log = "0.8.1"
|
||||
pythonize = "0.17.0"
|
||||
pythonize = "0.19.0"
|
||||
regex = "1.6.0"
|
||||
serde = { version = "1.0.144", features = ["derive"] }
|
||||
serde_json = "1.0.85"
|
||||
|
||||
@@ -105,6 +105,17 @@ impl PushRuleEvaluator {
|
||||
/// Create a new `PushRuleEvaluator`. See struct docstring for details.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[new]
|
||||
#[pyo3(signature = (
|
||||
flattened_keys,
|
||||
has_mentions,
|
||||
room_member_count,
|
||||
sender_power_level,
|
||||
notification_power_levels,
|
||||
related_events_flattened,
|
||||
related_event_match_enabled,
|
||||
room_version_feature_flags,
|
||||
msc3931_enabled,
|
||||
))]
|
||||
pub fn py_new(
|
||||
flattened_keys: BTreeMap<String, JsonValue>,
|
||||
has_mentions: bool,
|
||||
|
||||
@@ -214,7 +214,7 @@ fi
|
||||
|
||||
extra_test_args=()
|
||||
|
||||
test_tags="synapse_blacklist,msc3874,msc3890,msc3391,msc3930,faster_joins"
|
||||
test_packages="./tests/csapi ./tests ./tests/msc3874 ./tests/msc3890 ./tests/msc3391 ./tests/msc3930 ./tests/msc3902"
|
||||
|
||||
# All environment variables starting with PASS_ will be shared.
|
||||
# (The prefix is stripped off before reaching the container.)
|
||||
@@ -277,4 +277,4 @@ export PASS_SYNAPSE_LOG_TESTING=1
|
||||
echo "Images built; running complement"
|
||||
cd "$COMPLEMENT_DIR"
|
||||
|
||||
go test -v -tags $test_tags -count=1 "${extra_test_args[@]}" "$@" ./tests/...
|
||||
go test -v -tags "synapse_blacklist" -count=1 "${extra_test_args[@]}" "$@" $test_packages
|
||||
|
||||
@@ -16,13 +16,24 @@
|
||||
can crop up, e.g the cache descriptors.
|
||||
"""
|
||||
|
||||
from typing import Callable, Optional, Type
|
||||
from typing import Callable, Optional, Tuple, Type, Union
|
||||
|
||||
import mypy.types
|
||||
from mypy.erasetype import remove_instance_last_known_values
|
||||
from mypy.nodes import ARG_NAMED_OPT
|
||||
from mypy.plugin import MethodSigContext, Plugin
|
||||
from mypy.errorcodes import ErrorCode
|
||||
from mypy.nodes import ARG_NAMED_OPT, TempNode, Var
|
||||
from mypy.plugin import FunctionSigContext, MethodSigContext, Plugin
|
||||
from mypy.typeops import bind_self
|
||||
from mypy.types import CallableType, Instance, NoneType, UnionType
|
||||
from mypy.types import (
|
||||
AnyType,
|
||||
CallableType,
|
||||
Instance,
|
||||
NoneType,
|
||||
TupleType,
|
||||
TypeAliasType,
|
||||
UninhabitedType,
|
||||
UnionType,
|
||||
)
|
||||
|
||||
|
||||
class SynapsePlugin(Plugin):
|
||||
@@ -36,9 +47,37 @@ class SynapsePlugin(Plugin):
|
||||
)
|
||||
):
|
||||
return cached_function_method_signature
|
||||
|
||||
if fullname in (
|
||||
"synapse.util.caches.descriptors._CachedFunctionDescriptor.__call__",
|
||||
"synapse.util.caches.descriptors._CachedListFunctionDescriptor.__call__",
|
||||
):
|
||||
return check_is_cacheable_wrapper
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _get_true_return_type(signature: CallableType) -> mypy.types.Type:
|
||||
"""
|
||||
Get the "final" return type of a callable which might return an Awaitable/Deferred.
|
||||
"""
|
||||
if isinstance(signature.ret_type, Instance):
|
||||
# If a coroutine, unwrap the coroutine's return type.
|
||||
if signature.ret_type.type.fullname == "typing.Coroutine":
|
||||
return signature.ret_type.args[2]
|
||||
|
||||
# If an awaitable, unwrap the awaitable's final value.
|
||||
elif signature.ret_type.type.fullname == "typing.Awaitable":
|
||||
return signature.ret_type.args[0]
|
||||
|
||||
# If a Deferred, unwrap the Deferred's final value.
|
||||
elif signature.ret_type.type.fullname == "twisted.internet.defer.Deferred":
|
||||
return signature.ret_type.args[0]
|
||||
|
||||
# Otherwise, return the raw value of the function.
|
||||
return signature.ret_type
|
||||
|
||||
|
||||
def cached_function_method_signature(ctx: MethodSigContext) -> CallableType:
|
||||
"""Fixes the `CachedFunction.__call__` signature to be correct.
|
||||
|
||||
@@ -47,16 +86,17 @@ def cached_function_method_signature(ctx: MethodSigContext) -> CallableType:
|
||||
1. the `self` argument needs to be marked as "bound";
|
||||
2. any `cache_context` argument should be removed;
|
||||
3. an optional keyword argument `on_invalidated` should be added.
|
||||
4. Wrap the return type to always be a Deferred.
|
||||
"""
|
||||
|
||||
# First we mark this as a bound function signature.
|
||||
signature = bind_self(ctx.default_signature)
|
||||
# 1. Mark this as a bound function signature.
|
||||
signature: CallableType = bind_self(ctx.default_signature)
|
||||
|
||||
# Secondly, we remove any "cache_context" args.
|
||||
# 2. Remove any "cache_context" args.
|
||||
#
|
||||
# Note: We should be only doing this if `cache_context=True` is set, but if
|
||||
# it isn't then the code will raise an exception when its called anyway, so
|
||||
# its not the end of the world.
|
||||
# it's not the end of the world.
|
||||
context_arg_index = None
|
||||
for idx, name in enumerate(signature.arg_names):
|
||||
if name == "cache_context":
|
||||
@@ -72,7 +112,7 @@ def cached_function_method_signature(ctx: MethodSigContext) -> CallableType:
|
||||
arg_names.pop(context_arg_index)
|
||||
arg_kinds.pop(context_arg_index)
|
||||
|
||||
# Third, we add an optional "on_invalidate" argument.
|
||||
# 3. Add an optional "on_invalidate" argument.
|
||||
#
|
||||
# This is a either
|
||||
# - a callable which accepts no input and returns nothing, or
|
||||
@@ -94,35 +134,16 @@ def cached_function_method_signature(ctx: MethodSigContext) -> CallableType:
|
||||
arg_names.append("on_invalidate")
|
||||
arg_kinds.append(ARG_NAMED_OPT) # Arg is an optional kwarg.
|
||||
|
||||
# Finally we ensure the return type is a Deferred.
|
||||
if (
|
||||
isinstance(signature.ret_type, Instance)
|
||||
and signature.ret_type.type.fullname == "twisted.internet.defer.Deferred"
|
||||
):
|
||||
# If it is already a Deferred, nothing to do.
|
||||
ret_type = signature.ret_type
|
||||
else:
|
||||
ret_arg = None
|
||||
if isinstance(signature.ret_type, Instance):
|
||||
# If a coroutine, wrap the coroutine's return type in a Deferred.
|
||||
if signature.ret_type.type.fullname == "typing.Coroutine":
|
||||
ret_arg = signature.ret_type.args[2]
|
||||
# 4. Ensure the return type is a Deferred.
|
||||
ret_arg = _get_true_return_type(signature)
|
||||
|
||||
# If an awaitable, wrap the awaitable's final value in a Deferred.
|
||||
elif signature.ret_type.type.fullname == "typing.Awaitable":
|
||||
ret_arg = signature.ret_type.args[0]
|
||||
|
||||
# Otherwise, wrap the return value in a Deferred.
|
||||
if ret_arg is None:
|
||||
ret_arg = signature.ret_type
|
||||
|
||||
# This should be able to use ctx.api.named_generic_type, but that doesn't seem
|
||||
# to find the correct symbol for anything more than 1 module deep.
|
||||
#
|
||||
# modules is not part of CheckerPluginInterface. The following is a combination
|
||||
# of TypeChecker.named_generic_type and TypeChecker.lookup_typeinfo.
|
||||
sym = ctx.api.modules["twisted.internet.defer"].names.get("Deferred") # type: ignore[attr-defined]
|
||||
ret_type = Instance(sym.node, [remove_instance_last_known_values(ret_arg)])
|
||||
# This should be able to use ctx.api.named_generic_type, but that doesn't seem
|
||||
# to find the correct symbol for anything more than 1 module deep.
|
||||
#
|
||||
# modules is not part of CheckerPluginInterface. The following is a combination
|
||||
# of TypeChecker.named_generic_type and TypeChecker.lookup_typeinfo.
|
||||
sym = ctx.api.modules["twisted.internet.defer"].names.get("Deferred") # type: ignore[attr-defined]
|
||||
ret_type = Instance(sym.node, [remove_instance_last_known_values(ret_arg)])
|
||||
|
||||
signature = signature.copy_modified(
|
||||
arg_types=arg_types,
|
||||
@@ -134,6 +155,198 @@ def cached_function_method_signature(ctx: MethodSigContext) -> CallableType:
|
||||
return signature
|
||||
|
||||
|
||||
def check_is_cacheable_wrapper(ctx: MethodSigContext) -> CallableType:
|
||||
"""Asserts that the signature of a method returns a value which can be cached.
|
||||
|
||||
Makes no changes to the provided method signature.
|
||||
"""
|
||||
# The true signature, this isn't being modified so this is what will be returned.
|
||||
signature: CallableType = ctx.default_signature
|
||||
|
||||
if not isinstance(ctx.args[0][0], TempNode):
|
||||
ctx.api.note("Cached function is not a TempNode?!", ctx.context) # type: ignore[attr-defined]
|
||||
return signature
|
||||
|
||||
orig_sig = ctx.args[0][0].type
|
||||
if not isinstance(orig_sig, CallableType):
|
||||
ctx.api.fail("Cached 'function' is not a callable", ctx.context)
|
||||
return signature
|
||||
|
||||
check_is_cacheable(orig_sig, ctx)
|
||||
|
||||
return signature
|
||||
|
||||
|
||||
def check_is_cacheable(
|
||||
signature: CallableType,
|
||||
ctx: Union[MethodSigContext, FunctionSigContext],
|
||||
) -> None:
|
||||
"""
|
||||
Check if a callable returns a type which can be cached.
|
||||
|
||||
Args:
|
||||
signature: The callable to check.
|
||||
ctx: The signature context, used for error reporting.
|
||||
"""
|
||||
# Unwrap the true return type from the cached function.
|
||||
return_type = _get_true_return_type(signature)
|
||||
|
||||
verbose = ctx.api.options.verbosity >= 1
|
||||
# TODO Technically a cachedList only needs immutable values, but forcing them
|
||||
# to return Mapping instead of Dict is fine.
|
||||
ok, note = is_cacheable(return_type, signature, verbose)
|
||||
|
||||
if ok:
|
||||
message = f"function {signature.name} is @cached, returning {return_type}"
|
||||
else:
|
||||
message = f"function {signature.name} is @cached, but has mutable return value {return_type}"
|
||||
|
||||
if note:
|
||||
message += f" ({note})"
|
||||
message = message.replace("builtins.", "").replace("typing.", "")
|
||||
|
||||
if ok and note:
|
||||
ctx.api.note(message, ctx.context) # type: ignore[attr-defined]
|
||||
elif not ok:
|
||||
ctx.api.fail(message, ctx.context, code=AT_CACHED_MUTABLE_RETURN)
|
||||
|
||||
|
||||
# Immutable simple values.
|
||||
IMMUTABLE_VALUE_TYPES = {
|
||||
"builtins.bool",
|
||||
"builtins.int",
|
||||
"builtins.float",
|
||||
"builtins.str",
|
||||
"builtins.bytes",
|
||||
}
|
||||
|
||||
# Types defined in Synapse which are known to be immutable.
|
||||
IMMUTABLE_CUSTOM_TYPES = {
|
||||
"synapse.synapse_rust.acl.ServerAclEvaluator",
|
||||
"synapse.synapse_rust.push.FilteredPushRules",
|
||||
# This is technically not immutable, but close enough.
|
||||
"signedjson.types.VerifyKey",
|
||||
}
|
||||
|
||||
# Immutable containers only if the values are also immutable.
|
||||
IMMUTABLE_CONTAINER_TYPES_REQUIRING_IMMUTABLE_ELEMENTS = {
|
||||
"builtins.frozenset",
|
||||
"builtins.tuple",
|
||||
"typing.AbstractSet",
|
||||
"typing.Sequence",
|
||||
"immutabledict.immutabledict",
|
||||
}
|
||||
|
||||
MUTABLE_CONTAINER_TYPES = {
|
||||
"builtins.set",
|
||||
"builtins.list",
|
||||
"builtins.dict",
|
||||
}
|
||||
|
||||
AT_CACHED_MUTABLE_RETURN = ErrorCode(
|
||||
"synapse-@cached-mutable",
|
||||
"@cached() should have an immutable return type",
|
||||
"General",
|
||||
)
|
||||
|
||||
|
||||
def is_cacheable(
|
||||
rt: mypy.types.Type, signature: CallableType, verbose: bool
|
||||
) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Check if a particular type is cachable.
|
||||
|
||||
A type is cachable if it is immutable; for complex types this recurses to
|
||||
check each type parameter.
|
||||
|
||||
Returns: a 2-tuple (cacheable, message).
|
||||
- cachable: False means the type is definitely not cacheable;
|
||||
true means anything else.
|
||||
- Optional message.
|
||||
"""
|
||||
|
||||
# This should probably be done via a TypeVisitor. Apologies to the reader!
|
||||
if isinstance(rt, AnyType):
|
||||
return True, ("may be mutable" if verbose else None)
|
||||
|
||||
elif isinstance(rt, Instance):
|
||||
if (
|
||||
rt.type.fullname in IMMUTABLE_VALUE_TYPES
|
||||
or rt.type.fullname in IMMUTABLE_CUSTOM_TYPES
|
||||
):
|
||||
# "Simple" types are generally immutable.
|
||||
return True, None
|
||||
|
||||
elif rt.type.fullname == "typing.Mapping":
|
||||
# Generally mapping keys are immutable, but they only *have* to be
|
||||
# hashable, which doesn't imply immutability. E.g. Mapping[K, V]
|
||||
# is cachable iff K and V are cachable.
|
||||
return is_cacheable(rt.args[0], signature, verbose) and is_cacheable(
|
||||
rt.args[1], signature, verbose
|
||||
)
|
||||
|
||||
elif rt.type.fullname in IMMUTABLE_CONTAINER_TYPES_REQUIRING_IMMUTABLE_ELEMENTS:
|
||||
# E.g. Collection[T] is cachable iff T is cachable.
|
||||
return is_cacheable(rt.args[0], signature, verbose)
|
||||
|
||||
elif rt.type.fullname in MUTABLE_CONTAINER_TYPES:
|
||||
# Mutable containers are mutable regardless of their underlying type.
|
||||
return False, None
|
||||
|
||||
elif "attrs" in rt.type.metadata:
|
||||
# attrs classes are only cachable iff it is frozen (immutable itself)
|
||||
# and all attributes are cachable.
|
||||
frozen = rt.type.metadata["attrs"]["frozen"]
|
||||
if frozen:
|
||||
for attribute in rt.type.metadata["attrs"]["attributes"]:
|
||||
attribute_name = attribute["name"]
|
||||
symbol_node = rt.type.names[attribute_name].node
|
||||
assert isinstance(symbol_node, Var)
|
||||
assert symbol_node.type is not None
|
||||
ok, note = is_cacheable(symbol_node.type, signature, verbose)
|
||||
if not ok:
|
||||
return False, f"non-frozen attrs property: {attribute_name}"
|
||||
# All attributes were frozen.
|
||||
return True, None
|
||||
else:
|
||||
return False, "non-frozen attrs class"
|
||||
|
||||
else:
|
||||
# Ensure we fail for unknown types, these generally means that the
|
||||
# above code is not complete.
|
||||
return (
|
||||
False,
|
||||
f"Don't know how to handle {rt.type.fullname} return type instance",
|
||||
)
|
||||
|
||||
elif isinstance(rt, NoneType):
|
||||
# None is cachable.
|
||||
return True, None
|
||||
|
||||
elif isinstance(rt, (TupleType, UnionType)):
|
||||
# Tuples and unions are cachable iff all their items are cachable.
|
||||
for item in rt.items:
|
||||
ok, note = is_cacheable(item, signature, verbose)
|
||||
if not ok:
|
||||
return False, note
|
||||
# This discards notes but that's probably fine
|
||||
return True, None
|
||||
|
||||
elif isinstance(rt, TypeAliasType):
|
||||
# For a type alias, check if the underlying real type is cachable.
|
||||
return is_cacheable(mypy.types.get_proper_type(rt), signature, verbose)
|
||||
|
||||
elif isinstance(rt, UninhabitedType) and rt.is_noreturn:
|
||||
# There is no return value, just consider it cachable. This is only used
|
||||
# in tests.
|
||||
return True, None
|
||||
|
||||
else:
|
||||
# Ensure we fail for unknown types, these generally means that the
|
||||
# above code is not complete.
|
||||
return False, f"Don't know how to handle {type(rt).__qualname__} return type"
|
||||
|
||||
|
||||
def plugin(version: str) -> Type[SynapsePlugin]:
|
||||
# This is the entry point of the plugin, and lets us deal with the fact
|
||||
# that the mypy plugin interface is *not* stable by looking at the version
|
||||
|
||||
@@ -684,6 +684,10 @@ def full(gh_token: str) -> None:
|
||||
click.echo("1. If this is a security release, read the security wiki page.")
|
||||
click.echo("2. Check for any release blockers before proceeding.")
|
||||
click.echo(" https://github.com/matrix-org/synapse/labels/X-Release-Blocker")
|
||||
click.echo(
|
||||
"3. Check for any other special release notes, including announcements to add to the changelog or special deployment instructions."
|
||||
)
|
||||
click.echo(" See the 'Synapse Maintainer Report'.")
|
||||
|
||||
click.confirm("Ready?", abort=True)
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ def request_registration(
|
||||
url = "%s/_synapse/admin/v1/register" % (server_location.rstrip("/"),)
|
||||
|
||||
# Get the nonce
|
||||
r = requests.get(url, verify=False)
|
||||
r = requests.get(url)
|
||||
|
||||
if r.status_code != 200:
|
||||
_print("ERROR! Received %d %s" % (r.status_code, r.reason))
|
||||
@@ -88,7 +88,7 @@ def request_registration(
|
||||
}
|
||||
|
||||
_print("Sending registration request...")
|
||||
r = requests.post(url, json=data, verify=False)
|
||||
r = requests.post(url, json=data)
|
||||
|
||||
if r.status_code != 200:
|
||||
_print("ERROR! Received %d %s" % (r.status_code, r.reason))
|
||||
|
||||
@@ -115,7 +115,7 @@ class InternalAuth(BaseAuth):
|
||||
Once get_user_by_req has set up the opentracing span, this does the actual work.
|
||||
"""
|
||||
try:
|
||||
ip_addr = request.getClientAddress().host
|
||||
ip_addr = request.get_client_ip_if_available()
|
||||
user_agent = get_request_user_agent(request)
|
||||
|
||||
access_token = self.get_access_token_from_request(request)
|
||||
|
||||
@@ -80,10 +80,6 @@ class UserPresenceState:
|
||||
def as_dict(self) -> JsonDict:
|
||||
return attr.asdict(self)
|
||||
|
||||
@staticmethod
|
||||
def from_dict(d: JsonDict) -> "UserPresenceState":
|
||||
return UserPresenceState(**d)
|
||||
|
||||
def copy_and_replace(self, **kwargs: Any) -> "UserPresenceState":
|
||||
return attr.evolve(self, **kwargs)
|
||||
|
||||
|
||||
@@ -1402,7 +1402,7 @@ class FederationClient(FederationBase):
|
||||
The remote homeserver return some state from the room. The response
|
||||
dictionary is in the form:
|
||||
|
||||
{"knock_state_events": [<state event dict>, ...]}
|
||||
{"knock_room_state": [<state event dict>, ...]}
|
||||
|
||||
The list of state events may be empty.
|
||||
|
||||
@@ -1429,7 +1429,7 @@ class FederationClient(FederationBase):
|
||||
The remote homeserver can optionally return some state from the room. The response
|
||||
dictionary is in the form:
|
||||
|
||||
{"knock_state_events": [<state event dict>, ...]}
|
||||
{"knock_room_state": [<state event dict>, ...]}
|
||||
|
||||
The list of state events may be empty.
|
||||
"""
|
||||
|
||||
@@ -850,14 +850,7 @@ class FederationServer(FederationBase):
|
||||
context, self._room_prejoin_state_types
|
||||
)
|
||||
)
|
||||
return {
|
||||
"knock_room_state": stripped_room_state,
|
||||
# Since v1.37, Synapse incorrectly used "knock_state_events" for this field.
|
||||
# Thus, we also populate a 'knock_state_events' with the same content to
|
||||
# support old instances.
|
||||
# See https://github.com/matrix-org/synapse/issues/14088.
|
||||
"knock_state_events": stripped_room_state,
|
||||
}
|
||||
return {"knock_room_state": stripped_room_state}
|
||||
|
||||
async def _on_send_membership_event(
|
||||
self, origin: str, content: JsonDict, membership_type: str, room_id: str
|
||||
|
||||
@@ -395,7 +395,7 @@ class PresenceDestinationsRow(BaseFederationRow):
|
||||
@staticmethod
|
||||
def from_data(data: JsonDict) -> "PresenceDestinationsRow":
|
||||
return PresenceDestinationsRow(
|
||||
state=UserPresenceState.from_dict(data["state"]), destinations=data["dests"]
|
||||
state=UserPresenceState(**data["state"]), destinations=data["dests"]
|
||||
)
|
||||
|
||||
def to_data(self) -> JsonDict:
|
||||
|
||||
@@ -67,7 +67,7 @@ The loop continues so long as there is anything to send. At each iteration of th
|
||||
|
||||
When the `PerDestinationQueue` has the catch-up flag set, the *Catch-Up Transmission Loop*
|
||||
(`_catch_up_transmission_loop`) is used in lieu of the regular `_transaction_transmission_loop`.
|
||||
(Only once the catch-up mode has been exited can the regular tranaction transmission behaviour
|
||||
(Only once the catch-up mode has been exited can the regular transaction transmission behaviour
|
||||
be resumed.)
|
||||
|
||||
*Catch-Up Mode*, entered upon Synapse startup or once a homeserver has fallen behind due to
|
||||
|
||||
@@ -431,7 +431,7 @@ class TransportLayerClient:
|
||||
The remote homeserver can optionally return some state from the room. The response
|
||||
dictionary is in the form:
|
||||
|
||||
{"knock_state_events": [<state event dict>, ...]}
|
||||
{"knock_room_state": [<state event dict>, ...]}
|
||||
|
||||
The list of state events may be empty.
|
||||
"""
|
||||
|
||||
@@ -212,8 +212,8 @@ class AccountValidityHandler:
|
||||
|
||||
addresses = []
|
||||
for threepid in threepids:
|
||||
if threepid["medium"] == "email":
|
||||
addresses.append(threepid["address"])
|
||||
if threepid.medium == "email":
|
||||
addresses.append(threepid.address)
|
||||
|
||||
return addresses
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ import abc
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Sequence, Set
|
||||
|
||||
import attr
|
||||
|
||||
from synapse.api.constants import Direction, Membership
|
||||
from synapse.events import EventBase
|
||||
from synapse.types import JsonMapping, RoomStreamToken, StateMap, UserID, UserInfo
|
||||
@@ -93,7 +95,7 @@ class AdminHandler:
|
||||
]
|
||||
user_info_dict["displayname"] = profile.display_name
|
||||
user_info_dict["avatar_url"] = profile.avatar_url
|
||||
user_info_dict["threepids"] = threepids
|
||||
user_info_dict["threepids"] = [attr.asdict(t) for t in threepids]
|
||||
user_info_dict["external_ids"] = external_ids
|
||||
user_info_dict["erased"] = await self._store.is_user_erased(user.to_string())
|
||||
|
||||
@@ -171,8 +173,8 @@ class AdminHandler:
|
||||
else:
|
||||
stream_ordering = room.stream_ordering
|
||||
|
||||
from_key = RoomStreamToken(0, 0)
|
||||
to_key = RoomStreamToken(None, stream_ordering)
|
||||
from_key = RoomStreamToken(topological=0, stream=0)
|
||||
to_key = RoomStreamToken(stream=stream_ordering)
|
||||
|
||||
# Events that we've processed in this room
|
||||
written_events: Set[str] = set()
|
||||
|
||||
@@ -216,7 +216,7 @@ class ApplicationServicesHandler:
|
||||
|
||||
def notify_interested_services_ephemeral(
|
||||
self,
|
||||
stream_key: str,
|
||||
stream_key: StreamKeyType,
|
||||
new_token: Union[int, RoomStreamToken],
|
||||
users: Collection[Union[str, UserID]],
|
||||
) -> None:
|
||||
@@ -326,7 +326,7 @@ class ApplicationServicesHandler:
|
||||
async def _notify_interested_services_ephemeral(
|
||||
self,
|
||||
services: List[ApplicationService],
|
||||
stream_key: str,
|
||||
stream_key: StreamKeyType,
|
||||
new_token: int,
|
||||
users: Collection[Union[str, UserID]],
|
||||
) -> None:
|
||||
|
||||
@@ -117,9 +117,9 @@ class DeactivateAccountHandler:
|
||||
|
||||
# Remove any local threepid associations for this account.
|
||||
local_threepids = await self.store.user_get_threepids(user_id)
|
||||
for threepid in local_threepids:
|
||||
for local_threepid in local_threepids:
|
||||
await self._auth_handler.delete_local_threepid(
|
||||
user_id, threepid["medium"], threepid["address"]
|
||||
user_id, local_threepid.medium, local_threepid.address
|
||||
)
|
||||
|
||||
# delete any devices belonging to the user, which will also
|
||||
|
||||
@@ -14,17 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import logging
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Dict,
|
||||
Iterable,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Set,
|
||||
Tuple,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Dict, Iterable, List, Mapping, Optional, Set, Tuple
|
||||
|
||||
from synapse.api import errors
|
||||
from synapse.api.constants import EduTypes, EventTypes
|
||||
@@ -41,6 +31,7 @@ from synapse.metrics.background_process_metrics import (
|
||||
run_as_background_process,
|
||||
wrap_as_background_process,
|
||||
)
|
||||
from synapse.storage.databases.main.client_ips import DeviceLastConnectionInfo
|
||||
from synapse.types import (
|
||||
JsonDict,
|
||||
JsonMapping,
|
||||
@@ -601,6 +592,8 @@ class DeviceHandler(DeviceWorkerHandler):
|
||||
)
|
||||
|
||||
# Delete device messages asynchronously and in batches using the task scheduler
|
||||
# We specify an upper stream id to avoid deleting non delivered messages
|
||||
# if an user re-uses a device ID.
|
||||
await self._task_scheduler.schedule_task(
|
||||
DELETE_DEVICE_MSGS_TASK_NAME,
|
||||
resource_id=device_id,
|
||||
@@ -845,7 +838,6 @@ class DeviceHandler(DeviceWorkerHandler):
|
||||
else:
|
||||
assert max_stream_id == stream_id
|
||||
# Avoid moving `room_id` backwards.
|
||||
pass
|
||||
|
||||
if self._handle_new_device_update_new_data:
|
||||
continue
|
||||
@@ -1009,14 +1001,14 @@ class DeviceHandler(DeviceWorkerHandler):
|
||||
|
||||
|
||||
def _update_device_from_client_ips(
|
||||
device: JsonDict, client_ips: Mapping[Tuple[str, str], Mapping[str, Any]]
|
||||
device: JsonDict, client_ips: Mapping[Tuple[str, str], DeviceLastConnectionInfo]
|
||||
) -> None:
|
||||
ip = client_ips.get((device["user_id"], device["device_id"]), {})
|
||||
ip = client_ips.get((device["user_id"], device["device_id"]))
|
||||
device.update(
|
||||
{
|
||||
"last_seen_user_agent": ip.get("user_agent"),
|
||||
"last_seen_ts": ip.get("last_seen"),
|
||||
"last_seen_ip": ip.get("ip"),
|
||||
"last_seen_user_agent": ip.user_agent if ip else None,
|
||||
"last_seen_ts": ip.last_seen if ip else None,
|
||||
"last_seen_ip": ip.ip if ip else None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -868,19 +868,10 @@ class FederationHandler:
|
||||
# This is a bit of a hack and is cribbing off of invites. Basically we
|
||||
# store the room state here and retrieve it again when this event appears
|
||||
# in the invitee's sync stream. It is stripped out for all other local users.
|
||||
stripped_room_state = (
|
||||
knock_response.get("knock_room_state")
|
||||
# Since v1.37, Synapse incorrectly used "knock_state_events" for this field.
|
||||
# Thus, we also check for a 'knock_state_events' to support old instances.
|
||||
# See https://github.com/matrix-org/synapse/issues/14088.
|
||||
or knock_response.get("knock_state_events")
|
||||
)
|
||||
stripped_room_state = knock_response.get("knock_room_state")
|
||||
|
||||
if stripped_room_state is None:
|
||||
raise KeyError(
|
||||
"Missing 'knock_room_state' (or legacy 'knock_state_events') field in "
|
||||
"send_knock response"
|
||||
)
|
||||
raise KeyError("Missing 'knock_room_state' field in send_knock response")
|
||||
|
||||
event.unsigned["knock_room_state"] = stripped_room_state
|
||||
|
||||
@@ -1506,7 +1497,6 @@ class FederationHandler:
|
||||
# in the meantime and context needs to be recomputed, so let's do so.
|
||||
if i == max_retries - 1:
|
||||
raise e
|
||||
pass
|
||||
else:
|
||||
destinations = {x.split(":", 1)[-1] for x in (sender_user_id, room_id)}
|
||||
|
||||
@@ -1582,7 +1572,6 @@ class FederationHandler:
|
||||
# in the meantime and context needs to be recomputed, so let's do so.
|
||||
if i == max_retries - 1:
|
||||
raise e
|
||||
pass
|
||||
|
||||
async def add_display_name_to_third_party_invite(
|
||||
self,
|
||||
|
||||
@@ -192,8 +192,7 @@ class InitialSyncHandler:
|
||||
)
|
||||
elif event.membership == Membership.LEAVE:
|
||||
room_end_token = RoomStreamToken(
|
||||
None,
|
||||
event.stream_ordering,
|
||||
stream=event.stream_ordering,
|
||||
)
|
||||
deferred_room_state = run_in_background(
|
||||
self._state_storage_controller.get_state_for_events,
|
||||
|
||||
@@ -1133,7 +1133,6 @@ class EventCreationHandler:
|
||||
# in the meantime and context needs to be recomputed, so let's do so.
|
||||
if i == max_retries - 1:
|
||||
raise e
|
||||
pass
|
||||
|
||||
# we know it was persisted, so must have a stream ordering
|
||||
assert ev.internal_metadata.stream_ordering
|
||||
@@ -2038,7 +2037,6 @@ class EventCreationHandler:
|
||||
# in the meantime and context needs to be recomputed, so let's do so.
|
||||
if i == max_retries - 1:
|
||||
raise e
|
||||
pass
|
||||
return True
|
||||
except AuthError:
|
||||
logger.info(
|
||||
|
||||
@@ -110,6 +110,7 @@ from synapse.replication.http.streams import ReplicationGetStreamUpdates
|
||||
from synapse.replication.tcp.commands import ClearUserSyncsCommand
|
||||
from synapse.replication.tcp.streams import PresenceFederationStream, PresenceStream
|
||||
from synapse.storage.databases.main import DataStore
|
||||
from synapse.storage.databases.main.state_deltas import StateDelta
|
||||
from synapse.streams import EventSource
|
||||
from synapse.types import (
|
||||
JsonDict,
|
||||
@@ -1499,9 +1500,9 @@ class PresenceHandler(BasePresenceHandler):
|
||||
# We may get multiple deltas for different rooms, but we want to
|
||||
# handle them on a room by room basis, so we batch them up by
|
||||
# room.
|
||||
deltas_by_room: Dict[str, List[JsonDict]] = {}
|
||||
deltas_by_room: Dict[str, List[StateDelta]] = {}
|
||||
for delta in deltas:
|
||||
deltas_by_room.setdefault(delta["room_id"], []).append(delta)
|
||||
deltas_by_room.setdefault(delta.room_id, []).append(delta)
|
||||
|
||||
for room_id, deltas_for_room in deltas_by_room.items():
|
||||
await self._handle_state_delta(room_id, deltas_for_room)
|
||||
@@ -1513,7 +1514,7 @@ class PresenceHandler(BasePresenceHandler):
|
||||
max_pos
|
||||
)
|
||||
|
||||
async def _handle_state_delta(self, room_id: str, deltas: List[JsonDict]) -> None:
|
||||
async def _handle_state_delta(self, room_id: str, deltas: List[StateDelta]) -> None:
|
||||
"""Process current state deltas for the room to find new joins that need
|
||||
to be handled.
|
||||
"""
|
||||
@@ -1524,31 +1525,30 @@ class PresenceHandler(BasePresenceHandler):
|
||||
newly_joined_users = set()
|
||||
|
||||
for delta in deltas:
|
||||
assert room_id == delta["room_id"]
|
||||
assert room_id == delta.room_id
|
||||
|
||||
typ = delta["type"]
|
||||
state_key = delta["state_key"]
|
||||
event_id = delta["event_id"]
|
||||
prev_event_id = delta["prev_event_id"]
|
||||
|
||||
logger.debug("Handling: %r %r, %s", typ, state_key, event_id)
|
||||
logger.debug(
|
||||
"Handling: %r %r, %s", delta.event_type, delta.state_key, delta.event_id
|
||||
)
|
||||
|
||||
# Drop any event that isn't a membership join
|
||||
if typ != EventTypes.Member:
|
||||
if delta.event_type != EventTypes.Member:
|
||||
continue
|
||||
|
||||
if event_id is None:
|
||||
if delta.event_id is None:
|
||||
# state has been deleted, so this is not a join. We only care about
|
||||
# joins.
|
||||
continue
|
||||
|
||||
event = await self.store.get_event(event_id, allow_none=True)
|
||||
event = await self.store.get_event(delta.event_id, allow_none=True)
|
||||
if not event or event.content.get("membership") != Membership.JOIN:
|
||||
# We only care about joins
|
||||
continue
|
||||
|
||||
if prev_event_id:
|
||||
prev_event = await self.store.get_event(prev_event_id, allow_none=True)
|
||||
if delta.prev_event_id:
|
||||
prev_event = await self.store.get_event(
|
||||
delta.prev_event_id, allow_none=True
|
||||
)
|
||||
if (
|
||||
prev_event
|
||||
and prev_event.content.get("membership") == Membership.JOIN
|
||||
@@ -1556,7 +1556,7 @@ class PresenceHandler(BasePresenceHandler):
|
||||
# Ignore changes to join events.
|
||||
continue
|
||||
|
||||
newly_joined_users.add(state_key)
|
||||
newly_joined_users.add(delta.state_key)
|
||||
|
||||
if not newly_joined_users:
|
||||
# If nobody has joined then there's nothing to do.
|
||||
|
||||
@@ -19,7 +19,7 @@ from synapse.api.errors import SynapseError, UnrecognizedRequestError
|
||||
from synapse.push.clientformat import format_push_rules_for_user
|
||||
from synapse.storage.push_rule import RuleNotFoundException
|
||||
from synapse.synapse_rust.push import get_base_rule_ids
|
||||
from synapse.types import JsonDict, UserID
|
||||
from synapse.types import JsonDict, StreamKeyType, UserID
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.server import HomeServer
|
||||
@@ -114,7 +114,9 @@ class PushRulesHandler:
|
||||
user_id: the user ID the change is for.
|
||||
"""
|
||||
stream_id = self._main_store.get_max_push_rules_stream_id()
|
||||
self._notifier.on_new_event("push_rules_key", stream_id, users=[user_id])
|
||||
self._notifier.on_new_event(
|
||||
StreamKeyType.PUSH_RULES, stream_id, users=[user_id]
|
||||
)
|
||||
|
||||
async def push_rules_for_user(
|
||||
self, user: UserID
|
||||
|
||||
@@ -130,11 +130,10 @@ class ReceiptsHandler:
|
||||
|
||||
async def _handle_new_receipts(self, receipts: List[ReadReceipt]) -> bool:
|
||||
"""Takes a list of receipts, stores them and informs the notifier."""
|
||||
min_batch_id: Optional[int] = None
|
||||
max_batch_id: Optional[int] = None
|
||||
|
||||
receipts_persisted: List[ReadReceipt] = []
|
||||
for receipt in receipts:
|
||||
res = await self.store.insert_receipt(
|
||||
stream_id = await self.store.insert_receipt(
|
||||
receipt.room_id,
|
||||
receipt.receipt_type,
|
||||
receipt.user_id,
|
||||
@@ -143,30 +142,26 @@ class ReceiptsHandler:
|
||||
receipt.data,
|
||||
)
|
||||
|
||||
if not res:
|
||||
# res will be None if this receipt is 'old'
|
||||
if stream_id is None:
|
||||
# stream_id will be None if this receipt is 'old'
|
||||
continue
|
||||
|
||||
stream_id, max_persisted_id = res
|
||||
receipts_persisted.append(receipt)
|
||||
|
||||
if min_batch_id is None or stream_id < min_batch_id:
|
||||
min_batch_id = stream_id
|
||||
if max_batch_id is None or max_persisted_id > max_batch_id:
|
||||
max_batch_id = max_persisted_id
|
||||
|
||||
# Either both of these should be None or neither.
|
||||
if min_batch_id is None or max_batch_id is None:
|
||||
if not receipts_persisted:
|
||||
# no new receipts
|
||||
return False
|
||||
|
||||
affected_room_ids = list({r.room_id for r in receipts})
|
||||
max_batch_id = self.store.get_max_receipt_stream_id()
|
||||
|
||||
affected_room_ids = list({r.room_id for r in receipts_persisted})
|
||||
|
||||
self.notifier.on_new_event(
|
||||
StreamKeyType.RECEIPT, max_batch_id, rooms=affected_room_ids
|
||||
)
|
||||
# Note that the min here shouldn't be relied upon to be accurate.
|
||||
await self.hs.get_pusherpool().on_new_receipts(
|
||||
min_batch_id, max_batch_id, affected_room_ids
|
||||
{r.user_id for r in receipts_persisted}
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
@@ -261,7 +261,6 @@ class RoomCreationHandler:
|
||||
# in the meantime and context needs to be recomputed, so let's do so.
|
||||
if i == max_retries - 1:
|
||||
raise e
|
||||
pass
|
||||
|
||||
# This is to satisfy mypy and should never happen
|
||||
raise PartialStateConflictError()
|
||||
@@ -1708,7 +1707,7 @@ class RoomEventSource(EventSource[RoomStreamToken, EventBase]):
|
||||
|
||||
if from_key.topological:
|
||||
logger.warning("Stream has topological part!!!! %r", from_key)
|
||||
from_key = RoomStreamToken(None, from_key.stream)
|
||||
from_key = RoomStreamToken(stream=from_key.stream)
|
||||
|
||||
app_service = self.store.get_app_service_by_user_id(user.to_string())
|
||||
if app_service:
|
||||
|
||||
@@ -33,7 +33,7 @@ from synapse.api.errors import (
|
||||
RequestSendFailed,
|
||||
SynapseError,
|
||||
)
|
||||
from synapse.types import JsonDict, ThirdPartyInstanceID
|
||||
from synapse.types import JsonDict, JsonMapping, ThirdPartyInstanceID
|
||||
from synapse.util.caches.descriptors import _CacheContext, cached
|
||||
from synapse.util.caches.response_cache import ResponseCache
|
||||
|
||||
@@ -256,7 +256,7 @@ class RoomListHandler:
|
||||
cache_context: _CacheContext,
|
||||
with_alias: bool = True,
|
||||
allow_private: bool = False,
|
||||
) -> Optional[JsonDict]:
|
||||
) -> Optional[JsonMapping]:
|
||||
"""Returns the entry for a room
|
||||
|
||||
Args:
|
||||
|
||||
@@ -16,7 +16,7 @@ import abc
|
||||
import logging
|
||||
import random
|
||||
from http import HTTPStatus
|
||||
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Set, Tuple
|
||||
from typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple
|
||||
|
||||
from synapse import types
|
||||
from synapse.api.constants import (
|
||||
@@ -44,6 +44,7 @@ from synapse.handlers.worker_lock import NEW_EVENT_DURING_PURGE_LOCK_NAME
|
||||
from synapse.logging import opentracing
|
||||
from synapse.metrics import event_processing_positions
|
||||
from synapse.metrics.background_process_metrics import run_as_background_process
|
||||
from synapse.storage.databases.main.state_deltas import StateDelta
|
||||
from synapse.types import (
|
||||
JsonDict,
|
||||
Requester,
|
||||
@@ -382,8 +383,10 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||
and persist a new event for the new membership change.
|
||||
|
||||
Args:
|
||||
requester:
|
||||
target:
|
||||
requester: User requesting the membership change, i.e. the sender of the
|
||||
desired membership event.
|
||||
target: Use whose membership should change, i.e. the state_key of the
|
||||
desired membership event.
|
||||
room_id:
|
||||
membership:
|
||||
|
||||
@@ -415,7 +418,6 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||
Returns:
|
||||
Tuple of event ID and stream ordering position
|
||||
"""
|
||||
|
||||
user_id = target.to_string()
|
||||
|
||||
if content is None:
|
||||
@@ -475,21 +477,6 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||
(EventTypes.Member, user_id), None
|
||||
)
|
||||
|
||||
if event.membership == Membership.JOIN:
|
||||
newly_joined = True
|
||||
if prev_member_event_id:
|
||||
prev_member_event = await self.store.get_event(
|
||||
prev_member_event_id
|
||||
)
|
||||
newly_joined = prev_member_event.membership != Membership.JOIN
|
||||
|
||||
# Only rate-limit if the user actually joined the room, otherwise we'll end
|
||||
# up blocking profile updates.
|
||||
if newly_joined and ratelimit:
|
||||
await self._join_rate_limiter_local.ratelimit(requester)
|
||||
await self._join_rate_per_room_limiter.ratelimit(
|
||||
requester, key=room_id, update=False
|
||||
)
|
||||
with opentracing.start_active_span("handle_new_client_event"):
|
||||
result_event = (
|
||||
await self.event_creation_handler.handle_new_client_event(
|
||||
@@ -514,7 +501,6 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||
# in the meantime and context needs to be recomputed, so let's do so.
|
||||
if i == max_retries - 1:
|
||||
raise e
|
||||
pass
|
||||
|
||||
# we know it was persisted, so should have a stream ordering
|
||||
assert result_event.internal_metadata.stream_ordering
|
||||
@@ -618,6 +604,25 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||
Raises:
|
||||
ShadowBanError if a shadow-banned requester attempts to send an invite.
|
||||
"""
|
||||
if ratelimit:
|
||||
if action == Membership.JOIN:
|
||||
# Only rate-limit if the user isn't already joined to the room, otherwise
|
||||
# we'll end up blocking profile updates.
|
||||
(
|
||||
current_membership,
|
||||
_,
|
||||
) = await self.store.get_local_current_membership_for_user_in_room(
|
||||
requester.user.to_string(),
|
||||
room_id,
|
||||
)
|
||||
if current_membership != Membership.JOIN:
|
||||
await self._join_rate_limiter_local.ratelimit(requester)
|
||||
await self._join_rate_per_room_limiter.ratelimit(
|
||||
requester, key=room_id, update=False
|
||||
)
|
||||
elif action == Membership.INVITE:
|
||||
await self.ratelimit_invite(requester, room_id, target.to_string())
|
||||
|
||||
if action == Membership.INVITE and requester.shadow_banned:
|
||||
# We randomly sleep a bit just to annoy the requester.
|
||||
await self.clock.sleep(random.randint(1, 10))
|
||||
@@ -794,8 +799,6 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||
|
||||
if effective_membership_state == Membership.INVITE:
|
||||
target_id = target.to_string()
|
||||
if ratelimit:
|
||||
await self.ratelimit_invite(requester, room_id, target_id)
|
||||
|
||||
# block any attempts to invite the server notices mxid
|
||||
if target_id == self._server_notices_mxid:
|
||||
@@ -2002,7 +2005,6 @@ class RoomMemberMasterHandler(RoomMemberHandler):
|
||||
# in the meantime and context needs to be recomputed, so let's do so.
|
||||
if i == max_retries - 1:
|
||||
raise e
|
||||
pass
|
||||
|
||||
# we know it was persisted, so must have a stream ordering
|
||||
assert result_event.internal_metadata.stream_ordering
|
||||
@@ -2145,24 +2147,18 @@ class RoomForgetterHandler(StateDeltasHandler):
|
||||
|
||||
await self._store.update_room_forgetter_stream_pos(max_pos)
|
||||
|
||||
async def _handle_deltas(self, deltas: List[Dict[str, Any]]) -> None:
|
||||
async def _handle_deltas(self, deltas: List[StateDelta]) -> None:
|
||||
"""Called with the state deltas to process"""
|
||||
for delta in deltas:
|
||||
typ = delta["type"]
|
||||
state_key = delta["state_key"]
|
||||
room_id = delta["room_id"]
|
||||
event_id = delta["event_id"]
|
||||
prev_event_id = delta["prev_event_id"]
|
||||
|
||||
if typ != EventTypes.Member:
|
||||
if delta.event_type != EventTypes.Member:
|
||||
continue
|
||||
|
||||
if not self._hs.is_mine_id(state_key):
|
||||
if not self._hs.is_mine_id(delta.state_key):
|
||||
continue
|
||||
|
||||
change = await self._get_key_change(
|
||||
prev_event_id,
|
||||
event_id,
|
||||
delta.prev_event_id,
|
||||
delta.event_id,
|
||||
key_name="membership",
|
||||
public_value=Membership.JOIN,
|
||||
)
|
||||
@@ -2171,7 +2167,7 @@ class RoomForgetterHandler(StateDeltasHandler):
|
||||
if is_leave:
|
||||
try:
|
||||
await self._room_member_handler.forget(
|
||||
UserID.from_string(state_key), room_id
|
||||
UserID.from_string(delta.state_key), delta.room_id
|
||||
)
|
||||
except SynapseError as e:
|
||||
if e.code == 400:
|
||||
|
||||
+32
-32
@@ -27,6 +27,7 @@ from typing import (
|
||||
from synapse.api.constants import EventContentFields, EventTypes, Membership
|
||||
from synapse.metrics import event_processing_positions
|
||||
from synapse.metrics.background_process_metrics import run_as_background_process
|
||||
from synapse.storage.databases.main.state_deltas import StateDelta
|
||||
from synapse.types import JsonDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -142,7 +143,7 @@ class StatsHandler:
|
||||
self.pos = max_pos
|
||||
|
||||
async def _handle_deltas(
|
||||
self, deltas: Iterable[JsonDict]
|
||||
self, deltas: Iterable[StateDelta]
|
||||
) -> Tuple[Dict[str, CounterType[str]], Dict[str, CounterType[str]]]:
|
||||
"""Called with the state deltas to process
|
||||
|
||||
@@ -157,51 +158,50 @@ class StatsHandler:
|
||||
room_to_state_updates: Dict[str, Dict[str, Any]] = {}
|
||||
|
||||
for delta in deltas:
|
||||
typ = delta["type"]
|
||||
state_key = delta["state_key"]
|
||||
room_id = delta["room_id"]
|
||||
event_id = delta["event_id"]
|
||||
stream_id = delta["stream_id"]
|
||||
prev_event_id = delta["prev_event_id"]
|
||||
logger.debug(
|
||||
"Handling: %r, %r %r, %s",
|
||||
delta.room_id,
|
||||
delta.event_type,
|
||||
delta.state_key,
|
||||
delta.event_id,
|
||||
)
|
||||
|
||||
logger.debug("Handling: %r, %r %r, %s", room_id, typ, state_key, event_id)
|
||||
|
||||
token = await self.store.get_earliest_token_for_stats("room", room_id)
|
||||
token = await self.store.get_earliest_token_for_stats("room", delta.room_id)
|
||||
|
||||
# If the earliest token to begin from is larger than our current
|
||||
# stream ID, skip processing this delta.
|
||||
if token is not None and token >= stream_id:
|
||||
if token is not None and token >= delta.stream_id:
|
||||
logger.debug(
|
||||
"Ignoring: %s as earlier than this room's initial ingestion event",
|
||||
event_id,
|
||||
delta.event_id,
|
||||
)
|
||||
continue
|
||||
|
||||
if event_id is None and prev_event_id is None:
|
||||
if delta.event_id is None and delta.prev_event_id is None:
|
||||
logger.error(
|
||||
"event ID is None and so is the previous event ID. stream_id: %s",
|
||||
stream_id,
|
||||
delta.stream_id,
|
||||
)
|
||||
continue
|
||||
|
||||
event_content: JsonDict = {}
|
||||
|
||||
if event_id is not None:
|
||||
event = await self.store.get_event(event_id, allow_none=True)
|
||||
if delta.event_id is not None:
|
||||
event = await self.store.get_event(delta.event_id, allow_none=True)
|
||||
if event:
|
||||
event_content = event.content or {}
|
||||
|
||||
# All the values in this dict are deltas (RELATIVE changes)
|
||||
room_stats_delta = room_to_stats_deltas.setdefault(room_id, Counter())
|
||||
room_stats_delta = room_to_stats_deltas.setdefault(delta.room_id, Counter())
|
||||
|
||||
room_state = room_to_state_updates.setdefault(room_id, {})
|
||||
room_state = room_to_state_updates.setdefault(delta.room_id, {})
|
||||
|
||||
if prev_event_id is None:
|
||||
if delta.prev_event_id is None:
|
||||
# this state event doesn't overwrite another,
|
||||
# so it is a new effective/current state event
|
||||
room_stats_delta["current_state_events"] += 1
|
||||
|
||||
if typ == EventTypes.Member:
|
||||
if delta.event_type == EventTypes.Member:
|
||||
# we could use StateDeltasHandler._get_key_change here but it's
|
||||
# a bit inefficient given we're not testing for a specific
|
||||
# result; might as well just grab the prev_membership and
|
||||
@@ -210,9 +210,9 @@ class StatsHandler:
|
||||
# in the absence of a previous event because we do not want to
|
||||
# reduce the leave count when a new-to-the-room user joins.
|
||||
prev_membership = None
|
||||
if prev_event_id is not None:
|
||||
if delta.prev_event_id is not None:
|
||||
prev_event = await self.store.get_event(
|
||||
prev_event_id, allow_none=True
|
||||
delta.prev_event_id, allow_none=True
|
||||
)
|
||||
if prev_event:
|
||||
prev_event_content = prev_event.content
|
||||
@@ -256,7 +256,7 @@ class StatsHandler:
|
||||
else:
|
||||
raise ValueError("%r is not a valid membership" % (membership,))
|
||||
|
||||
user_id = state_key
|
||||
user_id = delta.state_key
|
||||
if self.is_mine_id(user_id):
|
||||
# this accounts for transitions like leave → ban and so on.
|
||||
has_changed_joinedness = (prev_membership == Membership.JOIN) != (
|
||||
@@ -272,30 +272,30 @@ class StatsHandler:
|
||||
|
||||
room_stats_delta["local_users_in_room"] += membership_delta
|
||||
|
||||
elif typ == EventTypes.Create:
|
||||
elif delta.event_type == EventTypes.Create:
|
||||
room_state["is_federatable"] = (
|
||||
event_content.get(EventContentFields.FEDERATE, True) is True
|
||||
)
|
||||
room_type = event_content.get(EventContentFields.ROOM_TYPE)
|
||||
if isinstance(room_type, str):
|
||||
room_state["room_type"] = room_type
|
||||
elif typ == EventTypes.JoinRules:
|
||||
elif delta.event_type == EventTypes.JoinRules:
|
||||
room_state["join_rules"] = event_content.get("join_rule")
|
||||
elif typ == EventTypes.RoomHistoryVisibility:
|
||||
elif delta.event_type == EventTypes.RoomHistoryVisibility:
|
||||
room_state["history_visibility"] = event_content.get(
|
||||
"history_visibility"
|
||||
)
|
||||
elif typ == EventTypes.RoomEncryption:
|
||||
elif delta.event_type == EventTypes.RoomEncryption:
|
||||
room_state["encryption"] = event_content.get("algorithm")
|
||||
elif typ == EventTypes.Name:
|
||||
elif delta.event_type == EventTypes.Name:
|
||||
room_state["name"] = event_content.get("name")
|
||||
elif typ == EventTypes.Topic:
|
||||
elif delta.event_type == EventTypes.Topic:
|
||||
room_state["topic"] = event_content.get("topic")
|
||||
elif typ == EventTypes.RoomAvatar:
|
||||
elif delta.event_type == EventTypes.RoomAvatar:
|
||||
room_state["avatar"] = event_content.get("url")
|
||||
elif typ == EventTypes.CanonicalAlias:
|
||||
elif delta.event_type == EventTypes.CanonicalAlias:
|
||||
room_state["canonical_alias"] = event_content.get("alias")
|
||||
elif typ == EventTypes.GuestAccess:
|
||||
elif delta.event_type == EventTypes.GuestAccess:
|
||||
room_state["guest_access"] = event_content.get(
|
||||
EventContentFields.GUEST_ACCESS
|
||||
)
|
||||
|
||||
+45
-31
@@ -40,7 +40,6 @@ from synapse.api.filtering import FilterCollection
|
||||
from synapse.api.presence import UserPresenceState
|
||||
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
|
||||
from synapse.events import EventBase
|
||||
from synapse.handlers.device import DELETE_DEVICE_MSGS_TASK_NAME
|
||||
from synapse.handlers.relations import BundledAggregations
|
||||
from synapse.logging import issue9533_logger
|
||||
from synapse.logging.context import current_context
|
||||
@@ -363,36 +362,15 @@ class SyncHandler:
|
||||
# (since we now know that the device has received them)
|
||||
if since_token is not None:
|
||||
since_stream_id = since_token.to_device_key
|
||||
# Fast path: delete a limited number of to-device messages up front.
|
||||
# We do this to avoid the overhead of scheduling a task for every
|
||||
# sync.
|
||||
device_deletion_limit = 100
|
||||
deleted = await self.store.delete_messages_for_device(
|
||||
sync_config.user.to_string(),
|
||||
sync_config.device_id,
|
||||
since_stream_id,
|
||||
limit=device_deletion_limit,
|
||||
)
|
||||
logger.debug(
|
||||
"Deleted %d to-device messages up to %d", deleted, since_stream_id
|
||||
)
|
||||
|
||||
# If we hit the limit, schedule a background task to delete the rest.
|
||||
if deleted >= device_deletion_limit:
|
||||
await self._task_scheduler.schedule_task(
|
||||
DELETE_DEVICE_MSGS_TASK_NAME,
|
||||
resource_id=sync_config.device_id,
|
||||
params={
|
||||
"user_id": sync_config.user.to_string(),
|
||||
"device_id": sync_config.device_id,
|
||||
"up_to_stream_id": since_stream_id,
|
||||
},
|
||||
)
|
||||
logger.debug(
|
||||
"Deletion of to-device messages up to %d scheduled",
|
||||
since_stream_id,
|
||||
)
|
||||
|
||||
if timeout == 0 or since_token is None or full_state:
|
||||
# we are going to return immediately, so don't bother calling
|
||||
# notifier.wait_for_events.
|
||||
@@ -522,12 +500,27 @@ class SyncHandler:
|
||||
async def _load_filtered_recents(
|
||||
self,
|
||||
room_id: str,
|
||||
sync_result_builder: "SyncResultBuilder",
|
||||
sync_config: SyncConfig,
|
||||
now_token: StreamToken,
|
||||
upto_token: StreamToken,
|
||||
since_token: Optional[StreamToken] = None,
|
||||
potential_recents: Optional[List[EventBase]] = None,
|
||||
newly_joined_room: bool = False,
|
||||
) -> TimelineBatch:
|
||||
"""Create a timeline batch for the room
|
||||
|
||||
Args:
|
||||
room_id
|
||||
sync_result_builder
|
||||
sync_config
|
||||
upto_token: The token up to which we should fetch (more) events.
|
||||
If `potential_results` is non-empty then this is *start* of
|
||||
the the list.
|
||||
since_token
|
||||
potential_recents: If non-empty, the events between the since token
|
||||
and current token to send down to clients.
|
||||
newly_joined_room
|
||||
"""
|
||||
with Measure(self.clock, "load_filtered_recents"):
|
||||
timeline_limit = sync_config.filter_collection.timeline_limit()
|
||||
block_all_timeline = (
|
||||
@@ -543,6 +536,20 @@ class SyncHandler:
|
||||
else:
|
||||
limited = False
|
||||
|
||||
# Check if there is a gap, if so we need to mark this as limited and
|
||||
# recalculate which events to send down.
|
||||
gap_token = await self.store.get_timeline_gaps(
|
||||
room_id,
|
||||
since_token.room_key if since_token else None,
|
||||
sync_result_builder.now_token.room_key,
|
||||
)
|
||||
if gap_token:
|
||||
# There's a gap, so we need to ignore the passed in
|
||||
# `potential_recents`, and reset `upto_token` to match.
|
||||
potential_recents = None
|
||||
upto_token = sync_result_builder.now_token
|
||||
limited = True
|
||||
|
||||
log_kv({"limited": limited})
|
||||
|
||||
if potential_recents:
|
||||
@@ -581,10 +588,10 @@ class SyncHandler:
|
||||
recents = []
|
||||
|
||||
if not limited or block_all_timeline:
|
||||
prev_batch_token = now_token
|
||||
prev_batch_token = upto_token
|
||||
if recents:
|
||||
room_key = recents[0].internal_metadata.before
|
||||
prev_batch_token = now_token.copy_and_replace(
|
||||
prev_batch_token = upto_token.copy_and_replace(
|
||||
StreamKeyType.ROOM, room_key
|
||||
)
|
||||
|
||||
@@ -595,11 +602,15 @@ class SyncHandler:
|
||||
filtering_factor = 2
|
||||
load_limit = max(timeline_limit * filtering_factor, 10)
|
||||
max_repeat = 5 # Only try a few times per room, otherwise
|
||||
room_key = now_token.room_key
|
||||
room_key = upto_token.room_key
|
||||
end_key = room_key
|
||||
|
||||
since_key = None
|
||||
if since_token and not newly_joined_room:
|
||||
if since_token and gap_token:
|
||||
# If there is a gap then we need to only include events after
|
||||
# it.
|
||||
since_key = gap_token
|
||||
elif since_token and not newly_joined_room:
|
||||
since_key = since_token.room_key
|
||||
|
||||
while limited and len(recents) < timeline_limit and max_repeat:
|
||||
@@ -669,7 +680,7 @@ class SyncHandler:
|
||||
recents = recents[-timeline_limit:]
|
||||
room_key = recents[0].internal_metadata.before
|
||||
|
||||
prev_batch_token = now_token.copy_and_replace(StreamKeyType.ROOM, room_key)
|
||||
prev_batch_token = upto_token.copy_and_replace(StreamKeyType.ROOM, room_key)
|
||||
|
||||
# Don't bother to bundle aggregations if the timeline is unlimited,
|
||||
# as clients will have all the necessary information.
|
||||
@@ -684,7 +695,9 @@ class SyncHandler:
|
||||
return TimelineBatch(
|
||||
events=recents,
|
||||
prev_batch=prev_batch_token,
|
||||
limited=limited or newly_joined_room,
|
||||
# Also mark as limited if this is a new room or there has been a gap
|
||||
# (to force client to paginate the gap).
|
||||
limited=limited or newly_joined_room or gap_token is not None,
|
||||
bundled_aggregations=bundled_aggregations,
|
||||
)
|
||||
|
||||
@@ -2333,7 +2346,7 @@ class SyncHandler:
|
||||
continue
|
||||
|
||||
leave_token = now_token.copy_and_replace(
|
||||
StreamKeyType.ROOM, RoomStreamToken(None, event.stream_ordering)
|
||||
StreamKeyType.ROOM, RoomStreamToken(stream=event.stream_ordering)
|
||||
)
|
||||
room_entries.append(
|
||||
RoomSyncResultBuilder(
|
||||
@@ -2419,8 +2432,9 @@ class SyncHandler:
|
||||
|
||||
batch = await self._load_filtered_recents(
|
||||
room_id,
|
||||
sync_result_builder,
|
||||
sync_config,
|
||||
now_token=upto_token,
|
||||
upto_token=upto_token,
|
||||
since_token=since_token,
|
||||
potential_recents=events,
|
||||
newly_joined_room=newly_joined,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
import logging
|
||||
from http import HTTPStatus
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple
|
||||
from typing import TYPE_CHECKING, List, Optional, Set, Tuple
|
||||
|
||||
from twisted.internet.interfaces import IDelayedCall
|
||||
|
||||
@@ -23,6 +23,7 @@ from synapse.api.constants import EventTypes, HistoryVisibility, JoinRules, Memb
|
||||
from synapse.api.errors import Codes, SynapseError
|
||||
from synapse.handlers.state_deltas import MatchChange, StateDeltasHandler
|
||||
from synapse.metrics.background_process_metrics import run_as_background_process
|
||||
from synapse.storage.databases.main.state_deltas import StateDelta
|
||||
from synapse.storage.databases.main.user_directory import SearchResult
|
||||
from synapse.storage.roommember import ProfileInfo
|
||||
from synapse.types import UserID
|
||||
@@ -247,32 +248,31 @@ class UserDirectoryHandler(StateDeltasHandler):
|
||||
|
||||
await self.store.update_user_directory_stream_pos(max_pos)
|
||||
|
||||
async def _handle_deltas(self, deltas: List[Dict[str, Any]]) -> None:
|
||||
async def _handle_deltas(self, deltas: List[StateDelta]) -> None:
|
||||
"""Called with the state deltas to process"""
|
||||
for delta in deltas:
|
||||
typ = delta["type"]
|
||||
state_key = delta["state_key"]
|
||||
room_id = delta["room_id"]
|
||||
event_id: Optional[str] = delta["event_id"]
|
||||
prev_event_id: Optional[str] = delta["prev_event_id"]
|
||||
|
||||
logger.debug("Handling: %r %r, %s", typ, state_key, event_id)
|
||||
logger.debug(
|
||||
"Handling: %r %r, %s", delta.event_type, delta.state_key, delta.event_id
|
||||
)
|
||||
|
||||
# For join rule and visibility changes we need to check if the room
|
||||
# may have become public or not and add/remove the users in said room
|
||||
if typ in (EventTypes.RoomHistoryVisibility, EventTypes.JoinRules):
|
||||
if delta.event_type in (
|
||||
EventTypes.RoomHistoryVisibility,
|
||||
EventTypes.JoinRules,
|
||||
):
|
||||
await self._handle_room_publicity_change(
|
||||
room_id, prev_event_id, event_id, typ
|
||||
delta.room_id, delta.prev_event_id, delta.event_id, delta.event_type
|
||||
)
|
||||
elif typ == EventTypes.Member:
|
||||
elif delta.event_type == EventTypes.Member:
|
||||
await self._handle_room_membership_event(
|
||||
room_id,
|
||||
prev_event_id,
|
||||
event_id,
|
||||
state_key,
|
||||
delta.room_id,
|
||||
delta.prev_event_id,
|
||||
delta.event_id,
|
||||
delta.state_key,
|
||||
)
|
||||
else:
|
||||
logger.debug("Ignoring irrelevant type: %r", typ)
|
||||
logger.debug("Ignoring irrelevant type: %r", delta.event_type)
|
||||
|
||||
async def _handle_room_publicity_change(
|
||||
self,
|
||||
|
||||
@@ -266,7 +266,7 @@ class HttpServer(Protocol):
|
||||
def register_paths(
|
||||
self,
|
||||
method: str,
|
||||
path_patterns: Iterable[Pattern],
|
||||
path_patterns: Iterable[Pattern[str]],
|
||||
callback: ServletCallback,
|
||||
servlet_classname: str,
|
||||
) -> None:
|
||||
|
||||
+46
-46
@@ -26,11 +26,11 @@ from twisted.internet.interfaces import IConsumer
|
||||
from twisted.protocols.basic import FileSender
|
||||
from twisted.web.server import Request
|
||||
|
||||
from synapse.api.errors import Codes, SynapseError, cs_error
|
||||
from synapse.api.errors import Codes, cs_error
|
||||
from synapse.http.server import finish_request, respond_with_json
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.logging.context import make_deferred_yieldable
|
||||
from synapse.util.stringutils import is_ascii, parse_and_validate_server_name
|
||||
from synapse.util.stringutils import is_ascii
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -50,53 +50,46 @@ TEXT_CONTENT_TYPES = [
|
||||
"text/xml",
|
||||
]
|
||||
|
||||
|
||||
def parse_media_id(request: Request) -> Tuple[str, str, Optional[str]]:
|
||||
"""Parses the server name, media ID and optional file name from the request URI
|
||||
|
||||
Also performs some rough validation on the server name.
|
||||
|
||||
Args:
|
||||
request: The `Request`.
|
||||
|
||||
Returns:
|
||||
A tuple containing the parsed server name, media ID and optional file name.
|
||||
|
||||
Raises:
|
||||
SynapseError(404): if parsing or validation fail for any reason
|
||||
"""
|
||||
try:
|
||||
# The type on postpath seems incorrect in Twisted 21.2.0.
|
||||
postpath: List[bytes] = request.postpath # type: ignore
|
||||
assert postpath
|
||||
|
||||
# This allows users to append e.g. /test.png to the URL. Useful for
|
||||
# clients that parse the URL to see content type.
|
||||
server_name_bytes, media_id_bytes = postpath[:2]
|
||||
server_name = server_name_bytes.decode("utf-8")
|
||||
media_id = media_id_bytes.decode("utf8")
|
||||
|
||||
# Validate the server name, raising if invalid
|
||||
parse_and_validate_server_name(server_name)
|
||||
|
||||
file_name = None
|
||||
if len(postpath) > 2:
|
||||
try:
|
||||
file_name = urllib.parse.unquote(postpath[-1].decode("utf-8"))
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
return server_name, media_id, file_name
|
||||
except Exception:
|
||||
raise SynapseError(
|
||||
404, "Invalid media id token %r" % (request.postpath,), Codes.UNKNOWN
|
||||
)
|
||||
# A list of all content types that are "safe" to be rendered inline in a browser.
|
||||
INLINE_CONTENT_TYPES = [
|
||||
"text/css",
|
||||
"text/plain",
|
||||
"text/csv",
|
||||
"application/json",
|
||||
"application/ld+json",
|
||||
# We allow some media files deemed as safe, which comes from the matrix-react-sdk.
|
||||
# https://github.com/matrix-org/matrix-react-sdk/blob/a70fcfd0bcf7f8c85986da18001ea11597989a7c/src/utils/blobs.ts#L51
|
||||
# SVGs are *intentionally* omitted.
|
||||
"image/jpeg",
|
||||
"image/gif",
|
||||
"image/png",
|
||||
"image/apng",
|
||||
"image/webp",
|
||||
"image/avif",
|
||||
"video/mp4",
|
||||
"video/webm",
|
||||
"video/ogg",
|
||||
"video/quicktime",
|
||||
"audio/mp4",
|
||||
"audio/webm",
|
||||
"audio/aac",
|
||||
"audio/mpeg",
|
||||
"audio/ogg",
|
||||
"audio/wave",
|
||||
"audio/wav",
|
||||
"audio/x-wav",
|
||||
"audio/x-pn-wav",
|
||||
"audio/flac",
|
||||
"audio/x-flac",
|
||||
]
|
||||
|
||||
|
||||
def respond_404(request: SynapseRequest) -> None:
|
||||
assert request.path is not None
|
||||
respond_with_json(
|
||||
request,
|
||||
404,
|
||||
cs_error("Not found %r" % (request.postpath,), code=Codes.NOT_FOUND),
|
||||
cs_error("Not found '%s'" % (request.path.decode(),), code=Codes.NOT_FOUND),
|
||||
send_cors=True,
|
||||
)
|
||||
|
||||
@@ -153,8 +146,15 @@ def add_file_headers(
|
||||
|
||||
request.setHeader(b"Content-Type", content_type.encode("UTF-8"))
|
||||
|
||||
# Use a Content-Disposition of attachment to force download of media.
|
||||
disposition = "attachment"
|
||||
# A strict subset of content types is allowed to be inlined so that they may
|
||||
# be viewed directly in a browser. Other file types are forced to be downloads.
|
||||
#
|
||||
# Only the type & subtype are important, parameters can be ignored.
|
||||
if media_type.lower().split(";", 1)[0] in INLINE_CONTENT_TYPES:
|
||||
disposition = "inline"
|
||||
else:
|
||||
disposition = "attachment"
|
||||
|
||||
if upload_name:
|
||||
# RFC6266 section 4.1 [1] defines both `filename` and `filename*`.
|
||||
#
|
||||
@@ -334,7 +334,7 @@ class ThumbnailInfo:
|
||||
# Content type of thumbnail, e.g. image/png
|
||||
type: str
|
||||
# The size of the media file, in bytes.
|
||||
length: Optional[int] = None
|
||||
length: int
|
||||
|
||||
|
||||
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
||||
|
||||
@@ -48,6 +48,7 @@ from synapse.media.filepath import MediaFilePaths
|
||||
from synapse.media.media_storage import MediaStorage
|
||||
from synapse.media.storage_provider import StorageProviderWrapper
|
||||
from synapse.media.thumbnailer import Thumbnailer, ThumbnailError
|
||||
from synapse.media.url_previewer import UrlPreviewer
|
||||
from synapse.metrics.background_process_metrics import run_as_background_process
|
||||
from synapse.types import UserID
|
||||
from synapse.util.async_helpers import Linearizer
|
||||
@@ -114,7 +115,7 @@ class MediaRepository:
|
||||
)
|
||||
storage_providers.append(provider)
|
||||
|
||||
self.media_storage = MediaStorage(
|
||||
self.media_storage: MediaStorage = MediaStorage(
|
||||
self.hs, self.primary_base_path, self.filepaths, storage_providers
|
||||
)
|
||||
|
||||
@@ -142,6 +143,13 @@ class MediaRepository:
|
||||
MEDIA_RETENTION_CHECK_PERIOD_MS,
|
||||
)
|
||||
|
||||
if hs.config.media.url_preview_enabled:
|
||||
self.url_previewer: Optional[UrlPreviewer] = UrlPreviewer(
|
||||
hs, self, self.media_storage
|
||||
)
|
||||
else:
|
||||
self.url_previewer = None
|
||||
|
||||
def _start_update_recently_accessed(self) -> Deferred:
|
||||
return run_as_background_process(
|
||||
"update_recently_accessed_media", self._update_recently_accessed
|
||||
@@ -616,6 +624,7 @@ class MediaRepository:
|
||||
height=t_height,
|
||||
method=t_method,
|
||||
type=t_type,
|
||||
length=t_byte_source.tell(),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -686,6 +695,7 @@ class MediaRepository:
|
||||
height=t_height,
|
||||
method=t_method,
|
||||
type=t_type,
|
||||
length=t_byte_source.tell(),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -831,6 +841,7 @@ class MediaRepository:
|
||||
height=t_height,
|
||||
method=t_method,
|
||||
type=t_type,
|
||||
length=t_byte_source.tell(),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -678,7 +678,7 @@ class ModuleApi:
|
||||
"msisdn" for phone numbers, and an "address" key which value is the
|
||||
threepid's address.
|
||||
"""
|
||||
return await self._store.user_get_threepids(user_id)
|
||||
return [attr.asdict(t) for t in await self._store.user_get_threepids(user_id)]
|
||||
|
||||
def check_user_exists(self, user_id: str) -> "defer.Deferred[Optional[str]]":
|
||||
"""Check if user exists.
|
||||
|
||||
+8
-9
@@ -126,7 +126,7 @@ class _NotifierUserStream:
|
||||
|
||||
def notify(
|
||||
self,
|
||||
stream_key: str,
|
||||
stream_key: StreamKeyType,
|
||||
stream_id: Union[int, RoomStreamToken],
|
||||
time_now_ms: int,
|
||||
) -> None:
|
||||
@@ -454,7 +454,7 @@ class Notifier:
|
||||
|
||||
def on_new_event(
|
||||
self,
|
||||
stream_key: str,
|
||||
stream_key: StreamKeyType,
|
||||
new_token: Union[int, RoomStreamToken],
|
||||
users: Optional[Collection[Union[str, UserID]]] = None,
|
||||
rooms: Optional[StrCollection] = None,
|
||||
@@ -655,30 +655,29 @@ class Notifier:
|
||||
events: List[Union[JsonDict, EventBase]] = []
|
||||
end_token = from_token
|
||||
|
||||
for name, source in self.event_sources.sources.get_sources():
|
||||
keyname = "%s_key" % name
|
||||
before_id = getattr(before_token, keyname)
|
||||
after_id = getattr(after_token, keyname)
|
||||
for keyname, source in self.event_sources.sources.get_sources():
|
||||
before_id = before_token.get_field(keyname)
|
||||
after_id = after_token.get_field(keyname)
|
||||
if before_id == after_id:
|
||||
continue
|
||||
|
||||
new_events, new_key = await source.get_new_events(
|
||||
user=user,
|
||||
from_key=getattr(from_token, keyname),
|
||||
from_key=from_token.get_field(keyname),
|
||||
limit=limit,
|
||||
is_guest=is_peeking,
|
||||
room_ids=room_ids,
|
||||
explicit_room_id=explicit_room_id,
|
||||
)
|
||||
|
||||
if name == "room":
|
||||
if keyname == StreamKeyType.ROOM:
|
||||
new_events = await filter_events_for_client(
|
||||
self._storage_controllers,
|
||||
user.to_string(),
|
||||
new_events,
|
||||
is_peeking=is_peeking,
|
||||
)
|
||||
elif name == "presence":
|
||||
elif keyname == StreamKeyType.PRESENCE:
|
||||
now = self.clock.time_msec()
|
||||
new_events[:] = [
|
||||
{
|
||||
|
||||
@@ -101,7 +101,7 @@ if TYPE_CHECKING:
|
||||
class PusherConfig:
|
||||
"""Parameters necessary to configure a pusher."""
|
||||
|
||||
id: Optional[str]
|
||||
id: Optional[int]
|
||||
user_name: str
|
||||
|
||||
profile_tag: str
|
||||
@@ -182,7 +182,7 @@ class Pusher(metaclass=abc.ABCMeta):
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
def on_new_receipts(self, min_stream_id: int, max_stream_id: int) -> None:
|
||||
def on_new_receipts(self) -> None:
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
|
||||
@@ -99,7 +99,7 @@ class EmailPusher(Pusher):
|
||||
pass
|
||||
self.timed_call = None
|
||||
|
||||
def on_new_receipts(self, min_stream_id: int, max_stream_id: int) -> None:
|
||||
def on_new_receipts(self) -> None:
|
||||
# We could wake up and cancel the timer but there tend to be quite a
|
||||
# lot of read receipts so it's probably less work to just let the
|
||||
# timer fire
|
||||
|
||||
@@ -160,7 +160,7 @@ class HttpPusher(Pusher):
|
||||
if should_check_for_notifs:
|
||||
self._start_processing()
|
||||
|
||||
def on_new_receipts(self, min_stream_id: int, max_stream_id: int) -> None:
|
||||
def on_new_receipts(self) -> None:
|
||||
# Note that the min here shouldn't be relied upon to be accurate.
|
||||
|
||||
# We could check the receipts are actually m.read receipts here,
|
||||
|
||||
@@ -292,20 +292,12 @@ class PusherPool:
|
||||
except Exception:
|
||||
logger.exception("Exception in pusher on_new_notifications")
|
||||
|
||||
async def on_new_receipts(
|
||||
self, min_stream_id: int, max_stream_id: int, affected_room_ids: Iterable[str]
|
||||
) -> None:
|
||||
async def on_new_receipts(self, users_affected: StrCollection) -> None:
|
||||
if not self.pushers:
|
||||
# nothing to do here.
|
||||
return
|
||||
|
||||
try:
|
||||
# Need to subtract 1 from the minimum because the lower bound here
|
||||
# is not inclusive
|
||||
users_affected = await self.store.get_users_sent_receipts_between(
|
||||
min_stream_id - 1, max_stream_id
|
||||
)
|
||||
|
||||
for u in users_affected:
|
||||
# Don't push if the user account has expired
|
||||
expired = await self._account_validity_handler.is_user_expired(u)
|
||||
@@ -314,7 +306,7 @@ class PusherPool:
|
||||
|
||||
if u in self.pushers:
|
||||
for p in self.pushers[u].values():
|
||||
p.on_new_receipts(min_stream_id, max_stream_id)
|
||||
p.on_new_receipts()
|
||||
|
||||
except Exception:
|
||||
logger.exception("Exception in pusher on_new_receipts")
|
||||
|
||||
@@ -138,7 +138,11 @@ class ReplicationFederationSendEventsRestServlet(ReplicationEndpoint):
|
||||
|
||||
event_and_contexts.append((event, context))
|
||||
|
||||
logger.info("Got %d events from federation", len(event_and_contexts))
|
||||
logger.info(
|
||||
"Got batch of %i events to persist to room %s",
|
||||
len(event_and_contexts),
|
||||
room_id,
|
||||
)
|
||||
|
||||
max_stream_id = await self.federation_event_handler.persist_events_and_notify(
|
||||
room_id, event_and_contexts, backfilled
|
||||
|
||||
@@ -118,6 +118,7 @@ class ReplicationSendEventsRestServlet(ReplicationEndpoint):
|
||||
with Measure(self.clock, "repl_send_events_parse"):
|
||||
events_and_context = []
|
||||
events = payload["events"]
|
||||
rooms = set()
|
||||
|
||||
for event_payload in events:
|
||||
event_dict = event_payload["event"]
|
||||
@@ -144,11 +145,13 @@ class ReplicationSendEventsRestServlet(ReplicationEndpoint):
|
||||
UserID.from_string(u) for u in event_payload["extra_users"]
|
||||
]
|
||||
|
||||
logger.info(
|
||||
"Got batch of events to send, last ID of batch is: %s, sending into room: %s",
|
||||
event.event_id,
|
||||
event.room_id,
|
||||
)
|
||||
# all the rooms *should* be the same, but we'll log separately to be
|
||||
# sure.
|
||||
rooms.add(event.room_id)
|
||||
|
||||
logger.info(
|
||||
"Got batch of %i events to persist to rooms %s", len(events), rooms
|
||||
)
|
||||
|
||||
last_event = (
|
||||
await self.event_creation_handler.persist_and_notify_client_events(
|
||||
|
||||
@@ -129,9 +129,7 @@ class ReplicationDataHandler:
|
||||
self.notifier.on_new_event(
|
||||
StreamKeyType.RECEIPT, token, rooms=[row.room_id for row in rows]
|
||||
)
|
||||
await self._pusher_pool.on_new_receipts(
|
||||
token, token, {row.room_id for row in rows}
|
||||
)
|
||||
await self._pusher_pool.on_new_receipts({row.user_id for row in rows})
|
||||
elif stream_name == ToDeviceStream.NAME:
|
||||
entities = [row.entity for row in rows if row.entity.startswith("@")]
|
||||
if entities:
|
||||
@@ -339,7 +337,7 @@ class ReplicationDataHandler:
|
||||
try:
|
||||
await make_deferred_yieldable(deferred)
|
||||
except defer.TimeoutError:
|
||||
logger.error(
|
||||
logger.warning(
|
||||
"Timed out waiting for repl stream %r to reach %s (%s)"
|
||||
"; currently at: %s",
|
||||
stream_name,
|
||||
|
||||
@@ -18,7 +18,7 @@ allowed to be sent by which side.
|
||||
"""
|
||||
import abc
|
||||
import logging
|
||||
from typing import Optional, Tuple, Type, TypeVar
|
||||
from typing import List, Optional, Tuple, Type, TypeVar
|
||||
|
||||
from synapse.replication.tcp.streams._base import StreamRow
|
||||
from synapse.util import json_decoder, json_encoder
|
||||
@@ -74,6 +74,8 @@ SC = TypeVar("SC", bound="_SimpleCommand")
|
||||
class _SimpleCommand(Command):
|
||||
"""An implementation of Command whose argument is just a 'data' string."""
|
||||
|
||||
__slots__ = ["data"]
|
||||
|
||||
def __init__(self, data: str):
|
||||
self.data = data
|
||||
|
||||
@@ -122,6 +124,8 @@ class RdataCommand(Command):
|
||||
RDATA presence master 59 ["@baz:example.com", "online", ...]
|
||||
"""
|
||||
|
||||
__slots__ = ["stream_name", "instance_name", "token", "row"]
|
||||
|
||||
NAME = "RDATA"
|
||||
|
||||
def __init__(
|
||||
@@ -179,6 +183,8 @@ class PositionCommand(Command):
|
||||
of the stream.
|
||||
"""
|
||||
|
||||
__slots__ = ["stream_name", "instance_name", "prev_token", "new_token"]
|
||||
|
||||
NAME = "POSITION"
|
||||
|
||||
def __init__(
|
||||
@@ -235,6 +241,8 @@ class ReplicateCommand(Command):
|
||||
REPLICATE
|
||||
"""
|
||||
|
||||
__slots__: List[str] = []
|
||||
|
||||
NAME = "REPLICATE"
|
||||
|
||||
def __init__(self) -> None:
|
||||
@@ -264,6 +272,8 @@ class UserSyncCommand(Command):
|
||||
Where <state> is either "start" or "end"
|
||||
"""
|
||||
|
||||
__slots__ = ["instance_id", "user_id", "device_id", "is_syncing", "last_sync_ms"]
|
||||
|
||||
NAME = "USER_SYNC"
|
||||
|
||||
def __init__(
|
||||
@@ -316,6 +326,8 @@ class ClearUserSyncsCommand(Command):
|
||||
CLEAR_USER_SYNC <instance_id>
|
||||
"""
|
||||
|
||||
__slots__ = ["instance_id"]
|
||||
|
||||
NAME = "CLEAR_USER_SYNC"
|
||||
|
||||
def __init__(self, instance_id: str):
|
||||
@@ -343,6 +355,8 @@ class FederationAckCommand(Command):
|
||||
FEDERATION_ACK <instance_name> <token>
|
||||
"""
|
||||
|
||||
__slots__ = ["instance_name", "token"]
|
||||
|
||||
NAME = "FEDERATION_ACK"
|
||||
|
||||
def __init__(self, instance_name: str, token: int):
|
||||
@@ -368,6 +382,15 @@ class UserIpCommand(Command):
|
||||
USER_IP <user_id>, <access_token>, <ip>, <device_id>, <last_seen>, <user_agent>
|
||||
"""
|
||||
|
||||
__slots__ = [
|
||||
"user_id",
|
||||
"access_token",
|
||||
"ip",
|
||||
"user_agent",
|
||||
"device_id",
|
||||
"last_seen",
|
||||
]
|
||||
|
||||
NAME = "USER_IP"
|
||||
|
||||
def __init__(
|
||||
@@ -423,8 +446,6 @@ class RemoteServerUpCommand(_SimpleCommand):
|
||||
"""Sent when a worker has detected that a remote server is no longer
|
||||
"down" and retry timings should be reset.
|
||||
|
||||
If sent from a client the server will relay to all other workers.
|
||||
|
||||
Format::
|
||||
|
||||
REMOTE_SERVER_UP <server>
|
||||
@@ -441,6 +462,8 @@ class LockReleasedCommand(Command):
|
||||
LOCK_RELEASED ["<instance_name>", "<lock_name>", "<lock_key>"]
|
||||
"""
|
||||
|
||||
__slots__ = ["instance_name", "lock_name", "lock_key"]
|
||||
|
||||
NAME = "LOCK_RELEASED"
|
||||
|
||||
def __init__(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import heapq
|
||||
from collections import defaultdict
|
||||
from typing import TYPE_CHECKING, Iterable, Optional, Tuple, Type, TypeVar, cast
|
||||
|
||||
import attr
|
||||
@@ -51,8 +52,19 @@ data part are:
|
||||
* The state_key of the state which has changed
|
||||
* The event id of the new state
|
||||
|
||||
A "state-all" row is sent whenever the "current state" in a room changes, but there are
|
||||
too many state updates for a particular room in the same update. This replaces any
|
||||
"state" rows on a per-room basis. The fields in the data part are:
|
||||
|
||||
* The room id for the state changes
|
||||
|
||||
"""
|
||||
|
||||
# Any room with more than _MAX_STATE_UPDATES_PER_ROOM will send a EventsStreamAllStateRow
|
||||
# instead of individual EventsStreamEventRow. This is predominantly useful when
|
||||
# purging large rooms.
|
||||
_MAX_STATE_UPDATES_PER_ROOM = 150
|
||||
|
||||
|
||||
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
||||
class EventsStreamRow:
|
||||
@@ -111,9 +123,17 @@ class EventsStreamCurrentStateRow(BaseEventsStreamRow):
|
||||
event_id: Optional[str]
|
||||
|
||||
|
||||
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
||||
class EventsStreamAllStateRow(BaseEventsStreamRow):
|
||||
TypeId = "state-all"
|
||||
|
||||
room_id: str
|
||||
|
||||
|
||||
_EventRows: Tuple[Type[BaseEventsStreamRow], ...] = (
|
||||
EventsStreamEventRow,
|
||||
EventsStreamCurrentStateRow,
|
||||
EventsStreamAllStateRow,
|
||||
)
|
||||
|
||||
TypeToRow = {Row.TypeId: Row for Row in _EventRows}
|
||||
@@ -213,9 +233,28 @@ class EventsStream(Stream):
|
||||
if stream_id <= upper_limit
|
||||
)
|
||||
|
||||
# Separate out rooms that have many state updates, listeners should clear
|
||||
# all state for those rooms.
|
||||
state_updates_by_room = defaultdict(list)
|
||||
for stream_id, room_id, _type, _state_key, _event_id in state_rows:
|
||||
state_updates_by_room[room_id].append(stream_id)
|
||||
|
||||
state_all_rows = [
|
||||
(stream_ids[-1], room_id)
|
||||
for room_id, stream_ids in state_updates_by_room.items()
|
||||
if len(stream_ids) >= _MAX_STATE_UPDATES_PER_ROOM
|
||||
]
|
||||
state_all_updates: Iterable[Tuple[int, Tuple]] = (
|
||||
(max_stream_id, (EventsStreamAllStateRow.TypeId, (room_id,)))
|
||||
for (max_stream_id, room_id) in state_all_rows
|
||||
)
|
||||
|
||||
# Any remaining state updates are sent individually.
|
||||
state_all_rooms = {room_id for _, room_id in state_all_rows}
|
||||
state_updates: Iterable[Tuple[int, Tuple]] = (
|
||||
(stream_id, (EventsStreamCurrentStateRow.TypeId, rest))
|
||||
for (stream_id, *rest) in state_rows
|
||||
if rest[0] not in state_all_rooms
|
||||
)
|
||||
|
||||
ex_outliers_updates: Iterable[Tuple[int, Tuple]] = (
|
||||
@@ -224,7 +263,11 @@ class EventsStream(Stream):
|
||||
)
|
||||
|
||||
# we need to return a sorted list, so merge them together.
|
||||
updates = list(heapq.merge(event_updates, state_updates, ex_outliers_updates))
|
||||
updates = list(
|
||||
heapq.merge(
|
||||
event_updates, state_all_updates, state_updates, ex_outliers_updates
|
||||
)
|
||||
)
|
||||
return updates, upper_limit, limited
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
import platform
|
||||
from http import HTTPStatus
|
||||
from typing import TYPE_CHECKING, Optional, Tuple
|
||||
|
||||
@@ -107,10 +106,7 @@ class VersionServlet(RestServlet):
|
||||
PATTERNS = admin_patterns("/server_version$")
|
||||
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
self.res = {
|
||||
"server_version": SYNAPSE_VERSION,
|
||||
"python_version": platform.python_version(),
|
||||
}
|
||||
self.res = {"server_version": SYNAPSE_VERSION}
|
||||
|
||||
def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
return HTTPStatus.OK, self.res
|
||||
@@ -150,7 +146,7 @@ class PurgeHistoryRestServlet(RestServlet):
|
||||
# RoomStreamToken expects [int] not Optional[int]
|
||||
assert event.internal_metadata.stream_ordering is not None
|
||||
room_token = RoomStreamToken(
|
||||
event.depth, event.internal_metadata.stream_ordering
|
||||
topological=event.depth, stream=event.internal_metadata.stream_ordering
|
||||
)
|
||||
token = await room_token.to_string(self.store)
|
||||
|
||||
|
||||
@@ -198,7 +198,13 @@ class DestinationMembershipRestServlet(RestServlet):
|
||||
rooms, total = await self._store.get_destination_rooms_paginate(
|
||||
destination, start, limit, direction
|
||||
)
|
||||
response = {"rooms": rooms, "total": total}
|
||||
response = {
|
||||
"rooms": [
|
||||
{"room_id": room_id, "stream_ordering": stream_ordering}
|
||||
for room_id, stream_ordering in rooms
|
||||
],
|
||||
"total": total,
|
||||
}
|
||||
if (start + limit) < total:
|
||||
response["next_token"] = str(start + len(rooms))
|
||||
|
||||
|
||||
@@ -329,9 +329,8 @@ class UserRestServletV2(RestServlet):
|
||||
|
||||
if threepids is not None:
|
||||
# get changed threepids (added and removed)
|
||||
# convert List[Dict[str, Any]] into Set[Tuple[str, str]]
|
||||
cur_threepids = {
|
||||
(threepid["medium"], threepid["address"])
|
||||
(threepid.medium, threepid.address)
|
||||
for threepid in await self.store.user_get_threepids(user_id)
|
||||
}
|
||||
add_threepids = new_threepids - cur_threepids
|
||||
@@ -842,7 +841,18 @@ class SearchUsersRestServlet(RestServlet):
|
||||
logger.info("term: %s ", term)
|
||||
|
||||
ret = await self.store.search_users(term)
|
||||
return HTTPStatus.OK, ret
|
||||
results = [
|
||||
{
|
||||
"name": name,
|
||||
"password_hash": password_hash,
|
||||
"is_guest": bool(is_guest),
|
||||
"admin": bool(admin),
|
||||
"user_type": user_type,
|
||||
}
|
||||
for name, password_hash, is_guest, admin, user_type in ret
|
||||
]
|
||||
|
||||
return HTTPStatus.OK, results
|
||||
|
||||
|
||||
class UserAdminServlet(RestServlet):
|
||||
|
||||
@@ -24,6 +24,8 @@ if TYPE_CHECKING or HAS_PYDANTIC_V2:
|
||||
from pydantic.v1 import StrictBool, StrictStr, constr
|
||||
else:
|
||||
from pydantic import StrictBool, StrictStr, constr
|
||||
|
||||
import attr
|
||||
from typing_extensions import Literal
|
||||
|
||||
from twisted.web.server import Request
|
||||
@@ -595,7 +597,7 @@ class ThreepidRestServlet(RestServlet):
|
||||
|
||||
threepids = await self.datastore.user_get_threepids(requester.user.to_string())
|
||||
|
||||
return 200, {"threepids": threepids}
|
||||
return 200, {"threepids": [attr.asdict(t) for t in threepids]}
|
||||
|
||||
# NOTE(dmr): I have chosen not to use Pydantic to parse this request's body, because
|
||||
# the endpoint is deprecated. (If you really want to, you could do this by reusing
|
||||
|
||||
@@ -14,17 +14,19 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from synapse.http.server import DirectServeJsonResource, respond_with_json
|
||||
from synapse.http.server import respond_with_json
|
||||
from synapse.http.servlet import RestServlet
|
||||
from synapse.http.site import SynapseRequest
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.server import HomeServer
|
||||
|
||||
|
||||
class MediaConfigResource(DirectServeJsonResource):
|
||||
isLeaf = True
|
||||
class MediaConfigResource(RestServlet):
|
||||
PATTERNS = [re.compile("/_matrix/media/(r0|v3|v1)/config$")]
|
||||
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
super().__init__()
|
||||
@@ -33,9 +35,6 @@ class MediaConfigResource(DirectServeJsonResource):
|
||||
self.auth = hs.get_auth()
|
||||
self.limits_dict = {"m.upload.size": config.media.max_upload_size}
|
||||
|
||||
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
||||
async def on_GET(self, request: SynapseRequest) -> None:
|
||||
await self.auth.get_user_by_req(request)
|
||||
respond_with_json(request, 200, self.limits_dict, send_cors=True)
|
||||
|
||||
async def _async_render_OPTIONS(self, request: SynapseRequest) -> None:
|
||||
respond_with_json(request, 200, {}, send_cors=True)
|
||||
|
||||
@@ -13,16 +13,14 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
import re
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from synapse.http.server import (
|
||||
DirectServeJsonResource,
|
||||
set_corp_headers,
|
||||
set_cors_headers,
|
||||
)
|
||||
from synapse.http.servlet import parse_boolean
|
||||
from synapse.http.server import set_corp_headers, set_cors_headers
|
||||
from synapse.http.servlet import RestServlet, parse_boolean
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.media._base import parse_media_id, respond_404
|
||||
from synapse.media._base import respond_404
|
||||
from synapse.util.stringutils import parse_and_validate_server_name
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.media.media_repository import MediaRepository
|
||||
@@ -31,15 +29,28 @@ if TYPE_CHECKING:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DownloadResource(DirectServeJsonResource):
|
||||
isLeaf = True
|
||||
class DownloadResource(RestServlet):
|
||||
PATTERNS = [
|
||||
re.compile(
|
||||
"/_matrix/media/(r0|v3|v1)/download/(?P<server_name>[^/]*)/(?P<media_id>[^/]*)(/(?P<file_name>[^/]*))?$"
|
||||
)
|
||||
]
|
||||
|
||||
def __init__(self, hs: "HomeServer", media_repo: "MediaRepository"):
|
||||
super().__init__()
|
||||
self.media_repo = media_repo
|
||||
self._is_mine_server_name = hs.is_mine_server_name
|
||||
|
||||
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
||||
async def on_GET(
|
||||
self,
|
||||
request: SynapseRequest,
|
||||
server_name: str,
|
||||
media_id: str,
|
||||
file_name: Optional[str] = None,
|
||||
) -> None:
|
||||
# Validate the server name, raising if invalid
|
||||
parse_and_validate_server_name(server_name)
|
||||
|
||||
set_cors_headers(request)
|
||||
set_corp_headers(request)
|
||||
request.setHeader(
|
||||
@@ -58,9 +69,8 @@ class DownloadResource(DirectServeJsonResource):
|
||||
b"Referrer-Policy",
|
||||
b"no-referrer",
|
||||
)
|
||||
server_name, media_id, name = parse_media_id(request)
|
||||
if self._is_mine_server_name(server_name):
|
||||
await self.media_repo.get_local_media(request, media_id, name)
|
||||
await self.media_repo.get_local_media(request, media_id, file_name)
|
||||
else:
|
||||
allow_remote = parse_boolean(request, "allow_remote", default=True)
|
||||
if not allow_remote:
|
||||
@@ -72,4 +82,6 @@ class DownloadResource(DirectServeJsonResource):
|
||||
respond_404(request)
|
||||
return
|
||||
|
||||
await self.media_repo.get_remote_media(request, server_name, media_id, name)
|
||||
await self.media_repo.get_remote_media(
|
||||
request, server_name, media_id, file_name
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from synapse.config._base import ConfigError
|
||||
from synapse.http.server import UnrecognizedRequestResource
|
||||
from synapse.http.server import HttpServer, JsonResource
|
||||
|
||||
from .config_resource import MediaConfigResource
|
||||
from .download_resource import DownloadResource
|
||||
@@ -27,7 +27,7 @@ if TYPE_CHECKING:
|
||||
from synapse.server import HomeServer
|
||||
|
||||
|
||||
class MediaRepositoryResource(UnrecognizedRequestResource):
|
||||
class MediaRepositoryResource(JsonResource):
|
||||
"""File uploading and downloading.
|
||||
|
||||
Uploads are POSTed to a resource which returns a token which is used to GET
|
||||
@@ -70,6 +70,11 @@ class MediaRepositoryResource(UnrecognizedRequestResource):
|
||||
width and height are close to the requested size and the aspect matches
|
||||
the requested size. The client should scale the image if it needs to fit
|
||||
within a given rectangle.
|
||||
|
||||
This gets mounted at various points under /_matrix/media, including:
|
||||
* /_matrix/media/r0
|
||||
* /_matrix/media/v1
|
||||
* /_matrix/media/v3
|
||||
"""
|
||||
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
@@ -77,17 +82,23 @@ class MediaRepositoryResource(UnrecognizedRequestResource):
|
||||
if not hs.config.media.can_load_media_repo:
|
||||
raise ConfigError("Synapse is not configured to use a media repo.")
|
||||
|
||||
super().__init__()
|
||||
JsonResource.__init__(self, hs, canonical_json=False)
|
||||
self.register_servlets(self, hs)
|
||||
|
||||
@staticmethod
|
||||
def register_servlets(http_server: HttpServer, hs: "HomeServer") -> None:
|
||||
media_repo = hs.get_media_repository()
|
||||
|
||||
self.putChild(b"upload", UploadResource(hs, media_repo))
|
||||
self.putChild(b"download", DownloadResource(hs, media_repo))
|
||||
self.putChild(
|
||||
b"thumbnail", ThumbnailResource(hs, media_repo, media_repo.media_storage)
|
||||
# Note that many of these should not exist as v1 endpoints, but empirically
|
||||
# a lot of traffic still goes to them.
|
||||
|
||||
UploadResource(hs, media_repo).register(http_server)
|
||||
DownloadResource(hs, media_repo).register(http_server)
|
||||
ThumbnailResource(hs, media_repo, media_repo.media_storage).register(
|
||||
http_server
|
||||
)
|
||||
if hs.config.media.url_preview_enabled:
|
||||
self.putChild(
|
||||
b"preview_url",
|
||||
PreviewUrlResource(hs, media_repo, media_repo.media_storage),
|
||||
PreviewUrlResource(hs, media_repo, media_repo.media_storage).register(
|
||||
http_server
|
||||
)
|
||||
self.putChild(b"config", MediaConfigResource(hs))
|
||||
MediaConfigResource(hs).register(http_server)
|
||||
|
||||
@@ -13,24 +13,20 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from synapse.http.server import (
|
||||
DirectServeJsonResource,
|
||||
respond_with_json,
|
||||
respond_with_json_bytes,
|
||||
)
|
||||
from synapse.http.servlet import parse_integer, parse_string
|
||||
from synapse.http.server import respond_with_json_bytes
|
||||
from synapse.http.servlet import RestServlet, parse_integer, parse_string
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.media.media_storage import MediaStorage
|
||||
from synapse.media.url_previewer import UrlPreviewer
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.media.media_repository import MediaRepository
|
||||
from synapse.server import HomeServer
|
||||
|
||||
|
||||
class PreviewUrlResource(DirectServeJsonResource):
|
||||
class PreviewUrlResource(RestServlet):
|
||||
"""
|
||||
The `GET /_matrix/media/r0/preview_url` endpoint provides a generic preview API
|
||||
for URLs which outputs Open Graph (https://ogp.me/) responses (with some Matrix
|
||||
@@ -48,7 +44,7 @@ class PreviewUrlResource(DirectServeJsonResource):
|
||||
* Matrix cannot be used to distribute the metadata between homeservers.
|
||||
"""
|
||||
|
||||
isLeaf = True
|
||||
PATTERNS = [re.compile("/_matrix/media/(r0|v3|v1)/preview_url$")]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -62,14 +58,10 @@ class PreviewUrlResource(DirectServeJsonResource):
|
||||
self.clock = hs.get_clock()
|
||||
self.media_repo = media_repo
|
||||
self.media_storage = media_storage
|
||||
assert self.media_repo.url_previewer is not None
|
||||
self.url_previewer = self.media_repo.url_previewer
|
||||
|
||||
self._url_previewer = UrlPreviewer(hs, media_repo, media_storage)
|
||||
|
||||
async def _async_render_OPTIONS(self, request: SynapseRequest) -> None:
|
||||
request.setHeader(b"Allow", b"OPTIONS, GET")
|
||||
respond_with_json(request, 200, {}, send_cors=True)
|
||||
|
||||
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
||||
async def on_GET(self, request: SynapseRequest) -> None:
|
||||
# XXX: if get_user_by_req fails, what should we do in an async render?
|
||||
requester = await self.auth.get_user_by_req(request)
|
||||
url = parse_string(request, "url", required=True)
|
||||
@@ -77,5 +69,5 @@ class PreviewUrlResource(DirectServeJsonResource):
|
||||
if ts is None:
|
||||
ts = self.clock.time_msec()
|
||||
|
||||
og = await self._url_previewer.preview(url, requester.user, ts)
|
||||
og = await self.url_previewer.preview(url, requester.user, ts)
|
||||
respond_with_json_bytes(request, 200, og, send_cors=True)
|
||||
|
||||
@@ -13,29 +13,24 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||
import re
|
||||
from typing import TYPE_CHECKING, List, Optional, Tuple
|
||||
|
||||
from synapse.api.errors import Codes, SynapseError, cs_error
|
||||
from synapse.config.repository import THUMBNAIL_SUPPORTED_MEDIA_FORMAT_MAP
|
||||
from synapse.http.server import (
|
||||
DirectServeJsonResource,
|
||||
respond_with_json,
|
||||
set_corp_headers,
|
||||
set_cors_headers,
|
||||
)
|
||||
from synapse.http.servlet import parse_integer, parse_string
|
||||
from synapse.http.server import respond_with_json, set_corp_headers, set_cors_headers
|
||||
from synapse.http.servlet import RestServlet, parse_integer, parse_string
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.media._base import (
|
||||
FileInfo,
|
||||
ThumbnailInfo,
|
||||
parse_media_id,
|
||||
respond_404,
|
||||
respond_with_file,
|
||||
respond_with_responder,
|
||||
)
|
||||
from synapse.media.media_storage import MediaStorage
|
||||
from synapse.util.stringutils import parse_and_validate_server_name
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.media.media_repository import MediaRepository
|
||||
@@ -44,8 +39,12 @@ if TYPE_CHECKING:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThumbnailResource(DirectServeJsonResource):
|
||||
isLeaf = True
|
||||
class ThumbnailResource(RestServlet):
|
||||
PATTERNS = [
|
||||
re.compile(
|
||||
"/_matrix/media/(r0|v3|v1)/thumbnail/(?P<server_name>[^/]*)/(?P<media_id>[^/]*)$"
|
||||
)
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -60,12 +59,17 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
self.media_storage = media_storage
|
||||
self.dynamic_thumbnails = hs.config.media.dynamic_thumbnails
|
||||
self._is_mine_server_name = hs.is_mine_server_name
|
||||
self._server_name = hs.hostname
|
||||
self.prevent_media_downloads_from = hs.config.media.prevent_media_downloads_from
|
||||
|
||||
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
||||
async def on_GET(
|
||||
self, request: SynapseRequest, server_name: str, media_id: str
|
||||
) -> None:
|
||||
# Validate the server name, raising if invalid
|
||||
parse_and_validate_server_name(server_name)
|
||||
|
||||
set_cors_headers(request)
|
||||
set_corp_headers(request)
|
||||
server_name, media_id, _ = parse_media_id(request)
|
||||
width = parse_integer(request, "width", required=True)
|
||||
height = parse_integer(request, "height", required=True)
|
||||
method = parse_string(request, "method", "scale")
|
||||
@@ -155,30 +159,24 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
|
||||
thumbnail_infos = await self.store.get_local_media_thumbnails(media_id)
|
||||
for info in thumbnail_infos:
|
||||
t_w = info["thumbnail_width"] == desired_width
|
||||
t_h = info["thumbnail_height"] == desired_height
|
||||
t_method = info["thumbnail_method"] == desired_method
|
||||
t_type = info["thumbnail_type"] == desired_type
|
||||
t_w = info.width == desired_width
|
||||
t_h = info.height == desired_height
|
||||
t_method = info.method == desired_method
|
||||
t_type = info.type == desired_type
|
||||
|
||||
if t_w and t_h and t_method and t_type:
|
||||
file_info = FileInfo(
|
||||
server_name=None,
|
||||
file_id=media_id,
|
||||
url_cache=media_info["url_cache"],
|
||||
thumbnail=ThumbnailInfo(
|
||||
width=info["thumbnail_width"],
|
||||
height=info["thumbnail_height"],
|
||||
type=info["thumbnail_type"],
|
||||
method=info["thumbnail_method"],
|
||||
),
|
||||
thumbnail=info,
|
||||
)
|
||||
|
||||
t_type = file_info.thumbnail_type
|
||||
t_length = info["thumbnail_length"]
|
||||
|
||||
responder = await self.media_storage.fetch_media(file_info)
|
||||
if responder:
|
||||
await respond_with_responder(request, responder, t_type, t_length)
|
||||
await respond_with_responder(
|
||||
request, responder, info.type, info.length
|
||||
)
|
||||
return
|
||||
|
||||
logger.debug("We don't have a thumbnail of that size. Generating")
|
||||
@@ -218,29 +216,23 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
file_id = media_info["filesystem_id"]
|
||||
|
||||
for info in thumbnail_infos:
|
||||
t_w = info["thumbnail_width"] == desired_width
|
||||
t_h = info["thumbnail_height"] == desired_height
|
||||
t_method = info["thumbnail_method"] == desired_method
|
||||
t_type = info["thumbnail_type"] == desired_type
|
||||
t_w = info.width == desired_width
|
||||
t_h = info.height == desired_height
|
||||
t_method = info.method == desired_method
|
||||
t_type = info.type == desired_type
|
||||
|
||||
if t_w and t_h and t_method and t_type:
|
||||
file_info = FileInfo(
|
||||
server_name=server_name,
|
||||
file_id=media_info["filesystem_id"],
|
||||
thumbnail=ThumbnailInfo(
|
||||
width=info["thumbnail_width"],
|
||||
height=info["thumbnail_height"],
|
||||
type=info["thumbnail_type"],
|
||||
method=info["thumbnail_method"],
|
||||
),
|
||||
thumbnail=info,
|
||||
)
|
||||
|
||||
t_type = file_info.thumbnail_type
|
||||
t_length = info["thumbnail_length"]
|
||||
|
||||
responder = await self.media_storage.fetch_media(file_info)
|
||||
if responder:
|
||||
await respond_with_responder(request, responder, t_type, t_length)
|
||||
await respond_with_responder(
|
||||
request, responder, info.type, info.length
|
||||
)
|
||||
return
|
||||
|
||||
logger.debug("We don't have a thumbnail of that size. Generating")
|
||||
@@ -300,7 +292,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
desired_height: int,
|
||||
desired_method: str,
|
||||
desired_type: str,
|
||||
thumbnail_infos: List[Dict[str, Any]],
|
||||
thumbnail_infos: List[ThumbnailInfo],
|
||||
media_id: str,
|
||||
file_id: str,
|
||||
url_cache: bool,
|
||||
@@ -315,7 +307,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
desired_height: The desired height, the returned thumbnail may be larger than this.
|
||||
desired_method: The desired method used to generate the thumbnail.
|
||||
desired_type: The desired content-type of the thumbnail.
|
||||
thumbnail_infos: A list of dictionaries of candidate thumbnails.
|
||||
thumbnail_infos: A list of thumbnail info of candidate thumbnails.
|
||||
file_id: The ID of the media that a thumbnail is being requested for.
|
||||
url_cache: True if this is from a URL cache.
|
||||
server_name: The server name, if this is a remote thumbnail.
|
||||
@@ -418,13 +410,14 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
# `dynamic_thumbnails` is disabled.
|
||||
logger.info("Failed to find any generated thumbnails")
|
||||
|
||||
assert request.path is not None
|
||||
respond_with_json(
|
||||
request,
|
||||
400,
|
||||
cs_error(
|
||||
"Cannot find any thumbnails for the requested media (%r). This might mean the media is not a supported_media_format=(%s) or that thumbnailing failed for some other reason. (Dynamic thumbnails are disabled on this server.)"
|
||||
"Cannot find any thumbnails for the requested media ('%s'). This might mean the media is not a supported_media_format=(%s) or that thumbnailing failed for some other reason. (Dynamic thumbnails are disabled on this server.)"
|
||||
% (
|
||||
request.postpath,
|
||||
request.path.decode(),
|
||||
", ".join(THUMBNAIL_SUPPORTED_MEDIA_FORMAT_MAP.keys()),
|
||||
),
|
||||
code=Codes.UNKNOWN,
|
||||
@@ -438,7 +431,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
desired_height: int,
|
||||
desired_method: str,
|
||||
desired_type: str,
|
||||
thumbnail_infos: List[Dict[str, Any]],
|
||||
thumbnail_infos: List[ThumbnailInfo],
|
||||
file_id: str,
|
||||
url_cache: bool,
|
||||
server_name: Optional[str],
|
||||
@@ -451,7 +444,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
desired_height: The desired height, the returned thumbnail may be larger than this.
|
||||
desired_method: The desired method used to generate the thumbnail.
|
||||
desired_type: The desired content-type of the thumbnail.
|
||||
thumbnail_infos: A list of dictionaries of candidate thumbnails.
|
||||
thumbnail_infos: A list of thumbnail infos of candidate thumbnails.
|
||||
file_id: The ID of the media that a thumbnail is being requested for.
|
||||
url_cache: True if this is from a URL cache.
|
||||
server_name: The server name, if this is a remote thumbnail.
|
||||
@@ -469,21 +462,25 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
|
||||
if desired_method == "crop":
|
||||
# Thumbnails that match equal or larger sizes of desired width/height.
|
||||
crop_info_list: List[Tuple[int, int, int, bool, int, Dict[str, Any]]] = []
|
||||
crop_info_list: List[
|
||||
Tuple[int, int, int, bool, Optional[int], ThumbnailInfo]
|
||||
] = []
|
||||
# Other thumbnails.
|
||||
crop_info_list2: List[Tuple[int, int, int, bool, int, Dict[str, Any]]] = []
|
||||
crop_info_list2: List[
|
||||
Tuple[int, int, int, bool, Optional[int], ThumbnailInfo]
|
||||
] = []
|
||||
for info in thumbnail_infos:
|
||||
# Skip thumbnails generated with different methods.
|
||||
if info["thumbnail_method"] != "crop":
|
||||
if info.method != "crop":
|
||||
continue
|
||||
|
||||
t_w = info["thumbnail_width"]
|
||||
t_h = info["thumbnail_height"]
|
||||
t_w = info.width
|
||||
t_h = info.height
|
||||
aspect_quality = abs(d_w * t_h - d_h * t_w)
|
||||
min_quality = 0 if d_w <= t_w and d_h <= t_h else 1
|
||||
size_quality = abs((d_w - t_w) * (d_h - t_h))
|
||||
type_quality = desired_type != info["thumbnail_type"]
|
||||
length_quality = info["thumbnail_length"]
|
||||
type_quality = desired_type != info.type
|
||||
length_quality = info.length
|
||||
if t_w >= d_w or t_h >= d_h:
|
||||
crop_info_list.append(
|
||||
(
|
||||
@@ -508,7 +505,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
)
|
||||
# Pick the most appropriate thumbnail. Some values of `desired_width` and
|
||||
# `desired_height` may result in a tie, in which case we avoid comparing on
|
||||
# the thumbnail info dictionary and pick the thumbnail that appears earlier
|
||||
# the thumbnail info and pick the thumbnail that appears earlier
|
||||
# in the list of candidates.
|
||||
if crop_info_list:
|
||||
thumbnail_info = min(crop_info_list, key=lambda t: t[:-1])[-1]
|
||||
@@ -516,20 +513,20 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
thumbnail_info = min(crop_info_list2, key=lambda t: t[:-1])[-1]
|
||||
elif desired_method == "scale":
|
||||
# Thumbnails that match equal or larger sizes of desired width/height.
|
||||
info_list: List[Tuple[int, bool, int, Dict[str, Any]]] = []
|
||||
info_list: List[Tuple[int, bool, int, ThumbnailInfo]] = []
|
||||
# Other thumbnails.
|
||||
info_list2: List[Tuple[int, bool, int, Dict[str, Any]]] = []
|
||||
info_list2: List[Tuple[int, bool, int, ThumbnailInfo]] = []
|
||||
|
||||
for info in thumbnail_infos:
|
||||
# Skip thumbnails generated with different methods.
|
||||
if info["thumbnail_method"] != "scale":
|
||||
if info.method != "scale":
|
||||
continue
|
||||
|
||||
t_w = info["thumbnail_width"]
|
||||
t_h = info["thumbnail_height"]
|
||||
t_w = info.width
|
||||
t_h = info.height
|
||||
size_quality = abs((d_w - t_w) * (d_h - t_h))
|
||||
type_quality = desired_type != info["thumbnail_type"]
|
||||
length_quality = info["thumbnail_length"]
|
||||
type_quality = desired_type != info.type
|
||||
length_quality = info.length
|
||||
if t_w >= d_w or t_h >= d_h:
|
||||
info_list.append((size_quality, type_quality, length_quality, info))
|
||||
else:
|
||||
@@ -538,7 +535,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
)
|
||||
# Pick the most appropriate thumbnail. Some values of `desired_width` and
|
||||
# `desired_height` may result in a tie, in which case we avoid comparing on
|
||||
# the thumbnail info dictionary and pick the thumbnail that appears earlier
|
||||
# the thumbnail info and pick the thumbnail that appears earlier
|
||||
# in the list of candidates.
|
||||
if info_list:
|
||||
thumbnail_info = min(info_list, key=lambda t: t[:-1])[-1]
|
||||
@@ -550,13 +547,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||
file_id=file_id,
|
||||
url_cache=url_cache,
|
||||
server_name=server_name,
|
||||
thumbnail=ThumbnailInfo(
|
||||
width=thumbnail_info["thumbnail_width"],
|
||||
height=thumbnail_info["thumbnail_height"],
|
||||
type=thumbnail_info["thumbnail_type"],
|
||||
method=thumbnail_info["thumbnail_method"],
|
||||
length=thumbnail_info["thumbnail_length"],
|
||||
),
|
||||
thumbnail=thumbnail_info,
|
||||
)
|
||||
|
||||
# No matching thumbnail was found.
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
import re
|
||||
from typing import IO, TYPE_CHECKING, Dict, List, Optional
|
||||
|
||||
from synapse.api.errors import Codes, SynapseError
|
||||
from synapse.http.server import DirectServeJsonResource, respond_with_json
|
||||
from synapse.http.servlet import parse_bytes_from_args
|
||||
from synapse.http.server import respond_with_json
|
||||
from synapse.http.servlet import RestServlet, parse_bytes_from_args
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.media.media_storage import SpamMediaException
|
||||
|
||||
@@ -29,8 +30,8 @@ if TYPE_CHECKING:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UploadResource(DirectServeJsonResource):
|
||||
isLeaf = True
|
||||
class UploadResource(RestServlet):
|
||||
PATTERNS = [re.compile("/_matrix/media/(r0|v3|v1)/upload")]
|
||||
|
||||
def __init__(self, hs: "HomeServer", media_repo: "MediaRepository"):
|
||||
super().__init__()
|
||||
@@ -43,10 +44,7 @@ class UploadResource(DirectServeJsonResource):
|
||||
self.max_upload_size = hs.config.media.max_upload_size
|
||||
self.clock = hs.get_clock()
|
||||
|
||||
async def _async_render_OPTIONS(self, request: SynapseRequest) -> None:
|
||||
respond_with_json(request, 200, {}, send_cors=True)
|
||||
|
||||
async def _async_render_POST(self, request: SynapseRequest) -> None:
|
||||
async def on_POST(self, request: SynapseRequest) -> None:
|
||||
requester = await self.auth.get_user_by_req(request)
|
||||
raw_content_length = request.getHeader("Content-Length")
|
||||
if raw_content_length is None:
|
||||
|
||||
+2
-3
@@ -23,7 +23,6 @@ from typing import (
|
||||
Generator,
|
||||
Iterable,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Sequence,
|
||||
Set,
|
||||
@@ -269,7 +268,7 @@ async def _get_power_level_for_sender(
|
||||
|
||||
async def _get_auth_chain_difference(
|
||||
room_id: str,
|
||||
state_sets: Sequence[Mapping[Any, str]],
|
||||
state_sets: Sequence[StateMap[str]],
|
||||
unpersisted_events: Dict[str, EventBase],
|
||||
state_res_store: StateResolutionStore,
|
||||
) -> Set[str]:
|
||||
@@ -405,7 +404,7 @@ def _seperate(
|
||||
|
||||
# mypy doesn't understand that discarding None above means that conflicted
|
||||
# state is StateMap[Set[str]], not StateMap[Set[Optional[Str]]].
|
||||
return unconflicted_state, conflicted_state # type: ignore
|
||||
return unconflicted_state, conflicted_state # type: ignore[return-value]
|
||||
|
||||
|
||||
def _is_power_event(event: EventBase) -> bool:
|
||||
|
||||
@@ -16,7 +16,6 @@ from itertools import chain
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
AbstractSet,
|
||||
Any,
|
||||
Callable,
|
||||
Collection,
|
||||
Dict,
|
||||
@@ -32,6 +31,7 @@ from typing import (
|
||||
from synapse.api.constants import EventTypes, Membership
|
||||
from synapse.events import EventBase
|
||||
from synapse.logging.opentracing import tag_args, trace
|
||||
from synapse.storage.databases.main.state_deltas import StateDelta
|
||||
from synapse.storage.roommember import ProfileInfo
|
||||
from synapse.storage.util.partial_state_events_tracker import (
|
||||
PartialCurrentStateTracker,
|
||||
@@ -531,19 +531,9 @@ class StateStorageController:
|
||||
@tag_args
|
||||
async def get_current_state_deltas(
|
||||
self, prev_stream_id: int, max_stream_id: int
|
||||
) -> Tuple[int, List[Dict[str, Any]]]:
|
||||
) -> Tuple[int, List[StateDelta]]:
|
||||
"""Fetch a list of room state changes since the given stream id
|
||||
|
||||
Each entry in the result contains the following fields:
|
||||
- stream_id (int)
|
||||
- room_id (str)
|
||||
- type (str): event type
|
||||
- state_key (str):
|
||||
- event_id (str|None): new event_id for this state key. None if the
|
||||
state has been deleted.
|
||||
- prev_event_id (str|None): previous event_id for this state key. None
|
||||
if it's new state.
|
||||
|
||||
Args:
|
||||
prev_stream_id: point to get changes since (exclusive)
|
||||
max_stream_id: the point that we know has been correctly persisted
|
||||
|
||||
+15
-71
@@ -1874,9 +1874,9 @@ class DatabasePool:
|
||||
keyvalues: Optional[Dict[str, Any]] = None,
|
||||
desc: str = "simple_select_many_batch",
|
||||
batch_size: int = 100,
|
||||
) -> List[Dict[str, Any]]:
|
||||
) -> List[Tuple[Any, ...]]:
|
||||
"""Executes a SELECT query on the named table, which may return zero or
|
||||
more rows, returning the result as a list of dicts.
|
||||
more rows.
|
||||
|
||||
Filters rows by whether the value of `column` is in `iterable`.
|
||||
|
||||
@@ -1888,10 +1888,13 @@ class DatabasePool:
|
||||
keyvalues: dict of column names and values to select the rows with
|
||||
desc: description of the transaction, for logging and metrics
|
||||
batch_size: the number of rows for each select query
|
||||
|
||||
Returns:
|
||||
The results as a list of tuples.
|
||||
"""
|
||||
keyvalues = keyvalues or {}
|
||||
|
||||
results: List[Dict[str, Any]] = []
|
||||
results: List[Tuple[Any, ...]] = []
|
||||
|
||||
for chunk in batch_iter(iterable, batch_size):
|
||||
rows = await self.runInteraction(
|
||||
@@ -1918,9 +1921,9 @@ class DatabasePool:
|
||||
iterable: Collection[Any],
|
||||
keyvalues: Dict[str, Any],
|
||||
retcols: Iterable[str],
|
||||
) -> List[Dict[str, Any]]:
|
||||
) -> List[Tuple[Any, ...]]:
|
||||
"""Executes a SELECT query on the named table, which may return zero or
|
||||
more rows, returning the result as a list of dicts.
|
||||
more rows.
|
||||
|
||||
Filters rows by whether the value of `column` is in `iterable`.
|
||||
|
||||
@@ -1931,6 +1934,9 @@ class DatabasePool:
|
||||
iterable: list
|
||||
keyvalues: dict of column names and values to select the rows with
|
||||
retcols: list of strings giving the names of the columns to return
|
||||
|
||||
Returns:
|
||||
The results as a list of tuples.
|
||||
"""
|
||||
if not iterable:
|
||||
return []
|
||||
@@ -1949,7 +1955,7 @@ class DatabasePool:
|
||||
)
|
||||
|
||||
txn.execute(sql, values)
|
||||
return cls.cursor_to_dict(txn)
|
||||
return txn.fetchall()
|
||||
|
||||
async def simple_update(
|
||||
self,
|
||||
@@ -2418,7 +2424,7 @@ class DatabasePool:
|
||||
keyvalues: Optional[Dict[str, Any]] = None,
|
||||
exclude_keyvalues: Optional[Dict[str, Any]] = None,
|
||||
order_direction: str = "ASC",
|
||||
) -> List[Dict[str, Any]]:
|
||||
) -> List[Tuple[Any, ...]]:
|
||||
"""
|
||||
Executes a SELECT query on the named table with start and limit,
|
||||
of row numbers, which may return zero or number of rows from start to limit,
|
||||
@@ -2447,7 +2453,7 @@ class DatabasePool:
|
||||
order_direction: Whether the results should be ordered "ASC" or "DESC".
|
||||
|
||||
Returns:
|
||||
The result as a list of dictionaries.
|
||||
The result as a list of tuples.
|
||||
"""
|
||||
if order_direction not in ["ASC", "DESC"]:
|
||||
raise ValueError("order_direction must be one of 'ASC' or 'DESC'.")
|
||||
@@ -2474,69 +2480,7 @@ class DatabasePool:
|
||||
)
|
||||
txn.execute(sql, arg_list + [limit, start])
|
||||
|
||||
return cls.cursor_to_dict(txn)
|
||||
|
||||
async def simple_search_list(
|
||||
self,
|
||||
table: str,
|
||||
term: Optional[str],
|
||||
col: str,
|
||||
retcols: Collection[str],
|
||||
desc: str = "simple_search_list",
|
||||
) -> Optional[List[Dict[str, Any]]]:
|
||||
"""Executes a SELECT query on the named table, which may return zero or
|
||||
more rows, returning the result as a list of dicts.
|
||||
|
||||
Args:
|
||||
table: the table name
|
||||
term: term for searching the table matched to a column.
|
||||
col: column to query term should be matched to
|
||||
retcols: the names of the columns to return
|
||||
|
||||
Returns:
|
||||
A list of dictionaries or None.
|
||||
"""
|
||||
|
||||
return await self.runInteraction(
|
||||
desc,
|
||||
self.simple_search_list_txn,
|
||||
table,
|
||||
term,
|
||||
col,
|
||||
retcols,
|
||||
db_autocommit=True,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def simple_search_list_txn(
|
||||
cls,
|
||||
txn: LoggingTransaction,
|
||||
table: str,
|
||||
term: Optional[str],
|
||||
col: str,
|
||||
retcols: Iterable[str],
|
||||
) -> Optional[List[Dict[str, Any]]]:
|
||||
"""Executes a SELECT query on the named table, which may return zero or
|
||||
more rows, returning the result as a list of dicts.
|
||||
|
||||
Args:
|
||||
txn: Transaction object
|
||||
table: the table name
|
||||
term: term for searching the table matched to a column.
|
||||
col: column to query term should be matched to
|
||||
retcols: the names of the columns to return
|
||||
|
||||
Returns:
|
||||
None if no term is given, otherwise a list of dictionaries.
|
||||
"""
|
||||
if term:
|
||||
sql = "SELECT %s FROM %s WHERE %s LIKE ?" % (", ".join(retcols), table, col)
|
||||
termvalues = ["%%" + term + "%%"]
|
||||
txn.execute(sql, termvalues)
|
||||
else:
|
||||
return None
|
||||
|
||||
return cls.cursor_to_dict(txn)
|
||||
return txn.fetchall()
|
||||
|
||||
|
||||
def make_in_list_sql_clause(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user