use toml #517; auto convert cfg to toml
This commit is contained in:
parent
780846fdf6
commit
ba4ed4583e
12 changed files with 288 additions and 267 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
*.env
|
||||
__pycache__/
|
||||
config/*.cfg
|
||||
config/*.toml
|
||||
.idea
|
||||
.vscode
|
||||
assets/mcversion.txt
|
||||
|
|
45
DEPLOY.md
45
DEPLOY.md
|
@ -13,6 +13,7 @@
|
|||
## 下载源代码
|
||||
|
||||
1. 从 [Release 页面](https://github.com/Teahouse-Studios/bot/releases/latest) 的 Assets 部分中下载 Source code(源代码)。当然。你也可以下载 [master 分支的最新代码](https://github.com/Teahouse-Studios/akari-bot/archive/refs/heads/master.zip)。
|
||||
(注意:master分支下的部署文档可能会有所不同,请在下载对应版本的源码后打开目录下的DEPLOY.md继续查看部署教程)
|
||||
2. 解压源代码,然后打开终端,进入文件夹。
|
||||
|
||||
## 安装依赖
|
||||
|
@ -82,11 +83,11 @@ $ pip install -r requirements.txt
|
|||
|
||||
## 配置
|
||||
|
||||
进入 `config` 文件夹,将 `config.cfg.example` 重命名为 `config.cfg`,然后开始配置你所需要的内容。
|
||||
进入 `config` 文件夹,将 `config.toml.example` 重命名为 `config.toml`,然后开始配置你所需要的内容。
|
||||
|
||||
对于第一次的简单部署,我们只需要关注数据库字段即可,其余字段可留空:
|
||||
|
||||
`db_path = mysql+pymysql://`
|
||||
`db_path = "mysql+pymysql://"`
|
||||
|
||||
机器人需要一个数据库以用于存储用户数据。
|
||||
|
||||
|
@ -113,7 +114,7 @@ $ pip install -r requirements.txt
|
|||
|
||||
**格式**
|
||||
|
||||
`db_path = sqlite:///<相对路径>/<数据库文件名>.db`
|
||||
`db_path = "sqlite:///<相对路径>/<数据库文件名>.db"`
|
||||
|
||||
**实际示例**
|
||||
|
||||
|
@ -145,9 +146,9 @@ $ pip install -r requirements.txt
|
|||
|
||||
我们在这里使用了 [aiocqhttp](https://github.com/nonebot/aiocqhttp) 来对接 [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) 客户端。
|
||||
|
||||
`qq_host = 127.0.0.1:11451` - 将会在填写的 IP 地址和端口中开启一个 websocket 服务器,用于 go-cqhttp 反向连接。
|
||||
`qq_host = "127.0.0.1:11451"` - 将会在填写的 IP 地址和端口中开启一个 websocket 服务器,用于 go-cqhttp 反向连接。
|
||||
|
||||
`qq_account = 2314163511` - 填写机器人的 QQ 号。
|
||||
`qq_account = "2314163511"` - 填写机器人的 QQ 号。
|
||||
|
||||
填写好后,请配置 `go-cqhttp` 的 `config.yml` 文件中的对应的连接方式。
|
||||
|
||||
|
@ -205,7 +206,7 @@ servers:
|
|||
|
||||
由于小可有着许多的功能,部分功能需要进一步的配置才能使用。
|
||||
|
||||
部分字段可能并未预设于 `config.yml.example` 中,手动添加即可。
|
||||
部分字段可能并未预设于 `config.toml.example` 中,手动添加即可。
|
||||
|
||||
### 屏蔽词
|
||||
|
||||
|
@ -255,7 +256,7 @@ FC_SERVER_PORT=15551 # 填写服务运行的端口
|
|||
|
||||
**示例**
|
||||
|
||||
`web_render = http://127.0.0.1:15551/`
|
||||
`web_render = "http://127.0.0.1:15551/"`
|
||||
|
||||
### 模块
|
||||
|
||||
|
@ -270,12 +271,14 @@ FC_SERVER_PORT=15551 # 填写服务运行的端口
|
|||
填写完后,你还需要从下载 [Arcaea](https://arcaea.lowiro.com/) 的 Apk 文件,将其放置于 `assets` 文件夹并重命名为 `arc.apk`,并在 Bot
|
||||
启动后使用 `~arcaea initialize` 来初始化资源文件。
|
||||
|
||||
如果不需要本模块的功能,将api字段删除即可。
|
||||
|
||||
#### coin
|
||||
`coin` 模块需要一些额外的参数才能正常工作。
|
||||
|
||||
`coin_limit = 10000` - 一次可投掷的硬币最大个数。
|
||||
|
||||
co`in_faceup_rate = 4994` - 硬币正面朝上的概率,按一万分之几计算。
|
||||
`coin_faceup_rate = 4994` - 硬币正面朝上的概率,按一万分之几计算。
|
||||
|
||||
`coin_facedown_rate = 4994` - 硬币反面朝上的概率,按一万分之几计算。
|
||||
|
||||
|
@ -322,33 +325,41 @@ assets
|
|||
|
||||
具体配置教程请查看链接所指向的文档。
|
||||
|
||||
配置好上述所需要用到的服务后,请确保在 `config` 目录下的 `config.cfg` 文件中填写以下字段:
|
||||
配置好上述所需要用到的服务后,请确保在 `config` 目录下的 `config.toml` 文件中填写以下字段:
|
||||
|
||||
+ `web_render` - Webrender 的地址(IP 或域名)及端口
|
||||
+ `netease_cloud_music_api` - NeteaseCloudMusicApi 的地址(IP 或域名)及端口
|
||||
|
||||
如果不需要本模块的功能,将api字段删除即可。
|
||||
|
||||
#### secret
|
||||
|
||||
此模块下的内容主要用于监测 Minecraft Wiki 注册日志和滥用日志,如无需要可直接删除此模块的文件夹。
|
||||
|
||||
### 其他功能
|
||||
|
||||
`qq_msg_logging_to_db = True` - 将 QQ 平台内的命令触发消息记录至 `database/msg.db` 中,有助于判断是否存在违规使用机器人的情况。
|
||||
|
||||
`base_superuser =` - 设置机器人主超级用户。可用格式为 `QQ|<QQ号>`、`Discord|<ClientID>`、`Telegram|<ClientID>`,可在机器人开启后使用 `~whoami`
|
||||
命令来查看自身的 ID,机器人启动后将自动标记对象为超级用户。
|
||||
|
||||
`qq_enable_dirty_check = True` - 是否启用 QQ 平台的屏蔽词检查。
|
||||
`qq_disable_temp_session = true` - 是否禁用 QQ 平台的临时会话功能。
|
||||
|
||||
`qq_enable_urlmanager = True` - 是否启用 QQ 平台的 URL 管理(替换外部链接,提示非官方页面)。若停用此功能将同时停用 `wiki_audit` 命令。
|
||||
`qq_enable_dirty_check = true` - 是否启用 QQ 平台的屏蔽词检查。
|
||||
|
||||
`slower_schedule = False` - 部分计划任务模块使用更长的时间间隔执行,可能有助于网络较差环境的优化。
|
||||
`qq_enable_urlmanager = true` - 是否启用 QQ 平台的 URL 管理(替换外部链接,提示非官方页面)。若停用此功能将同时停用 `wiki_audit` 命令。
|
||||
|
||||
`enable_tos = False` - 是否启用内置的违反服务条款的检查。
|
||||
`slower_schedule = false` - 部分计划任务模块使用更长的时间间隔执行,可能有助于网络较差环境的优化。
|
||||
|
||||
`enable_tos = false` - 是否启用内置的违反服务条款的检查。
|
||||
|
||||
`enable_analytics = true` - 是否启用内置的 `analytics` 命令,用于统计命令使用次数。
|
||||
|
||||
`enable_eval= true` - 是否启用内置的 `eval` 命令。
|
||||
|
||||
`qq_enable_listening_self_message = false` - 是否启用 QQ 平台的自我消息处理(可能有助于多设备下使用,但也可能会导致误触发导致消息陷入死循环状态)。
|
||||
|
||||
`allow_request_private_ip = true` - 是否允许机器人请求私有 IP 地址。
|
||||
|
||||
`enable_analytics = True` - 是否启用内置的 `analytics` 命令,用于统计命令使用次数。
|
||||
|
||||
`enable_eval= True` - 是否启用内置的 `eval` 命令。
|
||||
|
||||
#### 自定义确认词及命令前缀
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import logging
|
||||
import os
|
||||
import re
|
||||
import traceback
|
||||
from typing import Dict, Any
|
||||
|
||||
from aiocqhttp import Event, Error
|
||||
|
||||
|
@ -18,7 +16,7 @@ from database import BotDBUtil
|
|||
PrivateAssets.set(os.path.abspath(os.path.dirname(__file__) + '/assets'))
|
||||
EnableDirtyWordCheck.status = True if Config('qq_enable_dirty_check') else False
|
||||
Url.disable_mm = False if Config('qq_enable_urlmanager') else True
|
||||
qq_account = Config("qq_account")
|
||||
qq_account = str(Config("qq_account"))
|
||||
enable_listening_self_message = Config("qq_enable_listening_self_message")
|
||||
|
||||
|
||||
|
|
|
@ -1,34 +1,54 @@
|
|||
from configparser import ConfigParser
|
||||
import os
|
||||
|
||||
import toml
|
||||
from os.path import abspath
|
||||
|
||||
from core.exceptions import ConfigFileNotFound
|
||||
|
||||
config_filename = 'config.cfg'
|
||||
config_filename = 'config.toml'
|
||||
config_path = abspath('./config/' + config_filename)
|
||||
|
||||
old_cfg_file_path = abspath('./config/config.cfg')
|
||||
|
||||
|
||||
def convert_cfg_to_toml():
|
||||
import configparser
|
||||
config = configparser.ConfigParser()
|
||||
config.read(old_cfg_file_path)
|
||||
config_dict = {}
|
||||
for section in config.sections():
|
||||
config_dict[section] = dict(config[section])
|
||||
|
||||
for x in config_dict:
|
||||
for y in config_dict[x]:
|
||||
if config_dict[x][y] == "True":
|
||||
config_dict[x][y] = True
|
||||
elif config_dict[x][y] == "False":
|
||||
config_dict[x][y] = False
|
||||
elif config_dict[x][y].isdigit():
|
||||
config_dict[x][y] = int(config_dict[x][y])
|
||||
|
||||
with open(config_path, 'w') as f:
|
||||
f.write(toml.dumps(config_dict))
|
||||
os.remove(old_cfg_file_path)
|
||||
|
||||
|
||||
class CFG:
|
||||
def __init__(self):
|
||||
self.cp = ConfigParser()
|
||||
self.cp.read(config_path)
|
||||
if not os.path.exists(config_path):
|
||||
if os.path.exists(old_cfg_file_path):
|
||||
convert_cfg_to_toml()
|
||||
else:
|
||||
raise ConfigFileNotFound(config_path) from None
|
||||
self.cp = toml.loads(open(config_path, 'r', encoding='utf-8').read())
|
||||
|
||||
def config(self, q):
|
||||
section = self.cp.sections()
|
||||
|
||||
if len(section) == 0:
|
||||
raise ConfigFileNotFound(config_path) from None
|
||||
value = self.cp.get('secret', q, fallback=False)
|
||||
value_s = self.cp.get('secret')
|
||||
value_n = self.cp.get('cfg')
|
||||
value = value_s.get(q)
|
||||
if not value:
|
||||
value = self.cp.get('cfg', q, fallback=False)
|
||||
if not value:
|
||||
return None
|
||||
if value.upper() == 'TRUE':
|
||||
return True
|
||||
if value.upper() in ['', 'FALSE']:
|
||||
return False
|
||||
value = value_n.get(q)
|
||||
return value
|
||||
|
||||
|
||||
Config = CFG().config
|
||||
CachePath = Config('cache_path')
|
||||
DBPath = Config('db_path')
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
[secret]
|
||||
db_path = mysql+pymysql://
|
||||
Check_accessKeyId =
|
||||
Check_accessKeySecret =
|
||||
web_render =
|
||||
netease_cloud_music_api_url =
|
||||
botarcapi_url =
|
||||
botarcapi_agent =
|
||||
dc_token =
|
||||
tg_token =
|
||||
openai_api_key =
|
||||
nl2c_model =
|
||||
curseforge_api_key =
|
||||
exchange_rate_api_key =
|
||||
|
||||
[cfg]
|
||||
base_superuser = QQ|2596322644
|
||||
debug = False
|
||||
cache_path = ./cache/
|
||||
extra_services = False
|
||||
db_cache = False
|
||||
bug_report_url = https://s.wd-ljt.com/botreportbug
|
||||
donate_url = https://afdian.net/@teahouse
|
||||
help_url = https://bot.teahouse.team
|
||||
issue_url = https://github.com/Teahouse-Studios/bot/issues/new/choose
|
||||
wiki_whitelist_url = https://s.wd-ljt.com/botwhitelist
|
||||
qq_msg_logging_to_db = True
|
||||
qq_host = 127.0.0.1:11451
|
||||
qq_account = 2314163511
|
||||
qq_enable_dirty_check = True
|
||||
qq_enable_urlmanager = True
|
||||
qq_disable_temp_session = False
|
||||
web_render_local =
|
||||
slower_schedule = False
|
||||
enable_tos = False
|
||||
enable_analytics = True
|
||||
allow_request_private_ip = False
|
||||
enable_eval = True
|
||||
coin_limit = 10000
|
||||
coin_faceup_rate = 4994
|
||||
coin_facedown_rate = 4994
|
||||
dice_limit = 100
|
||||
dice_roll_limit = 10
|
||||
dice_mod_max = 10000
|
||||
dice_mod_min = -10000
|
||||
dice_output_cnt = 50
|
||||
dice_output_len = 200
|
||||
dice_detail_cnt = 5
|
||||
dice_count_limit = 10
|
||||
qq_enable_listening_self_message = False
|
49
config/config.toml.example
Normal file
49
config/config.toml.example
Normal file
|
@ -0,0 +1,49 @@
|
|||
[secret]
|
||||
db_path = "mysql+pymysql://"
|
||||
Check_accessKeyId =
|
||||
Check_accessKeySecret =
|
||||
web_render =
|
||||
netease_cloud_music_api_url =
|
||||
botarcapi_url =
|
||||
botarcapi_agent =
|
||||
dc_token =
|
||||
tg_token =
|
||||
openai_api_key =
|
||||
nl2c_model =
|
||||
curseforge_api_key =
|
||||
exchange_rate_api_key =
|
||||
|
||||
[cfg]
|
||||
base_superuser = "QQ|2596322644"
|
||||
debug = false
|
||||
cache_path = "./cache/"
|
||||
extra_services = false
|
||||
db_cache = false
|
||||
bug_report_url = "https://s.wd-ljt.com/botreportbug"
|
||||
donate_url = "https://afdian.net/@teahouse"
|
||||
help_url = "https://bot.teahouse.team"
|
||||
issue_url = "https://github.com/Teahouse-Studios/bot/issues/new/choose"
|
||||
wiki_whitelist_url = "https://s.wd-ljt.com/botwhitelist"
|
||||
qq_host = "127.0.0.1:11451"
|
||||
qq_account = 2314163511
|
||||
qq_enable_dirty_check = true
|
||||
qq_enable_urlmanager = true
|
||||
qq_disable_temp_session = false
|
||||
web_render_local =
|
||||
slower_schedule = false
|
||||
enable_tos = false
|
||||
enable_analytics = true
|
||||
allow_request_private_ip = false
|
||||
enable_eval = true
|
||||
coin_limit = 10000
|
||||
coin_faceup_rate = 4994
|
||||
coin_facedown_rate = 4994
|
||||
dice_limit = 100
|
||||
dice_roll_limit = 10
|
||||
dice_mod_max = 10000
|
||||
dice_mod_min = -10000
|
||||
dice_output_cnt = 50
|
||||
dice_output_len = 200
|
||||
dice_detail_cnt = 5
|
||||
dice_count_limit = 10
|
||||
qq_enable_listening_self_message = false
|
|
@ -9,7 +9,7 @@ import filetype
|
|||
from PIL import Image as PImage
|
||||
from tenacity import retry, stop_after_attempt
|
||||
|
||||
from config import CachePath, Config
|
||||
from config import Config
|
||||
from core.types.message.internal import Plain as P, Image as I, Voice as V, Embed as E, EmbedField as EF, \
|
||||
Url as U, ErrorMessage as EMsg
|
||||
from core.utils.i18n import Locale
|
||||
|
@ -74,7 +74,7 @@ class Image(I):
|
|||
self.path = path
|
||||
self.headers = headers
|
||||
if isinstance(path, PImage.Image):
|
||||
save = f'{CachePath}{str(uuid.uuid4())}.png'
|
||||
save = f'{Config("cache_path")}{str(uuid.uuid4())}.png'
|
||||
path.convert('RGBA').save(save)
|
||||
self.path = save
|
||||
elif re.match('^https?://.*', path):
|
||||
|
@ -92,7 +92,7 @@ class Image(I):
|
|||
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
|
||||
raw = await req.read()
|
||||
ft = filetype.match(raw).extension
|
||||
img_path = f'{CachePath}{str(uuid.uuid4())}.{ft}'
|
||||
img_path = f'{Config("cache_path")}{str(uuid.uuid4())}.{ft}'
|
||||
with open(img_path, 'wb+') as image_cache:
|
||||
image_cache.write(raw)
|
||||
return img_path
|
||||
|
|
|
@ -2,11 +2,12 @@ import asyncio
|
|||
import logging
|
||||
import os
|
||||
import traceback
|
||||
from configparser import ConfigParser
|
||||
from os.path import abspath
|
||||
|
||||
import ujson as json
|
||||
|
||||
from config import CFG
|
||||
|
||||
from core.builtins import PrivateAssets, Secret
|
||||
from core.exceptions import ConfigFileNotFound
|
||||
from core.loader import load_modules, ModulesManager
|
||||
|
@ -32,18 +33,10 @@ async def init_async() -> None:
|
|||
|
||||
|
||||
async def load_secret():
|
||||
config_filename = 'config.cfg'
|
||||
config_path = abspath('./config/' + config_filename)
|
||||
cp = ConfigParser()
|
||||
cp.read(config_path)
|
||||
section = cp.sections()
|
||||
if len(section) == 0:
|
||||
raise ConfigFileNotFound(config_path) from None
|
||||
options = cp.options('secret')
|
||||
for option in options:
|
||||
value = cp.get('secret', option)
|
||||
if value.upper() not in ['', 'TRUE', 'FALSE']:
|
||||
Secret.add(value.upper())
|
||||
for x in CFG().cp:
|
||||
if x == 'secret':
|
||||
for y in CFG().cp[x]:
|
||||
Secret.add(str(CFG().cp[x][y]).upper())
|
||||
|
||||
async def append_ip():
|
||||
try:
|
||||
|
|
|
@ -27,179 +27,176 @@ class WithErrCode(Exception):
|
|||
pass
|
||||
|
||||
|
||||
@arc.command('b30 [<friend_code>] {{arcaea.help.b30}}')
|
||||
async def _(msg: Bot.MessageSession, friend_code: int = None):
|
||||
if not os.path.exists(assets_path):
|
||||
await msg.finish(msg.locale.t("arcaea.message.assets.not_found", prefix=msg.prefixes[0]))
|
||||
if friend_code is not None:
|
||||
if len(str(friend_code)) != 9:
|
||||
await msg.finish(msg.locale.t("arcaea.message.invalid.friendcode.non_digital"))
|
||||
query_code = friend_code
|
||||
else:
|
||||
query_code = ArcBindInfoManager(msg).get_bind_friendcode()
|
||||
if query_code is not None:
|
||||
try:
|
||||
if msg.target.senderId in query_tasks:
|
||||
await msg.finish(msg.locale.t("arcaea.message.b30.wait.already"))
|
||||
query_tasks.add(msg.target.senderId)
|
||||
get_ = await get_url(api + f'user/bests/session?user_name={query_code}', headers=headers,
|
||||
fmt='json')
|
||||
if get_['status'] == 0:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait"))
|
||||
if msg.target.targetFrom not in ['Discord|Channel', 'Telegram|group', 'Telegram|supergroup']:
|
||||
await msg.sendMessage([Plain(msg.locale.t("arcaea.message.sb616")),
|
||||
Image(os.path.abspath('./assets/noc.jpg')),
|
||||
Image(os.path.abspath('./assets/aof.jpg'))])
|
||||
elif get_['status'] == -33:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait.cached"))
|
||||
elif get_['status'] == -23:
|
||||
await msg.finish(msg.locale.t("arcaea.message.b30.low_potential"))
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed") + get_['message'])
|
||||
ExecutionLockList.remove(msg)
|
||||
if api:
|
||||
|
||||
async def _get_result(session):
|
||||
try:
|
||||
get_ = await get_url(api + f'user/bests/result?session_info={session}&with_song_info=true',
|
||||
headers=headers,
|
||||
fmt='json')
|
||||
if get_['status'] in [-31, -32]:
|
||||
Logger.warn(get_['message'])
|
||||
@arc.command('b30 [<friend_code>] {{arcaea.help.b30}}')
|
||||
async def _(msg: Bot.MessageSession, friend_code: int = None):
|
||||
if not os.path.exists(assets_path):
|
||||
await msg.finish(msg.locale.t("arcaea.message.assets.not_found", prefix=msg.prefixes[0]))
|
||||
if friend_code is not None:
|
||||
if len(str(friend_code)) != 9:
|
||||
await msg.finish(msg.locale.t("arcaea.message.invalid.friendcode.non_digital"))
|
||||
query_code = friend_code
|
||||
else:
|
||||
query_code = ArcBindInfoManager(msg).get_bind_friendcode()
|
||||
if query_code is not None:
|
||||
try:
|
||||
if msg.target.senderId in query_tasks:
|
||||
await msg.finish(msg.locale.t("arcaea.message.b30.wait.already"))
|
||||
query_tasks.add(msg.target.senderId)
|
||||
get_ = await get_url(api + f'user/bests/session?user_name={query_code}', headers=headers,
|
||||
fmt='json')
|
||||
if get_['status'] == 0:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait"))
|
||||
if msg.target.targetFrom not in ['Discord|Channel', 'Telegram|group', 'Telegram|supergroup']:
|
||||
await msg.sendMessage([Plain(msg.locale.t("arcaea.message.sb616")),
|
||||
Image(os.path.abspath('./assets/noc.jpg')),
|
||||
Image(os.path.abspath('./assets/aof.jpg'))])
|
||||
elif get_['status'] == -33:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait.cached"))
|
||||
elif get_['status'] == -23:
|
||||
await msg.finish(msg.locale.t("arcaea.message.b30.low_potential"))
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed") + get_['message'])
|
||||
ExecutionLockList.remove(msg)
|
||||
|
||||
async def _get_result(session):
|
||||
try:
|
||||
get_ = await get_url(api + f'user/bests/result?session_info={session}&with_song_info=true',
|
||||
headers=headers,
|
||||
fmt='json')
|
||||
if get_['status'] in [-31, -32]:
|
||||
Logger.warn(get_['message'])
|
||||
return False
|
||||
return get_
|
||||
except Exception as e:
|
||||
Logger.error(e)
|
||||
return False
|
||||
return get_
|
||||
except Exception as e:
|
||||
Logger.error(e)
|
||||
return False
|
||||
|
||||
async def _check(msg: Bot.MessageSession, session, tried):
|
||||
if tried == 0:
|
||||
for _ in range(4):
|
||||
await msg.sleep(15)
|
||||
async def _check(msg: Bot.MessageSession, session, tried):
|
||||
if tried == 0:
|
||||
for _ in range(4):
|
||||
await msg.sleep(15)
|
||||
if _result := await _get_result(session):
|
||||
return _result
|
||||
elif tried == 1:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait.check"))
|
||||
await msg.sleep(60)
|
||||
if _result := await _get_result(session):
|
||||
return _result
|
||||
elif tried <= 30:
|
||||
await msg.sleep(60)
|
||||
if _result := await _get_result(session):
|
||||
return _result
|
||||
elif tried == 1:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait.check"))
|
||||
await msg.sleep(60)
|
||||
if _result := await _get_result(session):
|
||||
return _result
|
||||
elif tried <= 30:
|
||||
await msg.sleep(60)
|
||||
if _result := await _get_result(session):
|
||||
return _result
|
||||
else:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait.timeout"))
|
||||
return False
|
||||
tried += 1
|
||||
return await _check(msg, session, tried)
|
||||
|
||||
resp = await _check(msg, get_['content']['session_info'], 0)
|
||||
if resp:
|
||||
resp = await make_b30_img(resp)
|
||||
if resp['status']:
|
||||
msgchain = [Plain(msg.locale.t("arcaea.message.b30.success", b30=resp["b30"], r10=resp["r10"],
|
||||
last5list=resp["last5list"]))]
|
||||
if 'file' in resp and msg.Feature.image:
|
||||
msgchain.append(Image(path=resp['file']))
|
||||
await msg.finish(msgchain)
|
||||
else:
|
||||
if 'errcode' in resp:
|
||||
raise WithErrCode(resp['errcode'])
|
||||
else:
|
||||
raise
|
||||
except WithErrCode as e:
|
||||
err_key = "arcaea.errcode." + str(e.args[0])
|
||||
err_msg = msg.locale.t(err_key)
|
||||
if err_key != err_msg:
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed") + err_msg)
|
||||
else:
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.b30.wait.timeout"))
|
||||
return False
|
||||
tried += 1
|
||||
return await _check(msg, session, tried)
|
||||
|
||||
resp = await _check(msg, get_['content']['session_info'], 0)
|
||||
if resp:
|
||||
resp = await make_b30_img(resp)
|
||||
if resp['status']:
|
||||
msgchain = [Plain(msg.locale.t("arcaea.message.b30.success", b30=resp["b30"], r10=resp["r10"],
|
||||
last5list=resp["last5list"]))]
|
||||
if 'file' in resp and msg.Feature.image:
|
||||
msgchain.append(Image(path=resp['file']))
|
||||
await msg.finish(msgchain)
|
||||
else:
|
||||
if 'errcode' in resp:
|
||||
raise WithErrCode(resp['errcode'])
|
||||
else:
|
||||
raise
|
||||
except WithErrCode as e:
|
||||
err_key = "arcaea.errcode." + str(e.args[0])
|
||||
err_msg = msg.locale.t(err_key)
|
||||
if err_key != err_msg:
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed") + err_msg)
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed"))
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed"))
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed"))
|
||||
finally:
|
||||
query_tasks.remove(msg.target.senderId)
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.user_unbound", prefix=msg.prefixes[0]))
|
||||
|
||||
|
||||
@arc.command('info [<friend_code>] {{arcaea.help.info}}')
|
||||
async def _(msg: Bot.MessageSession, friend_code: int = None):
|
||||
if not os.path.exists(assets_path):
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.assets.not_found", prefix=msg.prefixes[0]))
|
||||
return
|
||||
if friend_code is not None:
|
||||
if len(str(friend_code)) != 9:
|
||||
await msg.finish(msg.locale.t("arcaea.message.invalid.friendcode.non_digital"))
|
||||
query_code = friend_code
|
||||
else:
|
||||
query_code = ArcBindInfoManager(msg).get_bind_friendcode()
|
||||
if query_code is not None:
|
||||
try:
|
||||
resp = await get_info(msg, query_code)
|
||||
await msg.finish(resp)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed"))
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.user_unbound", prefix=msg.prefixes[0]))
|
||||
|
||||
|
||||
@arc.command('song <songname> [<diff>] {{arcaea.help.song}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
songname = msg.parsed_msg['<songname>']
|
||||
diff_ = msg.parsed_msg.get('<diff>')
|
||||
if not diff_:
|
||||
diff_ = 'FTR'
|
||||
|
||||
s = diff_.upper()
|
||||
if s in ['PST', 'PAST']:
|
||||
diff = 0
|
||||
elif s in ['PRS', 'PRESENT']:
|
||||
diff = 1
|
||||
elif s in ['FTR', 'FUTURE']:
|
||||
diff = 2
|
||||
elif s in ['BYD', 'BEYOND']:
|
||||
diff = 3
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.song.invalid.difficulty"))
|
||||
|
||||
usercode = ArcBindInfoManager(msg).get_bind_friendcode()
|
||||
await msg.finish(Plain(await get_song_info(msg, songname, diff, usercode)))
|
||||
|
||||
|
||||
@arc.command('bind <friendcode|username> {{arcaea.help.bind}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
code: str = msg.parsed_msg['<friendcode|username>']
|
||||
getcode = await get_userinfo(code)
|
||||
if getcode:
|
||||
bind = ArcBindInfoManager(msg).set_bind_info(username=getcode[0], friendcode=getcode[1])
|
||||
if bind:
|
||||
await msg.finish(msg.locale.t("arcaea.message.bind.success", username=getcode[0], friendcode=getcode[1]))
|
||||
else:
|
||||
if code.isdigit():
|
||||
bind = ArcBindInfoManager(msg).set_bind_info(username='', friendcode=code)
|
||||
if bind:
|
||||
await msg.finish(msg.locale.t("arcaea.message.bind.success.but_failed_fetch_username"))
|
||||
finally:
|
||||
query_tasks.remove(msg.target.senderId)
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.bind.failed"))
|
||||
await msg.finish(msg.locale.t("arcaea.message.user_unbound", prefix=msg.prefixes[0]))
|
||||
|
||||
@arc.command('info [<friend_code>] {{arcaea.help.info}}')
|
||||
async def _(msg: Bot.MessageSession, friend_code: int = None):
|
||||
if not os.path.exists(assets_path):
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.assets.not_found", prefix=msg.prefixes[0]))
|
||||
return
|
||||
if friend_code is not None:
|
||||
if len(str(friend_code)) != 9:
|
||||
await msg.finish(msg.locale.t("arcaea.message.invalid.friendcode.non_digital"))
|
||||
query_code = friend_code
|
||||
else:
|
||||
query_code = ArcBindInfoManager(msg).get_bind_friendcode()
|
||||
if query_code is not None:
|
||||
try:
|
||||
resp = await get_info(msg, query_code)
|
||||
await msg.finish(resp)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
await msg.finish(msg.locale.t("arcaea.message.get_failed"))
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.user_unbound", prefix=msg.prefixes[0]))
|
||||
|
||||
@arc.command('unbind {{arcaea.help.unbind}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
unbind = ArcBindInfoManager(msg).remove_bind_info()
|
||||
if unbind:
|
||||
await msg.finish(msg.locale.t("arcaea.message.unbind.success"))
|
||||
@arc.command('song <songname> [<diff>] {{arcaea.help.song}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
songname = msg.parsed_msg['<songname>']
|
||||
diff_ = msg.parsed_msg.get('<diff>')
|
||||
if not diff_:
|
||||
diff_ = 'FTR'
|
||||
|
||||
s = diff_.upper()
|
||||
if s in ['PST', 'PAST']:
|
||||
diff = 0
|
||||
elif s in ['PRS', 'PRESENT']:
|
||||
diff = 1
|
||||
elif s in ['FTR', 'FUTURE']:
|
||||
diff = 2
|
||||
elif s in ['BYD', 'BEYOND']:
|
||||
diff = 3
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.song.invalid.difficulty"))
|
||||
|
||||
@arc.command('initialize', required_superuser=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
assets_apk = os.path.abspath('./assets/arc.apk')
|
||||
if not os.path.exists(assets_apk):
|
||||
await msg.finish(msg.locale.t("arcaea.message.initialize.not_found"))
|
||||
return
|
||||
result = await arcb30init()
|
||||
if result:
|
||||
await msg.finish(msg.locale.t("arcaea.message.initialize.success"))
|
||||
usercode = ArcBindInfoManager(msg).get_bind_friendcode()
|
||||
await msg.finish(Plain(await get_song_info(msg, songname, diff, usercode)))
|
||||
|
||||
@arc.command('bind <friendcode|username> {{arcaea.help.bind}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
code: str = msg.parsed_msg['<friendcode|username>']
|
||||
getcode = await get_userinfo(code)
|
||||
if getcode:
|
||||
bind = ArcBindInfoManager(msg).set_bind_info(username=getcode[0], friendcode=getcode[1])
|
||||
if bind:
|
||||
await msg.finish(msg.locale.t("arcaea.message.bind.success", username=getcode[0], friendcode=getcode[1]))
|
||||
else:
|
||||
if code.isdigit():
|
||||
bind = ArcBindInfoManager(msg).set_bind_info(username='', friendcode=code)
|
||||
if bind:
|
||||
await msg.finish(msg.locale.t("arcaea.message.bind.success.but_failed_fetch_username"))
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.bind.failed"))
|
||||
|
||||
@arc.command('unbind {{arcaea.help.unbind}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
unbind = ArcBindInfoManager(msg).remove_bind_info()
|
||||
if unbind:
|
||||
await msg.finish(msg.locale.t("arcaea.message.unbind.success"))
|
||||
|
||||
@arc.command('initialize', required_superuser=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
assets_apk = os.path.abspath('./assets/arc.apk')
|
||||
if not os.path.exists(assets_apk):
|
||||
await msg.finish(msg.locale.t("arcaea.message.initialize.not_found"))
|
||||
return
|
||||
result = await arcb30init()
|
||||
if result:
|
||||
await msg.finish(msg.locale.t("arcaea.message.initialize.success"))
|
||||
|
||||
|
||||
@arc.command('download {{arcaea.help.download}}')
|
||||
|
|
|
@ -2,7 +2,6 @@ from config import Config
|
|||
from core.builtins import Bot, Plain, Image
|
||||
from core.component import module
|
||||
from core.utils.http import get_url
|
||||
from core.utils.image import msgchain2image
|
||||
|
||||
api_address = Config('netease_cloud_music_api_url')
|
||||
|
||||
|
@ -13,6 +12,8 @@ ncmusic = module('ncmusic',
|
|||
|
||||
@ncmusic.handle('search <keyword> {{ncmusic.help.search}}')
|
||||
async def search(msg: Bot.MessageSession, keyword: str):
|
||||
if not api_address:
|
||||
await msg.finish(msg.locale.t('ncmusic.message.api_unconfigured'))
|
||||
url = f"{api_address}search?keywords={keyword}"
|
||||
result = await get_url(url, 200, fmt='json')
|
||||
|
||||
|
|
2
poetry.lock
generated
2
poetry.lock
generated
|
@ -4433,4 +4433,4 @@ cffi = ["cffi (>=1.11)"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8.1"
|
||||
content-hash = "397c58aa2c29af72e750d4ec142b2db8a8a59f009d10c9c15e61c396256a5272"
|
||||
content-hash = "21c1f768442311a5d4fa657d4f07b5290eb7f1b8fd09b8be89cae12c15904c70"
|
||||
|
|
|
@ -52,6 +52,7 @@ chromadb = "^0.3.21"
|
|||
tiktoken = "^0.3.3"
|
||||
pycryptodome = "^3.18.0"
|
||||
langconv = "^0.2.0"
|
||||
toml = "^0.10.2"
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
|
|
Reference in a new issue