diff --git a/languages/built-in/en.yml b/languages/built-in/en.yml index ed8a039..bb1d076 100644 --- a/languages/built-in/en.yml +++ b/languages/built-in/en.yml @@ -167,6 +167,7 @@ translate_des: Translate the target message into the specified language through translate_parameters: translate_processing: The translation is being generated... translate_ValueError: Something went wrong ~ The target language could not be found, please correct the error in the configuration file. +translate_ImportError: Something went wrong ~ The translators module could not be found. translate_hits: text translation translate_original_lang: source language translate_tg_limit_uploading_file: The output exceeds the TG limit, and it is trying to upload a file. @@ -461,6 +462,7 @@ This command is only for developers. If you know what you are doing, please manu # restart restart_des: Restart PagerMaid-Modify restart_processing: Try to restart PagerMaid-Modify. +restart_complete: PagerMaid-Modify has been restarted. restart_log: PagerMaid-Modify restarts. # trace trace_des: Trace the redirection of the URL. diff --git a/languages/built-in/zh-cn.yml b/languages/built-in/zh-cn.yml index cfcdbbf..6013593 100644 --- a/languages/built-in/zh-cn.yml +++ b/languages/built-in/zh-cn.yml @@ -176,6 +176,7 @@ translate_des: 通过 Google 翻译将目标消息翻译成指定的语言。( translate_parameters: <文本> translate_processing: 正在生成翻译中 . . . translate_ValueError: 出错了呜呜呜 ~ 找不到目标语言,请更正配置文件中的错误。 +translate_ImportError: 出错了呜呜呜 ~ 请先安装 translators 模块。 translate_hits: 文本翻译 translate_original_lang: 源语言 translate_tg_limit_uploading_file: 输出超出 TG 限制,正在尝试上传文件。 @@ -475,7 +476,8 @@ eval_need_dev: '**请注意:此命令可以直接操作您的账户** 此命令仅适用于开发者,如果您知道您在做什么的话,请手动在 Redis 数据库配置 dev 项为任意值或者在 data 文件夹下创建 dev 文件。' ## restart restart_des: 使 PagerMaid-Modify 重新启动 -restart_processing: 尝试重新启动 PagerMaid-Modify. +restart_processing: 尝试重启 PagerMaid-Modify... +restart_complete: PagerMaid-Modify 重启完成。 restart_log: PagerMaid-Modify 重新启动。 ## trace trace_des: 跟踪 URL 的重定向。 diff --git a/languages/built-in/zh-tw.yml b/languages/built-in/zh-tw.yml index 593cf5e..59147df 100644 --- a/languages/built-in/zh-tw.yml +++ b/languages/built-in/zh-tw.yml @@ -167,6 +167,7 @@ translate_des: 透過Google翻譯把目標訊息翻譯成指定的語言。( translate_parameters: <文字> translate_processing: 正在生成翻譯… translate_ValueError: Error!找不到目標語言,請更正設定檔! +translate_ImportError: Error!請先安裝 translators 模組! translate_hits: 文字翻譯 translate_original_lang: 源語言 translate_tg_limit_uploading_file: 輸出超過限制,正在嘗試上傳檔案。 @@ -460,8 +461,9 @@ eval_need_dev: '**請注意:此命令可以直接操作您的賬戶** 此命令僅適用於開發者,如果您知道您在做什麼的話,請手動在 Redis 數據庫配置 dev 項為任意值或者在 data 文件夾下創建 dev 文件。' # restart restart_des: 重新啟動 -restart_processing: 嘗試重新啟動 -restart_log: 已重新啟動 +restart_processing: 正在嘗試重新啟動 +restart_complete: 重新啟動 +restart_log: 重新啟動 PagerMaid-Modify # trace trace_des: 跟蹤URL的重新導向。 trace_processing: 跟蹤中… diff --git a/pagermaid/__init__.py b/pagermaid/__init__.py index 887fb70..ed78eb1 100644 --- a/pagermaid/__init__.py +++ b/pagermaid/__init__.py @@ -78,6 +78,7 @@ except Exception as e: print("Reading language YAML file failed") print(e) exit(1) + # Customization try: with open(f"languages/custom.yml", "r", encoding="utf-8") as f: @@ -266,10 +267,6 @@ async def save_id(): logs.info(f"{lang('save_id')} {me.first_name}({user_id})") -with bot: - bot.loop.run_until_complete(save_id()) - - def before_send(event, hint): global report_time exc_info = hint.get("exc_info") @@ -299,6 +296,8 @@ def before_send(event, hint): report_time = time() return event +with bot: + bot.loop.run_until_complete(save_id()) report_time = time() start_time = datetime.utcnow() diff --git a/pagermaid/__main__.py b/pagermaid/__main__.py index fd8ffe4..16cf178 100644 --- a/pagermaid/__main__.py +++ b/pagermaid/__main__.py @@ -3,8 +3,10 @@ from sys import path from importlib import import_module from telethon.errors.rpcerrorlist import PhoneNumberInvalidError -from pagermaid import bot, logs, working_dir, user_bot +from pagermaid import bot, logs, working_dir, user_bot, redis, redis_status from pagermaid.utils import lang + + if not user_bot: from pagermaid.modules import module_list, plugin_list else: @@ -27,6 +29,7 @@ try: except PhoneNumberInvalidError: print(lang('PhoneNumberInvalidError')) exit(1) + for module_name in module_list: try: if user_bot: @@ -35,16 +38,35 @@ for module_name in module_list: import_module("pagermaid.modules." + module_name) except BaseException as exception: logs.info(f"{lang('module')} {module_name} {lang('error')}: {type(exception)}: {exception}") + for plugin_name in plugin_list: try: import_module("plugins." + plugin_name) except BaseException as exception: logs.info(f"{lang('module')} {plugin_name} {lang('error')}: {exception}") plugin_list.remove(plugin_name) + if server is not None: import_module("pagermaid.interface") + logs.info(lang('start')) + +if redis_status(): + async def _restart_complete_report(): + restart_args = redis.get("restart_edit") + if restart_args: + redis.delete("restart_edit") + restart_args = restart_args.decode("utf-8") + restart_msg, restart_chat = restart_args.split("|") + await bot.edit_message( + restart_chat, restart_msg, + lang('restart_complete') + ) + + bot.loop.create_task(_restart_complete_report()) + bot.run_until_disconnected() + if server is not None: try: server.stop() diff --git a/pagermaid/modules/help.py b/pagermaid/modules/help.py index b98dde8..acd4fb7 100644 --- a/pagermaid/modules/help.py +++ b/pagermaid/modules/help.py @@ -2,7 +2,7 @@ from os import listdir from json import dump as json_dump -from pagermaid import help_messages, alias_dict +from pagermaid import help_messages, alias_dict, redis_status, redis from pagermaid.utils import lang, alias_command from pagermaid.listener import listener, config @@ -83,7 +83,9 @@ async def lang_change(context): file = file.replace(f'application_language: "{from_lang}"', f'application_language: "{to_lang}"') with open('config.yml', 'w') as f: f.write(file) - await context.edit(f"{lang('lang_change_to')} {to_lang}, {lang('lang_reboot')}") + result = await context.edit(f"{lang('lang_change_to')} {to_lang}, {lang('lang_reboot')}") + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await context.client.disconnect() else: await context.edit( @@ -116,7 +118,9 @@ async def alias_commands(context): del alias_dict[source_command] with open("data/alias.json", 'w') as f: json_dump(alias_dict, f) - await context.edit(lang('alias_success')) + result = await context.edit(lang('alias_success')) + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await context.client.disconnect() except KeyError: await context.edit(lang('alias_no_exist')) @@ -130,5 +134,7 @@ async def alias_commands(context): alias_dict[source_command] = to_command with open("data/alias.json", 'w') as f: json_dump(alias_dict, f) - await context.edit(lang('alias_success')) + result = await context.edit(lang('alias_success')) + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await context.client.disconnect() diff --git a/pagermaid/modules/plugin.py b/pagermaid/modules/plugin.py index f801a68..0b181e5 100644 --- a/pagermaid/modules/plugin.py +++ b/pagermaid/modules/plugin.py @@ -6,7 +6,7 @@ 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 +from pagermaid import log, working_dir, config, redis_status, redis from pagermaid.listener import listener from pagermaid.utils import upload_attachment, lang, alias_command, client from pagermaid.modules import plugin_list as active_plugins, __list_plugins @@ -83,8 +83,10 @@ async def plugin(context): pass return move_plugin(file_path) - await context.edit( + result = await context.edit( f"{lang('apt_plugin')} {path.basename(file_path)[:-3]} {lang('apt_installed')},{lang('apt_reboot')}") + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await log(f"{lang('apt_install_success')} {path.basename(file_path)[:-3]}.") await context.client.disconnect() elif len(context.parameter) >= 2: @@ -136,8 +138,10 @@ async def plugin(context): restart = len(success_list) > 0 if restart: message += lang('apt_reboot') - await context.edit(message) + result = await context.edit(message) if restart: + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await context.client.disconnect() else: await context.edit(lang('arg_error')) @@ -150,7 +154,10 @@ async def plugin(context): version_json[context.parameter[1]] = '0.0' with open(f"{plugin_directory}version.json", 'w') as f: json.dump(version_json, f) - await context.edit(f"{lang('apt_remove_success')} {context.parameter[1]}, {lang('apt_reboot')} ") + result = await context.edit( + f"{lang('apt_remove_success')} {context.parameter[1]}, {lang('apt_reboot')} ") + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await log(f"{lang('apt_remove')} {context.parameter[1]}.") await context.client.disconnect() elif exists(f"{plugin_directory}{context.parameter[1]}.py.disabled"): @@ -209,8 +216,10 @@ async def plugin(context): if exists(f"{plugin_directory}{context.parameter[1]}.py.disabled"): rename(f"{plugin_directory}{context.parameter[1]}.py.disabled", f"{plugin_directory}{context.parameter[1]}.py") - await context.edit( + result = await context.edit( f"{lang('apt_plugin')} {context.parameter[1]} {lang('apt_enable')},{lang('apt_reboot')}") + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await log(f"{lang('apt_enable')} {context.parameter[1]}.") await context.client.disconnect() else: @@ -222,8 +231,10 @@ async def plugin(context): if exists(f"{plugin_directory}{context.parameter[1]}.py") is True: rename(f"{plugin_directory}{context.parameter[1]}.py", f"{plugin_directory}{context.parameter[1]}.py.disabled") - await context.edit( + result = await context.edit( f"{lang('apt_plugin')} {context.parameter[1]} {lang('apt_disable')},{lang('apt_reboot')}") + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await log(f"{lang('apt_disable')} {context.parameter[1]}.") await context.client.disconnect() else: @@ -296,7 +307,9 @@ async def plugin(context): version_json[i] = m['version'] with open(f"{plugin_directory}version.json", 'w') as f: json.dump(version_json, f) - await context.edit(lang('apt_reading_list') + need_update) + result = await context.edit(lang('apt_reading_list') + need_update) + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await context.client.disconnect() elif context.parameter[0] == "search": if len(context.parameter) == 1: diff --git a/pagermaid/modules/status.py b/pagermaid/modules/status.py index 745a04a..d36af90 100644 --- a/pagermaid/modules/status.py +++ b/pagermaid/modules/status.py @@ -1,24 +1,25 @@ """ PagerMaid module that contains utilities related to system status. """ -from json import loads -from PIL import Image -from os import remove, popen from datetime import datetime +from json import loads +from os import remove, popen +from pathlib import Path +from platform import python_version, uname +from re import sub, findall +from sys import platform + +from PIL import Image +from requests import get 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 from telethon.tl.types import User, Chat, Channel -from sys import platform -from re import sub, findall -from requests import get -from pathlib import Path -from pagermaid import log, config, redis_status, start_time, silent -from pagermaid.utils import execute, upload_attachment, lang, alias_command -from pagermaid.listener import listener +from wordcloud import WordCloud +from pagermaid import log, config, redis_status, start_time, silent, bot +from pagermaid.listener import listener +from pagermaid.utils import execute, upload_attachment, lang, alias_command DCs = { 1: "149.154.175.50", @@ -324,15 +325,18 @@ async def pingdc(context): ) -@listener(is_plugin=False, outgoing=True, command=alias_command("ping"), - description=lang('ping_des')) +@listener(is_plugin=False, outgoing=True, command=alias_command("ping"), description=lang('ping_des')) async def ping(context): """ Calculates latency between PagerMaid and Telegram. """ start = datetime.now() + await bot(functions.PingRequest(ping_id=0)) + end = datetime.now() + ping_duration = (end - start).microseconds / 1000 + start = datetime.now() await context.edit("Pong!") end = datetime.now() - duration = (end - start).microseconds / 1000 - await context.edit(f"Pong!|{duration}") + msg_duration = (end - start).microseconds / 1000 + await context.edit(f"Pong!| PING: {ping_duration} | MSG: {msg_duration}") @listener(is_plugin=False, outgoing=True, command=alias_command("topcloud"), diff --git a/pagermaid/modules/system.py b/pagermaid/modules/system.py index 4bef142..7ce6344 100644 --- a/pagermaid/modules/system.py +++ b/pagermaid/modules/system.py @@ -132,7 +132,13 @@ async def sh(context): async def restart(context): """ To re-execute PagerMaid. """ if not context.text[0].isalpha(): - await context.edit(lang('restart_processing')) + try: + result = await context.edit(lang('restart_processing')) + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") + + except: # noqa + pass await log(lang('restart_log')) await context.client.disconnect() diff --git a/pagermaid/modules/update.py b/pagermaid/modules/update.py index 1a7dc9a..88f5977 100644 --- a/pagermaid/modules/update.py +++ b/pagermaid/modules/update.py @@ -14,7 +14,7 @@ from git.exc import GitCommandError, InvalidGitRepositoryError, NoSuchPathError from telethon.tl.functions.channels import GetFullChannelRequest -from pagermaid import log, config, silent, scheduler, bot, version, working_dir, logs +from pagermaid import log, config, silent, scheduler, bot, version, working_dir, logs, redis_status, redis from pagermaid.listener import listener from pagermaid.modules.plugin import remove_plugin, update_version, download from pagermaid.utils import execute, lang, alias_command @@ -29,17 +29,19 @@ except KeyError: @scheduler.scheduled_job("cron", minute="*/30", id="0") async def run_every_30_minute(): - if not need_update_check: + try: + await bot(GetFullChannelRequest("PGMUPD1")) + except: # noqa return - result = await bot(GetFullChannelRequest("PGMUPD1")) # noqa + + need_restart = False async for msg in bot.iter_messages("PGMUPD1"): if msg.text: try: - data_ = loads(msg.text.strip("`")) + security_data = loads(msg.text.strip("`")) except JSONDecodeError: continue - need_restart = False - for data in data_["data"]: + for data in security_data["data"]: if data["mode"] == "master": if version < data["version"]: logs.info(lang('update_master')) @@ -48,23 +50,31 @@ async def run_every_30_minute(): await execute(f"{executable} -m pip install -r requirements.txt --upgrade") await execute(f"{executable} -m pip install -r requirements.txt") need_restart = True + break elif data["mode"] == "plugins": if not exists(f"{working_dir}/plugins/version.json"): - return + continue with open(f"{working_dir}/plugins/version.json", 'r', encoding="utf-8") as f: - version_json = load(f) + try: + version_json = load(f) + except JSONDecodeError: + continue try: - plugin_version = version_json[data["name"]] - except KeyError: - return + plugin_version = version_json.get(data["name"]) + if plugin_version is None: + continue + except AttributeError: + continue + if (float(data["version"]) - float(plugin_version)) > 0: logs.info(lang('update_plugins')) remove_plugin(data["name"]) await download(data["name"]) update_version(data["name"], data["version"]) need_restart = True - if need_restart: - await bot.disconnect() + + if need_restart: + await bot.disconnect() @listener(is_plugin=False, outgoing=True, command=alias_command("update"), @@ -191,12 +201,16 @@ async def update(context): await execute(f"{executable} -m pip install -r requirements.txt --upgrade") await execute(f"{executable} -m pip install -r requirements.txt") await log(f"PagerMaid-Modify {lang('update_is_updated')}") - await context.edit(lang('update_success') + lang('apt_reboot')) + result = await context.edit(lang('update_success') + lang('apt_reboot')) + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await context.client.disconnect() except GitCommandError: upstream_remote.git.reset('--hard') await log(lang('update_failed')) - await context.edit(lang('update_failed') + lang('apt_reboot')) + result = await context.edit(lang('update_failed') + lang('apt_reboot')) + if redis_status(): + redis.set("restart_edit", f"{result.id}|{result.peer_id.channel_id}") await context.client.disconnect()