From 289f164a0c4c67d1efffa94f72ff788cfe7ce560 Mon Sep 17 00:00:00 2001 From: xtaodada Date: Sun, 8 Sep 2024 23:11:32 +0800 Subject: [PATCH] :sparkles: Gacha Log Online View --- modules/gacha_log/error.py | 12 ++++ modules/gacha_log/log.py | 3 +- modules/gacha_log/online_view.py | 82 +++++++++++++++++++++++++++ pdm.lock | 96 ++++++++++++++++---------------- plugins/admin/set_command.py | 1 + plugins/zzz/signal_log.py | 75 ++++++++++++++++++++----- pyproject.toml | 6 +- requirements.txt | 16 +++--- 8 files changed, 218 insertions(+), 73 deletions(-) create mode 100644 modules/gacha_log/online_view.py diff --git a/modules/gacha_log/error.py b/modules/gacha_log/error.py index 27bd05e..62b7e56 100644 --- a/modules/gacha_log/error.py +++ b/modules/gacha_log/error.py @@ -35,3 +35,15 @@ class PaimonMoeGachaLogFileError(GachaLogFileError): super().__init__("Paimon.Moe version not supported") self.support_version = support_version self.file_version = file_version + + +class GachaLogWebError(GachaLogException): + pass + + +class GachaLogWebNotConfigError(GachaLogWebError): + pass + + +class GachaLogWebUploadError(GachaLogWebError): + pass diff --git a/modules/gacha_log/log.py b/modules/gacha_log/log.py index 4eb717c..e3e3e96 100644 --- a/modules/gacha_log/log.py +++ b/modules/gacha_log/log.py @@ -34,6 +34,7 @@ from modules.gacha_log.models import ( ZZZGFItem, ZZZGFModel, ) +from modules.gacha_log.online_view import GachaLogOnlineView from utils.const import PROJECT_ROOT from utils.uid import mask_number @@ -45,7 +46,7 @@ GACHA_LOG_PATH = PROJECT_ROOT.joinpath("data", "apihelper", "signal_log") GACHA_LOG_PATH.mkdir(parents=True, exist_ok=True) -class GachaLog: +class GachaLog(GachaLogOnlineView): def __init__(self, gacha_log_path: Path = GACHA_LOG_PATH): self.gacha_log_path = gacha_log_path diff --git a/modules/gacha_log/online_view.py b/modules/gacha_log/online_view.py new file mode 100644 index 0000000..2c98ea7 --- /dev/null +++ b/modules/gacha_log/online_view.py @@ -0,0 +1,82 @@ +from pathlib import Path +from typing import Optional + +import httpx +from httpx import URL +from httpx import HTTPError +from telegram import InlineKeyboardMarkup, InlineKeyboardButton +from telegram.helpers import create_deep_linked_url + +from gram_core.basemodel import Settings +from modules.gacha_log.error import GachaLogWebNotConfigError, GachaLogWebUploadError, GachaLogNotFound + + +class GachaLogWebConfig(Settings): + """抽卡记录在线查询配置""" + + url: Optional[str] = "" + token: Optional[str] = "" + + class Config(Settings.Config): + env_prefix = "gacha_log_web_" + + +gacha_log_web_config = GachaLogWebConfig() +DEFAULT_POOL = "代理人调频" + + +class GachaLogOnlineView: + """抽卡记录在线查询""" + + gacha_log_path: Path + + @staticmethod + def get_web_upload_button(bot_username: str): + if not gacha_log_web_config.url: + return None + return InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + ">> 查询详细信息 <<", url=create_deep_linked_url(bot_username, "gacha_log_online_view") + ) + ] + ] + ) + + async def web_upload(self, user_id: str, uid: str) -> str: + if not gacha_log_web_config.url: + raise GachaLogWebNotConfigError + file_path = self.gacha_log_path / f"{user_id}-{uid}.json" + if not file_path.exists(): + raise GachaLogNotFound + async with httpx.AsyncClient() as client: + with open(file_path, "rb") as file: + try: + req = await client.post( + URL(gacha_log_web_config.url).join("upload"), + files={"file": file}, + data={ + "token": gacha_log_web_config.token, + "uid": uid, + "game": "zzz", + }, + ) + req.raise_for_status() + except HTTPError as e: + raise GachaLogWebUploadError from e + account_id = req.json()["account_id"] + url = ( + URL(gacha_log_web_config.url) + .join("gacha_log") + .copy_merge_params( + { + "account_id": account_id, + "banner_type": DEFAULT_POOL, + "rarities": "3,4,5", + "size": 100, + "page": 1, + } + ) + ) + return str(url) diff --git a/pdm.lock b/pdm.lock index 9adb811..d66cde4 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "genshin-artifact", "pyro", "test"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:3d416a652e7aa7b7015ac8405e7f32746effdf357ab45d32e337ce15529cdb63" +content_hash = "sha256:6b338c644e19e0b0552cd8c9c23055f9a344bed5650d9037ee7d1a3ae6e9be83" [[metadata.targets]] requires_python = "~=3.8" @@ -632,7 +632,7 @@ files = [ [[package]] name = "cryptography" -version = "43.0.0" +version = "43.0.1" requires_python = ">=3.7" summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." groups = ["default"] @@ -640,33 +640,33 @@ dependencies = [ "cffi>=1.12; platform_python_implementation != \"PyPy\"", ] files = [ - {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, - {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, - {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, - {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, - {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, - {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, - {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, + {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"}, + {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"}, + {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"}, + {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"}, + {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"}, + {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"}, + {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"}, ] [[package]] @@ -674,7 +674,7 @@ name = "enkanetwork-py" version = "1.4.4" requires_python = ">=3.6" git = "https://github.com/PaiGramTeam/EnkaNetwork.py" -revision = "77265cfdee0c0767d08791f28b54d9c105868a93" +revision = "0924cbce3b8b61cee1db33d7bc7a89f34572a048" summary = "Library for fetching JSON data from site https://enka.network/" groups = ["default"] dependencies = [ @@ -724,7 +724,7 @@ files = [ [[package]] name = "fastapi" -version = "0.112.2" +version = "0.114.0" requires_python = ">=3.8" summary = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" groups = ["default"] @@ -734,8 +734,8 @@ dependencies = [ "typing-extensions>=4.8.0", ] files = [ - {file = "fastapi-0.112.2-py3-none-any.whl", hash = "sha256:db84b470bd0e2b1075942231e90e3577e12a903c4dc8696f0d206a7904a7af1c"}, - {file = "fastapi-0.112.2.tar.gz", hash = "sha256:3d4729c038414d5193840706907a41839d839523da6ed0c2811f1168cac1798c"}, + {file = "fastapi-0.114.0-py3-none-any.whl", hash = "sha256:fee75aa1b1d3d73f79851c432497e4394e413e1dece6234f68d3ce250d12760a"}, + {file = "fastapi-0.114.0.tar.gz", hash = "sha256:9908f2a5cc733004de6ca5e1412698f35085cefcbfd41d539245b9edf87b73c1"}, ] [[package]] @@ -997,7 +997,7 @@ files = [ [[package]] name = "httpx" -version = "0.27.0" +version = "0.27.2" requires_python = ">=3.8" summary = "The next generation HTTP client." groups = ["default"] @@ -1009,8 +1009,8 @@ dependencies = [ "sniffio", ] files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, + {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, + {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, ] [[package]] @@ -1830,7 +1830,7 @@ files = [ [[package]] name = "python-telegram-bot" -version = "21.4" +version = "21.5" requires_python = ">=3.8" summary = "We have made you a wrapper you can't refuse" groups = ["default"] @@ -1838,13 +1838,13 @@ dependencies = [ "httpx~=0.27", ] files = [ - {file = "python_telegram_bot-21.4-py3-none-any.whl", hash = "sha256:71ce864130af43b48be70ff0593ef4db31d99d92aa64a2933289b8d544e6e9df"}, - {file = "python_telegram_bot-21.4.tar.gz", hash = "sha256:d4d41f29f2e2c02920a4be75d9c1ecf85ec381bf47bbeb51af5b097e340b8377"}, + {file = "python_telegram_bot-21.5-py3-none-any.whl", hash = "sha256:1bbba653477ba164411622b717a0cfe1eb7843da016348e41df97f96c93f578e"}, + {file = "python_telegram_bot-21.5.tar.gz", hash = "sha256:2d679173072cce8d6b49aac2e438d49dbfc01c1a4ef5658828c2a65951ee830b"}, ] [[package]] name = "python-telegram-bot" -version = "21.4" +version = "21.5" extras = ["ext", "rate-limiter"] requires_python = ">=3.8" summary = "We have made you a wrapper you can't refuse" @@ -1853,14 +1853,14 @@ dependencies = [ "aiolimiter~=1.1.0", "aiolimiter~=1.1.0", "apscheduler~=3.10.4", - "cachetools~=5.3.3", - "python-telegram-bot==21.4", + "cachetools<5.6.0,>=5.3.3", + "python-telegram-bot==21.5", "pytz>=2018.6", "tornado~=6.4", ] files = [ - {file = "python_telegram_bot-21.4-py3-none-any.whl", hash = "sha256:71ce864130af43b48be70ff0593ef4db31d99d92aa64a2933289b8d544e6e9df"}, - {file = "python_telegram_bot-21.4.tar.gz", hash = "sha256:d4d41f29f2e2c02920a4be75d9c1ecf85ec381bf47bbeb51af5b097e340b8377"}, + {file = "python_telegram_bot-21.5-py3-none-any.whl", hash = "sha256:1bbba653477ba164411622b717a0cfe1eb7843da016348e41df97f96c93f578e"}, + {file = "python_telegram_bot-21.5.tar.gz", hash = "sha256:2d679173072cce8d6b49aac2e438d49dbfc01c1a4ef5658828c2a65951ee830b"}, ] [[package]] @@ -2100,7 +2100,7 @@ name = "simnet" version = "0.1.23" requires_python = "<4.0,>=3.8" git = "https://github.com/PaiGramTeam/SIMNet" -revision = "10aa45ddbbadec40769c01206a1266a3e8b9addc" +revision = "1ba4729700d9455014f0fae75c30ccd418190399" summary = "Modern API wrapper for Genshin Impact & Honkai: Star Rail built on asyncio and pydantic." groups = ["default"] dependencies = [ @@ -2220,7 +2220,7 @@ files = [ [[package]] name = "sqlmodel" -version = "0.0.21" +version = "0.0.22" requires_python = ">=3.7" summary = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." groups = ["default"] @@ -2229,8 +2229,8 @@ dependencies = [ "pydantic<3.0.0,>=1.10.13", ] files = [ - {file = "sqlmodel-0.0.21-py3-none-any.whl", hash = "sha256:eca104afe8a643f0764076b29f02e51d19d6b35c458f4c119942960362a4b52a"}, - {file = "sqlmodel-0.0.21.tar.gz", hash = "sha256:b2034c23d930f66d2091b17a4280a9c23a7ea540a71e7fcf9c746d262f06f74a"}, + {file = "sqlmodel-0.0.22-py3-none-any.whl", hash = "sha256:a1ed13e28a1f4057cbf4ff6cdb4fc09e85702621d3259ba17b3c230bfb2f941b"}, + {file = "sqlmodel-0.0.22.tar.gz", hash = "sha256:7d37c882a30c43464d143e35e9ecaf945d88035e20117bf5ec2834a23cbe505e"}, ] [[package]] diff --git a/plugins/admin/set_command.py b/plugins/admin/set_command.py index c85b6e0..4c90b1f 100644 --- a/plugins/admin/set_command.py +++ b/plugins/admin/set_command.py @@ -26,6 +26,7 @@ class SetCommandPlugin(Plugin): BotCommand("signal_log_import", "导入调频记录"), BotCommand("signal_log_export", "导出调频记录"), BotCommand("signal_log_delete", "删除调频记录"), + BotCommand("signal_log_online_view", "调频记录在线浏览"), BotCommand("avatars", "查询角色练度"), BotCommand("player_card", "角色卡片"), BotCommand("agent_detail", "角色详细信息"), diff --git a/plugins/zzz/signal_log.py b/plugins/zzz/signal_log.py index bdbfeda..06e002d 100644 --- a/plugins/zzz/signal_log.py +++ b/plugins/zzz/signal_log.py @@ -27,6 +27,7 @@ from modules.gacha_log.error import ( GachaLogInvalidAuthkey, GachaLogMixedProvider, GachaLogNotFound, + GachaLogWebError, ) from modules.gacha_log.helpers import from_url_get_authkey from modules.gacha_log.log import GachaLog @@ -52,6 +53,11 @@ if TYPE_CHECKING: INPUT_URL, INPUT_FILE, CONFIRM_DELETE = range(10100, 10103) WAITING = f"小{config.notice.bot_name}正在从服务器获取数据,请稍后" WISHLOG_NOT_FOUND = f"{config.notice.bot_name}没有找到你的调频记录,快来私聊{config.notice.bot_name}导入吧~" +WISHLOG_WEB = """调频记录详细信息查询 + +已为您创建一枚令牌,点击下方按钮可直接进行查询。 + +有效期为 1 小时,过期需重新申请。如怀疑泄漏请立即重新申请。""" class WishLogPlugin(Plugin.Conversation): @@ -417,7 +423,9 @@ class WishLogPlugin(Plugin.Conversation): if reply_message.photo: self.wish_photo = reply_message.photo[-1].file_id - async def wish_log_pool_send(self, user_id: int, uid: int, pool_type: "ZZZBannerType", message: "Message"): + async def wish_log_pool_send( + self, user_id: int, uid: int, pool_type: "ZZZBannerType", message: "Message", bot_username: str + ): await message.reply_chat_action(ChatAction.TYPING) png_data = await self.rander_wish_log_analysis(user_id, uid, pool_type) if isinstance(png_data, str): @@ -428,9 +436,11 @@ class WishLogPlugin(Plugin.Conversation): else: await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) if png_data.file_type == FileType.DOCUMENT: - await png_data.reply_document(message, filename="调频统计.png") + await png_data.reply_document( + message, filename="调频统计.png", reply_markup=self.gacha_log.get_web_upload_button(bot_username) + ) else: - await png_data.reply_photo(message) + await png_data.reply_photo(message, reply_markup=self.gacha_log.get_web_upload_button(bot_username)) @handler.command(command="signal_log", block=False) @handler.message(filters=filters.Regex("^调频记录?(光锥|角色|常驻|新手)$"), block=False) @@ -454,7 +464,7 @@ class WishLogPlugin(Plugin.Conversation): if pool_type is None: await self.wish_log_pool_choose(user_id, player_id, message) else: - await self.wish_log_pool_send(user_id, player_id, pool_type, message) + await self.wish_log_pool_send(user_id, player_id, pool_type, message, context.bot.username) except GachaLogNotFound: self.log_user(update, logger.info, "未找到调频记录") buttons = [ @@ -470,7 +480,7 @@ class WishLogPlugin(Plugin.Conversation): ) @handler.callback_query(pattern=r"^get_wish_log\|", block=False) - async def get_wish_log(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None: + async def get_wish_log(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None: callback_query = update.callback_query user = callback_query.from_user message = callback_query.message @@ -502,11 +512,13 @@ class WishLogPlugin(Plugin.Conversation): await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True) return if show_type == "count": - await self.get_wish_log_count(update, user_id, uid, pool) + await self.get_wish_log_count(update, context, user_id, uid, pool) else: - await self.get_wish_log_log(update, user_id, uid, pool) + await self.get_wish_log_log(update, context, user_id, uid, pool) - async def get_wish_log_log(self, update: "Update", user_id: int, uid: int, pool: str): + async def get_wish_log_log( + self, update: "Update", context: "ContextTypes.DEFAULT_TYPE", user_id: int, uid: int, pool: str + ): callback_query = update.callback_query message = callback_query.message @@ -523,12 +535,20 @@ class WishLogPlugin(Plugin.Conversation): await callback_query.answer(text="正在渲染图片中 请稍等 请不要重复点击按钮", show_alert=False) await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) if png_data.file_type == FileType.DOCUMENT: - await png_data.reply_document(message, filename="调频统计.png") + await png_data.reply_document( + message, + filename="调频统计.png", + reply_markup=self.gacha_log.get_web_upload_button(context.bot.username), + ) self.add_delete_message_job(message, delay=1) else: - await png_data.edit_media(message) + await png_data.edit_media( + message, reply_markup=self.gacha_log.get_web_upload_button(context.bot.username) + ) - async def get_wish_log_count(self, update: "Update", user_id: int, uid: int, pool: str): + async def get_wish_log_count( + self, update: "Update", context: "ContextTypes.DEFAULT_TYPE", user_id: int, uid: int, pool: str + ): callback_query = update.callback_query message = callback_query.message @@ -563,10 +583,14 @@ class WishLogPlugin(Plugin.Conversation): ) await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) if document: - await png.reply_document(message, filename="调频统计.png") + await png.reply_document( + message, + filename="调频统计.png", + reply_markup=self.gacha_log.get_web_upload_button(context.bot.username), + ) self.add_delete_message_job(message, delay=1) else: - await png.edit_media(message) + await png.edit_media(message, reply_markup=self.gacha_log.get_web_upload_button(context.bot.username)) async def add_theme_data(self, data: Dict, player_id: int): theme_info = await self.player_info.get_theme_info(player_id) @@ -574,6 +598,31 @@ class WishLogPlugin(Plugin.Conversation): data["background"] = theme_info.name_card return data + @handler.command(command="signal_log_online_view", block=False) + @handler.command(command="start", filters=filters.Regex(r"gacha_log_online_view$"), block=False) + async def command_start_upload_web(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None: + user_id = await self.get_real_user_id(update) + uid, offset = self.get_real_uid_or_offset(update) + message = update.effective_message + self.log_user(update, logger.info, "调频记录在线浏览命令请求") + try: + player_id = await self.get_player_id(user_id, uid, offset) + url = await self.gacha_log.web_upload(user_id, str(player_id)) + await message.reply_text( + WISHLOG_WEB, + parse_mode="html", + reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("点我查看", url=url)]]), + ) + except GachaLogNotFound: + self.log_user(update, logger.info, "未找到调频记录") + buttons = [ + [InlineKeyboardButton("点我导入", url=create_deep_linked_url(context.bot.username, "gacha_log_import"))] + ] + await message.reply_text(WISHLOG_NOT_FOUND, reply_markup=InlineKeyboardMarkup(buttons)) + except GachaLogWebError as e: + logger.error("申请在线查看调频记录失败", exc_info=e) + await message.reply_text("申请在线查看调频记录失败,请联系管理员") + @staticmethod async def get_migrate_data( old_user_id: int, new_user_id: int, old_players: List["Player"] diff --git a/pyproject.toml b/pyproject.toml index 979606f..68cd9ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ dependencies = [ "ujson<6.0.0,>=5.9.0", "Jinja2<4.0.0,>=3.1.2", "python-telegram-bot[ext,rate-limiter]<22.0,>=21.3", - "sqlmodel<1.0.0,>=0.0.21", + "sqlmodel<1.0.0,>=0.0.22", "colorlog<7.0.0,>=6.8.0", "fakeredis<3.0.0,>=2.19.0", "redis<6.0.0,>=5.0.1", @@ -31,14 +31,14 @@ dependencies = [ "enkanetwork-py @ git+https://github.com/PaiGramTeam/EnkaNetwork.py", "lxml<6.0.0,>=5.0.0", "arko-wrapper<1.0.0,>=0.3.0", - "fastapi<1.0.0,>=0.112.0", + "fastapi<1.0.0,>=0.113.0", "uvicorn[standard]<1.0.0,>=0.30.1", "sentry-sdk<3.0.0,>=2.7.0", "GitPython<4.0.0,>=3.1.30", "openpyxl<4.0.0,>=3.1.1", "async-lru<3.0.0,>=2.0.4", "thefuzz<1.0.0,>=0.22.1", - "cryptography<44.0.0,>=43.0.0", + "cryptography<44.0.0,>=43.0.1", "pillow<11.0.0,>=10.0.1", "playwright==1.46.0", "aiosqlite[sqlite]<1.0.0,>=0.20.0", diff --git a/requirements.txt b/requirements.txt index 1bc0fc2..6f56bf8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,12 +27,12 @@ ciso8601==2.3.1 click==8.1.7 colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" colorlog==6.8.2 -cryptography==43.0.0 -enkanetwork-py @ git+https://github.com/PaiGramTeam/EnkaNetwork.py@77265cfdee0c0767d08791f28b54d9c105868a93 +cryptography==43.0.1 +enkanetwork-py @ git+https://github.com/PaiGramTeam/EnkaNetwork.py@0924cbce3b8b61cee1db33d7bc7a89f34572a048 et-xmlfile==1.1.0 exceptiongroup==1.2.2; python_version < "3.11" fakeredis==2.24.1 -fastapi==0.112.2 +fastapi==0.114.0 flaky==3.8.1 frozenlist==1.4.1 gitdb==4.0.11 @@ -41,7 +41,7 @@ greenlet==3.0.3 h11==0.14.0 httpcore==1.0.5 httptools==0.6.1 -httpx==0.27.0 +httpx==0.27.2 idna==3.7 importlib-metadata==8.2.0; python_version < "3.9" importlib-resources==6.4.0; python_version < "3.9" @@ -76,8 +76,8 @@ pytest-asyncio==0.24.0 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 python-genshin-artifact==1.0.9 -python-telegram-bot==21.4 -python-telegram-bot[ext,rate-limiter]==21.4 +python-telegram-bot==21.5 +python-telegram-bot[ext,rate-limiter]==21.5 pytz==2024.1 pyyaml==6.0.1 rapidfuzz==3.9.5 @@ -86,14 +86,14 @@ redis==5.0.8 rich==13.8.0 sentry-sdk==2.13.0 setuptools==72.1.0 -simnet @ git+https://github.com/PaiGramTeam/SIMNet@10aa45ddbbadec40769c01206a1266a3e8b9addc +simnet @ git+https://github.com/PaiGramTeam/SIMNet@1ba4729700d9455014f0fae75c30ccd418190399 six==1.16.0 smmap==5.0.1 sniffio==1.3.1 sortedcontainers==2.4.0 soupsieve==2.5 sqlalchemy==2.0.31 -sqlmodel==0.0.21 +sqlmodel==0.0.22 starlette==0.37.2 tgcrypto==1.2.5 thefuzz==0.22.1