mirror of
https://github.com/TeamPGM/PagerMaid-Pyro.git
synced 2024-11-28 02:51:33 +00:00
🔖 Update to v1.2.4
This commit is contained in:
parent
e1660d0dec
commit
21f58ba3d4
@ -14,7 +14,7 @@ import pyromod.listen
|
||||
from pyrogram import Client
|
||||
import sys
|
||||
|
||||
pgm_version = "1.2.3"
|
||||
pgm_version = "1.2.4"
|
||||
CMD_LIST = {}
|
||||
module_dir = __path__[0]
|
||||
working_dir = getcwd()
|
||||
|
@ -7,6 +7,7 @@ from pyrogram import idle
|
||||
from pagermaid import bot, logs, working_dir
|
||||
from pagermaid.hook import Hook
|
||||
from pagermaid.modules import module_list, plugin_list
|
||||
from pagermaid.single_utils import safe_remove
|
||||
from pagermaid.utils import lang, process_exit
|
||||
|
||||
path.insert(1, f"{working_dir}{sep}plugins")
|
||||
@ -18,6 +19,9 @@ async def main():
|
||||
await bot.start()
|
||||
|
||||
me = await bot.get_me()
|
||||
if me.is_bot:
|
||||
safe_remove("pagermaid.session")
|
||||
exit()
|
||||
logs.info(f"{lang('save_id')} {me.first_name}({me.id})")
|
||||
|
||||
for module_name in module_list:
|
||||
|
@ -5,7 +5,7 @@ from yaml import load, FullLoader, safe_load
|
||||
from shutil import copyfile
|
||||
|
||||
|
||||
def strtobool(val):
|
||||
def strtobool(val, default=False):
|
||||
"""Convert a string representation of truth to true (1) or false (0).
|
||||
|
||||
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
|
||||
@ -18,7 +18,8 @@ def strtobool(val):
|
||||
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
|
||||
return 0
|
||||
else:
|
||||
raise ValueError("invalid truth value %r" % (val,))
|
||||
print("[Degrade] invalid truth value %r" % (val,))
|
||||
return default
|
||||
|
||||
|
||||
try:
|
||||
@ -35,17 +36,20 @@ class Config:
|
||||
API_HASH = os.environ.get("API_HASH", config["api_hash"])
|
||||
STRING_SESSION = os.environ.get("STRING_SESSION")
|
||||
DEBUG = strtobool(os.environ.get("PGM_DEBUG", config["debug"]))
|
||||
ERROR_REPORT = strtobool(os.environ.get("PGM_ERROR_REPORT", config["error_report"]))
|
||||
ERROR_REPORT = strtobool(os.environ.get("PGM_ERROR_REPORT", config["error_report"]), True)
|
||||
LANGUAGE = os.environ.get("PGM_LANGUAGE", config["application_language"])
|
||||
REGION = os.environ.get("PGM_REGION", config["application_region"])
|
||||
TTS = os.environ.get("PGM_TTS", config["application_tts"])
|
||||
LOG = strtobool(os.environ.get("PGM_LOG", config["log"]))
|
||||
LOG_ID = int(os.environ.get("PGM_LOG_ID", config["log_chatid"]))
|
||||
IPV6 = strtobool(os.environ.get("PGM_IPV6", config["ipv6"]))
|
||||
ALLOW_ANALYTIC = strtobool(os.environ.get("PGM_ALLOW_ANALYTIC", config["allow_analytic"]), True)
|
||||
SENTRY_API = "https://0785960e63e04279a694d0486d47d9ea@o1342815.ingest.sentry.io/6617119"
|
||||
MIXPANEL_API = "c79162511383b0fa1e9c062a2a86c855"
|
||||
TIME_FORM = os.environ.get("PGM_TIME_FORM", config["time_form"])
|
||||
DATE_FORM = os.environ.get("PGM_DATE_FORM", config["date_form"])
|
||||
START_FORM = os.environ.get("PGM_START_FORM", config["start_form"])
|
||||
SILENT = strtobool(os.environ.get("PGM_PGM_SILENT", config["silent"]))
|
||||
SILENT = strtobool(os.environ.get("PGM_PGM_SILENT", config["silent"]), True)
|
||||
PROXY_ADDRESS = os.environ.get("PGM_PROXY_ADDRESS", config["proxy_addr"])
|
||||
PROXY_PORT = os.environ.get("PGM_PROXY_PORT", config["proxy_port"])
|
||||
PROXY = None
|
||||
|
@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
from pyrogram import StopPropagation
|
||||
|
||||
@ -81,31 +82,64 @@ class Hook:
|
||||
logs.info(f"[shutdown]: {type(exception)}: {exception}")
|
||||
|
||||
@staticmethod
|
||||
async def command_pre(message: Message):
|
||||
if cors := [pre(**inject(message, pre)) for pre in hook_functions["command_pre"]]: # noqa
|
||||
try:
|
||||
async def command_pre(message: Message, command):
|
||||
cors = []
|
||||
try:
|
||||
for pre in hook_functions["command_pre"]:
|
||||
try:
|
||||
data = inject(message, pre, command=command)
|
||||
except Exception as exception:
|
||||
logs.info(f"[process_error]: {type(exception)}: {exception}")
|
||||
continue
|
||||
cors.append(pre(**data)) # noqa
|
||||
if cors:
|
||||
await asyncio.gather(*cors)
|
||||
except StopPropagation as e:
|
||||
raise StopPropagation from e
|
||||
except Exception as exception:
|
||||
logs.info(f"[command_pre]: {type(exception)}: {exception}")
|
||||
except SystemExit:
|
||||
await Hook.shutdown()
|
||||
sys.exit(0)
|
||||
except StopPropagation as e:
|
||||
raise StopPropagation from e
|
||||
except Exception as exception:
|
||||
logs.info(f"[command_pre]: {type(exception)}: {exception}")
|
||||
|
||||
@staticmethod
|
||||
async def command_post(message: Message):
|
||||
if cors := [post(**inject(message, post)) for post in hook_functions["command_post"]]: # noqa
|
||||
try:
|
||||
async def command_post(message: Message, command):
|
||||
cors = []
|
||||
try:
|
||||
for post in hook_functions["command_post"]:
|
||||
try:
|
||||
data = inject(message, post, command=command)
|
||||
except Exception as exception:
|
||||
logs.info(f"[process_error]: {type(exception)}: {exception}")
|
||||
continue
|
||||
cors.append(post(**data)) # noqa
|
||||
if cors:
|
||||
await asyncio.gather(*cors)
|
||||
except StopPropagation as e:
|
||||
raise StopPropagation from e
|
||||
except Exception as exception:
|
||||
logs.info(f"[command_post]: {type(exception)}: {exception}")
|
||||
except SystemExit:
|
||||
await Hook.shutdown()
|
||||
sys.exit(0)
|
||||
except StopPropagation as e:
|
||||
raise StopPropagation from e
|
||||
except Exception as exception:
|
||||
logs.info(f"[command_post]: {type(exception)}: {exception}")
|
||||
|
||||
@staticmethod
|
||||
async def process_error_exec(message: Message, exc_info: BaseException, exc_format: str):
|
||||
if cors := [error(**inject(message, error, exc_info=exc_info, exc_format=exc_format)) for error in hook_functions["process_error"]]: # noqa
|
||||
try:
|
||||
async def process_error_exec(message: Message, command, exc_info: BaseException, exc_format: str):
|
||||
cors = []
|
||||
try:
|
||||
for error in hook_functions["process_error"]:
|
||||
try:
|
||||
data = inject(message, error, command=command, exc_info=exc_info, exc_format=exc_format)
|
||||
except Exception as exception:
|
||||
logs.info(f"[process_error]: {type(exception)}: {exception}")
|
||||
continue
|
||||
cors.append(error(**data)) # noqa
|
||||
if cors:
|
||||
await asyncio.gather(*cors)
|
||||
except StopPropagation as e:
|
||||
raise StopPropagation from e
|
||||
except Exception as exception:
|
||||
logs.info(f"[process_error]: {type(exception)}: {exception}")
|
||||
except SystemExit:
|
||||
await Hook.shutdown()
|
||||
sys.exit(0)
|
||||
except StopPropagation as e:
|
||||
raise StopPropagation from e
|
||||
except Exception as exception:
|
||||
logs.info(f"[process_error]: {type(exception)}: {exception}")
|
||||
|
@ -6,6 +6,7 @@ from time import strftime, gmtime, time
|
||||
from traceback import format_exc
|
||||
|
||||
from pyrogram import ContinuePropagation, StopPropagation, filters, Client
|
||||
from pyrogram.errors import Flood, Forbidden
|
||||
from pyrogram.errors.exceptions.bad_request_400 import (
|
||||
MessageIdInvalid,
|
||||
MessageNotModified,
|
||||
@ -139,7 +140,7 @@ def listener(**args):
|
||||
read_context[(message.chat.id, message.id)] = True
|
||||
|
||||
if command:
|
||||
await Hook.command_pre(message)
|
||||
await Hook.command_pre(message, command)
|
||||
if data := inject(message, function):
|
||||
await function(**data)
|
||||
else:
|
||||
@ -150,12 +151,12 @@ def listener(**args):
|
||||
elif function.__code__.co_argcount == 2:
|
||||
await function(client, message)
|
||||
if command:
|
||||
await Hook.command_post(message)
|
||||
await Hook.command_post(message, command)
|
||||
except StopPropagation as e:
|
||||
raise StopPropagation from e
|
||||
except KeyboardInterrupt as e:
|
||||
raise KeyboardInterrupt from e
|
||||
except MessageNotModified:
|
||||
except (UserNotParticipant, MessageNotModified, MessageEmpty, Flood, Forbidden):
|
||||
pass
|
||||
except MessageIdInvalid:
|
||||
logs.warning(
|
||||
@ -179,8 +180,6 @@ def listener(**args):
|
||||
)
|
||||
with contextlib.suppress(BaseException):
|
||||
await message.edit(lang("reload_des"))
|
||||
except UserNotParticipant:
|
||||
pass
|
||||
except ContinuePropagation as e:
|
||||
if block_process:
|
||||
raise StopPropagation from e
|
||||
@ -196,12 +195,12 @@ def listener(**args):
|
||||
await message.edit(lang("run_error"), no_reply=True) # noqa
|
||||
if not diagnostics:
|
||||
return
|
||||
await Hook.process_error_exec(message, exc_info, exc_format)
|
||||
if Config.ERROR_REPORT:
|
||||
report = f"""# Generated: {strftime('%H:%M %d/%m/%Y', gmtime())}. \n# ChatID: {message.chat.id}. \n# UserID: {message.from_user.id if message.from_user else message.sender_chat.id}. \n# Message: \n-----BEGIN TARGET MESSAGE-----\n{message.text or message.caption}\n-----END TARGET MESSAGE-----\n# Traceback: \n-----BEGIN TRACEBACK-----\n{str(exc_format)}\n-----END TRACEBACK-----\n# Error: "{str(exc_info)}". \n"""
|
||||
|
||||
await attach_report(report, f"exception.{time()}.pgp.txt", None,
|
||||
"PGP Error report generated.")
|
||||
await Hook.process_error_exec(message, command, exc_info, exc_format)
|
||||
if (message.chat.id, message.id) in read_context:
|
||||
del read_context[(message.chat.id, message.id)]
|
||||
if block_process:
|
||||
@ -274,9 +273,7 @@ def raw_listener(filter_s):
|
||||
await process_exit(start=False, _client=client, message=message)
|
||||
await Hook.shutdown()
|
||||
sys.exit(0)
|
||||
except UserNotParticipant:
|
||||
pass
|
||||
except MessageEmpty:
|
||||
except (UserNotParticipant, MessageNotModified, MessageEmpty, Flood, Forbidden):
|
||||
pass
|
||||
except BaseException:
|
||||
exc_info = sys.exc_info()[1]
|
||||
|
29
pagermaid/modules/mixpanel.py
Normal file
29
pagermaid/modules/mixpanel.py
Normal file
@ -0,0 +1,29 @@
|
||||
from pagermaid import Config
|
||||
from pagermaid.enums import Client, Message
|
||||
from pagermaid.hook import Hook
|
||||
|
||||
from mixpanel import Mixpanel
|
||||
|
||||
|
||||
mp = Mixpanel(Config.MIXPANEL_API)
|
||||
|
||||
|
||||
@Hook.on_startup()
|
||||
async def mixpanel_init_id(bot: Client):
|
||||
me = await bot.get_me()
|
||||
if me.username:
|
||||
mp.people_set(str(me.id), {'$first_name': me.first_name, "username": me.username})
|
||||
else:
|
||||
mp.people_set(str(me.id), {'$first_name': me.first_name})
|
||||
|
||||
|
||||
@Hook.command_postprocessor()
|
||||
async def mixpanel_report(bot: Client, message: Message, command):
|
||||
if not Config.ALLOW_ANALYTIC:
|
||||
return
|
||||
me = await bot.get_me()
|
||||
sender_id = message.from_user.id if message.from_user else ""
|
||||
sender_id = message.sender_chat.id if message.sender_chat else sender_id
|
||||
if sender_id < 0 and message.outgoing:
|
||||
sender_id = me.id
|
||||
mp.track(str(sender_id), f'Function {command}', {'command': command, "bot_id": me.id})
|
@ -4,7 +4,8 @@ from asyncio import sleep
|
||||
|
||||
from pagermaid import log
|
||||
from pagermaid.listener import listener
|
||||
from pagermaid.utils import lang, Message
|
||||
from pagermaid.enums import Client, Message
|
||||
from pagermaid.utils import lang
|
||||
|
||||
import contextlib
|
||||
|
||||
@ -44,40 +45,31 @@ async def prune(message: Message):
|
||||
need_admin=True,
|
||||
description=lang('sp_des'),
|
||||
parameters=lang('sp_parameters'))
|
||||
async def self_prune(message: Message):
|
||||
async def self_prune(bot: Client, message: Message):
|
||||
""" Deletes specific amount of messages you sent. """
|
||||
msgs = []
|
||||
count_buffer = 0
|
||||
offset = 0
|
||||
if len(message.parameter) != 1:
|
||||
if not message.reply_to_message:
|
||||
return await message.edit(lang('arg_error'))
|
||||
async for msg in message.bot.search_messages(
|
||||
message.chat.id,
|
||||
from_user="me",
|
||||
offset=message.reply_to_message.id,
|
||||
):
|
||||
msgs.append(msg.id)
|
||||
count_buffer += 1
|
||||
if len(msgs) == 100:
|
||||
await message.bot.delete_messages(message.chat.id, msgs)
|
||||
msgs = []
|
||||
if msgs:
|
||||
await message.bot.delete_messages(message.chat.id, msgs)
|
||||
if count_buffer == 0:
|
||||
await message.delete()
|
||||
count_buffer += 1
|
||||
await log(f"{lang('prune_hint1')}{lang('sp_hint')} {str(count_buffer)} {lang('prune_hint2')}")
|
||||
notification = await send_prune_notify(message, count_buffer, count_buffer)
|
||||
await sleep(1)
|
||||
await notification.delete()
|
||||
return
|
||||
offset = message.reply_to_message.id
|
||||
try:
|
||||
count = int(message.parameter[0])
|
||||
await message.delete()
|
||||
except ValueError:
|
||||
await message.edit(lang('arg_error'))
|
||||
return
|
||||
async for msg in message.bot.search_messages(message.chat.id, from_user="me"):
|
||||
async for msg in bot.get_chat_history(message.chat.id, limit=100):
|
||||
if count_buffer == count:
|
||||
break
|
||||
if msg.from_user and msg.from_user.is_self:
|
||||
msgs.append(msg.id)
|
||||
count_buffer += 1
|
||||
if len(msgs) == 100:
|
||||
await message.bot.delete_messages(message.chat.id, msgs)
|
||||
msgs = []
|
||||
async for msg in bot.search_messages(message.chat.id, from_user="me", offset=offset):
|
||||
if count_buffer == count:
|
||||
break
|
||||
msgs.append(msg.id)
|
||||
@ -101,7 +93,7 @@ async def self_prune(message: Message):
|
||||
need_admin=True,
|
||||
description=lang('yp_des'),
|
||||
parameters=lang('sp_parameters'))
|
||||
async def your_prune(message: Message):
|
||||
async def your_prune(bot: Client, message: Message):
|
||||
""" Deletes specific amount of messages someone sent. """
|
||||
if not message.reply_to_message:
|
||||
return await message.edit(lang('not_reply'))
|
||||
@ -119,18 +111,34 @@ async def your_prune(message: Message):
|
||||
except Exception: # noqa
|
||||
pass
|
||||
count_buffer = 0
|
||||
async for msg in message.bot.search_messages(message.chat.id, from_user=target.from_user.id):
|
||||
msgs = []
|
||||
async for msg in bot.get_chat_history(message.chat.id, limit=100):
|
||||
if count_buffer == count:
|
||||
break
|
||||
if msg.from_user and msg.from_user.id == target.from_user.id:
|
||||
msgs.append(msg.id)
|
||||
count_buffer += 1
|
||||
if len(msgs) == 100:
|
||||
await message.bot.delete_messages(message.chat.id, msgs)
|
||||
msgs = []
|
||||
async for msg in bot.search_messages(message.chat.id, from_user=target.from_user.id):
|
||||
if count_buffer == count:
|
||||
break
|
||||
await msg.delete()
|
||||
count_buffer += 1
|
||||
msgs.append(msg.id)
|
||||
if len(msgs) == 100:
|
||||
await message.bot.delete_messages(message.chat.id, msgs)
|
||||
msgs = []
|
||||
if msgs:
|
||||
await message.bot.delete_messages(message.chat.id, msgs)
|
||||
await log(
|
||||
f"{lang('prune_hint1')}{lang('yp_hint')} {str(count_buffer)} / {count} {lang('prune_hint2')}"
|
||||
)
|
||||
|
||||
notification = await send_prune_notify(message, count_buffer, count)
|
||||
await sleep(1)
|
||||
await notification.delete()
|
||||
with contextlib.suppress(ValueError):
|
||||
notification = await send_prune_notify(message, count_buffer, count)
|
||||
await sleep(1)
|
||||
await notification.delete()
|
||||
|
||||
|
||||
@listener(is_plugin=False, outgoing=True, command="del",
|
||||
|
58
pagermaid/modules/sentry.py
Normal file
58
pagermaid/modules/sentry.py
Normal file
@ -0,0 +1,58 @@
|
||||
import sentry_sdk
|
||||
|
||||
from subprocess import run, PIPE
|
||||
from time import time
|
||||
|
||||
from pyrogram.errors import Unauthorized
|
||||
|
||||
from pagermaid import Config
|
||||
from pagermaid.enums import Client, Message
|
||||
from pagermaid.hook import Hook
|
||||
from pagermaid.single_utils import safe_remove
|
||||
|
||||
|
||||
def sentry_before_send(event, hint):
|
||||
global sentry_sdk_report_time
|
||||
exc_info = hint.get("exc_info")
|
||||
if exc_info and isinstance(exc_info[1], Unauthorized):
|
||||
# The user has been deleted/deactivated or session revoked
|
||||
safe_remove('pagermaid.session')
|
||||
exit(1)
|
||||
if time() <= sentry_sdk_report_time + 30:
|
||||
sentry_sdk_report_time = time()
|
||||
return None
|
||||
else:
|
||||
sentry_sdk_report_time = time()
|
||||
return event
|
||||
|
||||
|
||||
sentry_sdk_report_time = time()
|
||||
sentry_sdk_git_hash = run("git rev-parse HEAD", stdout=PIPE, shell=True).stdout.decode().strip()
|
||||
sentry_sdk.init(
|
||||
Config.SENTRY_API,
|
||||
traces_sample_rate=1.0,
|
||||
release=sentry_sdk_git_hash,
|
||||
before_send=sentry_before_send,
|
||||
environment="production",
|
||||
)
|
||||
|
||||
|
||||
@Hook.on_startup()
|
||||
async def sentry_init_id(bot: Client):
|
||||
me = await bot.get_me()
|
||||
if me.username:
|
||||
sentry_sdk.set_user({"id": me.id, "name": me.first_name, "username": me.username, "ip_address": "{{auto}}"})
|
||||
else:
|
||||
sentry_sdk.set_user({"id": me.id, "name": me.first_name, "ip_address": "{{auto}}"})
|
||||
|
||||
|
||||
@Hook.process_error()
|
||||
async def sentry_report(message: Message, command, exc_info, **_):
|
||||
sender_id = message.from_user.id if message.from_user else ""
|
||||
sender_id = message.sender_chat.id if message.sender_chat else sender_id
|
||||
sentry_sdk.set_context("Target", {"ChatID": str(message.chat.id),
|
||||
"UserID": str(sender_id),
|
||||
"Msg": message.text or ""})
|
||||
if command:
|
||||
sentry_sdk.set_tag("com", command)
|
||||
sentry_sdk.capture_exception(exc_info)
|
@ -8,4 +8,6 @@ psutil>=5.8.0
|
||||
httpx
|
||||
apscheduler
|
||||
sqlitedict
|
||||
casbin==1.16.9
|
||||
casbin==1.16.11
|
||||
mixpanel
|
||||
sentry-sdk==1.9.0
|
||||
|
Loading…
Reference in New Issue
Block a user