From 257ee205acfb35ae81cadcd6148abf6263b4e990 Mon Sep 17 00:00:00 2001 From: "faming.zhou" Date: Fri, 29 Dec 2023 11:32:05 +0800 Subject: [PATCH 01/41] =?UTF-8?q?fix:=20UNION=20=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=20character=20varying=20=E5=92=8C=20uuid=20=E4=B8=8D?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/audits/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/audits/api.py b/apps/audits/api.py index c2cd84756..7dc1a5725 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -5,6 +5,7 @@ from importlib import import_module from django.conf import settings from django.db.models import F, Value, CharField, Q +from django.db.models.functions import Cast from django.http import HttpResponse, FileResponse from django.utils.encoding import escape_uri_path from rest_framework import generics @@ -163,7 +164,7 @@ class ResourceActivityAPIView(generics.ListAPIView): q |= Q(user=str(user)) queryset = OperateLog.objects.filter(q, org_q).annotate( r_type=Value(ActivityChoices.operate_log, CharField()), - r_detail_id=F('id'), r_detail=Value(None, CharField()), + r_detail_id=Cast(F('id'), CharField()), r_detail=Value(None, CharField()), r_user=F('user'), r_action=F('action'), ).values(*fields)[:limit] return queryset From 38642024be0ecc95bb56792591c18df625d81a67 Mon Sep 17 00:00:00 2001 From: Bryan Date: Fri, 29 Dec 2023 13:23:02 +0500 Subject: [PATCH 02/41] Update README.md (#12463) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15728ce9b..d9e8ff444 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ JumpServer是一款安全产品,请参考 [基本安全建议](https://docs.ju ## License & Copyright -Copyright (c) 2014-2023 飞致云 FIT2CLOUD, All rights reserved. +Copyright (c) 2014-2024 飞致云 FIT2CLOUD, All rights reserved. Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at From 2d6e815b3db3e72cbd956c4381076ec40fc8de40 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Fri, 29 Dec 2023 18:45:15 +0800 Subject: [PATCH 03/41] =?UTF-8?q?fix:=20=E5=A6=82=20Redis=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E4=BF=A1=E6=81=AF=E5=8C=85=E5=90=AB=E7=89=B9=E6=AE=8A?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E6=97=B6=EF=BC=8C=E6=9C=8D=E5=8A=A1=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 80790eb2e..66aba779e 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -17,7 +17,7 @@ import re import sys import types from importlib import import_module -from urllib.parse import urljoin, urlparse +from urllib.parse import urljoin, urlparse, quote import yaml from django.urls import reverse_lazy @@ -693,6 +693,13 @@ class Config(dict): if openid_config: self.set_openid_config(openid_config) + def compatible_redis(self): + redis_config = { + 'REDIS_PASSWORD': quote(str(self.REDIS_PASSWORD)), + } + for key, value in redis_config.items(): + self[key] = value + def compatible(self): """ 对配置做兼容处理 @@ -704,6 +711,8 @@ class Config(dict): """ # 兼容 OpenID 配置 self.compatible_auth_openid() + # 兼容 Redis 配置 + self.compatible_redis() def convert_type(self, k, v): default_value = self.defaults.get(k) From 7cdba3ef38e6db413d22081de23fae791e434579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Sat, 30 Dec 2023 13:22:14 +0800 Subject: [PATCH 04/41] build(deps): bump pyfreerdp from 0.0.1 to 0.0.2 --- poetry.lock | 96 +++++++++++++++++++++++++++----------------------- pyproject.toml | 2 +- 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4b7cac7ea..3be1006b6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "adal" @@ -2408,6 +2408,17 @@ files = [ {file = "ephem-4.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8f9b27117e7a82f7f70db9cb23b5cc36d37b166a2f73c55e14d7225d0ab95afa"}, {file = "ephem-4.1.4-cp311-cp311-win32.whl", hash = "sha256:9bb21c0b117c9122c0141b0a71ee6fbbb087ed2aab4a7ab60f009e95e9f4a521"}, {file = "ephem-4.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:55d7fb5c34b2e453e01fa4ca7ee375b19b438c9401ae8c4099ae4a3a37656972"}, + {file = "ephem-4.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f9e24aeea560dfcece3c2e313eb94e6be3e84888091455e541fa88f3a44da584"}, + {file = "ephem-4.1.4-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:653d99386932e5f78bb9cfc4495030ad9f3345eb4c2b32dca55547da8f1f0332"}, + {file = "ephem-4.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53786461a6d5799d5fffe76622ad51444b264d1c7263b92a6dfcac640c3da93a"}, + {file = "ephem-4.1.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:268f57f8768ccb0abbdf4cefb4781c7db812950019868f687b407b428513ee53"}, + {file = "ephem-4.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d630aa287255ea9fba6962f351e4e0729bb620570684d52fbfcc31b11527f09e"}, + {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5f229bbf62ecb4cd6bb3374b15d0f8ff7b3d970c2936fccd89bdf9d693907a2"}, + {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d60d56f182de54bd84fadd6ea2dd8e8ef6fdef6a698c7cafd404ecb6eeefa598"}, + {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:404500c8d0030d75ec15bb6b98eee78ad163fd5252102c962ae6fb39c9488198"}, + {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fb020d6cc5ab1ad1cd9d3da4a6e2506beebb41d1b337d79cc20cc0a17f550f1"}, + {file = "ephem-4.1.4-cp312-cp312-win32.whl", hash = "sha256:29e71636ee4719419d03184abc85085f76989c79a61844f5e60acbf2513d2b42"}, + {file = "ephem-4.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:549654f63d88e0ab6248ae25ac2939131474ab9f3a91bee6b68ca6f214747c2a"}, {file = "ephem-4.1.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:40067fc050c946c8d4c2d779805b61f063471a091e6124cbabcf61ac538011b2"}, {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e2abe97aa2b091090012768b4d94793213cc01f0bf040dcc311a380ab08df69"}, {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2677d3a5b42aedc578de10b0eecdba6a50731f159cb28f7ad38c5f62143494"}, @@ -2734,14 +2745,8 @@ files = [ [package.dependencies] google-auth = ">=2.14.1,<3.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0" -grpcio = [ - {version = ">=1.33.2,<2.0dev", optional = true, markers = "extra == \"grpc\""}, - {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, -] -grpcio-status = [ - {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "extra == \"grpc\""}, - {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, -] +grpcio = {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} +grpcio-status = {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" requests = ">=2.18.0,<3.0.0.dev0" @@ -5468,43 +5473,44 @@ reference = "tsinghua" [[package]] name = "pyfreerdp" -version = "0.0.1" -description = "" +version = "0.0.2" +description = "Python wrapper for FreeRDP" optional = false -python-versions = "*" +python-versions = ">=3.10" files = [ - {file = "pyfreerdp-0.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74b4e757d879b1d01c0bd7e1f91c17ddc007b941b92766f11077696546758490"}, - {file = "pyfreerdp-0.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c73dc9c87c185cd009c00561102a4727bb0cdff69e69eeb9af02a87b1ed627a"}, - {file = "pyfreerdp-0.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:363a9caea1b56f82726eea42bc42f47750440867ce1958e3855f5a01aed3d23a"}, - {file = "pyfreerdp-0.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:310a8471afb533d0ab4ff1fdb10c54106884883ed727e1ad6b61491a7fed466f"}, - {file = "pyfreerdp-0.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c869ca101e7e262dfa536472e3ac192c89999351f682328bfbcf056daa98aa99"}, - {file = "pyfreerdp-0.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a48ac00d35a2c2fd7bacbbd93b9753995d7b80f3202b2cacd35e1ece3154cd9"}, - {file = "pyfreerdp-0.0.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f3c7c635316ab2ab8f0379f146b4fdec6636123ed45c0ef6edce6f9d615bcbba"}, - {file = "pyfreerdp-0.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2edc5d938f2bbb337b70c46413a3a578257daf852211a4fb71ad592c57870436"}, - {file = "pyfreerdp-0.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee1439e6fc82ed5973ec098eb47c532abdb8de6d48f36b736cc39855f76df217"}, - {file = "pyfreerdp-0.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0ea400aaff3c00fa6b2fdcdf52696b27cfe16ce83feeffc22969eabebacfde1d"}, - {file = "pyfreerdp-0.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4d5f3340086956bedbf8cf0b43bb974e516df1730f80e63e4914fd0c6001e17f"}, - {file = "pyfreerdp-0.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f205f4d29da3bb118681bbc9ae732fb607fc86da210b04b4916a711fa1b67a9d"}, - {file = "pyfreerdp-0.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d424c70a36280f5445b6d213f947f3fffca1142a4414e5b3bb56c870f114397"}, - {file = "pyfreerdp-0.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:38eafc6a60759a25d97ae45f030a0c4e6c8c8a018541fc2076115cf302fd9475"}, - {file = "pyfreerdp-0.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9b26a9ff4e25d04631330da16f3bdad2e805948edb3367f175b5db4cc6eed573"}, - {file = "pyfreerdp-0.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:414ede648e851be7fb0b8bd7b2f38390c5561ef73ea2f15bce2689fbbdaecb8b"}, - {file = "pyfreerdp-0.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cec04cce9aa23268a0e8b1de78c65708b46a9fb8b7664f7bc00932761eed359"}, - {file = "pyfreerdp-0.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f31d916bcadc015c775167895c823be8909aff8286847bc61f1162dd751fc0"}, - {file = "pyfreerdp-0.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:352d30fe3d7f4323b37f474faaed34b21ea3f230a53911e834ec5a51e9cc747b"}, - {file = "pyfreerdp-0.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd3e4cf7f24fb8a3eef4bf2e1147d92437e3298027280eef29a6d08c84b3e7dd"}, - {file = "pyfreerdp-0.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1ba8c23643746d9638469c7a8981f9d57a9bdf068d03fa2c32c28728011db7cc"}, - {file = "pyfreerdp-0.0.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:05f0f16dc1621cfbd3da6b3f8acd292dcf09ac2cde3a578aec7af359a65174b9"}, - {file = "pyfreerdp-0.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4f577beba135c1b603e0cc3b1a71fbfc53bdb53a5aeedc7650f1120a5d52d14"}, - {file = "pyfreerdp-0.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c8311d355b54cdfadccc2dba7c9d8962aa8179f4c5a852ecb3a33bc9a6f0ee2"}, - {file = "pyfreerdp-0.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:51ecfecc1a8a40a2461a5b4ff105bc92ef86a57fd6364c3c309c6fe7c66fb5e7"}, - {file = "pyfreerdp-0.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:48cf5c73d98d3f8edaf229c78884828652242036484dff3e61974bf1bce852a3"}, - {file = "pyfreerdp-0.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3adaaf7bb2e32c2288a4bb939130fa0a3afb5d87a11c46c2d6f882c051ee43e"}, - {file = "pyfreerdp-0.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2127d10afa600d691e4b4795f3c6e70cf227e9a65b536bc0ec096f93eb92b4dd"}, - {file = "pyfreerdp-0.0.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed7f0413e4e5c0c03c01f9bcf24eb3fe2b0223fc84947917352421fbd548de5"}, - {file = "pyfreerdp-0.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40a91c509fe62ef74341e5ef66b3ac8530f989df87cf5477945de2eb8984522f"}, - {file = "pyfreerdp-0.0.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:509e1643fc87c597ec5bc1ab9505e2839b5e9ca049b5af95a3d70b828e8c4bfd"}, - {file = "pyfreerdp-0.0.1.tar.gz", hash = "sha256:946eca882741e6802794185cbdd47b49626c3181bce99dbd27c5746563c13d43"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27ca63ac041dc5f657e0a87e81d05139ac0100124dcc84ea2ae7c5ae8daf28e8"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7ce5d215c08601b938c61fa3ad75c975bb35bf5bdecd154437534c3962d6072"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5d310b578e1dbf1da191817266161a030ba987234bd8c675efbce8b1e8c6ac"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fc92f15b63ab9f018f36391464a102c32edee090a98932817827d24c69633c"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b8d8db814ef56c62c4582d27da44aab4f6630146b88d4428dfabbc1c754202"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ed6a302ed8b475f7c0df1fe37922fd786706f5b632196e32b911ff566600f880"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:99dfe7bd0fcda0003dd41b72b80b76d24dddde0b66535b507d823a5ce073ec2a"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:881003ce2853d9a290c47a04c165941a5a0addd7ad360d033f275dec3eead192"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:a54ae7c62b3c92e4dba082e328e0bb190f83f45eb84cf59eabb894dfe24a07f7"}, + {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33c3e14664e306c31c2a792cb8dfdd6a381e35f79583a271dd20be25b14ad73d"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cfd97b8da87b1439407b40e7eda998f0df44332211353b0f4217e91d233bc53"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9ce1a906e861335864bb8c976612a5b1d0595955b0cde35e3697eed7812c8b6"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b630f604300323b3e1fe6b27d442636f9b0d247eba3cc4340a39721c6d85273"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ecd8bab19ab9a4b6bd22e82821e697ffe2b48de1f648e85064e1083b1dafbc7"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22be067f8aa145726f73c893c820339f103e91abfa204fdf20647c6b866c3e27"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:26ffa208cd92c344f1003704a10e0cc2f92cfe935e077626b9e6564e351c306e"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:93ae2624af6eb117ff27137659d72362b46bbd6f0e3474183a44bcdca1808a3f"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:75ecac10e8879b9c163f68fef32bfb308d95d04fa9c89a37624aba34ce16e652"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0cccf234d8b08ded94a76894608ad848c002d87b3c0998d1462863ad1117c298"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f9de9830825e6ef12536759fc04f51243451553909eb91c903a03f181da7a610"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2016772418ea6708d07becc7334425b2a19610fea38f28597b0e9dd57c302f0"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f659cd917d8dd291a8d5d6198f23b84a9ac9835c642b80a578dba9d85c8db975"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1770a1bcfbf953448ad17cc871ba68ed14321f6168054a2bb7b185c2d967ee5d"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aac97779172199a2e9a24889cf2284adc66ef0757c2214dce1f4307e381678b"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36497154f63a5b5cc9cba0e821d17ee7890d7b2c00d73630be2c4ca512a72d45"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9ecbf36edbc4fdc64e2ae5e513c8a5bf97d82fcb1634271b8d9a1c021e76a109"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:649884ef8642b732f4b24bcb5a8ca7c040b5b909ca5e97bcd297faf31510d108"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:f19b370c370e4ed18985455deb48b06e51f33cce6c3eb889e421a76f33fb13c0"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:4db29d2f12875b764baaed9d76251c3be739485cfce3dbf030977c2bd7d79fca"}, + {file = "pyfreerdp-0.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:caf6cf6b33bb08761b1a8680c41525170c139a8e6848441f2061eef96369da19"}, + {file = "pyfreerdp-0.0.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb31b620013859a7142a391d9ce57c195f26c3c9991883f87bc5ef1703cf806f"}, + {file = "pyfreerdp-0.0.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c839d3ed9c0cc4021129e26c06d3bc45982bdaba8a2a115051ad43c5f6108d11"}, + {file = "pyfreerdp-0.0.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c2a23db4a56903dfff9ac5e8b2b7aa713af694dce5a4f3905ef7703b4f9dcd"}, ] [package.source] @@ -7771,4 +7777,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "19950a5300f8a4425e3e3c9a096fc3782cb544e02152e92ac1bc09d1d9b5274a" +content-hash = "9cd692c23b87a664c7e274fb3679332bc0b49cdfba4174844870ed635162f8c4" diff --git a/pyproject.toml b/pyproject.toml index 58b9991f6..f639644df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -127,7 +127,7 @@ python-redis-lock = "4.0.0" pyopenssl = "23.2.0" redis = "4.6.0" pymongo = "4.4.1" -pyfreerdp = "0.0.1" +pyfreerdp = "0.0.2" ipython = "8.14.0" forgerypy3 = "0.3.1" django-debug-toolbar = "4.1.0" From e80a0e41ba7a808678173a4d82f87b24fcb21d47 Mon Sep 17 00:00:00 2001 From: wangruidong <940853815@qq.com> Date: Tue, 2 Jan 2024 14:42:51 +0800 Subject: [PATCH 05/41] =?UTF-8?q?fix:=20=E5=90=8C=E6=AD=A5LDAP=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=97=B6=EF=BC=8C=E7=94=A8=E6=88=B7=E7=BB=84=E5=8F=AA?= =?UTF-8?q?=E7=A7=BB=E9=99=A4LDAP=E5=90=8C=E6=AD=A5=E8=BF=87=E6=9D=A5?= =?UTF-8?q?=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/utils/ldap.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/settings/utils/ldap.py b/apps/settings/utils/ldap.py index 23b7b3882..b4f21affa 100644 --- a/apps/settings/utils/ldap.py +++ b/apps/settings/utils/ldap.py @@ -423,12 +423,11 @@ class LDAPImportUtil(object): logger.info('End perform import ldap users') return errors - @staticmethod - def exit_user_group(user_groups_mapper): + def exit_user_group(self, user_groups_mapper): # 通过对比查询本次导入用户需要移除的用户组 group_remove_users_mapper = defaultdict(set) for user, current_groups in user_groups_mapper.items(): - old_groups = set(user.groups.all()) + old_groups = set(user.groups.filter(name__startswith=self.user_group_name_prefix)) exit_groups = old_groups - current_groups logger.debug(f'Ldap user {user} exits user groups {exit_groups}') for g in exit_groups: From 2fcbfe9f2105c22d00308170cb2e50e2d1af0ceb Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:11:56 +0800 Subject: [PATCH 06/41] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20tree=20nodes?= =?UTF-8?q?=20=E9=81=BF=E5=85=8D=E5=A4=AA=E6=85=A2=20(#12472)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 优化 tree nodes 避免太慢 perf: 优化大量资产上的资产数生成比较慢 perf: 优化节点树 perf: 修改 tree nooooooooodes perf: 优化一些 api 比较大的问题 perf: 优化平台 api perf: 分页返回同步树 perf: 优化节点树 perf: 深度优化节点树 * perf: remove unused config --------- Co-authored-by: ibuler --- apps/assets/api/asset/asset.py | 7 +- apps/assets/api/domain.py | 9 +- apps/assets/api/mixin.py | 38 ++-- apps/assets/api/platform.py | 4 +- apps/assets/api/tree.py | 2 + apps/assets/const/types.py | 6 +- apps/assets/filters.py | 3 +- apps/assets/models/node.py | 34 ++-- apps/assets/serializers/domain.py | 26 ++- apps/assets/signal_handlers/asset.py | 7 +- .../signal_handlers/node_assets_amount.py | 4 +- .../signal_handlers/node_assets_mapping.py | 7 +- apps/common/api/mixin.py | 13 +- apps/common/decorators.py | 2 +- apps/common/signal_handlers.py | 6 +- apps/common/utils/common.py | 2 +- apps/common/utils/lock.py | 22 +-- apps/jumpserver/conf.py | 1 + apps/jumpserver/settings/custom.py | 1 + apps/jumpserver/settings/logging.py | 2 +- apps/orgs/signal_handlers/cache.py | 4 +- apps/perms/api/asset_permission.py | 6 +- apps/perms/api/user_permission/tree/asset.py | 9 +- .../user_permission/tree/node_with_asset.py | 164 +++++++++--------- apps/perms/models/asset_permission.py | 27 ++- apps/perms/serializers/permission.py | 35 +++- apps/perms/signal_handlers/refresh_perms.py | 11 +- apps/perms/utils/permission.py | 4 +- apps/perms/utils/user_perm.py | 94 ++++++++-- apps/perms/utils/user_perm_tree.py | 101 +++++++++-- apps/rbac/permissions.py | 2 +- apps/users/api/group.py | 7 +- apps/users/serializers/group.py | 17 +- utils/generate_fake_data/generate.py | 3 + .../generate_fake_data/resources/accounts.py | 32 ++++ utils/generate_fake_data/resources/assets.py | 13 +- utils/generate_fake_data/resources/base.py | 2 +- utils/generate_fake_data/resources/users.py | 17 +- 38 files changed, 508 insertions(+), 236 deletions(-) create mode 100644 utils/generate_fake_data/resources/accounts.py diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py index eef18a773..b6e532b36 100644 --- a/apps/assets/api/asset/asset.py +++ b/apps/assets/api/asset/asset.py @@ -21,7 +21,6 @@ from common.drf.filters import BaseFilterSet, AttrRulesFilterBackend from common.utils import get_logger, is_uuid from orgs.mixins import generics from orgs.mixins.api import OrgBulkModelViewSet -from ..mixin import NodeFilterMixin from ...notifications import BulkUpdatePlatformSkipAssetUserMsg logger = get_logger(__file__) @@ -86,7 +85,7 @@ class AssetFilterSet(BaseFilterSet): return queryset.filter(protocols__name__in=value).distinct() -class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet): +class AssetViewSet(SuggestionMixin, OrgBulkModelViewSet): """ API endpoint that allows Asset to be viewed or edited. """ @@ -114,9 +113,7 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet): ] def get_queryset(self): - queryset = super().get_queryset() \ - .prefetch_related('nodes', 'protocols') \ - .select_related('platform', 'domain') + queryset = super().get_queryset() if queryset.model is not Asset: queryset = queryset.select_related('asset_ptr') return queryset diff --git a/apps/assets/api/domain.py b/apps/assets/api/domain.py index 86097247c..46b586458 100644 --- a/apps/assets/api/domain.py +++ b/apps/assets/api/domain.py @@ -20,14 +20,15 @@ class DomainViewSet(OrgBulkModelViewSet): filterset_fields = ("name",) search_fields = filterset_fields ordering = ('name',) + serializer_classes = { + 'default': serializers.DomainSerializer, + 'list': serializers.DomainListSerializer, + } def get_serializer_class(self): if self.request.query_params.get('gateway'): return serializers.DomainWithGatewaySerializer - return serializers.DomainSerializer - - def get_queryset(self): - return super().get_queryset().prefetch_related('assets') + return super().get_serializer_class() class GatewayViewSet(HostViewSet): diff --git a/apps/assets/api/mixin.py b/apps/assets/api/mixin.py index d3ea4761d..25aefa62a 100644 --- a/apps/assets/api/mixin.py +++ b/apps/assets/api/mixin.py @@ -2,7 +2,7 @@ from typing import List from rest_framework.request import Request -from assets.models import Node, Protocol +from assets.models import Node, Platform, Protocol from assets.utils import get_node_from_request, is_query_node_all_assets from common.utils import lazyproperty, timeit @@ -71,37 +71,43 @@ class SerializeToTreeNodeMixin: return 'file' @timeit - def serialize_assets(self, assets, node_key=None, pid=None): - if node_key is None: - get_pid = lambda asset: getattr(asset, 'parent_key', '') - else: - get_pid = lambda asset: node_key + def serialize_assets(self, assets, node_key=None, get_pid=None): + if not get_pid and not node_key: + get_pid = lambda asset, platform: getattr(asset, 'parent_key', '') + sftp_asset_ids = Protocol.objects.filter(name='sftp') \ .values_list('asset_id', flat=True) - sftp_asset_ids = list(sftp_asset_ids) - data = [ - { + sftp_asset_ids = set(sftp_asset_ids) + platform_map = {p.id: p for p in Platform.objects.all()} + + data = [] + for asset in assets: + platform = platform_map.get(asset.platform_id) + if not platform: + continue + pid = node_key or get_pid(asset, platform) + if not pid or pid.isdigit(): + continue + data.append({ 'id': str(asset.id), 'name': asset.name, - 'title': f'{asset.address}\n{asset.comment}', - 'pId': pid or get_pid(asset), + 'title': f'{asset.address}\n{asset.comment}'.strip(), + 'pId': pid, 'isParent': False, 'open': False, - 'iconSkin': self.get_icon(asset), + 'iconSkin': self.get_icon(platform), 'chkDisabled': not asset.is_active, 'meta': { 'type': 'asset', 'data': { - 'platform_type': asset.platform.type, + 'platform_type': platform.type, 'org_name': asset.org_name, 'sftp': asset.id in sftp_asset_ids, 'name': asset.name, 'address': asset.address }, } - } - for asset in assets - ] + }) return data diff --git a/apps/assets/api/platform.py b/apps/assets/api/platform.py index 449b7b8a3..9f3a55bda 100644 --- a/apps/assets/api/platform.py +++ b/apps/assets/api/platform.py @@ -29,7 +29,9 @@ class AssetPlatformViewSet(JMSModelViewSet): } def get_queryset(self): - queryset = super().get_queryset() + queryset = super().get_queryset().prefetch_related( + 'protocols', 'automation' + ) queryset = queryset.filter(type__in=AllTypes.get_types_values()) return queryset diff --git a/apps/assets/api/tree.py b/apps/assets/api/tree.py index 762859ca1..277ab323e 100644 --- a/apps/assets/api/tree.py +++ b/apps/assets/api/tree.py @@ -126,6 +126,8 @@ class NodeChildrenAsTreeApi(SerializeToTreeNodeMixin, NodeChildrenApi): include_assets = self.request.query_params.get('assets', '0') == '1' if not self.instance or not include_assets: return Asset.objects.none() + if self.instance.is_org_root(): + return Asset.objects.none() if query_all: assets = self.instance.get_all_assets() else: diff --git a/apps/assets/const/types.py b/apps/assets/const/types.py index c33052c64..220d10731 100644 --- a/apps/assets/const/types.py +++ b/apps/assets/const/types.py @@ -268,7 +268,7 @@ class AllTypes(ChoicesMixin): meta = {'type': 'category', 'category': category.value, '_type': category.value} category_node = cls.choice_to_node(category, 'ROOT', meta=meta) category_count = category_type_mapper.get(category, 0) - category_node['name'] += f'({category_count})' + category_node['name'] += f' ({category_count})' nodes.append(category_node) # Type 格式化 @@ -277,7 +277,7 @@ class AllTypes(ChoicesMixin): meta = {'type': 'type', 'category': category.value, '_type': tp.value} tp_node = cls.choice_to_node(tp, category_node['id'], opened=False, meta=meta) tp_count = category_type_mapper.get(category + '_' + tp, 0) - tp_node['name'] += f'({tp_count})' + tp_node['name'] += f' ({tp_count})' platforms = tp_platforms.get(category + '_' + tp, []) if not platforms: tp_node['isParent'] = False @@ -286,7 +286,7 @@ class AllTypes(ChoicesMixin): # Platform 格式化 for p in platforms: platform_node = cls.platform_to_node(p, tp_node['id'], include_asset) - platform_node['name'] += f'({platform_count.get(p.id, 0)})' + platform_node['name'] += f' ({platform_count.get(p.id, 0)})' nodes.append(platform_node) return nodes diff --git a/apps/assets/filters.py b/apps/assets/filters.py index f1fe6d666..1475f9b2e 100644 --- a/apps/assets/filters.py +++ b/apps/assets/filters.py @@ -63,11 +63,10 @@ class NodeFilterBackend(filters.BaseFilterBackend): query_all = is_query_node_all_assets(request) if query_all: return queryset.filter( - Q(nodes__key__istartswith=f'{node.key}:') | + Q(nodes__key__startswith=f'{node.key}:') | Q(nodes__key=node.key) ).distinct() else: - print("Query query origin: ", queryset.count()) return queryset.filter(nodes__key=node.key).distinct() diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index d4fc8165d..7a15b9349 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -13,7 +13,7 @@ from django.db.transaction import atomic from django.utils.translation import gettext_lazy as _, gettext from common.db.models import output_as_string -from common.utils import get_logger +from common.utils import get_logger, timeit from common.utils.lock import DistributedLock from orgs.mixins.models import OrgManager, JMSOrgBaseModel from orgs.models import Organization @@ -195,11 +195,6 @@ class FamilyMixin: ancestor_keys = self.get_ancestor_keys(with_self=with_self) return self.__class__.objects.filter(key__in=ancestor_keys) - # @property - # def parent_key(self): - # parent_key = ":".join(self.key.split(":")[:-1]) - # return parent_key - def compute_parent_key(self): return compute_parent_key(self.key) @@ -349,29 +344,26 @@ class NodeAllAssetsMappingMixin: return 'ASSETS_ORG_NODE_ALL_ASSET_ids_MAPPING_{}'.format(org_id) @classmethod + @timeit def generate_node_all_asset_ids_mapping(cls, org_id): - from .asset import Asset - - logger.info(f'Generate node asset mapping: ' - f'thread={threading.get_ident()} ' - f'org_id={org_id}') + logger.info(f'Generate node asset mapping: org_id={org_id}') t1 = time.time() with tmp_to_org(org_id): node_ids_key = Node.objects.annotate( char_id=output_as_string('id') ).values_list('char_id', 'key') - # * 直接取出全部. filter(node__org_id=org_id)(大规模下会更慢) - nodes_asset_ids = Asset.nodes.through.objects.all() \ - .annotate(char_node_id=output_as_string('node_id')) \ - .annotate(char_asset_id=output_as_string('asset_id')) \ - .values_list('char_node_id', 'char_asset_id') - node_id_ancestor_keys_mapping = { node_id: cls.get_node_ancestor_keys(node_key, with_self=True) for node_id, node_key in node_ids_key } + # * 直接取出全部. filter(node__org_id=org_id)(大规模下会更慢) + nodes_asset_ids = cls.assets.through.objects.all() \ + .annotate(char_node_id=output_as_string('node_id')) \ + .annotate(char_asset_id=output_as_string('asset_id')) \ + .values_list('char_node_id', 'char_asset_id') + nodeid_assetsid_mapping = defaultdict(set) for node_id, asset_id in nodes_asset_ids: nodeid_assetsid_mapping[node_id].add(asset_id) @@ -386,7 +378,7 @@ class NodeAllAssetsMappingMixin: mapping[ancestor_key].update(asset_ids) t3 = time.time() - logger.info('t1-t2(DB Query): {} s, t3-t2(Generate mapping): {} s'.format(t2 - t1, t3 - t2)) + logger.info('Generate asset nodes mapping, DB query: {:.2f}s, mapping: {:.2f}s'.format(t2 - t1, t3 - t2)) return mapping @@ -436,6 +428,7 @@ class NodeAssetsMixin(NodeAllAssetsMappingMixin): return asset_ids @classmethod + @timeit def get_nodes_all_assets(cls, *nodes): from .asset import Asset node_ids = set() @@ -559,11 +552,6 @@ class Node(JMSOrgBaseModel, SomeNodesMixin, FamilyMixin, NodeAssetsMixin): def __str__(self): return self.full_value - # def __eq__(self, other): - # if not other: - # return False - # return self.id == other.id - # def __gt__(self, other): self_key = [int(k) for k in self.key.split(':')] other_key = [int(k) for k in other.key.split(':')] diff --git a/apps/assets/serializers/domain.py b/apps/assets/serializers/domain.py index d2b3e3550..9ea603ac3 100644 --- a/apps/assets/serializers/domain.py +++ b/apps/assets/serializers/domain.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # +from django.db.models import Count from django.utils.translation import gettext_lazy as _ from rest_framework import serializers @@ -7,18 +8,15 @@ from common.serializers import ResourceLabelsMixin from common.serializers.fields import ObjectRelatedField from orgs.mixins.serializers import BulkOrgResourceModelSerializer from .gateway import GatewayWithAccountSecretSerializer -from ..models import Domain, Asset +from ..models import Domain -__all__ = ['DomainSerializer', 'DomainWithGatewaySerializer'] +__all__ = ['DomainSerializer', 'DomainWithGatewaySerializer', 'DomainListSerializer'] class DomainSerializer(ResourceLabelsMixin, BulkOrgResourceModelSerializer): gateways = ObjectRelatedField( many=True, required=False, label=_('Gateway'), read_only=True, ) - assets = ObjectRelatedField( - many=True, required=False, queryset=Asset.objects, label=_('Asset') - ) class Meta: model = Domain @@ -30,7 +28,9 @@ class DomainSerializer(ResourceLabelsMixin, BulkOrgResourceModelSerializer): def to_representation(self, instance): data = super().to_representation(instance) - assets = data['assets'] + assets = data.get('assets') + if assets is None: + return data gateway_ids = [str(i['id']) for i in data['gateways']] data['assets'] = [i for i in assets if str(i['id']) not in gateway_ids] return data @@ -49,6 +49,20 @@ class DomainSerializer(ResourceLabelsMixin, BulkOrgResourceModelSerializer): return queryset +class DomainListSerializer(DomainSerializer): + assets_amount = serializers.IntegerField(label=_('Assets amount'), read_only=True) + + class Meta(DomainSerializer.Meta): + fields = list(set(DomainSerializer.Meta.fields + ['assets_amount']) - {'assets'}) + + @classmethod + def setup_eager_loading(cls, queryset): + queryset = queryset.annotate( + assets_amount=Count('assets'), + ) + return queryset + + class DomainWithGatewaySerializer(serializers.ModelSerializer): gateways = GatewayWithAccountSecretSerializer(many=True, read_only=True) diff --git a/apps/assets/signal_handlers/asset.py b/apps/assets/signal_handlers/asset.py index 9598bec5d..5ab4a4117 100644 --- a/apps/assets/signal_handlers/asset.py +++ b/apps/assets/signal_handlers/asset.py @@ -80,10 +80,11 @@ RELATED_NODE_IDS = '_related_node_ids' @receiver(pre_delete, sender=Asset) def on_asset_delete(instance: Asset, using, **kwargs): - logger.debug("Asset pre delete signal recv: {}".format(instance)) node_ids = Node.objects.filter(assets=instance) \ .distinct().values_list('id', flat=True) - setattr(instance, RELATED_NODE_IDS, node_ids) + node_ids = list(node_ids) + logger.debug("Asset pre delete signal recv: {}, node_ids: {}".format(instance, node_ids)) + setattr(instance, RELATED_NODE_IDS, list(node_ids)) m2m_changed.send( sender=Asset.nodes.through, instance=instance, reverse=False, model=Node, pk_set=node_ids, @@ -93,8 +94,8 @@ def on_asset_delete(instance: Asset, using, **kwargs): @receiver(post_delete, sender=Asset) def on_asset_post_delete(instance: Asset, using, **kwargs): - logger.debug("Asset post delete signal recv: {}".format(instance)) node_ids = getattr(instance, RELATED_NODE_IDS, []) + logger.debug("Asset post delete signal recv: {}, node_ids: {}".format(instance, node_ids)) if node_ids: m2m_changed.send( sender=Asset.nodes.through, instance=instance, reverse=False, diff --git a/apps/assets/signal_handlers/node_assets_amount.py b/apps/assets/signal_handlers/node_assets_amount.py index 79e2ed568..ea2b3ba8a 100644 --- a/apps/assets/signal_handlers/node_assets_amount.py +++ b/apps/assets/signal_handlers/node_assets_amount.py @@ -15,8 +15,8 @@ from ..tasks import check_node_assets_amount_task logger = get_logger(__file__) -@on_transaction_commit @receiver(m2m_changed, sender=Asset.nodes.through) +@on_transaction_commit def on_node_asset_change(sender, action, instance, reverse, pk_set, **kwargs): # 不允许 `pre_clear` ,因为该信号没有 `pk_set` # [官网](https://docs.djangoproject.com/en/3.1/ref/signals/#m2m-changed) @@ -37,7 +37,7 @@ def on_node_asset_change(sender, action, instance, reverse, pk_set, **kwargs): update_nodes_assets_amount(node_ids=node_ids) -@merge_delay_run(ttl=5) +@merge_delay_run(ttl=30) def update_nodes_assets_amount(node_ids=()): nodes = Node.objects.filter(id__in=node_ids) nodes = Node.get_ancestor_queryset(nodes) diff --git a/apps/assets/signal_handlers/node_assets_mapping.py b/apps/assets/signal_handlers/node_assets_mapping.py index 34b707dab..a53e534b6 100644 --- a/apps/assets/signal_handlers/node_assets_mapping.py +++ b/apps/assets/signal_handlers/node_assets_mapping.py @@ -21,7 +21,7 @@ logger = get_logger(__name__) node_assets_mapping_pub_sub = lazy(lambda: RedisPubSub('fm.node_asset_mapping'), RedisPubSub)() -@merge_delay_run(ttl=5) +@merge_delay_run(ttl=30) def expire_node_assets_mapping(org_ids=()): logger.debug("Recv asset nodes changed signal, expire memery node asset mapping") # 所有进程清除(自己的 memory 数据) @@ -53,8 +53,9 @@ def on_node_post_delete(sender, instance, **kwargs): @receiver(m2m_changed, sender=Asset.nodes.through) -def on_node_asset_change(sender, instance, **kwargs): - expire_node_assets_mapping(org_ids=(instance.org_id,)) +def on_node_asset_change(sender, instance, action='pre_remove', **kwargs): + if action.startswith('post'): + expire_node_assets_mapping(org_ids=(instance.org_id,)) @receiver(django_ready) diff --git a/apps/common/api/mixin.py b/apps/common/api/mixin.py index c87d5f22a..50bb1efbe 100644 --- a/apps/common/api/mixin.py +++ b/apps/common/api/mixin.py @@ -98,12 +98,17 @@ class QuerySetMixin: return queryset if self.action == 'metadata': queryset = queryset.none() - if self.action in ['list', 'metadata']: - serializer_class = self.get_serializer_class() - if serializer_class and hasattr(serializer_class, 'setup_eager_loading'): - queryset = serializer_class.setup_eager_loading(queryset) return queryset + def paginate_queryset(self, queryset): + page = super().paginate_queryset(queryset) + serializer_class = self.get_serializer_class() + if page and serializer_class and hasattr(serializer_class, 'setup_eager_loading'): + ids = [i.id for i in page] + page = self.get_queryset().filter(id__in=ids) + page = serializer_class.setup_eager_loading(page) + return page + class ExtraFilterFieldsMixin: """ diff --git a/apps/common/decorators.py b/apps/common/decorators.py index 24b2695d3..7269c9e0d 100644 --- a/apps/common/decorators.py +++ b/apps/common/decorators.py @@ -65,7 +65,7 @@ class EventLoopThread(threading.Thread): _loop_thread = EventLoopThread() -_loop_thread.setDaemon(True) +_loop_thread.daemon = True _loop_thread.start() executor = ThreadPoolExecutor( max_workers=10, diff --git a/apps/common/signal_handlers.py b/apps/common/signal_handlers.py index 588a63632..ba5a4ad92 100644 --- a/apps/common/signal_handlers.py +++ b/apps/common/signal_handlers.py @@ -62,7 +62,7 @@ def digest_sql_query(): method = current_request.method path = current_request.get_full_path() - print(">>> [{}] {}".format(method, path)) + print(">>>. [{}] {}".format(method, path)) for table_name, queries in table_queries.items(): if table_name.startswith('rbac_') or table_name.startswith('auth_permission'): continue @@ -77,9 +77,9 @@ def digest_sql_query(): sql = query['sql'] if not sql or not sql.startswith('SELECT'): continue - print('\t{}. {}'.format(i, sql)) + print('\t{}.[{}s] {}'.format(i, round(float(query['time']), 2), sql[:1000])) - logger.debug(">>> [{}] {}".format(method, path)) + # logger.debug(">>> [{}] {}".format(method, path)) for name, counter in counters: logger.debug("Query {:3} times using {:.2f}s {}".format( counter.counter, counter.time, name) diff --git a/apps/common/utils/common.py b/apps/common/utils/common.py index 798b4a94c..86b68bef7 100644 --- a/apps/common/utils/common.py +++ b/apps/common/utils/common.py @@ -220,7 +220,7 @@ def timeit(func): now = time.time() result = func(*args, **kwargs) using = (time.time() - now) * 1000 - msg = "End call {}, using: {:.1f}ms".format(name, using) + msg = "Ends call: {}, using: {:.1f}ms".format(name, using) logger.debug(msg) return result diff --git a/apps/common/utils/lock.py b/apps/common/utils/lock.py index 773647725..949d13c6b 100644 --- a/apps/common/utils/lock.py +++ b/apps/common/utils/lock.py @@ -1,18 +1,16 @@ -from functools import wraps import threading +from functools import wraps +from django.db import transaction from redis_lock import ( Lock as RedisLock, NotAcquired, UNLOCK_SCRIPT, EXTEND_SCRIPT, RESET_SCRIPT, RESET_ALL_SCRIPT ) -from redis import Redis -from django.db import transaction -from common.utils import get_logger -from common.utils.inspect import copy_function_args -from common.utils.connection import get_redis_client -from jumpserver.const import CONFIG from common.local import thread_local +from common.utils import get_logger +from common.utils.connection import get_redis_client +from common.utils.inspect import copy_function_args logger = get_logger(__file__) @@ -76,6 +74,7 @@ class DistributedLock(RedisLock): # 要创建一个新的锁对象 with self.__class__(**self.kwargs_copy): return func(*args, **kwds) + return inner @classmethod @@ -95,7 +94,6 @@ class DistributedLock(RedisLock): if self.locked(): owner_id = self.get_owner_id() local_owner_id = getattr(thread_local, self.name, None) - if local_owner_id and owner_id == local_owner_id: return True return False @@ -140,14 +138,16 @@ class DistributedLock(RedisLock): logger.debug(f'Released reentrant-lock: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name}') return else: - self._raise_exc_with_log(f'Reentrant-lock is not acquired: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name}') + self._raise_exc_with_log( + f'Reentrant-lock is not acquired: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name}') def _release_on_reentrant_locked_by_me(self): logger.debug(f'Release reentrant-lock locked by me: lock_id={self.id} lock={self.name}') id = getattr(thread_local, self.name, None) if id != self.id: - raise PermissionError(f'Reentrant-lock is not locked by me: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name}') + raise PermissionError( + f'Reentrant-lock is not locked by me: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name}') try: # 这里要保证先删除 thread_local 的标记, delattr(thread_local, self.name) @@ -191,7 +191,7 @@ class DistributedLock(RedisLock): # 处理是否在事务提交时才释放锁 if self._release_on_transaction_commit: logger.debug( - f'Release lock on transaction commit ... :lock_id={self.id} lock={self.name}') + f'Release lock on transaction commit:lock_id={self.id} lock={self.name}') transaction.on_commit(_release) else: _release() diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 66aba779e..60e3dfd0c 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -531,6 +531,7 @@ class Config(dict): 'SYSLOG_SOCKTYPE': 2, 'PERM_EXPIRED_CHECK_PERIODIC': 60 * 60, + 'PERM_TREE_REGEN_INTERVAL': 1, 'FLOWER_URL': "127.0.0.1:5555", 'LANGUAGE_CODE': 'zh', 'TIME_ZONE': 'Asia/Shanghai', diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index fad5f0e9d..311e54aa8 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -208,6 +208,7 @@ OPERATE_LOG_ELASTICSEARCH_CONFIG = CONFIG.OPERATE_LOG_ELASTICSEARCH_CONFIG MAX_LIMIT_PER_PAGE = CONFIG.MAX_LIMIT_PER_PAGE DEFAULT_PAGE_SIZE = CONFIG.DEFAULT_PAGE_SIZE +PERM_TREE_REGEN_INTERVAL = CONFIG.PERM_TREE_REGEN_INTERVAL # Magnus DB Port MAGNUS_ORACLE_PORTS = CONFIG.MAGNUS_ORACLE_PORTS diff --git a/apps/jumpserver/settings/logging.py b/apps/jumpserver/settings/logging.py index c4cf90ebb..bd44e22dc 100644 --- a/apps/jumpserver/settings/logging.py +++ b/apps/jumpserver/settings/logging.py @@ -21,7 +21,7 @@ LOGGING = { }, 'main': { 'datefmt': '%Y-%m-%d %H:%M:%S', - 'format': '%(asctime)s [%(module)s %(levelname)s] %(message)s', + 'format': '%(asctime)s [%(levelname).4s] %(message)s', }, 'exception': { 'datefmt': '%Y-%m-%d %H:%M:%S', diff --git a/apps/orgs/signal_handlers/cache.py b/apps/orgs/signal_handlers/cache.py index b4e6001e3..4dc3c796e 100644 --- a/apps/orgs/signal_handlers/cache.py +++ b/apps/orgs/signal_handlers/cache.py @@ -75,7 +75,7 @@ model_cache_field_mapper = { class OrgResourceStatisticsRefreshUtil: @staticmethod - @merge_delay_run(ttl=5) + @merge_delay_run(ttl=30) def refresh_org_fields(org_fields=()): for org, cache_field_name in org_fields: OrgResourceStatisticsCache(org).expire(*cache_field_name) @@ -104,7 +104,7 @@ def on_post_delete_refresh_org_resource_statistics_cache(sender, instance, **kwa def _refresh_session_org_resource_statistics_cache(instance: Session): cache_field_name = [ 'total_count_online_users', 'total_count_online_sessions', - 'total_count_today_active_assets','total_count_today_failed_sessions' + 'total_count_today_active_assets', 'total_count_today_failed_sessions' ] org_cache = OrgResourceStatisticsCache(instance.org) diff --git a/apps/perms/api/asset_permission.py b/apps/perms/api/asset_permission.py index 750f41fb4..c72254d0d 100644 --- a/apps/perms/api/asset_permission.py +++ b/apps/perms/api/asset_permission.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # + from orgs.mixins.api import OrgBulkModelViewSet from perms import serializers from perms.filters import AssetPermissionFilter @@ -13,7 +14,10 @@ class AssetPermissionViewSet(OrgBulkModelViewSet): 资产授权列表的增删改查api """ model = AssetPermission - serializer_class = serializers.AssetPermissionSerializer + serializer_classes = { + 'default': serializers.AssetPermissionSerializer, + 'list': serializers.AssetPermissionListSerializer, + } filterset_class = AssetPermissionFilter search_fields = ('name',) ordering = ('name',) diff --git a/apps/perms/api/user_permission/tree/asset.py b/apps/perms/api/user_permission/tree/asset.py index c620356ad..e5e2ab4d3 100644 --- a/apps/perms/api/user_permission/tree/asset.py +++ b/apps/perms/api/user_permission/tree/asset.py @@ -1,16 +1,14 @@ from django.conf import settings from rest_framework.response import Response -from assets.models import Asset from assets.api import SerializeToTreeNodeMixin +from assets.models import Asset from common.utils import get_logger - -from ..assets import UserAllPermedAssetsApi from .mixin import RebuildTreeMixin +from ..assets import UserAllPermedAssetsApi logger = get_logger(__name__) - __all__ = [ 'UserAllPermedAssetsAsTreeApi', 'UserUngroupAssetsAsTreeApi', @@ -31,7 +29,7 @@ class AssetTreeMixin(RebuildTreeMixin, SerializeToTreeNodeMixin): if request.query_params.get('search'): """ 限制返回数量, 搜索的条件不精准时,会返回大量的无意义数据 """ assets = assets[:999] - data = self.serialize_assets(assets, None) + data = self.serialize_assets(assets, 'root') return Response(data=data) @@ -42,6 +40,7 @@ class UserAllPermedAssetsAsTreeApi(AssetTreeMixin, UserAllPermedAssetsApi): class UserUngroupAssetsAsTreeApi(UserAllPermedAssetsAsTreeApi): """ 用户 '未分组节点的资产(直接授权的资产)' 作为树 """ + def get_assets(self): if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: return super().get_assets() diff --git a/apps/perms/api/user_permission/tree/node_with_asset.py b/apps/perms/api/user_permission/tree/node_with_asset.py index 0289b9d63..17cdd7573 100644 --- a/apps/perms/api/user_permission/tree/node_with_asset.py +++ b/apps/perms/api/user_permission/tree/node_with_asset.py @@ -1,6 +1,4 @@ import abc -import re -from collections import defaultdict from urllib.parse import parse_qsl from django.conf import settings @@ -13,7 +11,6 @@ from rest_framework.response import Response from accounts.const import AliasAccount from assets.api import SerializeToTreeNodeMixin -from assets.const import AllTypes from assets.models import Asset from assets.utils import KubernetesTree from authentication.models import ConnectionToken @@ -38,21 +35,36 @@ class BaseUserNodeWithAssetAsTreeApi( SelfOrPKUserMixin, RebuildTreeMixin, SerializeToTreeNodeMixin, ListAPIView ): + page_limit = 10000 def list(self, request, *args, **kwargs): - nodes, assets = self.get_nodes_assets() - tree_nodes = self.serialize_nodes(nodes, with_asset_amount=True) - tree_assets = self.serialize_assets(assets, node_key=self.node_key_for_serialize_assets) - data = list(tree_nodes) + list(tree_assets) - return Response(data=data) + offset = int(request.query_params.get('offset', 0)) + page_assets = self.get_page_assets() + + if not offset: + nodes, assets = self.get_nodes_assets() + page = page_assets[:self.page_limit] + assets = [*assets, *page] + tree_nodes = self.serialize_nodes(nodes, with_asset_amount=True) + tree_assets = self.serialize_assets(assets, **self.serialize_asset_kwargs) + data = list(tree_nodes) + list(tree_assets) + else: + page = page_assets[offset:(offset + self.page_limit)] + data = self.serialize_assets(page, **self.serialize_asset_kwargs) if page else [] + offset += len(page) + headers = {'X-JMS-TREE-OFFSET': offset} if offset else {} + return Response(data=data, headers=headers) @abc.abstractmethod def get_nodes_assets(self): return [], [] - @lazyproperty - def node_key_for_serialize_assets(self): - return None + def get_page_assets(self): + return [] + + @property + def serialize_asset_kwargs(self): + return {} class UserPermedNodesWithAssetsAsTreeApi(BaseUserNodeWithAssetAsTreeApi): @@ -61,7 +73,6 @@ class UserPermedNodesWithAssetsAsTreeApi(BaseUserNodeWithAssetAsTreeApi): def get_nodes_assets(self): self.query_node_util = UserPermNodeUtil(self.request.user) - self.query_asset_util = UserPermAssetUtil(self.request.user) ung_nodes, ung_assets = self._get_nodes_assets_for_ungrouped() fav_nodes, fav_assets = self._get_nodes_assets_for_favorite() all_nodes, all_assets = self._get_nodes_assets_for_all() @@ -69,31 +80,37 @@ class UserPermedNodesWithAssetsAsTreeApi(BaseUserNodeWithAssetAsTreeApi): assets = list(ung_assets) + list(fav_assets) + list(all_assets) return nodes, assets + def get_page_assets(self): + return self.query_asset_util.get_all_assets().annotate(parent_key=F('nodes__key')) + @timeit def _get_nodes_assets_for_ungrouped(self): if not settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: return [], [] node = self.query_node_util.get_ungrouped_node() assets = self.query_asset_util.get_ungroup_assets() - assets = assets.annotate(parent_key=Value(node.key, output_field=CharField())) \ - .prefetch_related('platform') + assets = assets.annotate(parent_key=Value(node.key, output_field=CharField())) return [node], assets + @lazyproperty + def query_asset_util(self): + return UserPermAssetUtil(self.user) + @timeit def _get_nodes_assets_for_favorite(self): node = self.query_node_util.get_favorite_node() assets = self.query_asset_util.get_favorite_assets() - assets = assets.annotate(parent_key=Value(node.key, output_field=CharField())) \ - .prefetch_related('platform') + assets = assets.annotate(parent_key=Value(node.key, output_field=CharField())) return [node], assets + @timeit def _get_nodes_assets_for_all(self): nodes = self.query_node_util.get_whole_tree_nodes(with_special=False) if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE: assets = self.query_asset_util.get_perm_nodes_assets() else: - assets = self.query_asset_util.get_all_assets() - assets = assets.annotate(parent_key=F('nodes__key')).prefetch_related('platform') + assets = Asset.objects.none() + assets = assets.annotate(parent_key=F('nodes__key')) return nodes, assets @@ -103,6 +120,7 @@ class UserPermedNodeChildrenWithAssetsAsTreeApi(BaseUserNodeWithAssetAsTreeApi): # 默认展开的节点key default_unfolded_node_key = None + @timeit def get_nodes_assets(self): query_node_util = UserPermNodeUtil(self.user) query_asset_util = UserPermAssetUtil(self.user) @@ -136,14 +154,14 @@ class UserPermedNodeChildrenWithAssetsAsTreeApi(BaseUserNodeWithAssetAsTreeApi): node_key = getattr(node, 'key', None) return node_key - @lazyproperty - def node_key_for_serialize_assets(self): - return self.query_node_key or self.default_unfolded_node_key + @property + def serialize_asset_kwargs(self): + return { + 'node_key': self.query_node_key or self.default_unfolded_node_key + } -class UserPermedNodeChildrenWithAssetsAsCategoryTreeApi( - SelfOrPKUserMixin, SerializeToTreeNodeMixin, ListAPIView -): +class UserPermedNodeChildrenWithAssetsAsCategoryTreeApi(BaseUserNodeWithAssetAsTreeApi): @property def is_sync(self): sync = self.request.query_params.get('sync', 0) @@ -151,66 +169,52 @@ class UserPermedNodeChildrenWithAssetsAsCategoryTreeApi( @property def tp(self): - return self.request.query_params.get('type') - - def get_assets(self): - query_asset_util = UserPermAssetUtil(self.user) - node = PermNode.objects.filter( - granted_node_rels__user=self.user, parent_key='').first() - if node: - __, assets = query_asset_util.get_node_all_assets(node.id) - else: - assets = Asset.objects.none() - return assets - - def to_tree_nodes(self, assets): - if not assets: - return [] - assets = assets.annotate(tp=F('platform__type')) - asset_type_map = defaultdict(list) - for asset in assets: - asset_type_map[asset.tp].append(asset) - tp = self.tp - if tp: - assets = asset_type_map.get(tp, []) - if not assets: - return [] - pid = f'ROOT_{str(assets[0].category).upper()}_{tp}' - return self.serialize_assets(assets, pid=pid) params = self.request.query_params - get_root = not list(filter(lambda x: params.get(x), ('type', 'n'))) - resource_platforms = assets.order_by('id').values_list('platform_id', flat=True) - node_all = AllTypes.get_tree_nodes(resource_platforms, get_root=get_root) - pattern = re.compile(r'\(0\)?') - nodes = [] - for node in node_all: - meta = node.get('meta', {}) - if pattern.search(node['name']) or meta.get('type') == 'platform': - continue - _type = meta.get('_type') - if _type: - node['type'] = _type - meta.setdefault('data', {}) - node['meta'] = meta - nodes.append(node) + return [params.get('category'), params.get('type')] - if not self.is_sync: - return nodes + @lazyproperty + def query_asset_util(self): + return UserPermAssetUtil(self.user) - asset_nodes = [] - for node in nodes: - node['open'] = True - tp = node.get('meta', {}).get('_type') - if not tp: - continue - assets = asset_type_map.get(tp, []) - asset_nodes += self.serialize_assets(assets, pid=node['id']) - return nodes + asset_nodes + @timeit + def get_assets(self): + return self.query_asset_util.get_all_assets() - def list(self, request, *args, **kwargs): - assets = self.get_assets() - nodes = self.to_tree_nodes(assets) - return Response(data=nodes) + def _get_tree_nodes_async(self): + if not self.tp or not all(self.tp): + nodes = UserPermAssetUtil.get_type_nodes_tree_or_cached(self.user) + return nodes, [] + + category, tp = self.tp + assets = self.get_assets().filter(platform__type=tp, platform__category=category) + return [], assets + + def _get_tree_nodes_sync(self): + if self.request.query_params.get('lv'): + return [] + nodes = self.query_asset_util.get_type_nodes_tree() + return nodes, [] + + @property + def serialize_asset_kwargs(self): + return { + 'get_pid': lambda asset, platform: 'ROOT_{}_{}'.format(platform.category.upper(), platform.type), + } + + def serialize_nodes(self, nodes, with_asset_amount=False): + return nodes + + def get_nodes_assets(self): + if self.is_sync: + return self._get_tree_nodes_sync() + else: + return self._get_tree_nodes_async() + + def get_page_assets(self): + if self.is_sync: + return self.get_assets() + else: + return [] class UserGrantedK8sAsTreeApi(SelfOrPKUserMixin, ListAPIView): diff --git a/apps/perms/models/asset_permission.py b/apps/perms/models/asset_permission.py index 5ecf824c0..519b0adb8 100644 --- a/apps/perms/models/asset_permission.py +++ b/apps/perms/models/asset_permission.py @@ -8,7 +8,7 @@ from django.utils.translation import gettext_lazy as _ from accounts.const import AliasAccount from accounts.models import Account from assets.models import Asset -from common.utils import date_expired_default +from common.utils import date_expired_default, lazyproperty from common.utils.timezone import local_now from labels.mixins import LabeledMixin from orgs.mixins.models import JMSOrgBaseModel @@ -105,6 +105,22 @@ class AssetPermission(LabeledMixin, JMSOrgBaseModel): return True return False + @lazyproperty + def users_amount(self): + return self.users.count() + + @lazyproperty + def user_groups_amount(self): + return self.user_groups.count() + + @lazyproperty + def assets_amount(self): + return self.assets.count() + + @lazyproperty + def nodes_amount(self): + return self.nodes.count() + def get_all_users(self): from users.models import User user_ids = self.users.all().values_list('id', flat=True) @@ -143,11 +159,14 @@ class AssetPermission(LabeledMixin, JMSOrgBaseModel): @classmethod def get_all_users_for_perms(cls, perm_ids, flat=False): - user_ids = cls.users.through.objects.filter(assetpermission_id__in=perm_ids) \ + user_ids = cls.users.through.objects \ + .filter(assetpermission_id__in=perm_ids) \ .values_list('user_id', flat=True).distinct() - group_ids = cls.user_groups.through.objects.filter(assetpermission_id__in=perm_ids) \ + group_ids = cls.user_groups.through.objects \ + .filter(assetpermission_id__in=perm_ids) \ .values_list('usergroup_id', flat=True).distinct() - group_user_ids = User.groups.through.objects.filter(usergroup_id__in=group_ids) \ + group_user_ids = User.groups.through.objects \ + .filter(usergroup_id__in=group_ids) \ .values_list('user_id', flat=True).distinct() user_ids = set(user_ids) | set(group_user_ids) if flat: diff --git a/apps/perms/serializers/permission.py b/apps/perms/serializers/permission.py index d09c33538..36e0a6f33 100644 --- a/apps/perms/serializers/permission.py +++ b/apps/perms/serializers/permission.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.db.models import Q +from django.db.models import Q, Count from django.utils.translation import gettext_lazy as _ from rest_framework import serializers @@ -14,7 +14,7 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer from perms.models import ActionChoices, AssetPermission from users.models import User, UserGroup -__all__ = ["AssetPermissionSerializer", "ActionChoicesField"] +__all__ = ["AssetPermissionSerializer", "ActionChoicesField", "AssetPermissionListSerializer"] class ActionChoicesField(BitChoicesField): @@ -142,8 +142,8 @@ class AssetPermissionSerializer(ResourceLabelsMixin, BulkOrgResourceModelSeriali def perform_display_create(instance, **kwargs): # 用户 users_to_set = User.objects.filter( - Q(name__in=kwargs.get("users_display")) - | Q(username__in=kwargs.get("users_display")) + Q(name__in=kwargs.get("users_display")) | + Q(username__in=kwargs.get("users_display")) ).distinct() instance.users.add(*users_to_set) # 用户组 @@ -153,8 +153,8 @@ class AssetPermissionSerializer(ResourceLabelsMixin, BulkOrgResourceModelSeriali instance.user_groups.add(*user_groups_to_set) # 资产 assets_to_set = Asset.objects.filter( - Q(address__in=kwargs.get("assets_display")) - | Q(name__in=kwargs.get("assets_display")) + Q(address__in=kwargs.get("assets_display")) | + Q(name__in=kwargs.get("assets_display")) ).distinct() instance.assets.add(*assets_to_set) # 节点 @@ -180,3 +180,26 @@ class AssetPermissionSerializer(ResourceLabelsMixin, BulkOrgResourceModelSeriali instance = super().create(validated_data) self.perform_display_create(instance, **display) return instance + + +class AssetPermissionListSerializer(AssetPermissionSerializer): + users_amount = serializers.IntegerField(read_only=True, label=_("Users amount")) + user_groups_amount = serializers.IntegerField(read_only=True, label=_("User groups amount")) + assets_amount = serializers.IntegerField(read_only=True, label=_("Assets amount")) + nodes_amount = serializers.IntegerField(read_only=True, label=_("Nodes amount")) + + class Meta(AssetPermissionSerializer.Meta): + amount_fields = ["users_amount", "user_groups_amount", "assets_amount", "nodes_amount"] + remove_fields = {"users", "assets", "nodes", "user_groups"} + fields = list(set(AssetPermissionSerializer.Meta.fields + amount_fields) - remove_fields) + + @classmethod + def setup_eager_loading(cls, queryset): + """Perform necessary eager loading of data.""" + queryset = queryset.annotate( + users_amount=Count("users"), + user_groups_amount=Count("user_groups"), + assets_amount=Count("assets"), + nodes_amount=Count("nodes"), + ) + return queryset diff --git a/apps/perms/signal_handlers/refresh_perms.py b/apps/perms/signal_handlers/refresh_perms.py index 88a5fe674..5387bc33f 100644 --- a/apps/perms/signal_handlers/refresh_perms.py +++ b/apps/perms/signal_handlers/refresh_perms.py @@ -3,15 +3,13 @@ from django.db.models.signals import m2m_changed, pre_delete, pre_save, post_save from django.dispatch import receiver -from users.models import User, UserGroup from assets.models import Asset -from common.utils import get_logger, get_object_or_none -from common.exceptions import M2MReverseNotAllowed from common.const.signals import POST_ADD, POST_REMOVE, POST_CLEAR - +from common.exceptions import M2MReverseNotAllowed +from common.utils import get_logger, get_object_or_none from perms.models import AssetPermission from perms.utils import UserPermTreeExpireUtil - +from users.models import User, UserGroup logger = get_logger(__file__) @@ -38,7 +36,7 @@ def on_user_groups_change(sender, instance, action, reverse, pk_set, **kwargs): group = UserGroup.objects.get(id=list(group_ids)[0]) org_id = group.org_id - has_group_perm = AssetPermission.user_groups.through.objects\ + has_group_perm = AssetPermission.user_groups.through.objects \ .filter(usergroup_id__in=group_ids).exists() if not has_group_perm: return @@ -115,6 +113,7 @@ def on_asset_permission_user_groups_changed(sender, instance, action, pk_set, re def on_node_asset_change(action, instance, reverse, pk_set, **kwargs): if not need_rebuild_mapping_node(action): return + print("Asset node changed: ", action) if reverse: asset_ids = pk_set node_ids = [instance.id] diff --git a/apps/perms/utils/permission.py b/apps/perms/utils/permission.py index b9b5b01be..036dabef2 100644 --- a/apps/perms/utils/permission.py +++ b/apps/perms/utils/permission.py @@ -1,8 +1,7 @@ from django.db.models import QuerySet from assets.models import Node, Asset -from common.utils import get_logger - +from common.utils import get_logger, timeit from perms.models import AssetPermission logger = get_logger(__file__) @@ -13,6 +12,7 @@ __all__ = ['AssetPermissionUtil'] class AssetPermissionUtil(object): """ 资产授权相关的方法工具 """ + @timeit def get_permissions_for_user(self, user, with_group=True, flat=False): """ 获取用户的授权规则 """ perm_ids = set() diff --git a/apps/perms/utils/user_perm.py b/apps/perms/utils/user_perm.py index 42d6cc462..0ad02fb25 100644 --- a/apps/perms/utils/user_perm.py +++ b/apps/perms/utils/user_perm.py @@ -1,13 +1,22 @@ -from django.conf import settings -from django.db.models import Q +import json +import re +from django.conf import settings +from django.core.cache import cache +from django.db.models import Q +from rest_framework.utils.encoders import JSONEncoder + +from assets.const import AllTypes from assets.models import FavoriteAsset, Asset -from common.utils.common import timeit +from common.utils.common import timeit, get_logger +from orgs.utils import current_org, tmp_to_root_org from perms.models import PermNode, UserAssetGrantedTreeNodeRelation from .permission import AssetPermissionUtil __all__ = ['AssetPermissionPermAssetUtil', 'UserPermAssetUtil', 'UserPermNodeUtil'] +logger = get_logger(__name__) + class AssetPermissionPermAssetUtil: @@ -16,29 +25,32 @@ class AssetPermissionPermAssetUtil: def get_all_assets(self): """ 获取所有授权的资产 """ - node_asset_ids = self.get_perm_nodes_assets(flat=True) - direct_asset_ids = self.get_direct_assets(flat=True) - asset_ids = list(node_asset_ids) + list(direct_asset_ids) - assets = Asset.objects.filter(id__in=asset_ids) - return assets + node_assets = self.get_perm_nodes_assets() + direct_assets = self.get_direct_assets() + # 比原来的查到所有 asset id 再搜索块很多,因为当资产量大的时候,搜索会很慢 + return (node_assets | direct_assets).distinct() + @timeit def get_perm_nodes_assets(self, flat=False): """ 获取所有授权节点下的资产 """ from assets.models import Node - nodes = Node.objects.prefetch_related('granted_by_permissions').filter( - granted_by_permissions__in=self.perm_ids).only('id', 'key') + nodes = Node.objects \ + .prefetch_related('granted_by_permissions') \ + .filter(granted_by_permissions__in=self.perm_ids) \ + .only('id', 'key') assets = PermNode.get_nodes_all_assets(*nodes) if flat: - return assets.values_list('id', flat=True) + return set(assets.values_list('id', flat=True)) return assets + @timeit def get_direct_assets(self, flat=False): """ 获取直接授权的资产 """ assets = Asset.objects.order_by() \ .filter(granted_by_permissions__id__in=self.perm_ids) \ .distinct() if flat: - return assets.values_list('id', flat=True) + return set(assets.values_list('id', flat=True)) return assets @@ -52,12 +64,62 @@ class UserPermAssetUtil(AssetPermissionPermAssetUtil): def get_ungroup_assets(self): return self.get_direct_assets() + @timeit def get_favorite_assets(self): - assets = self.get_all_assets() + assets = Asset.objects.all().valid() asset_ids = FavoriteAsset.objects.filter(user=self.user).values_list('asset_id', flat=True) assets = assets.filter(id__in=list(asset_ids)) return assets + def get_type_nodes_tree(self): + assets = self.get_all_assets() + resource_platforms = assets.order_by('id').values_list('platform_id', flat=True) + node_all = AllTypes.get_tree_nodes(resource_platforms, get_root=True) + pattern = re.compile(r'\(0\)?') + nodes = [] + for node in node_all: + meta = node.get('meta', {}) + if pattern.search(node['name']) or meta.get('type') == 'platform': + continue + _type = meta.get('_type') + if _type: + node['type'] = _type + node['category'] = meta.get('category') + meta.setdefault('data', {}) + node['meta'] = meta + nodes.append(node) + return nodes + + @classmethod + def get_type_nodes_tree_or_cached(cls, user): + key = f'perms:type-nodes-tree:{user.id}:{current_org.id}' + nodes = cache.get(key) + if nodes is None: + nodes = cls(user).get_type_nodes_tree() + nodes_json = json.dumps(nodes, cls=JSONEncoder) + cache.set(key, nodes_json, 60 * 60 * 24) + else: + nodes = json.loads(nodes) + return nodes + + def refresh_type_nodes_tree_cache(self): + logger.debug("Refresh type nodes tree cache") + key = f'perms:type-nodes-tree:{self.user.id}:{current_org.id}' + cache.delete(key) + + def refresh_favorite_assets(self): + favor_ids = FavoriteAsset.objects.filter(user=self.user).values_list('asset_id', flat=True) + favor_ids = set(favor_ids) + + with tmp_to_root_org(): + valid_ids = self.get_all_assets() \ + .filter(id__in=favor_ids) \ + .values_list('id', flat=True) + valid_ids = set(valid_ids) + + invalid_ids = favor_ids - valid_ids + FavoriteAsset.objects.filter(user=self.user, asset_id__in=invalid_ids).delete() + def get_node_assets(self, key): node = PermNode.objects.get(key=key) node.compute_node_from_and_assets_amount(self.user) @@ -134,7 +196,11 @@ class UserPermNodeUtil: self.perm_ids = AssetPermissionUtil().get_permissions_for_user(self.user, flat=True) def get_favorite_node(self): - assets_amount = UserPermAssetUtil(self.user).get_favorite_assets().count() + favor_ids = FavoriteAsset.objects \ + .filter(user=self.user) \ + .values_list('asset_id') \ + .distinct() + assets_amount = Asset.objects.all().valid().filter(id__in=favor_ids).count() return PermNode.get_favorite_node(assets_amount) def get_ungrouped_node(self): diff --git a/apps/perms/utils/user_perm_tree.py b/apps/perms/utils/user_perm_tree.py index b88b6db26..13577a9b1 100644 --- a/apps/perms/utils/user_perm_tree.py +++ b/apps/perms/utils/user_perm_tree.py @@ -3,11 +3,12 @@ from collections import defaultdict from django.conf import settings from django.core.cache import cache +from django.db import transaction from assets.models import Asset from assets.utils import NodeAssetsUtil from common.db.models import output_as_string -from common.decorators import on_transaction_commit +from common.decorators import on_transaction_commit, merge_delay_run from common.utils import get_logger from common.utils.common import lazyproperty, timeit from orgs.models import Organization @@ -23,6 +24,7 @@ from perms.models import ( PermNode ) from users.models import User +from . import UserPermAssetUtil from .permission import AssetPermissionUtil logger = get_logger(__name__) @@ -50,24 +52,74 @@ class UserPermTreeRefreshUtil(_UserPermTreeCacheMixin): def __init__(self, user): self.user = user - self.orgs = self.user.orgs.distinct() - self.org_ids = [str(o.id) for o in self.orgs] + + @lazyproperty + def orgs(self): + return self.user.orgs.distinct() + + @lazyproperty + def org_ids(self): + return [str(o.id) for o in self.orgs] @lazyproperty def cache_key_user(self): return self.get_cache_key(self.user.id) + @lazyproperty + def cache_key_time(self): + key = 'perms.user.node_tree.built_time.{}'.format(self.user.id) + return key + @timeit def refresh_if_need(self, force=False): - self._clean_user_perm_tree_for_legacy_org() + built_just_now = cache.get(self.cache_key_time) + if built_just_now: + logger.info('Refresh user perm tree just now, pass: {}'.format(built_just_now)) + return to_refresh_orgs = self.orgs if force else self._get_user_need_refresh_orgs() if not to_refresh_orgs: logger.info('Not have to refresh orgs') return - with UserGrantedTreeRebuildLock(self.user.id): + logger.info("Delay refresh user orgs: {} {}".format(self.user, [o.name for o in to_refresh_orgs])) + refresh_user_orgs_perm_tree(user_orgs=((self.user, tuple(to_refresh_orgs)),)) + refresh_user_favorite_assets(users=(self.user,)) + + @timeit + def refresh_tree_manual(self): + built_just_now = cache.get(self.cache_key_time) + if built_just_now: + logger.info('Refresh just now, pass: {}'.format(built_just_now)) + return + to_refresh_orgs = self._get_user_need_refresh_orgs() + if not to_refresh_orgs: + logger.info('Not have to refresh orgs for user: {}'.format(self.user)) + return + self.perform_refresh_user_tree(to_refresh_orgs) + + @timeit + def perform_refresh_user_tree(self, to_refresh_orgs): + # 再判断一次,毕竟构建树比较慢 + built_just_now = cache.get(self.cache_key_time) + if built_just_now: + logger.info('Refresh user perm tree just now, pass: {}'.format(built_just_now)) + return + + self._clean_user_perm_tree_for_legacy_org() + ttl = settings.PERM_TREE_REGEN_INTERVAL + cache.set(self.cache_key_time, int(time.time()), ttl) + + lock = UserGrantedTreeRebuildLock(self.user.id) + got = lock.acquire(blocking=False) + if not got: + logger.info('User perm tree rebuild lock not acquired, pass') + return + + try: for org in to_refresh_orgs: self._rebuild_user_perm_tree_for_org(org) - self._mark_user_orgs_refresh_finished(to_refresh_orgs) + self._mark_user_orgs_refresh_finished(to_refresh_orgs) + finally: + lock.release() def _rebuild_user_perm_tree_for_org(self, org): with tmp_to_org(org): @@ -75,7 +127,7 @@ class UserPermTreeRefreshUtil(_UserPermTreeCacheMixin): UserPermTreeBuildUtil(self.user).rebuild_user_perm_tree() end = time.time() logger.info( - 'Refresh user [{user}] org [{org}] perm tree, user {use_time:.2f}s' + 'Refresh user perm tree: [{user}] org [{org}] {use_time:.2f}s' ''.format(user=self.user, org=org, use_time=end - start) ) @@ -90,7 +142,7 @@ class UserPermTreeRefreshUtil(_UserPermTreeCacheMixin): cached_org_ids = self.client.smembers(self.cache_key_user) cached_org_ids = {oid.decode() for oid in cached_org_ids} to_refresh_org_ids = set(self.org_ids) - cached_org_ids - to_refresh_orgs = Organization.objects.filter(id__in=to_refresh_org_ids) + to_refresh_orgs = list(Organization.objects.filter(id__in=to_refresh_org_ids)) logger.info(f'Need to refresh orgs: {to_refresh_orgs}') return to_refresh_orgs @@ -128,7 +180,8 @@ class UserPermTreeExpireUtil(_UserPermTreeCacheMixin): self.expire_perm_tree_for_user_groups_orgs(group_ids, org_ids) def expire_perm_tree_for_user_groups_orgs(self, group_ids, org_ids): - user_ids = User.groups.through.objects.filter(usergroup_id__in=group_ids) \ + user_ids = User.groups.through.objects \ + .filter(usergroup_id__in=group_ids) \ .values_list('user_id', flat=True).distinct() self.expire_perm_tree_for_users_orgs(user_ids, org_ids) @@ -151,6 +204,21 @@ class UserPermTreeExpireUtil(_UserPermTreeCacheMixin): logger.info('Expire all user perm tree') +@merge_delay_run(ttl=20) +def refresh_user_orgs_perm_tree(user_orgs=()): + for user, orgs in user_orgs: + util = UserPermTreeRefreshUtil(user) + util.perform_refresh_user_tree(orgs) + + +@merge_delay_run(ttl=20) +def refresh_user_favorite_assets(users=()): + for user in users: + util = UserPermAssetUtil(user) + util.refresh_favorite_assets() + util.refresh_type_nodes_tree_cache() + + class UserPermTreeBuildUtil(object): node_only_fields = ('id', 'key', 'parent_key', 'org_id') @@ -161,13 +229,14 @@ class UserPermTreeBuildUtil(object): self._perm_nodes_key_node_mapper = {} def rebuild_user_perm_tree(self): - self.clean_user_perm_tree() - if not self.user_perm_ids: - logger.info('User({}) not have permissions'.format(self.user)) - return - self.compute_perm_nodes() - self.compute_perm_nodes_asset_amount() - self.create_mapping_nodes() + with transaction.atomic(): + self.clean_user_perm_tree() + if not self.user_perm_ids: + logger.info('User({}) not have permissions'.format(self.user)) + return + self.compute_perm_nodes() + self.compute_perm_nodes_asset_amount() + self.create_mapping_nodes() def clean_user_perm_tree(self): UserAssetGrantedTreeNodeRelation.objects.filter(user=self.user).delete() diff --git a/apps/rbac/permissions.py b/apps/rbac/permissions.py index 7c3f21610..cffc22e71 100644 --- a/apps/rbac/permissions.py +++ b/apps/rbac/permissions.py @@ -139,7 +139,7 @@ class RBACPermission(permissions.DjangoModelPermissions): if isinstance(perms, str): perms = [perms] has = request.user.has_perms(perms) - logger.debug('View require perms: {}, result: {}'.format(perms, has)) + logger.debug('Api require perms: {}, result: {}'.format(perms, has)) return has def has_object_permission(self, request, view, obj): diff --git a/apps/users/api/group.py b/apps/users/api/group.py index 6cccfb4a2..1e34a7caa 100644 --- a/apps/users/api/group.py +++ b/apps/users/api/group.py @@ -6,7 +6,7 @@ from rest_framework.response import Response from orgs.mixins.api import OrgBulkModelViewSet from ..models import UserGroup, User -from ..serializers import UserGroupSerializer +from ..serializers import UserGroupSerializer, UserGroupListSerializer __all__ = ['UserGroupViewSet'] @@ -15,7 +15,10 @@ class UserGroupViewSet(OrgBulkModelViewSet): model = UserGroup filterset_fields = ("name",) search_fields = filterset_fields - serializer_class = UserGroupSerializer + serializer_classes = { + 'default': UserGroupSerializer, + 'list': UserGroupListSerializer, + } ordering = ('name',) rbac_perms = ( ("add_all_users", "users.add_usergroup"), diff --git a/apps/users/serializers/group.py b/apps/users/serializers/group.py index 2276b6e0e..b87ba4a0e 100644 --- a/apps/users/serializers/group.py +++ b/apps/users/serializers/group.py @@ -2,6 +2,7 @@ # from django.db.models import Count from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers from common.serializers.fields import ObjectRelatedField from common.serializers.mixin import ResourceLabelsMixin @@ -10,7 +11,7 @@ from .. import utils from ..models import User, UserGroup __all__ = [ - 'UserGroupSerializer', + 'UserGroupSerializer', 'UserGroupListSerializer', ] @@ -29,7 +30,6 @@ class UserGroupSerializer(ResourceLabelsMixin, BulkOrgResourceModelSerializer): fields = fields_mini + fields_small + ['users', 'labels'] extra_kwargs = { 'created_by': {'label': _('Created by'), 'read_only': True}, - 'users_amount': {'label': _('Users amount')}, 'id': {'label': _('ID')}, } @@ -45,6 +45,17 @@ class UserGroupSerializer(ResourceLabelsMixin, BulkOrgResourceModelSerializer): @classmethod def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ - queryset = queryset.prefetch_related('users', 'labels', 'labels__label') \ + queryset = queryset.prefetch_related('labels', 'labels__label') \ .annotate(users_amount=Count('users')) return queryset + + +class UserGroupListSerializer(UserGroupSerializer): + users_amount = serializers.IntegerField(label=_('Users amount'), read_only=True) + + class Meta(UserGroupSerializer.Meta): + fields = list(set(UserGroupSerializer.Meta.fields + ['users_amount']) - {'users'}) + extra_kwargs = { + **UserGroupSerializer.Meta.extra_kwargs, + 'users_amount': {'label': _('Users amount')}, + } diff --git a/utils/generate_fake_data/generate.py b/utils/generate_fake_data/generate.py index 0931cca8f..cda1bbaed 100644 --- a/utils/generate_fake_data/generate.py +++ b/utils/generate_fake_data/generate.py @@ -17,6 +17,7 @@ from resources.assets import AssetsGenerator, NodesGenerator, PlatformGenerator from resources.users import UserGroupGenerator, UserGenerator from resources.perms import AssetPermissionGenerator from resources.terminal import CommandGenerator, SessionGenerator +from resources.accounts import AccountGenerator resource_generator_mapper = { 'asset': AssetsGenerator, @@ -27,6 +28,7 @@ resource_generator_mapper = { 'asset_permission': AssetPermissionGenerator, 'command': CommandGenerator, 'session': SessionGenerator, + 'account': AccountGenerator, 'all': None # 'stat': StatGenerator } @@ -45,6 +47,7 @@ def main(): parser.add_argument('-o', '--org', type=str, default='') args = parser.parse_args() resource, count, batch_size, org_id = args.resource, args.count, args.batch_size, args.org + resource = resource.lower().rstrip('s') generator_cls = [] if resource == 'all': diff --git a/utils/generate_fake_data/resources/accounts.py b/utils/generate_fake_data/resources/accounts.py new file mode 100644 index 000000000..9b0fc75d5 --- /dev/null +++ b/utils/generate_fake_data/resources/accounts.py @@ -0,0 +1,32 @@ +import random + +import forgery_py + +from accounts.models import Account +from assets.models import Asset +from .base import FakeDataGenerator + + +class AccountGenerator(FakeDataGenerator): + resource = 'account' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.assets = list(list(Asset.objects.all()[:5000])) + + def do_generate(self, batch, batch_size): + accounts = [] + for i in batch: + asset = random.choice(self.assets) + name = forgery_py.internet.user_name(True) + '-' + str(i) + d = { + 'username': name, + 'name': name, + 'asset': asset, + 'secret': name, + 'secret_type': 'password', + 'is_active': True, + 'privileged': False, + } + accounts.append(Account(**d)) + Account.objects.bulk_create(accounts, ignore_conflicts=True) diff --git a/utils/generate_fake_data/resources/assets.py b/utils/generate_fake_data/resources/assets.py index 517122c9b..a8e3ce239 100644 --- a/utils/generate_fake_data/resources/assets.py +++ b/utils/generate_fake_data/resources/assets.py @@ -48,7 +48,7 @@ class AssetsGenerator(FakeDataGenerator): def pre_generate(self): self.node_ids = list(Node.objects.all().values_list('id', flat=True)) - self.platform_ids = list(Platform.objects.all().values_list('id', flat=True)) + self.platform_ids = list(Platform.objects.filter(category='host').values_list('id', flat=True)) def set_assets_nodes(self, assets): for asset in assets: @@ -72,6 +72,17 @@ class AssetsGenerator(FakeDataGenerator): assets.append(Asset(**data)) creates = Asset.objects.bulk_create(assets, ignore_conflicts=True) self.set_assets_nodes(creates) + self.set_asset_platform(creates) + + @staticmethod + def set_asset_platform(assets): + protocol = random.choice(['ssh', 'rdp', 'telnet', 'vnc']) + protocols = [] + + for asset in assets: + port = 22 if protocol == 'ssh' else 3389 + protocols.append(Protocol(asset=asset, name=protocol, port=port)) + Protocol.objects.bulk_create(protocols, ignore_conflicts=True) def after_generate(self): pass diff --git a/utils/generate_fake_data/resources/base.py b/utils/generate_fake_data/resources/base.py index 39942d5f1..dd02c65f7 100644 --- a/utils/generate_fake_data/resources/base.py +++ b/utils/generate_fake_data/resources/base.py @@ -41,7 +41,7 @@ class FakeDataGenerator: start = time.time() self.do_generate(batch, self.batch_size) end = time.time() - using = end - start + using = round(end - start, 3) from_size = created created += len(batch) print('Generate %s: %s-%s [%s]' % (self.resource, from_size, created, using)) diff --git a/utils/generate_fake_data/resources/users.py b/utils/generate_fake_data/resources/users.py index c05e0793b..5ed159b53 100644 --- a/utils/generate_fake_data/resources/users.py +++ b/utils/generate_fake_data/resources/users.py @@ -1,9 +1,11 @@ -from random import choice, sample +from random import sample + import forgery_py -from .base import FakeDataGenerator - +from orgs.utils import current_org +from rbac.models import RoleBinding, Role from users.models import * +from .base import FakeDataGenerator class UserGroupGenerator(FakeDataGenerator): @@ -47,3 +49,12 @@ class UserGenerator(FakeDataGenerator): users.append(u) users = User.objects.bulk_create(users, ignore_conflicts=True) self.set_groups(users) + self.set_to_org(users) + + def set_to_org(self, users): + bindings = [] + role = Role.objects.get(name='OrgUser') + for u in users: + b = RoleBinding(user=u, role=role, org_id=current_org.id, scope='org') + bindings.append(b) + RoleBinding.objects.bulk_create(bindings, ignore_conflicts=True) From 4dd72b109f1ec06c86bde7053c81d59c29aff254 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Tue, 2 Jan 2024 19:07:58 +0800 Subject: [PATCH 07/41] =?UTF-8?q?feat:=20=E5=8E=86=E5=8F=B2=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E5=AE=9A=E6=9C=9F=E5=88=A0=E9=99=A4=20=E5=8F=AF?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=BF=9D=E7=95=99=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/tasks/remove_account.py | 48 ++++++++++++++++++++++++++- apps/jumpserver/conf.py | 2 ++ apps/jumpserver/settings/auth.py | 2 ++ apps/settings/serializers/feature.py | 11 ++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/apps/accounts/tasks/remove_account.py b/apps/accounts/tasks/remove_account.py index 269a7f349..44bb9a840 100644 --- a/apps/accounts/tasks/remove_account.py +++ b/apps/accounts/tasks/remove_account.py @@ -1,9 +1,19 @@ -from celery import shared_task +import uuid +from collections import defaultdict + +from celery import shared_task, current_task +from django.conf import settings +from django.db.models import Count from django.utils.translation import gettext_noop, gettext_lazy as _ from accounts.const import AutomationTypes +from accounts.models import Account from accounts.tasks.common import quickstart_automation_by_snapshot +from audits.const import ActivityChoices +from common.const.crontab import CRONTAB_AT_AM_TWO from common.utils import get_logger +from ops.celery.decorator import register_as_period_task +from orgs.utils import tmp_to_root_org logger = get_logger(__file__) @@ -29,3 +39,39 @@ def remove_accounts_task(gather_account_ids): tp = AutomationTypes.remove_account quickstart_automation_by_snapshot(task_name, tp, task_snapshot) + + +@shared_task(verbose_name=_('Clean historical accounts')) +@register_as_period_task(crontab=CRONTAB_AT_AM_TWO) +@tmp_to_root_org() +def clean_historical_accounts(): + from audits.signal_handlers import create_activities + print("Clean historical accounts start.") + if settings.HISTORY_ACCOUNT_CLEAN_LIMIT >= 999: + return + limit = settings.HISTORY_ACCOUNT_CLEAN_LIMIT + + history_ids_to_be_deleted = [] + history_model = Account.history.model + history_id_mapper = defaultdict(list) + + ids = history_model.objects.values('id').annotate(count=Count('id')) \ + .filter(count__gte=limit).values_list('id', flat=True) + + if not ids: + return + + for i in history_model.objects.filter(id__in=ids): + _id = str(i.id) + history_id_mapper[_id].append(i.history_id) + + for history_ids in history_id_mapper.values(): + history_ids_to_be_deleted.extend(history_ids[limit:]) + history_qs = history_model.objects.filter(history_id__in=history_ids_to_be_deleted) + + resource_ids = list(history_qs.values_list('history_id', flat=True)) + history_qs.delete() + + task_id = current_task.request.id if current_task else str(uuid.uuid4()) + detail = gettext_noop('Remove historical accounts that are out of range.') + create_activities(resource_ids, detail, task_id, action=ActivityChoices.task, org_id='') diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 60e3dfd0c..f5f5d5d0c 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -261,6 +261,8 @@ class Config(dict): 'VAULT_HCP_TOKEN': '', 'VAULT_HCP_MOUNT_POINT': 'jumpserver', + 'HISTORY_ACCOUNT_CLEAN_LIMIT': 999, + # Cache login password 'CACHE_LOGIN_PASSWORD_ENABLED': False, 'CACHE_LOGIN_PASSWORD_TTL': 60 * 60 * 24, diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index 94c45b135..ff26efd19 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -190,6 +190,8 @@ VAULT_HCP_HOST = CONFIG.VAULT_HCP_HOST VAULT_HCP_TOKEN = CONFIG.VAULT_HCP_TOKEN VAULT_HCP_MOUNT_POINT = CONFIG.VAULT_HCP_MOUNT_POINT +HISTORY_ACCOUNT_CLEAN_LIMIT = CONFIG.HISTORY_ACCOUNT_CLEAN_LIMIT + # Other setting # 这个是 User Login Private Token TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION diff --git a/apps/settings/serializers/feature.py b/apps/settings/serializers/feature.py index 083e2749a..07a3dbcd6 100644 --- a/apps/settings/serializers/feature.py +++ b/apps/settings/serializers/feature.py @@ -55,6 +55,17 @@ class VaultSettingSerializer(serializers.Serializer): max_length=256, allow_blank=True, required=False, label=_('Mount Point') ) + HISTORY_ACCOUNT_CLEAN_LIMIT = serializers.IntegerField( + default=999, max_value=999, min_value=1, + required=False, label=_('History Account Count'), + help_text=_( + 'If the specific value is less than 999, ' + 'the system will automatically perform a task every night: ' + 'check and delete historical accounts that exceed the predetermined number. ' + 'If the value reaches or exceeds 999, no historical account deletion will be performed.' + ) + ) + class ChatAISettingSerializer(serializers.Serializer): PREFIX_TITLE = _('Chat AI') From eb5a53b91bfe79b11291bbb2f869624af40cfcf3 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 3 Jan 2024 11:25:45 +0800 Subject: [PATCH 08/41] =?UTF-8?q?perf:=20=E7=BF=BB=E8=AF=91=20(#12487)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 206 ++++++++++++++++----------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 205 +++++++++++++++----------- apps/settings/serializers/feature.py | 2 +- 5 files changed, 246 insertions(+), 175 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 50e4479af..169dd1e30 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71d292647cf751c002b459449c7bebf4d2bf5a3933748387e7c2f80a7111302e -size 169602 +oid sha256:d8f3d621226f7e11db46fb35abf0b5f5528eb454a3a6f889499d7872d41a275d +size 170675 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 92d6c4552..b566534c4 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-26 14:13+0800\n" +"POT-Creation-Date: 2024-01-03 11:23+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -115,8 +115,8 @@ msgstr "パスワードを変更する" msgid "Verify account" msgstr "アカウントを確認" -#: accounts/const/automation.py:27 accounts/tasks/remove_account.py:14 -#: accounts/tasks/remove_account.py:23 +#: accounts/const/automation.py:27 accounts/tasks/remove_account.py:24 +#: accounts/tasks/remove_account.py:33 msgid "Remove account" msgstr "アカウントの削除" @@ -248,8 +248,7 @@ msgstr "ユーザー %s がパスワードを閲覧/導き出しました" #: accounts/templates/accounts/asset_account_change_info.html:7 #: acls/serializers/base.py:123 assets/models/asset/common.py:95 #: assets/models/asset/common.py:350 assets/models/cmd_filter.py:36 -#: assets/serializers/domain.py:20 audits/models.py:58 -#: authentication/models/connection_token.py:36 +#: audits/models.py:58 authentication/models/connection_token.py:36 #: perms/models/asset_permission.py:69 perms/serializers/permission.py:36 #: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 #: terminal/notifications.py:155 terminal/serializers/command.py:17 @@ -510,9 +509,8 @@ msgstr "最終ログイン日" #: accounts/models/automations/gather_account.py:17 #: accounts/models/automations/push_account.py:15 accounts/models/base.py:65 #: accounts/serializers/account/virtual.py:21 acls/serializers/base.py:19 -#: acls/serializers/base.py:50 acls/templates/acls/asset_login_reminder.html:5 -#: acls/templates/acls/user_login_reminder.html:5 assets/models/_user.py:23 -#: audits/models.py:188 authentication/forms.py:25 authentication/forms.py:27 +#: acls/serializers/base.py:50 assets/models/_user.py:23 audits/models.py:188 +#: authentication/forms.py:25 authentication/forms.py:27 #: authentication/models/temp_token.py:9 #: authentication/templates/authentication/_msg_different_city.html:9 #: authentication/templates/authentication/_msg_oauth_bind.html:9 @@ -813,11 +811,13 @@ msgstr "アカウントはすでに存在しています" #: accounts/serializers/account/account.py:441 #: authentication/serializers/connect_token_secret.py:159 #: authentication/templates/authentication/_access_key_modal.html:30 -#: perms/models/perm_node.py:21 users/serializers/group.py:32 +#: perms/models/perm_node.py:21 users/serializers/group.py:33 msgid "ID" msgstr "ID" #: accounts/serializers/account/account.py:451 acls/serializers/base.py:116 +#: acls/templates/acls/asset_login_reminder.html:5 +#: acls/templates/acls/user_login_reminder.html:5 #: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:54 #: audits/models.py:90 audits/models.py:172 audits/models.py:269 #: audits/serializers.py:171 authentication/models/connection_token.py:32 @@ -831,8 +831,8 @@ msgstr "ID" #: terminal/notifications.py:205 terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: terminal/templates/terminal/_msg_session_sharing.html:6 -#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:1003 -#: users/models/user.py:1040 users/serializers/group.py:19 +#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:1004 +#: users/models/user.py:1041 users/serializers/group.py:21 msgid "User" msgstr "ユーザー" @@ -1019,6 +1019,14 @@ msgstr "資産の口座番号を収集する" msgid "Push accounts to assets" msgstr "アカウントをアセットにプッシュ:" +#: accounts/tasks/remove_account.py:44 +msgid "Clean historical accounts" +msgstr "過去のアカウントをクリアする" + +#: accounts/tasks/remove_account.py:76 +msgid "Remove historical accounts that are out of range." +msgstr "範囲外の履歴アカウントを削除する" + #: accounts/tasks/template.py:11 msgid "Template sync info to related accounts" msgstr "関連するアカウントへの情報の同期" @@ -1191,7 +1199,7 @@ msgstr "ログインasset acl" msgid "Login asset confirm" msgstr "ログイン資産の確認" -#: acls/notifications.py:11 +#: acls/notifications.py:12 msgid "User login reminder" msgstr "ユーザーログインのリマインダ" @@ -1312,13 +1320,13 @@ msgstr "アプリケーション" msgid "Can match application" msgstr "アプリケーションを一致させることができます" -#: assets/api/asset/asset.py:182 +#: assets/api/asset/asset.py:179 msgid "Cannot create asset directly, you should create a host or other" msgstr "" "資産を直接作成することはできません。ホストまたはその他を作成する必要がありま" "す" -#: assets/api/domain.py:63 +#: assets/api/domain.py:64 msgid "Number required" msgstr "必要な数" @@ -1617,7 +1625,7 @@ msgstr "SSHパブリックキー" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 #: audits/models.py:267 common/db/models.py:34 ops/models/base.py:54 -#: ops/models/job.py:234 users/models/user.py:1041 +#: ops/models/job.py:234 users/models/user.py:1042 msgid "Date created" msgstr "作成された日付" @@ -1629,7 +1637,7 @@ msgstr "更新日" #: assets/models/_user.py:30 assets/models/cmd_filter.py:44 #: assets/models/cmd_filter.py:91 assets/models/group.py:18 #: common/db/models.py:32 users/models/user.py:843 -#: users/serializers/group.py:30 +#: users/serializers/group.py:32 msgid "Created by" msgstr "によって作成された" @@ -1731,7 +1739,7 @@ msgid "Domain" msgstr "ドメイン" #: assets/models/asset/common.py:165 assets/models/automations/base.py:18 -#: assets/models/cmd_filter.py:32 assets/models/node.py:553 +#: assets/models/cmd_filter.py:32 assets/models/node.py:546 #: perms/models/asset_permission.py:72 perms/serializers/permission.py:37 #: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:330 msgid "Node" @@ -1782,7 +1790,7 @@ msgstr "クライアントキー" msgid "Allow invalid cert" msgstr "証明書チェックを無視" -#: assets/models/asset/gpt.py:8 settings/serializers/feature.py:73 +#: assets/models/asset/gpt.py:8 settings/serializers/feature.py:84 msgid "Proxy" msgstr "プロキシー" @@ -1849,7 +1857,7 @@ msgstr "コマンドフィルタルール" msgid "Favorite asset" msgstr "お気に入りのアセット" -#: assets/models/gateway.py:34 assets/serializers/domain.py:17 +#: assets/models/gateway.py:34 assets/serializers/domain.py:18 msgid "Gateway" msgstr "ゲートウェイ" @@ -1867,11 +1875,11 @@ msgstr "デフォルト" msgid "Default asset group" msgstr "デフォルトアセットグループ" -#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:1026 +#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:1027 msgid "System" msgstr "システム" -#: assets/models/label.py:19 assets/models/node.py:539 +#: assets/models/label.py:19 assets/models/node.py:532 #: assets/serializers/cagegory.py:11 assets/serializers/cagegory.py:18 #: assets/serializers/cagegory.py:24 #: authentication/models/connection_token.py:29 @@ -1894,23 +1902,23 @@ msgstr "ラベル" msgid "New node" msgstr "新しいノード" -#: assets/models/node.py:467 audits/backends/db.py:65 audits/backends/db.py:66 +#: assets/models/node.py:460 audits/backends/db.py:65 audits/backends/db.py:66 msgid "empty" msgstr "空" -#: assets/models/node.py:538 perms/models/perm_node.py:28 +#: assets/models/node.py:531 perms/models/perm_node.py:28 msgid "Key" msgstr "キー" -#: assets/models/node.py:540 assets/serializers/node.py:20 +#: assets/models/node.py:533 assets/serializers/node.py:20 msgid "Full value" msgstr "フルバリュー" -#: assets/models/node.py:544 perms/models/perm_node.py:30 +#: assets/models/node.py:537 perms/models/perm_node.py:30 msgid "Parent key" msgstr "親キー" -#: assets/models/node.py:556 +#: assets/models/node.py:549 msgid "Can match node" msgstr "ノードを一致させることができます" @@ -2170,6 +2178,10 @@ msgstr "制約" msgid "Types" msgstr "タイプ" +#: assets/serializers/domain.py:53 perms/serializers/permission.py:188 +msgid "Assets amount" +msgstr "資産数量" + #: assets/serializers/gateway.py:23 common/validators.py:34 msgid "This field must be unique." msgstr "このフィールドは一意である必要があります。" @@ -3035,7 +3047,7 @@ msgstr "電話番号を設定して有効にする" msgid "Clear phone number to disable" msgstr "無効にする電話番号をクリアする" -#: authentication/middleware.py:94 settings/utils/ldap.py:677 +#: authentication/middleware.py:94 settings/utils/ldap.py:676 msgid "Authentication failed (before login check failed): {}" msgstr "認証に失敗しました (ログインチェックが失敗する前): {}" @@ -3297,7 +3309,7 @@ msgstr "コードエラー" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:455 +#: jumpserver/conf.py:457 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:32 @@ -3938,16 +3950,16 @@ msgstr "特殊文字を含むべきではない" msgid "The mobile phone number format is incorrect" msgstr "携帯電話番号の形式が正しくありません" -#: jumpserver/conf.py:450 +#: jumpserver/conf.py:452 #, python-brace-format msgid "The verification code is: {code}" msgstr "認証コードは: {code}" -#: jumpserver/conf.py:454 +#: jumpserver/conf.py:456 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:456 +#: jumpserver/conf.py:458 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -4587,7 +4599,7 @@ msgid "today" msgstr "今日" #: perms/notifications.py:12 perms/notifications.py:44 -#: settings/serializers/feature.py:106 +#: settings/serializers/feature.py:117 msgid "day" msgstr "日" @@ -4607,6 +4619,19 @@ msgstr "資産権限の有効期限が近づいています" msgid "asset permissions of organization {}" msgstr "組織 {} の資産権限" +#: perms/serializers/permission.py:186 rbac/serializers/role.py:27 +#: users/serializers/group.py:54 users/serializers/group.py:60 +msgid "Users amount" +msgstr "ユーザー数" + +#: perms/serializers/permission.py:187 +msgid "User groups amount" +msgstr "ユーザーグループの数" + +#: perms/serializers/permission.py:189 +msgid "Nodes amount" +msgstr "ノード数" + #: perms/tasks.py:27 msgid "Check asset permission expired" msgstr "アセット認証ルールの有効期限が切れていることを確認する" @@ -4748,10 +4773,6 @@ msgstr "システムロールバインディング" msgid "Perms" msgstr "パーマ" -#: rbac/serializers/role.py:27 users/serializers/group.py:31 -msgid "Users amount" -msgstr "ユーザー数" - #: rbac/serializers/role.py:28 terminal/models/applet/applet.py:34 #: terminal/models/virtualapp/virtualapp.py:20 msgid "Display name" @@ -4823,7 +4844,7 @@ msgstr "リモートアプリケーション" msgid "Ticket comment" msgstr "チケットコメント" -#: rbac/tree.py:130 settings/serializers/feature.py:98 +#: rbac/tree.py:130 settings/serializers/feature.py:109 #: tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "チケット" @@ -5525,62 +5546,77 @@ msgid "Mount Point" msgstr "マウントポイント" #: settings/serializers/feature.py:60 +msgid "Historical accounts retained count" +msgstr "保持されている過去のアカウントの数" + +#: settings/serializers/feature.py:62 +msgid "" +"If the specific value is less than 999, the system will automatically " +"perform a task every night: check and delete historical accounts that exceed " +"the predetermined number. If the value reaches or exceeds 999, no historical " +"account deletion will be performed." +msgstr "" +"特定の値が 999 未満の場合、システムは毎晩自動的にタスクを実行します。つまり、" +"所定の数を超える履歴アカウントを確認して削除します。 値が 999 以上の場合、履" +"歴アカウントの削除は実行されません。" + +#: settings/serializers/feature.py:71 msgid "Chat AI" msgstr "チャットAI" -#: settings/serializers/feature.py:64 +#: settings/serializers/feature.py:75 msgid "Enable Chat AI" msgstr "チャットAIを起動する" -#: settings/serializers/feature.py:67 +#: settings/serializers/feature.py:78 msgid "Base Url" msgstr "基本的なUrl" -#: settings/serializers/feature.py:70 templates/_header_bar.html:90 +#: settings/serializers/feature.py:81 templates/_header_bar.html:90 msgid "API Key" msgstr "API Key" -#: settings/serializers/feature.py:76 +#: settings/serializers/feature.py:87 msgid "GPT Model" msgstr "GPTモデル" -#: settings/serializers/feature.py:100 +#: settings/serializers/feature.py:111 msgid "Enable tickets" msgstr "チケットを有効にする" -#: settings/serializers/feature.py:103 +#: settings/serializers/feature.py:114 msgid "Ticket authorize default time" msgstr "デフォルト製造オーダ承認時間" -#: settings/serializers/feature.py:106 +#: settings/serializers/feature.py:117 msgid "hour" msgstr "時" -#: settings/serializers/feature.py:107 +#: settings/serializers/feature.py:118 msgid "Ticket authorize default time unit" msgstr "デフォルト製造オーダ承認時間単位" -#: settings/serializers/feature.py:112 +#: settings/serializers/feature.py:123 msgid "Feature" msgstr "機能" -#: settings/serializers/feature.py:115 +#: settings/serializers/feature.py:126 msgid "Operation center" msgstr "職業センター" -#: settings/serializers/feature.py:116 +#: settings/serializers/feature.py:127 msgid "Allow user run batch command or not using ansible" msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" -#: settings/serializers/feature.py:120 +#: settings/serializers/feature.py:131 msgid "Operation center command blacklist" msgstr "オペレーション センター コマンド ブラックリスト" -#: settings/serializers/feature.py:121 +#: settings/serializers/feature.py:132 msgid "Commands that are not allowed execute." msgstr "実行が許可されていないコマンド" -#: settings/serializers/feature.py:126 +#: settings/serializers/feature.py:137 #: terminal/models/virtualapp/provider.py:17 #: terminal/models/virtualapp/virtualapp.py:36 #: terminal/models/virtualapp/virtualapp.py:97 @@ -5588,7 +5624,7 @@ msgstr "実行が許可されていないコマンド" msgid "Virtual app" msgstr "仮想アプリケーション" -#: settings/serializers/feature.py:129 +#: settings/serializers/feature.py:140 msgid "Enable virtual app" msgstr "仮想アプリケーションの有効化" @@ -6057,104 +6093,104 @@ msgstr "LDAP ユーザーを定期的にインポートする" msgid "Registration periodic import ldap user task" msgstr "登録サイクルLDAPユーザータスクのインポート" -#: settings/utils/ldap.py:492 +#: settings/utils/ldap.py:491 msgid "ldap:// or ldaps:// protocol is used." msgstr "ldap:// または ldaps:// プロトコルが使用されます。" -#: settings/utils/ldap.py:503 +#: settings/utils/ldap.py:502 msgid "Host or port is disconnected: {}" msgstr "ホストまたはポートが切断されました: {}" -#: settings/utils/ldap.py:505 +#: settings/utils/ldap.py:504 msgid "The port is not the port of the LDAP service: {}" msgstr "ポートはLDAPサービスのポートではありません: {}" -#: settings/utils/ldap.py:507 +#: settings/utils/ldap.py:506 msgid "Please add certificate: {}" msgstr "証明書を追加してください: {}" -#: settings/utils/ldap.py:511 settings/utils/ldap.py:538 -#: settings/utils/ldap.py:568 settings/utils/ldap.py:596 +#: settings/utils/ldap.py:510 settings/utils/ldap.py:537 +#: settings/utils/ldap.py:567 settings/utils/ldap.py:595 msgid "Unknown error: {}" msgstr "不明なエラー: {}" -#: settings/utils/ldap.py:525 +#: settings/utils/ldap.py:524 msgid "Bind DN or Password incorrect" msgstr "DNまたはパスワードのバインドが正しくありません" -#: settings/utils/ldap.py:532 +#: settings/utils/ldap.py:531 msgid "Please enter Bind DN: {}" msgstr "バインドDN: {} を入力してください" -#: settings/utils/ldap.py:534 +#: settings/utils/ldap.py:533 msgid "Please enter Password: {}" msgstr "パスワードを入力してください: {}" -#: settings/utils/ldap.py:536 +#: settings/utils/ldap.py:535 msgid "Please enter correct Bind DN and Password: {}" msgstr "正しいバインドDNとパスワードを入力してください: {}" -#: settings/utils/ldap.py:554 +#: settings/utils/ldap.py:553 msgid "Invalid User OU or User search filter: {}" msgstr "無効なユーザー OU またはユーザー検索フィルター: {}" -#: settings/utils/ldap.py:585 +#: settings/utils/ldap.py:584 msgid "LDAP User attr map not include: {}" msgstr "LDAP ユーザーattrマップは含まれません: {}" -#: settings/utils/ldap.py:592 +#: settings/utils/ldap.py:591 msgid "LDAP User attr map is not dict" msgstr "LDAPユーザーattrマップはdictではありません" -#: settings/utils/ldap.py:611 +#: settings/utils/ldap.py:610 msgid "LDAP authentication is not enabled" msgstr "LDAP 認証が有効になっていない" -#: settings/utils/ldap.py:629 +#: settings/utils/ldap.py:628 msgid "Error (Invalid LDAP server): {}" msgstr "エラー (LDAPサーバーが無効): {}" -#: settings/utils/ldap.py:631 +#: settings/utils/ldap.py:630 msgid "Error (Invalid Bind DN): {}" msgstr "エラー (DNのバインドが無効): {}" -#: settings/utils/ldap.py:633 +#: settings/utils/ldap.py:632 msgid "Error (Invalid LDAP User attr map): {}" msgstr "エラー (LDAPユーザーattrマップが無効): {}" -#: settings/utils/ldap.py:635 +#: settings/utils/ldap.py:634 msgid "Error (Invalid User OU or User search filter): {}" msgstr "エラー (ユーザーOUまたはユーザー検索フィルターが無効): {}" -#: settings/utils/ldap.py:637 +#: settings/utils/ldap.py:636 msgid "Error (Not enabled LDAP authentication): {}" msgstr "エラー (LDAP認証が有効化されていません): {}" -#: settings/utils/ldap.py:639 +#: settings/utils/ldap.py:638 msgid "Error (Unknown): {}" msgstr "エラー (不明): {}" -#: settings/utils/ldap.py:642 +#: settings/utils/ldap.py:641 msgid "Succeed: Match {} s user" msgstr "成功: {} 人のユーザーに一致" -#: settings/utils/ldap.py:653 +#: settings/utils/ldap.py:652 msgid "Please test the connection first" msgstr "まず接続をテストしてください" -#: settings/utils/ldap.py:675 +#: settings/utils/ldap.py:674 msgid "Authentication failed (configuration incorrect): {}" msgstr "認証に失敗しました (設定が正しくありません): {}" -#: settings/utils/ldap.py:679 +#: settings/utils/ldap.py:678 msgid "Authentication failed (username or password incorrect): {}" msgstr "認証に失敗しました (ユーザー名またはパスワードが正しくありません): {}" -#: settings/utils/ldap.py:681 +#: settings/utils/ldap.py:680 msgid "Authentication failed (Unknown): {}" msgstr "認証に失敗しました (不明): {}" -#: settings/utils/ldap.py:684 +#: settings/utils/ldap.py:683 msgid "Authentication success: {}" msgstr "認証成功: {}" @@ -7806,31 +7842,31 @@ msgstr "更新パスワードが必要" msgid "Date api key used" msgstr "Api key 最後に使用した日付" -#: users/models/user.py:984 +#: users/models/user.py:985 msgid "Can not delete admin user" msgstr "管理者ユーザーを削除できませんでした" -#: users/models/user.py:1011 +#: users/models/user.py:1012 msgid "Can invite user" msgstr "ユーザーを招待できます" -#: users/models/user.py:1012 +#: users/models/user.py:1013 msgid "Can remove user" msgstr "ユーザーを削除できます" -#: users/models/user.py:1013 +#: users/models/user.py:1014 msgid "Can match user" msgstr "ユーザーに一致できます" -#: users/models/user.py:1022 +#: users/models/user.py:1023 msgid "Administrator" msgstr "管理者" -#: users/models/user.py:1025 +#: users/models/user.py:1026 msgid "Administrator is the super user of system" msgstr "管理者はシステムのスーパーユーザーです" -#: users/models/user.py:1050 +#: users/models/user.py:1051 msgid "User password history" msgstr "ユーザーパスワード履歴" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 1fe3d019d..4efb8d030 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80dd11dde678e4f9b64df18906175125218fd9f719bfe9aaa667ad6e2d055d40 -size 139012 +oid sha256:44d560db28dc9dd1a450f7e715b6de7a18ba44caece18f4e7da40c1659eefc48 +size 139920 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 472fb7b2e..335b5d3de 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-26 14:13+0800\n" +"POT-Creation-Date: 2024-01-03 11:23+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -114,8 +114,8 @@ msgstr "更改密码" msgid "Verify account" msgstr "验证账号" -#: accounts/const/automation.py:27 accounts/tasks/remove_account.py:14 -#: accounts/tasks/remove_account.py:23 +#: accounts/const/automation.py:27 accounts/tasks/remove_account.py:24 +#: accounts/tasks/remove_account.py:33 msgid "Remove account" msgstr "移除账号" @@ -247,8 +247,7 @@ msgstr "用户 %s 查看/导出 了密码" #: accounts/templates/accounts/asset_account_change_info.html:7 #: acls/serializers/base.py:123 assets/models/asset/common.py:95 #: assets/models/asset/common.py:350 assets/models/cmd_filter.py:36 -#: assets/serializers/domain.py:20 audits/models.py:58 -#: authentication/models/connection_token.py:36 +#: audits/models.py:58 authentication/models/connection_token.py:36 #: perms/models/asset_permission.py:69 perms/serializers/permission.py:36 #: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 #: terminal/notifications.py:155 terminal/serializers/command.py:17 @@ -509,9 +508,8 @@ msgstr "最后登录日期" #: accounts/models/automations/gather_account.py:17 #: accounts/models/automations/push_account.py:15 accounts/models/base.py:65 #: accounts/serializers/account/virtual.py:21 acls/serializers/base.py:19 -#: acls/serializers/base.py:50 acls/templates/acls/asset_login_reminder.html:5 -#: acls/templates/acls/user_login_reminder.html:5 assets/models/_user.py:23 -#: audits/models.py:188 authentication/forms.py:25 authentication/forms.py:27 +#: acls/serializers/base.py:50 assets/models/_user.py:23 audits/models.py:188 +#: authentication/forms.py:25 authentication/forms.py:27 #: authentication/models/temp_token.py:9 #: authentication/templates/authentication/_msg_different_city.html:9 #: authentication/templates/authentication/_msg_oauth_bind.html:9 @@ -811,11 +809,13 @@ msgstr "账号已存在" #: accounts/serializers/account/account.py:441 #: authentication/serializers/connect_token_secret.py:159 #: authentication/templates/authentication/_access_key_modal.html:30 -#: perms/models/perm_node.py:21 users/serializers/group.py:32 +#: perms/models/perm_node.py:21 users/serializers/group.py:33 msgid "ID" msgstr "ID" #: accounts/serializers/account/account.py:451 acls/serializers/base.py:116 +#: acls/templates/acls/asset_login_reminder.html:5 +#: acls/templates/acls/user_login_reminder.html:5 #: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:54 #: audits/models.py:90 audits/models.py:172 audits/models.py:269 #: audits/serializers.py:171 authentication/models/connection_token.py:32 @@ -829,8 +829,8 @@ msgstr "ID" #: terminal/notifications.py:205 terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: terminal/templates/terminal/_msg_session_sharing.html:6 -#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:1003 -#: users/models/user.py:1040 users/serializers/group.py:19 +#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:1004 +#: users/models/user.py:1041 users/serializers/group.py:21 msgid "User" msgstr "用户" @@ -1016,6 +1016,14 @@ msgstr "收集资产上的账号" msgid "Push accounts to assets" msgstr "推送账号到资产" +#: accounts/tasks/remove_account.py:44 +msgid "Clean historical accounts" +msgstr "清理历史账号" + +#: accounts/tasks/remove_account.py:76 +msgid "Remove historical accounts that are out of range." +msgstr "删除超出范围的历史帐户。" + #: accounts/tasks/template.py:11 msgid "Template sync info to related accounts" msgstr "同步信息到关联的账号" @@ -1187,7 +1195,7 @@ msgstr "登录资产访问控制" msgid "Login asset confirm" msgstr "登录资产复核" -#: acls/notifications.py:11 +#: acls/notifications.py:12 msgid "User login reminder" msgstr "用户登录提醒" @@ -1306,11 +1314,11 @@ msgstr "应用程序" msgid "Can match application" msgstr "匹配应用" -#: assets/api/asset/asset.py:182 +#: assets/api/asset/asset.py:179 msgid "Cannot create asset directly, you should create a host or other" msgstr "不能直接创建资产, 你应该创建主机或其他资产" -#: assets/api/domain.py:63 +#: assets/api/domain.py:64 msgid "Number required" msgstr "需要为数字" @@ -1609,7 +1617,7 @@ msgstr "SSH公钥" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 #: audits/models.py:267 common/db/models.py:34 ops/models/base.py:54 -#: ops/models/job.py:234 users/models/user.py:1041 +#: ops/models/job.py:234 users/models/user.py:1042 msgid "Date created" msgstr "创建日期" @@ -1621,7 +1629,7 @@ msgstr "更新日期" #: assets/models/_user.py:30 assets/models/cmd_filter.py:44 #: assets/models/cmd_filter.py:91 assets/models/group.py:18 #: common/db/models.py:32 users/models/user.py:843 -#: users/serializers/group.py:30 +#: users/serializers/group.py:32 msgid "Created by" msgstr "创建者" @@ -1723,7 +1731,7 @@ msgid "Domain" msgstr "网域" #: assets/models/asset/common.py:165 assets/models/automations/base.py:18 -#: assets/models/cmd_filter.py:32 assets/models/node.py:553 +#: assets/models/cmd_filter.py:32 assets/models/node.py:546 #: perms/models/asset_permission.py:72 perms/serializers/permission.py:37 #: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:330 msgid "Node" @@ -1774,7 +1782,7 @@ msgstr "客户端密钥" msgid "Allow invalid cert" msgstr "忽略证书校验" -#: assets/models/asset/gpt.py:8 settings/serializers/feature.py:73 +#: assets/models/asset/gpt.py:8 settings/serializers/feature.py:84 msgid "Proxy" msgstr "代理" @@ -1841,7 +1849,7 @@ msgstr "命令过滤规则" msgid "Favorite asset" msgstr "收藏的资产" -#: assets/models/gateway.py:34 assets/serializers/domain.py:17 +#: assets/models/gateway.py:34 assets/serializers/domain.py:18 msgid "Gateway" msgstr "网关" @@ -1859,11 +1867,11 @@ msgstr "默认" msgid "Default asset group" msgstr "默认资产组" -#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:1026 +#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:1027 msgid "System" msgstr "系统" -#: assets/models/label.py:19 assets/models/node.py:539 +#: assets/models/label.py:19 assets/models/node.py:532 #: assets/serializers/cagegory.py:11 assets/serializers/cagegory.py:18 #: assets/serializers/cagegory.py:24 #: authentication/models/connection_token.py:29 @@ -1886,23 +1894,23 @@ msgstr "标签" msgid "New node" msgstr "新节点" -#: assets/models/node.py:467 audits/backends/db.py:65 audits/backends/db.py:66 +#: assets/models/node.py:460 audits/backends/db.py:65 audits/backends/db.py:66 msgid "empty" msgstr "空" -#: assets/models/node.py:538 perms/models/perm_node.py:28 +#: assets/models/node.py:531 perms/models/perm_node.py:28 msgid "Key" msgstr "键" -#: assets/models/node.py:540 assets/serializers/node.py:20 +#: assets/models/node.py:533 assets/serializers/node.py:20 msgid "Full value" msgstr "全称" -#: assets/models/node.py:544 perms/models/perm_node.py:30 +#: assets/models/node.py:537 perms/models/perm_node.py:30 msgid "Parent key" msgstr "ssh私钥" -#: assets/models/node.py:556 +#: assets/models/node.py:549 msgid "Can match node" msgstr "可以匹配节点" @@ -2160,6 +2168,10 @@ msgstr "约束" msgid "Types" msgstr "类型" +#: assets/serializers/domain.py:53 perms/serializers/permission.py:188 +msgid "Assets amount" +msgstr "资产数量" + #: assets/serializers/gateway.py:23 common/validators.py:34 msgid "This field must be unique." msgstr "字段必须唯一" @@ -3005,7 +3017,7 @@ msgstr "设置手机号码启用" msgid "Clear phone number to disable" msgstr "清空手机号码禁用" -#: authentication/middleware.py:94 settings/utils/ldap.py:677 +#: authentication/middleware.py:94 settings/utils/ldap.py:676 msgid "Authentication failed (before login check failed): {}" msgstr "认证失败 (登录前检查失败): {}" @@ -3265,7 +3277,7 @@ msgstr "代码错误" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:455 +#: jumpserver/conf.py:457 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:32 @@ -3894,16 +3906,16 @@ msgstr "不能包含特殊字符" msgid "The mobile phone number format is incorrect" msgstr "手机号格式不正确" -#: jumpserver/conf.py:450 +#: jumpserver/conf.py:452 #, python-brace-format msgid "The verification code is: {code}" msgstr "验证码为: {code}" -#: jumpserver/conf.py:454 +#: jumpserver/conf.py:456 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:456 +#: jumpserver/conf.py:458 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -4535,7 +4547,7 @@ msgid "today" msgstr "今天" #: perms/notifications.py:12 perms/notifications.py:44 -#: settings/serializers/feature.py:106 +#: settings/serializers/feature.py:117 msgid "day" msgstr "天" @@ -4555,6 +4567,19 @@ msgstr "资产授权规则将要过期" msgid "asset permissions of organization {}" msgstr "组织 ({}) 的资产授权" +#: perms/serializers/permission.py:186 rbac/serializers/role.py:27 +#: users/serializers/group.py:54 users/serializers/group.py:60 +msgid "Users amount" +msgstr "用户数量" + +#: perms/serializers/permission.py:187 +msgid "User groups amount" +msgstr "用户组数量" + +#: perms/serializers/permission.py:189 +msgid "Nodes amount" +msgstr "节点数量" + #: perms/tasks.py:27 msgid "Check asset permission expired" msgstr "校验资产授权规则已过期" @@ -4695,10 +4720,6 @@ msgstr "系统角色绑定" msgid "Perms" msgstr "权限" -#: rbac/serializers/role.py:27 users/serializers/group.py:31 -msgid "Users amount" -msgstr "用户数量" - #: rbac/serializers/role.py:28 terminal/models/applet/applet.py:34 #: terminal/models/virtualapp/virtualapp.py:20 msgid "Display name" @@ -4770,7 +4791,7 @@ msgstr "远程应用" msgid "Ticket comment" msgstr "工单评论" -#: rbac/tree.py:130 settings/serializers/feature.py:98 +#: rbac/tree.py:130 settings/serializers/feature.py:109 #: tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "工单管理" @@ -5466,62 +5487,76 @@ msgid "Mount Point" msgstr "挂载点" #: settings/serializers/feature.py:60 +msgid "Historical accounts retained count" +msgstr "历史账号保留数量" + +#: settings/serializers/feature.py:62 +msgid "" +"If the specific value is less than 999, the system will automatically " +"perform a task every night: check and delete historical accounts that exceed " +"the predetermined number. If the value reaches or exceeds 999, no historical " +"account deletion will be performed." +msgstr "" +"若特定数值小于999,系统将在每日晚间自动执行任务:检查并删除超出预定数量的历史" +"账号。如果该数值达到或超过999,则不进行任何历史账号的删除操作。" + +#: settings/serializers/feature.py:71 msgid "Chat AI" msgstr "聊天 AI" -#: settings/serializers/feature.py:64 +#: settings/serializers/feature.py:75 msgid "Enable Chat AI" msgstr "启动聊天 AI" -#: settings/serializers/feature.py:67 +#: settings/serializers/feature.py:78 msgid "Base Url" msgstr "基本地址" -#: settings/serializers/feature.py:70 templates/_header_bar.html:90 +#: settings/serializers/feature.py:81 templates/_header_bar.html:90 msgid "API Key" msgstr "API Key" -#: settings/serializers/feature.py:76 +#: settings/serializers/feature.py:87 msgid "GPT Model" msgstr "GPT 模型" -#: settings/serializers/feature.py:100 +#: settings/serializers/feature.py:111 msgid "Enable tickets" msgstr "启用工单" -#: settings/serializers/feature.py:103 +#: settings/serializers/feature.py:114 msgid "Ticket authorize default time" msgstr "默认工单授权时间" -#: settings/serializers/feature.py:106 +#: settings/serializers/feature.py:117 msgid "hour" msgstr "时" -#: settings/serializers/feature.py:107 +#: settings/serializers/feature.py:118 msgid "Ticket authorize default time unit" msgstr "默认工单授权时间单位" -#: settings/serializers/feature.py:112 +#: settings/serializers/feature.py:123 msgid "Feature" msgstr "功能" -#: settings/serializers/feature.py:115 +#: settings/serializers/feature.py:126 msgid "Operation center" msgstr "作业中心" -#: settings/serializers/feature.py:116 +#: settings/serializers/feature.py:127 msgid "Allow user run batch command or not using ansible" msgstr "是否允许用户使用 ansible 执行批量命令" -#: settings/serializers/feature.py:120 +#: settings/serializers/feature.py:131 msgid "Operation center command blacklist" msgstr "作业中心命令黑名单" -#: settings/serializers/feature.py:121 +#: settings/serializers/feature.py:132 msgid "Commands that are not allowed execute." msgstr "不允许执行的命令" -#: settings/serializers/feature.py:126 +#: settings/serializers/feature.py:137 #: terminal/models/virtualapp/provider.py:17 #: terminal/models/virtualapp/virtualapp.py:36 #: terminal/models/virtualapp/virtualapp.py:97 @@ -5529,7 +5564,7 @@ msgstr "不允许执行的命令" msgid "Virtual app" msgstr "虚拟应用" -#: settings/serializers/feature.py:129 +#: settings/serializers/feature.py:140 msgid "Enable virtual app" msgstr "启用虚拟应用" @@ -5974,104 +6009,104 @@ msgstr "周期导入 LDAP 用户" msgid "Registration periodic import ldap user task" msgstr "注册周期导入 LDAP 用户 任务" -#: settings/utils/ldap.py:492 +#: settings/utils/ldap.py:491 msgid "ldap:// or ldaps:// protocol is used." msgstr "使用 ldap:// 或 ldaps:// 协议" -#: settings/utils/ldap.py:503 +#: settings/utils/ldap.py:502 msgid "Host or port is disconnected: {}" msgstr "主机或端口不可连接: {}" -#: settings/utils/ldap.py:505 +#: settings/utils/ldap.py:504 msgid "The port is not the port of the LDAP service: {}" msgstr "端口不是LDAP服务端口: {}" -#: settings/utils/ldap.py:507 +#: settings/utils/ldap.py:506 msgid "Please add certificate: {}" msgstr "请添加证书" -#: settings/utils/ldap.py:511 settings/utils/ldap.py:538 -#: settings/utils/ldap.py:568 settings/utils/ldap.py:596 +#: settings/utils/ldap.py:510 settings/utils/ldap.py:537 +#: settings/utils/ldap.py:567 settings/utils/ldap.py:595 msgid "Unknown error: {}" msgstr "未知错误: {}" -#: settings/utils/ldap.py:525 +#: settings/utils/ldap.py:524 msgid "Bind DN or Password incorrect" msgstr "绑定DN或密码错误" -#: settings/utils/ldap.py:532 +#: settings/utils/ldap.py:531 msgid "Please enter Bind DN: {}" msgstr "请输入绑定DN: {}" -#: settings/utils/ldap.py:534 +#: settings/utils/ldap.py:533 msgid "Please enter Password: {}" msgstr "请输入密码: {}" -#: settings/utils/ldap.py:536 +#: settings/utils/ldap.py:535 msgid "Please enter correct Bind DN and Password: {}" msgstr "请输入正确的绑定DN和密码: {}" -#: settings/utils/ldap.py:554 +#: settings/utils/ldap.py:553 msgid "Invalid User OU or User search filter: {}" msgstr "不合法的用户OU或用户过滤器: {}" -#: settings/utils/ldap.py:585 +#: settings/utils/ldap.py:584 msgid "LDAP User attr map not include: {}" msgstr "LDAP属性映射没有包含: {}" -#: settings/utils/ldap.py:592 +#: settings/utils/ldap.py:591 msgid "LDAP User attr map is not dict" msgstr "LDAP属性映射不合法" -#: settings/utils/ldap.py:611 +#: settings/utils/ldap.py:610 msgid "LDAP authentication is not enabled" msgstr "LDAP认证没有启用" -#: settings/utils/ldap.py:629 +#: settings/utils/ldap.py:628 msgid "Error (Invalid LDAP server): {}" msgstr "错误 (不合法的LDAP服务器地址): {}" -#: settings/utils/ldap.py:631 +#: settings/utils/ldap.py:630 msgid "Error (Invalid Bind DN): {}" msgstr "错误 (不合法的绑定DN): {}" -#: settings/utils/ldap.py:633 +#: settings/utils/ldap.py:632 msgid "Error (Invalid LDAP User attr map): {}" msgstr "错误 (不合法的LDAP属性映射): {}" -#: settings/utils/ldap.py:635 +#: settings/utils/ldap.py:634 msgid "Error (Invalid User OU or User search filter): {}" msgstr "错误 (不合法的用户OU或用户过滤器): {}" -#: settings/utils/ldap.py:637 +#: settings/utils/ldap.py:636 msgid "Error (Not enabled LDAP authentication): {}" msgstr "错误 (没有启用LDAP认证): {}" -#: settings/utils/ldap.py:639 +#: settings/utils/ldap.py:638 msgid "Error (Unknown): {}" msgstr "错误 (未知): {}" -#: settings/utils/ldap.py:642 +#: settings/utils/ldap.py:641 msgid "Succeed: Match {} s user" msgstr "成功匹配 {} 个用户" -#: settings/utils/ldap.py:653 +#: settings/utils/ldap.py:652 msgid "Please test the connection first" msgstr "请先测试连接" -#: settings/utils/ldap.py:675 +#: settings/utils/ldap.py:674 msgid "Authentication failed (configuration incorrect): {}" msgstr "认证失败 (配置错误): {}" -#: settings/utils/ldap.py:679 +#: settings/utils/ldap.py:678 msgid "Authentication failed (username or password incorrect): {}" msgstr "认证失败 (用户名或密码不正确): {}" -#: settings/utils/ldap.py:681 +#: settings/utils/ldap.py:680 msgid "Authentication failed (Unknown): {}" msgstr "认证失败: (未知): {}" -#: settings/utils/ldap.py:684 +#: settings/utils/ldap.py:683 msgid "Authentication success: {}" msgstr "认证成功: {}" @@ -7700,31 +7735,31 @@ msgstr "需要更新密码" msgid "Date api key used" msgstr "Api key 最后使用日期" -#: users/models/user.py:984 +#: users/models/user.py:985 msgid "Can not delete admin user" msgstr "无法删除管理员用户" -#: users/models/user.py:1011 +#: users/models/user.py:1012 msgid "Can invite user" msgstr "可以邀请用户" -#: users/models/user.py:1012 +#: users/models/user.py:1013 msgid "Can remove user" msgstr "可以移除用户" -#: users/models/user.py:1013 +#: users/models/user.py:1014 msgid "Can match user" msgstr "可以匹配用户" -#: users/models/user.py:1022 +#: users/models/user.py:1023 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:1025 +#: users/models/user.py:1026 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/models/user.py:1050 +#: users/models/user.py:1051 msgid "User password history" msgstr "用户密码历史" diff --git a/apps/settings/serializers/feature.py b/apps/settings/serializers/feature.py index 07a3dbcd6..a1a734d54 100644 --- a/apps/settings/serializers/feature.py +++ b/apps/settings/serializers/feature.py @@ -57,7 +57,7 @@ class VaultSettingSerializer(serializers.Serializer): HISTORY_ACCOUNT_CLEAN_LIMIT = serializers.IntegerField( default=999, max_value=999, min_value=1, - required=False, label=_('History Account Count'), + required=False, label=_('Historical accounts retained count'), help_text=_( 'If the specific value is less than 999, ' 'the system will automatically perform a task every night: ' From 15ac81a422defdf1dbb9e506a712934cdceccfbe Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 3 Jan 2024 16:14:27 +0800 Subject: [PATCH 09/41] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E7=BB=91=E5=AE=9A=EF=BC=8C=E4=BB=85=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E5=88=B0=E8=B5=84=E4=BA=A7=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/platform.py | 3 ++- apps/assets/serializers/asset/common.py | 9 +++++---- apps/assets/serializers/platform.py | 6 ------ apps/common/drf/filters.py | 4 ++-- apps/common/signal_handlers.py | 2 +- apps/labels/api.py | 24 ++++++++++++++++-------- apps/labels/mixins.py | 20 ++++++++++++++++++-- 7 files changed, 44 insertions(+), 24 deletions(-) diff --git a/apps/assets/api/platform.py b/apps/assets/api/platform.py index 9f3a55bda..6a31f9519 100644 --- a/apps/assets/api/platform.py +++ b/apps/assets/api/platform.py @@ -29,8 +29,9 @@ class AssetPlatformViewSet(JMSModelViewSet): } def get_queryset(self): + # 因为没有走分页逻辑,所以需要这里 prefetch queryset = super().get_queryset().prefetch_related( - 'protocols', 'automation' + 'protocols', 'automation', 'labels', 'labels__label', ) queryset = queryset.filter(type__in=AllTypes.get_types_values()) return queryset diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 6c45944de..501d06780 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -100,7 +100,10 @@ class AssetAccountSerializer(AccountSerializer): class Meta(AccountSerializer.Meta): fields = [ f for f in AccountSerializer.Meta.fields - if f not in ['spec_info'] + if f not in [ + 'spec_info', 'connectivity', 'labels', 'created_by', + 'date_update', 'date_created' + ] ] extra_kwargs = { **AccountSerializer.Meta.extra_kwargs, @@ -375,7 +378,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer, ResourceLabelsMixin, Writa class DetailMixin(serializers.Serializer): - accounts = AssetAccountSerializer(many=True, required=False, label=_('Accounts')) spec_info = MethodSerializer(label=_('Spec info'), read_only=True) gathered_info = MethodSerializer(label=_('Gathered info'), read_only=True) auto_config = serializers.DictField(read_only=True, label=_('Auto info')) @@ -390,8 +392,7 @@ class DetailMixin(serializers.Serializer): def get_field_names(self, declared_fields, info): names = super().get_field_names(declared_fields, info) names.extend([ - 'accounts', 'gathered_info', 'spec_info', - 'auto_config', + 'gathered_info', 'spec_info', 'auto_config', ]) return names diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index f67df9906..2cc7d73ef 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -200,12 +200,6 @@ class PlatformSerializer(ResourceLabelsMixin, WritableNestedModelSerializer): constraints = AllTypes.get_constraints(category, tp) return constraints - @classmethod - def setup_eager_loading(cls, queryset): - queryset = queryset.prefetch_related('protocols', 'automation') \ - .prefetch_related('labels', 'labels__label') - return queryset - def validate_protocols(self, protocols): if not protocols: raise serializers.ValidationError(_("Protocols is required")) diff --git a/apps/common/drf/filters.py b/apps/common/drf/filters.py index 0fb8ca63a..d187cd414 100644 --- a/apps/common/drf/filters.py +++ b/apps/common/drf/filters.py @@ -219,10 +219,10 @@ class LabelFilterBackend(filters.BaseFilterBackend): if not hasattr(queryset, 'model'): return queryset - if not hasattr(queryset.model, 'labels'): + if not hasattr(queryset.model, 'label_model'): return queryset - model = queryset.model + model = queryset.model.label_model() labeled_resource_cls = model._labels.field.related_model app_label = model._meta.app_label model_name = model._meta.model_name diff --git a/apps/common/signal_handlers.py b/apps/common/signal_handlers.py index ba5a4ad92..ad765657e 100644 --- a/apps/common/signal_handlers.py +++ b/apps/common/signal_handlers.py @@ -69,7 +69,7 @@ def digest_sql_query(): for query in queries: sql = query['sql'] - print(" # {}: {}".format(query['time'], sql)) + print(" # {}: {}".format(query['time'], sql[:1000])) if len(queries) < 3: continue print("- Table: {}".format(table_name)) diff --git a/apps/labels/api.py b/apps/labels/api.py index 44a6702e7..1c6965a43 100644 --- a/apps/labels/api.py +++ b/apps/labels/api.py @@ -73,7 +73,7 @@ class LabelContentTypeResourceViewSet(JMSModelViewSet): queryset = model.objects.all() if bound == '1': queryset = queryset.filter(id__in=list(res_ids)) - elif bound == '0': + else: queryset = queryset.exclude(id__in=list(res_ids)) keyword = self.request.query_params.get('search') if keyword: @@ -90,9 +90,10 @@ class LabelContentTypeResourceViewSet(JMSModelViewSet): LabeledResource.objects \ .filter(res_type=content_type, label=label) \ .exclude(res_id__in=res_ids).delete() - resources = [] - for res_id in res_ids: - resources.append(LabeledResource(res_type=content_type, res_id=res_id, label=label, org_id=current_org.id)) + resources = [ + LabeledResource(res_type=content_type, res_id=res_id, label=label, org_id=current_org.id) + for res_id in res_ids + ] LabeledResource.objects.bulk_create(resources, ignore_conflicts=True) return Response({"total": len(res_ids)}) @@ -129,15 +130,22 @@ class LabeledResourceViewSet(OrgBulkModelViewSet): } ordering_fields = ('res_type', 'date_created') - # Todo: 这里需要优化,查询 sql 太多 def filter_search(self, queryset): keyword = self.request.query_params.get('search') if not keyword: return queryset + keyword = keyword.strip().lower() matched = [] - for instance in queryset: - if keyword.lower() in str(instance.resource).lower(): - matched.append(instance.id) + offset = 0 + limit = 10000 + while True: + page = queryset[offset:offset + limit] + if not page: + break + offset += limit + for instance in page: + if keyword in str(instance.resource).lower(): + matched.append(instance.id) return queryset.filter(id__in=matched) def get_queryset(self): diff --git a/apps/labels/mixins.py b/apps/labels/mixins.py index 90b76f3ed..9feb6f0f0 100644 --- a/apps/labels/mixins.py +++ b/apps/labels/mixins.py @@ -1,5 +1,6 @@ from django.contrib.contenttypes.fields import GenericRelation from django.db import models +from django.db.models import OneToOneField from .models import LabeledResource @@ -12,10 +13,25 @@ class LabeledMixin(models.Model): class Meta: abstract = True + @classmethod + def label_model(cls): + pk_field = cls._meta.pk + model = cls + if isinstance(pk_field, OneToOneField): + model = pk_field.related_model + return model + + @property + def real(self): + pk_field = self._meta.pk + if isinstance(pk_field, OneToOneField): + return getattr(self, pk_field.name) + return self + @property def labels(self): - return self._labels + return self.real._labels @labels.setter def labels(self, value): - self._labels.set(value, bulk=False) + self.real._labels.set(value, bulk=False) From 2a29cd0e707e7b3f8d808fa0d53602b2e37ddf29 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 3 Jan 2024 16:51:43 +0800 Subject: [PATCH 10/41] =?UTF-8?q?perf:=20=E4=BD=BF=E7=94=A8=20nginx=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=9D=99=E6=80=81=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/settings/base.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index e2bfbc5c1..aebb73741 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -312,12 +312,17 @@ STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), ) -# Media files (File, ImageField) will be save these +# Media files (File, ImageField) will be safe these MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(PROJECT_DIR, 'data', 'media').replace('\\', '/') + '/' PRIVATE_STORAGE_ROOT = MEDIA_ROOT PRIVATE_STORAGE_AUTH_FUNCTION = 'jumpserver.rewriting.storage.permissions.allow_access' +PRIVATE_STORAGE_INTERNAL_URL = '/private-media/' +PRIVATE_STORAGE_SERVER = 'nginx' +if DEBUG_DEV: + PRIVATE_STORAGE_SERVER = 'django' + # Use django-bootstrap-form to format template, input max width arg # BOOTSTRAP_COLUMN_COUNT = 11 From 9ede3670a7bede0be1c036d901116dcb305f0c38 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Tue, 2 Jan 2024 17:00:15 +0800 Subject: [PATCH 11/41] =?UTF-8?q?perf:=20=E9=82=AE=E7=AE=B1=E6=94=AF?= =?UTF-8?q?=E6=8C=81exchange=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/tasks.py | 17 ++++- apps/jumpserver/conf.py | 1 + apps/jumpserver/rewriting/exchange.py | 104 ++++++++++++++++++++++++++ apps/jumpserver/settings/base.py | 1 + apps/settings/api/email.py | 3 +- apps/settings/serializers/msg.py | 19 +++-- 6 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 apps/jumpserver/rewriting/exchange.py diff --git a/apps/common/tasks.py b/apps/common/tasks.py index d5c0cb609..5bffe07f4 100644 --- a/apps/common/tasks.py +++ b/apps/common/tasks.py @@ -2,7 +2,7 @@ import os from celery import shared_task from django.conf import settings -from django.core.mail import send_mail, EmailMultiAlternatives +from django.core.mail import send_mail, EmailMultiAlternatives, get_connection from django.utils.translation import gettext_lazy as _ import jms_storage @@ -11,6 +11,16 @@ from .utils import get_logger logger = get_logger(__file__) +def get_email_connection(**kwargs): + email_backend_map = { + 'smtp': 'django.core.mail.backends.smtp.EmailBackend', + 'exchange': 'jumpserver.rewriting.exchange.EmailBackend' + } + return get_connection( + backend=email_backend_map.get(settings.EMAIL_PROTOCOL), **kwargs + ) + + def task_activity_callback(self, subject, message, recipient_list, *args, **kwargs): from users.models import User email_list = recipient_list @@ -40,7 +50,7 @@ def send_mail_async(*args, **kwargs): args = tuple(args) try: - return send_mail(*args, **kwargs) + return send_mail(connection=get_email_connection(), *args, **kwargs) except Exception as e: logger.error("Sending mail error: {}".format(e)) @@ -55,7 +65,8 @@ def send_mail_attachment_async(subject, message, recipient_list, attachment_list subject=subject, body=message, from_email=from_email, - to=recipient_list + to=recipient_list, + connection=get_email_connection(), ) for attachment in attachment_list: email.attach_file(attachment) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index f5f5d5d0c..18e570271 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -453,6 +453,7 @@ class Config(dict): 'CUSTOM_SMS_REQUEST_METHOD': 'get', # Email + 'EMAIL_PROTOCOL': 'smtp', 'EMAIL_CUSTOM_USER_CREATED_SUBJECT': _('Create account successfully'), 'EMAIL_CUSTOM_USER_CREATED_HONORIFIC': _('Hello'), 'EMAIL_CUSTOM_USER_CREATED_BODY': _('Your account has been created successfully'), diff --git a/apps/jumpserver/rewriting/exchange.py b/apps/jumpserver/rewriting/exchange.py new file mode 100644 index 000000000..709e5558f --- /dev/null +++ b/apps/jumpserver/rewriting/exchange.py @@ -0,0 +1,104 @@ +import urllib3 + +from urllib3.exceptions import InsecureRequestWarning + +from django.core.mail.backends.base import BaseEmailBackend +from django.core.mail.message import sanitize_address +from django.conf import settings +from exchangelib import Account, Credentials, Configuration, DELEGATE +from exchangelib import Mailbox, Message, HTMLBody, FileAttachment +from exchangelib import BaseProtocol, NoVerifyHTTPAdapter +from exchangelib.errors import TransportError + + +urllib3.disable_warnings(InsecureRequestWarning) +BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter + + +class EmailBackend(BaseEmailBackend): + def __init__( + self, + service_endpoint=None, + username=None, + password=None, + fail_silently=False, + **kwargs, + ): + super().__init__(fail_silently=fail_silently) + self.service_endpoint = service_endpoint or settings.EMAIL_HOST + self.username = settings.EMAIL_HOST_USER if username is None else username + self.password = settings.EMAIL_HOST_PASSWORD if password is None else password + self._connection = None + + def open(self): + if self._connection: + return False + + try: + config = Configuration( + service_endpoint=self.service_endpoint, credentials=Credentials( + username=self.username, password=self.password + ) + ) + self._connection = Account(self.username, config=config, access_type=DELEGATE) + return True + except TransportError: + if not self.fail_silently: + raise + + def close(self): + self._connection = None + + def send_messages(self, email_messages): + if not email_messages: + return 0 + + new_conn_created = self.open() + if not self._connection or new_conn_created is None: + return 0 + num_sent = 0 + for message in email_messages: + sent = self._send(message) + if sent: + num_sent += 1 + if new_conn_created: + self.close() + return num_sent + + def _send(self, email_message): + if not email_message.recipients(): + return False + + encoding = settings.DEFAULT_CHARSET + from_email = sanitize_address(email_message.from_email, encoding) + recipients = [ + Mailbox(email_address=sanitize_address(addr, encoding)) for addr in email_message.recipients() + ] + try: + message_body = email_message.body + alternatives = email_message.alternatives or [] + attachments = [] + for attachment in email_message.attachments or []: + name, content, mimetype = attachment + if isinstance(content, str): + content = content.encode(encoding) + attachments.append( + FileAttachment(name=name, content=content, content_type=mimetype) + ) + for alternative in alternatives: + if alternative[1] == 'text/html': + message_body = HTMLBody(alternative[0]) + break + + email_message = Message( + account=self._connection, subject=email_message.subject, + body=message_body, to_recipients=recipients, sender=from_email, + attachments=[] + ) + email_message.attach(attachments) + email_message.send_and_save() + except Exception as error: + if not self.fail_silently: + raise error + return False + return True diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index aebb73741..4fdba8b97 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -331,6 +331,7 @@ if DEBUG_DEV: FIXTURE_DIRS = [os.path.join(BASE_DIR, 'fixtures'), ] # Email config +EMAIL_PROTOCOL = CONFIG.EMAIL_PROTOCOL EMAIL_HOST = CONFIG.EMAIL_HOST EMAIL_PORT = CONFIG.EMAIL_PORT EMAIL_HOST_USER = CONFIG.EMAIL_HOST_USER diff --git a/apps/settings/api/email.py b/apps/settings/api/email.py index 1e8ef2286..3790752d5 100644 --- a/apps/settings/api/email.py +++ b/apps/settings/api/email.py @@ -4,11 +4,12 @@ from smtplib import SMTPSenderRefused from django.conf import settings -from django.core.mail import send_mail, get_connection +from django.core.mail import send_mail from django.utils.translation import gettext_lazy as _ from rest_framework.views import Response, APIView from common.utils import get_logger +from common.tasks import get_email_connection as get_connection from .. import serializers logger = get_logger(__file__) diff --git a/apps/settings/serializers/msg.py b/apps/settings/serializers/msg.py index 07e8e7205..ace4ab42c 100644 --- a/apps/settings/serializers/msg.py +++ b/apps/settings/serializers/msg.py @@ -1,11 +1,12 @@ # coding: utf-8 # - +from django.db import models from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField + __all__ = [ 'MailTestSerializer', 'EmailSettingSerializer', 'EmailContentSettingSerializer', 'SMSBackendSerializer', @@ -18,14 +19,20 @@ class MailTestSerializer(serializers.Serializer): class EmailSettingSerializer(serializers.Serializer): - # encrypt_fields 现在使用 write_only 来判断了 PREFIX_TITLE = _('Email') - EMAIL_HOST = serializers.CharField(max_length=1024, required=True, label=_("SMTP host")) - EMAIL_PORT = serializers.CharField(max_length=5, required=True, label=_("SMTP port")) - EMAIL_HOST_USER = serializers.CharField(max_length=128, required=True, label=_("SMTP account")) + class EmailProtocol(models.TextChoices): + smtp = 'smtp', _('SMTP') + exchange = 'exchange', _('EXCHANGE') + + EMAIL_PROTOCOL = serializers.ChoiceField( + choices=EmailProtocol.choices, label=_("Protocol"), default=EmailProtocol.smtp + ) + EMAIL_HOST = serializers.CharField(max_length=1024, required=True, label=_("Host")) + EMAIL_PORT = serializers.CharField(max_length=5, required=True, label=_("Port")) + EMAIL_HOST_USER = serializers.CharField(max_length=128, required=True, label=_("Account")) EMAIL_HOST_PASSWORD = EncryptedField( - max_length=1024, required=False, label=_("SMTP password"), + max_length=1024, required=False, label=_("Password"), help_text=_("Tips: Some provider use token except password") ) EMAIL_FROM = serializers.CharField( From b4c1dd29445e2dd17ed410478fa720c1efade6a0 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Tue, 2 Jan 2024 18:22:26 +0800 Subject: [PATCH 12/41] =?UTF-8?q?perf:=20slack=E6=B6=88=E6=81=AF=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E4=BC=98=E5=8C=96-mistune=E5=8D=87=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/sdk/im/slack/__init__.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/common/sdk/im/slack/__init__.py b/apps/common/sdk/im/slack/__init__.py index bea92e78e..06de4f04f 100644 --- a/apps/common/sdk/im/slack/__init__.py +++ b/apps/common/sdk/im/slack/__init__.py @@ -22,15 +22,15 @@ class URL: AUTH_TEST = 'https://slack.com/api/auth.test' -class SlackRenderer(mistune.Renderer): - def header(self, text, level, raw=None): +class SlackRenderer(mistune.renderers.HTMLRenderer): + def heading(self, text, level): return '*' + text + '*\n' - def double_emphasis(self, text): + def strong(self, text): return '*' + text + '*' - def list(self, body, ordered=True): - lines = body.split('\n') + def list(self, text, **kwargs): + lines = text.split('\n') for i, line in enumerate(lines): if not line: continue @@ -41,9 +41,9 @@ class SlackRenderer(mistune.Renderer): def block_code(self, code, lang=None): return f'`{code}`' - def link(self, link, title, content): - if title or content: - label = str(title or content).strip() + def link(self, link, text=None, title=None): + if title or text: + label = str(title or text).strip() return f'<{link}|{label}>' return f'<{link}>' From b57e94399089288d0184b10ed120c03a316b050e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Tue, 2 Jan 2024 15:26:14 +0800 Subject: [PATCH 13/41] =?UTF-8?q?build(deps):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 1280 ++++++++++++++++++++++++------------------------ pyproject.toml | 9 +- 2 files changed, 645 insertions(+), 644 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3be1006b6..d11c14093 100644 --- a/poetry.lock +++ b/poetry.lock @@ -40,98 +40,111 @@ reference = "tsinghua" [[package]] name = "aiohttp" -version = "3.9.1" +version = "3.8.6" description = "Async http client/server framework (asyncio)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.6" files = [ - {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1f80197f8b0b846a8d5cf7b7ec6084493950d0882cc5537fb7b96a69e3c8590"}, - {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72444d17777865734aa1a4d167794c34b63e5883abb90356a0364a28904e6c0"}, - {file = "aiohttp-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b05d5cbe9dafcdc733262c3a99ccf63d2f7ce02543620d2bd8db4d4f7a22f83"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c4fa235d534b3547184831c624c0b7c1e262cd1de847d95085ec94c16fddcd5"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:289ba9ae8e88d0ba16062ecf02dd730b34186ea3b1e7489046fc338bdc3361c4"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bff7e2811814fa2271be95ab6e84c9436d027a0e59665de60edf44e529a42c1f"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81b77f868814346662c96ab36b875d7814ebf82340d3284a31681085c051320f"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b9c7426923bb7bd66d409da46c41e3fb40f5caf679da624439b9eba92043fa6"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8d44e7bf06b0c0a70a20f9100af9fcfd7f6d9d3913e37754c12d424179b4e48f"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22698f01ff5653fe66d16ffb7658f582a0ac084d7da1323e39fd9eab326a1f26"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ca7ca5abfbfe8d39e653870fbe8d7710be7a857f8a8386fc9de1aae2e02ce7e4"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8d7f98fde213f74561be1d6d3fa353656197f75d4edfbb3d94c9eb9b0fc47f5d"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5216b6082c624b55cfe79af5d538e499cd5f5b976820eac31951fb4325974501"}, - {file = "aiohttp-3.9.1-cp310-cp310-win32.whl", hash = "sha256:0e7ba7ff228c0d9a2cd66194e90f2bca6e0abca810b786901a569c0de082f489"}, - {file = "aiohttp-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:c7e939f1ae428a86e4abbb9a7c4732bf4706048818dfd979e5e2839ce0159f23"}, - {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df9cf74b9bc03d586fc53ba470828d7b77ce51b0582d1d0b5b2fb673c0baa32d"}, - {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecca113f19d5e74048c001934045a2b9368d77b0b17691d905af18bd1c21275e"}, - {file = "aiohttp-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8cef8710fb849d97c533f259103f09bac167a008d7131d7b2b0e3a33269185c0"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea94403a21eb94c93386d559bce297381609153e418a3ffc7d6bf772f59cc35"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91c742ca59045dce7ba76cab6e223e41d2c70d79e82c284a96411f8645e2afff"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c93b7c2e52061f0925c3382d5cb8980e40f91c989563d3d32ca280069fd6a87"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee2527134f95e106cc1653e9ac78846f3a2ec1004cf20ef4e02038035a74544d"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11ff168d752cb41e8492817e10fb4f85828f6a0142b9726a30c27c35a1835f01"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b8c3a67eb87394386847d188996920f33b01b32155f0a94f36ca0e0c635bf3e3"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c7b5d5d64e2a14e35a9240b33b89389e0035e6de8dbb7ffa50d10d8b65c57449"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:69985d50a2b6f709412d944ffb2e97d0be154ea90600b7a921f95a87d6f108a2"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c9110c06eaaac7e1f5562caf481f18ccf8f6fdf4c3323feab28a93d34cc646bd"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737e69d193dac7296365a6dcb73bbbf53bb760ab25a3727716bbd42022e8d7a"}, - {file = "aiohttp-3.9.1-cp311-cp311-win32.whl", hash = "sha256:4ee8caa925aebc1e64e98432d78ea8de67b2272252b0a931d2ac3bd876ad5544"}, - {file = "aiohttp-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a34086c5cc285be878622e0a6ab897a986a6e8bf5b67ecb377015f06ed316587"}, - {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f800164276eec54e0af5c99feb9494c295118fc10a11b997bbb1348ba1a52065"}, - {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:500f1c59906cd142d452074f3811614be04819a38ae2b3239a48b82649c08821"}, - {file = "aiohttp-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0b0a6a36ed7e164c6df1e18ee47afbd1990ce47cb428739d6c99aaabfaf1b3af"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69da0f3ed3496808e8cbc5123a866c41c12c15baaaead96d256477edf168eb57"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176df045597e674fa950bf5ae536be85699e04cea68fa3a616cf75e413737eb5"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b796b44111f0cab6bbf66214186e44734b5baab949cb5fb56154142a92989aeb"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f27fdaadce22f2ef950fc10dcdf8048407c3b42b73779e48a4e76b3c35bca26c"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcb6532b9814ea7c5a6a3299747c49de30e84472fa72821b07f5a9818bce0f66"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:54631fb69a6e44b2ba522f7c22a6fb2667a02fd97d636048478db2fd8c4e98fe"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4b4c452d0190c5a820d3f5c0f3cd8a28ace48c54053e24da9d6041bf81113183"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:cae4c0c2ca800c793cae07ef3d40794625471040a87e1ba392039639ad61ab5b"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:565760d6812b8d78d416c3c7cfdf5362fbe0d0d25b82fed75d0d29e18d7fc30f"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54311eb54f3a0c45efb9ed0d0a8f43d1bc6060d773f6973efd90037a51cd0a3f"}, - {file = "aiohttp-3.9.1-cp312-cp312-win32.whl", hash = "sha256:85c3e3c9cb1d480e0b9a64c658cd66b3cfb8e721636ab8b0e746e2d79a7a9eed"}, - {file = "aiohttp-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:11cb254e397a82efb1805d12561e80124928e04e9c4483587ce7390b3866d213"}, - {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a22a34bc594d9d24621091d1b91511001a7eea91d6652ea495ce06e27381f70"}, - {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:598db66eaf2e04aa0c8900a63b0101fdc5e6b8a7ddd805c56d86efb54eb66672"}, - {file = "aiohttp-3.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c9376e2b09895c8ca8b95362283365eb5c03bdc8428ade80a864160605715f1"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41473de252e1797c2d2293804e389a6d6986ef37cbb4a25208de537ae32141dd"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c5857612c9813796960c00767645cb5da815af16dafb32d70c72a8390bbf690"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffcd828e37dc219a72c9012ec44ad2e7e3066bec6ff3aaa19e7d435dbf4032ca"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:219a16763dc0294842188ac8a12262b5671817042b35d45e44fd0a697d8c8361"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f694dc8a6a3112059258a725a4ebe9acac5fe62f11c77ac4dcf896edfa78ca28"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bcc0ea8d5b74a41b621ad4a13d96c36079c81628ccc0b30cfb1603e3dfa3a014"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:90ec72d231169b4b8d6085be13023ece8fa9b1bb495e4398d847e25218e0f431"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cf2a0ac0615842b849f40c4d7f304986a242f1e68286dbf3bd7a835e4f83acfd"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:0e49b08eafa4f5707ecfb321ab9592717a319e37938e301d462f79b4e860c32a"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c59e0076ea31c08553e868cec02d22191c086f00b44610f8ab7363a11a5d9d8"}, - {file = "aiohttp-3.9.1-cp38-cp38-win32.whl", hash = "sha256:4831df72b053b1eed31eb00a2e1aff6896fb4485301d4ccb208cac264b648db4"}, - {file = "aiohttp-3.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:3135713c5562731ee18f58d3ad1bf41e1d8883eb68b363f2ffde5b2ea4b84cc7"}, - {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cfeadf42840c1e870dc2042a232a8748e75a36b52d78968cda6736de55582766"}, - {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:70907533db712f7aa791effb38efa96f044ce3d4e850e2d7691abd759f4f0ae0"}, - {file = "aiohttp-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdefe289681507187e375a5064c7599f52c40343a8701761c802c1853a504558"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7481f581251bb5558ba9f635db70908819caa221fc79ee52a7f58392778c636"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49f0c1b3c2842556e5de35f122fc0f0b721334ceb6e78c3719693364d4af8499"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d406b01a9f5a7e232d1b0d161b40c05275ffbcbd772dc18c1d5a570961a1ca4"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d8e4450e7fe24d86e86b23cc209e0023177b6d59502e33807b732d2deb6975f"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c0266cd6f005e99f3f51e583012de2778e65af6b73860038b968a0a8888487a"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab221850108a4a063c5b8a70f00dd7a1975e5a1713f87f4ab26a46e5feac5a0e"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c88a15f272a0ad3d7773cf3a37cc7b7d077cbfc8e331675cf1346e849d97a4e5"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:237533179d9747080bcaad4d02083ce295c0d2eab3e9e8ce103411a4312991a0"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:02ab6006ec3c3463b528374c4cdce86434e7b89ad355e7bf29e2f16b46c7dd6f"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04fa38875e53eb7e354ece1607b1d2fdee2d175ea4e4d745f6ec9f751fe20c7c"}, - {file = "aiohttp-3.9.1-cp39-cp39-win32.whl", hash = "sha256:82eefaf1a996060602f3cc1112d93ba8b201dbf5d8fd9611227de2003dddb3b7"}, - {file = "aiohttp-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:9b05d33ff8e6b269e30a7957bd3244ffbce2a7a35a81b81c382629b80af1a8bf"}, - {file = "aiohttp-3.9.1.tar.gz", hash = "sha256:8fc49a87ac269d4529da45871e2ffb6874e87779c3d0e2ccd813c0899221239d"}, + {file = "aiohttp-3.8.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:41d55fc043954cddbbd82503d9cc3f4814a40bcef30b3569bc7b5e34130718c1"}, + {file = "aiohttp-3.8.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1d84166673694841d8953f0a8d0c90e1087739d24632fe86b1a08819168b4566"}, + {file = "aiohttp-3.8.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:253bf92b744b3170eb4c4ca2fa58f9c4b87aeb1df42f71d4e78815e6e8b73c9e"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fd194939b1f764d6bb05490987bfe104287bbf51b8d862261ccf66f48fb4096"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c5f938d199a6fdbdc10bbb9447496561c3a9a565b43be564648d81e1102ac22"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2817b2f66ca82ee699acd90e05c95e79bbf1dc986abb62b61ec8aaf851e81c93"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fa375b3d34e71ccccf172cab401cd94a72de7a8cc01847a7b3386204093bb47"}, + {file = "aiohttp-3.8.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9de50a199b7710fa2904be5a4a9b51af587ab24c8e540a7243ab737b45844543"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e1d8cb0b56b3587c5c01de3bf2f600f186da7e7b5f7353d1bf26a8ddca57f965"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8e31e9db1bee8b4f407b77fd2507337a0a80665ad7b6c749d08df595d88f1cf5"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7bc88fc494b1f0311d67f29fee6fd636606f4697e8cc793a2d912ac5b19aa38d"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ec00c3305788e04bf6d29d42e504560e159ccaf0be30c09203b468a6c1ccd3b2"}, + {file = "aiohttp-3.8.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad1407db8f2f49329729564f71685557157bfa42b48f4b93e53721a16eb813ed"}, + {file = "aiohttp-3.8.6-cp310-cp310-win32.whl", hash = "sha256:ccc360e87341ad47c777f5723f68adbb52b37ab450c8bc3ca9ca1f3e849e5fe2"}, + {file = "aiohttp-3.8.6-cp310-cp310-win_amd64.whl", hash = "sha256:93c15c8e48e5e7b89d5cb4613479d144fda8344e2d886cf694fd36db4cc86865"}, + {file = "aiohttp-3.8.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e2f9cc8e5328f829f6e1fb74a0a3a939b14e67e80832975e01929e320386b34"}, + {file = "aiohttp-3.8.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e6a00ffcc173e765e200ceefb06399ba09c06db97f401f920513a10c803604ca"}, + {file = "aiohttp-3.8.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:41bdc2ba359032e36c0e9de5a3bd00d6fb7ea558a6ce6b70acedf0da86458321"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14cd52ccf40006c7a6cd34a0f8663734e5363fd981807173faf3a017e202fec9"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2d5b785c792802e7b275c420d84f3397668e9d49ab1cb52bd916b3b3ffcf09ad"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1bed815f3dc3d915c5c1e556c397c8667826fbc1b935d95b0ad680787896a358"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96603a562b546632441926cd1293cfcb5b69f0b4159e6077f7c7dbdfb686af4d"}, + {file = "aiohttp-3.8.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d76e8b13161a202d14c9584590c4df4d068c9567c99506497bdd67eaedf36403"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e3f1e3f1a1751bb62b4a1b7f4e435afcdade6c17a4fd9b9d43607cebd242924a"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:76b36b3124f0223903609944a3c8bf28a599b2cc0ce0be60b45211c8e9be97f8"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a2ece4af1f3c967a4390c284797ab595a9f1bc1130ef8b01828915a05a6ae684"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:16d330b3b9db87c3883e565340d292638a878236418b23cc8b9b11a054aaa887"}, + {file = "aiohttp-3.8.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:42c89579f82e49db436b69c938ab3e1559e5a4409eb8639eb4143989bc390f2f"}, + {file = "aiohttp-3.8.6-cp311-cp311-win32.whl", hash = "sha256:efd2fcf7e7b9d7ab16e6b7d54205beded0a9c8566cb30f09c1abe42b4e22bdcb"}, + {file = "aiohttp-3.8.6-cp311-cp311-win_amd64.whl", hash = "sha256:3b2ab182fc28e7a81f6c70bfbd829045d9480063f5ab06f6e601a3eddbbd49a0"}, + {file = "aiohttp-3.8.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fdee8405931b0615220e5ddf8cd7edd8592c606a8e4ca2a00704883c396e4479"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d25036d161c4fe2225d1abff2bd52c34ed0b1099f02c208cd34d8c05729882f0"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d791245a894be071d5ab04bbb4850534261a7d4fd363b094a7b9963e8cdbd31"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0cccd1de239afa866e4ce5c789b3032442f19c261c7d8a01183fd956b1935349"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f13f60d78224f0dace220d8ab4ef1dbc37115eeeab8c06804fec11bec2bbd07"}, + {file = "aiohttp-3.8.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a9b5a0606faca4f6cc0d338359d6fa137104c337f489cd135bb7fbdbccb1e39"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:13da35c9ceb847732bf5c6c5781dcf4780e14392e5d3b3c689f6d22f8e15ae31"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:4d4cbe4ffa9d05f46a28252efc5941e0462792930caa370a6efaf491f412bc66"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:229852e147f44da0241954fc6cb910ba074e597f06789c867cb7fb0621e0ba7a"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:713103a8bdde61d13490adf47171a1039fd880113981e55401a0f7b42c37d071"}, + {file = "aiohttp-3.8.6-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:45ad816b2c8e3b60b510f30dbd37fe74fd4a772248a52bb021f6fd65dff809b6"}, + {file = "aiohttp-3.8.6-cp36-cp36m-win32.whl", hash = "sha256:2b8d4e166e600dcfbff51919c7a3789ff6ca8b3ecce16e1d9c96d95dd569eb4c"}, + {file = "aiohttp-3.8.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0912ed87fee967940aacc5306d3aa8ba3a459fcd12add0b407081fbefc931e53"}, + {file = "aiohttp-3.8.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e2a988a0c673c2e12084f5e6ba3392d76c75ddb8ebc6c7e9ead68248101cd446"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebf3fd9f141700b510d4b190094db0ce37ac6361a6806c153c161dc6c041ccda"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3161ce82ab85acd267c8f4b14aa226047a6bee1e4e6adb74b798bd42c6ae1f80"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d95fc1bf33a9a81469aa760617b5971331cdd74370d1214f0b3109272c0e1e3c"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c43ecfef7deaf0617cee936836518e7424ee12cb709883f2c9a1adda63cc460"}, + {file = "aiohttp-3.8.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca80e1b90a05a4f476547f904992ae81eda5c2c85c66ee4195bb8f9c5fb47f28"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:90c72ebb7cb3a08a7f40061079817133f502a160561d0675b0a6adf231382c92"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bb54c54510e47a8c7c8e63454a6acc817519337b2b78606c4e840871a3e15349"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:de6a1c9f6803b90e20869e6b99c2c18cef5cc691363954c93cb9adeb26d9f3ae"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:a3628b6c7b880b181a3ae0a0683698513874df63783fd89de99b7b7539e3e8a8"}, + {file = "aiohttp-3.8.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fc37e9aef10a696a5a4474802930079ccfc14d9f9c10b4662169671ff034b7df"}, + {file = "aiohttp-3.8.6-cp37-cp37m-win32.whl", hash = "sha256:f8ef51e459eb2ad8e7a66c1d6440c808485840ad55ecc3cafefadea47d1b1ba2"}, + {file = "aiohttp-3.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:b2fe42e523be344124c6c8ef32a011444e869dc5f883c591ed87f84339de5976"}, + {file = "aiohttp-3.8.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9e2ee0ac5a1f5c7dd3197de309adfb99ac4617ff02b0603fd1e65b07dc772e4b"}, + {file = "aiohttp-3.8.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01770d8c04bd8db568abb636c1fdd4f7140b284b8b3e0b4584f070180c1e5c62"}, + {file = "aiohttp-3.8.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3c68330a59506254b556b99a91857428cab98b2f84061260a67865f7f52899f5"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89341b2c19fb5eac30c341133ae2cc3544d40d9b1892749cdd25892bbc6ac951"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71783b0b6455ac8f34b5ec99d83e686892c50498d5d00b8e56d47f41b38fbe04"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f628dbf3c91e12f4d6c8b3f092069567d8eb17814aebba3d7d60c149391aee3a"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04691bc6601ef47c88f0255043df6f570ada1a9ebef99c34bd0b72866c217ae"}, + {file = "aiohttp-3.8.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ee912f7e78287516df155f69da575a0ba33b02dd7c1d6614dbc9463f43066e3"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9c19b26acdd08dd239e0d3669a3dddafd600902e37881f13fbd8a53943079dbc"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:99c5ac4ad492b4a19fc132306cd57075c28446ec2ed970973bbf036bcda1bcc6"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f0f03211fd14a6a0aed2997d4b1c013d49fb7b50eeb9ffdf5e51f23cfe2c77fa"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:8d399dade330c53b4106160f75f55407e9ae7505263ea86f2ccca6bfcbdb4921"}, + {file = "aiohttp-3.8.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ec4fd86658c6a8964d75426517dc01cbf840bbf32d055ce64a9e63a40fd7b771"}, + {file = "aiohttp-3.8.6-cp38-cp38-win32.whl", hash = "sha256:33164093be11fcef3ce2571a0dccd9041c9a93fa3bde86569d7b03120d276c6f"}, + {file = "aiohttp-3.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:bdf70bfe5a1414ba9afb9d49f0c912dc524cf60141102f3a11143ba3d291870f"}, + {file = "aiohttp-3.8.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d52d5dc7c6682b720280f9d9db41d36ebe4791622c842e258c9206232251ab2b"}, + {file = "aiohttp-3.8.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ac39027011414dbd3d87f7edb31680e1f430834c8cef029f11c66dad0670aa5"}, + {file = "aiohttp-3.8.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3f5c7ce535a1d2429a634310e308fb7d718905487257060e5d4598e29dc17f0b"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b30e963f9e0d52c28f284d554a9469af073030030cef8693106d918b2ca92f54"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:918810ef188f84152af6b938254911055a72e0f935b5fbc4c1a4ed0b0584aed1"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:002f23e6ea8d3dd8d149e569fd580c999232b5fbc601c48d55398fbc2e582e8c"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fcf3eabd3fd1a5e6092d1242295fa37d0354b2eb2077e6eb670accad78e40e1"}, + {file = "aiohttp-3.8.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:255ba9d6d5ff1a382bb9a578cd563605aa69bec845680e21c44afc2670607a95"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d67f8baed00870aa390ea2590798766256f31dc5ed3ecc737debb6e97e2ede78"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:86f20cee0f0a317c76573b627b954c412ea766d6ada1a9fcf1b805763ae7feeb"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:39a312d0e991690ccc1a61f1e9e42daa519dcc34ad03eb6f826d94c1190190dd"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e827d48cf802de06d9c935088c2924e3c7e7533377d66b6f31ed175c1620e05e"}, + {file = "aiohttp-3.8.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd111d7fc5591ddf377a408ed9067045259ff2770f37e2d94e6478d0f3fc0c17"}, + {file = "aiohttp-3.8.6-cp39-cp39-win32.whl", hash = "sha256:caf486ac1e689dda3502567eb89ffe02876546599bbf915ec94b1fa424eeffd4"}, + {file = "aiohttp-3.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:3f0e27e5b733803333bb2371249f41cf42bae8884863e8e8965ec69bebe53132"}, + {file = "aiohttp-3.8.6.tar.gz", hash = "sha256:b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c"}, ] [package.dependencies] aiosignal = ">=1.1.2" +async-timeout = ">=4.0.0a3,<5.0" attrs = ">=17.3.0" +charset-normalizer = ">=2.0,<4.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" yarl = ">=1.0,<2.0" [package.extras] -speedups = ["Brotli", "aiodns", "brotlicffi"] +speedups = ["Brotli", "aiodns", "cchardet"] [package.source] type = "legacy" @@ -254,16 +267,16 @@ reference = "tsinghua" [[package]] name = "alibabacloud-tea" -version = "0.3.3" +version = "0.3.5" description = "The tea module of alibabaCloud Python SDK." optional = false python-versions = ">=3.6" files = [ - {file = "alibabacloud-tea-0.3.3.tar.gz", hash = "sha256:90f1b3310552f7cb004f713e2b55d129acd4a885bd79342df6d621422de23775"}, + {file = "alibabacloud-tea-0.3.5.tar.gz", hash = "sha256:25a5d14ed955301e381e966f66de961544356a04ba954fcf65f007f75a5c3c26"}, ] [package.dependencies] -aiohttp = ">=3.7.0,<4.0.0" +aiohttp = ">=3.7.0,<3.9.0" requests = ">=2.21.0,<3.0.0" urllib3 = "<2.0.0" @@ -506,13 +519,13 @@ reference = "tsinghua" [[package]] name = "anyio" -version = "3.7.1" +version = "4.2.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, + {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, + {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, ] [package.dependencies] @@ -520,9 +533,9 @@ idna = ">=2.8" sniffio = ">=1.1" [package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] [package.source] type = "legacy" @@ -621,21 +634,22 @@ reference = "tsinghua" [[package]] name = "attrs" -version = "23.1.0" +version = "23.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] +dev = ["attrs[tests]", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [package.source] type = "legacy" @@ -716,17 +730,18 @@ reference = "tsinghua" [[package]] name = "azure-core" -version = "1.29.5" +version = "1.29.6" description = "Microsoft Azure Core Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "azure-core-1.29.5.tar.gz", hash = "sha256:52983c89d394c6f881a121e5101c5fa67278ca3b1f339c8fb2ef39230c70e9ac"}, - {file = "azure_core-1.29.5-py3-none-any.whl", hash = "sha256:0fa04b7b1f7d44a4fb8468c4093deb2ea01fdf4faddbf802ed9205615f99d68c"}, + {file = "azure-core-1.29.6.tar.gz", hash = "sha256:13b485252ecd9384ae624894fe51cfa6220966207264c360beada239f88b738a"}, + {file = "azure_core-1.29.6-py3-none-any.whl", hash = "sha256:604a005bce6a49ba661bb7b2be84a9b169047e52fcfcd0a4e4770affab4178f7"}, ] [package.dependencies] -requests = ">=2.18.4" +anyio = ">=3.0,<5.0" +requests = ">=2.21.0" six = ">=1.11.0" typing-extensions = ">=4.6.0" @@ -1798,13 +1813,13 @@ reference = "tsinghua" [[package]] name = "distro" -version = "1.8.0" +version = "1.9.0" description = "Distro - an OS platform information API" optional = false python-versions = ">=3.6" files = [ - {file = "distro-1.8.0-py3-none-any.whl", hash = "sha256:99522ca3e365cac527b44bde033f64c6945d90eb9f769703caaec52b09bbd3ff"}, - {file = "distro-1.8.0.tar.gz", hash = "sha256:02e111d1dc6a50abb8eed6bf31c3e48ed8b0830d1ea2a1b78c61765c2513fdd8"}, + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, ] [package.source] @@ -1814,13 +1829,13 @@ reference = "tsinghua" [[package]] name = "django" -version = "4.1.10" +version = "4.1.13" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.8" files = [ - {file = "Django-4.1.10-py3-none-any.whl", hash = "sha256:26d0260c2fb8121009e62ffc548b2398dea2522b6454208a852fb0ef264c206c"}, - {file = "Django-4.1.10.tar.gz", hash = "sha256:56343019a9fd839e2e5bf203daf45f25af79d5bffa4c71d56eae4f4404d82ade"}, + {file = "Django-4.1.13-py3-none-any.whl", hash = "sha256:04ab3f6f46d084a0bba5a2c9a93a3a2eb3fe81589512367a75f79ee8acf790ce"}, + {file = "Django-4.1.13.tar.gz", hash = "sha256:94a3f471e833c8f124ee7a2de11e92f633991d975e3fa5bdd91e8abd66426318"}, ] [package.dependencies] @@ -1921,16 +1936,17 @@ reference = "tsinghua" [[package]] name = "django-cors-headers" -version = "4.3.0" +version = "4.3.1" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." optional = false python-versions = ">=3.8" files = [ - {file = "django_cors_headers-4.3.0-py3-none-any.whl", hash = "sha256:bd36c7aea0d070e462f3383f0dc9ef717e5fdc2b10a99c98c285f16da84ffba2"}, - {file = "django_cors_headers-4.3.0.tar.gz", hash = "sha256:25aabc94d4837678c1edf442c7f68a5f5fd151f6767b0e0b01c61a2179d02711"}, + {file = "django-cors-headers-4.3.1.tar.gz", hash = "sha256:0bf65ef45e606aff1994d35503e6b677c0b26cafff6506f8fd7187f3be840207"}, + {file = "django_cors_headers-4.3.1-py3-none-any.whl", hash = "sha256:0b1fd19297e37417fc9f835d39e45c8c642938ddba1acce0c1753d3edef04f36"}, ] [package.dependencies] +asgiref = ">=3.6" Django = ">=3.2" [package.source] @@ -2604,72 +2620,88 @@ reference = "tsinghua" [[package]] name = "frozenlist" -version = "1.4.0" +version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" files = [ - {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab"}, - {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559"}, - {file = "frozenlist-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62"}, - {file = "frozenlist-1.4.0-cp310-cp310-win32.whl", hash = "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0"}, - {file = "frozenlist-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb"}, - {file = "frozenlist-1.4.0-cp311-cp311-win32.whl", hash = "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431"}, - {file = "frozenlist-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8"}, - {file = "frozenlist-1.4.0-cp38-cp38-win32.whl", hash = "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc"}, - {file = "frozenlist-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3"}, - {file = "frozenlist-1.4.0-cp39-cp39-win32.whl", hash = "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f"}, - {file = "frozenlist-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167"}, - {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, ] [package.source] @@ -2733,13 +2765,13 @@ reference = "tsinghua" [[package]] name = "google-api-core" -version = "2.14.0" +version = "2.15.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google-api-core-2.14.0.tar.gz", hash = "sha256:5368a4502b793d9bbf812a5912e13e4e69f9bd87f6efb508460c43f5bbd1ce41"}, - {file = "google_api_core-2.14.0-py3-none-any.whl", hash = "sha256:de2fb50ed34d47ddbb2bd2dcf680ee8fead46279f4ed6b16de362aca23a18952"}, + {file = "google-api-core-2.15.0.tar.gz", hash = "sha256:abc978a72658f14a2df1e5e12532effe40f94f868f6e23d95133bd6abcca35ca"}, + {file = "google_api_core-2.15.0-py3-none-any.whl", hash = "sha256:2aa56d2be495551e66bbff7f729b790546f87d5c90e74781aa77233bcb395a8a"}, ] [package.dependencies] @@ -2762,13 +2794,13 @@ reference = "tsinghua" [[package]] name = "google-auth" -version = "2.23.4" +version = "2.25.2" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google-auth-2.23.4.tar.gz", hash = "sha256:79905d6b1652187def79d491d6e23d0cbb3a21d3c7ba0dbaa9c8a01906b13ff3"}, - {file = "google_auth-2.23.4-py2.py3-none-any.whl", hash = "sha256:d4bbc92fe4b8bfd2f3e8d88e5ba7085935da208ee38a134fc280e7ce682a05f2"}, + {file = "google-auth-2.25.2.tar.gz", hash = "sha256:42f707937feb4f5e5a39e6c4f343a17300a459aaf03141457ba505812841cc40"}, + {file = "google_auth-2.25.2-py2.py3-none-any.whl", hash = "sha256:473a8dfd0135f75bb79d878436e568f2695dce456764bf3a02b6f8c540b1d256"}, ] [package.dependencies] @@ -2790,18 +2822,18 @@ reference = "tsinghua" [[package]] name = "google-cloud-compute" -version = "1.13.0" +version = "1.15.0" description = "Google Cloud Compute API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-compute-1.13.0.tar.gz", hash = "sha256:93b72129c6443c898da5a060d2021bc2d11c2a57ef2fbb9306afbb5126a376b9"}, - {file = "google_cloud_compute-1.13.0-py2.py3-none-any.whl", hash = "sha256:0f75d6c09cc504e43f4eceb2a466de9e9eb6fca819ca8ffdcf098ca5b21c7dc1"}, + {file = "google-cloud-compute-1.15.0.tar.gz", hash = "sha256:fa675aeaf04c627a442cd3032196d6f36ad68443ba327c9767a6bfbc40a42b21"}, + {file = "google_cloud_compute-1.15.0-py2.py3-none-any.whl", hash = "sha256:9eb39cae22c32c89c20c7e4f44635a7c5985a558c89f279e0f6e97edeb291e8f"}, ] [package.dependencies] google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} -proto-plus = {version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""} +proto-plus = ">=1.22.3,<2.0.0dev" protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" [package.source] @@ -2811,13 +2843,13 @@ reference = "tsinghua" [[package]] name = "googleapis-common-protos" -version = "1.61.0" +version = "1.62.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.61.0.tar.gz", hash = "sha256:8a64866a97f6304a7179873a465d6eee97b7a24ec6cfd78e0f575e96b821240b"}, - {file = "googleapis_common_protos-1.61.0-py2.py3-none-any.whl", hash = "sha256:22f1915393bb3245343f6efe87f6fe868532efc12aa26b391b15132e1279f1c0"}, + {file = "googleapis-common-protos-1.62.0.tar.gz", hash = "sha256:83f0ece9f94e5672cced82f592d2a5edf527a96ed1794f0bab36d5735c996277"}, + {file = "googleapis_common_protos-1.62.0-py2.py3-none-any.whl", hash = "sha256:4750113612205514f9f6aa4cb00d523a94f3e8c06c5ad2fee466387dc4875f07"}, ] [package.dependencies] @@ -2908,60 +2940,69 @@ reference = "tsinghua" [[package]] name = "grpcio" -version = "1.56.2" +version = "1.60.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.7" files = [ - {file = "grpcio-1.56.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:bf0b9959e673505ee5869950642428046edb91f99942607c2ecf635f8a4b31c9"}, - {file = "grpcio-1.56.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:5144feb20fe76e73e60c7d73ec3bf54f320247d1ebe737d10672480371878b48"}, - {file = "grpcio-1.56.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:a72797549935c9e0b9bc1def1768c8b5a709538fa6ab0678e671aec47ebfd55e"}, - {file = "grpcio-1.56.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c3f3237a57e42f79f1e560726576aedb3a7ef931f4e3accb84ebf6acc485d316"}, - {file = "grpcio-1.56.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:900bc0096c2ca2d53f2e5cebf98293a7c32f532c4aeb926345e9747452233950"}, - {file = "grpcio-1.56.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:97e0efaebbfd222bcaac2f1735c010c1d3b167112d9d237daebbeedaaccf3d1d"}, - {file = "grpcio-1.56.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c0c85c5cbe8b30a32fa6d802588d55ffabf720e985abe9590c7c886919d875d4"}, - {file = "grpcio-1.56.2-cp310-cp310-win32.whl", hash = "sha256:06e84ad9ae7668a109e970c7411e7992751a116494cba7c4fb877656527f9a57"}, - {file = "grpcio-1.56.2-cp310-cp310-win_amd64.whl", hash = "sha256:10954662f77dc36c9a1fb5cc4a537f746580d6b5734803be1e587252682cda8d"}, - {file = "grpcio-1.56.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:c435f5ce1705de48e08fcbcfaf8aee660d199c90536e3e06f2016af7d6a938dd"}, - {file = "grpcio-1.56.2-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:6108e5933eb8c22cd3646e72d5b54772c29f57482fd4c41a0640aab99eb5071d"}, - {file = "grpcio-1.56.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:8391cea5ce72f4a12368afd17799474015d5d3dc00c936a907eb7c7eaaea98a5"}, - {file = "grpcio-1.56.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:750de923b456ca8c0f1354d6befca45d1f3b3a789e76efc16741bd4132752d95"}, - {file = "grpcio-1.56.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fda2783c12f553cdca11c08e5af6eecbd717280dc8fbe28a110897af1c15a88c"}, - {file = "grpcio-1.56.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9e04d4e4cfafa7c5264e535b5d28e786f0571bea609c3f0aaab13e891e933e9c"}, - {file = "grpcio-1.56.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:89a49cc5ad08a38b6141af17e00d1dd482dc927c7605bc77af457b5a0fca807c"}, - {file = "grpcio-1.56.2-cp311-cp311-win32.whl", hash = "sha256:6a007a541dff984264981fbafeb052bfe361db63578948d857907df9488d8774"}, - {file = "grpcio-1.56.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4063ef2b11b96d949dccbc5a987272f38d55c23c4c01841ea65a517906397f"}, - {file = "grpcio-1.56.2-cp37-cp37m-linux_armv7l.whl", hash = "sha256:a6ff459dac39541e6a2763a4439c4ca6bc9ecb4acc05a99b79246751f9894756"}, - {file = "grpcio-1.56.2-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:f20fd21f7538f8107451156dd1fe203300b79a9ddceba1ee0ac8132521a008ed"}, - {file = "grpcio-1.56.2-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:d1fbad1f9077372b6587ec589c1fc120b417b6c8ad72d3e3cc86bbbd0a3cee93"}, - {file = "grpcio-1.56.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ee26e9dfb3996aff7c870f09dc7ad44a5f6732b8bdb5a5f9905737ac6fd4ef1"}, - {file = "grpcio-1.56.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c60abd950d6de3e4f1ddbc318075654d275c29c846ab6a043d6ed2c52e4c8c"}, - {file = "grpcio-1.56.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1c31e52a04e62c8577a7bf772b3e7bed4df9c9e0dd90f92b6ffa07c16cab63c9"}, - {file = "grpcio-1.56.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:345356b307cce5d14355e8e055b4ca5f99bc857c33a3dc1ddbc544fca9cd0475"}, - {file = "grpcio-1.56.2-cp37-cp37m-win_amd64.whl", hash = "sha256:42e63904ee37ae46aa23de50dac8b145b3596f43598fa33fe1098ab2cbda6ff5"}, - {file = "grpcio-1.56.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:7c5ede2e2558f088c49a1ddda19080e4c23fb5d171de80a726b61b567e3766ed"}, - {file = "grpcio-1.56.2-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:33971197c47965cc1d97d78d842163c283e998223b151bab0499b951fd2c0b12"}, - {file = "grpcio-1.56.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d39f5d4af48c138cb146763eda14eb7d8b3ccbbec9fe86fb724cd16e0e914c64"}, - {file = "grpcio-1.56.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ded637176addc1d3eef35331c39acc598bac550d213f0a1bedabfceaa2244c87"}, - {file = "grpcio-1.56.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c90da4b124647547a68cf2f197174ada30c7bb9523cb976665dfd26a9963d328"}, - {file = "grpcio-1.56.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3ccb621749a81dc7755243665a70ce45536ec413ef5818e013fe8dfbf5aa497b"}, - {file = "grpcio-1.56.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4eb37dd8dd1aa40d601212afa27ca5be255ba792e2e0b24d67b8af5e012cdb7d"}, - {file = "grpcio-1.56.2-cp38-cp38-win32.whl", hash = "sha256:ddb4a6061933bd9332b74eac0da25f17f32afa7145a33a0f9711ad74f924b1b8"}, - {file = "grpcio-1.56.2-cp38-cp38-win_amd64.whl", hash = "sha256:8940d6de7068af018dfa9a959a3510e9b7b543f4c405e88463a1cbaa3b2b379a"}, - {file = "grpcio-1.56.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:51173e8fa6d9a2d85c14426bdee5f5c4a0654fd5fddcc21fe9d09ab0f6eb8b35"}, - {file = "grpcio-1.56.2-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:373b48f210f43327a41e397391715cd11cfce9ded2fe76a5068f9bacf91cc226"}, - {file = "grpcio-1.56.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:42a3bbb2bc07aef72a7d97e71aabecaf3e4eb616d39e5211e2cfe3689de860ca"}, - {file = "grpcio-1.56.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5344be476ac37eb9c9ad09c22f4ea193c1316bf074f1daf85bddb1b31fda5116"}, - {file = "grpcio-1.56.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3fa3ab0fb200a2c66493828ed06ccd1a94b12eddbfb985e7fd3e5723ff156c6"}, - {file = "grpcio-1.56.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b975b85d1d5efc36cf8b237c5f3849b64d1ba33d6282f5e991f28751317504a1"}, - {file = "grpcio-1.56.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cbdf2c498e077282cd427cfd88bdce4668019791deef0be8155385ab2ba7837f"}, - {file = "grpcio-1.56.2-cp39-cp39-win32.whl", hash = "sha256:139f66656a762572ae718fa0d1f2dce47c05e9fbf7a16acd704c354405b97df9"}, - {file = "grpcio-1.56.2-cp39-cp39-win_amd64.whl", hash = "sha256:830215173ad45d670140ff99aac3b461f9be9a6b11bee1a17265aaaa746a641a"}, - {file = "grpcio-1.56.2.tar.gz", hash = "sha256:0ff789ae7d8ddd76d2ac02e7d13bfef6fc4928ac01e1dcaa182be51b6bcc0aaa"}, + {file = "grpcio-1.60.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:d020cfa595d1f8f5c6b343530cd3ca16ae5aefdd1e832b777f9f0eb105f5b139"}, + {file = "grpcio-1.60.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b98f43fcdb16172dec5f4b49f2fece4b16a99fd284d81c6bbac1b3b69fcbe0ff"}, + {file = "grpcio-1.60.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:20e7a4f7ded59097c84059d28230907cd97130fa74f4a8bfd1d8e5ba18c81491"}, + {file = "grpcio-1.60.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:452ca5b4afed30e7274445dd9b441a35ece656ec1600b77fff8c216fdf07df43"}, + {file = "grpcio-1.60.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43e636dc2ce9ece583b3e2ca41df5c983f4302eabc6d5f9cd04f0562ee8ec1ae"}, + {file = "grpcio-1.60.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e306b97966369b889985a562ede9d99180def39ad42c8014628dd3cc343f508"}, + {file = "grpcio-1.60.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f897c3b127532e6befdcf961c415c97f320d45614daf84deba0a54e64ea2457b"}, + {file = "grpcio-1.60.0-cp310-cp310-win32.whl", hash = "sha256:b87efe4a380887425bb15f220079aa8336276398dc33fce38c64d278164f963d"}, + {file = "grpcio-1.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:a9c7b71211f066908e518a2ef7a5e211670761651039f0d6a80d8d40054047df"}, + {file = "grpcio-1.60.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:fb464479934778d7cc5baf463d959d361954d6533ad34c3a4f1d267e86ee25fd"}, + {file = "grpcio-1.60.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:4b44d7e39964e808b071714666a812049765b26b3ea48c4434a3b317bac82f14"}, + {file = "grpcio-1.60.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:90bdd76b3f04bdb21de5398b8a7c629676c81dfac290f5f19883857e9371d28c"}, + {file = "grpcio-1.60.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91229d7203f1ef0ab420c9b53fe2ca5c1fbeb34f69b3bc1b5089466237a4a134"}, + {file = "grpcio-1.60.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b36a2c6d4920ba88fa98075fdd58ff94ebeb8acc1215ae07d01a418af4c0253"}, + {file = "grpcio-1.60.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:297eef542156d6b15174a1231c2493ea9ea54af8d016b8ca7d5d9cc65cfcc444"}, + {file = "grpcio-1.60.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:87c9224acba0ad8bacddf427a1c2772e17ce50b3042a789547af27099c5f751d"}, + {file = "grpcio-1.60.0-cp311-cp311-win32.whl", hash = "sha256:95ae3e8e2c1b9bf671817f86f155c5da7d49a2289c5cf27a319458c3e025c320"}, + {file = "grpcio-1.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:467a7d31554892eed2aa6c2d47ded1079fc40ea0b9601d9f79204afa8902274b"}, + {file = "grpcio-1.60.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:a7152fa6e597c20cb97923407cf0934e14224af42c2b8d915f48bc3ad2d9ac18"}, + {file = "grpcio-1.60.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:7db16dd4ea1b05ada504f08d0dca1cd9b926bed3770f50e715d087c6f00ad748"}, + {file = "grpcio-1.60.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:b0571a5aef36ba9177e262dc88a9240c866d903a62799e44fd4aae3f9a2ec17e"}, + {file = "grpcio-1.60.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fd9584bf1bccdfff1512719316efa77be235469e1e3295dce64538c4773840b"}, + {file = "grpcio-1.60.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6a478581b1a1a8fdf3318ecb5f4d0cda41cacdffe2b527c23707c9c1b8fdb55"}, + {file = "grpcio-1.60.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:77c8a317f0fd5a0a2be8ed5cbe5341537d5c00bb79b3bb27ba7c5378ba77dbca"}, + {file = "grpcio-1.60.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1c30bb23a41df95109db130a6cc1b974844300ae2e5d68dd4947aacba5985aa5"}, + {file = "grpcio-1.60.0-cp312-cp312-win32.whl", hash = "sha256:2aef56e85901c2397bd557c5ba514f84de1f0ae5dd132f5d5fed042858115951"}, + {file = "grpcio-1.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:e381fe0c2aa6c03b056ad8f52f8efca7be29fb4d9ae2f8873520843b6039612a"}, + {file = "grpcio-1.60.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:92f88ca1b956eb8427a11bb8b4a0c0b2b03377235fc5102cb05e533b8693a415"}, + {file = "grpcio-1.60.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:e278eafb406f7e1b1b637c2cf51d3ad45883bb5bd1ca56bc05e4fc135dfdaa65"}, + {file = "grpcio-1.60.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:a48edde788b99214613e440fce495bbe2b1e142a7f214cce9e0832146c41e324"}, + {file = "grpcio-1.60.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de2ad69c9a094bf37c1102b5744c9aec6cf74d2b635558b779085d0263166454"}, + {file = "grpcio-1.60.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073f959c6f570797272f4ee9464a9997eaf1e98c27cb680225b82b53390d61e6"}, + {file = "grpcio-1.60.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c826f93050c73e7769806f92e601e0efdb83ec8d7c76ddf45d514fee54e8e619"}, + {file = "grpcio-1.60.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9e30be89a75ee66aec7f9e60086fadb37ff8c0ba49a022887c28c134341f7179"}, + {file = "grpcio-1.60.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b0fb2d4801546598ac5cd18e3ec79c1a9af8b8f2a86283c55a5337c5aeca4b1b"}, + {file = "grpcio-1.60.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:9073513ec380434eb8d21970e1ab3161041de121f4018bbed3146839451a6d8e"}, + {file = "grpcio-1.60.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:74d7d9fa97809c5b892449b28a65ec2bfa458a4735ddad46074f9f7d9550ad13"}, + {file = "grpcio-1.60.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:1434ca77d6fed4ea312901122dc8da6c4389738bf5788f43efb19a838ac03ead"}, + {file = "grpcio-1.60.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e61e76020e0c332a98290323ecfec721c9544f5b739fab925b6e8cbe1944cf19"}, + {file = "grpcio-1.60.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675997222f2e2f22928fbba640824aebd43791116034f62006e19730715166c0"}, + {file = "grpcio-1.60.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5208a57eae445ae84a219dfd8b56e04313445d146873117b5fa75f3245bc1390"}, + {file = "grpcio-1.60.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:428d699c8553c27e98f4d29fdc0f0edc50e9a8a7590bfd294d2edb0da7be3629"}, + {file = "grpcio-1.60.0-cp38-cp38-win32.whl", hash = "sha256:83f2292ae292ed5a47cdcb9821039ca8e88902923198f2193f13959360c01860"}, + {file = "grpcio-1.60.0-cp38-cp38-win_amd64.whl", hash = "sha256:705a68a973c4c76db5d369ed573fec3367d7d196673fa86614b33d8c8e9ebb08"}, + {file = "grpcio-1.60.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:c193109ca4070cdcaa6eff00fdb5a56233dc7610216d58fb81638f89f02e4968"}, + {file = "grpcio-1.60.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:676e4a44e740deaba0f4d95ba1d8c5c89a2fcc43d02c39f69450b1fa19d39590"}, + {file = "grpcio-1.60.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5ff21e000ff2f658430bde5288cb1ac440ff15c0d7d18b5fb222f941b46cb0d2"}, + {file = "grpcio-1.60.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c86343cf9ff7b2514dd229bdd88ebba760bd8973dac192ae687ff75e39ebfab"}, + {file = "grpcio-1.60.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fd3b3968ffe7643144580f260f04d39d869fcc2cddb745deef078b09fd2b328"}, + {file = "grpcio-1.60.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:30943b9530fe3620e3b195c03130396cd0ee3a0d10a66c1bee715d1819001eaf"}, + {file = "grpcio-1.60.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b10241250cb77657ab315270b064a6c7f1add58af94befa20687e7c8d8603ae6"}, + {file = "grpcio-1.60.0-cp39-cp39-win32.whl", hash = "sha256:79a050889eb8d57a93ed21d9585bb63fca881666fc709f5d9f7f9372f5e7fd03"}, + {file = "grpcio-1.60.0-cp39-cp39-win_amd64.whl", hash = "sha256:8a97a681e82bc11a42d4372fe57898d270a2707f36c45c6676e49ce0d5c41353"}, + {file = "grpcio-1.60.0.tar.gz", hash = "sha256:2199165a1affb666aa24adf0c97436686d0a61bc5fc113c037701fb7c7fceb96"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.56.2)"] +protobuf = ["grpcio-tools (>=1.60.0)"] [package.source] type = "legacy" @@ -2970,18 +3011,18 @@ reference = "tsinghua" [[package]] name = "grpcio-status" -version = "1.56.2" +version = "1.60.0" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.6" files = [ - {file = "grpcio-status-1.56.2.tar.gz", hash = "sha256:a046b2c0118df4a5687f4585cca9d3c3bae5c498c4dff055dcb43fb06a1180c8"}, - {file = "grpcio_status-1.56.2-py3-none-any.whl", hash = "sha256:63f3842867735f59f5d70e723abffd2e8501a6bcd915612a1119e52f10614782"}, + {file = "grpcio-status-1.60.0.tar.gz", hash = "sha256:f10e0b6db3adc0fdc244b71962814ee982996ef06186446b5695b9fa635aa1ab"}, + {file = "grpcio_status-1.60.0-py3-none-any.whl", hash = "sha256:7d383fa36e59c1e61d380d91350badd4d12ac56e4de2c2b831b050362c3c572e"}, ] [package.dependencies] googleapis-common-protos = ">=1.5.5" -grpcio = ">=1.56.2" +grpcio = ">=1.60.0" protobuf = ">=4.21.6" [package.source] @@ -3094,19 +3135,19 @@ reference = "tsinghua" [[package]] name = "httpx" -version = "0.25.1" +version = "0.26.0" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.25.1-py3-none-any.whl", hash = "sha256:fec7d6cc5c27c578a391f7e87b9aa7d3d8fbcd034f6399f9f79b45bcc12a866a"}, - {file = "httpx-0.25.1.tar.gz", hash = "sha256:ffd96d5cf901e63863d9f1b4b6807861dbea4d301613415d9e6e57ead15fc5d0"}, + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] [package.dependencies] anyio = "*" certifi = "*" -httpcore = "*" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -3682,110 +3723,72 @@ reference = "tsinghua" [[package]] name = "lxml" -version = "4.9.3" +version = "5.0.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ - {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, - {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, - {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, - {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, - {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, - {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, - {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, - {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, - {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, - {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, - {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, - {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, - {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, - {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, - {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, - {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, - {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, - {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, - {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, - {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, - {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, - {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, - {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, - {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, - {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, + {file = "lxml-5.0.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73bfab795d354aaf2f4eb7a5b0db513031734fd371047342d5803834ce19ec18"}, + {file = "lxml-5.0.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cb564bbe55ff0897d9cf1225041a44576d7ae87f06fd60163544c91de2623d3f"}, + {file = "lxml-5.0.0-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6a5501438dd521bb7e0dde5008c40c7bfcfaafaf86eccb3f9bd27509abb793da"}, + {file = "lxml-5.0.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7ba26a7dc929a1b3487d51bbcb0099afed2fc06e891b82845c8f37a2d7d7fbbd"}, + {file = "lxml-5.0.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:9b59c429e1a2246da86ae237ffc3565efcdc71c281cd38ca8b44d5fb6a3b993a"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:3ffa066db40b0347e48334bd4465de768e295a3525b9a59831228b5f4f93162d"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8ce8b468ab50f9e944719d1134709ec11fe0d2840891a6cae369e22141b1094c"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:583c0e15ae06adc81035346ae2abb2e748f0b5197e7740d8af31222db41bbf7b"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:904d36165848b59c4e04ae5b969072e602bd987485076fca8ec42c6cd7a7aedc"}, + {file = "lxml-5.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ac21aace6712472e77ea9dfc38329f53830c4259ece54c786107105ebb069053"}, + {file = "lxml-5.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f92d73faa0b1a76d1932429d684b7ce95829e93c3eef3715ec9b98ab192c9d31"}, + {file = "lxml-5.0.0-cp310-cp310-win32.whl", hash = "sha256:03290e2f714f2e7431c8430c08b48167f657da7bc689c6248e828ff3c66d5b1b"}, + {file = "lxml-5.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e6cbb68bf70081f036bfc018649cf4b46c4e7eaf7860a277cae92dee2a57f69"}, + {file = "lxml-5.0.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5382612ba2424cea5d2c89e2c29077023d8de88f8d60d5ceff5f76334516df9e"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:07a900735bad9af7be3085480bf384f68ed5580ba465b39a098e6a882c060d6b"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:980ba47c8db4b9d870014c7040edb230825b79017a6a27aa54cdb6fcc02d8cc0"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6507c58431dbd95b50654b3313c5ad54f90e54e5f2cdacf733de61eae478eec5"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:4a45a278518e4308865c1e9dbb2c42ce84fb154efb03adeb16fdae3c1687c7c9"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:59cea9ba1c675fbd6867ca1078fc717a113e7f5b7644943b74137b7cc55abebf"}, + {file = "lxml-5.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dd39ef87fd1f7bb5c4aa53454936e6135cbfe03fe3744e8218be193f9e4fef16"}, + {file = "lxml-5.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e6bb39d91bf932e7520cb5718ae3c2f498052aca53294d5d59fdd9068fe1a7f2"}, + {file = "lxml-5.0.0-cp311-cp311-win32.whl", hash = "sha256:21af2c3862db6f4f486cddf73ec1157b40d5828876c47cd880edcbad8240ea1b"}, + {file = "lxml-5.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:c1249aa4eaced30b59ecf8b8cae0b1ccede04583c74ca7d10b6f8bbead908b2c"}, + {file = "lxml-5.0.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:f30e697b6215e759d0824768b2c5b0618d2dc19abe6c67eeed2b0460f52470d1"}, + {file = "lxml-5.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:d1bb64646480c36a4aa1b6a44a5b6e33d0fcbeab9f53f1b39072cd3bb2c6243a"}, + {file = "lxml-5.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4e69c36c8618707a90ed3fb6f48a6cc9254ffcdbf7b259e439a5ae5fbf9c5206"}, + {file = "lxml-5.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9ca498f8554a09fbc3a2f8fc4b23261e07bc27bef99b3df98e2570688033f6fc"}, + {file = "lxml-5.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0326e9b8176ea77269fb39e7af4010906e73e9496a9f8eaf06d253b1b1231ceb"}, + {file = "lxml-5.0.0-cp312-cp312-win32.whl", hash = "sha256:5fb988e15378d6e905ca8f60813950a0c56da9469d0e8e5d8fe785b282684ec5"}, + {file = "lxml-5.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:bb58e8f4b2cfe012cd312239b8d5139995fe8f5945c7c26d5fbbbb1ddb9acd47"}, + {file = "lxml-5.0.0-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:81509dffd8aba3bdb43e90cbd218c9c068a1f4047d97bc9546b3ac9e3a4ae81d"}, + {file = "lxml-5.0.0-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e675a4b95208e74c34ac0751cc4bab9170e7728b61601fb0f4746892c2bb7e0b"}, + {file = "lxml-5.0.0-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:405e3760f83a8ba3bdb6e622ec79595cdc20db916ce37377bbcb95b5711fa4ca"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f15844a1b93dcaa09c2b22e22a73384f3ae4502347c3881cfdd674e14ac04e21"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88f559f8beb6b90e41a7faae4aca4c8173a4819874a9bf8e74c8d7c1d51f3162"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e8c63f5c7d87e7044880b01851ac4e863c3349e6f6b6ab456fe218d9346e816d"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:0d277d4717756fe8816f0beeff229cb72f9dd02a43b70e1d3f07c8efadfb9fe1"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8954da15403db1acfc0544b3c3f963a6ef4e428283ab6555e3e298bbbff1cf6"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:aebd8fd378e074b22e79cad329dcccd243c40ff1cafaa512d19276c5bb9554e1"}, + {file = "lxml-5.0.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b6d4e148edee59c2ad38af15810dbcb8b5d7b13e5de3509d8cf3edfe74c0adca"}, + {file = "lxml-5.0.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:70ab4e02f7aa5fb4131c8b222a111ce7676f3767e36084fba3a4e7338dc82dcd"}, + {file = "lxml-5.0.0-cp36-cp36m-win32.whl", hash = "sha256:de1a8b54170024cf1c0c2718c82412bca42cd82e390556e3d8031af9541b416f"}, + {file = "lxml-5.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5b39f63edbe7e018c2ac1cf0259ee0dd2355274e8a3003d404699b040782e55e"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:77b73952534967a4497d9e4f26fbeebfba19950cbc66b7cc3a706214429d8106"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8cc0a951e5616ac626f7036309c41fb9774adcd4aa7db0886463da1ce5b65edb"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:4b9d5b01900a760eb3acf6cef50aead4ef2fa79e7ddb927084244e41dfe37b65"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:173bcead3af5d87c7bca9a030675073ddaad8e0a9f0b04be07cd9390453e7226"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:44fa9afd632210f1eeda51cf284ed8dbab0c7ec8b008dd39ba02818e0e114e69"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fef10f27d6318d2d7c88680e113511ddecf09ee4f9559b3623b73ee89fa8f6cc"}, + {file = "lxml-5.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3663542aee845129a981889c19b366beab0b1dadcf5ca164696aabfe1aa51667"}, + {file = "lxml-5.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7188495c1bf71bfda87d78ed50601e72d252119ce11710d6e71ff36e35fea5a0"}, + {file = "lxml-5.0.0-cp37-cp37m-win32.whl", hash = "sha256:6a2de85deabf939b0af89e2e1ea46bfb1239545e2da6f8ac96522755a388025f"}, + {file = "lxml-5.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ea56825c1e23c9c8ea385a191dac75f9160477057285b88c88736d9305e6118f"}, + {file = "lxml-5.0.0.tar.gz", hash = "sha256:9165c82bcccf0249feff82cd1fba202e4ce26c25dc69040a0d2c2d0e49cbeba3"}, ] [package.extras] cssselect = ["cssselect (>=0.7)"] html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] -source = ["Cython (>=0.29.35)"] +source = ["Cython (>=3.0.7)"] [package.source] type = "legacy" @@ -3952,13 +3955,13 @@ reference = "tsinghua" [[package]] name = "mistune" -version = "0.8.4" -description = "The fastest markdown parser in pure Python" +version = "2.0.3" +description = "A sane Markdown parser with useful plugins and renderers" optional = false python-versions = "*" files = [ - {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, - {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, + {file = "mistune-2.0.3-py2.py3-none-any.whl", hash = "sha256:e3964140c0775535fba50bd616fe180920044a64bc21850253267b07bff89924"}, + {file = "mistune-2.0.3.tar.gz", hash = "sha256:d7605b46b6156b53b7d52a465202b29a6f00f4ea4130ad5d25e9d5547d6b7e50"}, ] [package.source] @@ -3968,13 +3971,13 @@ reference = "tsinghua" [[package]] name = "msal" -version = "1.25.0" -description = "The Microsoft Authentication Library (MSAL) for Python library" +version = "1.26.0" +description = "The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of users with Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) using industry standard OAuth2 and OpenID Connect." optional = false python-versions = ">=2.7" files = [ - {file = "msal-1.25.0-py2.py3-none-any.whl", hash = "sha256:386df621becb506bc315a713ec3d4d5b5d6163116955c7dde23622f156b81af6"}, - {file = "msal-1.25.0.tar.gz", hash = "sha256:f44329fdb59f4f044c779164a34474b8a44ad9e4940afbc4c3a3a2bbe90324d9"}, + {file = "msal-1.26.0-py2.py3-none-any.whl", hash = "sha256:be77ba6a8f49c9ff598bbcdc5dfcf1c9842f3044300109af738e8c3e371065b5"}, + {file = "msal-1.26.0.tar.gz", hash = "sha256:224756079fe338be838737682b49f8ebc20a87c1c5eeaf590daae4532b83de15"}, ] [package.dependencies] @@ -3992,20 +3995,21 @@ reference = "tsinghua" [[package]] name = "msal-extensions" -version = "1.0.0" +version = "1.1.0" description = "Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS and Linux. Concurrent data access will be coordinated by a file lock mechanism." optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "msal-extensions-1.0.0.tar.gz", hash = "sha256:c676aba56b0cce3783de1b5c5ecfe828db998167875126ca4b47dc6436451354"}, - {file = "msal_extensions-1.0.0-py2.py3-none-any.whl", hash = "sha256:91e3db9620b822d0ed2b4d1850056a0f133cba04455e62f11612e40f5502f2ee"}, + {file = "msal-extensions-1.1.0.tar.gz", hash = "sha256:6ab357867062db7b253d0bd2df6d411c7891a0ee7308d54d1e4317c1d1c54252"}, + {file = "msal_extensions-1.1.0-py3-none-any.whl", hash = "sha256:01be9711b4c0b1a151450068eeb2c4f0997df3bba085ac299de3a66f585e382f"}, ] [package.dependencies] msal = ">=0.4.1,<2.0.0" +packaging = "*" portalocker = [ - {version = ">=1.0,<3", markers = "python_version >= \"3.5\" and platform_system != \"Windows\""}, - {version = ">=1.6,<3", markers = "python_version >= \"3.5\" and platform_system == \"Windows\""}, + {version = ">=1.0,<3", markers = "platform_system != \"Windows\""}, + {version = ">=1.6,<3", markers = "platform_system == \"Windows\""}, ] [package.source] @@ -4241,13 +4245,13 @@ reference = "tsinghua" [[package]] name = "netaddr" -version = "0.9.0" +version = "0.10.0" description = "A network address manipulation library for Python" optional = false python-versions = "*" files = [ - {file = "netaddr-0.9.0-py3-none-any.whl", hash = "sha256:5148b1055679d2a1ec070c521b7db82137887fabd6d7e37f5199b44f775c3bb1"}, - {file = "netaddr-0.9.0.tar.gz", hash = "sha256:7b46fa9b1a2d71fd5de9e4a3784ef339700a53a08c8040f08baf5f1194da0128"}, + {file = "netaddr-0.10.0-py2.py3-none-any.whl", hash = "sha256:8752f96c8fc24162edbf5b73d3e464b5d88e62869917582daa37b2695b65afb4"}, + {file = "netaddr-0.10.0.tar.gz", hash = "sha256:4c30c54adf4ea4318b3c055ea3d8c7f6554a50aa2cd8aea4605a23caa0b0229e"}, ] [package.source] @@ -4337,23 +4341,23 @@ reference = "tsinghua" [[package]] name = "openai" -version = "1.3.7" +version = "1.6.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.3.7-py3-none-any.whl", hash = "sha256:e5c51367a910297e4d1cd33d2298fb87d7edf681edbe012873925ac16f95bee0"}, - {file = "openai-1.3.7.tar.gz", hash = "sha256:18074a0f51f9b49d1ae268c7abc36f7f33212a0c0d08ce11b7053ab2d17798de"}, + {file = "openai-1.6.1-py3-none-any.whl", hash = "sha256:bc9f774838d67ac29fb24cdeb2d58faf57de8b311085dcd1348f7aa02a96c7ee"}, + {file = "openai-1.6.1.tar.gz", hash = "sha256:d553ca9dbf9486b08e75b09e8671e4f638462aaadccfced632bf490fc3d75fa2"}, ] [package.dependencies] -anyio = ">=3.5.0,<4" +anyio = ">=3.5.0,<5" distro = ">=1.7.0,<2" httpx = ">=0.23.0,<1" pydantic = ">=1.9.0,<3" sniffio = "*" tqdm = ">4" -typing-extensions = ">=4.5,<5" +typing-extensions = ">=4.7,<5" [package.extras] datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] @@ -4739,67 +4743,65 @@ reference = "tsinghua" [[package]] name = "pillow" -version = "10.0.0" +version = "10.0.1" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891"}, - {file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1"}, - {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf"}, - {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3"}, - {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992"}, - {file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de"}, - {file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485"}, - {file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd"}, - {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629"}, - {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, - {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, - {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, - {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, - {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, - {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223"}, - {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff"}, - {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, - {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, - {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, - {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, - {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, - {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530"}, - {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51"}, - {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86"}, - {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7"}, - {file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0"}, - {file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa"}, - {file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3"}, - {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba"}, - {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3"}, - {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017"}, - {file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3"}, - {file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684"}, - {file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3"}, - {file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396"}, + {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"}, ] [package.extras] @@ -4878,13 +4880,13 @@ reference = "tsinghua" [[package]] name = "prompt-toolkit" -version = "3.0.41" +version = "3.0.43" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.41-py3-none-any.whl", hash = "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2"}, - {file = "prompt_toolkit-3.0.41.tar.gz", hash = "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0"}, + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, ] [package.dependencies] @@ -4897,13 +4899,13 @@ reference = "tsinghua" [[package]] name = "proto-plus" -version = "1.22.3" +version = "1.23.0" description = "Beautiful, Pythonic protocol buffers." optional = false python-versions = ">=3.6" files = [ - {file = "proto-plus-1.22.3.tar.gz", hash = "sha256:fdcd09713cbd42480740d2fe29c990f7fbd885a67efc328aa8be6ee3e9f76a6b"}, - {file = "proto_plus-1.22.3-py3-none-any.whl", hash = "sha256:a49cd903bc0b6ab41f76bf65510439d56ca76f868adf0274e738bfdd096894df"}, + {file = "proto-plus-1.23.0.tar.gz", hash = "sha256:89075171ef11988b3fa157f5dbd8b9cf09d65fffee97e29ce403cd8defba19d2"}, + {file = "proto_plus-1.23.0-py3-none-any.whl", hash = "sha256:a829c79e619e1cf632de091013a4173deed13a55f326ef84f05af6f50ff4c82c"}, ] [package.dependencies] @@ -5256,18 +5258,18 @@ reference = "tsinghua" [[package]] name = "pydantic" -version = "2.5.2" +version = "2.5.3" description = "Data validation using Python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-2.5.2-py3-none-any.whl", hash = "sha256:80c50fb8e3dcecfddae1adbcc00ec5822918490c99ab31f6cf6140ca1c1429f0"}, - {file = "pydantic-2.5.2.tar.gz", hash = "sha256:ff177ba64c6faf73d7afa2e8cad38fd456c0dbe01c9954e71038001cd15a6edd"}, + {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, + {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.14.5" +pydantic-core = "2.14.6" typing-extensions = ">=4.6.1" [package.extras] @@ -5280,116 +5282,116 @@ reference = "tsinghua" [[package]] name = "pydantic-core" -version = "2.14.5" +version = "2.14.6" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic_core-2.14.5-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:7e88f5696153dc516ba6e79f82cc4747e87027205f0e02390c21f7cb3bd8abfd"}, - {file = "pydantic_core-2.14.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4641e8ad4efb697f38a9b64ca0523b557c7931c5f84e0fd377a9a3b05121f0de"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:774de879d212db5ce02dfbf5b0da9a0ea386aeba12b0b95674a4ce0593df3d07"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ebb4e035e28f49b6f1a7032920bb9a0c064aedbbabe52c543343d39341a5b2a3"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b53e9ad053cd064f7e473a5f29b37fc4cc9dc6d35f341e6afc0155ea257fc911"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aa1768c151cf562a9992462239dfc356b3d1037cc5a3ac829bb7f3bda7cc1f9"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eac5c82fc632c599f4639a5886f96867ffced74458c7db61bc9a66ccb8ee3113"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae91f50ccc5810b2f1b6b858257c9ad2e08da70bf890dee02de1775a387c66"}, - {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6b9ff467ffbab9110e80e8c8de3bcfce8e8b0fd5661ac44a09ae5901668ba997"}, - {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61ea96a78378e3bd5a0be99b0e5ed00057b71f66115f5404d0dae4819f495093"}, - {file = "pydantic_core-2.14.5-cp310-none-win32.whl", hash = "sha256:bb4c2eda937a5e74c38a41b33d8c77220380a388d689bcdb9b187cf6224c9720"}, - {file = "pydantic_core-2.14.5-cp310-none-win_amd64.whl", hash = "sha256:b7851992faf25eac90bfcb7bfd19e1f5ffa00afd57daec8a0042e63c74a4551b"}, - {file = "pydantic_core-2.14.5-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:4e40f2bd0d57dac3feb3a3aed50f17d83436c9e6b09b16af271b6230a2915459"}, - {file = "pydantic_core-2.14.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab1cdb0f14dc161ebc268c09db04d2c9e6f70027f3b42446fa11c153521c0e88"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aae7ea3a1c5bb40c93cad361b3e869b180ac174656120c42b9fadebf685d121b"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60b7607753ba62cf0739177913b858140f11b8af72f22860c28eabb2f0a61937"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2248485b0322c75aee7565d95ad0e16f1c67403a470d02f94da7344184be770f"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:823fcc638f67035137a5cd3f1584a4542d35a951c3cc68c6ead1df7dac825c26"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96581cfefa9123accc465a5fd0cc833ac4d75d55cc30b633b402e00e7ced00a6"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a33324437018bf6ba1bb0f921788788641439e0ed654b233285b9c69704c27b4"}, - {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9bd18fee0923ca10f9a3ff67d4851c9d3e22b7bc63d1eddc12f439f436f2aada"}, - {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:853a2295c00f1d4429db4c0fb9475958543ee80cfd310814b5c0ef502de24dda"}, - {file = "pydantic_core-2.14.5-cp311-none-win32.whl", hash = "sha256:cb774298da62aea5c80a89bd58c40205ab4c2abf4834453b5de207d59d2e1651"}, - {file = "pydantic_core-2.14.5-cp311-none-win_amd64.whl", hash = "sha256:e87fc540c6cac7f29ede02e0f989d4233f88ad439c5cdee56f693cc9c1c78077"}, - {file = "pydantic_core-2.14.5-cp311-none-win_arm64.whl", hash = "sha256:57d52fa717ff445cb0a5ab5237db502e6be50809b43a596fb569630c665abddf"}, - {file = "pydantic_core-2.14.5-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:e60f112ac88db9261ad3a52032ea46388378034f3279c643499edb982536a093"}, - {file = "pydantic_core-2.14.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6e227c40c02fd873c2a73a98c1280c10315cbebe26734c196ef4514776120aeb"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0cbc7fff06a90bbd875cc201f94ef0ee3929dfbd5c55a06674b60857b8b85ed"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:103ef8d5b58596a731b690112819501ba1db7a36f4ee99f7892c40da02c3e189"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c949f04ecad823f81b1ba94e7d189d9dfb81edbb94ed3f8acfce41e682e48cef"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1452a1acdf914d194159439eb21e56b89aa903f2e1c65c60b9d874f9b950e5d"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb4679d4c2b089e5ef89756bc73e1926745e995d76e11925e3e96a76d5fa51fc"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf9d3fe53b1ee360e2421be95e62ca9b3296bf3f2fb2d3b83ca49ad3f925835e"}, - {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:70f4b4851dbb500129681d04cc955be2a90b2248d69273a787dda120d5cf1f69"}, - {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:59986de5710ad9613ff61dd9b02bdd2f615f1a7052304b79cc8fa2eb4e336d2d"}, - {file = "pydantic_core-2.14.5-cp312-none-win32.whl", hash = "sha256:699156034181e2ce106c89ddb4b6504c30db8caa86e0c30de47b3e0654543260"}, - {file = "pydantic_core-2.14.5-cp312-none-win_amd64.whl", hash = "sha256:5baab5455c7a538ac7e8bf1feec4278a66436197592a9bed538160a2e7d11e36"}, - {file = "pydantic_core-2.14.5-cp312-none-win_arm64.whl", hash = "sha256:e47e9a08bcc04d20975b6434cc50bf82665fbc751bcce739d04a3120428f3e27"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:af36f36538418f3806048f3b242a1777e2540ff9efaa667c27da63d2749dbce0"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:45e95333b8418ded64745f14574aa9bfc212cb4fbeed7a687b0c6e53b5e188cd"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e47a76848f92529879ecfc417ff88a2806438f57be4a6a8bf2961e8f9ca9ec7"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d81e6987b27bc7d101c8597e1cd2bcaa2fee5e8e0f356735c7ed34368c471550"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34708cc82c330e303f4ce87758828ef6e457681b58ce0e921b6e97937dd1e2a3"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:652c1988019752138b974c28f43751528116bcceadad85f33a258869e641d753"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e4d090e73e0725b2904fdbdd8d73b8802ddd691ef9254577b708d413bf3006e"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5c7d5b5005f177764e96bd584d7bf28d6e26e96f2a541fdddb934c486e36fd59"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a71891847f0a73b1b9eb86d089baee301477abef45f7eaf303495cd1473613e4"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a717aef6971208f0851a2420b075338e33083111d92041157bbe0e2713b37325"}, - {file = "pydantic_core-2.14.5-cp37-none-win32.whl", hash = "sha256:de790a3b5aa2124b8b78ae5faa033937a72da8efe74b9231698b5a1dd9be3405"}, - {file = "pydantic_core-2.14.5-cp37-none-win_amd64.whl", hash = "sha256:6c327e9cd849b564b234da821236e6bcbe4f359a42ee05050dc79d8ed2a91588"}, - {file = "pydantic_core-2.14.5-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:ef98ca7d5995a82f43ec0ab39c4caf6a9b994cb0b53648ff61716370eadc43cf"}, - {file = "pydantic_core-2.14.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6eae413494a1c3f89055da7a5515f32e05ebc1a234c27674a6956755fb2236f"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcf4e6d85614f7a4956c2de5a56531f44efb973d2fe4a444d7251df5d5c4dcfd"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6637560562134b0e17de333d18e69e312e0458ee4455bdad12c37100b7cad706"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77fa384d8e118b3077cccfcaf91bf83c31fe4dc850b5e6ee3dc14dc3d61bdba1"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16e29bad40bcf97aac682a58861249ca9dcc57c3f6be22f506501833ddb8939c"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531f4b4252fac6ca476fbe0e6f60f16f5b65d3e6b583bc4d87645e4e5ddde331"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:074f3d86f081ce61414d2dc44901f4f83617329c6f3ab49d2bc6c96948b2c26b"}, - {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c2adbe22ab4babbca99c75c5d07aaf74f43c3195384ec07ccbd2f9e3bddaecec"}, - {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0f6116a558fd06d1b7c2902d1c4cf64a5bd49d67c3540e61eccca93f41418124"}, - {file = "pydantic_core-2.14.5-cp38-none-win32.whl", hash = "sha256:fe0a5a1025eb797752136ac8b4fa21aa891e3d74fd340f864ff982d649691867"}, - {file = "pydantic_core-2.14.5-cp38-none-win_amd64.whl", hash = "sha256:079206491c435b60778cf2b0ee5fd645e61ffd6e70c47806c9ed51fc75af078d"}, - {file = "pydantic_core-2.14.5-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a6a16f4a527aae4f49c875da3cdc9508ac7eef26e7977952608610104244e1b7"}, - {file = "pydantic_core-2.14.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:abf058be9517dc877227ec3223f0300034bd0e9f53aebd63cf4456c8cb1e0863"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b08aae5013640a3bfa25a8eebbd95638ec3f4b2eaf6ed82cf0c7047133f03b"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2d97e906b4ff36eb464d52a3bc7d720bd6261f64bc4bcdbcd2c557c02081ed2"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3128e0bbc8c091ec4375a1828d6118bc20404883169ac95ffa8d983b293611e6"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88e74ab0cdd84ad0614e2750f903bb0d610cc8af2cc17f72c28163acfcf372a4"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c339dabd8ee15f8259ee0f202679b6324926e5bc9e9a40bf981ce77c038553db"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3387277f1bf659caf1724e1afe8ee7dbc9952a82d90f858ebb931880216ea955"}, - {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ba6b6b3846cfc10fdb4c971980a954e49d447cd215ed5a77ec8190bc93dd7bc5"}, - {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca61d858e4107ce5e1330a74724fe757fc7135190eb5ce5c9d0191729f033209"}, - {file = "pydantic_core-2.14.5-cp39-none-win32.whl", hash = "sha256:ec1e72d6412f7126eb7b2e3bfca42b15e6e389e1bc88ea0069d0cc1742f477c6"}, - {file = "pydantic_core-2.14.5-cp39-none-win_amd64.whl", hash = "sha256:c0b97ec434041827935044bbbe52b03d6018c2897349670ff8fe11ed24d1d4ab"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79e0a2cdbdc7af3f4aee3210b1172ab53d7ddb6a2d8c24119b5706e622b346d0"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:678265f7b14e138d9a541ddabbe033012a2953315739f8cfa6d754cc8063e8ca"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b15e855ae44f0c6341ceb74df61b606e11f1087e87dcb7482377374aac6abe"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09b0e985fbaf13e6b06a56d21694d12ebca6ce5414b9211edf6f17738d82b0f8"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ad873900297bb36e4b6b3f7029d88ff9829ecdc15d5cf20161775ce12306f8a"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2d0ae0d8670164e10accbeb31d5ad45adb71292032d0fdb9079912907f0085f4"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d37f8ec982ead9ba0a22a996129594938138a1503237b87318392a48882d50b7"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:35613015f0ba7e14c29ac6c2483a657ec740e5ac5758d993fdd5870b07a61d8b"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab4ea451082e684198636565224bbb179575efc1658c48281b2c866bfd4ddf04"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ce601907e99ea5b4adb807ded3570ea62186b17f88e271569144e8cca4409c7"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb2ed8b3fe4bf4506d6dab3b93b83bbc22237e230cba03866d561c3577517d18"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70f947628e074bb2526ba1b151cee10e4c3b9670af4dbb4d73bc8a89445916b5"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4bc536201426451f06f044dfbf341c09f540b4ebdb9fd8d2c6164d733de5e634"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4791cf0f8c3104ac668797d8c514afb3431bc3305f5638add0ba1a5a37e0d88"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:038c9f763e650712b899f983076ce783175397c848da04985658e7628cbe873b"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:27548e16c79702f1e03f5628589c6057c9ae17c95b4c449de3c66b589ead0520"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97bee68898f3f4344eb02fec316db93d9700fb1e6a5b760ffa20d71d9a46ce3"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9b759b77f5337b4ea024f03abc6464c9f35d9718de01cfe6bae9f2e139c397e"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:439c9afe34638ace43a49bf72d201e0ffc1a800295bed8420c2a9ca8d5e3dbb3"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ba39688799094c75ea8a16a6b544eb57b5b0f3328697084f3f2790892510d144"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ccd4d5702bb90b84df13bd491be8d900b92016c5a455b7e14630ad7449eb03f8"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:81982d78a45d1e5396819bbb4ece1fadfe5f079335dd28c4ab3427cd95389944"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:7f8210297b04e53bc3da35db08b7302a6a1f4889c79173af69b72ec9754796b8"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:8c8a8812fe6f43a3a5b054af6ac2d7b8605c7bcab2804a8a7d68b53f3cd86e00"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:206ed23aecd67c71daf5c02c3cd19c0501b01ef3cbf7782db9e4e051426b3d0d"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2027d05c8aebe61d898d4cffd774840a9cb82ed356ba47a90d99ad768f39789"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40180930807ce806aa71eda5a5a5447abb6b6a3c0b4b3b1b1962651906484d68"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:615a0a4bff11c45eb3c1996ceed5bdaa2f7b432425253a7c2eed33bb86d80abc"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5e412d717366e0677ef767eac93566582518fe8be923361a5c204c1a62eaafe"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:513b07e99c0a267b1d954243845d8a833758a6726a3b5d8948306e3fe14675e3"}, - {file = "pydantic_core-2.14.5.tar.gz", hash = "sha256:6d30226dfc816dd0fdf120cae611dd2215117e4f9b124af8c60ab9093b6e8e71"}, + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"}, + {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"}, + {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"}, + {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"}, + {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"}, + {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"}, + {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, + {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, + {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, + {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, + {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"}, + {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"}, + {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"}, + {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"}, + {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"}, + {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, ] [package.dependencies] @@ -6574,13 +6576,13 @@ reference = "tsinghua" [[package]] name = "setuptools" -version = "69.0.2" +version = "69.0.3" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, - {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, + {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, + {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, ] [package.extras] @@ -6951,22 +6953,22 @@ reference = "tsinghua" [[package]] name = "tornado" -version = "6.3.3" +version = "6.4" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">= 3.8" files = [ - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, - {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, - {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, - {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, + {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, + {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, + {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, ] [package.source] @@ -7138,13 +7140,13 @@ reference = "tsinghua" [[package]] name = "typing-extensions" -version = "4.8.0" +version = "4.9.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] [package.source] @@ -7154,13 +7156,13 @@ reference = "tsinghua" [[package]] name = "tzdata" -version = "2023.3" +version = "2023.4" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, - {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, + {file = "tzdata-2023.4-py2.py3-none-any.whl", hash = "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3"}, + {file = "tzdata-2023.4.tar.gz", hash = "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9"}, ] [package.source] @@ -7610,101 +7612,101 @@ reference = "tsinghua" [[package]] name = "yarl" -version = "1.9.3" +version = "1.9.4" description = "Yet another URL library" optional = false python-versions = ">=3.7" files = [ - {file = "yarl-1.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32435d134414e01d937cd9d6cc56e8413a8d4741dea36af5840c7750f04d16ab"}, - {file = "yarl-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9a5211de242754b5e612557bca701f39f8b1a9408dff73c6db623f22d20f470e"}, - {file = "yarl-1.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:525cd69eff44833b01f8ef39aa33a9cc53a99ff7f9d76a6ef6a9fb758f54d0ff"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc94441bcf9cb8c59f51f23193316afefbf3ff858460cb47b5758bf66a14d130"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e36021db54b8a0475805acc1d6c4bca5d9f52c3825ad29ae2d398a9d530ddb88"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0f17d1df951336a02afc8270c03c0c6e60d1f9996fcbd43a4ce6be81de0bd9d"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5f3faeb8100a43adf3e7925d556801d14b5816a0ac9e75e22948e787feec642"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aed37db837ecb5962469fad448aaae0f0ee94ffce2062cf2eb9aed13328b5196"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:721ee3fc292f0d069a04016ef2c3a25595d48c5b8ddc6029be46f6158d129c92"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b8bc5b87a65a4e64bc83385c05145ea901b613d0d3a434d434b55511b6ab0067"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:dd952b9c64f3b21aedd09b8fe958e4931864dba69926d8a90c90d36ac4e28c9a"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:c405d482c320a88ab53dcbd98d6d6f32ada074f2d965d6e9bf2d823158fa97de"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9df9a0d4c5624790a0dea2e02e3b1b3c69aed14bcb8650e19606d9df3719e87d"}, - {file = "yarl-1.9.3-cp310-cp310-win32.whl", hash = "sha256:d34c4f80956227f2686ddea5b3585e109c2733e2d4ef12eb1b8b4e84f09a2ab6"}, - {file = "yarl-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:cf7a4e8de7f1092829caef66fd90eaf3710bc5efd322a816d5677b7664893c93"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d61a0ca95503867d4d627517bcfdc28a8468c3f1b0b06c626f30dd759d3999fd"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73cc83f918b69110813a7d95024266072d987b903a623ecae673d1e71579d566"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d81657b23e0edb84b37167e98aefb04ae16cbc5352770057893bd222cdc6e45f"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a1a8443091c7fbc17b84a0d9f38de34b8423b459fb853e6c8cdfab0eacf613"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe34befb8c765b8ce562f0200afda3578f8abb159c76de3ab354c80b72244c41"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c757f64afe53a422e45e3e399e1e3cf82b7a2f244796ce80d8ca53e16a49b9f"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72a57b41a0920b9a220125081c1e191b88a4cdec13bf9d0649e382a822705c65"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:632c7aeb99df718765adf58eacb9acb9cbc555e075da849c1378ef4d18bf536a"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b0b8c06afcf2bac5a50b37f64efbde978b7f9dc88842ce9729c020dc71fae4ce"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1d93461e2cf76c4796355494f15ffcb50a3c198cc2d601ad8d6a96219a10c363"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4003f380dac50328c85e85416aca6985536812c082387255c35292cb4b41707e"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4d6d74a97e898c1c2df80339aa423234ad9ea2052f66366cef1e80448798c13d"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b61e64b06c3640feab73fa4ff9cb64bd8182de52e5dc13038e01cfe674ebc321"}, - {file = "yarl-1.9.3-cp311-cp311-win32.whl", hash = "sha256:29beac86f33d6c7ab1d79bd0213aa7aed2d2f555386856bb3056d5fdd9dab279"}, - {file = "yarl-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:f7271d6bd8838c49ba8ae647fc06469137e1c161a7ef97d778b72904d9b68696"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:dd318e6b75ca80bff0b22b302f83a8ee41c62b8ac662ddb49f67ec97e799885d"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c4b1efb11a8acd13246ffb0bee888dd0e8eb057f8bf30112e3e21e421eb82d4a"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c6f034386e5550b5dc8ded90b5e2ff7db21f0f5c7de37b6efc5dac046eb19c10"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd49a908cb6d387fc26acee8b7d9fcc9bbf8e1aca890c0b2fdfd706057546080"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa4643635f26052401750bd54db911b6342eb1a9ac3e74f0f8b58a25d61dfe41"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e741bd48e6a417bdfbae02e088f60018286d6c141639359fb8df017a3b69415a"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c86d0d0919952d05df880a1889a4f0aeb6868e98961c090e335671dea5c0361"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d5434b34100b504aabae75f0622ebb85defffe7b64ad8f52b8b30ec6ef6e4b9"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79e1df60f7c2b148722fb6cafebffe1acd95fd8b5fd77795f56247edaf326752"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:44e91a669c43f03964f672c5a234ae0d7a4d49c9b85d1baa93dec28afa28ffbd"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3cfa4dbe17b2e6fca1414e9c3bcc216f6930cb18ea7646e7d0d52792ac196808"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:88d2c3cc4b2f46d1ba73d81c51ec0e486f59cc51165ea4f789677f91a303a9a7"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cccdc02e46d2bd7cb5f38f8cc3d9db0d24951abd082b2f242c9e9f59c0ab2af3"}, - {file = "yarl-1.9.3-cp312-cp312-win32.whl", hash = "sha256:96758e56dceb8a70f8a5cff1e452daaeff07d1cc9f11e9b0c951330f0a2396a7"}, - {file = "yarl-1.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:c4472fe53ebf541113e533971bd8c32728debc4c6d8cc177f2bff31d011ec17e"}, - {file = "yarl-1.9.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:126638ab961633f0940a06e1c9d59919003ef212a15869708dcb7305f91a6732"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c99ddaddb2fbe04953b84d1651149a0d85214780e4d0ee824e610ab549d98d92"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dab30b21bd6fb17c3f4684868c7e6a9e8468078db00f599fb1c14e324b10fca"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:828235a2a169160ee73a2fcfb8a000709edf09d7511fccf203465c3d5acc59e4"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc391e3941045fd0987c77484b2799adffd08e4b6735c4ee5f054366a2e1551d"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51382c72dd5377861b573bd55dcf680df54cea84147c8648b15ac507fbef984d"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:28a108cb92ce6cf867690a962372996ca332d8cda0210c5ad487fe996e76b8bb"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8f18a7832ff85dfcd77871fe677b169b1bc60c021978c90c3bb14f727596e0ae"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:7eaf13af79950142ab2bbb8362f8d8d935be9aaf8df1df89c86c3231e4ff238a"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:66a6dbf6ca7d2db03cc61cafe1ee6be838ce0fbc97781881a22a58a7c5efef42"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1a0a4f3aaa18580038cfa52a7183c8ffbbe7d727fe581300817efc1e96d1b0e9"}, - {file = "yarl-1.9.3-cp37-cp37m-win32.whl", hash = "sha256:946db4511b2d815979d733ac6a961f47e20a29c297be0d55b6d4b77ee4b298f6"}, - {file = "yarl-1.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2dad8166d41ebd1f76ce107cf6a31e39801aee3844a54a90af23278b072f1ccf"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bb72d2a94481e7dc7a0c522673db288f31849800d6ce2435317376a345728225"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9a172c3d5447b7da1680a1a2d6ecdf6f87a319d21d52729f45ec938a7006d5d8"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2dc72e891672343b99db6d497024bf8b985537ad6c393359dc5227ef653b2f17"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8d51817cf4b8d545963ec65ff06c1b92e5765aa98831678d0e2240b6e9fd281"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53ec65f7eee8655bebb1f6f1607760d123c3c115a324b443df4f916383482a67"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cfd77e8e5cafba3fb584e0f4b935a59216f352b73d4987be3af51f43a862c403"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e73db54c967eb75037c178a54445c5a4e7461b5203b27c45ef656a81787c0c1b"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09c19e5f4404574fcfb736efecf75844ffe8610606f3fccc35a1515b8b6712c4"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6280353940f7e5e2efaaabd686193e61351e966cc02f401761c4d87f48c89ea4"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c25ec06e4241e162f5d1f57c370f4078797ade95c9208bd0c60f484834f09c96"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7217234b10c64b52cc39a8d82550342ae2e45be34f5bff02b890b8c452eb48d7"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4ce77d289f8d40905c054b63f29851ecbfd026ef4ba5c371a158cfe6f623663e"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5f74b015c99a5eac5ae589de27a1201418a5d9d460e89ccb3366015c6153e60a"}, - {file = "yarl-1.9.3-cp38-cp38-win32.whl", hash = "sha256:8a2538806be846ea25e90c28786136932ec385c7ff3bc1148e45125984783dc6"}, - {file = "yarl-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:6465d36381af057d0fab4e0f24ef0e80ba61f03fe43e6eeccbe0056e74aadc70"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2f3c8822bc8fb4a347a192dd6a28a25d7f0ea3262e826d7d4ef9cc99cd06d07e"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7831566595fe88ba17ea80e4b61c0eb599f84c85acaa14bf04dd90319a45b90"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff34cb09a332832d1cf38acd0f604c068665192c6107a439a92abfd8acf90fe2"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe8080b4f25dfc44a86bedd14bc4f9d469dfc6456e6f3c5d9077e81a5fedfba7"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8535e111a064f3bdd94c0ed443105934d6f005adad68dd13ce50a488a0ad1bf3"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d155a092bf0ebf4a9f6f3b7a650dc5d9a5bbb585ef83a52ed36ba46f55cc39d"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:778df71c8d0c8c9f1b378624b26431ca80041660d7be7c3f724b2c7a6e65d0d6"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9f9cafaf031c34d95c1528c16b2fa07b710e6056b3c4e2e34e9317072da5d1a"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ca6b66f69e30f6e180d52f14d91ac854b8119553b524e0e28d5291a724f0f423"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0e7e83f31e23c5d00ff618045ddc5e916f9e613d33c5a5823bc0b0a0feb522f"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:af52725c7c39b0ee655befbbab5b9a1b209e01bb39128dce0db226a10014aacc"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0ab5baaea8450f4a3e241ef17e3d129b2143e38a685036b075976b9c415ea3eb"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d350388ba1129bc867c6af1cd17da2b197dff0d2801036d2d7d83c2d771a682"}, - {file = "yarl-1.9.3-cp39-cp39-win32.whl", hash = "sha256:e2a16ef5fa2382af83bef4a18c1b3bcb4284c4732906aa69422cf09df9c59f1f"}, - {file = "yarl-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:d92d897cb4b4bf915fbeb5e604c7911021a8456f0964f3b8ebbe7f9188b9eabb"}, - {file = "yarl-1.9.3-py3-none-any.whl", hash = "sha256:271d63396460b6607b588555ea27a1a02b717ca2e3f2cf53bdde4013d7790929"}, - {file = "yarl-1.9.3.tar.gz", hash = "sha256:4a14907b597ec55740f63e52d7fee0e9ee09d5b9d57a4f399a7423268e457b57"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, ] [package.dependencies] @@ -7777,4 +7779,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "9cd692c23b87a664c7e274fb3679332bc0b49cdfba4174844870ed635162f8c4" +content-hash = "f3a3ef297a045ff896b54897f8ac3593e0f0894637339c7de139453991278139" diff --git a/pyproject.toml b/pyproject.toml index f639644df..e46f10eb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,7 +78,7 @@ geoip2 = "4.7.0" ipip-ipdb = "1.6.1" pywinrm = "0.4.3" python-nmap = "0.7.1" -django = "4.1.10" +django = "4.1.13" django-bootstrap3 = "23.4" django-filter = "23.2" django-formtools = "2.4.1" @@ -97,7 +97,7 @@ drf-yasg = "1.21.7" coreapi = "2.3.3" coreschema = "0.0.4" openapi-codec = "1.3.2" -pillow = "10.0.0" +pillow = "10.0.1" pytz = "2023.3" django-proxy = "1.2.2" python-daemon = "3.0.1" @@ -143,7 +143,7 @@ fido2 = "^1.1.2" ua-parser = "^0.18.0" user-agents = "^2.2.0" django-cors-headers = "^4.3.0" -mistune = "0.8.4" +mistune = "2.0.3" openai = "^1.3.7" xlsxwriter = "^3.1.9" @@ -154,8 +154,7 @@ azure-mgmt-subscription = "3.1.1" azure-identity = "1.13.0" azure-mgmt-compute = "30.0.0" azure-mgmt-network = "23.1.0" -google-cloud-compute = "1.13.0" -grpcio = "1.56.2" +google-cloud-compute = "1.15.0" alibabacloud-dysmsapi20170525 = "2.0.24" python-novaclient = "18.3.0" python-keystoneclient = "5.1.0" From 496b72aaeeed4b8af5be5a58697a110ea8421f0a Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 8 Jan 2024 17:29:59 +0800 Subject: [PATCH 14/41] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/sdk/im/slack/__init__.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/common/sdk/im/slack/__init__.py b/apps/common/sdk/im/slack/__init__.py index 06de4f04f..2ff6e071d 100644 --- a/apps/common/sdk/im/slack/__init__.py +++ b/apps/common/sdk/im/slack/__init__.py @@ -1,16 +1,14 @@ -import requests import mistune - -from rest_framework.exceptions import APIException +import requests from django.utils.translation import gettext_lazy as _ +from rest_framework.exceptions import APIException -from users.utils import construct_user_email from common.utils.common import get_logger from jumpserver.utils import get_current_request +from users.utils import construct_user_email logger = get_logger(__name__) - SLACK_REDIRECT_URI_SESSION_KEY = '_slack_redirect_uri' @@ -22,7 +20,7 @@ class URL: AUTH_TEST = 'https://slack.com/api/auth.test' -class SlackRenderer(mistune.renderers.HTMLRenderer): +class SlackRenderer(mistune.HTMLRenderer): def heading(self, text, level): return '*' + text + '*\n' From 630bb56601316547998b33476ea4be10389434be Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 8 Jan 2024 17:16:26 +0800 Subject: [PATCH 15/41] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E6=89=8B?= =?UTF-8?q?=E6=9C=BA=E5=8F=B7=E5=8A=A0=E5=AF=86=E5=AF=BC=E8=87=B4=E5=BF=98?= =?UTF-8?q?=E8=AE=B0=E5=AF=86=E7=A0=81=E5=88=A4=E6=96=AD=E6=80=BB=E6=98=AF?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/password.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/authentication/api/password.py b/apps/authentication/api/password.py index cc1e6aff7..280e088ed 100644 --- a/apps/authentication/api/password.py +++ b/apps/authentication/api/password.py @@ -28,9 +28,13 @@ class UserResetPasswordSendCodeApi(CreateAPIView): serializer_class = ResetPasswordCodeSerializer @staticmethod - def is_valid_user(**kwargs): - user = get_object_or_none(User, **kwargs) - if not user: + def is_valid_user(username, **attr_query): + user = get_object_or_none(User, username=username) + valid = True + for attr, value in attr_query.items(): + if getattr(user, attr, None) != value: + valid = False + if not valid: err_msg = _('User does not exist: {}').format(_("No user matched")) return None, err_msg if not user.is_local: @@ -56,7 +60,6 @@ class UserResetPasswordSendCodeApi(CreateAPIView): target = serializer.validated_data[form_type] if form_type == 'sms': query_key = 'phone' - target = target.lstrip('+') else: query_key = form_type user, err = self.is_valid_user(username=username, **{query_key: target}) From 814dbeb74994e3614adaa04cbf5a6392383ef5dd Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 8 Jan 2024 17:50:09 +0800 Subject: [PATCH 16/41] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E6=89=8B?= =?UTF-8?q?=E6=9C=BA=E5=8F=B7=E5=8A=A0=E5=AF=86=E5=AF=BC=E8=87=B4=E5=BF=98?= =?UTF-8?q?=E8=AE=B0=E5=AF=86=E7=A0=81=E5=88=A4=E6=96=AD=E6=80=BB=E6=98=AF?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/password.py | 13 ++++--------- apps/authentication/utils.py | 12 +++++++++++- apps/users/views/profile/reset.py | 4 ++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/apps/authentication/api/password.py b/apps/authentication/api/password.py index 280e088ed..f721ed2a8 100644 --- a/apps/authentication/api/password.py +++ b/apps/authentication/api/password.py @@ -15,12 +15,11 @@ from authentication.mixins import authenticate from authentication.serializers import ( PasswordVerifySerializer, ResetPasswordCodeSerializer ) +from authentication.utils import check_user_property_is_correct from common.permissions import IsValidUser -from common.utils import get_object_or_none from common.utils.random import random_string from common.utils.verify_code import SendAndVerifyCodeUtil from settings.utils import get_login_title -from users.models import User class UserResetPasswordSendCodeApi(CreateAPIView): @@ -28,13 +27,9 @@ class UserResetPasswordSendCodeApi(CreateAPIView): serializer_class = ResetPasswordCodeSerializer @staticmethod - def is_valid_user(username, **attr_query): - user = get_object_or_none(User, username=username) - valid = True - for attr, value in attr_query.items(): - if getattr(user, attr, None) != value: - valid = False - if not valid: + def is_valid_user(username, **properties): + user = check_user_property_is_correct(username, **properties) + if not user: err_msg = _('User does not exist: {}').format(_("No user matched")) return None, err_msg if not user.is_local: diff --git a/apps/authentication/utils.py b/apps/authentication/utils.py index 9cbc95bf2..5fd41aec7 100644 --- a/apps/authentication/utils.py +++ b/apps/authentication/utils.py @@ -7,8 +7,9 @@ from django.conf import settings from django.utils.translation import gettext_lazy as _ from audits.const import DEFAULT_CITY +from users.models import User from audits.models import UserLoginLog -from common.utils import get_logger +from common.utils import get_logger, get_object_or_none from common.utils import validate_ip, get_ip_city, get_request_ip from .notifications import DifferentCityLoginMessage @@ -59,3 +60,12 @@ def build_absolute_uri_for_oidc(request, path=None): redirect_uri = urljoin(settings.BASE_SITE_URL, path) return redirect_uri return build_absolute_uri(request, path=path) + + +def check_user_property_is_correct(username, **properties): + user = get_object_or_none(User, username=username) + for attr, value in properties.items(): + if getattr(user, attr, None) != value: + user = None + break + return user diff --git a/apps/users/views/profile/reset.py b/apps/users/views/profile/reset.py index 96d407302..b2eed3cdd 100644 --- a/apps/users/views/profile/reset.py +++ b/apps/users/views/profile/reset.py @@ -12,6 +12,7 @@ from django.utils.translation import gettext as _ from django.views.generic import FormView, RedirectView from authentication.errors import IntervalTooShort +from authentication.utils import check_user_property_is_correct from common.utils import FlashMessageUtil, get_object_or_none, random_string from common.utils.verify_code import SendAndVerifyCodeUtil from users.notifications import ResetPasswordSuccessMsg @@ -148,7 +149,6 @@ class UserForgotPasswordView(FormView): query_key = form_type if form_type == 'sms': query_key = 'phone' - target = target.lstrip('+') try: self.safe_verify_code(token, target, form_type, code) @@ -158,7 +158,7 @@ class UserForgotPasswordView(FormView): form.add_error('code', str(e)) return super().form_invalid(form) - user = get_object_or_none(User, **{'username': username, query_key: target}) + user = check_user_property_is_correct(username, **{query_key: target}) if not user: form.add_error('code', _('No user matched')) return super().form_invalid(form) From 25223719cbf41a14f747de5bf127d56932405b64 Mon Sep 17 00:00:00 2001 From: Bai Date: Tue, 9 Jan 2024 18:29:06 +0800 Subject: [PATCH 17/41] =?UTF-8?q?perf:=20=E6=94=AF=E6=8C=81=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=20RADIUS=5FATTRIBUTES=20=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 1 + apps/jumpserver/settings/auth.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 18e570271..d6fb241db 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -327,6 +327,7 @@ class Config(dict): 'RADIUS_SERVER': 'localhost', 'RADIUS_PORT': 1812, 'RADIUS_SECRET': '', + 'RADIUS_ATTRIBUTES': {}, 'RADIUS_ENCRYPT_PASSWORD': True, 'OTP_IN_RADIUS': False, diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index ff26efd19..66ae6289c 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -99,6 +99,8 @@ AUTH_RADIUS_BACKEND = 'authentication.backends.radius.RadiusBackend' RADIUS_SERVER = CONFIG.RADIUS_SERVER RADIUS_PORT = CONFIG.RADIUS_PORT RADIUS_SECRET = CONFIG.RADIUS_SECRET +# https://github.com/robgolding/django-radius/blob/develop/radiusauth/backends/radius.py#L15-L52 +RADIUS_ATTRIBUTES = CONFIG.RADIUS_ATTRIBUTES # CAS Auth AUTH_CAS = CONFIG.AUTH_CAS From df655f304a008b260b5f51ab40f324a234c398d4 Mon Sep 17 00:00:00 2001 From: wangruidong <940853815@qq.com> Date: Tue, 9 Jan 2024 11:28:25 +0800 Subject: [PATCH 18/41] =?UTF-8?q?fix:=20=E7=99=BB=E5=BD=95=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E4=B8=8D=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/audits/api.py | 8 +++++--- apps/audits/utils.py | 11 +++++++++++ apps/authentication/utils.py | 3 ++- apps/jumpserver/api.py | 3 ++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/apps/audits/api.py b/apps/audits/api.py index 7dc1a5725..209bc30fd 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -41,6 +41,7 @@ from .serializers import ( PasswordChangeLogSerializer, ActivityUnionLogSerializer, FileSerializer, UserSessionSerializer ) +from .utils import construct_userlogin_usernames logger = get_logger(__name__) @@ -126,15 +127,16 @@ class UserLoginCommonMixin: class UserLoginLogViewSet(UserLoginCommonMixin, OrgReadonlyModelViewSet): @staticmethod - def get_org_members(): - users = current_org.get_members().values_list('username', flat=True) + def get_org_member_usernames(): + user_queryset = current_org.get_members() + users = construct_userlogin_usernames(user_queryset) return users def get_queryset(self): queryset = super().get_queryset() if current_org.is_root(): return queryset - users = self.get_org_members() + users = self.get_org_member_usernames() queryset = queryset.filter(username__in=users) return queryset diff --git a/apps/audits/utils.py b/apps/audits/utils.py index 4312962e6..d9728fbbd 100644 --- a/apps/audits/utils.py +++ b/apps/audits/utils.py @@ -4,6 +4,8 @@ from itertools import chain from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.db import models +from django.db.models import F, Value, CharField +from django.db.models.functions import Concat from common.db.fields import RelatedManager from common.utils import validate_ip, get_ip_city, get_logger @@ -115,3 +117,12 @@ def model_to_dict_for_operate_log( get_related_values(f) return data + + +def construct_userlogin_usernames(user_queryset): + usernames_original = user_queryset.values_list('username', flat=True) + usernames_combined = user_queryset.annotate( + usernames_combined_field=Concat(F('name'), Value('('), F('username'), Value(')'), output_field=CharField()) + ).values_list("usernames_combined_field", flat=True) + usernames = list(chain(usernames_original, usernames_combined)) + return usernames diff --git a/apps/authentication/utils.py b/apps/authentication/utils.py index 5fd41aec7..4cb1e7368 100644 --- a/apps/authentication/utils.py +++ b/apps/authentication/utils.py @@ -25,9 +25,10 @@ def check_different_city_login_if_need(user, request): is_private = ipaddress.ip_address(ip).is_private if is_private: return + usernames = [user.username, f"{user.name}({user.username})"] last_user_login = UserLoginLog.objects.exclude( city__in=city_white - ).filter(username=user.username, status=True).first() + ).filter(username__in=usernames, status=True).first() if not last_user_login: return diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py index 63d13df55..cfa6b771d 100644 --- a/apps/jumpserver/api.py +++ b/apps/jumpserver/api.py @@ -17,6 +17,7 @@ from assets.models import Asset from audits.api import OperateLogViewSet from audits.const import LoginStatusChoices from audits.models import UserLoginLog, PasswordChangeLog, OperateLog, FTPLog, JobLog +from audits.utils import construct_userlogin_usernames from common.utils import lazyproperty from common.utils.timezone import local_now, local_zero_hour from ops.const import JobStatus @@ -79,7 +80,7 @@ class DateTimeMixin: if not self.org.is_root(): if query_params == 'username': query = { - f'{query_params}__in': users.values_list('username', flat=True) + f'{query_params}__in': construct_userlogin_usernames(users) } else: query = { From 2b15fc5e8bde998f87168463e724a6385e0be416 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 10 Jan 2024 13:37:55 +0800 Subject: [PATCH 19/41] =?UTF-8?q?perf:=20=E5=85=BC=E7=94=A8=E5=A4=84?= =?UTF-8?q?=E7=90=86=E4=B8=80=E4=B8=8B=20tree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/mixin.py | 8 +++++++- apps/perms/serializers/permission.py | 13 +++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/apps/assets/api/mixin.py b/apps/assets/api/mixin.py index 25aefa62a..af5864e4e 100644 --- a/apps/assets/api/mixin.py +++ b/apps/assets/api/mixin.py @@ -81,13 +81,19 @@ class SerializeToTreeNodeMixin: platform_map = {p.id: p for p in Platform.objects.all()} data = [] + root_assets_count = 0 for asset in assets: platform = platform_map.get(asset.platform_id) if not platform: continue pid = node_key or get_pid(asset, platform) - if not pid or pid.isdigit(): + if not pid: continue + # 根节点最多显示 1000 个资产 + if pid.isdigit(): + if root_assets_count > 1000: + continue + root_assets_count += 1 data.append({ 'id': str(asset.id), 'name': asset.name, diff --git a/apps/perms/serializers/permission.py b/apps/perms/serializers/permission.py index 36e0a6f33..3e32b40e1 100644 --- a/apps/perms/serializers/permission.py +++ b/apps/perms/serializers/permission.py @@ -196,10 +196,11 @@ class AssetPermissionListSerializer(AssetPermissionSerializer): @classmethod def setup_eager_loading(cls, queryset): """Perform necessary eager loading of data.""" - queryset = queryset.annotate( - users_amount=Count("users"), - user_groups_amount=Count("user_groups"), - assets_amount=Count("assets"), - nodes_amount=Count("nodes"), - ) + queryset = queryset \ + .prefetch_related('labels', 'labels__label') \ + .annotate(users_amount=Count("users"), + user_groups_amount=Count("user_groups"), + assets_amount=Count("assets"), + nodes_amount=Count("nodes"), + ) return queryset From 6dcc74a3888789735bccf72d68340beb180b89e7 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:52:45 +0800 Subject: [PATCH 20/41] =?UTF-8?q?fix:=20=E8=B4=A6=E5=8F=B7=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E5=8F=AA=E5=AF=BC=E5=87=BA=E4=B8=80=E6=9D=A1=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=20(#12517)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: wangruidong <940853815@qq.com> --- apps/accounts/automations/backup_account/handlers.py | 6 +++--- apps/accounts/automations/change_secret/manager.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/accounts/automations/backup_account/handlers.py b/apps/accounts/automations/backup_account/handlers.py index 763428308..c47454685 100644 --- a/apps/accounts/automations/backup_account/handlers.py +++ b/apps/accounts/automations/backup_account/handlers.py @@ -145,9 +145,9 @@ class AccountBackupHandler: wb = Workbook(filename) for sheet, data in data_map.items(): ws = wb.add_worksheet(str(sheet)) - for row in data: - for col, _data in enumerate(row): - ws.write_string(0, col, _data) + for row_index, row_data in enumerate(data): + for col_index, col_data in enumerate(row_data): + ws.write_string(row_index, col_index, col_data) wb.close() files.append(filename) timedelta = round((time.time() - time_start), 2) diff --git a/apps/accounts/automations/change_secret/manager.py b/apps/accounts/automations/change_secret/manager.py index 74dfc717e..b5fa4cef7 100644 --- a/apps/accounts/automations/change_secret/manager.py +++ b/apps/accounts/automations/change_secret/manager.py @@ -228,8 +228,8 @@ class ChangeSecretManager(AccountBasePlaybookManager): rows.insert(0, header) wb = Workbook(filename) ws = wb.add_worksheet('Sheet1') - for row in rows: - for col, data in enumerate(row): - ws.write_string(0, col, data) + for row_index, row_data in enumerate(rows): + for col_index, col_data in enumerate(row_data): + ws.write_string(row_index, col_index, col_data) wb.close() return True From 3eb0b768a6b8a643f838d7c3030a43e1f9daac8d Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 11 Jan 2024 17:57:23 +0800 Subject: [PATCH 21/41] =?UTF-8?q?fix:=20=E6=94=B9=E5=AF=86=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E6=9B=B4=E6=96=B0=E6=97=A5=E6=9C=9F=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20(#12524)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/automations/change_secret/manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/accounts/automations/change_secret/manager.py b/apps/accounts/automations/change_secret/manager.py index b5fa4cef7..8381419ad 100644 --- a/apps/accounts/automations/change_secret/manager.py +++ b/apps/accounts/automations/change_secret/manager.py @@ -161,7 +161,8 @@ class ChangeSecretManager(AccountBasePlaybookManager): print("Account not found, deleted ?") return account.secret = recorder.new_secret - account.save(update_fields=['secret']) + account.date_updated = timezone.now() + account.save(update_fields=['secret', 'date_updated']) def on_host_error(self, host, error, result): recorder = self.name_recorder_mapper.get(host) From bab5b67c5238ef9d84ef1552b6b5a35917dcd68a Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 11 Jan 2024 18:38:30 +0800 Subject: [PATCH 22/41] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=20applet=20=E5=AF=BC=E5=85=A5=E7=9A=84=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/platform.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index 2cc7d73ef..4fb0418c6 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -191,7 +191,6 @@ class PlatformSerializer(ResourceLabelsMixin, WritableNestedModelSerializer): def add_type_choices(self, name, label): tp = self.fields['type'] tp.choices[name] = label - tp.choice_mapper[name] = label tp.choice_strings_to_values[name] = label @lazyproperty From 311c01242be6dab6b74018c5fd96ec93d16a2e02 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Thu, 11 Jan 2024 22:38:01 +0800 Subject: [PATCH 23/41] =?UTF-8?q?fix:=20=E5=88=86=E9=A1=B5=E5=90=8E?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/api/mixin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/common/api/mixin.py b/apps/common/api/mixin.py index 50bb1efbe..e8266d928 100644 --- a/apps/common/api/mixin.py +++ b/apps/common/api/mixin.py @@ -104,9 +104,11 @@ class QuerySetMixin: page = super().paginate_queryset(queryset) serializer_class = self.get_serializer_class() if page and serializer_class and hasattr(serializer_class, 'setup_eager_loading'): - ids = [i.id for i in page] + ids = [str(obj.id) for obj in page] page = self.get_queryset().filter(id__in=ids) page = serializer_class.setup_eager_loading(page) + page_mapper = {str(obj.id): obj for obj in page} + page = [page_mapper.get(_id) for _id in ids if _id in page_mapper] return page From 1275087f195041eb92985b816f7f09f002bf1741 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:21:27 +0800 Subject: [PATCH 24/41] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0LC=5FALL?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8FC.UTF-8=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3ansible=E6=97=A0=E6=B3=95=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E9=A6=96=E9=80=89=E8=AF=AD=E8=A8=80=E7=8E=AF=E5=A2=83=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20(#12530)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/common/management/commands/services/services/celery_base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/common/management/commands/services/services/celery_base.py b/apps/common/management/commands/services/services/celery_base.py index 8d197d4f8..4e63f4cbb 100644 --- a/apps/common/management/commands/services/services/celery_base.py +++ b/apps/common/management/commands/services/services/celery_base.py @@ -14,6 +14,7 @@ class CeleryBaseService(BaseService): print('\n- Start Celery as Distributed Task Queue: {}'.format(self.queue.capitalize())) ansible_config_path = os.path.join(settings.APPS_DIR, 'ops', 'ansible', 'ansible.cfg') ansible_modules_path = os.path.join(settings.APPS_DIR, 'ops', 'ansible', 'modules') + os.environ.setdefault('LC_ALL', 'C.UTF-8') os.environ.setdefault('PYTHONOPTIMIZE', '1') os.environ.setdefault('ANSIBLE_FORCE_COLOR', 'True') os.environ.setdefault('ANSIBLE_CONFIG', ansible_config_path) From e428eb351bc04870b5de7b5032b096d6d6436552 Mon Sep 17 00:00:00 2001 From: wangruidong <940853815@qq.com> Date: Thu, 11 Jan 2024 19:07:54 +0800 Subject: [PATCH 25/41] =?UTF-8?q?feat:=20=E5=90=8C=E6=AD=A5ldap=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=B6=88=E6=81=AF=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 1 + apps/jumpserver/settings/auth.py | 1 + apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 272 ++++++++++-------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 272 ++++++++++-------- apps/settings/api/ldap.py | 2 +- apps/settings/notifications.py | 35 +++ apps/settings/serializers/auth/ldap.py | 3 + apps/settings/tasks/ldap.py | 22 +- .../templates/ldap/_msg_import_ldap_user.html | 30 ++ apps/settings/utils/ldap.py | 5 +- 12 files changed, 398 insertions(+), 253 deletions(-) create mode 100644 apps/settings/notifications.py create mode 100644 apps/settings/templates/ldap/_msg_import_ldap_user.html diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index d6fb241db..741a0e5db 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -282,6 +282,7 @@ class Config(dict): 'AUTH_LDAP_SYNC_INTERVAL': None, 'AUTH_LDAP_SYNC_CRONTAB': None, 'AUTH_LDAP_SYNC_ORG_IDS': ['00000000-0000-0000-0000-000000000002'], + 'AUTH_LDAP_SYNC_RECEIVERS': [], 'AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS': False, 'AUTH_LDAP_OPTIONS_OPT_REFERRALS': -1, diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index 66ae6289c..5e44a22a4 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -50,6 +50,7 @@ AUTH_LDAP_SYNC_IS_PERIODIC = CONFIG.AUTH_LDAP_SYNC_IS_PERIODIC AUTH_LDAP_SYNC_INTERVAL = CONFIG.AUTH_LDAP_SYNC_INTERVAL AUTH_LDAP_SYNC_CRONTAB = CONFIG.AUTH_LDAP_SYNC_CRONTAB AUTH_LDAP_SYNC_ORG_IDS = CONFIG.AUTH_LDAP_SYNC_ORG_IDS +AUTH_LDAP_SYNC_RECEIVERS = CONFIG.AUTH_LDAP_SYNC_RECEIVERS AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS = CONFIG.AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS # ============================================================================== diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 169dd1e30..ba844d417 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8f3d621226f7e11db46fb35abf0b5f5528eb454a3a6f889499d7872d41a275d -size 170675 +oid sha256:18c4618e0d0470e25d99b143e83de9a439ac691e5cb1d92ea5406cc32338e8f8 +size 170813 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index b566534c4..54a52ff27 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-01-03 11:23+0800\n" +"POT-Creation-Date: 2024-01-11 18:58+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -29,8 +29,9 @@ msgstr "パラメータ 'action' は [{}] でなければなりません。" #: authentication/confirm/password.py:26 authentication/forms.py:32 #: authentication/templates/authentication/login.html:330 #: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47 -#: terminal/serializers/storage.py:123 terminal/serializers/storage.py:142 -#: users/forms/profile.py:22 users/serializers/user.py:104 +#: settings/serializers/msg.py:35 terminal/serializers/storage.py:123 +#: terminal/serializers/storage.py:142 users/forms/profile.py:22 +#: users/serializers/user.py:104 #: users/templates/users/_msg_user_created.html:13 #: users/templates/users/user_password_verify.html:18 #: xpack/plugins/cloud/serializers/account_attrs.py:28 @@ -200,10 +201,10 @@ msgstr "作成のみ" #: authentication/serializers/password_mfa.py:16 #: authentication/serializers/password_mfa.py:24 #: notifications/backends/__init__.py:10 settings/serializers/msg.py:22 -#: settings/serializers/msg.py:57 users/forms/profile.py:102 +#: settings/serializers/msg.py:64 users/forms/profile.py:102 #: users/forms/profile.py:109 users/models/user.py:802 #: users/templates/users/forgot_password.html:117 -#: users/views/profile/reset.py:92 +#: users/views/profile/reset.py:93 msgid "Email" msgstr "メール" @@ -287,11 +288,11 @@ msgstr "ソース ID" #: accounts/serializers/automations/change_secret.py:107 #: accounts/serializers/automations/change_secret.py:127 #: acls/serializers/base.py:124 acls/templates/acls/asset_login_reminder.html:7 -#: assets/serializers/asset/common.py:125 assets/serializers/gateway.py:28 +#: assets/serializers/asset/common.py:128 assets/serializers/gateway.py:28 #: audits/models.py:59 authentication/api/connection_token.py:405 #: ops/models/base.py:18 perms/models/asset_permission.py:75 -#: perms/serializers/permission.py:41 terminal/backends/command/models.py:18 -#: terminal/models/session/session.py:33 +#: perms/serializers/permission.py:41 settings/serializers/msg.py:33 +#: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 #: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 @@ -361,8 +362,9 @@ msgstr "アカウントバックアップ計画" #: assets/models/automations/base.py:115 audits/models.py:65 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:235 #: ops/templates/ops/celery_task_log.html:75 -#: perms/models/asset_permission.py:78 terminal/models/applet/host.py:141 -#: terminal/models/session/session.py:44 +#: perms/models/asset_permission.py:78 +#: settings/templates/ldap/_msg_import_ldap_user.html:25 +#: terminal/models/applet/host.py:141 terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 msgid "Date start" @@ -371,6 +373,7 @@ msgstr "開始日" #: accounts/models/automations/backup_account.py:122 #: authentication/templates/authentication/_msg_oauth_bind.html:11 #: notifications/notifications.py:186 +#: settings/templates/ldap/_msg_import_ldap_user.html:23 msgid "Time" msgstr "時間" @@ -446,6 +449,7 @@ msgstr "SSHキープッシュ方式" #: accounts/models/automations/gather_account.py:58 #: accounts/serializers/account/backup.py:41 #: accounts/serializers/automations/change_secret.py:56 +#: settings/serializers/auth/ldap.py:81 msgid "Recipient" msgstr "受信者" @@ -491,6 +495,7 @@ msgstr "ステータス" #: authentication/templates/authentication/passkey.html:173 #: authentication/views/base.py:42 authentication/views/base.py:43 #: authentication/views/base.py:44 common/const/choices.py:20 +#: settings/templates/ldap/_msg_import_ldap_user.html:16 msgid "Error" msgstr "間違い" @@ -593,8 +598,8 @@ msgstr "パスワードルール" #: assets/models/asset/common.py:159 assets/models/cmd_filter.py:21 #: assets/models/domain.py:19 assets/models/group.py:17 #: assets/models/label.py:18 assets/models/platform.py:16 -#: assets/models/platform.py:95 assets/serializers/asset/common.py:146 -#: assets/serializers/platform.py:118 assets/serializers/platform.py:235 +#: assets/models/platform.py:95 assets/serializers/asset/common.py:149 +#: assets/serializers/platform.py:118 assets/serializers/platform.py:228 #: authentication/backends/passkey/models.py:10 #: authentication/serializers/connect_token_secret.py:113 #: authentication/serializers/connect_token_secret.py:168 labels/models.py:11 @@ -602,7 +607,7 @@ msgstr "パスワードルール" #: ops/models/celery.py:57 ops/models/job.py:136 ops/models/playbook.py:28 #: ops/serializers/job.py:18 orgs/models.py:82 #: perms/models/asset_permission.py:61 rbac/models/role.py:29 -#: settings/models.py:33 settings/models.py:181 settings/serializers/msg.py:82 +#: settings/models.py:33 settings/models.py:181 settings/serializers/msg.py:89 #: terminal/models/applet/applet.py:33 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:95 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 @@ -738,8 +743,8 @@ msgstr "アカウントの存在ポリシー" #: accounts/serializers/account/account.py:193 applications/models.py:11 #: assets/models/label.py:21 assets/models/platform.py:96 -#: assets/serializers/asset/common.py:122 assets/serializers/cagegory.py:12 -#: assets/serializers/platform.py:140 assets/serializers/platform.py:236 +#: assets/serializers/asset/common.py:125 assets/serializers/cagegory.py:12 +#: assets/serializers/platform.py:140 assets/serializers/platform.py:229 #: perms/serializers/user_permission.py:26 settings/models.py:35 #: tickets/models/ticket/apply_application.py:13 users/models/preference.py:12 msgid "Category" @@ -750,7 +755,7 @@ msgstr "カテゴリ" #: acls/serializers/command_acl.py:19 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/cmd_filter.py:74 assets/models/platform.py:97 -#: assets/serializers/asset/common.py:123 assets/serializers/platform.py:120 +#: assets/serializers/asset/common.py:126 assets/serializers/platform.py:120 #: assets/serializers/platform.py:139 audits/serializers.py:53 #: audits/serializers.py:170 #: authentication/serializers/connect_token_secret.py:126 ops/models/job.py:144 @@ -868,7 +873,7 @@ msgid "Key password" msgstr "キーパスワード" #: accounts/serializers/account/base.py:78 -#: assets/serializers/asset/common.py:379 +#: assets/serializers/asset/common.py:381 msgid "Spec info" msgstr "特別情報" @@ -1117,8 +1122,8 @@ msgid "Users" msgstr "ユーザー" #: acls/models/base.py:98 assets/models/automations/base.py:17 -#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:378 -#: perms/serializers/user_permission.py:75 rbac/tree.py:35 +#: assets/models/cmd_filter.py:38 perms/serializers/user_permission.py:75 +#: rbac/tree.py:35 msgid "Accounts" msgstr "アカウント" @@ -1423,8 +1428,8 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:71 -#: settings/serializers/feature.py:49 terminal/models/component/endpoint.py:13 -#: terminal/serializers/applet.py:17 +#: settings/serializers/feature.py:49 settings/serializers/msg.py:31 +#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" msgstr "ホスト" @@ -1548,7 +1553,7 @@ msgid "We will consider login success when we see this prompt" msgstr "このプロンプトが表示されたらログイン成功とみなします" #: assets/const/protocol.py:119 assets/models/asset/database.py:10 -#: settings/serializers/msg.py:40 +#: settings/serializers/msg.py:47 msgid "Use SSL" msgstr "SSLの使用" @@ -1663,7 +1668,7 @@ msgstr "ユーザーと同じユーザー名" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:114 -#: terminal/models/applet/applet.py:42 +#: settings/serializers/msg.py:29 terminal/models/applet/applet.py:42 #: terminal/models/virtualapp/virtualapp.py:24 #: terminal/serializers/session.py:19 terminal/serializers/session.py:45 #: terminal/serializers/storage.py:71 @@ -1716,12 +1721,12 @@ msgstr "クラウド サービス" #: assets/models/asset/common.py:94 assets/models/platform.py:17 #: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:72 -#: terminal/serializers/storage.py:133 +#: settings/serializers/msg.py:32 terminal/serializers/storage.py:133 #: xpack/plugins/cloud/serializers/account_attrs.py:73 msgid "Port" msgstr "ポート" -#: assets/models/asset/common.py:160 assets/serializers/asset/common.py:147 +#: assets/models/asset/common.py:160 assets/serializers/asset/common.py:150 msgid "Address" msgstr "アドレス" @@ -1745,7 +1750,7 @@ msgstr "ドメイン" msgid "Node" msgstr "ノード" -#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:380 +#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:382 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "資産ハードウェア情報の収集" @@ -1894,7 +1899,7 @@ msgstr "値" #: assets/serializers/platform.py:119 #: authentication/serializers/connect_token_secret.py:124 #: common/serializers/common.py:85 labels/models.py:17 labels/models.py:33 -#: labels/serializers.py:45 settings/serializers/msg.py:83 +#: labels/serializers.py:45 settings/serializers/msg.py:90 msgid "Label" msgstr "ラベル" @@ -2065,7 +2070,7 @@ msgstr "" "プラットフォームタイプがスキップされた資産に合致しない、資産内の一括更新プ" "ラットフォーム" -#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:141 +#: assets/serializers/asset/common.py:127 assets/serializers/platform.py:141 #: authentication/serializers/connect_token_secret.py:30 #: authentication/serializers/connect_token_secret.py:75 #: perms/models/asset_permission.py:76 perms/serializers/permission.py:42 @@ -2074,29 +2079,29 @@ msgstr "" msgid "Protocols" msgstr "プロトコル" -#: assets/serializers/asset/common.py:126 -#: assets/serializers/asset/common.py:148 +#: assets/serializers/asset/common.py:129 +#: assets/serializers/asset/common.py:151 msgid "Node path" msgstr "ノードパスです" -#: assets/serializers/asset/common.py:145 -#: assets/serializers/asset/common.py:381 +#: assets/serializers/asset/common.py:148 +#: assets/serializers/asset/common.py:383 msgid "Auto info" msgstr "自動情報" -#: assets/serializers/asset/common.py:239 +#: assets/serializers/asset/common.py:242 msgid "Platform not exist" msgstr "プラットフォームが存在しません" -#: assets/serializers/asset/common.py:275 +#: assets/serializers/asset/common.py:278 msgid "port out of range (0-65535)" msgstr "ポート番号が範囲外です (0-65535)" -#: assets/serializers/asset/common.py:282 +#: assets/serializers/asset/common.py:285 msgid "Protocol is required: {}" msgstr "プロトコルが必要です: {}" -#: assets/serializers/asset/common.py:310 +#: assets/serializers/asset/common.py:313 msgid "Invalid data" msgstr "無効なデータ" @@ -2251,7 +2256,7 @@ msgstr "デフォルト ドメイン" msgid "type is required" msgstr "タイプ このフィールドは必須です." -#: assets/serializers/platform.py:211 +#: assets/serializers/platform.py:204 msgid "Protocols is required" msgstr "同意が必要です" @@ -2606,8 +2611,8 @@ msgstr "認証トークン" #: audits/signal_handlers/login_log.py:37 authentication/notifications.py:73 #: authentication/views/login.py:77 notifications/backends/__init__.py:11 -#: settings/serializers/auth/wecom.py:10 users/models/user.py:749 -#: users/models/user.py:855 +#: settings/notifications.py:68 settings/serializers/auth/wecom.py:10 +#: users/models/user.py:749 users/models/user.py:855 msgid "WeCom" msgstr "企業微信" @@ -2694,16 +2699,16 @@ msgstr "ACL アクションはレビューです" msgid "Current user not support mfa type: {}" msgstr "現在のユーザーはmfaタイプをサポートしていません: {}" -#: authentication/api/password.py:34 terminal/api/session/session.py:305 -#: users/views/profile/reset.py:61 +#: authentication/api/password.py:33 terminal/api/session/session.py:305 +#: users/views/profile/reset.py:62 msgid "User does not exist: {}" msgstr "ユーザーが存在しない: {}" -#: authentication/api/password.py:34 users/views/profile/reset.py:163 +#: authentication/api/password.py:33 users/views/profile/reset.py:163 msgid "No user matched" msgstr "ユーザーにマッチしなかった" -#: authentication/api/password.py:38 +#: authentication/api/password.py:37 msgid "" "The user is from {}, please go to the corresponding system to change the " "password" @@ -2711,7 +2716,7 @@ msgstr "" "ユーザーは {}からです。対応するシステムにアクセスしてパスワードを変更してくだ" "さい。" -#: authentication/api/password.py:67 +#: authentication/api/password.py:65 #: authentication/templates/authentication/login.html:361 #: users/templates/users/forgot_password.html:27 #: users/templates/users/forgot_password.html:28 @@ -3031,7 +3036,7 @@ msgstr "メッセージ検証コードが無効" #: authentication/serializers/password_mfa.py:24 #: settings/serializers/auth/sms.py:32 users/forms/profile.py:104 #: users/forms/profile.py:109 users/templates/users/forgot_password.html:112 -#: users/views/profile/reset.py:98 +#: users/views/profile/reset.py:99 msgid "SMS" msgstr "メッセージ" @@ -3047,7 +3052,7 @@ msgstr "電話番号を設定して有効にする" msgid "Clear phone number to disable" msgstr "無効にする電話番号をクリアする" -#: authentication/middleware.py:94 settings/utils/ldap.py:676 +#: authentication/middleware.py:94 settings/utils/ldap.py:679 msgid "Authentication failed (before login check failed): {}" msgstr "認証に失敗しました (ログインチェックが失敗する前): {}" @@ -3171,7 +3176,7 @@ msgstr "確認済み" msgid "Different city login reminder" msgstr "異なる都市ログインのリマインダー" -#: authentication/notifications.py:52 +#: authentication/notifications.py:52 settings/notifications.py:47 msgid "binding reminder" msgstr "バインディングリマインダー" @@ -3309,7 +3314,7 @@ msgstr "コードエラー" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:457 +#: jumpserver/conf.py:460 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:32 @@ -3481,7 +3486,7 @@ msgstr "" msgid "Do you want to retry ?" msgstr "再試行しますか?" -#: authentication/utils.py:23 common/utils/ip/geoip/utils.py:24 +#: authentication/utils.py:24 common/utils/ip/geoip/utils.py:24 #: xpack/plugins/cloud/const.py:32 msgid "LAN" msgstr "ローカルエリアネットワーク" @@ -3818,7 +3823,7 @@ msgstr "サポートされていません Elasticsearch8" msgid "Network error, please contact system administrator" msgstr "ネットワークエラー、システム管理者に連絡してください" -#: common/sdk/im/slack/__init__.py:79 +#: common/sdk/im/slack/__init__.py:77 msgid "Unknown error occur" msgstr "不明なエラーが発生しました" @@ -3913,15 +3918,15 @@ msgstr "無効なオプション: {}" msgid "Labels" msgstr "ラベル" -#: common/tasks.py:21 common/utils/verify_code.py:16 +#: common/tasks.py:31 common/utils/verify_code.py:16 msgid "Send email" msgstr "メールを送る" -#: common/tasks.py:48 +#: common/tasks.py:58 msgid "Send email attachment" msgstr "メールの添付ファイルを送信" -#: common/tasks.py:69 terminal/tasks.py:62 +#: common/tasks.py:80 terminal/tasks.py:62 msgid "Upload session replay to external storage" msgstr "セッションの記録を外部ストレージにアップロードする" @@ -3950,16 +3955,16 @@ msgstr "特殊文字を含むべきではない" msgid "The mobile phone number format is incorrect" msgstr "携帯電話番号の形式が正しくありません" -#: jumpserver/conf.py:452 +#: jumpserver/conf.py:454 #, python-brace-format msgid "The verification code is: {code}" msgstr "認証コードは: {code}" -#: jumpserver/conf.py:456 +#: jumpserver/conf.py:459 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:458 +#: jumpserver/conf.py:461 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -4382,6 +4387,7 @@ msgid "Is finished" msgstr "終了しました" #: ops/serializers/job.py:66 +#: settings/templates/ldap/_msg_import_ldap_user.html:27 msgid "Time cost" msgstr "時を過ごす" @@ -4867,7 +4873,7 @@ msgstr "チャットAIがオンになっていない" msgid "Test success" msgstr "テストの成功" -#: settings/api/email.py:21 +#: settings/api/email.py:22 msgid "Test mail sent to {}, please check" msgstr "{}に送信されたテストメールを確認してください" @@ -4970,6 +4976,10 @@ msgstr "他の設定を変えることができます" msgid "Chat prompt" msgstr "チャットのヒント" +#: settings/notifications.py:22 +msgid "Notification of Synchronized LDAP User Task Results" +msgstr "LDAPユーザータスクの結果通知を同期する" + #: settings/serializers/auth/base.py:12 msgid "LDAP Auth" msgstr "LDAP 認証" @@ -5125,7 +5135,7 @@ msgstr "接続タイムアウト (秒)" msgid "Search paged size (piece)" msgstr "ページサイズを検索 (じょう)" -#: settings/serializers/auth/ldap.py:81 +#: settings/serializers/auth/ldap.py:84 msgid "Enable LDAP auth" msgstr "LDAP認証の有効化" @@ -5342,7 +5352,7 @@ msgstr "認証コード長" #: settings/serializers/auth/sms.py:27 settings/serializers/auth/sms.py:49 #: settings/serializers/auth/sms.py:57 settings/serializers/auth/sms.py:66 -#: settings/serializers/auth/sms.py:77 settings/serializers/msg.py:76 +#: settings/serializers/auth/sms.py:77 settings/serializers/msg.py:83 msgid "Signature" msgstr "署名" @@ -5628,74 +5638,68 @@ msgstr "仮想アプリケーション" msgid "Enable virtual app" msgstr "仮想アプリケーションの有効化" -#: settings/serializers/msg.py:24 -msgid "SMTP host" +#: settings/serializers/msg.py:25 +#, fuzzy +#| msgid "SMTP host" +msgid "SMTP" msgstr "SMTPホスト" -#: settings/serializers/msg.py:25 -msgid "SMTP port" -msgstr "SMTPポート" - #: settings/serializers/msg.py:26 -msgid "SMTP account" -msgstr "SMTPアカウント" +msgid "EXCHANGE" +msgstr "" -#: settings/serializers/msg.py:28 -msgid "SMTP password" -msgstr "SMTPパスワード" - -#: settings/serializers/msg.py:29 +#: settings/serializers/msg.py:36 msgid "Tips: Some provider use token except password" msgstr "ヒント: 一部のプロバイダーはパスワード以外のトークンを使用します" -#: settings/serializers/msg.py:32 +#: settings/serializers/msg.py:39 msgid "Send user" msgstr "ユーザーを送信" -#: settings/serializers/msg.py:33 +#: settings/serializers/msg.py:40 msgid "Tips: Send mail account, default SMTP account as the send account" msgstr "" "ヒント: 送信メールアカウント、送信アカウントとしてのデフォルトのSMTPアカウン" "ト" -#: settings/serializers/msg.py:36 +#: settings/serializers/msg.py:43 msgid "Test recipient" msgstr "テスト受信者" -#: settings/serializers/msg.py:37 +#: settings/serializers/msg.py:44 msgid "Tips: Used only as a test mail recipient" msgstr "ヒント: テストメールの受信者としてのみ使用" -#: settings/serializers/msg.py:41 +#: settings/serializers/msg.py:48 msgid "If SMTP port is 465, may be select" msgstr "SMTPポートが465の場合は、" -#: settings/serializers/msg.py:44 +#: settings/serializers/msg.py:51 msgid "Use TLS" msgstr "TLSの使用" -#: settings/serializers/msg.py:45 +#: settings/serializers/msg.py:52 msgid "If SMTP port is 587, may be select" msgstr "SMTPポートが587の場合は、" -#: settings/serializers/msg.py:48 +#: settings/serializers/msg.py:55 msgid "Subject prefix" msgstr "件名プレフィックス" -#: settings/serializers/msg.py:51 +#: settings/serializers/msg.py:58 msgid "Email suffix" msgstr "メールのサフィックス" -#: settings/serializers/msg.py:52 +#: settings/serializers/msg.py:59 msgid "" "This is used by default if no email is returned during SSO authentication" msgstr "これは、SSO認証中にメールが返されない場合にデフォルトで使用されます。" -#: settings/serializers/msg.py:61 +#: settings/serializers/msg.py:68 msgid "Create user email subject" msgstr "ユーザーメール件名の作成" -#: settings/serializers/msg.py:62 +#: settings/serializers/msg.py:69 msgid "" "Tips: When creating a user, send the subject of the email (eg:Create account " "successfully)" @@ -5703,20 +5707,20 @@ msgstr "" "ヒント: ユーザーを作成するときに、メールの件名を送信します (例: アカウントを" "正常に作成)" -#: settings/serializers/msg.py:66 +#: settings/serializers/msg.py:73 msgid "Create user honorific" msgstr "ユーザー敬語の作成" -#: settings/serializers/msg.py:67 +#: settings/serializers/msg.py:74 msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)" msgstr "" "ヒント: ユーザーを作成するときは、メールの敬語を送信します (例: こんにちは)" -#: settings/serializers/msg.py:71 +#: settings/serializers/msg.py:78 msgid "Create user email content" msgstr "ユーザーのメールコンテンツを作成する" -#: settings/serializers/msg.py:73 +#: settings/serializers/msg.py:80 #, python-brace-format msgid "" "Tips: When creating a user, send the content of the email, support " @@ -5725,7 +5729,7 @@ msgstr "" "ヒント:ユーザーの作成時にパスワード設定メールの内容を送信し、{username}{name}" "{email}ラベルをサポートします。" -#: settings/serializers/msg.py:77 +#: settings/serializers/msg.py:84 msgid "Tips: Email signature (eg:jumpserver)" msgstr "ヒント: メール署名 (例: jumpserver)" @@ -6085,112 +6089,129 @@ msgstr "Razor の有効化" msgid "Enable SSH Client" msgstr "SSH Clientの有効化" -#: settings/tasks/ldap.py:24 +#: settings/tasks/ldap.py:29 msgid "Periodic import ldap user" msgstr "LDAP ユーザーを定期的にインポートする" -#: settings/tasks/ldap.py:45 +#: settings/tasks/ldap.py:66 msgid "Registration periodic import ldap user task" msgstr "登録サイクルLDAPユーザータスクのインポート" -#: settings/utils/ldap.py:491 +#: settings/templates/ldap/_msg_import_ldap_user.html:2 +msgid "Sync task Finish" +msgstr "同期タスクが完了しました" + +#: settings/templates/ldap/_msg_import_ldap_user.html:3 +msgid "Synced Organization" +msgstr "組織が同期されました" + +#: settings/templates/ldap/_msg_import_ldap_user.html:9 +msgid "Synced User" +msgstr "同期されたユーザー" + +#: settings/templates/ldap/_msg_import_ldap_user.html:26 +#: terminal/models/session/session.py:45 +msgid "Date end" +msgstr "終了日" + +#: settings/utils/ldap.py:494 msgid "ldap:// or ldaps:// protocol is used." msgstr "ldap:// または ldaps:// プロトコルが使用されます。" -#: settings/utils/ldap.py:502 +#: settings/utils/ldap.py:505 msgid "Host or port is disconnected: {}" msgstr "ホストまたはポートが切断されました: {}" -#: settings/utils/ldap.py:504 +#: settings/utils/ldap.py:507 msgid "The port is not the port of the LDAP service: {}" msgstr "ポートはLDAPサービスのポートではありません: {}" -#: settings/utils/ldap.py:506 +#: settings/utils/ldap.py:509 msgid "Please add certificate: {}" msgstr "証明書を追加してください: {}" -#: settings/utils/ldap.py:510 settings/utils/ldap.py:537 -#: settings/utils/ldap.py:567 settings/utils/ldap.py:595 +#: settings/utils/ldap.py:513 settings/utils/ldap.py:540 +#: settings/utils/ldap.py:570 settings/utils/ldap.py:598 msgid "Unknown error: {}" msgstr "不明なエラー: {}" -#: settings/utils/ldap.py:524 +#: settings/utils/ldap.py:527 msgid "Bind DN or Password incorrect" msgstr "DNまたはパスワードのバインドが正しくありません" -#: settings/utils/ldap.py:531 +#: settings/utils/ldap.py:534 msgid "Please enter Bind DN: {}" msgstr "バインドDN: {} を入力してください" -#: settings/utils/ldap.py:533 +#: settings/utils/ldap.py:536 msgid "Please enter Password: {}" msgstr "パスワードを入力してください: {}" -#: settings/utils/ldap.py:535 +#: settings/utils/ldap.py:538 msgid "Please enter correct Bind DN and Password: {}" msgstr "正しいバインドDNとパスワードを入力してください: {}" -#: settings/utils/ldap.py:553 +#: settings/utils/ldap.py:556 msgid "Invalid User OU or User search filter: {}" msgstr "無効なユーザー OU またはユーザー検索フィルター: {}" -#: settings/utils/ldap.py:584 +#: settings/utils/ldap.py:587 msgid "LDAP User attr map not include: {}" msgstr "LDAP ユーザーattrマップは含まれません: {}" -#: settings/utils/ldap.py:591 +#: settings/utils/ldap.py:594 msgid "LDAP User attr map is not dict" msgstr "LDAPユーザーattrマップはdictではありません" -#: settings/utils/ldap.py:610 +#: settings/utils/ldap.py:613 msgid "LDAP authentication is not enabled" msgstr "LDAP 認証が有効になっていない" -#: settings/utils/ldap.py:628 +#: settings/utils/ldap.py:631 msgid "Error (Invalid LDAP server): {}" msgstr "エラー (LDAPサーバーが無効): {}" -#: settings/utils/ldap.py:630 +#: settings/utils/ldap.py:633 msgid "Error (Invalid Bind DN): {}" msgstr "エラー (DNのバインドが無効): {}" -#: settings/utils/ldap.py:632 +#: settings/utils/ldap.py:635 msgid "Error (Invalid LDAP User attr map): {}" msgstr "エラー (LDAPユーザーattrマップが無効): {}" -#: settings/utils/ldap.py:634 +#: settings/utils/ldap.py:637 msgid "Error (Invalid User OU or User search filter): {}" msgstr "エラー (ユーザーOUまたはユーザー検索フィルターが無効): {}" -#: settings/utils/ldap.py:636 +#: settings/utils/ldap.py:639 msgid "Error (Not enabled LDAP authentication): {}" msgstr "エラー (LDAP認証が有効化されていません): {}" -#: settings/utils/ldap.py:638 +#: settings/utils/ldap.py:641 msgid "Error (Unknown): {}" msgstr "エラー (不明): {}" -#: settings/utils/ldap.py:641 +#: settings/utils/ldap.py:644 msgid "Succeed: Match {} s user" msgstr "成功: {} 人のユーザーに一致" -#: settings/utils/ldap.py:652 +#: settings/utils/ldap.py:655 msgid "Please test the connection first" msgstr "まず接続をテストしてください" -#: settings/utils/ldap.py:674 +#: settings/utils/ldap.py:677 msgid "Authentication failed (configuration incorrect): {}" msgstr "認証に失敗しました (設定が正しくありません): {}" -#: settings/utils/ldap.py:678 +#: settings/utils/ldap.py:681 msgid "Authentication failed (username or password incorrect): {}" msgstr "認証に失敗しました (ユーザー名またはパスワードが正しくありません): {}" -#: settings/utils/ldap.py:680 +#: settings/utils/ldap.py:683 msgid "Authentication failed (Unknown): {}" msgstr "認証に失敗しました (不明): {}" -#: settings/utils/ldap.py:683 +#: settings/utils/ldap.py:686 msgid "Authentication success: {}" msgstr "認証成功: {}" @@ -6803,10 +6824,6 @@ msgstr "ログイン元" msgid "Replay" msgstr "リプレイ" -#: terminal/models/session/session.py:45 -msgid "Date end" -msgstr "終了日" - #: terminal/models/session/session.py:47 terminal/serializers/session.py:65 msgid "Command amount" msgstr "コマンド量" @@ -8315,7 +8332,7 @@ msgstr "OTP無効化成功、ログインページを返す" msgid "Password invalid" msgstr "パスワード無効" -#: users/views/profile/reset.py:64 +#: users/views/profile/reset.py:65 msgid "" "Non-local users can log in only from third-party platforms and cannot change " "their passwords: {}" @@ -8492,7 +8509,7 @@ msgstr "そして" msgid "Or" msgstr "または" -#: xpack/plugins/cloud/manager.py:56 +#: xpack/plugins/cloud/manager.py:57 msgid "Account unavailable" msgstr "利用できないアカウント" @@ -9042,6 +9059,15 @@ msgstr "エンタープライズプロフェッショナル版" msgid "Ultimate edition" msgstr "エンタープライズ・フラッグシップ・エディション" +#~ msgid "SMTP port" +#~ msgstr "SMTPポート" + +#~ msgid "SMTP account" +#~ msgstr "SMTPアカウント" + +#~ msgid "SMTP password" +#~ msgstr "SMTPパスワード" + #~ msgid "Password can not contains `{{` or `}}`" #~ msgstr "パスワードには `{` または `}` 文字を含めることはできません" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 4efb8d030..efb8daa9d 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44d560db28dc9dd1a450f7e715b6de7a18ba44caece18f4e7da40c1659eefc48 -size 139920 +oid sha256:933315b682ee1387f7433b5a870d8597c07634f4fede4c56a42b4cab540e4208 +size 140012 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 335b5d3de..aabbbb733 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-01-03 11:23+0800\n" +"POT-Creation-Date: 2024-01-11 18:58+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -28,8 +28,9 @@ msgstr "参数 'action' 必须是 [{}]" #: authentication/confirm/password.py:26 authentication/forms.py:32 #: authentication/templates/authentication/login.html:330 #: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47 -#: terminal/serializers/storage.py:123 terminal/serializers/storage.py:142 -#: users/forms/profile.py:22 users/serializers/user.py:104 +#: settings/serializers/msg.py:35 terminal/serializers/storage.py:123 +#: terminal/serializers/storage.py:142 users/forms/profile.py:22 +#: users/serializers/user.py:104 #: users/templates/users/_msg_user_created.html:13 #: users/templates/users/user_password_verify.html:18 #: xpack/plugins/cloud/serializers/account_attrs.py:28 @@ -199,10 +200,10 @@ msgstr "仅创建" #: authentication/serializers/password_mfa.py:16 #: authentication/serializers/password_mfa.py:24 #: notifications/backends/__init__.py:10 settings/serializers/msg.py:22 -#: settings/serializers/msg.py:57 users/forms/profile.py:102 +#: settings/serializers/msg.py:64 users/forms/profile.py:102 #: users/forms/profile.py:109 users/models/user.py:802 #: users/templates/users/forgot_password.html:117 -#: users/views/profile/reset.py:92 +#: users/views/profile/reset.py:93 msgid "Email" msgstr "邮箱" @@ -286,11 +287,11 @@ msgstr "来源 ID" #: accounts/serializers/automations/change_secret.py:107 #: accounts/serializers/automations/change_secret.py:127 #: acls/serializers/base.py:124 acls/templates/acls/asset_login_reminder.html:7 -#: assets/serializers/asset/common.py:125 assets/serializers/gateway.py:28 +#: assets/serializers/asset/common.py:128 assets/serializers/gateway.py:28 #: audits/models.py:59 authentication/api/connection_token.py:405 #: ops/models/base.py:18 perms/models/asset_permission.py:75 -#: perms/serializers/permission.py:41 terminal/backends/command/models.py:18 -#: terminal/models/session/session.py:33 +#: perms/serializers/permission.py:41 settings/serializers/msg.py:33 +#: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 #: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 @@ -360,8 +361,9 @@ msgstr "账号备份计划" #: assets/models/automations/base.py:115 audits/models.py:65 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:235 #: ops/templates/ops/celery_task_log.html:75 -#: perms/models/asset_permission.py:78 terminal/models/applet/host.py:141 -#: terminal/models/session/session.py:44 +#: perms/models/asset_permission.py:78 +#: settings/templates/ldap/_msg_import_ldap_user.html:25 +#: terminal/models/applet/host.py:141 terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 msgid "Date start" @@ -370,6 +372,7 @@ msgstr "开始日期" #: accounts/models/automations/backup_account.py:122 #: authentication/templates/authentication/_msg_oauth_bind.html:11 #: notifications/notifications.py:186 +#: settings/templates/ldap/_msg_import_ldap_user.html:23 msgid "Time" msgstr "时间" @@ -445,6 +448,7 @@ msgstr "SSH 密钥推送方式" #: accounts/models/automations/gather_account.py:58 #: accounts/serializers/account/backup.py:41 #: accounts/serializers/automations/change_secret.py:56 +#: settings/serializers/auth/ldap.py:81 msgid "Recipient" msgstr "收件人" @@ -490,6 +494,7 @@ msgstr "状态" #: authentication/templates/authentication/passkey.html:173 #: authentication/views/base.py:42 authentication/views/base.py:43 #: authentication/views/base.py:44 common/const/choices.py:20 +#: settings/templates/ldap/_msg_import_ldap_user.html:16 msgid "Error" msgstr "错误" @@ -592,8 +597,8 @@ msgstr "密码规则" #: assets/models/asset/common.py:159 assets/models/cmd_filter.py:21 #: assets/models/domain.py:19 assets/models/group.py:17 #: assets/models/label.py:18 assets/models/platform.py:16 -#: assets/models/platform.py:95 assets/serializers/asset/common.py:146 -#: assets/serializers/platform.py:118 assets/serializers/platform.py:235 +#: assets/models/platform.py:95 assets/serializers/asset/common.py:149 +#: assets/serializers/platform.py:118 assets/serializers/platform.py:228 #: authentication/backends/passkey/models.py:10 #: authentication/serializers/connect_token_secret.py:113 #: authentication/serializers/connect_token_secret.py:168 labels/models.py:11 @@ -601,7 +606,7 @@ msgstr "密码规则" #: ops/models/celery.py:57 ops/models/job.py:136 ops/models/playbook.py:28 #: ops/serializers/job.py:18 orgs/models.py:82 #: perms/models/asset_permission.py:61 rbac/models/role.py:29 -#: settings/models.py:33 settings/models.py:181 settings/serializers/msg.py:82 +#: settings/models.py:33 settings/models.py:181 settings/serializers/msg.py:89 #: terminal/models/applet/applet.py:33 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:95 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 @@ -736,8 +741,8 @@ msgstr "账号存在策略" #: accounts/serializers/account/account.py:193 applications/models.py:11 #: assets/models/label.py:21 assets/models/platform.py:96 -#: assets/serializers/asset/common.py:122 assets/serializers/cagegory.py:12 -#: assets/serializers/platform.py:140 assets/serializers/platform.py:236 +#: assets/serializers/asset/common.py:125 assets/serializers/cagegory.py:12 +#: assets/serializers/platform.py:140 assets/serializers/platform.py:229 #: perms/serializers/user_permission.py:26 settings/models.py:35 #: tickets/models/ticket/apply_application.py:13 users/models/preference.py:12 msgid "Category" @@ -748,7 +753,7 @@ msgstr "类别" #: acls/serializers/command_acl.py:19 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/cmd_filter.py:74 assets/models/platform.py:97 -#: assets/serializers/asset/common.py:123 assets/serializers/platform.py:120 +#: assets/serializers/asset/common.py:126 assets/serializers/platform.py:120 #: assets/serializers/platform.py:139 audits/serializers.py:53 #: audits/serializers.py:170 #: authentication/serializers/connect_token_secret.py:126 ops/models/job.py:144 @@ -866,7 +871,7 @@ msgid "Key password" msgstr "密钥密码" #: accounts/serializers/account/base.py:78 -#: assets/serializers/asset/common.py:379 +#: assets/serializers/asset/common.py:381 msgid "Spec info" msgstr "特殊信息" @@ -1113,8 +1118,8 @@ msgid "Users" msgstr "用户管理" #: acls/models/base.py:98 assets/models/automations/base.py:17 -#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:378 -#: perms/serializers/user_permission.py:75 rbac/tree.py:35 +#: assets/models/cmd_filter.py:38 perms/serializers/user_permission.py:75 +#: rbac/tree.py:35 msgid "Accounts" msgstr "账号管理" @@ -1415,8 +1420,8 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:71 -#: settings/serializers/feature.py:49 terminal/models/component/endpoint.py:13 -#: terminal/serializers/applet.py:17 +#: settings/serializers/feature.py:49 settings/serializers/msg.py:31 +#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" msgstr "主机" @@ -1539,7 +1544,7 @@ msgid "We will consider login success when we see this prompt" msgstr "当我们看到这个提示时,我们将认为登录成功" #: assets/const/protocol.py:119 assets/models/asset/database.py:10 -#: settings/serializers/msg.py:40 +#: settings/serializers/msg.py:47 msgid "Use SSL" msgstr "使用 SSL" @@ -1655,7 +1660,7 @@ msgstr "用户名与用户相同" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:114 -#: terminal/models/applet/applet.py:42 +#: settings/serializers/msg.py:29 terminal/models/applet/applet.py:42 #: terminal/models/virtualapp/virtualapp.py:24 #: terminal/serializers/session.py:19 terminal/serializers/session.py:45 #: terminal/serializers/storage.py:71 @@ -1708,12 +1713,12 @@ msgstr "云服务" #: assets/models/asset/common.py:94 assets/models/platform.py:17 #: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:72 -#: terminal/serializers/storage.py:133 +#: settings/serializers/msg.py:32 terminal/serializers/storage.py:133 #: xpack/plugins/cloud/serializers/account_attrs.py:73 msgid "Port" msgstr "端口" -#: assets/models/asset/common.py:160 assets/serializers/asset/common.py:147 +#: assets/models/asset/common.py:160 assets/serializers/asset/common.py:150 msgid "Address" msgstr "地址" @@ -1737,7 +1742,7 @@ msgstr "网域" msgid "Node" msgstr "节点" -#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:380 +#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:382 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "收集资产硬件信息" @@ -1886,7 +1891,7 @@ msgstr "值" #: assets/serializers/platform.py:119 #: authentication/serializers/connect_token_secret.py:124 #: common/serializers/common.py:85 labels/models.py:17 labels/models.py:33 -#: labels/serializers.py:45 settings/serializers/msg.py:83 +#: labels/serializers.py:45 settings/serializers/msg.py:90 msgid "Label" msgstr "标签" @@ -2055,7 +2060,7 @@ msgid "" "type" msgstr "资产中批量更新平台,不符合平台类型跳过的资产" -#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:141 +#: assets/serializers/asset/common.py:127 assets/serializers/platform.py:141 #: authentication/serializers/connect_token_secret.py:30 #: authentication/serializers/connect_token_secret.py:75 #: perms/models/asset_permission.py:76 perms/serializers/permission.py:42 @@ -2064,29 +2069,29 @@ msgstr "资产中批量更新平台,不符合平台类型跳过的资产" msgid "Protocols" msgstr "协议组" -#: assets/serializers/asset/common.py:126 -#: assets/serializers/asset/common.py:148 +#: assets/serializers/asset/common.py:129 +#: assets/serializers/asset/common.py:151 msgid "Node path" msgstr "节点路径" -#: assets/serializers/asset/common.py:145 -#: assets/serializers/asset/common.py:381 +#: assets/serializers/asset/common.py:148 +#: assets/serializers/asset/common.py:383 msgid "Auto info" msgstr "自动化信息" -#: assets/serializers/asset/common.py:239 +#: assets/serializers/asset/common.py:242 msgid "Platform not exist" msgstr "平台不存在" -#: assets/serializers/asset/common.py:275 +#: assets/serializers/asset/common.py:278 msgid "port out of range (0-65535)" msgstr "端口超出范围 (0-65535)" -#: assets/serializers/asset/common.py:282 +#: assets/serializers/asset/common.py:285 msgid "Protocol is required: {}" msgstr "协议是必填的: {}" -#: assets/serializers/asset/common.py:310 +#: assets/serializers/asset/common.py:313 msgid "Invalid data" msgstr "无效的数据" @@ -2236,7 +2241,7 @@ msgstr "默认网域" msgid "type is required" msgstr "类型 该字段是必填项。" -#: assets/serializers/platform.py:211 +#: assets/serializers/platform.py:204 msgid "Protocols is required" msgstr "协议是必填的" @@ -2589,8 +2594,8 @@ msgstr "认证令牌" #: audits/signal_handlers/login_log.py:37 authentication/notifications.py:73 #: authentication/views/login.py:77 notifications/backends/__init__.py:11 -#: settings/serializers/auth/wecom.py:10 users/models/user.py:749 -#: users/models/user.py:855 +#: settings/notifications.py:68 settings/serializers/auth/wecom.py:10 +#: users/models/user.py:749 users/models/user.py:855 msgid "WeCom" msgstr "企业微信" @@ -2675,22 +2680,22 @@ msgstr "ACL 动作是复核" msgid "Current user not support mfa type: {}" msgstr "当前用户不支持 MFA 类型: {}" -#: authentication/api/password.py:34 terminal/api/session/session.py:305 -#: users/views/profile/reset.py:61 +#: authentication/api/password.py:33 terminal/api/session/session.py:305 +#: users/views/profile/reset.py:62 msgid "User does not exist: {}" msgstr "用户不存在: {}" -#: authentication/api/password.py:34 users/views/profile/reset.py:163 +#: authentication/api/password.py:33 users/views/profile/reset.py:163 msgid "No user matched" msgstr "没有匹配到用户" -#: authentication/api/password.py:38 +#: authentication/api/password.py:37 msgid "" "The user is from {}, please go to the corresponding system to change the " "password" msgstr "用户来自 {} 请去相应系统修改密码" -#: authentication/api/password.py:67 +#: authentication/api/password.py:65 #: authentication/templates/authentication/login.html:361 #: users/templates/users/forgot_password.html:27 #: users/templates/users/forgot_password.html:28 @@ -3001,7 +3006,7 @@ msgstr "短信验证码校验失败" #: authentication/serializers/password_mfa.py:24 #: settings/serializers/auth/sms.py:32 users/forms/profile.py:104 #: users/forms/profile.py:109 users/templates/users/forgot_password.html:112 -#: users/views/profile/reset.py:98 +#: users/views/profile/reset.py:99 msgid "SMS" msgstr "短信" @@ -3017,7 +3022,7 @@ msgstr "设置手机号码启用" msgid "Clear phone number to disable" msgstr "清空手机号码禁用" -#: authentication/middleware.py:94 settings/utils/ldap.py:676 +#: authentication/middleware.py:94 settings/utils/ldap.py:679 msgid "Authentication failed (before login check failed): {}" msgstr "认证失败 (登录前检查失败): {}" @@ -3139,7 +3144,7 @@ msgstr "已校验" msgid "Different city login reminder" msgstr "异地登录提醒" -#: authentication/notifications.py:52 +#: authentication/notifications.py:52 settings/notifications.py:47 msgid "binding reminder" msgstr "绑定提醒" @@ -3277,7 +3282,7 @@ msgstr "代码错误" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:457 +#: jumpserver/conf.py:460 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:32 @@ -3437,7 +3442,7 @@ msgstr "本页面未使用 HTTPS 协议,请使用 HTTPS 协议以确保您的 msgid "Do you want to retry ?" msgstr "是否重试 ?" -#: authentication/utils.py:23 common/utils/ip/geoip/utils.py:24 +#: authentication/utils.py:24 common/utils/ip/geoip/utils.py:24 #: xpack/plugins/cloud/const.py:32 msgid "LAN" msgstr "局域网" @@ -3772,7 +3777,7 @@ msgstr "不支持 Elasticsearch8" msgid "Network error, please contact system administrator" msgstr "网络错误,请联系系统管理员" -#: common/sdk/im/slack/__init__.py:79 +#: common/sdk/im/slack/__init__.py:77 msgid "Unknown error occur" msgstr "发生未知错误" @@ -3869,15 +3874,15 @@ msgstr "标签管理" # msgid "Labels" # msgstr "标签管理" -#: common/tasks.py:21 common/utils/verify_code.py:16 +#: common/tasks.py:31 common/utils/verify_code.py:16 msgid "Send email" msgstr "发件邮件" -#: common/tasks.py:48 +#: common/tasks.py:58 msgid "Send email attachment" msgstr "发送邮件附件" -#: common/tasks.py:69 terminal/tasks.py:62 +#: common/tasks.py:80 terminal/tasks.py:62 msgid "Upload session replay to external storage" msgstr "上传会话录像到外部存储" @@ -3906,16 +3911,16 @@ msgstr "不能包含特殊字符" msgid "The mobile phone number format is incorrect" msgstr "手机号格式不正确" -#: jumpserver/conf.py:452 +#: jumpserver/conf.py:454 #, python-brace-format msgid "The verification code is: {code}" msgstr "验证码为: {code}" -#: jumpserver/conf.py:456 +#: jumpserver/conf.py:459 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:458 +#: jumpserver/conf.py:461 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -4331,6 +4336,7 @@ msgid "Is finished" msgstr "是否完成" #: ops/serializers/job.py:66 +#: settings/templates/ldap/_msg_import_ldap_user.html:27 msgid "Time cost" msgstr "花费时间" @@ -4814,7 +4820,7 @@ msgstr "聊天 AI 没有开启" msgid "Test success" msgstr "测试成功" -#: settings/api/email.py:21 +#: settings/api/email.py:22 msgid "Test mail sent to {}, please check" msgstr "邮件已经发送{}, 请检查" @@ -4915,6 +4921,10 @@ msgstr "其它设置" msgid "Chat prompt" msgstr "聊天提示" +#: settings/notifications.py:22 +msgid "Notification of Synchronized LDAP User Task Results" +msgstr "同步LDAP用户任务结果通知" + #: settings/serializers/auth/base.py:12 msgid "LDAP Auth" msgstr "LDAP 认证" @@ -5070,7 +5080,7 @@ msgstr "连接超时时间 (秒)" msgid "Search paged size (piece)" msgstr "搜索分页数量 (条)" -#: settings/serializers/auth/ldap.py:81 +#: settings/serializers/auth/ldap.py:84 msgid "Enable LDAP auth" msgstr "启用 LDAP 认证" @@ -5286,7 +5296,7 @@ msgstr "验证码长度" #: settings/serializers/auth/sms.py:27 settings/serializers/auth/sms.py:49 #: settings/serializers/auth/sms.py:57 settings/serializers/auth/sms.py:66 -#: settings/serializers/auth/sms.py:77 settings/serializers/msg.py:76 +#: settings/serializers/auth/sms.py:77 settings/serializers/msg.py:83 msgid "Signature" msgstr "签名" @@ -5568,90 +5578,84 @@ msgstr "虚拟应用" msgid "Enable virtual app" msgstr "启用虚拟应用" -#: settings/serializers/msg.py:24 -msgid "SMTP host" +#: settings/serializers/msg.py:25 +#, fuzzy +#| msgid "SMTP host" +msgid "SMTP" msgstr "SMTP 主机" -#: settings/serializers/msg.py:25 -msgid "SMTP port" -msgstr "SMTP 端口" - #: settings/serializers/msg.py:26 -msgid "SMTP account" -msgstr "SMTP 账号" +msgid "EXCHANGE" +msgstr "" -#: settings/serializers/msg.py:28 -msgid "SMTP password" -msgstr "SMTP 密码" - -#: settings/serializers/msg.py:29 +#: settings/serializers/msg.py:36 msgid "Tips: Some provider use token except password" msgstr "提示:一些邮件提供商需要输入的是授权码" -#: settings/serializers/msg.py:32 +#: settings/serializers/msg.py:39 msgid "Send user" msgstr "发件人" -#: settings/serializers/msg.py:33 +#: settings/serializers/msg.py:40 msgid "Tips: Send mail account, default SMTP account as the send account" msgstr "提示:发送邮件账号,默认使用 SMTP 账号作为发送账号" -#: settings/serializers/msg.py:36 +#: settings/serializers/msg.py:43 msgid "Test recipient" msgstr "测试收件人" -#: settings/serializers/msg.py:37 +#: settings/serializers/msg.py:44 msgid "Tips: Used only as a test mail recipient" msgstr "提示:仅用来作为测试邮件收件人" -#: settings/serializers/msg.py:41 +#: settings/serializers/msg.py:48 msgid "If SMTP port is 465, may be select" msgstr "如果SMTP端口是465,通常需要启用 SSL" -#: settings/serializers/msg.py:44 +#: settings/serializers/msg.py:51 msgid "Use TLS" msgstr "使用 TLS" -#: settings/serializers/msg.py:45 +#: settings/serializers/msg.py:52 msgid "If SMTP port is 587, may be select" msgstr "如果SMTP端口是587,通常需要启用 TLS" -#: settings/serializers/msg.py:48 +#: settings/serializers/msg.py:55 msgid "Subject prefix" msgstr "主题前缀" -#: settings/serializers/msg.py:51 +#: settings/serializers/msg.py:58 msgid "Email suffix" msgstr "邮件后缀" -#: settings/serializers/msg.py:52 +#: settings/serializers/msg.py:59 msgid "" "This is used by default if no email is returned during SSO authentication" msgstr "SSO认证时,如果没有返回邮件地址,将使用该后缀" -#: settings/serializers/msg.py:61 +#: settings/serializers/msg.py:68 msgid "Create user email subject" msgstr "邮件主题" -#: settings/serializers/msg.py:62 +#: settings/serializers/msg.py:69 msgid "" "Tips: When creating a user, send the subject of the email (eg:Create account " "successfully)" msgstr "提示: 创建用户时,发送设置密码邮件的主题 (例如: 创建用户成功)" -#: settings/serializers/msg.py:66 +#: settings/serializers/msg.py:73 msgid "Create user honorific" msgstr "邮件问候语" -#: settings/serializers/msg.py:67 +#: settings/serializers/msg.py:74 msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)" msgstr "提示: 创建用户时,发送设置密码邮件的敬语 (例如: 你好)" -#: settings/serializers/msg.py:71 +#: settings/serializers/msg.py:78 msgid "Create user email content" msgstr "邮件的内容" -#: settings/serializers/msg.py:73 +#: settings/serializers/msg.py:80 #, python-brace-format msgid "" "Tips: When creating a user, send the content of the email, support " @@ -5659,7 +5663,7 @@ msgid "" msgstr "" "提示: 创建用户时,发送设置密码邮件的内容, 支持 {username} {name} {email} 标签" -#: settings/serializers/msg.py:77 +#: settings/serializers/msg.py:84 msgid "Tips: Email signature (eg:jumpserver)" msgstr "邮件署名 (如:jumpserver)" @@ -6001,112 +6005,129 @@ msgstr "启用 Razor 服务" msgid "Enable SSH Client" msgstr "启用 SSH Client" -#: settings/tasks/ldap.py:24 +#: settings/tasks/ldap.py:29 msgid "Periodic import ldap user" msgstr "周期导入 LDAP 用户" -#: settings/tasks/ldap.py:45 +#: settings/tasks/ldap.py:66 msgid "Registration periodic import ldap user task" msgstr "注册周期导入 LDAP 用户 任务" -#: settings/utils/ldap.py:491 +#: settings/templates/ldap/_msg_import_ldap_user.html:2 +msgid "Sync task Finish" +msgstr "同步任务完成" + +#: settings/templates/ldap/_msg_import_ldap_user.html:3 +msgid "Synced Organization" +msgstr "已同步组织" + +#: settings/templates/ldap/_msg_import_ldap_user.html:9 +msgid "Synced User" +msgstr "已同步用户" + +#: settings/templates/ldap/_msg_import_ldap_user.html:26 +#: terminal/models/session/session.py:45 +msgid "Date end" +msgstr "结束日期" + +#: settings/utils/ldap.py:494 msgid "ldap:// or ldaps:// protocol is used." msgstr "使用 ldap:// 或 ldaps:// 协议" -#: settings/utils/ldap.py:502 +#: settings/utils/ldap.py:505 msgid "Host or port is disconnected: {}" msgstr "主机或端口不可连接: {}" -#: settings/utils/ldap.py:504 +#: settings/utils/ldap.py:507 msgid "The port is not the port of the LDAP service: {}" msgstr "端口不是LDAP服务端口: {}" -#: settings/utils/ldap.py:506 +#: settings/utils/ldap.py:509 msgid "Please add certificate: {}" msgstr "请添加证书" -#: settings/utils/ldap.py:510 settings/utils/ldap.py:537 -#: settings/utils/ldap.py:567 settings/utils/ldap.py:595 +#: settings/utils/ldap.py:513 settings/utils/ldap.py:540 +#: settings/utils/ldap.py:570 settings/utils/ldap.py:598 msgid "Unknown error: {}" msgstr "未知错误: {}" -#: settings/utils/ldap.py:524 +#: settings/utils/ldap.py:527 msgid "Bind DN or Password incorrect" msgstr "绑定DN或密码错误" -#: settings/utils/ldap.py:531 +#: settings/utils/ldap.py:534 msgid "Please enter Bind DN: {}" msgstr "请输入绑定DN: {}" -#: settings/utils/ldap.py:533 +#: settings/utils/ldap.py:536 msgid "Please enter Password: {}" msgstr "请输入密码: {}" -#: settings/utils/ldap.py:535 +#: settings/utils/ldap.py:538 msgid "Please enter correct Bind DN and Password: {}" msgstr "请输入正确的绑定DN和密码: {}" -#: settings/utils/ldap.py:553 +#: settings/utils/ldap.py:556 msgid "Invalid User OU or User search filter: {}" msgstr "不合法的用户OU或用户过滤器: {}" -#: settings/utils/ldap.py:584 +#: settings/utils/ldap.py:587 msgid "LDAP User attr map not include: {}" msgstr "LDAP属性映射没有包含: {}" -#: settings/utils/ldap.py:591 +#: settings/utils/ldap.py:594 msgid "LDAP User attr map is not dict" msgstr "LDAP属性映射不合法" -#: settings/utils/ldap.py:610 +#: settings/utils/ldap.py:613 msgid "LDAP authentication is not enabled" msgstr "LDAP认证没有启用" -#: settings/utils/ldap.py:628 +#: settings/utils/ldap.py:631 msgid "Error (Invalid LDAP server): {}" msgstr "错误 (不合法的LDAP服务器地址): {}" -#: settings/utils/ldap.py:630 +#: settings/utils/ldap.py:633 msgid "Error (Invalid Bind DN): {}" msgstr "错误 (不合法的绑定DN): {}" -#: settings/utils/ldap.py:632 +#: settings/utils/ldap.py:635 msgid "Error (Invalid LDAP User attr map): {}" msgstr "错误 (不合法的LDAP属性映射): {}" -#: settings/utils/ldap.py:634 +#: settings/utils/ldap.py:637 msgid "Error (Invalid User OU or User search filter): {}" msgstr "错误 (不合法的用户OU或用户过滤器): {}" -#: settings/utils/ldap.py:636 +#: settings/utils/ldap.py:639 msgid "Error (Not enabled LDAP authentication): {}" msgstr "错误 (没有启用LDAP认证): {}" -#: settings/utils/ldap.py:638 +#: settings/utils/ldap.py:641 msgid "Error (Unknown): {}" msgstr "错误 (未知): {}" -#: settings/utils/ldap.py:641 +#: settings/utils/ldap.py:644 msgid "Succeed: Match {} s user" msgstr "成功匹配 {} 个用户" -#: settings/utils/ldap.py:652 +#: settings/utils/ldap.py:655 msgid "Please test the connection first" msgstr "请先测试连接" -#: settings/utils/ldap.py:674 +#: settings/utils/ldap.py:677 msgid "Authentication failed (configuration incorrect): {}" msgstr "认证失败 (配置错误): {}" -#: settings/utils/ldap.py:678 +#: settings/utils/ldap.py:681 msgid "Authentication failed (username or password incorrect): {}" msgstr "认证失败 (用户名或密码不正确): {}" -#: settings/utils/ldap.py:680 +#: settings/utils/ldap.py:683 msgid "Authentication failed (Unknown): {}" msgstr "认证失败: (未知): {}" -#: settings/utils/ldap.py:683 +#: settings/utils/ldap.py:686 msgid "Authentication success: {}" msgstr "认证成功: {}" @@ -6709,10 +6730,6 @@ msgstr "登录来源" msgid "Replay" msgstr "回放" -#: terminal/models/session/session.py:45 -msgid "Date end" -msgstr "结束日期" - #: terminal/models/session/session.py:47 terminal/serializers/session.py:65 msgid "Command amount" msgstr "命令数量" @@ -8193,7 +8210,7 @@ msgstr "MFA(OTP) 禁用成功,返回登录页面" msgid "Password invalid" msgstr "用户名或密码无效" -#: users/views/profile/reset.py:64 +#: users/views/profile/reset.py:65 msgid "" "Non-local users can log in only from third-party platforms and cannot change " "their passwords: {}" @@ -8368,7 +8385,7 @@ msgstr "与" msgid "Or" msgstr "或" -#: xpack/plugins/cloud/manager.py:56 +#: xpack/plugins/cloud/manager.py:57 msgid "Account unavailable" msgstr "账号无效" @@ -8915,6 +8932,15 @@ msgstr "企业专业版" msgid "Ultimate edition" msgstr "企业旗舰版" +#~ msgid "SMTP port" +#~ msgstr "SMTP 端口" + +#~ msgid "SMTP account" +#~ msgstr "SMTP 账号" + +#~ msgid "SMTP password" +#~ msgstr "SMTP 密码" + #~ msgid "Password can not contains `{{` or `}}`" #~ msgstr "密码不能包含 `{{` 或 `}}` 字符" diff --git a/apps/settings/api/ldap.py b/apps/settings/api/ldap.py index 9c619e24d..f13a2e9af 100644 --- a/apps/settings/api/ldap.py +++ b/apps/settings/api/ldap.py @@ -137,7 +137,7 @@ class LDAPUserImportAPI(APIView): return Response({'msg': _('Get ldap users is None')}, status=400) orgs = self.get_orgs() - errors = LDAPImportUtil().perform_import(users, orgs) + new_users, errors = LDAPImportUtil().perform_import(users, orgs) if errors: return Response({'errors': errors}, status=400) diff --git a/apps/settings/notifications.py b/apps/settings/notifications.py new file mode 100644 index 000000000..b8ddde70d --- /dev/null +++ b/apps/settings/notifications.py @@ -0,0 +1,35 @@ +from django.template.loader import render_to_string +from django.utils.translation import gettext as _ + +from common.utils import get_logger +from common.utils.timezone import local_now_display +from notifications.notifications import UserMessage + +logger = get_logger(__file__) + + +class LDAPImportMessage(UserMessage): + def __init__(self, user, extra_kwargs): + super().__init__(user) + self.orgs = extra_kwargs.pop('orgs', []) + self.end_time = extra_kwargs.pop('end_time', '') + self.start_time = extra_kwargs.pop('start_time', '') + self.time_start_display = extra_kwargs.pop('time_start_display', '') + self.new_users = extra_kwargs.pop('new_users', []) + self.errors = extra_kwargs.pop('errors', []) + + def get_html_msg(self) -> dict: + subject = _('Notification of Synchronized LDAP User Task Results') + context = { + 'orgs': self.orgs, + 'start_time': self.time_start_display, + 'end_time': local_now_display(), + 'cost_time': self.end_time - self.start_time, + 'users': self.new_users, + 'errors': self.errors + } + message = render_to_string('ldap/_msg_import_ldap_user.html', context) + return { + 'subject': subject, + 'message': message + } diff --git a/apps/settings/serializers/auth/ldap.py b/apps/settings/serializers/auth/ldap.py index 054fe6144..a79c0081f 100644 --- a/apps/settings/serializers/auth/ldap.py +++ b/apps/settings/serializers/auth/ldap.py @@ -77,6 +77,9 @@ class LDAPSettingSerializer(serializers.Serializer): required=False, label=_('Connect timeout (s)'), ) AUTH_LDAP_SEARCH_PAGED_SIZE = serializers.IntegerField(required=False, label=_('Search paged size (piece)')) + AUTH_LDAP_SYNC_RECEIVERS = serializers.ListField( + required=False, label=_('Recipient'), max_length=36 + ) AUTH_LDAP = serializers.BooleanField(required=False, label=_('Enable LDAP auth')) diff --git a/apps/settings/tasks/ldap.py b/apps/settings/tasks/ldap.py index 0530680e8..6a52e038d 100644 --- a/apps/settings/tasks/ldap.py +++ b/apps/settings/tasks/ldap.py @@ -1,15 +1,19 @@ # coding: utf-8 # +import time from celery import shared_task from django.conf import settings from django.utils.translation import gettext_lazy as _ from common.utils import get_logger +from common.utils.timezone import local_now_display from ops.celery.decorator import after_app_ready_start from ops.celery.utils import ( create_or_update_celery_periodic_tasks, disable_celery_periodic_task ) from orgs.models import Organization +from settings.notifications import LDAPImportMessage +from users.models import User from ..utils import LDAPSyncUtil, LDAPServerUtil, LDAPImportUtil __all__ = ['sync_ldap_user', 'import_ldap_user_periodic', 'import_ldap_user'] @@ -23,6 +27,8 @@ def sync_ldap_user(): @shared_task(verbose_name=_('Periodic import ldap user')) def import_ldap_user(): + start_time = time.time() + time_start_display = local_now_display() logger.info("Start import ldap user task") util_server = LDAPServerUtil() util_import = LDAPImportUtil() @@ -35,11 +41,25 @@ def import_ldap_user(): org_ids = [Organization.DEFAULT_ID] default_org = Organization.default() orgs = list(set([Organization.get_instance(org_id, default=default_org) for org_id in org_ids])) - errors = util_import.perform_import(users, orgs) + new_users, errors = util_import.perform_import(users, orgs) if errors: logger.error("Imported LDAP users errors: {}".format(errors)) else: logger.info('Imported {} users successfully'.format(len(users))) + if settings.AUTH_LDAP_SYNC_RECEIVERS: + user_ids = settings.AUTH_LDAP_SYNC_RECEIVERS + recipient_list = User.objects.filter(id__in=list(user_ids)) + end_time = time.time() + extra_kwargs = { + 'orgs': orgs, + 'end_time': end_time, + 'start_time': start_time, + 'time_start_display': time_start_display, + 'new_users': new_users, + 'errors': errors, + } + for user in recipient_list: + LDAPImportMessage(user, extra_kwargs).publish() @shared_task(verbose_name=_('Registration periodic import ldap user task')) diff --git a/apps/settings/templates/ldap/_msg_import_ldap_user.html b/apps/settings/templates/ldap/_msg_import_ldap_user.html new file mode 100644 index 000000000..f801dde36 --- /dev/null +++ b/apps/settings/templates/ldap/_msg_import_ldap_user.html @@ -0,0 +1,30 @@ +{% load i18n %} +

{% trans "Sync task Finish" %}

+{% trans 'Time' %}: +
    +
  • {% trans 'Date start' %}: {{ start_time }}
  • +
  • {% trans 'Date end' %}: {{ end_time }}
  • +
  • {% trans 'Time cost' %}: {{ cost_time| floatformat:0 }}s
  • +
+{% trans "Synced Organization" %}: +
    + {% for org in orgs %} +
  • {{ org }}
  • + {% endfor %} +
+{% trans "Synced User" %}: +
    + {% for user in users %} +
  • {{ user }}
  • + {% endfor %} +
+{% if errors %} + {% trans 'Error' %}: +
    + {% for error in errors %} +
  • {{ error }}
  • + {% endfor %} +
+{% endif %} + + diff --git a/apps/settings/utils/ldap.py b/apps/settings/utils/ldap.py index b4f21affa..6333f0350 100644 --- a/apps/settings/utils/ldap.py +++ b/apps/settings/utils/ldap.py @@ -400,11 +400,14 @@ class LDAPImportUtil(object): logger.info('Start perform import ldap users, count: {}'.format(len(users))) errors = [] objs = [] + new_users = [] group_users_mapper = defaultdict(set) for user in users: groups = user.pop('groups', []) try: obj, created = self.update_or_create(user) + if created: + new_users.append(obj) objs.append(obj) except Exception as e: errors.append({user['username']: str(e)}) @@ -421,7 +424,7 @@ class LDAPImportUtil(object): for org in orgs: self.bind_org(org, objs, group_users_mapper) logger.info('End perform import ldap users') - return errors + return new_users, errors def exit_user_group(self, user_groups_mapper): # 通过对比查询本次导入用户需要移除的用户组 From 9c8635b23011a6d48b1292c39bc3da00546c4f81 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 12 Jan 2024 16:44:46 +0800 Subject: [PATCH 26/41] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E8=B5=84=E4=BA=A7=20api=EF=BC=8C=E5=BE=88=E5=A4=9A?= =?UTF-8?q?=E8=B5=84=E4=BA=A7=E4=B9=9F=E4=B8=8D=E6=80=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/pagination.py | 3 ++- apps/perms/api/user_permission/assets.py | 3 +-- apps/perms/utils/user_perm.py | 19 +++++++++++-------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/apps/assets/pagination.py b/apps/assets/pagination.py index 8ae42ef16..316029301 100644 --- a/apps/assets/pagination.py +++ b/apps/assets/pagination.py @@ -1,8 +1,8 @@ from rest_framework.pagination import LimitOffsetPagination from rest_framework.request import Request -from common.utils import get_logger from assets.models import Node +from common.utils import get_logger logger = get_logger(__name__) @@ -28,6 +28,7 @@ class AssetPaginationBase(LimitOffsetPagination): 'key', 'all', 'show_current_asset', 'cache_policy', 'display', 'draw', 'order', 'node', 'node_id', 'fields_size', + 'asset' } for k, v in self._request.query_params.items(): if k not in exclude_query_params and v is not None: diff --git a/apps/perms/api/user_permission/assets.py b/apps/perms/api/user_permission/assets.py index bc51dfe77..6db934c3b 100644 --- a/apps/perms/api/user_permission/assets.py +++ b/apps/perms/api/user_permission/assets.py @@ -7,8 +7,7 @@ from assets.models import Asset, Node from common.utils import get_logger, lazyproperty, is_uuid from orgs.utils import tmp_to_root_org from perms import serializers -from perms.pagination import AllPermedAssetPagination -from perms.pagination import NodePermedAssetPagination +from perms.pagination import NodePermedAssetPagination, AllPermedAssetPagination from perms.utils import UserPermAssetUtil, PermAssetDetailUtil from .mixin import ( SelfOrPKUserMixin diff --git a/apps/perms/utils/user_perm.py b/apps/perms/utils/user_perm.py index 0ad02fb25..d06f18a83 100644 --- a/apps/perms/utils/user_perm.py +++ b/apps/perms/utils/user_perm.py @@ -24,7 +24,6 @@ class AssetPermissionPermAssetUtil: self.perm_ids = perm_ids def get_all_assets(self): - """ 获取所有授权的资产 """ node_assets = self.get_perm_nodes_assets() direct_assets = self.get_direct_assets() # 比原来的查到所有 asset id 再搜索块很多,因为当资产量大的时候,搜索会很慢 @@ -34,10 +33,11 @@ class AssetPermissionPermAssetUtil: def get_perm_nodes_assets(self, flat=False): """ 获取所有授权节点下的资产 """ from assets.models import Node - nodes = Node.objects \ - .prefetch_related('granted_by_permissions') \ - .filter(granted_by_permissions__in=self.perm_ids) \ - .only('id', 'key') + from ..models import AssetPermission + nodes_ids = AssetPermission.objects \ + .filter(id__in=self.perm_ids) \ + .values_list('nodes', flat=True) + nodes = Node.objects.filter(id__in=nodes_ids).only('id', 'key') assets = PermNode.get_nodes_all_assets(*nodes) if flat: return set(assets.values_list('id', flat=True)) @@ -46,9 +46,11 @@ class AssetPermissionPermAssetUtil: @timeit def get_direct_assets(self, flat=False): """ 获取直接授权的资产 """ - assets = Asset.objects.order_by() \ - .filter(granted_by_permissions__id__in=self.perm_ids) \ - .distinct() + from ..models import AssetPermission + asset_ids = AssetPermission.objects \ + .filter(id__in=self.perm_ids) \ + .values_list('assets', flat=True) + assets = Asset.objects.filter(id__in=asset_ids).distinct() if flat: return set(assets.values_list('id', flat=True)) return assets @@ -152,6 +154,7 @@ class UserPermAssetUtil(AssetPermissionPermAssetUtil): assets = assets.filter(nodes__id=node.id).order_by().distinct() return assets + @timeit def _get_indirect_perm_node_all_assets(self, node): """ 获取间接授权节点下的所有资产 此算法依据 `UserAssetGrantedTreeNodeRelation` 的数据查询 From 000a3038e1b7a27f3f08faa669ece81f7d518891 Mon Sep 17 00:00:00 2001 From: wangruidong <940853815@qq.com> Date: Fri, 12 Jan 2024 15:49:13 +0800 Subject: [PATCH 27/41] =?UTF-8?q?fix:=20=E7=BB=88=E7=AB=AF=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E9=94=99=E8=AF=AF=E7=9A=84MFA=E6=97=A0=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/mfa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentication/api/mfa.py b/apps/authentication/api/mfa.py index 049cd177a..2d3a9b072 100644 --- a/apps/authentication/api/mfa.py +++ b/apps/authentication/api/mfa.py @@ -90,6 +90,6 @@ class MFAChallengeVerifyApi(AuthMixin, CreateAPIView): return Response({'msg': 'ok'}) except errors.AuthFailedError as e: data = {"error": e.error, "msg": e.msg} - raise ValidationError(data) + return Response(data, status=401) except errors.NeedMoreInfoError as e: return Response(e.as_data(), status=200) From 644eada8a1faad46f1e9409e2f829de138d78d22 Mon Sep 17 00:00:00 2001 From: halo Date: Sat, 13 Jan 2024 19:40:46 +0800 Subject: [PATCH 28/41] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3openssh=E4=BD=8E?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=97=B6=E6=B5=8B=E8=AF=95=E5=8F=AF=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/ansible/modules_utils/custom_common.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/ops/ansible/modules_utils/custom_common.py b/apps/ops/ansible/modules_utils/custom_common.py index 0cf1420d2..7015ff2f9 100644 --- a/apps/ops/ansible/modules_utils/custom_common.py +++ b/apps/ops/ansible/modules_utils/custom_common.py @@ -4,6 +4,21 @@ import time import paramiko from sshtunnel import SSHTunnelForwarder +from packaging import version + +if version.parse(paramiko.__version__) > version.parse("2.8.1"): + _preferred_pubkeys = ( + "ssh-ed25519", + "ecdsa-sha2-nistp256", + "ecdsa-sha2-nistp384", + "ecdsa-sha2-nistp521", + "ssh-rsa", + "rsa-sha2-256", + "rsa-sha2-512", + "ssh-dss", + ) + paramiko.transport.Transport._preferred_pubkeys = _preferred_pubkeys + def common_argument_spec(): options = dict( From 2994ea6f6802c36f1581690994042cbd9c8190bc Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 15 Jan 2024 17:53:56 +0800 Subject: [PATCH 29/41] perf: revert asset labels api --- apps/assets/urls/api_urls.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py index 408550ece..b56458758 100644 --- a/apps/assets/urls/api_urls.py +++ b/apps/assets/urls/api_urls.py @@ -2,6 +2,7 @@ from django.urls import path from rest_framework_bulk.routes import BulkRouter +from labels.api import LabelViewSet from .. import api app_name = 'assets' @@ -22,6 +23,7 @@ router.register(r'domains', api.DomainViewSet, 'domain') router.register(r'gateways', api.GatewayViewSet, 'gateway') router.register(r'favorite-assets', api.FavoriteAssetViewSet, 'favorite-asset') router.register(r'protocol-settings', api.PlatformProtocolViewSet, 'protocol-setting') +router.register(r'labels', LabelViewSet, 'label') urlpatterns = [ # path('assets//gateways/', api.AssetGatewayListApi.as_view(), name='asset-gateway-list'), From fabee37e9e72b8f78e901608fc1dd2220be70386 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 15 Jan 2024 18:00:57 +0800 Subject: [PATCH 30/41] fix: user permed type tree recurse root node --- apps/perms/api/user_permission/tree/node_with_asset.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/perms/api/user_permission/tree/node_with_asset.py b/apps/perms/api/user_permission/tree/node_with_asset.py index 17cdd7573..c7bb0b8bb 100644 --- a/apps/perms/api/user_permission/tree/node_with_asset.py +++ b/apps/perms/api/user_permission/tree/node_with_asset.py @@ -181,6 +181,8 @@ class UserPermedNodeChildrenWithAssetsAsCategoryTreeApi(BaseUserNodeWithAssetAsT return self.query_asset_util.get_all_assets() def _get_tree_nodes_async(self): + if self.request.query_params.get('lv') == '0': + return [], [] if not self.tp or not all(self.tp): nodes = UserPermAssetUtil.get_type_nodes_tree_or_cached(self.user) return nodes, [] From e29e51121dcc071207f7c895ddf6cda24d988849 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 16 Jan 2024 11:33:21 +0800 Subject: [PATCH 31/41] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E7=89=88=E6=9C=AC=E8=AE=A1=E7=AE=97=E7=AD=96=E7=95=A5?= =?UTF-8?q?=20(#12547)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/signal_handlers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/accounts/signal_handlers.py b/apps/accounts/signal_handlers.py index d086a049c..4c87df5cf 100644 --- a/apps/accounts/signal_handlers.py +++ b/apps/accounts/signal_handlers.py @@ -21,7 +21,8 @@ def on_account_pre_save(sender, instance, **kwargs): if instance.version == 0: instance.version = 1 else: - instance.version = instance.history.count() + history_account = instance.history.first() + instance.version = history_account.version + 1 if history_account else 0 @merge_delay_run(ttl=5) From 3c3c1499b70a1c4a4987fc9a1bbab047b9478ff0 Mon Sep 17 00:00:00 2001 From: Bai Date: Tue, 16 Jan 2024 11:29:33 +0800 Subject: [PATCH 32/41] perf: Add requirement for exchangelib==5.1.0 --- poetry.lock | 177 ++++++++++++++++++++++++++++++++++++++----------- pyproject.toml | 1 + 2 files changed, 138 insertions(+), 40 deletions(-) diff --git a/poetry.lock b/poetry.lock index d11c14093..3271ee6c7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.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 = "adal" @@ -1062,6 +1062,22 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "cached-property" +version = "1.5.2" +description = "A decorator for caching properties in classes." +optional = false +python-versions = "*" +files = [ + {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, + {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "cachetools" version = "5.3.2" @@ -1811,6 +1827,22 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "distro" version = "1.9.0" @@ -2424,17 +2456,6 @@ files = [ {file = "ephem-4.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8f9b27117e7a82f7f70db9cb23b5cc36d37b166a2f73c55e14d7225d0ab95afa"}, {file = "ephem-4.1.4-cp311-cp311-win32.whl", hash = "sha256:9bb21c0b117c9122c0141b0a71ee6fbbb087ed2aab4a7ab60f009e95e9f4a521"}, {file = "ephem-4.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:55d7fb5c34b2e453e01fa4ca7ee375b19b438c9401ae8c4099ae4a3a37656972"}, - {file = "ephem-4.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f9e24aeea560dfcece3c2e313eb94e6be3e84888091455e541fa88f3a44da584"}, - {file = "ephem-4.1.4-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:653d99386932e5f78bb9cfc4495030ad9f3345eb4c2b32dca55547da8f1f0332"}, - {file = "ephem-4.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53786461a6d5799d5fffe76622ad51444b264d1c7263b92a6dfcac640c3da93a"}, - {file = "ephem-4.1.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:268f57f8768ccb0abbdf4cefb4781c7db812950019868f687b407b428513ee53"}, - {file = "ephem-4.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d630aa287255ea9fba6962f351e4e0729bb620570684d52fbfcc31b11527f09e"}, - {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5f229bbf62ecb4cd6bb3374b15d0f8ff7b3d970c2936fccd89bdf9d693907a2"}, - {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d60d56f182de54bd84fadd6ea2dd8e8ef6fdef6a698c7cafd404ecb6eeefa598"}, - {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:404500c8d0030d75ec15bb6b98eee78ad163fd5252102c962ae6fb39c9488198"}, - {file = "ephem-4.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fb020d6cc5ab1ad1cd9d3da4a6e2506beebb41d1b337d79cc20cc0a17f550f1"}, - {file = "ephem-4.1.4-cp312-cp312-win32.whl", hash = "sha256:29e71636ee4719419d03184abc85085f76989c79a61844f5e60acbf2513d2b42"}, - {file = "ephem-4.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:549654f63d88e0ab6248ae25ac2939131474ab9f3a91bee6b68ca6f214747c2a"}, {file = "ephem-4.1.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:40067fc050c946c8d4c2d779805b61f063471a091e6124cbabcf61ac538011b2"}, {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e2abe97aa2b091090012768b4d94793213cc01f0bf040dcc311a380ab08df69"}, {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2677d3a5b42aedc578de10b0eecdba6a50731f159cb28f7ad38c5f62143494"}, @@ -2539,6 +2560,41 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "exchangelib" +version = "5.1.0" +description = "Client for Microsoft Exchange Web Services (EWS)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "exchangelib-5.1.0-py2.py3-none-any.whl", hash = "sha256:28f492df84c3d74b1183d535d34daa8c7d7a80fe69cf6b35041770824781f4b0"}, + {file = "exchangelib-5.1.0.tar.gz", hash = "sha256:f835c14d380839dc74f53664f091cafc978a158855877a510c0c5554b85cdbac"}, +] + +[package.dependencies] +cached-property = "*" +defusedxml = ">=0.6.0" +dnspython = ">=2.2.0" +isodate = "*" +lxml = ">3.0" +oauthlib = "*" +pygments = "*" +requests = ">=2.7" +requests-ntlm = ">=0.2.0" +requests-oauthlib = "*" +tzdata = "*" +tzlocal = "*" + +[package.extras] +complete = ["requests-gssapi", "requests-negotiate-sspi"] +kerberos = ["requests-gssapi"] +sspi = ["requests-negotiate-sspi"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "executing" version = "2.0.1" @@ -2777,8 +2833,14 @@ files = [ [package.dependencies] google-auth = ">=2.14.1,<3.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0" -grpcio = {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} -grpcio-status = {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""} +grpcio = [ + {version = ">=1.33.2,<2.0dev", optional = true, markers = "extra == \"grpc\""}, + {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, +] +grpcio-status = [ + {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "extra == \"grpc\""}, + {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, +] protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" requests = ">=2.18.0,<3.0.0.dev0" @@ -3781,7 +3843,41 @@ files = [ {file = "lxml-5.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7188495c1bf71bfda87d78ed50601e72d252119ce11710d6e71ff36e35fea5a0"}, {file = "lxml-5.0.0-cp37-cp37m-win32.whl", hash = "sha256:6a2de85deabf939b0af89e2e1ea46bfb1239545e2da6f8ac96522755a388025f"}, {file = "lxml-5.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ea56825c1e23c9c8ea385a191dac75f9160477057285b88c88736d9305e6118f"}, - {file = "lxml-5.0.0.tar.gz", hash = "sha256:9165c82bcccf0249feff82cd1fba202e4ce26c25dc69040a0d2c2d0e49cbeba3"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:3f908afd0477cace17f941d1b9cfa10b769fe1464770abe4cfb3d9f35378d0f8"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52a9ab31853d3808e7cf0183b3a5f7e8ffd622ea4aee1deb5252dbeaefd5b40d"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c7fe19abb3d3c55a9e65d289b12ad73b3a31a3f0bda3c539a890329ae9973bd6"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:1ef0793e1e2dd221fce7c142177008725680f7b9e4a184ab108d90d5d3ab69b7"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:581a78f299a9f5448b2c3aea904bfcd17c59bf83016d221d7f93f83633bb2ab2"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:affdd833f82334fdb10fc9a1c7b35cdb5a86d0b672b4e14dd542e1fe7bcea894"}, + {file = "lxml-5.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6bba06d8982be0f0f6432d289a8d104417a0ab9ed04114446c4ceb6d4a40c65d"}, + {file = "lxml-5.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:80209b31dd3908bc5b014f540fd192c97ea52ab179713a730456c5baf7ce80c1"}, + {file = "lxml-5.0.0-cp38-cp38-win32.whl", hash = "sha256:dac2733fe4e159b0aae0439db6813b7b1d23ff96d0b34c0107b87faf79208c4e"}, + {file = "lxml-5.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:ee60f33456ff34b2dd1d048a740a2572798356208e4c494301c931de3a0ab3a2"}, + {file = "lxml-5.0.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:5eff173f0ff408bfa578cbdafd35a7e0ca94d1a9ffe09a8a48e0572d0904d486"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:78d6d8e5b54ed89dc0f0901eaaa579c384ad8d59fa43cc7fb06e9bb89115f8f4"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:71a7cee869578bc17b18050532bb2f0bc682a7b97dda77041741a1bd2febe6c7"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:7df433d08d4587dc3932f7fcfc3194519a6824824104854e76441fd3bc000d29"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:793be9b4945c2dfd69828fb5948d7d9569b78e0599e4a2e88d92affeb0ff3aa3"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7cfb6af73602c8d288581df8a225989d7e9d5aab0a174be0e19fcfa800b6797"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bfdc4668ac56687a89ca3eca44231144a2e9d02ba3b877558db74ba20e2bd9fa"}, + {file = "lxml-5.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2992591e2294bb07faf7f5f6d5cb60710c046404f4bfce09fb488b85d2a8f58f"}, + {file = "lxml-5.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4786b0af7511ea614fd86407a52a7bc161aa5772d311d97df2591ed2351de768"}, + {file = "lxml-5.0.0-cp39-cp39-win32.whl", hash = "sha256:016de3b29a262655fc3d2075dc1b2611f84f4c3d97a71d579c883d45e201eee4"}, + {file = "lxml-5.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:52c0acc2f29b0a204efc11a5ed911a74f50a25eb7d7d5069c2b1fd3b3346ce11"}, + {file = "lxml-5.0.0-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:96095bfc0c02072fc89afa67626013a253596ea5118b8a7f4daaae049dafa096"}, + {file = "lxml-5.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:992029258ed719f130d5a9c443d142c32843046f1263f2c492862b2a853be570"}, + {file = "lxml-5.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:db40e85cffd22f7d65dcce30e85af565a66401a6ed22fc0c56ed342cfa4ffc43"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:cfa8a4cdc3765574b7fd0c7cfa5fbd1e2108014c9dfd299c679e5152bea9a55e"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:049fef98d02513c34f5babd07569fc1cf1ed14c0f2fbff18fe72597f977ef3c2"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a85136d0ee18a41c91cc3e2844c683be0e72e6dda4cb58da9e15fcaef3726af7"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:766868f729f3ab84125350f1a0ea2594d8b1628a608a574542a5aff7355b9941"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:99cad5c912f359e59e921689c04e54662cdd80835d80eeaa931e22612f515df7"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:c90c593aa8dd57d5dab0ef6d7d64af894008971d98e6a41b320fdd75258fbc6e"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8134d5441d1ed6a682e3de3d7a98717a328dce619ee9c4c8b3b91f0cb0eb3e28"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f298ac9149037d6a3d5c74991bded39ac46292520b9c7c182cb102486cc87677"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:894c5f71186b410679aaab5774543fcb9cbabe8893f0b31d11cf28a0740e80be"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9cd3d6c2c67d4fdcd795e4945e2ba5434909c96640b4cc09453bd0dc7e8e1bac"}, + {file = "lxml-5.0.0.zip", hash = "sha256:2219cbf790e701acf9a21a31ead75f983e73daf0eceb9da6990212e4d20ebefe"}, ] [package.extras] @@ -3822,16 +3918,6 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -5490,6 +5576,8 @@ files = [ {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:881003ce2853d9a290c47a04c165941a5a0addd7ad360d033f275dec3eead192"}, {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:a54ae7c62b3c92e4dba082e328e0bb190f83f45eb84cf59eabb894dfe24a07f7"}, {file = "pyfreerdp-0.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33c3e14664e306c31c2a792cb8dfdd6a381e35f79583a271dd20be25b14ad73d"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c7df63da48b67a31d76b62ee70f5f0ffc964b79b34c4e6c610f67a24fba2aee1"}, + {file = "pyfreerdp-0.0.2-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:df62184ef7fd8bc76f9efd172387e6e7cef9f3777a57bb14f3551b2972f55ef3"}, {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cfd97b8da87b1439407b40e7eda998f0df44332211353b0f4217e91d233bc53"}, {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9ce1a906e861335864bb8c976612a5b1d0595955b0cde35e3697eed7812c8b6"}, {file = "pyfreerdp-0.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b630f604300323b3e1fe6b27d442636f9b0d247eba3cc4340a39721c6d85273"}, @@ -5513,6 +5601,7 @@ files = [ {file = "pyfreerdp-0.0.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb31b620013859a7142a391d9ce57c195f26c3c9991883f87bc5ef1703cf806f"}, {file = "pyfreerdp-0.0.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c839d3ed9c0cc4021129e26c06d3bc45982bdaba8a2a115051ad43c5f6108d11"}, {file = "pyfreerdp-0.0.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c2a23db4a56903dfff9ac5e8b2b7aa713af694dce5a4f3905ef7703b4f9dcd"}, + {file = "pyfreerdp-0.0.2.tar.gz", hash = "sha256:caf4b422eb32a327095b548bb1a22a22b926b6e15819c9a83b6461050b11870d"}, ] [package.source] @@ -5727,11 +5816,9 @@ files = [ {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:049f2e3de919e8e02504780a21ebbf235e21ca8ed5c7538c5b6e705aa6c43d8c"}, {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd86d8e3e346e34f3f03d12e333747b53a1daa74374a727f4714d5b82ee0dd5"}, {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:508226a0df7cb6faeda9f8e84e85743690ca427d7b27af9a73d75fcf0c1eef6e"}, - {file = "pymssql-2.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:47859887adeaf184766b5e0bc845dd23611f3808f9521552063bb36eabc10092"}, {file = "pymssql-2.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d873e553374d5b1c57fe1c43bb75e3bcc2920678db1ef26f6bfed396c7d21b30"}, {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf31b8b76634c826a91f9999e15b7bfb0c051a0f53b319fd56481a67e5b903bb"}, {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:821945c2214fe666fd456c61e09a29a00e7719c9e136c801bffb3a254e9c579b"}, - {file = "pymssql-2.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:cc85b609b4e60eac25fa38bbac1ff854fd2c2a276e0ca4a3614c6f97efb644bb"}, {file = "pymssql-2.2.8-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:ebe7f64d5278d807f14bea08951e02512bfbc6219fd4d4f15bb45ded885cf3d4"}, {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:253af3d39fc0235627966817262d5c4c94ad09dcbea59664748063470048c29c"}, {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c9d109df536dc5f7dd851a88d285a4c9cb12a9314b621625f4f5ab1197eb312"}, @@ -5747,13 +5834,11 @@ files = [ {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3906993300650844ec140aa58772c0f5f3e9e9d5709c061334fd1551acdcf066"}, {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7309c7352e4a87c9995c3183ebfe0ff4135e955bb759109637673c61c9f0ca8d"}, {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9b8d603cc1ec7ae585c5a409a1d45e8da067970c79dd550d45c238ae0aa0f79f"}, - {file = "pymssql-2.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:293cb4d0339e221d877d6b19a1905082b658f0100a1e2ccc9dda10de58938901"}, {file = "pymssql-2.2.8-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:895041edd002a2e91d8a4faf0906b6fbfef29d9164bc6beb398421f5927fa40e"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b2d9c6d38a416c6f2db36ff1cd8e69f9a5387a46f9f4f612623192e0c9404b1"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63d6f25cf40fe6a03c49be2d4d337858362b8ab944d6684c268e4990807cf0c"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c83ad3ad20951f3a94894b354fa5fa9666dcd5ebb4a635dad507c7d1dd545833"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3933f7f082be74698eea835df51798dab9bc727d94d3d280bffc75ab9265f890"}, - {file = "pymssql-2.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:de313375b90b0f554058992f35c4a4beb3f6ec2f5912d8cd6afb649f95b03a9f"}, {file = "pymssql-2.2.8.tar.gz", hash = "sha256:9baefbfbd07d0142756e2dfcaa804154361ac5806ab9381350aad4e780c3033e"}, ] @@ -6242,7 +6327,6 @@ 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"}, @@ -6250,15 +6334,8 @@ 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"}, @@ -6275,7 +6352,6 @@ 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"}, @@ -6283,7 +6359,6 @@ 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"}, @@ -7170,6 +7245,28 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "tzlocal" +version = "5.2" +description = "tzinfo object for the local timezone" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, + {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, +] + +[package.dependencies] +tzdata = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ua-parser" version = "0.18.0" @@ -7779,4 +7876,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "f3a3ef297a045ff896b54897f8ac3593e0f0894637339c7de139453991278139" +content-hash = "3d6e2ccd4d1c1943d9bda901601872db7eb0564858a258372ad7ccf02c978378" diff --git a/pyproject.toml b/pyproject.toml index e46f10eb5..c25951966 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -146,6 +146,7 @@ django-cors-headers = "^4.3.0" mistune = "2.0.3" openai = "^1.3.7" xlsxwriter = "^3.1.9" +exchangelib = "^5.1.0" [tool.poetry.group.xpack.dependencies] From 6cd36726040158258d0ff0b2805a21577de3b037 Mon Sep 17 00:00:00 2001 From: wangruidong <940853815@qq.com> Date: Tue, 16 Jan 2024 13:59:48 +0800 Subject: [PATCH 33/41] fix: sync LDAP notification error --- apps/settings/notifications.py | 3 ++- apps/settings/tasks/ldap.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/settings/notifications.py b/apps/settings/notifications.py index b8ddde70d..5a80c966e 100644 --- a/apps/settings/notifications.py +++ b/apps/settings/notifications.py @@ -17,6 +17,7 @@ class LDAPImportMessage(UserMessage): self.time_start_display = extra_kwargs.pop('time_start_display', '') self.new_users = extra_kwargs.pop('new_users', []) self.errors = extra_kwargs.pop('errors', []) + self.cost_time = extra_kwargs.pop('cost_time', '') def get_html_msg(self) -> dict: subject = _('Notification of Synchronized LDAP User Task Results') @@ -24,7 +25,7 @@ class LDAPImportMessage(UserMessage): 'orgs': self.orgs, 'start_time': self.time_start_display, 'end_time': local_now_display(), - 'cost_time': self.end_time - self.start_time, + 'cost_time': self.cost_time, 'users': self.new_users, 'errors': self.errors } diff --git a/apps/settings/tasks/ldap.py b/apps/settings/tasks/ldap.py index 6a52e038d..e662eeaeb 100644 --- a/apps/settings/tasks/ldap.py +++ b/apps/settings/tasks/ldap.py @@ -57,6 +57,7 @@ def import_ldap_user(): 'time_start_display': time_start_display, 'new_users': new_users, 'errors': errors, + 'cost_time': end_time - start_time, } for user in recipient_list: LDAPImportMessage(user, extra_kwargs).publish() From a2d6e418166bf91a6e304430b154de3abe40f8c6 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 16 Jan 2024 14:55:43 +0800 Subject: [PATCH 34/41] perf: labels getter and setter for inherite model --- apps/assets/serializers/asset/common.py | 5 ++++- apps/common/drf/filters.py | 2 +- apps/common/serializers/mixin.py | 2 +- apps/labels/mixins.py | 15 ++++++++------- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 501d06780..96371bcd2 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -206,9 +206,12 @@ class AssetSerializer(BulkOrgResourceModelSerializer, ResourceLabelsMixin, Writa """ Perform necessary eager loading of data. """ queryset = queryset.prefetch_related('domain', 'nodes', 'protocols', ) \ .prefetch_related('platform', 'platform__automation') \ - .prefetch_related('labels', 'labels__label') \ .annotate(category=F("platform__category")) \ .annotate(type=F("platform__type")) + if queryset.model is Asset: + queryset = queryset.prefetch_related('labels__label', 'labels') + else: + queryset = queryset.prefetch_related('asset_ptr__labels__label', 'asset_ptr__labels') return queryset @staticmethod diff --git a/apps/common/drf/filters.py b/apps/common/drf/filters.py index d187cd414..d84692dfe 100644 --- a/apps/common/drf/filters.py +++ b/apps/common/drf/filters.py @@ -223,7 +223,7 @@ class LabelFilterBackend(filters.BaseFilterBackend): return queryset model = queryset.model.label_model() - labeled_resource_cls = model._labels.field.related_model + labeled_resource_cls = model.labels.field.related_model app_label = model._meta.app_label model_name = model._meta.model_name diff --git a/apps/common/serializers/mixin.py b/apps/common/serializers/mixin.py index d51849f07..16555a6ce 100644 --- a/apps/common/serializers/mixin.py +++ b/apps/common/serializers/mixin.py @@ -394,7 +394,7 @@ class CommonBulkModelSerializer(CommonBulkSerializerMixin, serializers.ModelSeri class ResourceLabelsMixin(serializers.Serializer): - labels = LabelRelatedField(many=True, label=_('Labels'), required=False, allow_null=True) + labels = LabelRelatedField(many=True, label=_('Labels'), required=False, allow_null=True, source='res_labels') def update(self, instance, validated_data): labels = validated_data.pop('labels', None) diff --git a/apps/labels/mixins.py b/apps/labels/mixins.py index 9feb6f0f0..4b775cde5 100644 --- a/apps/labels/mixins.py +++ b/apps/labels/mixins.py @@ -2,13 +2,14 @@ from django.contrib.contenttypes.fields import GenericRelation from django.db import models from django.db.models import OneToOneField +from common.utils import lazyproperty from .models import LabeledResource __all__ = ['LabeledMixin'] class LabeledMixin(models.Model): - _labels = GenericRelation(LabeledResource, object_id_field='res_id', content_type_field='res_type') + labels = GenericRelation(LabeledResource, object_id_field='res_id', content_type_field='res_type') class Meta: abstract = True @@ -21,7 +22,7 @@ class LabeledMixin(models.Model): model = pk_field.related_model return model - @property + @lazyproperty def real(self): pk_field = self._meta.pk if isinstance(pk_field, OneToOneField): @@ -29,9 +30,9 @@ class LabeledMixin(models.Model): return self @property - def labels(self): - return self.real._labels + def res_labels(self): + return self.real.labels - @labels.setter - def labels(self, value): - self.real._labels.set(value, bulk=False) + @res_labels.setter + def res_labels(self, value): + self.real.labels.set(value, bulk=False) From 641e75a90518ff7fdc71662601bac67540baa56a Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Tue, 16 Jan 2024 16:43:22 +0800 Subject: [PATCH 35/41] =?UTF-8?q?fix:=20=E7=94=A8=E6=88=B7=E7=BB=84?= =?UTF-8?q?=E5=88=97=E8=A1=A8=20=E7=94=A8=E6=88=B7=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E4=B8=8D=E5=87=86=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/serializers/group.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/users/serializers/group.py b/apps/users/serializers/group.py index b87ba4a0e..4c0de20f6 100644 --- a/apps/users/serializers/group.py +++ b/apps/users/serializers/group.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.db.models import Count +from django.db.models import Count, Q from django.utils.translation import gettext_lazy as _ from rest_framework import serializers @@ -46,7 +46,7 @@ class UserGroupSerializer(ResourceLabelsMixin, BulkOrgResourceModelSerializer): def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ queryset = queryset.prefetch_related('labels', 'labels__label') \ - .annotate(users_amount=Count('users')) + .annotate(users_amount=Count('users', filter=Q(users__is_service_account=False))) return queryset From 13d41775312058b7c4a6157fe995672db313526d Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Wed, 17 Jan 2024 10:53:19 +0800 Subject: [PATCH 36/41] =?UTF-8?q?fix:=20=E5=B7=A5=E5=8D=95=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=9B=B4=E6=96=B0=E6=B2=A1=E6=9C=89=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/tickets/api/ticket.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/tickets/api/ticket.py b/apps/tickets/api/ticket.py index da60aefe8..ebac1c65a 100644 --- a/apps/tickets/api/ticket.py +++ b/apps/tickets/api/ticket.py @@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.exceptions import MethodNotAllowed +from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from audits.handler import create_or_update_operate_log @@ -41,7 +42,6 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): ordering = ('-date_created',) rbac_perms = { 'open': 'tickets.view_ticket', - 'bulk': 'tickets.change_ticket', } def retrieve(self, request, *args, **kwargs): @@ -122,7 +122,7 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): self._record_operate_log(instance, TicketAction.close) return Response('ok') - @action(detail=False, methods=[PUT], permission_classes=[RBACPermission, ]) + @action(detail=False, methods=[PUT], permission_classes=[IsAuthenticated, ]) def bulk(self, request, *args, **kwargs): self.ticket_not_allowed() From ae68241812907fdf8a9036bd04bb7943e2e4b2b2 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 17 Jan 2024 14:57:12 +0800 Subject: [PATCH 37/41] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E5=BD=95?= =?UTF-8?q?=E5=83=8F=E5=9C=A8=E7=BA=BF=E6=92=AD=E6=94=BE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/rewriting/storage/servers.py | 14 ++++++++++++++ apps/jumpserver/settings/base.py | 4 +--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 apps/jumpserver/rewriting/storage/servers.py diff --git a/apps/jumpserver/rewriting/storage/servers.py b/apps/jumpserver/rewriting/storage/servers.py new file mode 100644 index 000000000..5fc4b0514 --- /dev/null +++ b/apps/jumpserver/rewriting/storage/servers.py @@ -0,0 +1,14 @@ +from private_storage.servers import NginxXAccelRedirectServer, DjangoServer + + +class StaticFileServer(object): + + @staticmethod + def serve(private_file): + full_path = private_file.full_path + # todo: gzip 文件录像 nginx 处理后,浏览器无法正常解析内容 + # 造成在线播放失败,暂时仅使用 nginx 处理 mp4 录像文件 + if full_path.endswith('.mp4'): + return NginxXAccelRedirectServer.serve(private_file) + else: + return DjangoServer.serve(private_file) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 4fdba8b97..10188a1a7 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -319,9 +319,7 @@ MEDIA_ROOT = os.path.join(PROJECT_DIR, 'data', 'media').replace('\\', '/') + '/' PRIVATE_STORAGE_ROOT = MEDIA_ROOT PRIVATE_STORAGE_AUTH_FUNCTION = 'jumpserver.rewriting.storage.permissions.allow_access' PRIVATE_STORAGE_INTERNAL_URL = '/private-media/' -PRIVATE_STORAGE_SERVER = 'nginx' -if DEBUG_DEV: - PRIVATE_STORAGE_SERVER = 'django' +PRIVATE_STORAGE_SERVER = 'jumpserver.rewriting.storage.servers.StaticFileServer' # Use django-bootstrap-form to format template, input max width arg From e4d8ce097a2ed6c3622f8f6a8c7190c524c6e366 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Wed, 17 Jan 2024 17:44:11 +0800 Subject: [PATCH 38/41] =?UTF-8?q?fix:=20=E5=88=9B=E5=BB=BA=E8=B5=84?= =?UTF-8?q?=E4=BA=A7=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/serializers/mixin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/common/serializers/mixin.py b/apps/common/serializers/mixin.py index 16555a6ce..81fac91d9 100644 --- a/apps/common/serializers/mixin.py +++ b/apps/common/serializers/mixin.py @@ -397,17 +397,17 @@ class ResourceLabelsMixin(serializers.Serializer): labels = LabelRelatedField(many=True, label=_('Labels'), required=False, allow_null=True, source='res_labels') def update(self, instance, validated_data): - labels = validated_data.pop('labels', None) + labels = validated_data.pop('res_labels', None) res = super().update(instance, validated_data) if labels is not None: - instance.labels.set(labels, bulk=False) + instance.res_labels.set(labels, bulk=False) return res def create(self, validated_data): - labels = validated_data.pop('labels', None) + labels = validated_data.pop('res_labels', None) instance = super().create(validated_data) if labels is not None: - instance.labels.set(labels, bulk=False) + instance.res_labels.set(labels, bulk=False) return instance @classmethod From 86ef984c023cba115210b35a3980d588e0a3f80c Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Wed, 17 Jan 2024 18:11:05 +0800 Subject: [PATCH 39/41] =?UTF-8?q?perf:=20=E6=9F=A5=E7=9C=8B=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E7=94=A8=E6=88=B7=20=E4=B8=8D=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/perms/models/asset_permission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/perms/models/asset_permission.py b/apps/perms/models/asset_permission.py index 519b0adb8..d8c7026e5 100644 --- a/apps/perms/models/asset_permission.py +++ b/apps/perms/models/asset_permission.py @@ -130,7 +130,7 @@ class AssetPermission(LabeledMixin, JMSOrgBaseModel): qs1_ids = User.objects.filter(id__in=user_ids).distinct().values_list('id', flat=True) qs2_ids = User.objects.filter(groups__id__in=group_ids).distinct().values_list('id', flat=True) qs_ids = list(qs1_ids) + list(qs2_ids) - qs = User.objects.filter(id__in=qs_ids) + qs = User.objects.filter(id__in=qs_ids, is_service_account=False) return qs def get_all_assets(self, flat=False): From 18681d1f50cdbfc90cbcbbbed7e6c993038f8b4a Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:41:29 +0800 Subject: [PATCH 40/41] =?UTF-8?q?perf:=20=E8=BF=9E=E6=8E=A5k8s=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=20(#12563)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/assets/utils/k8s.py | 6 +++--- apps/perms/api/user_permission/tree/node_with_asset.py | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/assets/utils/k8s.py b/apps/assets/utils/k8s.py index 2b33ded89..dc3cd8bc6 100644 --- a/apps/assets/utils/k8s.py +++ b/apps/assets/utils/k8s.py @@ -4,7 +4,6 @@ from urllib.parse import urlencode, urlparse from kubernetes import client from kubernetes.client import api_client from kubernetes.client.api import core_v1_api -from kubernetes.client.exceptions import ApiException from sshtunnel import SSHTunnelForwarder, BaseSSHTunnelForwarderError from common.utils import get_logger @@ -88,8 +87,9 @@ class KubernetesClient: if hasattr(self, func_name): try: data = getattr(self, func_name)(*args) - except ApiException as e: - logger.error(e.reason) + except Exception as e: + logger.error(e) + raise e if self.server: self.server.stop() diff --git a/apps/perms/api/user_permission/tree/node_with_asset.py b/apps/perms/api/user_permission/tree/node_with_asset.py index c7bb0b8bb..114c5475e 100644 --- a/apps/perms/api/user_permission/tree/node_with_asset.py +++ b/apps/perms/api/user_permission/tree/node_with_asset.py @@ -14,6 +14,7 @@ from assets.api import SerializeToTreeNodeMixin from assets.models import Asset from assets.utils import KubernetesTree from authentication.models import ConnectionToken +from common.exceptions import JMSException from common.utils import get_object_or_none, lazyproperty from common.utils.common import timeit from perms.hands import Node @@ -264,5 +265,8 @@ class UserGrantedK8sAsTreeApi(SelfOrPKUserMixin, ListAPIView): if not any([namespace, pod]) and not key: asset_node = k8s_tree_instance.as_asset_tree_node() tree.append(asset_node) - tree.extend(k8s_tree_instance.async_tree_node(namespace, pod)) - return Response(data=tree) + try: + tree.extend(k8s_tree_instance.async_tree_node(namespace, pod)) + return Response(data=tree) + except Exception as e: + raise JMSException(e) From 2c2c3eb21a19e932cd038faa6cfd7519ed6d5a94 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:18:00 +0800 Subject: [PATCH 41/41] =?UTF-8?q?perf:=20=E7=BF=BB=E8=AF=91=20(#12564)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 72 ++++++++++++++-------------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 72 ++++++++++++++-------------- apps/users/signal_handlers.py | 4 +- 5 files changed, 80 insertions(+), 76 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index ba844d417..0f74a7c63 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:18c4618e0d0470e25d99b143e83de9a439ac691e5cb1d92ea5406cc32338e8f8 -size 170813 +oid sha256:7879f4eeb499e920ad6c4bfdb0b1f334936ca344c275be056f12fcf7485f2bf6 +size 170948 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 54a52ff27..c6a6dfe37 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-01-11 18:58+0800\n" +"POT-Creation-Date: 2024-01-17 19:11+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -363,7 +363,7 @@ msgstr "アカウントバックアップ計画" #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:235 #: ops/templates/ops/celery_task_log.html:75 #: perms/models/asset_permission.py:78 -#: settings/templates/ldap/_msg_import_ldap_user.html:25 +#: settings/templates/ldap/_msg_import_ldap_user.html:5 #: terminal/models/applet/host.py:141 terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -373,7 +373,7 @@ msgstr "開始日" #: accounts/models/automations/backup_account.py:122 #: authentication/templates/authentication/_msg_oauth_bind.html:11 #: notifications/notifications.py:186 -#: settings/templates/ldap/_msg_import_ldap_user.html:23 +#: settings/templates/ldap/_msg_import_ldap_user.html:3 msgid "Time" msgstr "時間" @@ -495,7 +495,7 @@ msgstr "ステータス" #: authentication/templates/authentication/passkey.html:173 #: authentication/views/base.py:42 authentication/views/base.py:43 #: authentication/views/base.py:44 common/const/choices.py:20 -#: settings/templates/ldap/_msg_import_ldap_user.html:16 +#: settings/templates/ldap/_msg_import_ldap_user.html:22 msgid "Error" msgstr "間違い" @@ -873,7 +873,7 @@ msgid "Key password" msgstr "キーパスワード" #: accounts/serializers/account/base.py:78 -#: assets/serializers/asset/common.py:381 +#: assets/serializers/asset/common.py:384 msgid "Spec info" msgstr "特別情報" @@ -989,17 +989,17 @@ msgstr "自動タスク実行履歴" msgid "Success" msgstr "成功" -#: accounts/signal_handlers.py:46 +#: accounts/signal_handlers.py:47 #, python-format msgid "Push related accounts to assets: %s, by system" msgstr "関連するアカウントをアセットにプッシュ: %s, by system" -#: accounts/signal_handlers.py:55 +#: accounts/signal_handlers.py:56 #, python-format msgid "Add account: %s" msgstr "アカウントを追加: %s" -#: accounts/signal_handlers.py:57 +#: accounts/signal_handlers.py:58 #, python-format msgid "Delete account: %s" msgstr "アカウントを削除: %s" @@ -1750,7 +1750,7 @@ msgstr "ドメイン" msgid "Node" msgstr "ノード" -#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:382 +#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:385 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "資産ハードウェア情報の収集" @@ -2085,23 +2085,23 @@ msgid "Node path" msgstr "ノードパスです" #: assets/serializers/asset/common.py:148 -#: assets/serializers/asset/common.py:383 +#: assets/serializers/asset/common.py:386 msgid "Auto info" msgstr "自動情報" -#: assets/serializers/asset/common.py:242 +#: assets/serializers/asset/common.py:245 msgid "Platform not exist" msgstr "プラットフォームが存在しません" -#: assets/serializers/asset/common.py:278 +#: assets/serializers/asset/common.py:281 msgid "port out of range (0-65535)" msgstr "ポート番号が範囲外です (0-65535)" -#: assets/serializers/asset/common.py:285 +#: assets/serializers/asset/common.py:288 msgid "Protocol is required: {}" msgstr "プロトコルが必要です: {}" -#: assets/serializers/asset/common.py:313 +#: assets/serializers/asset/common.py:316 msgid "Invalid data" msgstr "無効なデータ" @@ -2611,8 +2611,8 @@ msgstr "認証トークン" #: audits/signal_handlers/login_log.py:37 authentication/notifications.py:73 #: authentication/views/login.py:77 notifications/backends/__init__.py:11 -#: settings/notifications.py:68 settings/serializers/auth/wecom.py:10 -#: users/models/user.py:749 users/models/user.py:855 +#: settings/serializers/auth/wecom.py:10 users/models/user.py:749 +#: users/models/user.py:855 msgid "WeCom" msgstr "企業微信" @@ -2648,9 +2648,9 @@ msgstr "仮パスワード" msgid "Passkey" msgstr "Passkey" -#: audits/tasks.py:101 users/signal_handlers.py:166 +#: audits/tasks.py:101 msgid "Clean audits session task log" -msgstr "監査セッション タスク ログのクリーンアップ" +msgstr "資産監査セッションタスクログのクリーンアップ" #: audits/tasks.py:114 msgid "Upload FTP file to external storage" @@ -3176,7 +3176,7 @@ msgstr "確認済み" msgid "Different city login reminder" msgstr "異なる都市ログインのリマインダー" -#: authentication/notifications.py:52 settings/notifications.py:47 +#: authentication/notifications.py:52 msgid "binding reminder" msgstr "バインディングリマインダー" @@ -4387,7 +4387,7 @@ msgid "Is finished" msgstr "終了しました" #: ops/serializers/job.py:66 -#: settings/templates/ldap/_msg_import_ldap_user.html:27 +#: settings/templates/ldap/_msg_import_ldap_user.html:7 msgid "Time cost" msgstr "時を過ごす" @@ -4976,7 +4976,7 @@ msgstr "他の設定を変えることができます" msgid "Chat prompt" msgstr "チャットのヒント" -#: settings/notifications.py:22 +#: settings/notifications.py:23 msgid "Notification of Synchronized LDAP User Task Results" msgstr "LDAPユーザータスクの結果通知を同期する" @@ -5639,10 +5639,8 @@ msgid "Enable virtual app" msgstr "仮想アプリケーションの有効化" #: settings/serializers/msg.py:25 -#, fuzzy -#| msgid "SMTP host" msgid "SMTP" -msgstr "SMTPホスト" +msgstr "SMTP" #: settings/serializers/msg.py:26 msgid "EXCHANGE" @@ -6089,7 +6087,7 @@ msgstr "Razor の有効化" msgid "Enable SSH Client" msgstr "SSH Clientの有効化" -#: settings/tasks/ldap.py:29 +#: settings/tasks/ldap.py:28 msgid "Periodic import ldap user" msgstr "LDAP ユーザーを定期的にインポートする" @@ -6101,19 +6099,19 @@ msgstr "登録サイクルLDAPユーザータスクのインポート" msgid "Sync task Finish" msgstr "同期タスクが完了しました" -#: settings/templates/ldap/_msg_import_ldap_user.html:3 -msgid "Synced Organization" -msgstr "組織が同期されました" - -#: settings/templates/ldap/_msg_import_ldap_user.html:9 -msgid "Synced User" -msgstr "同期されたユーザー" - -#: settings/templates/ldap/_msg_import_ldap_user.html:26 +#: settings/templates/ldap/_msg_import_ldap_user.html:6 #: terminal/models/session/session.py:45 msgid "Date end" msgstr "終了日" +#: settings/templates/ldap/_msg_import_ldap_user.html:9 +msgid "Synced Organization" +msgstr "組織が同期されました" + +#: settings/templates/ldap/_msg_import_ldap_user.html:15 +msgid "Synced User" +msgstr "同期されたユーザー" + #: settings/utils/ldap.py:494 msgid "ldap:// or ldaps:// protocol is used." msgstr "ldap:// または ldaps:// プロトコルが使用されます。" @@ -8078,6 +8076,10 @@ msgstr "" "管理者は「既存のユーザーのみログインを許可」をオンにしており、現在のユーザー" "はユーザーリストにありません。管理者に連絡してください。" +#: users/signal_handlers.py:166 +msgid "Clean up expired user sessions" +msgstr "期限切れのユーザー・セッションのパージ" + #: users/tasks.py:25 msgid "Check password expired" msgstr "パスワードの有効期限が切れていることを確認する" @@ -8509,7 +8511,7 @@ msgstr "そして" msgid "Or" msgstr "または" -#: xpack/plugins/cloud/manager.py:57 +#: xpack/plugins/cloud/manager.py:56 msgid "Account unavailable" msgstr "利用できないアカウント" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index efb8daa9d..bf09fbd89 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:933315b682ee1387f7433b5a870d8597c07634f4fede4c56a42b4cab540e4208 -size 140012 +oid sha256:19d3a111cc245f9a9d36b860fd95447df916ad66c918bef672bacdad6bc77a8f +size 140119 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index aabbbb733..73f1032a6 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-01-11 18:58+0800\n" +"POT-Creation-Date: 2024-01-17 19:11+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -362,7 +362,7 @@ msgstr "账号备份计划" #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:235 #: ops/templates/ops/celery_task_log.html:75 #: perms/models/asset_permission.py:78 -#: settings/templates/ldap/_msg_import_ldap_user.html:25 +#: settings/templates/ldap/_msg_import_ldap_user.html:5 #: terminal/models/applet/host.py:141 terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -372,7 +372,7 @@ msgstr "开始日期" #: accounts/models/automations/backup_account.py:122 #: authentication/templates/authentication/_msg_oauth_bind.html:11 #: notifications/notifications.py:186 -#: settings/templates/ldap/_msg_import_ldap_user.html:23 +#: settings/templates/ldap/_msg_import_ldap_user.html:3 msgid "Time" msgstr "时间" @@ -494,7 +494,7 @@ msgstr "状态" #: authentication/templates/authentication/passkey.html:173 #: authentication/views/base.py:42 authentication/views/base.py:43 #: authentication/views/base.py:44 common/const/choices.py:20 -#: settings/templates/ldap/_msg_import_ldap_user.html:16 +#: settings/templates/ldap/_msg_import_ldap_user.html:22 msgid "Error" msgstr "错误" @@ -871,7 +871,7 @@ msgid "Key password" msgstr "密钥密码" #: accounts/serializers/account/base.py:78 -#: assets/serializers/asset/common.py:381 +#: assets/serializers/asset/common.py:384 msgid "Spec info" msgstr "特殊信息" @@ -986,17 +986,17 @@ msgstr "自动化任务执行历史" msgid "Success" msgstr "成功" -#: accounts/signal_handlers.py:46 +#: accounts/signal_handlers.py:47 #, python-format msgid "Push related accounts to assets: %s, by system" msgstr "推送账号到资产: %s, 由系统执行" -#: accounts/signal_handlers.py:55 +#: accounts/signal_handlers.py:56 #, python-format msgid "Add account: %s" msgstr "添加账号: %s" -#: accounts/signal_handlers.py:57 +#: accounts/signal_handlers.py:58 #, python-format msgid "Delete account: %s" msgstr "删除账号: %s" @@ -1742,7 +1742,7 @@ msgstr "网域" msgid "Node" msgstr "节点" -#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:382 +#: assets/models/asset/common.py:167 assets/serializers/asset/common.py:385 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "收集资产硬件信息" @@ -2075,23 +2075,23 @@ msgid "Node path" msgstr "节点路径" #: assets/serializers/asset/common.py:148 -#: assets/serializers/asset/common.py:383 +#: assets/serializers/asset/common.py:386 msgid "Auto info" msgstr "自动化信息" -#: assets/serializers/asset/common.py:242 +#: assets/serializers/asset/common.py:245 msgid "Platform not exist" msgstr "平台不存在" -#: assets/serializers/asset/common.py:278 +#: assets/serializers/asset/common.py:281 msgid "port out of range (0-65535)" msgstr "端口超出范围 (0-65535)" -#: assets/serializers/asset/common.py:285 +#: assets/serializers/asset/common.py:288 msgid "Protocol is required: {}" msgstr "协议是必填的: {}" -#: assets/serializers/asset/common.py:313 +#: assets/serializers/asset/common.py:316 msgid "Invalid data" msgstr "无效的数据" @@ -2594,8 +2594,8 @@ msgstr "认证令牌" #: audits/signal_handlers/login_log.py:37 authentication/notifications.py:73 #: authentication/views/login.py:77 notifications/backends/__init__.py:11 -#: settings/notifications.py:68 settings/serializers/auth/wecom.py:10 -#: users/models/user.py:749 users/models/user.py:855 +#: settings/serializers/auth/wecom.py:10 users/models/user.py:749 +#: users/models/user.py:855 msgid "WeCom" msgstr "企业微信" @@ -2631,9 +2631,9 @@ msgstr "临时密码" msgid "Passkey" msgstr "Passkey" -#: audits/tasks.py:101 users/signal_handlers.py:166 +#: audits/tasks.py:101 msgid "Clean audits session task log" -msgstr "清理审计会话任务日志" +msgstr "清理资产审计会话任务日志" #: audits/tasks.py:114 msgid "Upload FTP file to external storage" @@ -3144,7 +3144,7 @@ msgstr "已校验" msgid "Different city login reminder" msgstr "异地登录提醒" -#: authentication/notifications.py:52 settings/notifications.py:47 +#: authentication/notifications.py:52 msgid "binding reminder" msgstr "绑定提醒" @@ -4336,7 +4336,7 @@ msgid "Is finished" msgstr "是否完成" #: ops/serializers/job.py:66 -#: settings/templates/ldap/_msg_import_ldap_user.html:27 +#: settings/templates/ldap/_msg_import_ldap_user.html:7 msgid "Time cost" msgstr "花费时间" @@ -4921,7 +4921,7 @@ msgstr "其它设置" msgid "Chat prompt" msgstr "聊天提示" -#: settings/notifications.py:22 +#: settings/notifications.py:23 msgid "Notification of Synchronized LDAP User Task Results" msgstr "同步LDAP用户任务结果通知" @@ -5579,10 +5579,8 @@ msgid "Enable virtual app" msgstr "启用虚拟应用" #: settings/serializers/msg.py:25 -#, fuzzy -#| msgid "SMTP host" msgid "SMTP" -msgstr "SMTP 主机" +msgstr "SMTP" #: settings/serializers/msg.py:26 msgid "EXCHANGE" @@ -6005,7 +6003,7 @@ msgstr "启用 Razor 服务" msgid "Enable SSH Client" msgstr "启用 SSH Client" -#: settings/tasks/ldap.py:29 +#: settings/tasks/ldap.py:28 msgid "Periodic import ldap user" msgstr "周期导入 LDAP 用户" @@ -6017,19 +6015,19 @@ msgstr "注册周期导入 LDAP 用户 任务" msgid "Sync task Finish" msgstr "同步任务完成" -#: settings/templates/ldap/_msg_import_ldap_user.html:3 -msgid "Synced Organization" -msgstr "已同步组织" - -#: settings/templates/ldap/_msg_import_ldap_user.html:9 -msgid "Synced User" -msgstr "已同步用户" - -#: settings/templates/ldap/_msg_import_ldap_user.html:26 +#: settings/templates/ldap/_msg_import_ldap_user.html:6 #: terminal/models/session/session.py:45 msgid "Date end" msgstr "结束日期" +#: settings/templates/ldap/_msg_import_ldap_user.html:9 +msgid "Synced Organization" +msgstr "已同步组织" + +#: settings/templates/ldap/_msg_import_ldap_user.html:15 +msgid "Synced User" +msgstr "已同步用户" + #: settings/utils/ldap.py:494 msgid "ldap:// or ldaps:// protocol is used." msgstr "使用 ldap:// 或 ldaps:// 协议" @@ -7966,6 +7964,10 @@ msgid "" msgstr "" "管理员已开启'仅允许已存在用户登录',当前用户不在用户列表中,请联系管理员。" +#: users/signal_handlers.py:166 +msgid "Clean up expired user sessions" +msgstr "清除过期的用户会话" + #: users/tasks.py:25 msgid "Check password expired" msgstr "校验密码已过期" @@ -8385,7 +8387,7 @@ msgstr "与" msgid "Or" msgstr "或" -#: xpack/plugins/cloud/manager.py:57 +#: xpack/plugins/cloud/manager.py:56 msgid "Account unavailable" msgstr "账号无效" diff --git a/apps/users/signal_handlers.py b/apps/users/signal_handlers.py index 6e53bb87b..8e1f92254 100644 --- a/apps/users/signal_handlers.py +++ b/apps/users/signal_handlers.py @@ -163,9 +163,9 @@ def on_openid_create_or_update_user(sender, request, user, created, name, userna user.save() -@shared_task(verbose_name=_('Clean audits session task log')) +@shared_task(verbose_name=_('Clean up expired user sessions')) @register_as_period_task(crontab=CRONTAB_AT_PM_TWO) -def clean_audits_log_period(): +def clean_expired_user_session_period(): UserSession.clear_expired_sessions()