diff --git a/nonebot_plugin_tetris_stats/GameDataProcessor/TOPDataProcessor.py b/nonebot_plugin_tetris_stats/GameDataProcessor/TOPDataProcessor.py new file mode 100644 index 0000000..e6ca348 --- /dev/null +++ b/nonebot_plugin_tetris_stats/GameDataProcessor/TOPDataProcessor.py @@ -0,0 +1,148 @@ +from nonebot import on_regex +from nonebot.adapters.onebot.v11 import GROUP, MessageEvent +from nonebot.matcher import Matcher +from nonebot.log import logger + +from typing import Any +from re import I +from lxml import etree +from pandas import read_html +import aiohttp + +from ..Utils.MessageAnalyzer import handleBindMessage, handleStatsQueryMessage +from ..Utils.SQL import queryBindInfo, writeBindInfo + +topBind = on_regex(pattern=r'^top绑定|^topbind', flags=I, permission=GROUP) +topStats = on_regex(pattern=r'^top查|^topstats', flags=I, permission=GROUP) + + +@topBind.handle() +async def _(event: MessageEvent, matcher: Matcher): + decodedMessage = await handleBindMessage(message=event.raw_message, gameType='TOP') + if decodedMessage[0] is None: + await matcher.finish(decodedMessage[1][0]) + elif decodedMessage[0] == 'Name': + userData = await getUserData(decodedMessage[1][1]) + if userData[0] is False: + await matcher.finish('用户信息请求失败') + else: + if await checkUser(userData[1]) is False: + matcher.finish('用户不存在') + userName = await getUserName(userData[1]) + if event.sender.user_id is None: # 理论上是不会有None出现的,ide快乐行属于是( + logger.error('获取QQ号失败') + await matcher.finish('获取QQ号失败') + await matcher.finish(await writeBindInfo(QQNumber=event.sender.user_id, user=userName, gameType='TOP')) + + +@topStats.handle() +async def _(event: MessageEvent, matcher: Matcher): + decodedMessage = await handleStatsQueryMessage(message=event.raw_message, gameType='TOP') + if decodedMessage[0] is None: + await matcher.finish(decodedMessage[1][0]) + elif decodedMessage[0] == 'AT': + if event.is_tome() is True: + await matcher.finish(message='不能查询bot的信息') + bindInfo = await queryBindInfo(QQNumber=decodedMessage[1][1], gameType='TOP') + if bindInfo is None: + message = '未查询到绑定信息' + else: + message = (f'* 由于无法验证绑定信息,不能保证查询到的用户为本人\n{await generateMessage(bindInfo)}') + elif decodedMessage[0] == 'ME': + if event.sender.user_id is None: + logger.error('获取QQ号失败') + await matcher.finish('获取QQ号失败,请联系bot主人') + bindInfo = await queryBindInfo(QQNumber=event.sender.user_id, gameType='TOP') + if bindInfo is None: + message = '未查询到绑定信息' + else: + message = (f'* 由于无法验证绑定信息,不能保证查询到的用户为本人\n{await generateMessage(bindInfo)}') + elif decodedMessage[0] == 'Name': + message = await generateMessage(decodedMessage[1][1]) + await matcher.finish(message=message) + + +async def getUserData(userName: str) -> tuple[bool, str]: + Url = f'http://tetrisonline.pl/top/profile.php?user={userName}' + # 因为top查数据没有api 所以不得不再写一次请求( + try: + async with aiohttp.ClientSession() as session: + async with session.get(Url) as resp: + return (True, await resp.text()) + except aiohttp.client_exceptions.ClientConnectorError as e: + logger.error(e) + return (False, '') + + +async def checkUser(userData: str) -> bool: + return True if userData.find('user not found!') else False + + +async def getUserName(userData: str) -> str: + return etree.HTML(userData).xpath('//div[@class="mycontent"]/h1/text()')[0].replace('\'s profile', '') + + +async def getGameStats(userData: str) -> dict[str, Any]: + gameStats = {} + html = etree.HTML(userData) + for i in html.xpath('//div[@class="mycontent"]//text()'): + i = i.strip() + if i.startswith('lpm:'): + gameStats['24HStats'] = True + gameStats['24HLPM'] = i.replace('lpm:', '').strip() + elif i.startswith('apm:'): + gameStats['24HStats'] = True + gameStats['24HAPM'] = i.replace('apm:', '').strip() + if '24HLPM' in gameStats and '24HAPM' in gameStats: + break + # 如果没有24H统计数据 + if gameStats.get('24HLPM') in [None, ''] or gameStats.get('24HAPM') in [None, '']: + gameStats.pop('24HLPM') + gameStats.pop('24HAPM') + gameStats['24HStats'] = False + else: + gameStats['24HPPS'] = round(float(gameStats['24HLPM']) / 24, 2) + gameStats['24HAPL'] = round( + float(gameStats['24HAPM']) / float(gameStats['24HLPM']), 2) + gameStats['24HLPM'] = round(float(gameStats['24HLPM']), 2) + gameStats['24HAPM'] = round(float(gameStats['24HAPM']), 2) + statsTable = html.xpath('//table') + statsTable = etree.tostring(statsTable[0], encoding='utf-8').decode() + df = read_html(statsTable, encoding='utf-8', header=0)[0] + results = list(df.T.to_dict().values()) + if results != []: + gameStats['AllStats'] = True + gameStats['AllLPM'] = 0 + gameStats['AllAPM'] = 0 + for i in results: + gameStats['AllLPM'] += i['lpm'] + gameStats['AllAPM'] += i['apm'] + gameStats['AllLPM'] = gameStats['AllLPM'] / len(results) + gameStats['AllAPM'] = gameStats['AllAPM'] / len(results) + gameStats['AllPPS'] = round(gameStats['AllLPM'] / 24, 2) + gameStats['AllAPL'] = round( + float(gameStats['AllAPM']) / float(gameStats['AllLPM']), 2) + gameStats['AllLPM'] = round(float(gameStats['AllLPM']), 2) + gameStats['AllAPM'] = round(float(gameStats['AllAPM']), 2) + else: + gameStats['AllStats'] = False + return gameStats + + +async def generateMessage(userName: str) -> str: + userData = await getUserData(userName) + if userData[0] is False: + return '用户信息请求失败' + if await checkUser(userData[1]) is False: + return '用户不存在' + userName = await getUserName(userData[1]) + gameStats = await getGameStats(userData[1]) + if gameStats['24HStats'] is False and gameStats['AllStats'] is False: + message = f'用户 {userName} 暂无24小时内统计数据, 暂无历史统计数据' + elif gameStats['24HStats'] is True and gameStats['AllStats'] is False: + message = f'用户 {userName} 24小时内统计数据为: \nL\'PM: {gameStats["24HLPM"]} ( {gameStats["24HPPS"]} pps )\nAPM: {gameStats["24HAPM"]} ( x{gameStats["24HAPL"]} )\n暂无历史统计数据\n(这真的存在吗' + elif gameStats['24HStats'] is False and gameStats['AllStats'] is True: + message = f'用户 {userName} 暂无24小时内统计数据, 历史统计数据为: \nL\'PM: {gameStats["AllLPM"]} ( {gameStats["AllPPS"]} pps )\nAPM: {gameStats["AllAPM"]} ( x{gameStats["AllAPL"]} )' + else: + message = f'用户 {userName} 24小时内统计数据为: \nL\'PM: {gameStats["24HLPM"]} ( {gameStats["24HPPS"]} pps )\nAPM: {gameStats["24HAPM"]} ( x{gameStats["24HAPL"]} )\n历史统计数据为: \nL\'PM: {gameStats["AllLPM"]} ( {gameStats["AllPPS"]} pps )\nAPM: {gameStats["AllAPM"]} ( x{gameStats["AllAPL"]} )' + return message diff --git a/nonebot_plugin_tetris_stats/GameDataProcessor/__init__.py b/nonebot_plugin_tetris_stats/GameDataProcessor/__init__.py index 80027b4..6cadbe9 100644 --- a/nonebot_plugin_tetris_stats/GameDataProcessor/__init__.py +++ b/nonebot_plugin_tetris_stats/GameDataProcessor/__init__.py @@ -1 +1 @@ -from . import IODataProcessor, TOSDataProcessor +from . import IODataProcessor, TOSDataProcessor, TOPDataProcessor diff --git a/poetry.lock b/poetry.lock index 0944ff8..45440dd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -197,6 +197,20 @@ win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] dev = ["colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "black (>=19.10b0)", "isort (>=5.1.1)", "Sphinx (>=4.1.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)"] +[[package]] +name = "lxml" +version = "4.9.1" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["beautifulsoup4"] +source = ["Cython (>=0.29.7)"] + [[package]] name = "multidict" version = "6.0.2" @@ -267,6 +281,30 @@ websockets = ["websockets (>=10.0,<11.0)"] aiohttp = ["aiohttp[speedups] (>=3.7.4,<4.0.0)"] httpx = ["httpx[http2] (>=0.20.0,<1.0.0)"] +[[package]] +name = "numpy" +version = "1.23.1" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.8" + +[[package]] +name = "pandas" +version = "1.4.3" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] + [[package]] name = "pycodestyle" version = "2.8.0" @@ -299,6 +337,17 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + [[package]] name = "python-dotenv" version = "0.20.0" @@ -310,6 +359,14 @@ python-versions = ">=3.5" [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "pytz" +version = "2022.1" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "pyyaml" version = "6.0" @@ -318,6 +375,14 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "sniffio" version = "1.2.0" @@ -453,7 +518,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "a4d410151de3d540ca69d31936bedf6f731720abc4467821224b07bb34048cd1" +content-hash = "3f7b25f78ce3b5584096bf357be823f081e90723eb4814c4daec1f6b5affdf3a" [metadata.files] aiohttp = [ @@ -685,6 +750,7 @@ loguru = [ {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"}, {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"}, ] +lxml = [] multidict = [ {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"}, {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"}, @@ -783,6 +849,53 @@ nonebot2 = [ {file = "nonebot2-2.0.0b3-py3-none-any.whl", hash = "sha256:00f2ea63d5f2c665428bec4b7a33301f6b1b483d5635d2a3241f0a1ab3b5b2ea"}, {file = "nonebot2-2.0.0b3.tar.gz", hash = "sha256:b7ee6ddf387af268e36f4276c2d94b4f717c1a29078400738ca275c3fb266dd4"}, ] +numpy = [ + {file = "numpy-1.23.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b15c3f1ed08df4980e02cc79ee058b788a3d0bef2fb3c9ca90bb8cbd5b8a3a04"}, + {file = "numpy-1.23.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ce242162015b7e88092dccd0e854548c0926b75c7924a3495e02c6067aba1f5"}, + {file = "numpy-1.23.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d7447679ae9a7124385ccf0ea990bb85bb869cef217e2ea6c844b6a6855073"}, + {file = "numpy-1.23.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3119daed207e9410eaf57dcf9591fdc68045f60483d94956bee0bfdcba790953"}, + {file = "numpy-1.23.1-cp310-cp310-win32.whl", hash = "sha256:3ab67966c8d45d55a2bdf40701536af6443763907086c0a6d1232688e27e5447"}, + {file = "numpy-1.23.1-cp310-cp310-win_amd64.whl", hash = "sha256:1865fdf51446839ca3fffaab172461f2b781163f6f395f1aed256b1ddc253622"}, + {file = "numpy-1.23.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeba539285dcf0a1ba755945865ec61240ede5432df41d6e29fab305f4384db2"}, + {file = "numpy-1.23.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e8229f3687cdadba2c4faef39204feb51ef7c1a9b669247d49a24f3e2e1617c"}, + {file = "numpy-1.23.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68b69f52e6545af010b76516f5daaef6173e73353e3295c5cb9f96c35d755641"}, + {file = "numpy-1.23.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1408c3527a74a0209c781ac82bde2182b0f0bf54dea6e6a363fe0cc4488a7ce7"}, + {file = "numpy-1.23.1-cp38-cp38-win32.whl", hash = "sha256:47f10ab202fe4d8495ff484b5561c65dd59177949ca07975663f4494f7269e3e"}, + {file = "numpy-1.23.1-cp38-cp38-win_amd64.whl", hash = "sha256:37e5ebebb0eb54c5b4a9b04e6f3018e16b8ef257d26c8945925ba8105008e645"}, + {file = "numpy-1.23.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:173f28921b15d341afadf6c3898a34f20a0569e4ad5435297ba262ee8941e77b"}, + {file = "numpy-1.23.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:876f60de09734fbcb4e27a97c9a286b51284df1326b1ac5f1bf0ad3678236b22"}, + {file = "numpy-1.23.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35590b9c33c0f1c9732b3231bb6a72d1e4f77872390c47d50a615686ae7ed3fd"}, + {file = "numpy-1.23.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a35c4e64dfca659fe4d0f1421fc0f05b8ed1ca8c46fb73d9e5a7f175f85696bb"}, + {file = "numpy-1.23.1-cp39-cp39-win32.whl", hash = "sha256:c2f91f88230042a130ceb1b496932aa717dcbd665350beb821534c5c7e15881c"}, + {file = "numpy-1.23.1-cp39-cp39-win_amd64.whl", hash = "sha256:37ece2bd095e9781a7156852e43d18044fd0d742934833335599c583618181b9"}, + {file = "numpy-1.23.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8002574a6b46ac3b5739a003b5233376aeac5163e5dcd43dd7ad062f3e186129"}, + {file = "numpy-1.23.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d732d17b8a9061540a10fda5bfeabca5785700ab5469a5e9b93aca5e2d3a5fb"}, + {file = "numpy-1.23.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:55df0f7483b822855af67e38fb3a526e787adf189383b4934305565d71c4b148"}, + {file = "numpy-1.23.1.tar.gz", hash = "sha256:d748ef349bfef2e1194b59da37ed5a29c19ea8d7e6342019921ba2ba4fd8b624"}, +] +pandas = [ + {file = "pandas-1.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d51674ed8e2551ef7773820ef5dab9322be0828629f2cbf8d1fc31a0c4fed640"}, + {file = "pandas-1.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:16ad23db55efcc93fa878f7837267973b61ea85d244fc5ff0ccbcfa5638706c5"}, + {file = "pandas-1.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:958a0588149190c22cdebbc0797e01972950c927a11a900fe6c2296f207b1d6f"}, + {file = "pandas-1.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e48fbb64165cda451c06a0f9e4c7a16b534fcabd32546d531b3c240ce2844112"}, + {file = "pandas-1.4.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f803320c9da732cc79210d7e8cc5c8019aad512589c910c66529eb1b1818230"}, + {file = "pandas-1.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:2893e923472a5e090c2d5e8db83e8f907364ec048572084c7d10ef93546be6d1"}, + {file = "pandas-1.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:24ea75f47bbd5574675dae21d51779a4948715416413b30614c1e8b480909f81"}, + {file = "pandas-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ebc990bd34f4ac3c73a2724c2dcc9ee7bf1ce6cf08e87bb25c6ad33507e318"}, + {file = "pandas-1.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d6c0106415ff1a10c326c49bc5dd9ea8b9897a6ca0c8688eb9c30ddec49535ef"}, + {file = "pandas-1.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78b00429161ccb0da252229bcda8010b445c4bf924e721265bec5a6e96a92e92"}, + {file = "pandas-1.4.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dfbf16b1ea4f4d0ee11084d9c026340514d1d30270eaa82a9f1297b6c8ecbf0"}, + {file = "pandas-1.4.3-cp38-cp38-win32.whl", hash = "sha256:48350592665ea3cbcd07efc8c12ff12d89be09cd47231c7925e3b8afada9d50d"}, + {file = "pandas-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:605d572126eb4ab2eadf5c59d5d69f0608df2bf7bcad5c5880a47a20a0699e3e"}, + {file = "pandas-1.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a3924692160e3d847e18702bb048dc38e0e13411d2b503fecb1adf0fcf950ba4"}, + {file = "pandas-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:07238a58d7cbc8a004855ade7b75bbd22c0db4b0ffccc721556bab8a095515f6"}, + {file = "pandas-1.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:755679c49460bd0d2f837ab99f0a26948e68fa0718b7e42afbabd074d945bf84"}, + {file = "pandas-1.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41fc406e374590a3d492325b889a2686b31e7a7780bec83db2512988550dadbf"}, + {file = "pandas-1.4.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d9382f72a4f0e93909feece6fef5500e838ce1c355a581b3d8f259839f2ea76"}, + {file = "pandas-1.4.3-cp39-cp39-win32.whl", hash = "sha256:0daf876dba6c622154b2e6741f29e87161f844e64f84801554f879d27ba63c0d"}, + {file = "pandas-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:721a3dd2f06ef942f83a819c0f3f6a648b2830b191a72bbe9451bcd49c3bd42e"}, + {file = "pandas-1.4.3.tar.gz", hash = "sha256:2ff7788468e75917574f080cd4681b27e1a7bf36461fe968b49a87b5a54d007c"}, +] pycodestyle = [ {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, @@ -827,10 +940,18 @@ pydantic = [ pygtrie = [ {file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"}, ] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] python-dotenv = [ {file = "python-dotenv-0.20.0.tar.gz", hash = "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f"}, {file = "python_dotenv-0.20.0-py3-none-any.whl", hash = "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938"}, ] +pytz = [ + {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, + {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, +] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, @@ -866,6 +987,10 @@ pyyaml = [ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] sniffio = [ {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, diff --git a/pyproject.toml b/pyproject.toml index 8bf50c8..f2706a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,8 @@ nonebot-adapter-onebot = "^2.0.0-beta.1" aiohttp = "^3.8.1" asyncio = "^3.4.3" nonebot2 = "^2.0.0-beta.3" +lxml = "^4.9.1" +pandas = "^1.4.3" [tool.poetry.dev-dependencies] mypy = "^0.950"