Compare commits

...

5 commits

7 changed files with 221 additions and 37 deletions

View file

@ -5164,3 +5164,5 @@ buffalonews.com##+js(set, lee_trkLinkSrc, noopFunc)
!#if !ext_ublock
!#include uBO%20list%20extensions/LegitimateURLShortener%20—%20AdGuardOnlyEntries.txt
!#endif
$removeparam=utm_from

View file

@ -8,7 +8,7 @@ async def handle_actions(message: Message) -> None:
return
rawtext = message.text
from_user = message.from_user.mention_html(message.sender_chat.title) if message.sender_chat else message.from_user.mention_html()
replied_user = message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else message.reply_to_message.from_user.mention_html()
replied_user = message.reply_to_message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else message.reply_to_message.from_user.mention_html()
# 防止识别成命令而被误触发
if rawtext.replace('/','',1).isascii() or '@' in rawtext:
print(rawtext.replace('/','',1).isascii())
@ -22,7 +22,7 @@ async def handle_actions(message: Message) -> None:
async def handle_reverse_actions(message: Message) -> None:
from_user = message.from_user.mention_html(message.sender_chat.title) if message.sender_chat else message.from_user.mention_html()
replied_user = message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else message.reply_to_message.from_user.mention_html()
replied_user = message.reply_to_message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else message.reply_to_message.from_user.mention_html()
if not config.is_feature_enabled('actions', message.chat.id):
return
await message.reply(f"{from_user}{replied_user if message.reply_to_message else '自己'} {message.text.replace('\\','')}了!",disable_web_page_preview=True)

View file

