🔖 Update to v1.3.4

This commit is contained in:
xtaodada 2023-06-18 11:13:16 +08:00
parent 41db62feb0
commit 0cb44d621d
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
13 changed files with 178 additions and 109 deletions

6
.gitignore vendored
View File

@ -116,11 +116,11 @@ env.bak/
venv.bak/ venv.bak/
config.env config.env
config.yml config.yml
pagermaid.session *.session
pagermaid.session-journal *.session-journal
*.pagermaid *.pagermaid
docker-compose.yml docker-compose.yml
plugins/ plugins*/
data/* data/*
pagermaid.egg-info/ pagermaid.egg-info/
dump.rdb dump.rdb

View File

@ -58,7 +58,7 @@ mtp_port: ""
mtp_secret: "" mtp_secret: ""
# Apt Git source # Apt Git source
git_source: "https://raw.githubusercontent.com/TeamPGM/PagerMaid_Plugins_Pyro/v2/" git_source: "https://v2.xtaolabs.com/"
git_ssh: "https://github.com/TeamPGM/PagerMaid-Pyro.git" git_ssh: "https://github.com/TeamPGM/PagerMaid-Pyro.git"
# Update Notice # Update Notice

View File

@ -21,8 +21,8 @@ from pagermaid.scheduler import scheduler
import pyromod.listen import pyromod.listen
from pyrogram import Client from pyrogram import Client
pgm_version = "1.3.3" pgm_version = "1.3.4"
pgm_version_code = 1303 pgm_version_code = 1304
CMD_LIST = {} CMD_LIST = {}
module_dir = __path__[0] module_dir = __path__[0]
working_dir = getcwd() working_dir = getcwd()
@ -76,7 +76,7 @@ bot = Client(
api_hash=Config.API_HASH, api_hash=Config.API_HASH,
ipv6=Config.IPV6, ipv6=Config.IPV6,
proxy=Config.PROXY, proxy=Config.PROXY,
app_version=f"PagerMaid {pgm_version}", app_version=f"PGP {pgm_version}",
) )
bot.job = scheduler bot.job = scheduler

View File

@ -1,58 +1,73 @@
from sys import path, platform import asyncio
from os import sep from os import sep
from importlib import import_module from signal import signal as signal_fn, SIGINT, SIGTERM, SIGABRT
from sys import path, platform
from pyrogram import idle
from pyrogram.errors import AuthKeyUnregistered from pyrogram.errors import AuthKeyUnregistered
from pagermaid import bot, logs, working_dir from pagermaid import bot, logs, working_dir
from pagermaid.common.plugin import plugin_manager from pagermaid.common.reload import load_all
from pagermaid.hook import Hook
from pagermaid.modules import module_list, plugin_list
from pagermaid.single_utils import safe_remove from pagermaid.single_utils import safe_remove
from pagermaid.utils import lang, process_exit from pagermaid.utils import lang, process_exit
from pagermaid.web import web
from pyromod.methods.sign_in_qrcode import start_client from pyromod.methods.sign_in_qrcode import start_client
path.insert(1, f"{working_dir}{sep}plugins") path.insert(1, f"{working_dir}{sep}plugins")
async def main(): async def idle():
logs.info(lang("platform") + platform + lang("platform_load")) task = None
def signal_handler(_, __):
if web.web_server_task:
web.web_server_task.cancel()
task.cancel()
for s in (SIGINT, SIGTERM, SIGABRT):
signal_fn(s, signal_handler)
while True:
task = asyncio.create_task(asyncio.sleep(600))
web.bot_main_task = task
try:
await task
except asyncio.CancelledError:
break
async def console_bot():
try: try:
await start_client(bot) await start_client(bot)
except AuthKeyUnregistered: except AuthKeyUnregistered:
safe_remove("pagermaid.session") safe_remove("pagermaid.session")
exit() exit()
me = await bot.get_me() me = await bot.get_me()
if me.is_bot: if me.is_bot:
safe_remove("pagermaid.session") safe_remove("pagermaid.session")
exit() exit()
logs.info(f"{lang('save_id')} {me.first_name}({me.id})") logs.info(f"{lang('save_id')} {me.first_name}({me.id})")
await load_all()
for module_name in module_list:
try:
import_module(f"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.copy():
try:
import_module(f"plugins.{plugin_name}")
except BaseException as exception:
logs.info(f"{lang('module')} {plugin_name} {lang('error')}: {exception}")
plugin_list.remove(plugin_name)
plugin_manager.load_local_plugins()
await process_exit(start=True, _client=bot) await process_exit(start=True, _client=bot)
logs.info(lang("start"))
await Hook.load_success_exec()
await Hook.startup()
async def main():
logs.info(lang("platform") + platform + lang("platform_load"))
await web.start()
await console_bot()
logs.info(lang("start"))
try:
await idle() await idle()
finally:
try:
await bot.stop() await bot.stop()
except ConnectionError:
pass
if web.web_server:
try:
await web.web_server.shutdown()
except AttributeError:
pass
bot.run(main()) bot.run(main())

View File

@ -53,3 +53,22 @@ async def reload_all():
plugin_manager.load_local_plugins() plugin_manager.load_local_plugins()
plugin_manager.save_local_version_map() plugin_manager.save_local_version_map()
await Hook.load_success_exec() await Hook.load_success_exec()
async def load_all():
for module_name in pagermaid.modules.module_list.copy():
try:
importlib.import_module(f"pagermaid.modules.{module_name}")
except BaseException as exception:
logs.info(
f"{lang('module')} {module_name} {lang('error')}: {type(exception)}: {exception}"
)
for plugin_name in pagermaid.modules.plugin_list.copy():
try:
importlib.import_module(f"plugins.{plugin_name}")
except BaseException as exception:
logs.info(f"{lang('module')} {plugin_name} {lang('error')}: {exception}")
pagermaid.modules.plugin_list.remove(plugin_name)
plugin_manager.load_local_plugins()
await Hook.load_success_exec()
await Hook.startup()

View File

@ -91,6 +91,12 @@ class Config:
"TeamPGM/PagerMaid_Plugins/", "TeamPGM/PagerMaid_Plugins_Pyro/" "TeamPGM/PagerMaid_Plugins/", "TeamPGM/PagerMaid_Plugins_Pyro/"
) )
try: try:
with open(
f"languages{os.sep}built-in{os.sep}en.yml",
"r",
encoding="utf-8",
) as f:
lang_default_dict = safe_load(f)
with open( with open(
f"languages{os.sep}built-in{os.sep}{LANGUAGE}.yml", f"languages{os.sep}built-in{os.sep}{LANGUAGE}.yml",
"r", "r",
@ -104,7 +110,7 @@ class Config:
print(e) print(e)
try: try:
with open( with open(
f"languages{os.sep}built-in{os.sep}{LANGUAGE}.yml", f"languages{os.sep}built-in{os.sep}en.yml",
"r", "r",
encoding="utf-8", encoding="utf-8",
) as f: ) as f:

View File

@ -1,14 +1,14 @@
from os.path import exists, sep
from sys import exit
from platform import node
from getpass import getuser from getpass import getuser
from os.path import exists, sep
from platform import node
from pyrogram.enums import ParseMode from pyrogram.enums import ParseMode
from pagermaid.common.system import run_eval from pagermaid.common.system import run_eval
from pagermaid.listener import listener
from pagermaid.enums import Message from pagermaid.enums import Message
from pagermaid.listener import listener
from pagermaid.utils import attach_log, execute, lang, upload_attachment from pagermaid.utils import attach_log, execute, lang, upload_attachment
from pagermaid.web import web
@listener( @listener(
@ -51,7 +51,7 @@ async def restart(message: Message):
"""To re-execute PagerMaid.""" """To re-execute PagerMaid."""
if not message.text[0].isalpha(): if not message.text[0].isalpha():
await message.edit(lang("restart_log")) await message.edit(lang("restart_log"))
exit(0) web.stop()
@listener( @listener(

View File

@ -1,20 +0,0 @@
from pagermaid import logs
from pagermaid.config import Config
from pagermaid.hook import Hook
from pagermaid.services import bot
@Hook.on_startup()
async def init_web():
if not Config.WEB_ENABLE:
return
if not Config.WEB_SECRET_KEY:
logs.warning("未设置 WEB_SECRET_KEY ,请勿将 PagerMaid-Pyro 暴露在公网")
import uvicorn
from pagermaid.web import app, init_web
init_web()
server = uvicorn.Server(
config=uvicorn.Config(app, host=Config.WEB_HOST, port=Config.WEB_PORT)
)
bot.loop.create_task(server.serve())

View File

@ -19,7 +19,7 @@ from pagermaid.single_utils import _status_sudo, get_sudo_list, Message, sqlite
def lang(text: str) -> str: def lang(text: str) -> str:
"""i18n""" """i18n"""
return Config.lang_dict.get(text, text) return Config.lang_dict.get(text, Config.lang_default_dict.get(text, text))
def alias_command(command: str, disallow_alias: bool = False) -> str: def alias_command(command: str, disallow_alias: bool = False) -> str:

View File

@ -1,8 +1,11 @@
import asyncio
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from starlette.middleware.cors import CORSMiddleware from starlette.middleware.cors import CORSMiddleware
from starlette.responses import RedirectResponse from starlette.responses import RedirectResponse
from pagermaid import logs
from pagermaid.config import Config from pagermaid.config import Config
from pagermaid.web.api import base_api_router from pagermaid.web.api import base_api_router
from pagermaid.web.pages import admin_app, login_page from pagermaid.web.pages import admin_app, login_page
@ -25,13 +28,19 @@ responseAdaptor(api, payload, query, request, response) {
}, },
""" """
icon_path = "https://xtaolabs.com/pagermaid-logo.png" icon_path = "https://xtaolabs.com/pagermaid-logo.png"
app: FastAPI = FastAPI()
def init_web(): class Web:
app.include_router(base_api_router) def __init__(self):
self.app: FastAPI = FastAPI()
self.web_server = None
self.web_server_task = None
self.bot_main_task = None
app.add_middleware( def init_web(self):
self.app.include_router(base_api_router)
self.app.add_middleware(
CORSMiddleware, CORSMiddleware,
allow_origins=Config.WEB_ORIGINS, allow_origins=Config.WEB_ORIGINS,
allow_credentials=True, allow_credentials=True,
@ -39,11 +48,11 @@ def init_web():
allow_headers=["*"], allow_headers=["*"],
) )
@app.get("/", response_class=RedirectResponse) @self.app.get("/", response_class=RedirectResponse)
async def index(): async def index():
return "/admin" return "/admin"
@app.get("/admin", response_class=HTMLResponse) @self.app.get("/admin", response_class=HTMLResponse)
async def admin(): async def admin():
return admin_app.render( return admin_app.render(
site_title="PagerMaid-Pyro 后台管理", site_title="PagerMaid-Pyro 后台管理",
@ -52,9 +61,48 @@ def init_web():
responseAdaptor=responseAdaptor, responseAdaptor=responseAdaptor,
) )
@app.get("/login", response_class=HTMLResponse) @self.app.get("/login", response_class=HTMLResponse)
async def login(): async def login():
return login_page.render( return login_page.render(
site_title="登录 | PagerMaid-Pyro 后台管理", site_title="登录 | PagerMaid-Pyro 后台管理",
site_icon=icon_path, site_icon=icon_path,
) )
async def start(self):
if not Config.WEB_ENABLE:
return
if not Config.WEB_SECRET_KEY:
logs.warning("未设置 WEB_SECRET_KEY ,请勿将 PagerMaid-Pyro 暴露在公网")
import uvicorn
self.init_web()
self.web_server = uvicorn.Server(
config=uvicorn.Config(self.app, host=Config.WEB_HOST, port=Config.WEB_PORT)
)
server_config = self.web_server.config
server_config.setup_event_loop()
if not server_config.loaded:
server_config.load()
self.web_server.lifespan = server_config.lifespan_class(server_config)
try:
await self.web_server.startup()
except OSError as e:
if e.errno == 10048:
logs.error("Web Server 端口被占用:%s", e)
logs.error("Web Server 启动失败,正在退出")
raise SystemExit from None
if self.web_server.should_exit:
logs.error("Web Server 启动失败,正在退出")
raise SystemExit from None
logs.info("Web Server 启动成功")
self.web_server_task = asyncio.create_task(self.web_server.main_loop())
def stop(self):
if self.web_server_task:
self.web_server_task.cancel()
if self.bot_main_task:
self.bot_main_task.cancel()
web = Web()

View File

@ -1,6 +1,3 @@
import os
import signal
from fastapi import APIRouter from fastapi import APIRouter
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
@ -20,5 +17,7 @@ async def bot_update():
"/bot_restart", response_class=JSONResponse, dependencies=[authentication()] "/bot_restart", response_class=JSONResponse, dependencies=[authentication()]
) )
async def bot_restart(): async def bot_restart():
os.kill(os.getpid(), signal.SIGINT) from pagermaid.web import web
web.stop()
return {} return {}

View File

@ -1,3 +1,5 @@
from typing import Optional
from fastapi import APIRouter from fastapi import APIRouter
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from pydantic import BaseModel from pydantic import BaseModel
@ -8,7 +10,7 @@ from pagermaid.config import Config
class UserModel(BaseModel): class UserModel(BaseModel):
password: str password: Optional[str] = None
route = APIRouter() route = APIRouter()
@ -16,11 +18,11 @@ route = APIRouter()
@route.post("/login", response_class=JSONResponse) @route.post("/login", response_class=JSONResponse)
async def login(user: UserModel): async def login(user: UserModel):
if user.password != Config.WEB_SECRET_KEY: if not Config.WEB_SECRET_KEY or user.password == Config.WEB_SECRET_KEY:
return {"status": -100, "msg": "登录失败,请重新输入密钥"}
token = create_token() token = create_token()
return { return {
"status": 0, "status": 0,
"msg": "登录成功", "msg": "登录成功",
"data": {"version": pgm_version_code, "token": token}, "data": {"version": pgm_version_code, "token": token},
} }
return {"status": -100, "msg": "登录失败,请重新输入密钥"}

View File

@ -8,13 +8,13 @@ psutil>=5.8.0
httpx==0.24.1 httpx==0.24.1
apscheduler>=3.10.1 apscheduler>=3.10.1
sqlitedict~=2.1.0 sqlitedict~=2.1.0
casbin==1.18.2 casbin==1.19.0
sentry-sdk==1.23.1 sentry-sdk==1.25.1
PyQRCode>=1.2.1 PyQRCode>=1.2.1
PyPng PyPng
fastapi==0.95.2 fastapi==0.97.0
amis-python==1.0.7 amis-python==1.0.8.post2
python-jose python-jose
uvicorn uvicorn
pydantic==1.10.7 pydantic==1.10.9
starlette==0.27.0 starlette