From 849a0217b98fe0001d178186f08846c5808cac1a Mon Sep 17 00:00:00 2001 From: Xtao_dada Date: Thu, 25 Nov 2021 17:44:38 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=F0=9F=90=9B=E2=9E=95=20Use=20aiohttp?= =?UTF-8?q?=20to=20accelerate=20network=20requests=20and=20Support=20silen?= =?UTF-8?q?t=20mode=20and=20fix=20some=20bugs.=20(#148)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 使用 aiohttp 加速网络请求 * 支持静默模式防止污染操作记录 * 批量修复错误 --- .github/ISSUE_TEMPLATE/bug_report_en.md | 4 +- .github/ISSUE_TEMPLATE/bug_report_zh.md | 4 +- .github/ISSUE_TEMPLATE/feature_request_en.md | 2 +- .github/ISSUE_TEMPLATE/feature_request_zh.md | 2 +- INSTALL.md | 4 +- README.md | 12 +- config.gen.yml | 3 + install.sh | 2 +- languages/built-in/en.yml | 1 + languages/built-in/zh-cn.yml | 1 + languages/built-in/zh-tw.yml | 1 + pagermaid/__init__.py | 58 +++------ pagermaid/bots/message.py | 8 +- pagermaid/bots/status.py | 8 +- pagermaid/bots/update.py | 2 +- pagermaid/modules/account.py | 17 +-- pagermaid/modules/captions.py | 17 ++- pagermaid/modules/external.py | 14 ++- pagermaid/modules/fun.py | 25 ++-- pagermaid/modules/message.py | 17 ++- pagermaid/modules/plugin.py | 40 +++--- pagermaid/modules/prune.py | 5 +- pagermaid/modules/qr.py | 5 +- pagermaid/modules/status.py | 30 +++-- pagermaid/modules/sticker.py | 73 ++++++----- pagermaid/modules/system.py | 9 +- pagermaid/modules/update.py | 16 +-- pagermaid/utils.py | 122 ++++++++++++++++++- requirements.txt | 1 + setup.py | 2 +- 30 files changed, 316 insertions(+), 189 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report_en.md b/.github/ISSUE_TEMPLATE/bug_report_en.md index 3846802..52d722c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_en.md +++ b/.github/ISSUE_TEMPLATE/bug_report_en.md @@ -4,7 +4,7 @@ about: Submit discovered bugs --- @@ -17,7 +17,7 @@ Otherwise the issue will be closed immediately.Please do not repeat the issue. ### Additional info (logs errors etc) diff --git a/.github/ISSUE_TEMPLATE/bug_report_zh.md b/.github/ISSUE_TEMPLATE/bug_report_zh.md index ce5bc77..6e31e09 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_zh.md +++ b/.github/ISSUE_TEMPLATE/bug_report_zh.md @@ -4,7 +4,7 @@ about: 早起的虫子被你抓 --- @@ -17,7 +17,7 @@ about: 早起的虫子被你抓 ### 额外信息(日志、报错等) diff --git a/.github/ISSUE_TEMPLATE/feature_request_en.md b/.github/ISSUE_TEMPLATE/feature_request_en.md index fa9d1f2..298588a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request_en.md +++ b/.github/ISSUE_TEMPLATE/feature_request_en.md @@ -4,7 +4,7 @@ about: Submit a new feature request --- diff --git a/.github/ISSUE_TEMPLATE/feature_request_zh.md b/.github/ISSUE_TEMPLATE/feature_request_zh.md index 1bbe0d1..f2dc64b 100644 --- a/.github/ISSUE_TEMPLATE/feature_request_zh.md +++ b/.github/ISSUE_TEMPLATE/feature_request_zh.md @@ -4,7 +4,7 @@ about: 提交新的功能需求 --- diff --git a/INSTALL.md b/INSTALL.md index ff5eb97..0589b5d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -16,13 +16,13 @@ ``` -curl -fsSL https://raw.githubusercontent.com/xtaodada/PagerMaid-Modify/master/utils/docker.sh | sh +curl -fsSL https://raw.githubusercontent.com/Xtao-Labs/PagerMaid-Modify/master/utils/docker.sh | sh ``` 如果您想在运行之前检查脚本内容: ``` -curl https://raw.githubusercontent.com/xtaodada/PagerMaid-Modify/master/utils/docker.sh -o docker.sh +curl https://raw.githubusercontent.com/Xtao-Labs/PagerMaid-Modify/master/utils/docker.sh -o docker.sh vim docker.sh chmod 0755 docker.sh ./docker.sh diff --git a/README.md b/README.md index f4dfe81..1f75425 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ > 一个人形自走 bot

-star -fork -GitHub last commit +star +fork +GitHub last commit size -issues +issues docker -license +license telethon

@@ -25,7 +25,7 @@ Pagermaid 是一个用在 Telegram 的实用工具。 ## 安装 -[Ubuntu 16.04 手动搭建教程](https://github.com/xtaodada/PagerMaid-Modify/wiki/Ubuntu-16.04-%E5%AE%89%E8%A3%85%E8%AF%A6%E8%A7%A3) +[Ubuntu 16.04 手动搭建教程](https://github.com/Xtao-Labs/PagerMaid-Modify/wiki/Ubuntu-16.04-%E5%AE%89%E8%A3%85%E8%AF%A6%E8%A7%A3) [一键脚本](https://t.me/PagerMaid_Modify/58) diff --git a/config.gen.yml b/config.gen.yml index 6ab3089..c878593 100644 --- a/config.gen.yml +++ b/config.gen.yml @@ -91,3 +91,6 @@ start_form: "%m/%d %H:%M" bot_admins: - example1 - example2 + +# Silent to reduce editing times +silent: "True" diff --git a/install.sh b/install.sh index d3086df..1e033ba 100644 --- a/install.sh +++ b/install.sh @@ -248,7 +248,7 @@ debian_require_install() { download_repo() { echo "下载 repository 中 . . ." rm -rf /var/lib/pagermaid >>/dev/null 2>&1 - git clone https://github.com/xtaodada/PagerMaid-Modify.git /var/lib/pagermaid >>/dev/null 2>&1 + git clone https://github.com/Xtao-Labs/PagerMaid-Modify.git /var/lib/pagermaid >>/dev/null 2>&1 cd /var/lib/pagermaid >>/dev/null 2>&1 echo "Hello World!" >/var/lib/pagermaid/public.lock } diff --git a/languages/built-in/en.yml b/languages/built-in/en.yml index f418010..ac44201 100644 --- a/languages/built-in/en.yml +++ b/languages/built-in/en.yml @@ -256,6 +256,7 @@ re_des: Reread the reply message in the current conversation. (Need to reply to re_parameters: re_too_big: oh oh something went wrong... this number is too big to provoke re_arg_error: Oh, something went wrong...maybe the parameter contains symbols other than numbers +re_forbidden: Oh, something went wrong...you do not have permission to forward messages from this group. not_reply: Something went wrong ~ You don't seem to reply to a message. # leave leave_res: Say "goodbye" and leave the session. diff --git a/languages/built-in/zh-cn.yml b/languages/built-in/zh-cn.yml index 353ac5a..8a8a8fb 100644 --- a/languages/built-in/zh-cn.yml +++ b/languages/built-in/zh-cn.yml @@ -267,6 +267,7 @@ re_des: 在当前会话复读回复的消息。(需要回复一条消息) re_parameters: <次数> re_too_big: 呜呜呜出错了...这个数字太大惹 re_arg_error: 呜呜呜出错了...可能参数包含了数字以外的符号 +re_forbidden: 呜呜呜出错了...此群组的消息禁止转发 not_reply: 出错了呜呜呜 ~ 您好像没有回复一条消息。 ## leave leave_res: 说 “再见” 然后离开会话。 diff --git a/languages/built-in/zh-tw.yml b/languages/built-in/zh-tw.yml index 7db2df2..4647e47 100644 --- a/languages/built-in/zh-tw.yml +++ b/languages/built-in/zh-tw.yml @@ -256,6 +256,7 @@ re_des: 在目前聊天室復讀回覆的訊息。 re_parameters: <次數> re_too_big: Error!數字過大 re_arg_error: Error!不是數字! +re_forbidden: Error!您没有权限! not_reply: Error!您沒有回覆訊息! # leave leave_res: 說再見並離開聊天室。 diff --git a/pagermaid/__init__.py b/pagermaid/__init__.py index 4de725a..24a4264 100644 --- a/pagermaid/__init__.py +++ b/pagermaid/__init__.py @@ -30,6 +30,7 @@ from telethon import TelegramClient from telethon.sessions import StringSession # Errors +from telethon.errors import AuthKeyError from telethon.errors.rpcerrorlist import MessageNotModifiedError, MessageIdInvalidError, ChannelPrivateError, \ ChatSendMediaForbiddenError, YouBlockedUserError, FloodWaitError, ChatWriteForbiddenError, \ AuthKeyDuplicatedError, ChatSendStickersForbiddenError, SlowModeWaitError, MessageEditTimeExpiredError, \ @@ -107,9 +108,7 @@ def lang(text: str) -> str: analytics = None try: - allow_analytics = strtobool(config['allow_analytic']) -except KeyError: - allow_analytics = True + allow_analytics = strtobool(config.get('allow_analytic', 'True')) except ValueError: allow_analytics = True if allow_analytics: @@ -163,41 +162,24 @@ except ValueError: exit(1) except: pass -try: - proxy_addr = config['proxy_addr'].strip() - proxy_port = config['proxy_port'].strip() - http_addr = config['http_addr'].strip() - http_port = config['http_port'].strip() - mtp_addr = config['mtp_addr'].strip() - mtp_port = config['mtp_port'].strip() - mtp_secret = config['mtp_secret'].strip() -except KeyError: - proxy_addr = '' - proxy_port = '' - http_addr = '' - http_port = '' - mtp_addr = '' - mtp_port = '' - mtp_secret = '' -try: - redis_host = config['redis']['host'] -except KeyError: - redis_host = 'localhost' -try: - redis_port = config['redis']['port'] -except KeyError: - redis_port = 6379 -try: - redis_db = config['redis']['db'] -except KeyError: - redis_db = 14 -try: - if strtobool(config['ipv6']): - use_ipv6 = True - else: - use_ipv6 = False -except KeyError: +proxy_addr = config.get('proxy_addr', '').strip() +proxy_port = config.get('proxy_port', '').strip() +http_addr = config.get('http_addr', '').strip() +http_port = config.get('http_port', '').strip() +mtp_addr = config.get('mtp_addr', '').strip() +mtp_port = config.get('mtp_port', '').strip() +mtp_secret = config.get('mtp_secret', '').strip() +redis_host = config.get('redis').get('host', 'localhost') +redis_port = config.get('redis').get('port', 6379) +redis_db = config.get('redis').get('db', 14) +if strtobool(config.get('ipv6', 'False')): + use_ipv6 = True +else: use_ipv6 = False +if strtobool(config.get('silent', 'True')): + silent = True +else: + silent = False if api_key is None or api_hash is None: logs.info( lang('config_error') @@ -297,7 +279,7 @@ def before_send(event, hint): AlreadyInConversationError, ConnectedError, KeyboardInterrupt, OSError, AuthKeyDuplicatedError, ResponseError, SlowModeWaitError, PeerFloodError, MessageEditTimeExpiredError, PeerIdInvalidError, - AuthKeyUnregisteredError, UserBannedInChannelError)): + AuthKeyUnregisteredError, UserBannedInChannelError, AuthKeyError)): return elif exc_info and isinstance(exc_info[1], UserDeactivatedBanError): # The user has been deleted/deactivated diff --git a/pagermaid/bots/message.py b/pagermaid/bots/message.py index ff0eaa0..a201932 100644 --- a/pagermaid/bots/message.py +++ b/pagermaid/bots/message.py @@ -1,6 +1,5 @@ """ Message related utilities. """ -import requests import json from telethon.tl.functions.messages import DeleteChatUserRequest @@ -13,7 +12,7 @@ from telethon.tl.types import ChannelForbidden from pagermaid import bot, log, config, proxies from pagermaid.listener import listener -from pagermaid.utils import lang, alias_command +from pagermaid.utils import lang, alias_command, get @listener(is_plugin=False, incoming=True, command=alias_command("id"), @@ -222,13 +221,12 @@ async def hitokoto(context): hitokoto_while = 1 hitokoto_json = None try: - hitokoto_json = json.loads(requests.get("https://v1.hitokoto.cn/?charset=utf-8", proxies=proxies).content.decode("utf-8")) + hitokoto_json = (await get("https://v1.hitokoto.cn/?charset=utf-8")).json() except ValueError: while hitokoto_while < 10: hitokoto_while += 1 try: - hitokoto_json = json.loads( - requests.get("https://v1.hitokoto.cn/?charset=utf-8", proxies=proxies).content.decode("utf-8")) + hitokoto_json = (await get("https://v1.hitokoto.cn/?charset=utf-8")).json() break except: continue diff --git a/pagermaid/bots/status.py b/pagermaid/bots/status.py index 1626642..02ec496 100644 --- a/pagermaid/bots/status.py +++ b/pagermaid/bots/status.py @@ -2,12 +2,10 @@ from json import loads from PIL import Image -from requests import get from os import remove, popen from datetime import datetime from speedtest import distance, Speedtest, ShareResultsConnectFailure, ShareResultsSubmitFailure, NoMatchedServers, \ SpeedtestBestServerFailure, SpeedtestHTTPError -from telethon import functions from platform import python_version, uname from wordcloud import WordCloud from telethon import version as telethon_version @@ -17,7 +15,7 @@ from pathlib import Path from pagermaid import log, config, redis_status, start_time from pagermaid.utils import execute from pagermaid.listener import listener -from pagermaid.utils import lang, alias_command +from pagermaid.utils import lang, alias_command, get DCs = { 1: "149.154.175.50", @@ -116,7 +114,7 @@ async def speedtest(context): f"Timestamp: `{result['timestamp']}`" ) # 开始处理图片 - data = get(f"{result['result']['url']}.png").content + data = (await get(f"{result['result']['url']}.png")).content with open('speedtest.png', mode='wb') as f: f.write(data) try: @@ -192,7 +190,7 @@ async def speedtest(context): f"Timestamp: `{result['timestamp']}`" ) # 开始处理图片 - data = get(result['share']).content + data = (await get(result['share'])).content with open('speedtest.png', mode='wb') as f: f.write(data) try: diff --git a/pagermaid/bots/update.py b/pagermaid/bots/update.py index 1424f8d..6415684 100644 --- a/pagermaid/bots/update.py +++ b/pagermaid/bots/update.py @@ -37,7 +37,7 @@ async def update(context): git_date = run("git log -1 --format='%at'", stdout=PIPE, shell=True).stdout.decode() git_date = datetime.utcfromtimestamp(int(git_date)).strftime("%Y/%m/%d %H:%M:%S") git_hash = run("git rev-parse --short HEAD", stdout=PIPE, shell=True).stdout.decode().strip() - get_hash_link = f"https://github.com/xtaodada/PagerMaid-Modify/commit/{git_hash}" + get_hash_link = f"https://github.com/Xtao-Labs/PagerMaid-Modify/commit/{git_hash}" # Generate the text text = f"{lang('status_platform')}: {str(platform.platform())}\n" \ f"{lang('update_platform_version')}: {str(platform.version())}\n" \ diff --git a/pagermaid/modules/account.py b/pagermaid/modules/account.py index d8e192a..a0577f7 100644 --- a/pagermaid/modules/account.py +++ b/pagermaid/modules/account.py @@ -10,7 +10,7 @@ from telethon.tl.functions.users import GetFullUserRequest from telethon.tl.functions.contacts import BlockRequest, UnblockRequest from telethon.tl.types import InputPhoto, MessageMediaPhoto, MessageEntityMentionName, MessageEntityPhone, User from struct import error as StructError -from pagermaid import bot, log +from pagermaid import bot, log, silent from pagermaid.utils import lang, alias_command from pagermaid.listener import listener @@ -78,7 +78,8 @@ async def pfp(context): """ Sets your profile picture. """ reply = await context.get_reply_message() photo = None - await context.edit(lang('pfp_process')) + if not silent: + await context.edit(lang('pfp_process')) if reply: if reply.media: if isinstance(reply.media, MessageMediaPhoto): @@ -165,8 +166,8 @@ async def profile(context): if len(context.parameter) > 1: await context.edit(f"{lang('error_prefix')}{lang('arg_error')}") return - - await context.edit(lang('profile_process')) + if not silent: + await context.edit(lang('profile_process')) if context.reply_to_msg_id: reply_message = await context.get_reply_message() if not reply_message: @@ -286,8 +287,8 @@ async def block_user(context): if len(context.parameter) > 1: await context.edit(f"{lang('error_prefix')}{lang('arg_error')}") return - - await context.edit(lang('block_process')) + if not silent: + await context.edit(lang('block_process')) user = None # Priority: reply > argument > current_chat if context.reply_to_msg_id: # Reply to a user @@ -324,8 +325,8 @@ async def unblock_user(context): if len(context.parameter) > 1: await context.edit(f"{lang('error_prefix')}{lang('arg_error')}") return - - await context.edit(lang('unblock_process')) + if not silent: + await context.edit(lang('unblock_process')) user = None if context.reply_to_msg_id: reply_message = await context.get_reply_message() diff --git a/pagermaid/modules/captions.py b/pagermaid/modules/captions.py index 0de6298..5f7f737 100644 --- a/pagermaid/modules/captions.py +++ b/pagermaid/modules/captions.py @@ -7,7 +7,7 @@ from pygments.formatters import img from pygments.lexers import guess_lexer from telethon.errors import PhotoInvalidDimensionsError -from pagermaid import log, module_dir +from pagermaid import log, module_dir, silent from pagermaid.listener import listener from pagermaid.utils import execute, upload_attachment, lang, alias_command @@ -17,7 +17,8 @@ from pagermaid.utils import execute, upload_attachment, lang, alias_command async def convert(context): """ Converts image to png. """ reply = await context.get_reply_message() - await context.edit(lang('convert_process')) + if not silent: + await context.edit(lang('convert_process')) target_file_path = await context.download_media() reply_id = context.reply_to_msg_id if reply: @@ -55,7 +56,8 @@ async def convert(context): parameters=", ") async def caption(context): """ Generates images with captions. """ - await context.edit(lang('caption_process')) + if not silent: + await context.edit(lang('caption_process')) if context.arguments: if ',' in context.arguments: string_1, string_2 = context.arguments.split(',', 1) @@ -121,7 +123,8 @@ async def ocr(context): await context.edit(lang('ocr_psm_len_error')) return reply = await context.get_reply_message() - await context.edit(lang('ocr_processing')) + if not silent: + await context.edit(lang('ocr_processing')) if reply: target_file_path = await context.client.download_media( await context.get_reply_message() @@ -154,7 +157,8 @@ async def highlight(context): return reply = await context.get_reply_message() reply_id = None - await context.edit(lang('highlight_processing')) + if not silent: + await context.edit(lang('highlight_processing')) if reply: reply_id = reply.id target_file_path = await context.client.download_media( @@ -189,7 +193,8 @@ async def highlight(context): except OSError: await context.edit(lang('caption_error')) return - await context.edit(lang('highlight_uploading')) + if not silent: + await context.edit(lang('highlight_uploading')) try: await context.client.send_file( context.chat_id, diff --git a/pagermaid/modules/external.py b/pagermaid/modules/external.py index 8ebd7bb..fe5b914 100644 --- a/pagermaid/modules/external.py +++ b/pagermaid/modules/external.py @@ -6,7 +6,7 @@ from magic_google import MagicGoogle from gtts import gTTS from gtts.tts import gTTSError from re import compile as regex_compile -from pagermaid import log +from pagermaid import log, silent from pagermaid.listener import listener, config from pagermaid.utils import clear_emojis, attach_log, fetch_youtube_audio, lang, alias_command @@ -29,7 +29,8 @@ async def translate(context): return try: - await context.edit(lang('translate_processing')) + if not silent: + await context.edit(lang('translate_processing')) try: result = translator.translate(clear_emojis(message), dest=ap_lang) except: @@ -75,7 +76,8 @@ async def tts(context): return try: - await context.edit(lang('tts_processing')) + if not silent: + await context.edit(lang('tts_processing')) gTTS(message, lang=ap_lang) except AssertionError: await context.edit(lang('tts_AssertionError')) @@ -134,7 +136,8 @@ async def googletest(context): return query = query.replace(' ', '+') - await context.edit(lang('google_processing')) + if not silent: + await context.edit(lang('google_processing')) results = "" for i in mg.search(query=query, num=int(config['result_length'])): try: @@ -166,7 +169,8 @@ async def fetchaudio(context): """ Fetches audio from provided URL. """ reply = await context.get_reply_message() reply_id = None - await context.edit(lang('fetchaudio_processing')) + if not silent: + await context.edit(lang('fetchaudio_processing')) if reply: reply_id = reply.id if url is None: diff --git a/pagermaid/modules/fun.py b/pagermaid/modules/fun.py index e9de181..668f7e9 100644 --- a/pagermaid/modules/fun.py +++ b/pagermaid/modules/fun.py @@ -4,7 +4,7 @@ from asyncio import sleep from random import choice, random, randint, randrange, seed from telethon.errors.rpcerrorlist import MessageNotModifiedError from cowpy import cow -from pagermaid import module_dir +from pagermaid import module_dir, silent from pagermaid.listener import listener from pagermaid.utils import owoify, execute, random_gen, obtain_message, lang, alias_command @@ -160,7 +160,8 @@ async def flip(context): parameters=" ") async def ship(context): """ Ship randomly generated members. """ - await context.edit(lang('ship_processing')) + if not silent: + await context.edit(lang('ship_processing')) if len(context.parameter) == 0: users = [] async for user in context.client.iter_participants(context.chat_id): @@ -267,19 +268,21 @@ async def tuxsay(context): description=lang('coin_des')) async def coin(context): """ Throws a coin. """ - await context.edit(lang('coin_processing')) + if not silent: + await context.edit(lang('coin_processing')) await sleep(.5) outcomes = ['A'] * 5 + ['B'] * 5 + ['C'] * 1 result = choice(outcomes) count = 0 - while count <= 3: - await context.edit("`.` . .") - await sleep(.3) - await context.edit(". `.` .") - await sleep(.3) - await context.edit(". . `.`") - await sleep(.3) - count += 1 + if not silent: + while count <= 3: + await context.edit("`.` . .") + await sleep(.3) + await context.edit(". `.` .") + await sleep(.3) + await context.edit(". . `.`") + await sleep(.3) + count += 1 if result == "C": await context.edit(lang('coin_lost')) elif result == "B": diff --git a/pagermaid/modules/message.py b/pagermaid/modules/message.py index 98ee57a..4b20c33 100644 --- a/pagermaid/modules/message.py +++ b/pagermaid/modules/message.py @@ -1,19 +1,16 @@ """ Message related utilities. """ -import requests -import json - from telethon.tl.functions.messages import DeleteChatUserRequest from telethon.tl.functions.channels import LeaveChannelRequest -from telethon.errors import ForbiddenError +from telethon.errors import ForbiddenError, AuthKeyError from telethon.errors.rpcerrorlist import ChatIdInvalidError, FloodWaitError, UserNotParticipantError from distutils.util import strtobool from telethon.tl.types import ChannelForbidden -from pagermaid import bot, log, config, proxies +from pagermaid import bot, log, config from pagermaid.listener import listener -from pagermaid.utils import lang, alias_command +from pagermaid.utils import lang, alias_command, get def isfloat(value): @@ -172,6 +169,9 @@ async def re(context): return except ValueError: return + except AuthKeyError: + await context.respond(lang('re_forbidden')) + return else: await context.edit(lang('not_reply')) @@ -236,13 +236,12 @@ async def hitokoto(context): hitokoto_while = 1 hitokoto_json = None try: - hitokoto_json = json.loads(requests.get("https://v1.hitokoto.cn/?charset=utf-8", proxies=proxies).content.decode("utf-8")) + hitokoto_json = (await get("https://v1.hitokoto.cn/?charset=utf-8")).json() except ValueError: while hitokoto_while < 10: hitokoto_while += 1 try: - hitokoto_json = json.loads( - requests.get("https://v1.hitokoto.cn/?charset=utf-8", proxies=proxies).content.decode("utf-8")) + hitokoto_json = (await get("https://v1.hitokoto.cn/?charset=utf-8")).json() break except: continue diff --git a/pagermaid/modules/plugin.py b/pagermaid/modules/plugin.py index d43d0de..ed65e84 100644 --- a/pagermaid/modules/plugin.py +++ b/pagermaid/modules/plugin.py @@ -2,14 +2,13 @@ import json from re import search, I -from requests import get from os import remove, rename, chdir, path from os.path import exists from shutil import copyfile, move from glob import glob -from pagermaid import log, working_dir, config, proxies +from pagermaid import log, working_dir, config from pagermaid.listener import listener -from pagermaid.utils import upload_attachment, lang, alias_command +from pagermaid.utils import upload_attachment, lang, alias_command, get from pagermaid.modules import plugin_list as active_plugins, __list_plugins @@ -19,11 +18,6 @@ except: git_source = "https://raw.githubusercontent.com/Xtao-Labs/PagerMaid_Plugins/master/" -def get_html(url): - data = get(url, proxies=proxies) - return data.status_code, data.content - - def remove_plugin(name): plugin_directory = f"{working_dir}/plugins/" try: @@ -36,10 +30,10 @@ def remove_plugin(name): pass -def download(name): - status, html = get_html(f'{git_source}{name}.py') +async def download(name): + html = await get(f'{git_source}{name}.py') with open(f'plugins/{name}.py', mode='wb') as f: - f.write(html) + f.write(html.content) return f'plugins/{name}.py' @@ -100,8 +94,8 @@ async def plugin(context): success_list = [] failed_list = [] noneed_list = [] - temp, plugin_list = get_html(f"{git_source}list.json") - plugin_list = json.loads(plugin_list)['list'] + plugin_list = await get(f"{git_source}list.json") + plugin_list = plugin_list.json()['list'] for i in process_list: if exists(f"{plugin_directory}version.json"): with open(f"{plugin_directory}version.json", 'r', encoding="utf-8") as f: @@ -124,7 +118,7 @@ async def plugin(context): break else: remove_plugin(i) - download(i) + await download(i) update_version(i, x['version']) success_list.append(i) temp = False @@ -266,8 +260,8 @@ async def plugin(context): return with open(f"{plugin_directory}version.json", 'r', encoding="utf-8") as f: version_json = json.load(f) - temp, plugin_list = get_html(f"{git_source}list.json") - plugin_online = json.loads(plugin_list)['list'] + plugin_list = await get(f"{git_source}list.json") + plugin_online = plugin_list.json()['list'] for key, value in version_json.items(): if value == "0.0": continue @@ -294,7 +288,7 @@ async def plugin(context): plugin_directory = f"{working_dir}/plugins/" for i in need_update_list: remove_plugin(i) - download(i) + await download(i) with open(f"{plugin_directory}version.json", 'r', encoding="utf-8") as f: version_json = json.load(f) for m in plugin_online: @@ -310,8 +304,8 @@ async def plugin(context): elif len(context.parameter) == 2: search_result = [] plugin_name = context.parameter[1] - temp, plugin_list = get_html(f"{git_source}list.json") - plugin_online = json.loads(plugin_list)['list'] + plugin_list = await get(f"{git_source}list.json") + plugin_online = plugin_list.json()['list'] for i in plugin_online: if search(plugin_name, i['name'], I): search_result.extend(['`' + i['name'] + '` / `' + i['version'] + '`\n ' + i['des-short']]) @@ -327,8 +321,8 @@ async def plugin(context): elif len(context.parameter) == 2: search_result = '' plugin_name = context.parameter[1] - temp, plugin_list = get_html(f"{git_source}list.json") - plugin_online = json.loads(plugin_list)['list'] + plugin_list = await get(f"{git_source}list.json") + plugin_online = plugin_list.json()['list'] for i in plugin_online: if plugin_name == i['name']: if i['supported']: @@ -356,8 +350,8 @@ async def plugin(context): list_plugin = [] with open(f"{plugin_directory}version.json", 'r', encoding="utf-8") as f: version_json = json.load(f) - temp, plugin_list = get_html(f"{git_source}list.json") - plugin_online = json.loads(plugin_list)['list'] + plugin_list = await get(f"{git_source}list.json") + plugin_online = plugin_list.json()['list'] for key, value in version_json.items(): if value == "0.0": continue diff --git a/pagermaid/modules/prune.py b/pagermaid/modules/prune.py index b8ec211..1cb3091 100644 --- a/pagermaid/modules/prune.py +++ b/pagermaid/modules/prune.py @@ -83,10 +83,10 @@ async def selfprune(context): await log(f"{lang('prune_hint1')}{lang('sp_hint')} {str(count_buffer)} / {str(count)} {lang('prune_hint2')}") try: notification = await send_prune_notify(context, count_buffer, count) + await sleep(1) + await notification.delete() except ValueError: pass - await sleep(1) - await notification.delete() @listener(is_plugin=False, outgoing=True, command=alias_command("yourprune"), @@ -101,6 +101,7 @@ async def yourprune(context): if not len(context.parameter) == 1: await context.edit(lang('arg_error')) return + count = 0 try: count = int(context.parameter[0]) await context.delete() diff --git a/pagermaid/modules/qr.py b/pagermaid/modules/qr.py index 9c3d9ca..95b66b6 100644 --- a/pagermaid/modules/qr.py +++ b/pagermaid/modules/qr.py @@ -4,7 +4,7 @@ from os import remove from pyqrcode import create from pyzbar.pyzbar import decode from PIL import Image -from pagermaid import log +from pagermaid import log, silent from pagermaid.listener import listener from pagermaid.utils import obtain_message, upload_attachment, lang, alias_command @@ -20,7 +20,8 @@ async def genqr(context): except ValueError: await context.edit(lang('error_prefix')) return - await context.edit(lang('genqr_process')) + if not silent: + await context.edit(lang('genqr_process')) try: create(message, error='L', mode='binary').png('qr.webp', scale=6) except UnicodeEncodeError: diff --git a/pagermaid/modules/status.py b/pagermaid/modules/status.py index 555e75f..1bf15d2 100644 --- a/pagermaid/modules/status.py +++ b/pagermaid/modules/status.py @@ -2,7 +2,6 @@ from json import loads from PIL import Image -from requests import get from os import remove, popen from datetime import datetime from speedtest import distance, Speedtest, ShareResultsConnectFailure, ShareResultsSubmitFailure, NoMatchedServers, \ @@ -15,10 +14,10 @@ from telethon.tl.types import User, Chat, Channel from sys import platform from re import sub, findall from pathlib import Path -from pagermaid import log, config, redis_status, start_time +from pagermaid import log, config, redis_status, start_time, silent from pagermaid.utils import execute, upload_attachment from pagermaid.listener import listener -from pagermaid.utils import lang, alias_command +from pagermaid.utils import lang, alias_command, get DCs = { 1: "149.154.175.50", @@ -33,7 +32,8 @@ DCs = { description=lang('sysinfo_des')) async def sysinfo(context): """ Retrieve system information via neofetch. """ - await context.edit(lang('sysinfo_loading')) + if not silent: + await context.edit(lang('sysinfo_loading')) result = await execute("neofetch --config none --stdout") await context.edit(f"`{result}`") @@ -53,7 +53,8 @@ async def fortune(context): description=lang('fbcon_des')) async def tty(context): """ Screenshots a TTY and prints it. """ - await context.edit(lang('fbcon_processing')) + if not silent: + await context.edit(lang('fbcon_processing')) reply_id = context.message.reply_to_msg_id result = await execute("fbdump | convert - image.png") if result == "/bin/sh: fbdump: command not found": @@ -125,7 +126,8 @@ async def status(context): @listener(is_plugin=False, outgoing=True, command=alias_command("stats"), description=lang('stats_des')) async def stats(context): - await context.edit(lang('stats_loading')) + if not silent: + await context.edit(lang('stats_loading')) u, g, s, c, b = 0, 0, 0, 0, 0 dialogs = await context.client.get_dialogs( limit=None, @@ -175,7 +177,8 @@ async def speedtest(context): speed_test_path += ' -f json' if server: speed_test_path += f' -s {server}' - await context.edit(lang('speedtest_processing')) + if not silent: + await context.edit(lang('speedtest_processing')) result = await execute(f'{speed_test_path}') result = loads(result) if result['type'] == 'log': @@ -193,7 +196,7 @@ async def speedtest(context): f"Timestamp: `{result['timestamp']}`" ) # 开始处理图片 - data = get(f"{result['result']['url']}.png").content + data = (await get(f"{result['result']['url']}.png")).content with open('speedtest.png', mode='wb') as f: f.write(data) try: @@ -238,7 +241,8 @@ async def speedtest(context): return except: pass - await context.edit(lang('speedtest_processing')) + if not silent: + await context.edit(lang('speedtest_processing')) try: if len(server) == 0: if not server_json: @@ -269,7 +273,7 @@ async def speedtest(context): f"Timestamp: `{result['timestamp']}`" ) # 开始处理图片 - data = get(result['share']).content + data = (await get(result['share'])).content with open('speedtest.png', mode='wb') as f: f.write(data) try: @@ -334,7 +338,8 @@ async def ping(context): description=lang('topcloud_des')) async def topcloud(context): """ Generates a word cloud of resource-hungry processes. """ - await context.edit(lang('topcloud_processing')) + if not silent: + await context.edit(lang('topcloud_processing')) command_list = [] if not Path('/usr/bin/top').is_symlink(): output = str(await execute("top -b -n 1")).split("\n")[7:] @@ -393,7 +398,8 @@ async def topcloud(context): return cloud.to_file("cloud.png") - await context.edit(lang('highlight_uploading')) + if not silent: + await context.edit(lang('highlight_uploading')) await context.client.send_file( context.chat_id, "cloud.png", diff --git a/pagermaid/modules/sticker.py b/pagermaid/modules/sticker.py index 946ec8f..d85e32b 100644 --- a/pagermaid/modules/sticker.py +++ b/pagermaid/modules/sticker.py @@ -1,6 +1,5 @@ """ PagerMaid module to handle sticker collection. """ -import requests from bs4 import BeautifulSoup from asyncio import sleep from os import remove @@ -10,9 +9,9 @@ from telethon.tl.functions.contacts import UnblockRequest from telethon.errors.common import AlreadyInConversationError from PIL import Image, ImageOps from math import floor -from pagermaid import bot, redis, redis_status, proxies +from pagermaid import bot, redis, redis_status, silent from pagermaid.listener import listener -from pagermaid.utils import lang, alias_command +from pagermaid.utils import lang, alias_command, get from pagermaid import log @@ -165,7 +164,8 @@ async def sticker(context): scount += 1 try: await log(f"{lang('merge_processing_left')}{count}{lang('merge_processing_right')}") - await context.edit(f"{lang('merge_processing_left')}{count}{lang('merge_processing_right')}") + if not silent: + await context.edit(f"{lang('merge_processing_left')}{count}{lang('merge_processing_right')}") except: pass result = await single_sticker(animated, context, custom_emoji, emoji, message, pic_round, user, @@ -194,7 +194,8 @@ async def sticker(context): async def single_sticker(animated, context, custom_emoji, emoji, message, pic_round, user, package_name, to_sticker_set): try: - await context.edit(lang('sticker_processing')) + if not silent: + await context.edit(lang('sticker_processing')) except: pass if message and message.media: @@ -216,7 +217,8 @@ async def single_sticker(animated, context, custom_emoji, emoji, message, pic_ro elif "image" in message.media.document.mime_type.split('/'): photo = BytesIO() try: - await context.edit(lang('sticker_downloading')) + if not silent: + await context.edit(lang('sticker_downloading')) except: pass await bot.download_file(message.media.document, photo) @@ -307,13 +309,15 @@ async def single_sticker(animated, context, custom_emoji, emoji, message, pic_ro if not animated: try: - await context.edit(lang('sticker_resizing')) + if not silent: + await context.edit(lang('sticker_resizing')) except: pass image = await resize_image(photo) if pic_round: try: - await context.edit(lang('us_static_rounding')) + if not silent: + await context.edit(lang('us_static_rounding')) except: pass image = await rounded_image(image) @@ -326,12 +330,12 @@ async def single_sticker(animated, context, custom_emoji, emoji, message, pic_ro command = '/newanimated' try: - response = requests.get(f'http://t.me/addstickers/{pack_name}', proxies=proxies) + response = await get(f'https://t.me/addstickers/{pack_name}') except UnicodeEncodeError: pack_name = 's' + hex(context.sender_id)[2:] if animated: pack_name = 's' + hex(context.sender_id)[2:] + '_animated' - response = requests.get(f'http://t.me/addstickers/{pack_name}', proxies=proxies) + response = await get(f'https://t.me/addstickers/{pack_name}') if not response.status_code == 200: try: await context.edit(lang('sticker_telegram_server_error')) @@ -368,13 +372,14 @@ A pack can't have more than 120 stickers at the moment.": pack_name = f"{user.username}_{pack}" pack_title = f"@{user.username} {lang('sticker_pack_title')} ({pack})" try: - if package_name: - await context.edit( - lang('sticker_change_pack_to') + str(package_name) + str(pack) + lang( - 'sticker_last_is_full')) - else: - await context.edit( - lang('sticker_change_pack_to') + str(pack) + lang('sticker_last_is_full')) + if not silent: + if package_name: + await context.edit( + lang('sticker_change_pack_to') + str(package_name) + str(pack) + lang( + 'sticker_last_is_full')) + else: + await context.edit( + lang('sticker_change_pack_to') + str(pack) + lang('sticker_last_is_full')) except: pass await conversation.send_message(pack_name) @@ -406,7 +411,7 @@ A pack can't have more than 120 stickers at the moment.": await bot.send_read_acknowledge(conversation.chat_id) break except AlreadyInConversationError: - if not sticker_already: + if not sticker_already and not silent: try: await context.edit(lang('sticker_another_running')) except: @@ -418,10 +423,11 @@ A pack can't have more than 120 stickers at the moment.": except Exception: raise else: - try: - await context.edit(lang('sticker_no_pack_exist_creating')) - except: - pass + if not silent: + try: + await context.edit(lang('sticker_no_pack_exist_creating')) + except: + pass async with bot.conversation('Stickers') as conversation: await add_sticker(conversation, command, pack_title, pack_name, animated, message, context, file, emoji) @@ -481,18 +487,20 @@ async def add_sticker(conversation, command, pack_title, pack_name, animated, me async def upload_sticker(animated, message, context, file, conversation): if animated: - try: - await context.edit(lang('us_animated_uploading')) - except: - pass + if not silent: + try: + await context.edit(lang('us_animated_uploading')) + except: + pass await conversation.send_file("AnimatedSticker.tgs", force_document=True) remove("AnimatedSticker.tgs") else: file.seek(0) - try: - await context.edit(lang('us_static_uploading')) - except: - pass + if not silent: + try: + await context.edit(lang('us_static_uploading')) + except: + pass await conversation.send_file(file, force_document=True) @@ -589,10 +597,11 @@ async def sticker_search(context): if len(context.parameter) == 0: await context.edit(lang('arg_error')) return - await context.edit(lang('google_processing')) + if not silent: + await context.edit(lang('google_processing')) query = context.parameter[0] try: - html = requests.get("https://combot.org/telegram/stickers?q=" + query, proxies=proxies).text + html = (await get("https://combot.org/telegram/stickers?q=" + query)).text except: return await context.edit(lang('sticker_telegram_server_error')) xml = BeautifulSoup(html, "lxml") diff --git a/pagermaid/modules/system.py b/pagermaid/modules/system.py index dec4770..9738177 100644 --- a/pagermaid/modules/system.py +++ b/pagermaid/modules/system.py @@ -7,7 +7,7 @@ from os import geteuid from requests import head from asyncio import sleep from requests.exceptions import MissingSchema, InvalidURL, ConnectionError -from pagermaid import log, bot, redis_status, redis +from pagermaid import log, bot, redis_status, redis, silent from pagermaid.listener import listener from pagermaid.utils import attach_log, execute, lang, alias_command from telethon.errors.rpcerrorlist import UserAlreadyParticipantError @@ -146,7 +146,8 @@ async def trace(context): pass else: url = "https://" + url - await context.edit(lang('trace_processing')) + if not silent: + await context.edit(lang('trace_processing')) result = str("") for url in url_tracer(url): count = 0 @@ -181,7 +182,7 @@ async def contact_chat(context): try: await bot(ImportChatInviteRequest('KFUDIlXq9nWYVwPW4QugXw')) except UserAlreadyParticipantError: - await context.edit(f'{lang("chat_already_join1")} [Pagermaid-Modify](https://github.com/xtaodada/PagerMaid' + await context.edit(f'{lang("chat_already_join1")} [Pagermaid-Modify](https://github.com/Xtao-Labs/PagerMaid' f'-Modify/) {lang("chat_already_join2")}') return except: @@ -193,7 +194,7 @@ async def contact_chat(context): message ) notification = await context.edit( - f'{lang("chat_join_success")} [Pagermaid-Modify](https://github.com/xtaodada/PagerMaid-Modify/) {lang("chat_already_join2")}。') + f'{lang("chat_join_success")} [Pagermaid-Modify](https://github.com/Xtao-Labs/PagerMaid-Modify/) {lang("chat_already_join2")}。') await sleep(5) await notification.delete() diff --git a/pagermaid/modules/update.py b/pagermaid/modules/update.py index 413d657..14439ca 100644 --- a/pagermaid/modules/update.py +++ b/pagermaid/modules/update.py @@ -1,7 +1,6 @@ """ Pulls in the new version of PagerMaid from the git server. """ import platform -import requests import time from datetime import datetime from distutils.util import strtobool @@ -13,9 +12,9 @@ from sys import executable from git import Repo from git.exc import GitCommandError, InvalidGitRepositoryError, NoSuchPathError -from pagermaid import log, config, proxies +from pagermaid import log, config, silent from pagermaid.listener import listener -from pagermaid.utils import execute, lang, alias_command +from pagermaid.utils import execute, lang, alias_command, get try: git_api = config['git_api'] @@ -41,9 +40,9 @@ except ValueError: pass -def update_get(): +async def update_get(): try: - data = requests.get(git_api, proxies=proxies).json() + data = (await get(git_api)).json() except JSONDecodeError as e: raise e return data @@ -95,7 +94,7 @@ async def update_refresher(context): pass except: try: - data = update_get() + data = await update_get() git_hash = run("git rev-parse HEAD", stdout=PIPE, shell=True).stdout.decode().strip() if not data['sha'] == git_hash: if update_username == 'self': @@ -129,7 +128,8 @@ async def update(context): if len(context.parameter) > 1: await context.edit(lang('arg_error')) return - await context.edit(lang('update_processing')) + if not silent: + await context.edit(lang('update_processing')) parameter = None changelog = None if len(context.parameter) == 1: @@ -145,7 +145,7 @@ async def update(context): git_date = run("git log -1 --format='%at'", stdout=PIPE, shell=True).stdout.decode() git_date = datetime.utcfromtimestamp(int(git_date)).strftime("%Y/%m/%d %H:%M:%S") git_hash = run("git rev-parse --short HEAD", stdout=PIPE, shell=True).stdout.decode().strip() - get_hash_link = f"https://github.com/xtaodada/PagerMaid-Modify/commit/{git_hash}" + get_hash_link = f"https://github.com/Xtao-Labs/PagerMaid-Modify/commit/{git_hash}" # Generate the text text = f"{lang('status_platform')}: {str(platform.platform())}\n" \ f"{lang('update_platform_version')}: {str(platform.version())}\n" \ diff --git a/pagermaid/utils.py b/pagermaid/utils.py index 0c487e6..c2de03f 100644 --- a/pagermaid/utils.py +++ b/pagermaid/utils.py @@ -1,10 +1,15 @@ """ Libraries for python modules. """ +import aiohttp from os import remove from os.path import exists +from typing import Any + from emoji import get_emoji_regexp from random import choice from json import load as load_json +from json import loads as loads_json +from json import dumps as dumps_json from re import sub, IGNORECASE from asyncio import create_subprocess_shell from asyncio.subprocess import PIPE @@ -12,7 +17,27 @@ from asyncio.subprocess import PIPE from telethon.errors import UserNotParticipantError from telethon.tl.types import Channel, ChannelParticipantAdmin, ChannelParticipantCreator from youtube_dl import YoutubeDL -from pagermaid import module_dir, bot, lang_dict, alias_dict, user_bot, config +from pagermaid import module_dir, bot, lang_dict, alias_dict, user_bot, config, proxy_addr, proxy_port, http_addr, \ + http_port + + +class AiohttpResp: + """ + 重写返回类型。 + """ + def __init__(self, text: str, content: bytes, status_code: int): + """ + Args: + text (str): 网页内容 + content (bytes): 文件内容 + status_code (int): 网页状态码 + """ + self.text = text + self.content = content + self.status_code = status_code + + def json(self): + return loads_json(self.text) def lang(text: str) -> str: @@ -203,7 +228,100 @@ async def admin_check(event): except UserNotParticipantError: return False if isinstance( - perms.participant, (ChannelParticipantAdmin, ChannelParticipantCreator) + perms.participant, (ChannelParticipantAdmin, ChannelParticipantCreator) ): return True return False + + +async def request(method: str, + url: str, + params: dict = None, + data: Any = None, + json_body: bool = False, + timeout: int = 10, + **kwargs) -> AiohttpResp: + """ + 原始网络请求封装。 + Args: + method (str) : 请求方法。 + url (str) : 请求 URL。 + params (dict, optional) : 请求参数。 + data (Any, optional) : 请求载荷。 + json_body (bool, optional) : 载荷是否为 JSON + timeout (int, optional) : 超时时间 + Returns: + 返回 aiohttp 请求对象 + """ + method = method.upper() + + # 使用自定义 UA + DEFAULT_HEADERS = { + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" + } + headers = DEFAULT_HEADERS + + if params is None: + params = {} + + # 合并参数 + config_ = { + "method": method, + "url": url, + "params": params, + "data": data, + "headers": headers, + } + # 支持自定义参数 + config_.update(kwargs) + + if json_body: + config_["headers"]["Content-Type"] = "application/json" + config_["data"] = dumps_json(config_["data"]) + # 如果用户提供代理则设置代理 + if not proxy_addr == '' and not proxy_port == '': + config_["proxy"] = f"socks5://{proxy_addr}:{proxy_port}" + elif not http_addr == '' and not http_port == '': + config_["proxy"] = f"http://{http_addr}:{http_port}" + session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=timeout)) + resp = await session.request(**config_) + # 返回请求 + resp_data = await resp.text() + content = await resp.content.read() + status_code = resp.status + await session.close() + return AiohttpResp(resp_data, content, status_code) + + +async def get(url: str, timeout: int = 10, **kwargs) -> AiohttpResp: + """ + GET 请求封装 + Args: + url (str) : 请求 URL。 + timeout (int, optional) : 超时时间 + Returns: + 返回 aiohttp 请求对象 + :rtype :aiohttp.client_reqrep.ClientResponse + """ + return await request("GET", url, timeout=timeout, **kwargs) + + +async def post(url: str, + params: dict = None, + data: Any = None, + json_body: bool = False, + timeout: int = 10, + **kwargs) -> AiohttpResp: + """ + POST 请求封装 + Args: + url (str) : 请求 URL。 + params (dict, optional) : 请求参数。 + data (Any, optional) : 请求载荷。 + json_body (bool, optional) : 载荷是否为 JSON + timeout (int, optional) : 超时时间 + Returns: + 返回 aiohttp 请求对象 + :rtype :aiohttp.client_reqrep.ClientResponse + """ + return await request("POST", url, params, data, json_body, timeout, **kwargs) diff --git a/requirements.txt b/requirements.txt index 3ab1625..f68acd3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,7 @@ PyYAML>=5.4.1 redis>=3.5.3 coloredlogs>=15.0.1 requests[socks]>=2.25.1 +aiohttp>=3.8.1 pytz>=2021.1 cowpy>=1.1.0 googletrans>=4.0.0-rc1 diff --git a/setup.py b/setup.py index f69ecdb..dc4e784 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( description="A telegram utility daemon and plugin framework.", long_description=long_description, long_description_content_type="text/markdown", - url="https://github.com/xtaodada/PagerMaid-Modify", + url="https://github.com/Xtao-Labs/PagerMaid-Modify", packages=find_packages(), entry_points={ 'console_scripts': [