Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4305548ab5 | |||
| 99382a3bf5 | |||
| 92e43785bf | |||
| fc5b11c5e8 | |||
| 0ec66988fa | |||
| e5c3081c22 | |||
| 14b356120a |
@ -10,6 +10,10 @@ trigger:
|
|||||||
- master
|
- master
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: submodules
|
||||||
|
image: alpine/git
|
||||||
|
commands:
|
||||||
|
- git submodule update --init --recursive
|
||||||
- name: 构建 Docker 镜像
|
- name: 构建 Docker 镜像
|
||||||
image: plugins/docker:latest
|
image: plugins/docker:latest
|
||||||
privileged: true
|
privileged: true
|
||||||
@ -50,6 +54,10 @@ trigger:
|
|||||||
- tag
|
- tag
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: submodules
|
||||||
|
image: alpine/git
|
||||||
|
commands:
|
||||||
|
- git submodule update --init --recursive
|
||||||
- name: 构建并推送 Release Docker 镜像
|
- name: 构建并推送 Release Docker 镜像
|
||||||
image: plugins/docker:latest
|
image: plugins/docker:latest
|
||||||
privileged: true
|
privileged: true
|
||||||
|
|||||||
360393
assets/lexicon/common.txt
Normal file
360393
assets/lexicon/common.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,3 +12,10 @@ DOCS_PATH_MAN1 = DOCS_PATH / "user"
|
|||||||
DOCS_PATH_MAN3 = DOCS_PATH / "lib"
|
DOCS_PATH_MAN3 = DOCS_PATH / "lib"
|
||||||
DOCS_PATH_MAN7 = DOCS_PATH / "concepts"
|
DOCS_PATH_MAN7 = DOCS_PATH / "concepts"
|
||||||
DOCS_PATH_MAN8 = DOCS_PATH / "sys"
|
DOCS_PATH_MAN8 = DOCS_PATH / "sys"
|
||||||
|
|
||||||
|
if not DATA_PATH.exists():
|
||||||
|
DATA_PATH.mkdir()
|
||||||
|
|
||||||
|
if not LOG_PATH.exists():
|
||||||
|
LOG_PATH.mkdir()
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,14 @@ def init_lexicon():
|
|||||||
# 词语大表
|
# 词语大表
|
||||||
with open(ASSETS_PATH / "lexicon" / "ci.json", "r", encoding="utf-8") as f:
|
with open(ASSETS_PATH / "lexicon" / "ci.json", "r", encoding="utf-8") as f:
|
||||||
ALL_WORDS = json.load(f)
|
ALL_WORDS = json.load(f)
|
||||||
|
|
||||||
|
COMMON_WORDS = []
|
||||||
|
# 读取 COMMON 词语大表
|
||||||
|
with open(ASSETS_PATH / "lexicon" / "common.txt", "r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
word = line.strip()
|
||||||
|
if len(word) == 4:
|
||||||
|
COMMON_WORDS.append(word)
|
||||||
|
|
||||||
# 读取 THUOCL 成语库
|
# 读取 THUOCL 成语库
|
||||||
with open(ASSETS_PATH / "lexicon" / "THUOCL" / "data" / "THUOCL_chengyu.txt", "r", encoding="utf-8") as f:
|
with open(ASSETS_PATH / "lexicon" / "THUOCL" / "data" / "THUOCL_chengyu.txt", "r", encoding="utf-8") as f:
|
||||||
@ -49,7 +57,7 @@ def init_lexicon():
|
|||||||
ALL_IDIOMS = list(set(ALL_IDIOMS)) # 去重
|
ALL_IDIOMS = list(set(ALL_IDIOMS)) # 去重
|
||||||
|
|
||||||
# 其他四字词语表,仅表示可以有这个词
|
# 其他四字词语表,仅表示可以有这个词
|
||||||
ALL_WORDS = [word for word in ALL_WORDS if len(word) == 4] + THUOCL_WORDS
|
ALL_WORDS = [word for word in ALL_WORDS if len(word) == 4] + THUOCL_WORDS + COMMON_WORDS
|
||||||
ALL_WORDS = list(set(ALL_WORDS)) # 去重
|
ALL_WORDS = list(set(ALL_WORDS)) # 去重
|
||||||
|
|
||||||
# 根据成语大表,划分出成语首字字典
|
# 根据成语大表,划分出成语首字字典
|
||||||
@ -109,7 +117,7 @@ async def _(event: BaseEvent):
|
|||||||
# 按分数排序,名字用 at 的方式
|
# 按分数排序,名字用 at 的方式
|
||||||
sorted_score = sorted(SCORE_BOARD.items(), key=lambda x: x[1]["score"], reverse=True)
|
sorted_score = sorted(SCORE_BOARD.items(), key=lambda x: x[1]["score"], reverse=True)
|
||||||
for i, (user_id, info) in enumerate(sorted_score):
|
for i, (user_id, info) in enumerate(sorted_score):
|
||||||
result_text += f"{i+1}. " + UniMessage().at(user_id) + f" - {info['score']} 分\n"
|
result_text += f"{i+1}. " + UniMessage().at(user_id) + f": {info['score']} 分\n"
|
||||||
await evt.send(await result_text.export())
|
await evt.send(await result_text.export())
|
||||||
# 重置分数板
|
# 重置分数板
|
||||||
SCORE_BOARD = {}
|
SCORE_BOARD = {}
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
import json, time
|
import json, time
|
||||||
|
|
||||||
from nonebot_plugin_alconna import (Alconna, Args, Field, MultiVar, UniMessage,
|
from nonebot_plugin_alconna import Alconna, Args, Field, MultiVar, on_alconna
|
||||||
on_alconna)
|
|
||||||
from nonebot_plugin_alconna.uniseg import UniMsg, At, Reply
|
|
||||||
from nonebot.adapters.onebot.v11 import Event
|
from nonebot.adapters.onebot.v11 import Event
|
||||||
|
|
||||||
poll_json_path = "assets/json/poll.json"
|
from konabot.common.path import ASSETS_PATH, DATA_PATH
|
||||||
|
|
||||||
poll_file = open(poll_json_path,"r",encoding="utf-8")
|
|
||||||
poll_list_raw = poll_file.read()
|
POLL_TEMPLATE_FILE = ASSETS_PATH / "json" / "poll.json"
|
||||||
poll_file.close()
|
POLL_DATA_FILE = DATA_PATH / "poll.json"
|
||||||
poll_list = json.loads(poll_list_raw)['poll']
|
|
||||||
|
if not POLL_DATA_FILE.exists():
|
||||||
|
POLL_DATA_FILE.write_bytes(POLL_TEMPLATE_FILE.read_bytes())
|
||||||
|
|
||||||
|
|
||||||
|
poll_list = json.loads(POLL_DATA_FILE.read_text())['poll']
|
||||||
|
|
||||||
async def createpoll(title,qqid,options):
|
async def createpoll(title,qqid,options):
|
||||||
polllength = len(poll_list)
|
polllength = len(poll_list)
|
||||||
@ -44,8 +47,11 @@ def getpolldata(pollid_or_title):
|
|||||||
return [thepoll,polnum]
|
return [thepoll,polnum]
|
||||||
|
|
||||||
def writeback():
|
def writeback():
|
||||||
file = open(poll_json_path,"w",encoding="utf-8")
|
# file = open(poll_json_path,"w",encoding="utf-8")
|
||||||
json.dump({'poll':poll_list},file,ensure_ascii=False,sort_keys=True)
|
# json.dump({'poll':poll_list},file,ensure_ascii=False,sort_keys=True)
|
||||||
|
POLL_DATA_FILE.write_text(json.dumps({
|
||||||
|
'poll': poll_list,
|
||||||
|
}, ensure_ascii=False, sort_keys=True))
|
||||||
|
|
||||||
async def pollvote(polnum,optionnum,qqnum):
|
async def pollvote(polnum,optionnum,qqnum):
|
||||||
optiond = poll_list[polnum]["polldata"]
|
optiond = poll_list[polnum]["polldata"]
|
||||||
@ -157,4 +163,4 @@ async def _(saying: list, event: Event):
|
|||||||
# 写入项目
|
# 写入项目
|
||||||
else:
|
else:
|
||||||
await pollvote(polnum,optionnum,event.get_user_id())
|
await pollvote(polnum,optionnum,event.get_user_id())
|
||||||
await viewpoll.send("投票成功!你投给了 "+saying[1])
|
await viewpoll.send("投票成功!你投给了 "+saying[1])
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import asyncio
|
import asyncio as asynkio
|
||||||
import datetime
|
import datetime
|
||||||
|
import functools
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Literal, cast
|
from typing import Any, Literal, cast
|
||||||
|
|
||||||
|
import signal
|
||||||
import nonebot
|
import nonebot
|
||||||
import ptimeparse
|
import ptimeparse
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@ -24,7 +26,9 @@ evt = on_message()
|
|||||||
|
|
||||||
(Path(__file__).parent.parent.parent.parent / "data").mkdir(exist_ok=True)
|
(Path(__file__).parent.parent.parent.parent / "data").mkdir(exist_ok=True)
|
||||||
DATA_FILE_PATH = Path(__file__).parent.parent.parent.parent / "data" / "notify.json"
|
DATA_FILE_PATH = Path(__file__).parent.parent.parent.parent / "data" / "notify.json"
|
||||||
DATA_FILE_LOCK = asyncio.Lock()
|
DATA_FILE_LOCK = asynkio.Lock()
|
||||||
|
|
||||||
|
ASYNK_TASKS: set[asynkio.Task[Any]] = set()
|
||||||
|
|
||||||
|
|
||||||
class Notify(BaseModel):
|
class Notify(BaseModel):
|
||||||
@ -111,7 +115,11 @@ def create_notify_task(notify: Notify, fail2remove: bool = True):
|
|||||||
async def mission():
|
async def mission():
|
||||||
begin_time = datetime.datetime.now()
|
begin_time = datetime.datetime.now()
|
||||||
if begin_time < notify.notify_time:
|
if begin_time < notify.notify_time:
|
||||||
await asyncio.sleep((notify.notify_time - begin_time).total_seconds())
|
try:
|
||||||
|
await asynkio.sleep((notify.notify_time - begin_time).total_seconds())
|
||||||
|
except asynkio.CancelledError:
|
||||||
|
logger.debug("代办提醒被信号中止,任务退出")
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"期望在 {notify.notify_time} 在平台 {notify.platform} {notify.target_env}"
|
f"期望在 {notify.notify_time} 在平台 {notify.platform} {notify.target_env}"
|
||||||
@ -128,7 +136,7 @@ def create_notify_task(notify: Notify, fail2remove: bool = True):
|
|||||||
DATA_FILE_LOCK.release()
|
DATA_FILE_LOCK.release()
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
return asyncio.create_task(mission())
|
return asynkio.create_task(mission())
|
||||||
|
|
||||||
|
|
||||||
@evt.handle()
|
@evt.handle()
|
||||||
@ -214,11 +222,11 @@ async def _():
|
|||||||
|
|
||||||
DELTA = 2
|
DELTA = 2
|
||||||
logger.info(f"第一次探测到 Bot 连接,等待 {DELTA} 秒后开始通知")
|
logger.info(f"第一次探测到 Bot 连接,等待 {DELTA} 秒后开始通知")
|
||||||
await asyncio.sleep(DELTA)
|
await asynkio.sleep(DELTA)
|
||||||
|
|
||||||
await DATA_FILE_LOCK.acquire()
|
await DATA_FILE_LOCK.acquire()
|
||||||
|
|
||||||
tasks: set[asyncio.Task[Any]] = set()
|
# tasks: set[asynkio.Task[Any]] = set()
|
||||||
cfg = load_notify_config()
|
cfg = load_notify_config()
|
||||||
if cfg.version == 1:
|
if cfg.version == 1:
|
||||||
logger.info("将配置文件的版本升级为 2")
|
logger.info("将配置文件的版本升级为 2")
|
||||||
@ -227,11 +235,26 @@ async def _():
|
|||||||
counter = 0
|
counter = 0
|
||||||
for notify in [*cfg.notifies]:
|
for notify in [*cfg.notifies]:
|
||||||
task = create_notify_task(notify, fail2remove=False)
|
task = create_notify_task(notify, fail2remove=False)
|
||||||
tasks.add(task)
|
ASYNK_TASKS.add(task)
|
||||||
task.add_done_callback(lambda self: tasks.remove(self))
|
task.add_done_callback(lambda self: ASYNK_TASKS.remove(self))
|
||||||
counter += 1
|
counter += 1
|
||||||
logger.info(f"成功创建了 {counter} 条代办事项")
|
logger.info(f"成功创建了 {counter} 条代办事项")
|
||||||
save_notify_config(cfg)
|
save_notify_config(cfg)
|
||||||
DATA_FILE_LOCK.release()
|
DATA_FILE_LOCK.release()
|
||||||
|
|
||||||
await asyncio.gather(*tasks)
|
loop = asynkio.get_running_loop()
|
||||||
|
|
||||||
|
# 解决 asynk task 没有被 cancel 的问题
|
||||||
|
async def shutdown(sig: signal.Signals):
|
||||||
|
logger.info(f"收到 {sig.name} 指令,正在关闭所有的东西")
|
||||||
|
for task in ASYNK_TASKS:
|
||||||
|
task.cancel()
|
||||||
|
await asynkio.gather(*ASYNK_TASKS, return_exceptions=True)
|
||||||
|
logger.info("所有的代办提醒 Task 都已经退出了")
|
||||||
|
|
||||||
|
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||||
|
loop.add_signal_handler(sig, functools.partial(
|
||||||
|
asynkio.create_task, shutdown(sig)
|
||||||
|
))
|
||||||
|
|
||||||
|
await asynkio.gather(*ASYNK_TASKS)
|
||||||
|
|||||||
Reference in New Issue
Block a user