@ -1,6 +1,9 @@
import aiohttp
import requests
import re
import html
import asyncio
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
from abp.filters import parse_filterlist
from aiogram.types import Message
@ -8,21 +11,49 @@ from aiogram.types import Message
from config import config
def extend_short_urls(url):
""" 扩展短链接 """
r = requests.get(url)
if 'tb.cn' in urlparse(url).hostname:
# 淘宝短链接特殊处理
html_content = r.text
url = extract_tb_url_from_html(html_content)
if not url:
return url
if r.status_code != 200:
return url
elif r.status_code in [301,302,304,307,308]:
return r.headers['Location']
return url
def matches_adb_selector(url, selector):
"""Check if URL matches the given selector"""
if selector['type'] == 'url-pattern':
pattern = selector['value']
# Convert AdBlock pattern to regex
# ||domain/* becomes ^https?://[^/]*domain.*
# domain/* becomes .*domain.*
if pattern.startswith('||'):
domain_pattern = pattern[2:]
# Escape special regex chars except * which we'll convert to .*
domain_pattern = re.escape(domain_pattern).replace(r'\*', '.*')
regex_pattern = f"^https?://[^/]*{domain_pattern}"
else:
# Escape special regex chars except * which we'll convert to .*
regex_pattern = re.escape(pattern).replace(r'\*', '.*')
return bool(re.search(regex_pattern, url))
return False
def should_remove_param(url, filter_rule):
"""Check if parameter should be removed based on filter rule"""
if filter_rule.action == 'allow':
return False # Allowlist rules prevent removal
if filter_rule.selector:
return matches_adb_selector(url, filter_rule.selector)
return True # No selector means apply to all URLs
async def extend_short_urls(url):
""" 扩展短链接 """
async with aiohttp.ClientSession() as session:
async with session.get(url,allow_redirects=False) as r:
if 'tb.cn' in urlparse(url).hostname:
# 淘宝短链接特殊处理
html_content = await r.text()
url = extract_tb_url_from_html(html_content)
if not url:
return url
if r.status in [301, 302, 304, 307, 308] and 'Location' in r.headers:
return r.headers['Location']
return url
def extract_tb_url_from_html(html_content):
# 使用正则表达式匹配 var url = '...' 的模式
@ -42,22 +73,46 @@ def remove_tracking_params(url):
parsed_url = urlparse(url)
query_params = parse_qs(parsed_url.query)
tracking_params = []
# Modified tracking_params collection
tracking_rules = []
with open('assets/LegitimateURLShortener.txt','r', encoding='utf-8') as f:
with open('assets/LegitimateURLShortener.txt', 'r', encoding='utf-8') as f:
for line in parse_filterlist(f):
if hasattr(line, 'options') and line.options:
for option in line.options:
if option[0] == 'removeparam':
tracking_params.append(option[1])
for param in tracking_params:
query_params.pop(param, None)
tracking_rules.append(line)
break # Only add rule once even if multiple removeparam options
# Rebuild the URL without tracking parameters
cleaned_query = urlencode(query_params, doseq=True)
cleaned_url = urlunparse(parsed_url._replace(query=cleaned_query))
for rule in tracking_rules:
if not should_remove_param(url, rule):
continue
return cleaned_url
for option in rule.options or []:
if option[0] == 'removeparam':
param_pattern = option[1]
if param_pattern is True: # Remove all params
query_params.clear()
break
elif isinstance(param_pattern, str):
# Handle regex patterns
if param_pattern.startswith('/') and param_pattern.endswith('/'):
regex_pattern = param_pattern[1:-1]
params_to_remove = [
param for param in query_params.keys()
if re.search(regex_pattern, param)
]
else:
# Exact match
params_to_remove = [param_pattern] if param_pattern in query_params else []
for param in params_to_remove:
query_params.pop(param, None)
# Reconstruct URL
new_query = urlencode(query_params, doseq=True)
return urlunparse(parsed_url._replace(query=new_query))
def reserve_whitelisted_params(url):
""" 保留白名单中的参数 """
@ -71,8 +126,8 @@ def reserve_whitelisted_params(url):
# 重新构建URL
cleaned_query = urlencode(new_query_params, doseq=True)
return urlunparse(parsed_url._replace(query=cleaned_query))
elif parsed_url.hostname in ['mall.bilibili.com','space.bilibili.com','live.bilibili.com']:
# 只保留spm_id_from参数创建新的query_params
elif parsed_url.hostname in ['www.bilibili.com','m.bilibili.com','bilibili.com','mall.bilibili.com','space.bilibili.com','live.bilibili.com']:
# 不保留任何参数
new_query_params = {}
# 重新构建URL
cleaned_query = urlencode(new_query_params, doseq=True)
@ -85,9 +140,34 @@ def transform_into_fixed_url(url):
if parsed_url.hostname in ['x.com', 'twitter.com']:
# 把 twitter 的链接转换为 fixupx.com
return urlunparse(parsed_url._replace(hostname='i.fixupx.com'))
return urlunparse(parsed_url._replace(netloc='i.fixupx.com'))
if parsed_url.hostname in ['bilibili.com', 'm.bilibili.com']:
# 把 bilibili 的链接转换为桌面端的 www.bilibili.com
return urlunparse(parsed_url._replace(netloc='www.bilibili.com'))
return url
async def process_url(url):
# 首先清理跟踪参数
cleaned_url = remove_tracking_params(url)
# 扩展短链接
extended_url = await extend_short_urls(cleaned_url)
# 对于一些网站,只保留白名单中的参数
if urlparse(extended_url).hostname in ['item.taobao.com', 'detail.tmall.com', 'h5.m.goofish.com', 'music.163.com',
'www.bilibili.com', 'm.bilibili.com', 'bilibili.com', 'mall.bilibili.com',
'space.bilibili.com', 'live.bilibili.com']:
final_url = reserve_whitelisted_params(extended_url)
if urlparse(extended_url).hostname in ['bilibili.com', 'm.bilibili.com']:
final_url = transform_into_fixed_url(final_url)
elif urlparse(extended_url).hostname in ['x.com', 'twitter.com']:
# 对于 Twitter 链接,转换为 fixupx.com
removed_tracking_url = remove_tracking_params(extended_url)
final_url = transform_into_fixed_url(removed_tracking_url)
else:
# 对于其他链接,直接对其进行跟踪参数清理
final_url = remove_tracking_params(extended_url)
return final_url
async def handle_links(message: Message):
if not config.is_feature_enabled('link', message.chat.id):
@ -98,12 +178,8 @@ async def handle_links(message: Message):
# Extract URLs from message text
if message.text:
urls = re.findall(url_pattern, message.text)
for url in urls:
# Process each URL with your functions
cleaned_url = remove_tracking_params(url)
extended_url = extend_short_urls(cleaned_url)
only_wl_params_url = reserve_whitelisted_params(extended_url)
#untracked_url = remove_tracking_params(only_wl_params_url)
fixed_url = transform_into_fixed_url(only_wl_params_url)
# Do something with the processed URL
await message.reply(f"清理完成:\n{fixed_url}")
final_urls = await asyncio.gather(*[process_url(url) for url in urls])
# 回复处理后的链接
if final_urls:
await message.reply(f"{"\n".join(final_urls)}\n消息里有包含跟踪参数的链接,已经帮你转换了哦")

