From 584387682d1ff7681a33f8f904ab8f1347074499 Mon Sep 17 00:00:00 2001 From: San Lin Naing Date: Tue, 8 Oct 2024 20:34:44 +0900 Subject: [PATCH 1/6] some of lint warning fixing and code refactor for readability --- app.py | 4 ++-- controllers/auth.py | 6 ++++-- controllers/settings.py | 4 ++-- pushservices/bootstrap.py | 5 ++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app.py b/app.py index 13999508..436d1248 100755 --- a/app.py +++ b/app.py @@ -70,13 +70,13 @@ if options.sentrydsn: sentry_sdk.init(dsn=options.sentrydsn, integrations=[TornadoIntegration()]) else: - logging.warn("Sentry dsn is not set") + logging.warning("Sentry dsn is not set") mongodb = None while not mongodb: try: mongodb = pymongo.MongoClient(options.mongouri) - except: + except Exception: logging.error("Cannot not connect to MongoDB") masterdb = mongodb[options.masterdb] diff --git a/controllers/auth.py b/controllers/auth.py index 8b55410c..a9d8a462 100644 --- a/controllers/auth.py +++ b/controllers/auth.py @@ -25,8 +25,10 @@ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import hashlib, os -from controllers.base import * +from controllers.base import WebBaseHandler +from tornado.options import options +from routes import route +from util import get_password @route(r"/auth/([^/]+)") diff --git a/controllers/settings.py b/controllers/settings.py index d21456ed..49d4fa88 100644 --- a/controllers/settings.py +++ b/controllers/settings.py @@ -57,7 +57,7 @@ from pushservices.apns import ApnsClient import requests import traceback -from controllers.base import * +from controllers.base import WebBaseHandler @route(r"/applications/([^/]+)/settings[\/]?") @@ -126,7 +126,7 @@ def post(self, appname): app["wnstokenexpiry"] = int(responsedata["expires_in"]) + int( time.time() ) - ## Update connections too + # Update connections too self.wnsconnections[app["shortname"]] = [] wns = WNSClient(self.masterdb, app, 0) self.wnsconnections[app["shortname"]].append(wns) diff --git a/pushservices/bootstrap.py b/pushservices/bootstrap.py index 49c8cdf4..120c7c6e 100644 --- a/pushservices/bootstrap.py +++ b/pushservices/bootstrap.py @@ -1,5 +1,5 @@ import logging -from .apns import * +from .apns import ApnsClient from .clickatell import * from .fcm import FCMClient from .mpns import MPNSClient @@ -63,9 +63,8 @@ def init_messaging_agents(masterdb): if "wnsclientid" in app and "wnsclientsecret" in app and "shortname" in app: try: wns = WNSClient(masterdb, app, 0) + services["wns"][appname].append(wns) except Exception as ex: logging.error(ex) continue - services["wns"][appname].append(wns) - return services From f581e66d1b05debcfc411400b149b702c9875cf9 Mon Sep 17 00:00:00 2001 From: San Lin Naing Date: Tue, 8 Oct 2024 20:48:26 +0900 Subject: [PATCH 2/6] Fixed #238 issue that can't send broadcast message due to device type check for ios-fcm --- controllers/broadcast.py | 10 ++++++---- web.py | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/controllers/broadcast.py b/controllers/broadcast.py index a24284cf..13445f2f 100644 --- a/controllers/broadcast.py +++ b/controllers/broadcast.py @@ -27,8 +27,8 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import tornado.web - -from controllers.base import * +from routes import route +from controllers.base import WebBaseHandler @route(r"/applications/([^/]+)/broadcast") @@ -41,8 +41,10 @@ def get(self, appname): raise tornado.web.HTTPError(500) self.render("app_broadcast.html", app=app, sent=False) + # TODO: to check and implement for performance in case there are much devices + # to send the broadcast message. @tornado.web.authenticated - def post(self, appname): + async def post(self, appname): self.appname = appname app = self.masterdb.applications.find_one({"shortname": appname}) if not app: @@ -50,7 +52,7 @@ def post(self, appname): alert = self.get_argument("notification").strip() sound = "default" channel = "default" - self.application.send_broadcast( + await self.application.send_broadcast( self.appname, self.db, channel=channel, alert=alert, sound=sound ) self.render("app_broadcast.html", app=app, sent=True) diff --git a/web.py b/web.py index 6f53968c..619e2962 100644 --- a/web.py +++ b/web.py @@ -6,7 +6,11 @@ RELEASE, VERSION, ) -from uimodules import * +from uimodules import ( + AppSideBar, + NavBar, + TabBar +) import datetime import os import logging @@ -117,15 +121,16 @@ async def send_broadcast(self, appname, appdb, **kwargs): extra=extra, apns=kwargs.get("apns", {}), ) - elif token["device"] == DEVICE_TYPE_FCM or token["device"] == DEVICE_TYPE_ANDROID: + elif (token["device"].endswith(DEVICE_TYPE_FCM) or + token["device"] == DEVICE_TYPE_ANDROID): await fcm.process( token=t, alert=alert, extra=extra, fcm=kwargs.get("fcm", {}) ) - elif token["device"] == DEVICE_TYPE_WNS: - if wns is not None: - wns.process( - token=t, alert=alert, extra=extra, wns=kwargs.get("wns", {}) - ) + elif (token["device"] == DEVICE_TYPE_WNS and + wns is not None): + wns.process( + token=t, alert=alert, extra=extra, wns=kwargs.get("wns", {}) + ) except Exception as ex: logging.error(ex) From f7610db9abdc049e06a41dae47aa4846806e7c4b Mon Sep 17 00:00:00 2001 From: San Lin Naing Date: Tue, 8 Oct 2024 20:51:03 +0900 Subject: [PATCH 3/6] Pipenv rebuild to support newer Python version >=3.9 on upcomming commits. Python version upgrade started here. --- Pipfile | 20 +-- Pipfile.lock | 464 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 290 insertions(+), 194 deletions(-) diff --git a/Pipfile b/Pipfile index d3219faf..fbabc935 100644 --- a/Pipfile +++ b/Pipfile @@ -9,14 +9,12 @@ test = "python -m unittest discover -s tests -p 'test_*.py'" [dev-packages] [packages] -netaddr = "==0.7.18" -oauth2client = "==4.1.3" -pymongo = "==3.5.1" -requests = "==2.21.0" -tornado = "~=6.0" -click = "*" -sentry-sdk = "==0.13.2" -aiocontextvars = "*" -hyper = "*" -pyjwt = "*" -cryptography = "*" +netaddr = "~=1.3.0" +google-auth = "~=2.35.0" +requests = "~=2.32.3" +pymongo = "~=4.10.1" +tornado = "~=6.4.1" +click = "~=8.1.7" +sentry-sdk = "~=2.15.0" +pyjwt = "~=2.9.0" +httpx = {extras = ["http2"], version = "~=0.27.2"} diff --git a/Pipfile.lock b/Pipfile.lock index fa580aa6..9a40e925 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7c77039e12d818dabb8de1461ecedf1cbbf34693340c8796243d7ab27106e5cb" + "sha256": "4fa2113417a7ea773943e8e25f90951ce82d550e1c61a6ec290cc4faeb9303d2" }, "pipfile-spec": 6, "requires": {}, @@ -14,279 +14,377 @@ ] }, "default": { - "aiocontextvars": { + "anyio": { "hashes": [ - "sha256:885daf8261818767d8f7cbd79f9d4482d118f024b6586ef6e67980236a27bfa3", - "sha256:f027372dc48641f683c559f247bd84962becaacdc9ba711d583c3871fb5652aa" + "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb", + "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a" ], - "index": "pypi", - "version": "==0.2.2" + "markers": "python_version >= '3.9'", + "version": "==4.6.0" }, - "certifi": { + "cachetools": { "hashes": [ - "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", - "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" + "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292", + "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a" ], - "version": "==2019.11.28" + "markers": "python_version >= '3.7'", + "version": "==5.5.0" }, - "cffi": { + "certifi": { "hashes": [ - "sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42", - "sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04", - "sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5", - "sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54", - "sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba", - "sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57", - "sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396", - "sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12", - "sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97", - "sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43", - "sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db", - "sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3", - "sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b", - "sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579", - "sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346", - "sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159", - "sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652", - "sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e", - "sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a", - "sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506", - "sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f", - "sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d", - "sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c", - "sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20", - "sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858", - "sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc", - "sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a", - "sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3", - "sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e", - "sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410", - "sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25", - "sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b", - "sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d" + "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" ], - "version": "==1.13.2" + "markers": "python_version >= '3.6'", + "version": "==2024.8.30" }, - "chardet": { + "charset-normalizer": { "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" ], - "version": "==3.0.4" + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" }, "click": { "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "index": "pypi", - "version": "==7.0" + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "platform_system == 'Windows'", + "version": "==0.4.6" }, - "cryptography": { + "dnspython": { "hashes": [ - "sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c", - "sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595", - "sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad", - "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651", - "sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2", - "sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff", - "sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d", - "sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42", - "sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d", - "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e", - "sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912", - "sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793", - "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13", - "sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7", - "sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0", - "sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879", - "sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f", - "sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9", - "sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2", - "sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf", - "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8" + "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", + "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1" + ], + "markers": "python_version >= '3.9'", + "version": "==2.7.0" + }, + "google-auth": { + "hashes": [ + "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f", + "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a" ], "index": "pypi", - "version": "==2.8" + "markers": "python_version >= '3.7'", + "version": "==2.35.0" + }, + "h11": { + "hashes": [ + "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", + "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" + ], + "markers": "python_version >= '3.7'", + "version": "==0.14.0" }, "h2": { "hashes": [ - "sha256:93cbd1013a2218539af05cdf9fc37b786655b93bbc94f5296b7dabd1c5cadf41", - "sha256:af35878673c83a44afbc12b13ac91a489da2819b5dc1e11768f3c2406f740fe9" + "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d", + "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb" ], - "version": "==2.6.2" + "version": "==4.1.0" }, "hpack": { "hashes": [ - "sha256:0edd79eda27a53ba5be2dfabf3b15780928a0dff6eb0c60a3d6767720e970c89", - "sha256:8eec9c1f4bfae3408a3f30500261f7e6a65912dc138526ea054f9ad98892e9d2" + "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c", + "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095" ], - "version": "==3.0.0" + "markers": "python_full_version >= '3.6.1'", + "version": "==4.0.0" }, - "httplib2": { + "httpcore": { "hashes": [ - "sha256:79751cc040229ec896aa01dced54de0cd0bf042f928e84d5761294422dde4454", - "sha256:de96d0a49f46d0ee7e0aae80141d37b8fcd6a68fb05d02e0b82c128592dd8261" + "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", + "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f" ], - "version": "==0.17.0" + "markers": "python_version >= '3.8'", + "version": "==1.0.6" }, - "hyper": { + "httpx": { + "extras": [ + "http2" + ], "hashes": [ - "sha256:069514f54231fb7b5df2fb910a114663a83306d5296f588fffcb0a9be19407fc", - "sha256:12c82eacd122a659673484c1ea0d34576430afbe5aa6b8f63fe37fcb06a2458c" + "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", + "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2" ], - "index": "pypi", - "version": "==0.7.0" + "markers": "python_version >= '3.8'", + "version": "==0.27.2" }, "hyperframe": { "hashes": [ - "sha256:05f0e063e117c16fcdd13c12c93a4424a2c40668abfac3bb419a10f57698204e", - "sha256:4dcab11967482d400853b396d042038e4c492a15a5d2f57259e2b5f89a32f755" + "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15", + "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914" ], - "version": "==3.2.0" + "markers": "python_full_version >= '3.6.1'", + "version": "==6.0.1" }, "idna": { "hashes": [ - "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", - "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], - "version": "==2.8" + "markers": "python_version >= '3.6'", + "version": "==3.10" }, "netaddr": { "hashes": [ - "sha256:a1f5c9fcf75ac2579b9995c843dade33009543c04f218ff7c007b3c81695bd19", - "sha256:c64c570ac612e20e8b8a6eee72034c924fff9d76c7a46f50a9f919085f1bfbed", - "sha256:cb305179658334eb035860e515f054504e232b832abb4efc51c04bf8a72d3574" - ], - "index": "pypi", - "version": "==0.7.18" - }, - "oauth2client": { - "hashes": [ - "sha256:b8a81cc5d60e2d364f0b1b98f958dbd472887acaf1a5b05e21c28c31a2d6d3ac", - "sha256:d486741e451287f69568a4d26d70d9acd73a2bbfa275746c535b4209891cccc6" + "sha256:5c3c3d9895b551b763779ba7db7a03487dc1f8e3b385af819af341ae9ef6e48a", + "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe" ], "index": "pypi", - "version": "==4.1.3" + "markers": "python_version >= '3.7'", + "version": "==1.3.0" }, "pyasn1": { "hashes": [ - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba" + "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", + "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034" ], - "version": "==0.4.8" + "markers": "python_version >= '3.8'", + "version": "==0.6.1" }, "pyasn1-modules": { "hashes": [ - "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", - "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74" - ], - "version": "==0.2.8" - }, - "pycparser": { - "hashes": [ - "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3" + "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd", + "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c" ], - "version": "==2.19" + "markers": "python_version >= '3.8'", + "version": "==0.4.1" }, "pyjwt": { "hashes": [ - "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", - "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96" + "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850", + "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c" ], "index": "pypi", - "version": "==1.7.1" + "markers": "python_version >= '3.8'", + "version": "==2.9.0" }, "pymongo": { "hashes": [ - "sha256:0ce91b475d50b70388f512a2780bf91b0de643175d3f60bae3786ee4f133e751", - "sha256:0f0e2cd634a5f97fe84b8a860c52e86cee488764031505cdc7c855f01fed7bd4", - "sha256:166746d50df39c3d293ff26f18c64d728b4ac59b3d1940fb6475ad22820ba439", - "sha256:1863a7ee4080388a7e247c7f8040c2a1e1288cecc3792cdcbe25a4b55a3f4a75", - "sha256:2652d255b3a0b16a49c743879e882d6c3de40166282fa791075ad5db0285cbb4", - "sha256:28be0827bd176c844fc0c06d99dae95bf0f720b6ff3616099f3ab6d0e1742602", - "sha256:38fddffcd47b51415eef97290643dda4e72c7bf32af798df128d9ad94196f029", - "sha256:39961f650fca9b3c6a8294a47707c328283d42e298712030b1992083900f00c3", - "sha256:3eda499d1a6e584c448b8abb66c4cb7af02ba50f70a99a3063c4d9c460130e38", - "sha256:41c892df7f67ec9aa76f4e1b4e093ac18d9a9ebafa6c60fc4e57db68eadb0d87", - "sha256:4b68b6defa12b96e1087871e677ee8b9d67bbf57b1b70ee54ed19d2ee9dca538", - "sha256:521676f3f2739a6b92d8d7bd7141653594e609b5827a382b0b9d76da69eefb2e", - "sha256:57197ac3f47eeef633eec0ea46ddc3895904d0daf2bd271d85a5d691de539171", - "sha256:6c2b1b2ec87873c1d1e38b32378ad428409264d674cceaf1552d557d7f961e57", - "sha256:728a624a35383b147f2fca6051fb9604c7209ad0d9b65e35bf429e563d999e8a", - "sha256:8077f89268d702dfae5a633a389f7775122e4146e05e9d6c8b0ee12c91e4d84c", - "sha256:8946a46e3b9c4a7f0feb6909093594ab10771bda0fc4601901666b27043fc100", - "sha256:8de6afe3aa34be4800a0bc49ce8f0d05c5e936b4ec297322e64bb6db8e5fd754", - "sha256:906a13ad6081c5cb5c6862879bc22aa738a4ae12561c6b4ae64d2ff1b4fc47f5", - "sha256:a02035ab7ebef71f7fc4aaa0c2344bcc7d74c6de64a000464184f8cb9496966f", - "sha256:a11b456b549583d76a1ccca20a4a0ee710489e67753b3f3082cd929556693f31", - "sha256:a516bddf391ccded8a9fe75672200bfedb20449e09661f3f785e8e695a6b15e4", - "sha256:a7c3a6f32eb910fbdc0dde9aca9fb5407726cd21504d0a67334109f6aaade94e", - "sha256:abbcbdabe9fd64b107f3aef5c68a20f22906c5f941e75b8414a026e8860af489", - "sha256:bc2e6b5bc53269cad1f06ac32a86777a3b8761459f155c6bb14b25844720c0b1", - "sha256:c612ed53c88071da75a4998add30971d9e90e80c83339c86e3be5ebd6913e32b", - "sha256:cf8846fb59caffa587ba14da78f8fb23dba85017e009c1d752469b0005c444bf", - "sha256:d0e516d07979c43a65927cd98c8bda84c7620f09658e9f424ebfff8f28994f77", - "sha256:d2701658ea78ad484cd077fecb68de130de9a4ed784cc0a62d8d1d549d2b3fff", - "sha256:d3aabb3dfc564d4b797c3805f3f3b4ce24de6c7150041f9caad536f4c672110b", - "sha256:dd647f898031efefc093c14960b531ce13c10cd704dc0b43604cb93b168719e5", - "sha256:e820d93414f3bec1fa456c84afbd4af1b43ff41366321619db74e6bc065d6924", - "sha256:ef5dc292d27cb65a04776eaf0c9b5e6a87d6fd03f272a7043816fb8b946f4d8d", - "sha256:fd22e54beb634e3568638862f305ccd3a78a89fa14a2b62397255b3510eb6bca", - "sha256:ffaf9e135f9321423ac50035c4e3854b4f668e5a46c81d2e3341ae0504279ba3" + "sha256:0783e0c8e95397c84e9cf8ab092ab1e5dd7c769aec0ef3a5838ae7173b98dea0", + "sha256:0f56707497323150bd2ed5d63067f4ffce940d0549d4ea2dfae180deec7f9363", + "sha256:11280809e5dacaef4971113f0b4ff4696ee94cfdb720019ff4fa4f9635138252", + "sha256:15a624d752dd3c89d10deb0ef6431559b6d074703cab90a70bb849ece02adc6b", + "sha256:15b1492cc5c7cd260229590be7218261e81684b8da6d6de2660cf743445500ce", + "sha256:1a970fd3117ab40a4001c3dad333bbf3c43687d90f35287a6237149b5ccae61d", + "sha256:1ec3fa88b541e0481aff3c35194c9fac96e4d57ec5d1c122376000eb28c01431", + "sha256:1ecc2455e3974a6c429687b395a0bc59636f2d6aedf5785098cf4e1f180f1c71", + "sha256:23e1d62df5592518204943b507be7b457fb8a4ad95a349440406fd42db5d0923", + "sha256:29e1c323c28a4584b7095378ff046815e39ff82cdb8dc4cc6dfe3acf6f9ad1f8", + "sha256:2e3a593333e20c87415420a4fb76c00b7aae49b6361d2e2205b6fece0563bf40", + "sha256:345f8d340802ebce509f49d5833cc913da40c82f2e0daf9f60149cacc9ca680f", + "sha256:3a70d5efdc0387ac8cd50f9a5f379648ecfc322d14ec9e1ba8ec957e5d08c372", + "sha256:409ab7d6c4223e5c85881697f365239dd3ed1b58f28e4124b846d9d488c86880", + "sha256:442ca247f53ad24870a01e80a71cd81b3f2318655fd9d66748ee2bd1b1569d9e", + "sha256:45ee87a4e12337353242bc758accc7fb47a2f2d9ecc0382a61e64c8f01e86708", + "sha256:4924355245a9c79f77b5cda2db36e0f75ece5faf9f84d16014c0a297f6d66786", + "sha256:544890085d9641f271d4f7a47684450ed4a7344d6b72d5968bfae32203b1bb7c", + "sha256:57ee6becae534e6d47848c97f6a6dff69e3cce7c70648d6049bd586764febe59", + "sha256:594dd721b81f301f33e843453638e02d92f63c198358e5a0fa8b8d0b1218dabc", + "sha256:5ded27a4a5374dae03a92e084a60cdbcecd595306555bda553b833baf3fc4868", + "sha256:6131bc6568b26e7495a9f3ef2b1700566b76bbecd919f4472bfe90038a61f425", + "sha256:6f437a612f4d4f7aca1812311b1e84477145e950fdafe3285b687ab8c52541f3", + "sha256:6fb6a72e88df46d1c1040fd32cd2d2c5e58722e5d3e31060a0393f04ad3283de", + "sha256:70645abc714f06b4ad6b72d5bf73792eaad14e3a2cfe29c62a9c81ada69d9e4b", + "sha256:72e2ace7456167c71cfeca7dcb47bd5dceda7db2231265b80fc625c5e8073186", + "sha256:778ac646ce6ac1e469664062dfe9ae1f5c9961f7790682809f5ec3b8fda29d65", + "sha256:7bd26b2aec8ceeb95a5d948d5cc0f62b0eb6d66f3f4230705c1e3d3d2c04ec76", + "sha256:7c4d0e7cd08ef9f8fbf2d15ba281ed55604368a32752e476250724c3ce36c72e", + "sha256:88dc4aa45f8744ccfb45164aedb9a4179c93567bbd98a33109d7dc400b00eb08", + "sha256:8ad05eb9c97e4f589ed9e74a00fcaac0d443ccd14f38d1258eb4c39a35dd722b", + "sha256:90bc6912948dfc8c363f4ead54d54a02a15a7fee6cfafb36dc450fc8962d2cb7", + "sha256:9235fa319993405ae5505bf1333366388add2e06848db7b3deee8f990b69808e", + "sha256:93a0833c10a967effcd823b4e7445ec491f0bf6da5de0ca33629c0528f42b748", + "sha256:95207503c41b97e7ecc7e596d84a61f441b4935f11aa8332828a754e7ada8c82", + "sha256:9df4ab5594fdd208dcba81be815fa8a8a5d8dedaf3b346cbf8b61c7296246a7a", + "sha256:a920fee41f7d0259f5f72c1f1eb331bc26ffbdc952846f9bd8c3b119013bb52c", + "sha256:a9de02be53b6bb98efe0b9eda84ffa1ec027fcb23a2de62c4f941d9a2f2f3330", + "sha256:ae2fd94c9fe048c94838badcc6e992d033cb9473eb31e5710b3707cba5e8aee2", + "sha256:b3337804ea0394a06e916add4e5fac1c89902f1b6f33936074a12505cab4ff05", + "sha256:ba164e73fdade9b4614a2497321c5b7512ddf749ed508950bdecc28d8d76a2d9", + "sha256:bb99f003c720c6d83be02c8f1a7787c22384a8ca9a4181e406174db47a048619", + "sha256:ca6f700cff6833de4872a4e738f43123db34400173558b558ae079b5535857a4", + "sha256:cec237c305fcbeef75c0bcbe9d223d1e22a6e3ba1b53b2f0b79d3d29c742b45b", + "sha256:dabe8bf1ad644e6b93f3acf90ff18536d94538ca4d27e583c6db49889e98e48f", + "sha256:dac78a650dc0637d610905fd06b5fa6419ae9028cf4d04d6a2657bc18a66bbce", + "sha256:dcc07b1277e8b4bf4d7382ca133850e323b7ab048b8353af496d050671c7ac52", + "sha256:e0a15665b2d6cf364f4cd114d62452ce01d71abfbd9c564ba8c74dcd7bbd6822", + "sha256:e0e961923a7b8a1c801c43552dcb8153e45afa41749d9efbd3a6d33f45489f7a", + "sha256:e4a65567bd17d19f03157c7ec992c6530eafd8191a4e5ede25566792c4fe3fa2", + "sha256:e5d55f2a82e5eb23795f724991cac2bffbb1c0f219c0ba3bf73a835f97f1bb2e", + "sha256:e699aa68c4a7dea2ab5a27067f7d3e08555f8d2c0dc6a0c8c60cfd9ff2e6a4b1", + "sha256:e974ab16a60be71a8dfad4e5afccf8dd05d41c758060f5d5bda9a758605d9a5d", + "sha256:ee4c86d8e6872a61f7888fc96577b0ea165eb3bdb0d841962b444fa36001e2bb", + "sha256:f1945d48fb9b8a87d515da07f37e5b2c35b364a435f534c122e92747881f4a7c", + "sha256:f2bc1ee4b1ca2c4e7e6b7a5e892126335ec8d9215bcd3ac2fe075870fefc3358", + "sha256:fb104c3c2a78d9d85571c8ac90ec4f95bca9b297c6eee5ada71fabf1129e1674", + "sha256:fbedc4617faa0edf423621bb0b3b8707836687161210d470e69a4184be9ca011", + "sha256:fdeba88c540c9ed0338c0b2062d9f81af42b18d6646b3e6dda05cf6edd46ada9" ], "index": "pypi", - "version": "==3.5.1" + "markers": "python_version >= '3.8'", + "version": "==4.10.1" }, "requests": { "hashes": [ - "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", - "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" ], "index": "pypi", - "version": "==2.21.0" + "markers": "python_version >= '3.8'", + "version": "==2.32.3" }, "rsa": { "hashes": [ - "sha256:14ba45700ff1ec9eeb206a2ce76b32814958a98e372006c8fb76ba820211be66", - "sha256:1a836406405730121ae9823e19c6e806c62bbad73f890574fff50efa4122c487" + "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", + "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" ], - "version": "==4.0" + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==4.9" }, "sentry-sdk": { "hashes": [ - "sha256:09e1e8f00f22ea580348f83bbbd880adf40b29f1dec494a8e4b33e22f77184fb", - "sha256:ff1fa7fb85703ae9414c8b427ee73f8363232767c9cd19158f08f6e4f0b58fc7" + "sha256:8fb0d1a4e1a640172f31502e4503543765a1fe8a9209779134a4ac52d4677303", + "sha256:a599e7d3400787d6f43327b973e55a087b931ba2c592a7a7afa691f8eb5e75e2" ], "index": "pypi", - "version": "==0.13.2" + "markers": "python_version >= '3.6'", + "version": "==2.15.0" }, - "six": { + "sniffio": { "hashes": [ - "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", - "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" + "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" ], - "version": "==1.14.0" + "markers": "python_version >= '3.7'", + "version": "==1.3.1" }, "tornado": { "hashes": [ - "sha256:349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c", - "sha256:398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60", - "sha256:4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281", - "sha256:559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5", - "sha256:abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7", - "sha256:c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9", - "sha256:c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5" + "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8", + "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f", + "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4", + "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3", + "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14", + "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842", + "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9", + "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698", + "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7", + "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d", + "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4" ], "index": "pypi", - "version": "==6.0.3" + "markers": "python_version >= '3.8'", + "version": "==6.4.1" }, "urllib3": { "hashes": [ - "sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4", - "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb" + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" ], - "version": "==1.24.3" + "markers": "python_version >= '3.8'", + "version": "==2.2.3" } }, "develop": {} From 33d6b8d097281a1d895608a56b11b336561d5205 Mon Sep 17 00:00:00 2001 From: San Lin Naing Date: Tue, 8 Oct 2024 20:52:00 +0900 Subject: [PATCH 4/6] oauth2client is migrated to google-auth to support newer python version >=3.9 --- pushservices/fcm.py | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/pushservices/fcm.py b/pushservices/fcm.py index ef78dcc7..3a6a7c5b 100644 --- a/pushservices/fcm.py +++ b/pushservices/fcm.py @@ -2,11 +2,10 @@ # -*- coding: utf-8 -*- from . import PushService -from oauth2client.service_account import ServiceAccountCredentials +from google.auth.transport.requests import AuthorizedSession +from google.oauth2 import service_account from util import json_decode, json_encode -import datetime import logging -import tornado BASE_URL = "https://fcm.googleapis.com" SCOPES = ["https://www.googleapis.com/auth/firebase.messaging"] @@ -27,10 +26,13 @@ def __init__(self, **kwargs): self.jsonkey = kwargs["jsonkey"] self.appname = kwargs["appname"] self.instanceid = kwargs["instanceid"] - jsonData = json_decode(self.jsonkey) - self.oauth_client = ServiceAccountCredentials.from_json_keyfile_dict( - jsonData, SCOPES + service_account_info = json_decode(self.jsonkey) + credentials = service_account.Credentials.from_service_account_info( + service_account_info, + scopes=SCOPES ) + self.authed_session = AuthorizedSession(credentials) + self.endpoint = "%s/v1/projects/%s/messages:send" % (BASE_URL, self.project_id) def format_values(self, data=None): @@ -47,7 +49,7 @@ def format_values(self, data=None): elif isinstance(v, dict): try: formatted[k] = json_encode(self.format_values(v)) - except: + except Exception: logging.error("Error treating field " + k) elif v is not None: @@ -84,8 +86,7 @@ def build_request(self, token, alert, **kwargs): if apns: payload["message"]["apns"] = apns - text = json_encode(payload) - return text + return payload async def process(self, **kwargs): fcm = kwargs.get("fcm", {}) @@ -93,22 +94,9 @@ async def process(self, **kwargs): token = kwargs["token"] if not token: - raise FCMException(400, "devicde token is required") + raise FCMException(400, "device token is required") body = self.build_request(token, alert, fcm=fcm) logging.info(body) - - access_token, expires_in = self.oauth_client.get_access_token() - logging.info( - "access token expiring in %s..." % datetime.timedelta(seconds=expires_in) - ) - headers = { - "Authorization": "Bearer %s" % access_token, - "Content-Type": "application/json; UTF-8", - } - - http = tornado.httpclient.AsyncHTTPClient() - response = await http.fetch( - self.endpoint, method="POST", body=body, headers=headers - ) + response = self.authed_session.request('POST', self.endpoint, json=body) return response From 0d7f1d14cb6ebea828035dfc8f0a0b07dd9a960f Mon Sep 17 00:00:00 2001 From: San Lin Naing Date: Tue, 8 Oct 2024 20:53:15 +0900 Subject: [PATCH 5/6] migrated depricated `hyper` lib with `httpx` for http2 client to send APNs api for supporting python newer version >= 3.9 --- pushservices/apns.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pushservices/apns.py b/pushservices/apns.py index bc4bf76b..9e418a59 100644 --- a/pushservices/apns.py +++ b/pushservices/apns.py @@ -4,7 +4,7 @@ from . import PushService from util import json_encode import logging -import hyper +import httpx import jwt import time @@ -32,8 +32,7 @@ def __init__(self, **kwargs): self.instanceid = kwargs["instanceid"] self.last_token_refresh = 0 self.token = None - self.http2 = hyper.HTTPConnection(BASE_URL_PROD) - # self.http2dev = hyper.HTTPConnection(BASE_URL_DEV) + self.http2 = httpx.Client(http2=True) def create_token(self): now = time.time() @@ -47,7 +46,7 @@ def create_token(self): headers={"alg": ALGORITHM, "kid": self.key_id}, ) self.last_token_refresh = now - self.token = token.decode("ascii") + self.token = token return self.token def build_headers(self, push_type="alert"): @@ -88,17 +87,20 @@ def process(self, **kwargs): # https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html#//apple_ref/doc/uid/TP40008194-CH17-SW1 payload_data = {"aps": {"alert": alert, **filtered_apns}} self.payload = json_encode(payload_data) + + # byte_token = token.encode('utf-8') + # device_token = ''.join([f'{byte:02x}' for byte in byte_token]) - PATH = "/3/device/{0}".format(token) + PATH = f"https://{BASE_URL_PROD}/3/device/{token}" self.headers = self.build_headers(push_type=apns["push_type"]) - self.http2.request("POST", PATH, self.payload, headers=self.headers) - resp = self.http2.get_response() + resp = self.http2.post(PATH, json=self.payload, headers=self.headers) + logging.info(f"Apple APNS response HTTP version: {resp.http_version}") - if resp.status >= 400: + if resp.status_code >= 400: # headers = resp.headers # for k, v in headers.items(): # logging.error("%s: %s" % (k.decode("utf-8"), v.decode("utf-8"))) - body = resp.read().decode("utf-8") + body = resp.json() logging.error(body) raise ApnsException(400, body) From 47786008795940d6a884b68d92545cb6fd4aee4d Mon Sep 17 00:00:00 2001 From: San Lin Naing Date: Tue, 8 Oct 2024 20:54:56 +0900 Subject: [PATCH 6/6] pymongo is upgraded to newer version >= 4.x to support upcomming MongoDB and Python --- api/__init__.py | 32 +++++++++-------- api/accesskeys.py | 4 +-- api/tokens.py | 16 +++++---- controllers/base.py | 31 +++++++++-------- controllers/keys.py | 12 ++++--- controllers/newapp.py | 7 ++-- controllers/tokens.py | 8 +++-- dao.py | 6 ++-- install.py | 16 ++++----- pushservices/gcm.py | 2 +- pushservices/wns.py | 4 +-- tests/test_push.py | 2 +- upgrade.py | 81 +++++++++++++++++++++++-------------------- 13 files changed, 122 insertions(+), 99 deletions(-) diff --git a/api/__init__.py b/api/__init__.py index 74ba49e4..c498dba2 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -224,7 +224,7 @@ def add_to_log(self, action, info=None, level="info"): log["info"] = strip_tags(info) log["level"] = strip_tags(level) log["created"] = int(time.time()) - self.db.logs.insert(log) + self.db.logs.insert_one(log) class EntityBuilder(object): @@ -250,7 +250,7 @@ def delete(self, token): return try: - result = self.db.tokens.remove({"token": token}) + result = self.db.tokens.delete_one({"token": token}) if result["n"] == 0: self.send_response(NOT_FOUND, dict(status="Token does't exist")) else: @@ -278,7 +278,7 @@ def post(self, devicetoken): else: try: binascii.unhexlify(devicetoken) - except Exception as ex: + except Exception: self.send_response(BAD_REQUEST, dict(error="Invalid token")) else: # if it's not ios then we force FCM type device here @@ -288,18 +288,22 @@ def post(self, devicetoken): token = EntityBuilder.build_token(devicetoken, device, self.appname, channel) try: - result = self.db.tokens.update( + result = self.db.tokens.update_one( {"device": device, "token": devicetoken, "appname": self.appname}, - token, + {"$set": token}, upsert=True, ) # result # {u'updatedExisting': True, u'connectionId': 47, u'ok': 1.0, u'err': None, u'n': 1} - if result["updatedExisting"]: + if result.modified_count > 0: self.send_response(OK, dict(status="token exists")) - else: + elif result.upserted_id is not None: self.send_response(OK, dict(status="ok")) self.add_to_log("Add token", devicetoken) + elif result.matched_count > 0: + self.send_response(OK, dict(status="ok")) + self.add_to_log("No update because of same token", devicetoken) + except Exception as ex: self.add_to_log("Cannot add token", devicetoken, "warning") self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) @@ -325,7 +329,7 @@ def post(self): if cursor: self.send_response(BAD_REQUEST, dict(error="email already exists")) else: - userid = self.db.users.insert(user) + userid = self.db.users.insert_one(user) self.add_to_log("Add user", email) self.send_response(OK, {"userid": str(userid)}) except Exception as ex: @@ -372,7 +376,7 @@ def delete(self, classname, objectId): """ self.classname = classname self.objectid = ObjectId(objectId) - result = self.db[self.collection].remove({"_id": self.objectid}) + result = self.db[self.collection].delete_one({"_id": self.objectid}) self.send_response(OK, dict(result=result)) def put(self, classname, objectId): @@ -381,7 +385,7 @@ def put(self, classname, objectId): self.classname = classname data = json_decode(self.request.body) self.objectid = ObjectId(objectId) - result = self.db[self.collection].update({"_id": self.objectid}, data) + result = self.db[self.collection].update_one({"_id": self.objectid}, {"$set": data}) @property def collection(self): @@ -404,7 +408,7 @@ def collection(self): col["collection"] = self.classname col["created"] = int(time.time()) self.add_to_log("Register collection", self.classname) - self.db.objects.insert(col) + self.db.objects.insert_one(col) collectionname = "%s%s" % (options.collectionprefix, self.classname) return collectionname @@ -439,8 +443,8 @@ def post(self, classname): self.send_response(BAD_REQUEST, ex) self.add_to_log("Add object to %s" % self.classname, data) - objectId = self.db[self.collection].insert(data) - self.send_response(OK, dict(objectId=objectId)) + object_id = self.db[self.collection].insert_one(data) + self.send_response(OK, dict(objectId=object_id)) @route(r"/accesskeys/") @@ -470,7 +474,7 @@ def post(self): | API_PERMISSIONS["send_broadcast"][0] ) key["key"] = md5(str(uuid.uuid4())).hexdigest() - self.db.keys.insert(key) + self.db.keys.insert_one(key) self.send_response(OK, dict(accesskey=key["key"])) def verify_request(self): diff --git a/api/accesskeys.py b/api/accesskeys.py index b385d7f5..dccbf535 100644 --- a/api/accesskeys.py +++ b/api/accesskeys.py @@ -38,7 +38,7 @@ from api import APIBaseHandler from routes import route -from util import * +from util import create_access_key, json_decode @route(r"/api/v2/accesskeys[\/]?") @@ -74,7 +74,7 @@ def post(self): key["created"] = int(time.time()) key["permission"] = data["permission"] key["key"] = create_access_key() - self.db.keys.insert(key) + self.db.keys.insert_one(key) self.send_response(OK, dict(accesskey=key["key"])) except Exception as ex: self.send_response(FORBIDDEN, dict(error=str(ex))) diff --git a/api/tokens.py b/api/tokens.py index 24f203a2..18ff899a 100644 --- a/api/tokens.py +++ b/api/tokens.py @@ -46,7 +46,7 @@ def delete(self, token): return try: - result = self.db.tokens.remove({"token": token}) + result = self.db.tokens.delete_one({"token": token}) if result["n"] == 0: self.send_response(NOT_FOUND, dict(status="Token does't exist")) else: @@ -76,23 +76,27 @@ def post(self): return try: binascii.unhexlify(devicetoken) - except Exception as ex: + except Exception: self.send_response(BAD_REQUEST, dict(error="Invalid token")) token = EntityBuilder.build_token(devicetoken, device, self.appname, channel) try: - result = self.db.tokens.update( + result = self.db.tokens.update_one( {"device": device, "token": devicetoken, "appname": self.appname}, - token, + {"$set": token}, upsert=True, ) # result # {u'updatedExisting': True, u'connectionId': 47, u'ok': 1.0, u'err': None, u'n': 1} - if result["updatedExisting"]: + print(result) + if result.modified_count > 0: self.add_to_log("Token exists", devicetoken) self.send_response(OK) - else: + elif result.upserted_id is not None: self.add_to_log("Add token", devicetoken) self.send_response(OK) + elif result.matched_count > 0: + self.add_to_log("No update because of same token", devicetoken) + self.send_response(OK) except Exception as ex: self.send_response(INTERNAL_SERVER_ERROR, dict(error=str(ex))) diff --git a/controllers/base.py b/controllers/base.py index 12747d2a..01c1a22c 100644 --- a/controllers/base.py +++ b/controllers/base.py @@ -28,14 +28,15 @@ from routes import route import platform +import sys +import os import tornado.web import time from constants import DEVICE_TYPE_IOS, VERSION from pymongo import DESCENDING -from util import * +from util import get_password from tornado.options import options -from dao import Dao -import sys +from bson import ObjectId def buildUpdateFields(params): @@ -46,7 +47,7 @@ def buildUpdateFields(params): def normalize_tokens(tokens): for token in tokens: - if not "device" in token: + if "device" not in token: token["device"] = DEVICE_TYPE_IOS return tokens @@ -107,11 +108,11 @@ def currentuser(self): def get_current_user(self): """ Get current user from cookie """ - userid = self.get_secure_cookie("user") - if not userid: + cookie_user_id = self.get_secure_cookie("user") + if not cookie_user_id: return None - userId = ObjectId(userid.decode("utf-8")) - user = self.masterdb.managers.find_one({"_id": userId}) + user_id = ObjectId(cookie_user_id.decode("utf-8")) + user = self.masterdb.managers.find_one({"_id": user_id}) return user def render_string(self, template_name, **kwargs): @@ -151,7 +152,7 @@ def post(self, appname): app = self.masterdb.applications.find_one({"shortname": appname}) if not app: raise tornado.web.HTTPError(500) - self.masterdb.applications.remove({"shortname": appname}) + self.masterdb.applications.delete_one({"shortname": appname}) self.mongodbconnection.drop_database(appname) self.redirect(r"/applications") @@ -182,7 +183,7 @@ def post(self, appname): self.appname = appname now = int(time.time()) thirtydaysago = now - 60 * 60 * 24 * 30 - self.db.logs.remove({"created": {"$lt": thirtydaysago}}) + self.db.logs.delete_one({"created": {"$lt": thirtydaysago}}) self.redirect(r"/applications/%s/logs" % appname) @@ -264,7 +265,7 @@ def get(self, action): if self.get_argument("delete", None): user_id = self.get_argument("delete", None) if user_id: - self.masterdb.managers.remove({"_id": ObjectId(user_id)}) + self.masterdb.managers.delete_one({"_id": ObjectId(user_id)}) self.redirect("/admin/managers") return currentuser_orgid = self.currentuser["orgid"] @@ -296,11 +297,11 @@ def post(self, action): user["orgid"] = int(self.get_argument("orgid", 0)) else: user["orgid"] = currentuser_orgid - result = self.masterdb.managers.update( - {"email": user["email"]}, user, upsert=True + result = self.masterdb.managers.update_one( + {"email": user["email"]}, {"$set": user}, upsert=True ) managers = self.masterdb.managers.find() - if result["updatedExisting"]: + if result.modified_count > 0: self.render( "managers.html", managers=managers, @@ -319,7 +320,7 @@ def post(self, action): elif action == "changepassword": password = self.get_argument("newpassword").strip() passwordhash = get_password(password, options.passwordsalt) - self.masterdb.managers.update( + self.masterdb.managers.update_one( {"email": self.currentuser["email"]}, {"$set": {"password": passwordhash}}, ) diff --git a/controllers/keys.py b/controllers/keys.py index 14058a32..45a74a8e 100644 --- a/controllers/keys.py +++ b/controllers/keys.py @@ -28,9 +28,11 @@ import sys, os import tornado.web from api import API_PERMISSIONS -from controllers.base import * -from util import * +from controllers.base import WebBaseHandler +from util import create_access_key +from routes import route import logging +import time @route(r"/applications/([^/]+)/keys") @@ -55,7 +57,7 @@ def get(self, appname): ) return if key_to_be_deleted: - self.db.keys.remove({"key": key_to_be_deleted}) + self.db.keys.delete_one({"key": key_to_be_deleted}) self.redirect("/applications/%s/keys" % appname) self.render( "app_keys.html", @@ -87,9 +89,9 @@ def post(self, appname): # Alternative key generator, this is SHORT # crc = binascii.crc32(str(uuid.uuid4())) & 0xffffffff # key['key'] = '%08x' % crc - keyObjectId = self.db.keys.insert(key) + self.db.keys.insert_one(key) self.redirect("/applications/%s/keys" % appname) else: key["key"] = self.get_argument("accesskey").strip() - self.db.keys.update({"key": key["key"]}, key) + self.db.keys.update_one({"key": key["key"]}, {"$set": key}) self.redirect("/applications/%s/keys" % appname) diff --git a/controllers/newapp.py b/controllers/newapp.py index 9b4c8a3e..7d842481 100644 --- a/controllers/newapp.py +++ b/controllers/newapp.py @@ -27,9 +27,10 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import tornado.web -from controllers.base import * +from controllers.base import WebBaseHandler from util import filter_alphabetanum - +from pymongo import DESCENDING +from routes import route from constants import ( DEVICE_TYPE_IOS, VERSION, @@ -82,7 +83,7 @@ def post(self): current_app = self.masterdb.applications.find_one({"shortname": self.appname}) if not current_app: - self.masterdb.applications.insert(app) + self.masterdb.applications.insert_one(app) indexes = [("created", DESCENDING)] self.db["tokens"].create_index(indexes) self.db["logs"].create_index(indexes) diff --git a/controllers/tokens.py b/controllers/tokens.py index 3ba5098c..2f492429 100644 --- a/controllers/tokens.py +++ b/controllers/tokens.py @@ -27,8 +27,10 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import tornado.web - -from controllers.base import * +from bson import ObjectId +from controllers.base import WebBaseHandler +from pymongo import DESCENDING +from routes import route @route(r"/applications/([^/]+)/tokens") @@ -44,7 +46,7 @@ def get(self, appname): token_id = self.get_argument("delete", None) if token_id: - self.db.tokens.remove({"_id": ObjectId(token_id)}) + self.db.tokens.delete_one({"_id": ObjectId(token_id)}) self.redirect("/applications/%s/tokens" % appname) return if page: diff --git a/dao.py b/dao.py index 9cceae2b..792b010d 100644 --- a/dao.py +++ b/dao.py @@ -1,4 +1,5 @@ from typing import Dict +from bson import ObjectId import logging @@ -19,11 +20,12 @@ def find_app_by_name(self, name): return self.masterdb.applications.find_one({"shortname": name}) def update_app_by_name(self, name: str, app: Dict[str, str]): - self.masterdb.applications.update({"shortname": name}, app) + values = {"$set": app} + self.masterdb.applications.update_one({"shortname": name}, values) def find_token(self, token): logging.info("find token: %s" % token) return self.db.tokens.find_one({"token": token}) def add_token(self, token: Dict[str, str]): - return self.db.tokens.insert(token) + return self.db.tokens.insert_one(token) diff --git a/install.py b/install.py index 4de566bb..12ba730d 100755 --- a/install.py +++ b/install.py @@ -31,7 +31,7 @@ from os import path from pymongo.errors import CollectionInvalid from tornado.options import define, options -from util import * +from util import get_password import logging import pymongo import tornado.options @@ -61,9 +61,9 @@ mongodb = pymongo.MongoClient(options.mongouri) masterdb = mongodb[options.masterdb] - collection_names = masterdb.collection_names() + collection_names = masterdb.list_collection_names() try: - if not "applications" in collection_names: + if "applications" not in collection_names: masterdb.create_collection("applications") logging.info("db.applications installed") except CollectionInvalid as ex: @@ -71,10 +71,10 @@ pass try: - if not "managers" in collection_names: + if "managers" not in collection_names: masterdb.create_collection("managers") # masterdb.managers.ensure_index("username", unique=True) - masterdb.managers.ensure_index("email", unique=True) + masterdb.managers.create_index([('email', pymongo.ASCENDING)], unique=True) logging.info("db.managers installed") try: user = masterdb.managers.find_one({"email": EMAIL}) @@ -85,7 +85,7 @@ DEFAULTPASSWORD, options.passwordsalt ) manager["orgid"] = 0 - masterdb["managers"].insert(manager) + masterdb["managers"].insert_one(manager) logging.info( "Admin user created, username: %s, password: %s" % (EMAIL, DEFAULTPASSWORD) @@ -98,7 +98,7 @@ pass try: - if not "options" in collection_names: + if "options" not in collection_names: masterdb.create_collection("options") logging.info("db.options installed") try: @@ -107,7 +107,7 @@ option_ver = {} option_ver["name"] = "version" option_ver["value"] = VERSION - masterdb["options"].insert(option_ver) + masterdb["options"].insert_one(option_ver) logging.info(("Version number written: %s" % VERSION)) except Exception: logging.error("Failed to write version number") diff --git a/pushservices/gcm.py b/pushservices/gcm.py index 8abff1ce..1bb72fa8 100644 --- a/pushservices/gcm.py +++ b/pushservices/gcm.py @@ -218,4 +218,4 @@ def add_to_log(self, appdb, action, info=None, level="info"): log["level"] = strip_tags(level) log["created"] = int(time.time()) if appdb is not None: - appdb.logs.insert(log) + appdb.logs.insert_one(log) diff --git a/pushservices/wns.py b/pushservices/wns.py index 6768dabc..a74a08e6 100644 --- a/pushservices/wns.py +++ b/pushservices/wns.py @@ -109,8 +109,8 @@ def request_token(self): accesstoken = responsedata["access_token"] self.app["wnsaccesstoken"] = accesstoken self.app["wnstokenexpiry"] = int(responsedata["expires_in"]) + int(time.time()) - self.masterdb.applications.update( - {"shortname": self.app["shortname"]}, self.app + self.masterdb.applications.update_one( + {"shortname": self.app["shortname"]}, {"$set": self.app} ) return accesstoken diff --git a/tests/test_push.py b/tests/test_push.py index ca2a8c37..289fccef 100644 --- a/tests/test_push.py +++ b/tests/test_push.py @@ -23,7 +23,7 @@ def __init__(self): def find_one(self, xxx): return {"permission": 31} - def insert(self, xxx): + def insert_one(self, xxx): pass diff --git a/upgrade.py b/upgrade.py index 5c647de4..7432e674 100755 --- a/upgrade.py +++ b/upgrade.py @@ -30,9 +30,15 @@ import tornado import os import pymongo -from bson import * -from constants import * +from bson import ObjectId from tornado.options import define, options +from constants import ( + DEVICE_TYPE_IOS, + KEY_APNS_AUTHKEY, + KEY_APNS_BUNDLEID, + KEY_APNS_KEYID, + KEY_APNS_TEAMID, +) define("mongouri", default="mongodb://localhost:27017/", help="MongoDB host name") define("masterdb", default="airnotifier", help="MongoDB DB to store information") @@ -56,27 +62,28 @@ for app in apps: appname = app["shortname"] appid = ObjectId(app["_id"]) - ## Repair application setting collection - if not "blockediplist" in app: + # Repair application setting collection + if "blockediplist" not in app: app["blockediplist"] = "" - if not "description" in app: + if "description" not in app: app["description"] = "" - if not "gcmprojectnumber" in app: + if "gcmprojectnumber" not in app: app["gcmprojectnumber"] = "" - if not "gcmapikey" in app: + if "gcmapikey" not in app: app["gcmapikey"] = "" - masterdb.applications.update({"_id": appid}, app, upsert=True) + masterdb.applications.update_one({"_id": appid}, {"$set": app}, upsert=True) - ## Adding device to token collections + # Adding device to token collections db = mongodb[appprefix + appname] tokens = db["tokens"].find() for token in tokens: tokenid = ObjectId(token["_id"]) - if not "device" in token: + if "device" not in token: token["device"] = DEVICE_TYPE_IOS - result = db["tokens"].update({"_id": tokenid}, token, upsert=True) + result = db["tokens"].update_one( + {"_id": tokenid}, {"$set": token}, upsert=True) - r = masterdb["options"].update( + r = masterdb["options"].update_one( {"name": "version"}, {"$set": {"value": 20140315}}, upsert=True ) version_object = masterdb["options"].find_one({"name": "version"}) @@ -86,24 +93,24 @@ for app in apps: appname = app["shortname"] appid = ObjectId(app["_id"]) - ## Repair application setting collection - if not "wnsclientid" in app: + # Repair application setting collection + if "wnsclientid" not in app: app["wnsclientid"] = "" - if not "wnsclientsecret" in app: + if "wnsclientsecret" not in app: app["wnsclientsecret"] = "" - if not "wnsaccesstoken" in app: + if "wnsaccesstoken" not in app: app["wnsaccesstoken"] = "" - if not "wnstokentype" in app: + if "wnstokentype" not in app: app["wnstokentype"] = "" - if not "wnstokenexpiry" in app: + if "wnstokenexpiry" not in app: app["wnstokenexpiry"] = "" - masterdb.applications.update_one({"_id": appid}, app, upsert=True) + masterdb.applications.update_one({"_id": appid}, {"$set": app}, upsert=True) masterdb["options"].update_one( {"name": "version"}, {"$set": {"value": 20140720}}, upsert=True ) if version < 20140814: - ## Don't store fullpath in db, only filename + # Don't store fullpath in db, only filename import os apps = masterdb.applications.find() @@ -118,7 +125,7 @@ app["mpnscertificatefile"] = os.path.basename( app.get("mpnscertificatefile") ) - masterdb.applications.update_one({"_id": appid}, app, upsert=True) + masterdb.applications.update_one({"_id": appid}, {"$set": app}, upsert=True) masterdb["options"].update_one( {"name": "version"}, {"$set": {"value": 20140814}}, upsert=True ) @@ -128,14 +135,14 @@ for app in apps: appname = app["shortname"] appid = ObjectId(app["_id"]) - ## Repair application setting collection - if not "clickatellusername" in app: + # Repair application setting collection + if "clickatellusername" not in app: app["clickatellusername"] = "" - if not "clickatellpassword" in app: + if "clickatellpassword" not in app: app["clickatellpassword"] = "" - if not "clickatellappid" in app: + if "clickatellappid" not in app: app["clickatellappid"] = "" - masterdb.applications.update_one({"_id": appid}, app, upsert=True) + masterdb.applications.update_one({"_id": appid}, {"$set": app}, upsert=True) masterdb["options"].update_one( {"name": "version"}, {"$set": {"value": 20140820}}, upsert=True ) @@ -145,7 +152,7 @@ for app in apps: appname = app["shortname"] db = mongodb[appprefix + appname] - indexes = [("created", DESCENDING)] + indexes = [("created", pymongo.DESCENDING)] logging.info( ("Adding index to %s%s['tokens'].%s" % (appprefix, appname, "created")) ) @@ -169,18 +176,18 @@ for user in users: # appname = app["shortname"] # Repair application setting collection - if not "orgid" in user: + if "orgid" not in user: masterdb.managers.find_one_and_update( {"username": user["username"]}, {"$set": {"orgid": 0}} ) - if not "email" in user: + if "email" not in user: masterdb.managers.find_one_and_update( {"username": user["username"]}, {"$set": {"email": user["username"]}}, ) apps = masterdb.applications.find() for app in apps: - if not "orgid" in app: + if "orgid" not in app: masterdb.applications.find_one_and_update( {"shortname": app["shortname"]}, {"$set": {"orgid": 0}} ) @@ -195,7 +202,7 @@ {"name": "version"}, {"$set": {"value": 20190825}}, upsert=True ) if version < 20191117: - masterdb.managers.ensure_index("email", unique=True) + masterdb.managers.create_index([('email', pymongo.ASCENDING)], unique=True) try: masterdb.managers.drop_index("user") except Exception as ex: @@ -209,16 +216,16 @@ for app in apps: appname = app["shortname"] appid = ObjectId(app["_id"]) - if not KEY_APNS_AUTHKEY in app: + if KEY_APNS_AUTHKEY not in app: app[KEY_APNS_AUTHKEY] = "" - if not KEY_APNS_BUNDLEID in app: + if KEY_APNS_BUNDLEID not in app: app[KEY_APNS_BUNDLEID] = "" - if not KEY_APNS_KEYID in app: + if KEY_APNS_KEYID not in app: app[KEY_APNS_KEYID] = "" - if not KEY_APNS_TEAMID in app: + if KEY_APNS_TEAMID not in app: app[KEY_APNS_TEAMID] = "" - masterdb.applications.update({"_id": appid}, app, upsert=True) - masterdb.applications.update( + masterdb.applications.update_one({"_id": appid}, {"$set": app}, upsert=True) + masterdb.applications.update_one( {"_id": appid}, { "$unset": {