diff --git a/bot.py b/bot.py index a16e34ee..5972ba86 100644 --- a/bot.py +++ b/bot.py @@ -10,11 +10,13 @@ from threading import Thread encode = 'UTF-8' + def enqueue_output(out, queue): for line in iter(out.readline, b''): queue.put(line) out.close() + init_bot() logging.basicConfig(format="%(msg)s", level=logging.INFO) @@ -24,7 +26,8 @@ runlst = [] for x in lst: bot = f'{botdir}{x}/bot.py' if os.path.exists(bot): - p = subprocess.Popen(f'python {bot}', shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=os.path.abspath('.')) + p = subprocess.Popen(f'python {bot}', shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + cwd=os.path.abspath('.')) runlst.append(p) q = Queue() threads = [] diff --git a/core/bots/aiogram/bot.py b/core/bots/aiogram/bot.py index 963c4d05..d6f2f50a 100644 --- a/core/bots/aiogram/bot.py +++ b/core/bots/aiogram/bot.py @@ -11,10 +11,10 @@ from core.elements import MsgInfo, Session, Module from core.loader import Modules from core.parser.message import parser from core.scheduler import Scheduler -from core.utils import PrivateAssets +from core.utils import PrivateAssets, init, load_prompt PrivateAssets.set(os.path.abspath(os.path.dirname(__file__) + '/assets')) - +init() @dp.message_handler() @@ -40,6 +40,8 @@ async def on_startup(dispatcher): await asyncio.gather(*gather_list) Scheduler.start() logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING) + await load_prompt(FetchTarget) + if dp: diff --git a/core/bots/aiogram/message.py b/core/bots/aiogram/message.py index 158b0233..d8d0559d 100644 --- a/core/bots/aiogram/message.py +++ b/core/bots/aiogram/message.py @@ -4,7 +4,7 @@ import traceback from core.bots.aiogram.client import dp, bot from core.bots.aiogram.tasks import MessageTaskManager, FinishedTasks -from core.elements import Plain, Image, MessageSession as MS, MsgInfo, Session, Voice +from core.elements import Plain, Image, MessageSession as MS, MsgInfo, Session, Voice, FetchTarget as FT from core.elements.others import confirm_command from aiogram import types @@ -88,7 +88,7 @@ class MessageSession(MS): pass -class FetchTarget: +class FetchTarget(FT): @staticmethod async def fetch_target(targetId): matchChannel = re.match(r'^(Telegram\|.*?)\|(.*)', targetId) diff --git a/core/bots/discord/bot.py b/core/bots/discord/bot.py index 7909091c..82ad01ca 100644 --- a/core/bots/discord/bot.py +++ b/core/bots/discord/bot.py @@ -12,9 +12,10 @@ from core.loader import Modules from core.logger import Logger from core.parser.message import parser from core.scheduler import Scheduler -from core.utils import PrivateAssets +from core.utils import PrivateAssets, init, load_prompt PrivateAssets.set(os.path.abspath(os.path.dirname(__file__) + '/assets')) +init() @client.event @@ -27,6 +28,8 @@ async def on_ready(): await asyncio.gather(*gather_list) Scheduler.start() logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING) + await asyncio.sleep(5) + await load_prompt(FetchTarget) @client.event @@ -35,12 +38,12 @@ async def on_message(message): if message.author == client.user: return Logger.info(str(message) + message.content) - target = "DC|Channel" + target = "Discord|Channel" if isinstance(message.channel, discord.DMChannel): - target = "DC|DM|Channel" + target = "Discord|DM|Channel" msg = MessageSession(target=MsgInfo(targetId=f"{target}|{message.channel.id}", - senderId=f"DC|Client|{message.author.id}", - senderName=message.author.name, targetFrom=target, senderFrom="DC|Client"), + senderId=f"Discord|Client|{message.author.id}", + senderName=message.author.name, targetFrom=target, senderFrom="Discord|Client"), session=Session(message=message, target=message.channel, sender=message.author)) await parser(msg) diff --git a/core/bots/discord/message.py b/core/bots/discord/message.py index b6c1f367..05c38577 100644 --- a/core/bots/discord/message.py +++ b/core/bots/discord/message.py @@ -4,7 +4,7 @@ import traceback import discord from core.bots.discord.client import client -from core.elements import Plain, Image, MessageSession as MS, MsgInfo, Session +from core.elements import Plain, Image, MessageSession as MS, MsgInfo, Session, FetchTarget as FT from core.elements.others import confirm_command @@ -81,7 +81,7 @@ class MessageSession(MS): pass -class FetchTarget: +class FetchTarget(FT): @staticmethod async def fetch_target(targetId): matchChannel = re.match(r'^(DC\|(?:DM\||)Channel)\|(.*)', targetId) diff --git a/core/bots/graia/bot.py b/core/bots/graia/bot.py index 8b589250..8a17835f 100644 --- a/core/bots/graia/bot.py +++ b/core/bots/graia/bot.py @@ -14,9 +14,10 @@ from core.elements import MsgInfo, Session, Module from core.loader import Modules from core.parser.message import parser from core.scheduler import Scheduler -from core.utils import PrivateAssets +from core.utils import PrivateAssets, init, load_prompt PrivateAssets.set(os.path.abspath(os.path.dirname(__file__) + '/assets')) +init() @bcc.receiver('GroupMessage') @@ -56,6 +57,8 @@ async def autorun_handler(): await asyncio.gather(*gather_list) Scheduler.start() logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING) + await load_prompt(FetchTarget) + if Config('qq_host') and Config('qq_account'): diff --git a/core/bots/graia/message.py b/core/bots/graia/message.py index 9e04e0d3..c3d7a6d7 100644 --- a/core/bots/graia/message.py +++ b/core/bots/graia/message.py @@ -9,7 +9,7 @@ from graia.broadcast.interrupt import InterruptControl from graia.broadcast.interrupt.waiter import Waiter from core.bots.graia.broadcast import app, bcc -from core.elements import Plain as BPlain, Image as BImage, Voice as BVoice, MessageSession as MS, MsgInfo, Session +from core.elements import Plain as BPlain, Image as BImage, Voice as BVoice, MessageSession as MS, MsgInfo, Session, FetchTarget as FT from core.elements.others import confirm_command from core.utils import slk_converter @@ -120,7 +120,7 @@ class MessageSession(MS): pass -class FetchTarget: +class FetchTarget(FT): @staticmethod async def fetch_target(targetId): matchTarget = re.match(r'^(QQ\|(?:Group\||))(.*)', targetId) diff --git a/core/parser/message.py b/core/parser/message.py index 6a646abf..55488d69 100644 --- a/core/parser/message.py +++ b/core/parser/message.py @@ -49,14 +49,14 @@ async def parser(msg: MessageSession): if module.need_superuser: if not senderInfo.query.isSuperUser: return await msg.sendMessage('你没有使用该命令的权限。') - if module.need_admin: - if not await msg.checkPermission(): - return await msg.sendMessage('此命令仅能被该群组的管理员所使用,请联系管理员执行此命令。') - if not module.is_base_function: + elif not module.is_base_function: check_command_enable = BotDBUtil.Module(msg).check_target_enabled_module( command_first_word) # 是否开启模块 if not check_command_enable: # 若未开启 return await msg.sendMessage(f'此模块未启用,请发送~enable {command_first_word}启用本模块。') + if module.need_admin: + if not await msg.checkPermission(): + return await msg.sendMessage('此命令仅能被该群组的管理员所使用,请联系管理员执行此命令。') help_doc = module.help_doc if help_doc is not None: try: diff --git a/core/utils/bot.py b/core/utils/bot.py index fbc7483e..990afc2b 100644 --- a/core/utils/bot.py +++ b/core/utils/bot.py @@ -4,11 +4,14 @@ import shutil import traceback import uuid from os.path import abspath +import json import aiohttp import filetype as ft from core.logger import Logger +from core.elements import FetchTarget + class PrivateAssets: path = '' @@ -20,6 +23,17 @@ class PrivateAssets: PrivateAssets.path = path +def init(): + version = os.path.abspath(PrivateAssets.path + '/version') + write_version = open(version, 'w') + write_version.write(os.popen('git rev-parse HEAD', 'r').read()[0:7]) + write_version.close() + tag = os.path.abspath(PrivateAssets.path + '/version_tag') + write_tag = open(tag, 'w') + write_tag.write(os.popen('git tag -l', 'r').read().split('\n')[-2]) + write_tag.close() + + async def get_url(url: str, headers=None): async with aiohttp.ClientSession() as session: async with session.get(url, timeout=aiohttp.ClientTimeout(total=20), headers=headers) as req: @@ -53,18 +67,19 @@ async def slk_converter(filepath): Logger.info('Voice encoded.') return filepath2 -""" -async def load_prompt(): + +async def load_prompt(bot: FetchTarget): + print(111) author_cache = os.path.abspath('.cache_restart_author') loader_cache = os.path.abspath('.cache_loader') if os.path.exists(author_cache): - import json open_author_cache = open(author_cache, 'r') - cache_json = json.loads(open_author_cache.read()) + author = json.loads(open_author_cache.read())['ID'] open_loader_cache = open(loader_cache, 'r') - await sendMessage(cache_json, open_loader_cache.read(), quote=False) - open_loader_cache.close() - open_author_cache.close() - os.remove(author_cache) - os.remove(loader_cache) -""" \ No newline at end of file + m = await bot.fetch_target(author) + if m: + await m.sendMessage(open_loader_cache.read()) + open_loader_cache.close() + open_author_cache.close() + os.remove(author_cache) + os.remove(loader_cache) diff --git a/database/__init__.py b/database/__init__.py index d24b4831..870da156 100644 --- a/database/__init__.py +++ b/database/__init__.py @@ -15,9 +15,12 @@ def convert_str_to_list(s: str) -> list: class BotDBUtil: class Module: - def __init__(self, msg: MessageSession): - self.message = msg - self.query = session.query(EnabledModules).filter_by(targetId=str(msg.target.targetId)).first() + def __init__(self, msg: [MessageSession, str]): + if isinstance(msg, MessageSession): + self.targetId = str(msg.target.targetId) + else: + self.targetId = msg + self.query = session.query(EnabledModules).filter_by(targetId=self.targetId).first() self.enable_modules_list = convert_str_to_list(self.query.enabledModules) if self.query is not None else [] self.need_insert = True if self.query is None else False @@ -34,7 +37,7 @@ class BotDBUtil: self.enable_modules_list.append(x) value = convert_list_to_str(self.enable_modules_list) if self.need_insert: - table = EnabledModules(targetId=str(self.message.target.targetId), + table = EnabledModules(targetId=self.targetId, enabledModules=value) session.add_all([table]) else: @@ -77,6 +80,8 @@ class BotDBUtil: def edit(self, column: str, value): setattr(self.query, column, value) session.commit() + session.expire_all() + return True def check_TargetAdmin(self, targetId): query = session.query(TargetAdmin).filter_by(senderId=self.senderId, targetId=targetId).first() diff --git a/init.py b/init.py index 585caac3..9a67c468 100644 --- a/init.py +++ b/init.py @@ -1,5 +1,7 @@ import os import shutil +from database import BotDBUtil +from config import Config def init_bot(): @@ -10,12 +12,6 @@ def init_bot(): else: os.mkdir(cache_path) - version = os.path.abspath('.version') - write_version = open(version, 'w') - write_version.write(os.popen('git rev-parse HEAD', 'r').read()[0:7]) - write_version.close() - - tag = os.path.abspath('.version_tag') - write_tag = open(tag, 'w') - write_tag.write(os.popen('git tag -l', 'r').read().split('\n')[-2]) - write_tag.close() \ No newline at end of file + base_superuser = Config('base_superuser') + if base_superuser: + BotDBUtil.SenderInfo(base_superuser).edit('isSuperUser', True) diff --git a/modules/core/__init__.py b/modules/core/__init__.py index 5d434692..3c02d98d 100644 --- a/modules/core/__init__.py +++ b/modules/core/__init__.py @@ -1,10 +1,13 @@ import asyncio +import json import os +import sys import time import psutil from core.elements import MessageSession +from core.utils import PrivateAssets from core.loader import ModulesManager from core.loader.decorator import command from core.parser.command import CommandParser @@ -122,8 +125,8 @@ async def modules_help(msg: MessageSession): help_doc='~version {查看机器人的版本号}' ) async def bot_version(msg: MessageSession): - version = os.path.abspath('.version') - tag = os.path.abspath('.version_tag') + version = os.path.abspath(PrivateAssets.path + '/version') + tag = os.path.abspath(PrivateAssets.path + '/version_tag') open_version = open(version, 'r') open_tag = open(tag, 'r') msgs = f'当前运行的代码版本号为:{open_tag.read()}({open_version.read()})' @@ -186,3 +189,70 @@ async def config_gu(msg: MessageSession): if user: if BotDBUtil.SenderInfo(f"{msg.target.senderFrom}|{user}").remove_TargetAdmin(msg.target.targetId): await msg.sendMessage("成功") + + +@command('add_su', need_superuser=True, help_doc='add_su ') +async def add_su(message: MessageSession): + user = message.parsed_msg[''] + print(message.parsed_msg) + if user: + if BotDBUtil.SenderInfo(user).edit('isSuperUser', True): + await message.sendMessage('成功') + + +@command('del_su', need_superuser=True, help_doc='del_su ') +async def del_su(message: MessageSession): + user = message.parsed_msg[''] + if user: + if BotDBUtil.SenderInfo(user).edit('isSuperUser', False): + await message.sendMessage('成功') + + +""" +@command('set_modules', need_superuser=True, help_doc='set_modules <>') +async def set_modules(display_msg: dict): + ... +""" + + +@command('restart', need_superuser=True) +async def restart_bot(msg: MessageSession): + await msg.sendMessage('你确定吗?') + confirm = await msg.waitConfirm() + if confirm: + update = os.path.abspath('.cache_restart_author') + write_version = open(update, 'w') + write_version.write(json.dumps({'From': msg.target.targetFrom, 'ID': msg.target.targetId})) + write_version.close() + await msg.sendMessage('已执行。') + python = sys.executable + os.execl(python, python, *sys.argv) + + +@command('update', need_superuser=True) +async def update_bot(msg: MessageSession): + await msg.sendMessage('你确定吗?') + confirm = await msg.waitConfirm() + if confirm: + result = os.popen('git pull', 'r') + await msg.sendMessage(result.read()[:-1]) + + +@command('update&restart', need_superuser=True) +async def update_and_restart_bot(msg: MessageSession): + await msg.sendMessage('你确定吗?') + confirm = await msg.waitConfirm() + if confirm: + update = os.path.abspath('.cache_restart_author') + write_version = open(update, 'w') + write_version.write(json.dumps({'From': msg.target.targetFrom, 'ID': msg.target.targetId})) + write_version.close() + result = os.popen('git pull', 'r') + await msg.sendMessage(result.read()[:-1]) + python = sys.executable + os.execl(python, python, *sys.argv) + + +@command('echo', need_superuser=True, help_doc='echo ') +async def echo_msg(msg: MessageSession): + await msg.sendMessage(msg.parsed_msg['']) diff --git a/modules/core/admin.py b/modules/core/admin.py deleted file mode 100644 index 5937ad2c..00000000 --- a/modules/core/admin.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -import sys - -from core.elements import MessageSession -from core.loader.decorator import command -from database import BotDBUtil - - -@command('add_su', need_superuser=True, help_doc='add_su ') -async def add_su(message: MessageSession): - user = message.parsed_msg[''] - if user: - if BotDBUtil.SenderInfo(f'{message.target.senderFrom}|{user}').edit('isSuperUser', True): - await message.sendMessage('成功') - - -@command('del_su', need_superuser=True, help_doc='del_su ') -async def del_su(message: MessageSession): - user = message.parsed_msg[''] - if user: - if BotDBUtil.SenderInfo(f'{message.target.senderFrom}|{user}').edit('isSuperUser', False): - await message.sendMessage('成功') - - -""" -@command('set_modules', need_superuser=True, help_doc='set_modules <>') -async def set_modules(display_msg: dict): - ... -""" - - -@command('restart', need_superuser=True) -async def restart_bot(msg: MessageSession): - await msg.sendMessage('你确定吗?') - confirm = await msg.waitConfirm() - if confirm: - await msg.sendMessage('已执行。') - python = sys.executable - os.execl(python, python, *sys.argv) - -""" -async def update_bot(display_msg: dict): - await sendMessage(display_msg, '你确定吗?') - confirm = await wait_confirm(display_msg) - if confirm: - result = os.popen('git pull', 'r') - await sendMessage(display_msg, result.read()) - - -async def update_and_restart_bot(display_msg: dict): - await sendMessage(display_msg, '你确定吗?') - confirm = await wait_confirm(display_msg) - if confirm: - update = os.path.abspath('.cache_restart_author') - write_version = open(update, 'w') - write_version.write(json.dumps({'From': display_msg[Target].target_from, 'ID': display_msg[Target].id})) - write_version.close() - result = os.popen('git pull', 'r') - await sendMessage(display_msg, result.read()) - python = sys.executable - os.execl(python, python, *sys.argv) -""" - -@command('echo', need_superuser=True, help_doc='echo ') -async def echo_msg(msg: MessageSession): - await msg.sendMessage(msg.parsed_msg['']) diff --git a/modules/mcv_rss/__init__.py b/modules/mcv_rss/__init__.py index 6a4b0e5e..3257df09 100644 --- a/modules/mcv_rss/__init__.py +++ b/modules/mcv_rss/__init__.py @@ -51,7 +51,7 @@ async def mcv_rss(bot: FetchTarget): Logger.info(f'huh, we find {snapshot}.') get_target_id = BotDBUtil.Module.get_enabled_this('mcv_rss') for x in get_target_id: - fetch = bot.fetch_target(x) + fetch = await bot.fetch_target(x) if fetch: try: await fetch.sendMessage('启动器已更新' + file['latest']['snapshot'] + '快照。')