View file

@ -39,6 +39,8 @@ class MessageStatsMiddleware(BaseMiddleware):
name = event.from_user.full_name
self.stats[chat_id]['users'][user_id] = {
'message_count': 0,
'xm_count': 0,
'wocai_count': 0,
'username': event.from_user.username if event.from_user else 'Unknown',
'name': name
}
@ -46,6 +48,16 @@ class MessageStatsMiddleware(BaseMiddleware):
# 更新统计
self.stats[chat_id]['total_messages'] += 1
self.stats[chat_id]['users'][user_id]['message_count'] += 1
# 羡慕、我菜统计
if event.text and any(keyword in event.text.lower() for keyword in ['xm','xmsl','羡慕','羡慕死了']):
if not self.stats[chat_id]['users'][user_id]['xm_count']:
self.stats[chat_id]['users'][user_id]['xm_count'] = 0
self.stats[chat_id]['users'][user_id]['xm_count'] += 1
if event.text and '我菜' in event.text:
if not self.stats[chat_id]['users'][user_id]['wocai_count']:
self.stats[chat_id]['users'][user_id]['xm_count'] = 0
self.stats[chat_id]['users'][user_id]['wocai_count'] += 1
# 保存统计数据
self.save_stats()
return await handler(event, data)

View file

@ -28,6 +28,16 @@ async def handle_stats_command(message: Message):
key=lambda x: x[1]['message_count'],
reverse=True
)
sorted_most_xm_users = sorted(
stats['users'].items(),
key=lambda x: x[1]['xm_count'],
reverse=True
)
sorted_most_wocai_users = sorted(
stats['users'].items(),
key=lambda x: x[1]['wocai_count'],
reverse=True
)
# 构建统计消息
text = f"📊 群组统计\n\n"
@ -38,5 +48,17 @@ async def handle_stats_command(message: Message):
for i, (user_id, user_data) in enumerate(sorted_users[:10], 1):
name = user_data['name'] or user_data['username'] or str(user_id)
text += f"{i}. {name}: {user_data['message_count']}\n"
if sorted_most_xm_users:
text += "\n💬 羡慕统计:\n"
for user_id, user_data in sorted_most_xm_users:
if user_data['xm_count'] > 0:
name = user_data['name'] or user_data['username'] or str(user_id)
text += f"{name}: {user_data['xm_count']} 次羡慕\n"
if sorted_most_wocai_users:
text += "\n🥬 卖菜统计:\n"
for user_id, user_data in sorted_most_wocai_users:
if user_data['wocai_count'] > 0:
name = user_data['name'] or user_data['username'] or str(user_id)
text += f"{name}: {user_data['wocai_count']} 次卖菜\n"
await message.reply(text)

View file

