-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upstream #123
Upstream #123
Changes from all commits
c8074c8
448dd0f
c7f4d9a
de9d5da
5dc0ee0
b52bbaf
4f97bfb
3249abf
4bec9bd
ea94d1d
db3f75b
810f840
ab39adc
a114620
b03bcc6
1bf027d
04a0efd
0e1d094
ae420a2
bd6825f
7dbc7f4
169116a
eb0a6dc
ed024b7
ad9f41a
412ae00
2f88492
09bab96
c423afa
09d3010
3a34b6a
fa8dddf
2ac9578
220441f
ad59def
9f0df4d
b600f8f
b2e7c98
cc84bd1
c41d2a3
b9b4c18
cd2b33f
4a64562
0f5a6a4
72ac16b
c519e10
25dc602
c4e0430
8ba58de
be61e34
f2b26d5
4ec9bc1
353823f
79b8f4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,16 +7,11 @@ | |
from datetime import datetime | ||
from time import sleep | ||
|
||
import core.scripts.config_generate # noqa | ||
from core.config import Config, CFGManager | ||
from core.constants.default import base_superuser_default | ||
from core.constants.path import cache_path | ||
from core.database import BotDBUtil, session, DBVersion | ||
from core.logger import Logger | ||
from core.utils.info import Info | ||
from loguru import logger as loggerFallback | ||
|
||
|
||
ascii_art = r''' | ||
._. _ .____ ._. | ||
_ _ ____ _ | ||
/\ | | (_) | _ \ | | | ||
/ \ | | ____ _ _ __ _ | |_) | ___ | |_ | ||
/ /\ \ | |/ / _` | '__| | | _ < / _ \| __| | ||
|
@@ -49,20 +44,65 @@ class RestartBot(Exception): | |
|
||
|
||
failed_to_start_attempts = {} | ||
disabled_bots = [] | ||
processes = [] | ||
|
||
|
||
def init_bot(): | ||
import core.scripts.config_generate # noqa | ||
from core.config import Config, CFGManager # noqa | ||
from core.constants.default import base_superuser_default # noqa | ||
from core.database import BotDBUtil, session, DBVersion # noqa | ||
from core.logger import Logger # noqa | ||
|
||
query_dbver = session.query(DBVersion).first() | ||
if not query_dbver: | ||
session.add_all([DBVersion(value=str(BotDBUtil.database_version))]) | ||
session.commit() | ||
query_dbver = session.query(DBVersion).first() | ||
if (current_ver := int(query_dbver.value)) < (target_ver := BotDBUtil.database_version): | ||
Logger.info(f'Updating database from {current_ver} to {target_ver}...') | ||
from core.database.update import update_database | ||
|
||
update_database() | ||
Logger.info('Database updated successfully!') | ||
print(ascii_art) | ||
base_superuser = Config('base_superuser', base_superuser_default, cfg_type=(str, list)) | ||
if base_superuser: | ||
if isinstance(base_superuser, str): | ||
base_superuser = [base_superuser] | ||
for bu in base_superuser: | ||
BotDBUtil.SenderInfo(bu).init() | ||
BotDBUtil.SenderInfo(bu).edit('isSuperUser', True) | ||
print(ascii_art) | ||
else: | ||
Logger.warning("The base superuser was not found, please setup it in the config file.") | ||
|
||
disabled_bots.clear() | ||
for t in CFGManager.values: | ||
if t.startswith('bot_') and not t.endswith('_secret'): | ||
if 'enable' in CFGManager.values[t][t]: | ||
if not CFGManager.values[t][t]['enable']: | ||
disabled_bots.append(t[4:]) | ||
|
||
|
||
def multiprocess_run_until_complete(func): | ||
p = multiprocessing.Process( | ||
target=func,) | ||
p.start() | ||
|
||
while True: | ||
if not p.is_alive(): | ||
break | ||
sleep(1) | ||
p.terminate() | ||
p.join() | ||
p.close() | ||
|
||
|
||
def go(bot_name: str = None, subprocess: bool = False, binary_mode: bool = False): | ||
from core.logger import Logger # noqa | ||
from core.utils.info import Info # noqa | ||
|
||
Logger.info(f"[{bot_name}] Here we go!") | ||
Info.subprocess = subprocess | ||
Info.binary_mode = binary_mode | ||
|
@@ -76,41 +116,34 @@ def go(bot_name: str = None, subprocess: bool = False, binary_mode: bool = False | |
sys.exit(1) | ||
|
||
|
||
disabled_bots = [] | ||
processes = [] | ||
|
||
for t in CFGManager.values: | ||
if t.startswith('bot_') and not t.endswith('_secret'): | ||
if 'enable' in CFGManager.values[t][t]: | ||
if not CFGManager.values[t][t]['enable']: | ||
disabled_bots.append(t[4:]) | ||
|
||
|
||
def restart_process(bot_name: str): | ||
if bot_name not in failed_to_start_attempts or datetime.now( | ||
).timestamp() - failed_to_start_attempts[bot_name]['timestamp'] > 60: | ||
failed_to_start_attempts[bot_name] = {} | ||
failed_to_start_attempts[bot_name]['count'] = 0 | ||
def run_bot(): | ||
from core.constants.path import cache_path # noqa | ||
from core.config import Config # noqa | ||
from core.logger import Logger # noqa | ||
|
||
def restart_process(bot_name: str): | ||
if bot_name not in failed_to_start_attempts or datetime.now( | ||
).timestamp() - failed_to_start_attempts[bot_name]['timestamp'] > 60: | ||
failed_to_start_attempts[bot_name] = {} | ||
failed_to_start_attempts[bot_name]['count'] = 0 | ||
failed_to_start_attempts[bot_name]['timestamp'] = datetime.now().timestamp() | ||
failed_to_start_attempts[bot_name]['count'] += 1 | ||
failed_to_start_attempts[bot_name]['timestamp'] = datetime.now().timestamp() | ||
failed_to_start_attempts[bot_name]['count'] += 1 | ||
failed_to_start_attempts[bot_name]['timestamp'] = datetime.now().timestamp() | ||
if failed_to_start_attempts[bot_name]['count'] >= 3: | ||
Logger.error(f'Bot {bot_name} failed to start 3 times, abort to restart, please check the log.') | ||
return | ||
|
||
Logger.warning(f'Restarting bot {bot_name}...') | ||
p = multiprocessing.Process( | ||
target=go, | ||
args=( | ||
bot_name, | ||
True, | ||
bool(not sys.argv[0].endswith('.py'))), | ||
name=bot_name) | ||
p.start() | ||
processes.append(p) | ||
if failed_to_start_attempts[bot_name]['count'] >= 3: | ||
Logger.error(f'Bot {bot_name} failed to start 3 times, abort to restart, please check the log.') | ||
return | ||
|
||
Logger.warning(f'Restarting bot {bot_name}...') | ||
p = multiprocessing.Process( | ||
target=go, | ||
args=( | ||
bot_name, | ||
True, | ||
bool(not sys.argv[0].endswith('.py'))), | ||
name=bot_name) | ||
p.start() | ||
processes.append(p) | ||
|
||
def run_bot(): | ||
if os.path.exists(cache_path): | ||
shutil.rmtree(cache_path) | ||
os.makedirs(cache_path, exist_ok=True) | ||
|
@@ -153,45 +186,37 @@ def run_bot(): | |
processes.remove(p) | ||
p.terminate() | ||
p.join() | ||
p.close() | ||
restart_process(p.name) | ||
break | ||
|
||
if not processes: | ||
break | ||
sleep(1) | ||
Logger.critical('All bots exited unexpectedly, please check the output.') | ||
|
||
|
||
if __name__ == '__main__': | ||
query_dbver = session.query(DBVersion).first() | ||
if not query_dbver: | ||
session.add_all([DBVersion(value=str(BotDBUtil.database_version))]) | ||
session.commit() | ||
query_dbver = session.query(DBVersion).first() | ||
if (current_ver := int(query_dbver.value)) < (target_ver := BotDBUtil.database_version): | ||
Logger.info(f'Updating database from {current_ver} to {target_ver}...') | ||
from core.database.update import update_database | ||
|
||
update_database() | ||
Logger.info('Database updated successfully!') | ||
init_bot() | ||
try: | ||
while True: | ||
try: | ||
multiprocess_run_until_complete(init_bot) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 添加 在第 203 行,调用了 |
||
run_bot() # Process will block here so | ||
Logger.critical('All bots exited unexpectedly, please check the output.') | ||
break | ||
except RestartBot: | ||
for ps in processes: | ||
ps.terminate() | ||
ps.join() | ||
ps.close() | ||
processes.clear() | ||
continue | ||
except Exception: | ||
Logger.critical('An error occurred, please check the output.') | ||
loggerFallback.critical('An error occurred, please check the output.') | ||
traceback.print_exc() | ||
break | ||
except (KeyboardInterrupt, SystemExit): | ||
for ps in processes: | ||
ps.terminate() | ||
ps.join() | ||
ps.close() | ||
processes.clear() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,13 +22,16 @@ | |
|
||
class FinishedSession(FinishedSessionT): | ||
async def delete(self): | ||
if self.session.target.target_from == target_guild_prefix: | ||
try: | ||
from bots.qqbot.bot import client # noqa | ||
try: | ||
from bots.qqbot.bot import client # noqa | ||
if self.session.target.target_from == target_guild_prefix: | ||
for x in self.message_id: | ||
await client.api.recall_message(channel_id=self.session.target.target_id.split('|')[-1], message_id=x, hidetip=True) | ||
except Exception: | ||
Logger.error(traceback.format_exc()) | ||
elif self.session.target.target_from == target_group_prefix: | ||
for x in self.message_id: | ||
await client.api.recall_group_message(group_openid=self.session.target.target_id.split('|')[-1], message_id=x) | ||
except Exception: | ||
Logger.error(traceback.format_exc()) | ||
|
||
|
||
class MessageSession(MessageSessionT): | ||
|
@@ -226,6 +229,8 @@ async def delete(self): | |
except Exception: | ||
Logger.error(traceback.format_exc()) | ||
return False | ||
else: | ||
return False | ||
|
||
sendMessage = send_message | ||
asDisplay = as_display | ||
|
@@ -253,7 +258,7 @@ async def __aexit__(self, exc_type, exc_val, exc_tb): | |
class FetchedSession(Bot.FetchedSession): | ||
|
||
async def send_direct_message(self, message_chain, disable_secret_check=False, enable_parse_message=True, enable_split_image=True): | ||
from bots.qqbot.bot import client | ||
from bots.qqbot.bot import client # noqa | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 解决可能的未定义变量问题 在第261行,从 |
||
if self.target.target_from == target_guild_prefix: | ||
self.session.message = Message(api=client.api, event_id=None, data={ | ||
"channel_id": self.target.target_id.split('|')[-1]}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
检查
p.close()
的调用位置第 189 行的
p.close()
调用可能位于错误的位置。确保在正确的位置调用p.close()
,以便在任何情况下都能正确释放子进程资源。