PagerMaid_Plugins_Pyro/speed_test/main.py

128 lines
4.0 KiB
Python
Raw Normal View History

2022-07-17 09:57:19 +00:00
import contextlib
from PIL import Image
from os.path import exists
from httpx import ReadTimeout
from pagermaid.listener import listener
2022-09-01 08:28:48 +00:00
from pagermaid.single_utils import safe_remove
2022-09-01 12:30:34 +00:00
from pagermaid.enums import Client, Message, AsyncClient
2022-07-17 09:57:19 +00:00
from pagermaid.utils import lang, pip_install
pip_install("speedtest-cli", alias="speedtest")
2023-07-01 12:18:58 +00:00
from speedtest import (
Speedtest,
ShareResultsConnectFailure,
ShareResultsSubmitFailure,
NoMatchedServers,
SpeedtestBestServerFailure,
SpeedtestHTTPError,
)
2022-07-17 09:57:19 +00:00
def unit_convert(byte):
2023-07-01 12:18:58 +00:00
"""Converts byte into readable formats."""
2022-07-17 09:57:19 +00:00
power = 1000
zero = 0
2023-07-01 12:18:58 +00:00
units = {0: "", 1: "Kb/s", 2: "Mb/s", 3: "Gb/s", 4: "Tb/s"}
2022-07-17 09:57:19 +00:00
while byte > power:
byte /= power
zero += 1
return f"{round(byte, 2)} {units[zero]}"
2022-09-01 12:30:34 +00:00
async def run_speedtest(request: AsyncClient, message: Message):
2022-07-17 09:57:19 +00:00
test = Speedtest()
2022-07-17 11:06:05 +00:00
server = int(message.arguments) if len(message.parameter) == 1 else None
2022-07-17 09:57:19 +00:00
if server:
2022-07-17 11:06:05 +00:00
servers = test.get_closest_servers()
for i in servers:
if i["id"] == str(server):
2022-07-17 11:07:30 +00:00
test.servers = [i]
2022-07-17 11:06:05 +00:00
break
test.get_best_server(servers=test.servers)
2022-07-17 09:57:19 +00:00
test.download()
test.upload()
with contextlib.suppress(ShareResultsConnectFailure):
test.results.share()
result = test.results.dict()
des = (
f"**Speedtest** \n"
f"Server: `{result['server']['name']} - "
f"{result['server']['cc']}` \n"
f"Sponsor: `{result['server']['sponsor']}` \n"
f"Upload: `{unit_convert(result['upload'])}` \n"
f"Download: `{unit_convert(result['download'])}` \n"
f"Latency: `{result['ping']}` \n"
f"Timestamp: `{result['timestamp']}`"
)
if result["share"]:
2023-07-01 12:18:58 +00:00
data = await request.get(
result["share"].replace("http:", "https:"), follow_redirects=True
)
2022-07-17 09:57:19 +00:00
with open("speedtest.png", mode="wb") as f:
f.write(data.content)
with contextlib.suppress(Exception):
img = Image.open("speedtest.png")
c = img.crop((17, 11, 727, 389))
c.save("speedtest.png")
return des, "speedtest.png" if exists("speedtest.png") else None
async def get_all_ids():
test = Speedtest()
servers = test.get_closest_servers()
return (
(
"附近的测速点有:\n\n"
+ "\n".join(
f"`{i['id']}` - `{int(i['d'])}km` - `{i['name']}` - `{i['sponsor']}`"
for i in servers
),
None,
)
if servers
else ("附近没有测速点", None)
)
2023-07-01 12:18:58 +00:00
@listener(
command="speedtest",
description=lang("speedtest_des"),
parameters="(Server ID/测速点列表)",
)
2022-09-01 12:30:34 +00:00
async def speedtest(client: Client, message: Message, request: AsyncClient):
2023-07-01 12:18:58 +00:00
"""Tests internet speed using speedtest."""
if message.arguments == "测速点列表":
msg = message
else:
2023-07-01 12:18:58 +00:00
msg: Message = await message.edit(lang("speedtest_processing"))
2022-07-17 09:57:19 +00:00
try:
if message.arguments == "测速点列表":
des, photo = await get_all_ids()
else:
2022-09-01 12:30:34 +00:00
des, photo = await run_speedtest(request, message)
2022-07-17 09:57:19 +00:00
except SpeedtestHTTPError:
2023-07-01 12:18:58 +00:00
return await msg.edit(lang("speedtest_ConnectFailure"))
2022-09-24 08:21:44 +00:00
except (ValueError, TypeError):
2023-07-01 12:18:58 +00:00
return await msg.edit(lang("arg_error"))
2022-07-17 09:57:19 +00:00
except (SpeedtestBestServerFailure, NoMatchedServers):
2023-07-01 12:18:58 +00:00
return await msg.edit(lang("speedtest_ServerFailure"))
2022-07-17 09:57:19 +00:00
except (ShareResultsSubmitFailure, RuntimeError, ReadTimeout):
2023-07-01 12:18:58 +00:00
return await msg.edit(lang("speedtest_ConnectFailure"))
2022-07-17 09:57:19 +00:00
if not photo:
return await msg.edit(des)
try:
2022-11-21 11:38:51 +00:00
await client.send_photo(
message.chat.id,
photo,
caption=des,
2023-07-01 12:18:58 +00:00
reply_to_message_id=message.reply_to_top_message_id
or message.reply_to_message_id,
2022-11-21 11:38:51 +00:00
)
2022-07-17 09:57:19 +00:00
except Exception:
return await msg.edit(des)
await msg.safe_delete()
2022-07-17 09:57:19 +00:00
safe_remove(photo)