@ -4,6 +4,7 @@ version = "0.1.0"
description = "Add your description here"
requires-python = ">=3.13"
dependencies = [
"aiodns==3.5.0",
"aiogram==3.21.0",
"matrix-nio==0.25.2",
"python-abp==0.2.0",

71
uv.lock generated
View file

@ -2,6 +2,18 @@ version = 1
revision = 2
requires-python = ">=3.13"
[[package]]
name = "aiodns"
version = "3.5.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pycares" },
]
sdist = { url = "https://files.pythonhosted.org/packages/17/0a/163e5260cecc12de6abc259d158d9da3b8ec062ab863107dcdb1166cdcef/aiodns-3.5.0.tar.gz", hash = "sha256:11264edbab51896ecf546c18eb0dd56dff0428c6aa6d2cd87e643e07300eb310", size = 14380, upload-time = "2025-06-13T16:21:53.595Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f6/2c/711076e5f5d0707b8ec55a233c8bfb193e0981a800cd1b3b123e8ff61ca1/aiodns-3.5.0-py3-none-any.whl", hash = "sha256:6d0404f7d5215849233f6ee44854f2bb2481adf71b336b2279016ea5990ca5c5", size = 8068, upload-time = "2025-06-13T16:21:52.45Z" },
]
[[package]]
name = "aiofiles"
version = "24.1.0"
@ -123,6 +135,28 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722, upload-time = "2025-07-14T03:29:26.863Z" },
]
[[package]]
name = "cffi"
version = "1.17.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pycparser" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" },
{ url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" },
{ url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" },
{ url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" },
{ url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" },
{ url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" },
{ url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" },
{ url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" },
{ url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" },
{ url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" },
{ url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" },
]
[[package]]
name = "charset-normalizer"
version = "3.4.2"
@ -378,6 +412,41 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" },
]
[[package]]
name = "pycares"
version = "4.9.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f5/37/4d4f8ac929e98aad64781f37d9429e82ba65372fc89da0473cdbecdbbb03/pycares-4.9.0.tar.gz", hash = "sha256:8ee484ddb23dbec4d88d14ed5b6d592c1960d2e93c385d5e52b6fad564d82395", size = 655365, upload-time = "2025-06-13T00:37:49.923Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/10/da/e0240d156c6089bf2b38afd01600fe9db8b1dd6e53fb776f1dca020b1124/pycares-4.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:574d815112a95ab09d75d0a9dc7dea737c06985e3125cf31c32ba6a3ed6ca006", size = 145589, upload-time = "2025-06-13T00:37:17.154Z" },
{ url = "https://files.pythonhosted.org/packages/27/c5/1d4abd1a33b7fbd4dc0e854fcd6c76c4236bdfe1359dafb0a8349694462d/pycares-4.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50e5ab06361d59625a27a7ad93d27e067dc7c9f6aa529a07d691eb17f3b43605", size = 140730, upload-time = "2025-06-13T00:37:18.088Z" },
{ url = "https://files.pythonhosted.org/packages/24/4d/3ff037cd7fb7a6d9f1bf4289b96ff2d6ac59d098f02bbf3b18cb0a0ab576/pycares-4.9.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:785f5fd11ff40237d9bc8afa441551bb449e2812c74334d1d10859569e07515c", size = 587384, upload-time = "2025-06-13T00:37:19.047Z" },
{ url = "https://files.pythonhosted.org/packages/66/92/be8f527017769148687e45a4e5afd8d849aee2b145cda59003ad5a531aaf/pycares-4.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e194a500e403eba89b91fb863c917495c5b3dfcd1ce0ee8dc3a6f99a1360e2fc", size = 628273, upload-time = "2025-06-13T00:37:20.304Z" },
{ url = "https://files.pythonhosted.org/packages/a7/8d/e88cfdd08f7065ae52817b930834964320d0e43955f6ac68d2ab35728912/pycares-4.9.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:112dd49cdec4e6150a8d95b197e8b6b7b4468a3170b30738ed9b248cb2240c04", size = 665481, upload-time = "2025-06-13T00:37:21.727Z" },
{ url = "https://files.pythonhosted.org/packages/e0/9d/a2661f9c8e1e7fa842586d7b24710e78f068d26f768eea7a7437c249a2f6/pycares-4.9.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94aa3c2f3eb0aa69160137134775501f06c901188e722aac63d2a210d4084f99", size = 648157, upload-time = "2025-06-13T00:37:22.801Z" },
{ url = "https://files.pythonhosted.org/packages/43/b9/d04ea1de2a7d4e8a00b2b00a0ee94d7b0434f00eb55f5941ffa287c1dab2/pycares-4.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b510d71255cf5a92ccc2643a553548fcb0623d6ed11c8c633b421d99d7fa4167", size = 629244, upload-time = "2025-06-13T00:37:23.868Z" },
{ url = "https://files.pythonhosted.org/packages/d9/c8/7f81ccdd856ddc383d3f82708b4f4022761640f3baec6d233549960348b8/pycares-4.9.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5c6aa30b1492b8130f7832bf95178642c710ce6b7ba610c2b17377f77177e3cd", size = 621120, upload-time = "2025-06-13T00:37:25.164Z" },
{ url = "https://files.pythonhosted.org/packages/fd/96/9386654a244caafd77748e626da487f1a56f831e3db5ef1337410be3e5f6/pycares-4.9.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e5767988e044faffe2aff6a76aa08df99a8b6ef2641be8b00ea16334ce5dea93", size = 593493, upload-time = "2025-06-13T00:37:26.198Z" },
{ url = "https://files.pythonhosted.org/packages/76/bd/73286f329d03fef071e8517076dc62487e4478a3c85c4c59d652e6a663e5/pycares-4.9.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b9928a942820a82daa3207509eaba9e0fa9660756ac56667ec2e062815331fcb", size = 669086, upload-time = "2025-06-13T00:37:27.278Z" },
{ url = "https://files.pythonhosted.org/packages/2f/2a/0f623426225828f2793c3f86463ef72f6ecf6df12fe240a4e68435e8212f/pycares-4.9.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:556c854174da76d544714cdfab10745ed5d4b99eec5899f7b13988cd26ff4763", size = 652103, upload-time = "2025-06-13T00:37:28.361Z" },
{ url = "https://files.pythonhosted.org/packages/04/d8/7db6eee011f414f21e3d53a0ad81593baa87a332403d781c2f86d3eef315/pycares-4.9.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d42e2202ca9aa9a0a9a6e43a4a4408bbe0311aaa44800fa27b8fd7f82b20152a", size = 628373, upload-time = "2025-06-13T00:37:29.797Z" },
{ url = "https://files.pythonhosted.org/packages/72/a4/1a9b96678afb4f31651885129fbfa2cd44e78a438fd545c7b8d317a1f381/pycares-4.9.0-cp313-cp313-win32.whl", hash = "sha256:cce8ef72c9ed4982c84114e6148a4e42e989d745de7862a0ad8b3f1cdc05def2", size = 118511, upload-time = "2025-06-13T00:37:30.854Z" },
{ url = "https://files.pythonhosted.org/packages/79/e4/6724c71a08a91f2685ca60ca35d7950c187a2d79a776461130a6cb5b0d5e/pycares-4.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:318cdf24f826f1d2f0c5a988730bd597e1683296628c8f1be1a5b96643c284fe", size = 143746, upload-time = "2025-06-13T00:37:32.015Z" },
{ url = "https://files.pythonhosted.org/packages/ee/f8/b4d4bf71ae92727a0b3a9b9092c2e722833c1ca50ebd0414824843cb84fd/pycares-4.9.0-cp313-cp313-win_arm64.whl", hash = "sha256:faa9de8e647ed06757a2c117b70a7645a755561def814da6aca0d766cf71a402", size = 115646, upload-time = "2025-06-13T00:37:33.251Z" },
]
[[package]]
name = "pycparser"
version = "2.22"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" },
]
[[package]]
name = "pycryptodome"
version = "3.23.0"
@ -488,6 +557,7 @@ name = "realbot"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "aiodns" },
{ name = "aiogram" },
{ name = "matrix-nio" },
{ name = "python-abp" },
@ -497,6 +567,7 @@ dependencies = [
[package.metadata]
requires-dist = [
{ name = "aiodns", specifier = "==3.5.0" },
{ name = "aiogram", specifier = "==3.21.0" },
{ name = "matrix-nio", specifier = "==0.25.2" },
{ name = "python-abp", specifier = "==0.2.0" },