mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2025-04-12 23:29:37 +08:00
fix bug
This commit is contained in:
parent
b25415e341
commit
04f93b6eb0
@ -1,16 +1,17 @@
|
||||
import asyncio
|
||||
from . import util
|
||||
from typing import Union
|
||||
from pathlib import Path
|
||||
from nonebot import on_command
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.exception import FinishedException
|
||||
from nonebot.adapters.onebot.v11 import PrivateMessageEvent, GroupMessageEvent, MessageSegment, Bot, permission
|
||||
from .handler import Guess, get_random_voice
|
||||
from . import download_data
|
||||
from ..utils.config import config
|
||||
from typing import Union
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.adapters.onebot.v11 import PrivateMessageEvent, GroupMessageEvent, MessageSegment, Bot
|
||||
from nonebot.exception import FinishedException
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.permission import SUPERUSER
|
||||
|
||||
from utils.config import config
|
||||
from . import download_data
|
||||
from . import util
|
||||
from .handler import Guess, get_random_voice
|
||||
|
||||
setting_time = config.paimon_guess_voice # 游戏持续时间
|
||||
|
||||
|
@ -6,12 +6,13 @@
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from bs4 import BeautifulSoup
|
||||
from sqlitedict import SqliteDict # TODO 加入requirements
|
||||
from .util import get_path
|
||||
from nonebot import logger
|
||||
from ..utils.http_util import aiorequests
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from nonebot import logger
|
||||
from sqlitedict import SqliteDict # TODO 加入requirements
|
||||
|
||||
from utils import aiorequests
|
||||
from .util import get_path
|
||||
|
||||
# OUT_PUT = Path(__file__).parent / 'voice'
|
||||
OUT_PUT = Path() / 'data' / 'LittlePaimon' / 'guess_voice' / 'voice'
|
||||
|
@ -1,19 +1,20 @@
|
||||
import os
|
||||
import random
|
||||
import datetime
|
||||
import json
|
||||
from apscheduler.triggers.date import DateTrigger
|
||||
from typing import List
|
||||
import os
|
||||
import random
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from apscheduler.triggers.date import DateTrigger
|
||||
from nonebot import get_bot, require, logger
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, escape
|
||||
from sqlitedict import SqliteDict
|
||||
from .util import get_path, require_file
|
||||
from nonebot.rule import Rule
|
||||
from nonebot import on_regex
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, escape
|
||||
from nonebot.rule import Rule
|
||||
from sqlitedict import SqliteDict
|
||||
|
||||
from .download_data import voice_list_by_mys, voice_detail_by_mys
|
||||
from .util import get_path, require_file
|
||||
|
||||
scheduler = require('nonebot_plugin_apscheduler').scheduler
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import aiofiles
|
||||
from ..utils.http_util import aiorequests
|
||||
|
||||
from utils import aiorequests
|
||||
|
||||
|
||||
def get_path(dirname, filename):
|
||||
|
@ -1,13 +1,14 @@
|
||||
from nonebot import on_regex, logger
|
||||
from nonebot.exception import FinishedException
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageSegment
|
||||
from ..utils.util import FreqLimiter2
|
||||
from ..utils.config import config
|
||||
from .chat_list import chat_list
|
||||
from pathlib import Path
|
||||
import random
|
||||
import os
|
||||
import random
|
||||
from pathlib import Path
|
||||
|
||||
from nonebot import on_regex, logger
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageSegment
|
||||
from nonebot.exception import FinishedException
|
||||
|
||||
from utils.config import config
|
||||
from utils.auth_util import FreqLimiter2
|
||||
from .chat_list import chat_list
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res', 'voice')
|
||||
chat_lmt = FreqLimiter2(60)
|
||||
|
@ -1,13 +1,15 @@
|
||||
import re
|
||||
from typing import Dict, Union
|
||||
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, MessageEvent, GroupMessageEvent
|
||||
from nonebot.params import RegexDict
|
||||
|
||||
from utils.config import config
|
||||
from utils import aiorequests
|
||||
from utils.auth_util import FreqLimiter
|
||||
from .gacha_info import *
|
||||
from .gacha_res import more_ten
|
||||
from ..utils.config import config
|
||||
from ..utils.util import FreqLimiter
|
||||
from ..utils.http_util import aiorequests
|
||||
from typing import Dict, Union
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.params import RegexDict
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, MessageEvent, GroupMessageEvent
|
||||
|
||||
__usage__ = '''
|
||||
1.[抽n十连xx池]抽n次xx池的十连,最多同时5次
|
||||
|
@ -1,5 +1,5 @@
|
||||
import os
|
||||
import json
|
||||
from utils.file_handler import load_json, save_json
|
||||
|
||||
RES_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res', 'gacha_res')
|
||||
USER_INFO_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'user_data', 'user_gacha_info.json')
|
||||
@ -8,35 +8,15 @@ ROLE_2_PATH = os.path.join(RES_PATH, "DIY_gacha_pool", "role_2.json")
|
||||
WEAPON_PATH = os.path.join(RES_PATH, "DIY_gacha_pool", "weapon.json")
|
||||
All_STAR_PATH = os.path.join(RES_PATH, "DIY_gacha_pool", "all_star.json")
|
||||
|
||||
user_info = {}
|
||||
role_1_pool = {}
|
||||
role_2_pool = {}
|
||||
weapon_pool = {}
|
||||
all_star = {}
|
||||
user_info = load_json(path=USER_INFO_PATH)
|
||||
role_1_pool = load_json(path=ROLE_1_PATH)
|
||||
role_2_pool = load_json(path=ROLE_2_PATH)
|
||||
weapon_pool = load_json(path=WEAPON_PATH)
|
||||
all_star = load_json(path=All_STAR_PATH)
|
||||
|
||||
|
||||
def save_user_info():
|
||||
with open(USER_INFO_PATH, 'w', encoding='UTF-8') as f:
|
||||
json.dump(user_info, f, ensure_ascii=False)
|
||||
|
||||
|
||||
if not os.path.exists(USER_INFO_PATH):
|
||||
save_user_info()
|
||||
|
||||
with open(USER_INFO_PATH, 'r', encoding='UTF-8') as f:
|
||||
user_info = json.load(f)
|
||||
|
||||
with open(ROLE_1_PATH, 'r', encoding='UTF-8') as f:
|
||||
role_1_pool = json.load(f)
|
||||
|
||||
with open(ROLE_2_PATH, 'r', encoding='UTF-8') as f:
|
||||
role_2_pool = json.load(f)
|
||||
|
||||
with open(WEAPON_PATH, 'r', encoding='UTF-8') as f:
|
||||
weapon_pool = json.load(f)
|
||||
|
||||
with open(All_STAR_PATH, 'r', encoding='UTF-8') as f:
|
||||
all_star = json.load(f)
|
||||
save_json(data=user_info, path=USER_INFO_PATH)
|
||||
|
||||
|
||||
def init_user_info(uid: str):
|
||||
|
@ -1,13 +1,13 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
|
||||
import datetime
|
||||
import numpy
|
||||
import random
|
||||
|
||||
import numpy
|
||||
from PIL import Image, PngImagePlugin, ImageDraw, ImageFont
|
||||
|
||||
from utils.message_util import MessageBuild
|
||||
from .gacha_info import init_user_info, user_info, save_user_info
|
||||
from ..utils.util import pil2b64
|
||||
|
||||
RES_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res', 'gacha_res')
|
||||
font_path = os.path.join(RES_PATH, 'zh-cn.ttf')
|
||||
@ -117,7 +117,6 @@ def once(uid, gacha_data):
|
||||
user_info[uid]["gacha_list"]["wish_%s_up" % rank] += 1
|
||||
role['rank'] = rank
|
||||
else:
|
||||
role = random.choice(gacha_data['r%s_prob_list' % rank])
|
||||
while True:
|
||||
role = random.choice(gacha_data['r%s_prob_list' % rank])
|
||||
if role['is_up'] == 0:
|
||||
@ -246,4 +245,5 @@ async def more_ten(uid, gacha_data, num, sd):
|
||||
draw = ImageDraw.Draw(img)
|
||||
draw.text((27, 575 * num - 30), ('@%s %s Created By LittlePaimon' % (str(sd.nickname), time_str)), font=time_font,
|
||||
fill="#8E8E8E")
|
||||
return pil2b64(img, 75)
|
||||
|
||||
return MessageBuild.Image(img, quality=75)
|
||||
|
@ -1,8 +1,10 @@
|
||||
from .meta_data import *
|
||||
import time
|
||||
import os
|
||||
import time
|
||||
|
||||
import xlsxwriter
|
||||
|
||||
from .meta_data import *
|
||||
|
||||
data_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'user_data', 'gacha_log_data')
|
||||
|
||||
|
||||
|
@ -2,13 +2,16 @@ import json
|
||||
import os
|
||||
import re
|
||||
from typing import Union
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent, GroupMessageEvent
|
||||
from ..utils.util import get_uid_in_msg
|
||||
from nonebot.params import CommandArg
|
||||
|
||||
from utils.message_util import get_uid_in_msg
|
||||
from .api import toApi, checkApi
|
||||
from .gacha_logs import get_data
|
||||
from .get_img import get_gacha_log_img
|
||||
from .api import toApi, checkApi
|
||||
from pathlib import Path
|
||||
|
||||
__usage__ = '''
|
||||
1.[获取抽卡记录 (uid) (url)]提供url,获取原神抽卡记录,需要一定时间
|
||||
|
@ -1,5 +1,6 @@
|
||||
from urllib import parse
|
||||
from ..utils.http_util import aiorequests
|
||||
|
||||
from utils import aiorequests
|
||||
|
||||
|
||||
def toApi(url):
|
||||
|
@ -1,10 +1,11 @@
|
||||
import os
|
||||
import json
|
||||
import os
|
||||
from asyncio import sleep
|
||||
|
||||
from utils import aiorequests
|
||||
from .UIGF_and_XLSX import convertUIGF, writeXLSX
|
||||
from .api import getApi
|
||||
from .meta_data import gachaQueryTypeIds, gachaQueryTypeDict
|
||||
from .UIGF_and_XLSX import convertUIGF, writeXLSX
|
||||
from ..utils.http_util import aiorequests
|
||||
|
||||
data_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'user_data', 'gacha_log_data')
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import os
|
||||
from ..utils.util import pil2b64
|
||||
from ..utils.character_alias import get_short_name
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from utils.character_alias import get_short_name
|
||||
from utils.message_util import MessageBuild
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
|
||||
|
||||
@ -120,7 +121,7 @@ async def get_gacha_log_img(gacha_data, pool):
|
||||
break
|
||||
if not img:
|
||||
return '这个池子没有抽卡记录哦'
|
||||
total_height = (img.size)[1]
|
||||
total_height = img.size[1]
|
||||
else:
|
||||
img_list = []
|
||||
total_height = 0
|
||||
@ -129,17 +130,15 @@ async def get_gacha_log_img(gacha_data, pool):
|
||||
p_img = await draw_gacha_log(pd)
|
||||
if p_img:
|
||||
img_list.append(p_img)
|
||||
total_height += (p_img.size)[1]
|
||||
total_height += p_img.size[1]
|
||||
if not img_list:
|
||||
return '没有找到任何抽卡记录诶!'
|
||||
img = Image.new('RGBA', (768, total_height), (0, 0, 0, 255))
|
||||
for i in img_list:
|
||||
img.paste(i, (0, now_height))
|
||||
now_height += (i.size)[1]
|
||||
now_height += i.size[1]
|
||||
img_draw = ImageDraw.Draw(img)
|
||||
img_draw.text((595, 44), f'UID:{gacha_data["uid"]}', font=get_font(16), fill='black')
|
||||
img_draw.text((530, total_height - 45), 'Created by LittlePaimon', font=get_font(16), fill='black')
|
||||
|
||||
img = pil2b64(img, 95)
|
||||
img = MessageSegment.image(img)
|
||||
return img
|
||||
return MessageBuild.Image(img)
|
||||
|
@ -1,27 +1,31 @@
|
||||
import datetime
|
||||
import re
|
||||
import random
|
||||
from collections import defaultdict
|
||||
import re
|
||||
from asyncio import sleep
|
||||
from collections import defaultdict
|
||||
|
||||
from nonebot import on_command, require, logger, get_bot
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message, Bot
|
||||
from .get_data import get_bind_game, get_sign_info, sign, get_sign_list, get_abyss_data, get_daily_note_data
|
||||
from .get_data import get_monthinfo_data, get_player_card_data, get_chara_detail_data, get_chara_skill_data
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.rule import to_me
|
||||
|
||||
from utils.character_alias import get_id_by_alias
|
||||
from utils.config import config
|
||||
from utils.db_util import get_auto_sign, delete_auto_sign
|
||||
from utils.db_util import insert_public_cookie, update_private_cookie, delete_cookie_cache, delete_private_cookie, \
|
||||
update_last_query, reset_public_cookie
|
||||
from utils.db_util import update_note_remind2, update_note_remind, get_note_remind, delete_note_remind, \
|
||||
update_day_remind_count, get_private_cookie, add_auto_sign
|
||||
from utils.auth_util import check_cookie
|
||||
from utils.decorator import exception_handler
|
||||
from utils.message_util import get_uid_in_msg
|
||||
from .draw_abyss_info import draw_abyss_card
|
||||
from .draw_daily_note import draw_daily_note_card
|
||||
from .draw_month_info import draw_monthinfo_card
|
||||
from .draw_player_card import draw_player_card, draw_all_chara_card, draw_chara_card
|
||||
from ..utils.character_alias import get_id_by_alias
|
||||
from ..utils.util import get_uid_in_msg, check_cookie, exception_handler
|
||||
from ..utils.db_util import update_note_remind2, update_note_remind, get_note_remind, delete_note_remind, \
|
||||
update_day_remind_count, get_private_cookie, add_auto_sign
|
||||
from ..utils.db_util import insert_public_cookie, update_private_cookie, delete_cookie_cache, delete_private_cookie, \
|
||||
update_last_query, reset_public_cookie
|
||||
from ..utils.db_util import get_auto_sign, delete_auto_sign
|
||||
from ..utils.config import config
|
||||
from .get_data import get_bind_game, get_sign_info, sign, get_sign_list, get_abyss_data, get_daily_note_data
|
||||
from .get_data import get_monthinfo_data, get_player_card_data, get_chara_detail_data, get_chara_skill_data
|
||||
|
||||
scheduler = require('nonebot_plugin_apscheduler').scheduler
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import datetime
|
||||
import os
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from ..utils.util import pil2b64
|
||||
from ..utils.http_util import aiorequests
|
||||
|
||||
from utils import aiorequests
|
||||
from utils.message_util import MessageBuild
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
|
||||
|
||||
@ -189,6 +190,4 @@ async def draw_abyss_card(data, uid, floor_num):
|
||||
total_img.alpha_composite(floor_img, (5, 5 + 524 + 5 + h))
|
||||
h += 1210
|
||||
|
||||
total_img = pil2b64(total_img, 75)
|
||||
total_img = MessageSegment.image(total_img)
|
||||
return total_img
|
||||
return MessageBuild.Image(total_img, quality=75)
|
||||
|
@ -1,11 +1,12 @@
|
||||
import random
|
||||
import datetime
|
||||
import os
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import random
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from ..utils.util import pil2b64
|
||||
from ..utils.http_util import aiorequests
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from utils import aiorequests
|
||||
from utils.message_util import MessageBuild
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
|
||||
|
||||
@ -147,7 +148,4 @@ async def draw_daily_note_card(data, uid):
|
||||
bg_img.alpha_composite(role_img, (1220, 200))
|
||||
now = datetime.datetime.now().strftime('%m月%d日%H:%M')
|
||||
bg_draw.text((554, 1794), 'Created by LittlePaimon·' + now, fill='#5680d2', font=get_font(40, '优设标题黑.ttf'))
|
||||
bg_img = bg_img.resize((int(bg_img.size[0] * 0.35), int(bg_img.size[1] * 0.35)), Image.ANTIALIAS)
|
||||
bg_img = pil2b64(bg_img, 70)
|
||||
bg_img = MessageSegment.image(bg_img)
|
||||
return bg_img
|
||||
return MessageBuild.Image(bg_img, size=0.35, quality=70)
|
||||
|
@ -1,9 +1,9 @@
|
||||
import random
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import os
|
||||
import random
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from ..utils.util import pil2b64
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from utils.message_util import MessageBuild
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
|
||||
|
||||
@ -111,6 +111,4 @@ async def draw_monthinfo_card(data):
|
||||
bg_draw.text((49, 857), f'本月相比上个月,原石{ysstr},摩拉{mlstr}', font=get_font(23), fill='#27384C')
|
||||
bg_draw.text((167, 900), 'Created by LittlePaimon', font=get_font(21), fill='#27384C')
|
||||
|
||||
bg_img = pil2b64(bg_img, 70)
|
||||
bg_img = MessageSegment.image(bg_img)
|
||||
return bg_img
|
||||
return MessageBuild.Image(bg_img, quality=70)
|
||||
|
@ -1,9 +1,12 @@
|
||||
import os, random, re
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from ..utils.util import pil2b64
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
import copy
|
||||
from ..utils.http_util import aiorequests
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from utils import aiorequests
|
||||
from utils.message_util import MessageBuild
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
|
||||
|
||||
@ -248,9 +251,7 @@ async def draw_player_card(data, chara_data, uid, nickname="旅行者"):
|
||||
break
|
||||
else:
|
||||
nocha = '*这uid关闭了角色详情显示,派蒙看不到哦'
|
||||
bg_img = pil2b64(bg_img, 80)
|
||||
bg_img = MessageSegment.image(bg_img) + nocha
|
||||
return bg_img
|
||||
return MessageBuild.Image(bg_img, quality=80) + MessageBuild.Text(nocha)
|
||||
|
||||
|
||||
# ysa
|
||||
@ -335,9 +336,7 @@ async def draw_all_chara_card(data, uid):
|
||||
n += 1
|
||||
bg_img.paste(bg_bottom, (0, 382 + col * 474 - 50))
|
||||
|
||||
bg_img = pil2b64(bg_img, 55)
|
||||
bg_img = MessageSegment.image(bg_img)
|
||||
return bg_img
|
||||
return MessageBuild.Image(bg_img, size=0.9, quality=70)
|
||||
|
||||
|
||||
# ysc
|
||||
@ -443,8 +442,7 @@ async def draw_chara_card(data, skill_data, chara_name, uid):
|
||||
# 武器
|
||||
weapon_bg = Image.open(os.path.join(res_path, 'other', f'star{character["weapon"]["rarity"]}.png')).resize(
|
||||
(100, 100))
|
||||
weapon_name = character['weapon']['icon'].split('/')[-1]
|
||||
weapon_icon = Image.open(os.path.join(res_path, 'weapon', weapon_name)).resize((100, 100))
|
||||
weapon_icon = await aiorequests.get_img(url=character['weapon']['icon'], size=(100, 100), mode='RGBA')
|
||||
bg_img.alpha_composite(weapon_bg, (293, 175))
|
||||
bg_img.alpha_composite(weapon_icon, (293, 175))
|
||||
bg_img.alpha_composite(shadow.resize((50, 25)), (344, 250))
|
||||
@ -516,6 +514,5 @@ async def draw_chara_card(data, skill_data, chara_name, uid):
|
||||
i += 1
|
||||
|
||||
bg_draw.text((330, 371), 'Created by LittlePaimon', font=get_font(20), fill='white')
|
||||
bg_img = pil2b64(bg_img, 70)
|
||||
bg_img = MessageSegment.image(bg_img)
|
||||
return bg_img
|
||||
|
||||
return MessageBuild.Image(bg_img, size=0.95, quality=80)
|
||||
|
@ -1,6 +1,7 @@
|
||||
from ..utils.util import get_headers, get_sign_headers, cache, get_use_cookie, get_own_cookie, check_retcode
|
||||
from ..utils.db_util import update_cookie_cache
|
||||
from ..utils.http_util import aiorequests
|
||||
from utils.auth_util import get_headers, get_sign_headers, get_use_cookie, get_own_cookie, check_retcode
|
||||
from utils.db_util import update_cookie_cache
|
||||
from utils.decorator import cache
|
||||
from utils import aiorequests
|
||||
import datetime
|
||||
import re
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import random
|
||||
from asyncio import sleep
|
||||
from ..utils.config import config
|
||||
from utils.config import config
|
||||
from nonebot import get_driver
|
||||
from nonebot.message import event_preprocessor
|
||||
from nonebot.adapters.onebot.v11 import Bot, FriendRequestEvent, GroupRequestEvent
|
||||
|
@ -2,9 +2,10 @@ from urllib.parse import quote
|
||||
from nonebot import on_command
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent
|
||||
from ..utils.util import FreqLimiter, get_id
|
||||
from ..utils.config import config
|
||||
from ..utils.http_util import aiorequests
|
||||
from utils.auth_util import FreqLimiter
|
||||
from utils.message_util import get_message_id
|
||||
from utils.config import config
|
||||
from utils import aiorequests
|
||||
|
||||
couplets = on_command('对联', aliases={'对对联'}, priority=13, block=True)
|
||||
|
||||
@ -15,8 +16,8 @@ couplets_limit = FreqLimiter(config.paimon_couplets_cd)
|
||||
async def couplets_handler(event: MessageEvent, msg=CommandArg()):
|
||||
if not msg:
|
||||
await couplets.finish('请输入对联内容')
|
||||
if not couplets_limit.check(get_id(event)):
|
||||
await couplets.finish(f'对联冷却ing(剩余{couplets_limit.left_time(get_id(event))}秒)')
|
||||
if not couplets_limit.check(get_message_id(event)):
|
||||
await couplets.finish(f'对联冷却ing(剩余{couplets_limit.left_time(get_message_id(event))}秒)')
|
||||
else:
|
||||
msg = str(msg).split(' ')
|
||||
word = msg[0].strip()
|
||||
@ -25,7 +26,7 @@ async def couplets_handler(event: MessageEvent, msg=CommandArg()):
|
||||
except:
|
||||
num = 1
|
||||
num = num if num < 10 else 10
|
||||
couplets_limit.start_cd(get_id(event), config.paimon_couplets_cd)
|
||||
couplets_limit.start_cd(get_message_id(event), config.paimon_couplets_cd)
|
||||
text = quote(str(word))
|
||||
url = f'https://ai-backend.binwang.me/v0.2/couplet/{text}'
|
||||
res = await aiorequests.get(url=url)
|
||||
|
@ -2,8 +2,9 @@ import re
|
||||
from nonebot import on_command, require, get_bot, logger
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment
|
||||
from ..utils.util import load_data, save_data, get_id
|
||||
from ..utils.http_util import aiorequests
|
||||
from utils import aiorequests
|
||||
from utils.file_handler import load_json, save_json
|
||||
from utils.message_util import get_message_id
|
||||
|
||||
news60s_pic = on_command('早报', aliases={'今日早报', '今日新闻', '60s读世界'}, priority=13, block=True)
|
||||
|
||||
@ -22,8 +23,8 @@ async def news60s_pic_handler(event: MessageEvent, msg=CommandArg()):
|
||||
# 匹配msg中的xx:xx时间
|
||||
time_str = re.search(r'(\d{1,2}):(\d{2})', msg)
|
||||
if time_str:
|
||||
push_data = load_data('news60s_push.json')
|
||||
push_id = str(get_id(event))
|
||||
push_data = load_json('news60s_push.json')
|
||||
push_id = str(get_message_id(event))
|
||||
push_data[push_id] = {
|
||||
'type': event.message_type,
|
||||
'hour': int(time_str.group(1)),
|
||||
@ -31,26 +32,27 @@ async def news60s_pic_handler(event: MessageEvent, msg=CommandArg()):
|
||||
}
|
||||
if event.message_type == 'guild':
|
||||
push_data[push_id]['guild_id'] = event.guild_id
|
||||
if scheduler.get_job('60sNews' + str(get_id(event))):
|
||||
scheduler.remove_job('60sNews' + str(get_id(event)))
|
||||
if scheduler.get_job('60sNews' + str(get_message_id(event))):
|
||||
scheduler.remove_job('60sNews' + str(get_message_id(event)))
|
||||
scheduler.add_job(
|
||||
func=news60s_push_task,
|
||||
trigger='cron',
|
||||
hour=int(time_str.group(1)),
|
||||
minute=int(time_str.group(2)),
|
||||
id='60sNews' + str(get_id(event)),
|
||||
args=(str(get_id(event)),
|
||||
push_data[str(get_id(event))])
|
||||
id='60sNews' + str(get_message_id(event)),
|
||||
args=(str(get_message_id(event)),
|
||||
push_data[str(get_message_id(event))])
|
||||
)
|
||||
save_data(push_data, 'news60s_push.json')
|
||||
save_json(push_data, 'news60s_push.json')
|
||||
await news60s_pic.finish('开启60s读世界推送成功', at_sender=True)
|
||||
else:
|
||||
await news60s_pic.finish('请给出正确的时间,格式为12:00', at_sender=True)
|
||||
elif msg.startswith('关闭推送'):
|
||||
push_data = load_data('news60s_push.json')
|
||||
del push_data[str(get_id(event))]
|
||||
scheduler.remove_job('60sNews' + str(get_id(event)))
|
||||
save_data(push_data, 'news60s_push.json')
|
||||
push_data = load_json('news60s_push.json')
|
||||
del push_data[str(get_message_id(event))]
|
||||
if scheduler.get_job('60sNews' + str(get_message_id(event))):
|
||||
scheduler.remove_job('60sNews' + str(get_message_id(event)))
|
||||
save_json(push_data, 'news60s_push.json')
|
||||
await news60s_pic.finish('关闭60s读世界推送成功', at_sender=True)
|
||||
|
||||
|
||||
@ -71,7 +73,7 @@ async def news60s_push_task(push_id, push_data: dict):
|
||||
logger.exception(f'{push_data["type"]}的{push_id}的60秒读世界推送失败:{e}')
|
||||
|
||||
|
||||
for push_id, push_data in load_data('news60s_push.json').items():
|
||||
for push_id, push_data in load_json('news60s_push.json').items():
|
||||
scheduler.add_job(
|
||||
func=news60s_push_task,
|
||||
trigger='cron',
|
||||
|
@ -2,8 +2,8 @@ import random
|
||||
from nonebot import on_command
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.adapters.onebot.v11 import Message, MessageEvent, MessageSegment
|
||||
from ..utils.util import FreqLimiter
|
||||
from ..utils.http_util import aiorequests
|
||||
from utils.auth_util import FreqLimiter
|
||||
from utils import aiorequests
|
||||
|
||||
order_pic = on_command('点菜', aliases={'点餐', '食谱', '我想吃'}, priority=13, block=True)
|
||||
order_lmt = FreqLimiter(10)
|
||||
|
@ -2,8 +2,10 @@ import random
|
||||
from nonebot import on_command, on_regex
|
||||
from nonebot.params import RegexGroup
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment
|
||||
from ..utils.config import config
|
||||
from ..utils.util import FreqLimiter, auto_withdraw, get_id
|
||||
from utils.config import config
|
||||
from utils.auth_util import FreqLimiter
|
||||
from utils.message_util import get_message_id
|
||||
from utils.decorator import auto_withdraw
|
||||
|
||||
cat_lmt = FreqLimiter(config.paimon_cat_cd)
|
||||
ecy_lmt = FreqLimiter(config.paimon_ecy_cd)
|
||||
@ -16,11 +18,11 @@ ys_img = on_command('原神壁纸', aliases={'来点原神图', '来点原神壁
|
||||
|
||||
@cat_img.handle()
|
||||
async def cat_img_handler(event: MessageEvent):
|
||||
if not cat_lmt.check(get_id(event)):
|
||||
await cat_img.finish(f'猫片冷却ing(剩余{cat_lmt.left_time(get_id(event))}秒)')
|
||||
if not cat_lmt.check(get_message_id(event)):
|
||||
await cat_img.finish(f'猫片冷却ing(剩余{cat_lmt.left_time(get_message_id(event))}秒)')
|
||||
else:
|
||||
await cat_img.send('派蒙努力找图ing..请稍候...')
|
||||
cat_lmt.start_cd(get_id(event), config.paimon_cat_cd)
|
||||
cat_lmt.start_cd(get_message_id(event), config.paimon_cat_cd)
|
||||
url = 'http://edgecats.net/'
|
||||
await cat_img.finish(MessageSegment.image(file=url))
|
||||
|
||||
@ -49,11 +51,11 @@ async def ecy_img_handler(bot: Bot, event: MessageEvent, regexGroup=RegexGroup()
|
||||
url = 'https://iw233.cn/api.php?sort=pc'
|
||||
else:
|
||||
url = ''
|
||||
if not ecy_lmt.check(get_id(event)):
|
||||
await ecy_img.finish(f'二次元图片冷却ing(剩余{ecy_lmt.left_time(get_id(event))}秒)')
|
||||
if not ecy_lmt.check(get_message_id(event)):
|
||||
await ecy_img.finish(f'二次元图片冷却ing(剩余{ecy_lmt.left_time(get_message_id(event))}秒)')
|
||||
elif url:
|
||||
await ecy_img.send('派蒙努力找图ing..请稍候...')
|
||||
ecy_lmt.start_cd(get_id(event), config.paimon_ecy_cd)
|
||||
ecy_lmt.start_cd(get_message_id(event), config.paimon_ecy_cd)
|
||||
return await ecy_img.send(MessageSegment.image(file=url))
|
||||
|
||||
|
||||
@ -64,9 +66,9 @@ async def ys_img_handler(event: MessageEvent):
|
||||
'https://api.dujin.org/img/yuanshen/',
|
||||
'https://api.dreamofice.cn/random-v0/img.php?game=ys'
|
||||
]
|
||||
if not ys_lmt.check(get_id(event)):
|
||||
await ys_img.finish(f'原神壁纸冷却ing(剩余{ys_lmt.left_time(get_id(event))}秒)')
|
||||
if not ys_lmt.check(get_message_id(event)):
|
||||
await ys_img.finish(f'原神壁纸冷却ing(剩余{ys_lmt.left_time(get_message_id(event))}秒)')
|
||||
else:
|
||||
await ys_img.send('派蒙努力找图ing..请稍候...')
|
||||
ys_lmt.start_cd(get_id(event), config.paimon_ysp_cd)
|
||||
ys_lmt.start_cd(get_message_id(event), config.paimon_ysp_cd)
|
||||
await ys_img.finish(MessageSegment.image(file=random.choice(urls)))
|
@ -1,14 +1,16 @@
|
||||
import os
|
||||
from nonebot import on_endswith, on_command, on_regex
|
||||
from nonebot.params import RegexDict
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, MessageEvent
|
||||
from ..utils.character_alias import get_id_by_alias
|
||||
from ..utils.util import exception_handler
|
||||
from .blue import get_blue_pic
|
||||
from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
|
||||
import re
|
||||
import time
|
||||
|
||||
from nonebot import on_endswith, on_command, on_regex
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment, MessageEvent
|
||||
from nonebot.params import RegexDict
|
||||
|
||||
from utils.character_alias import get_id_by_alias
|
||||
from utils.decorator import exception_handler
|
||||
from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
|
||||
from .blue import get_blue_pic
|
||||
|
||||
__usage__ = '''
|
||||
1.[xx角色攻略]查看西风驿站出品的角色一图流攻略
|
||||
2.[xx角色材料]查看惜月出品的角色材料统计
|
||||
@ -70,7 +72,7 @@ async def genshinAttribute(event: MessageEvent):
|
||||
if name in ['风主', '岩主', '雷主'] or realname:
|
||||
name = realname[1][0] if name not in ['风主', '岩主', '雷主'] else name
|
||||
img = await get_blue_pic(name)
|
||||
await attribute.finish(MessageSegment.image(file=img))
|
||||
await attribute.finish(img)
|
||||
else:
|
||||
await attribute.finish(f'没有找到{name}的参考面板', at_sender=True)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from ..utils.http_util import aiorequests
|
||||
from utils import aiorequests
|
||||
|
||||
# 数据源自微信公众号原神创意工坊
|
||||
headers = {
|
||||
|
@ -1,9 +1,10 @@
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import os
|
||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from utils.character_alias import get_id_by_alias
|
||||
from utils.message_util import MessageBuild
|
||||
from .abyss_rate_data import get_rate, get_formation_rate
|
||||
from ..utils.util import pil2b64
|
||||
from ..utils.character_alias import get_id_by_alias
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
|
||||
|
||||
@ -73,7 +74,6 @@ async def draw_teams_rate(floor='上半半'):
|
||||
bg_img.alpha_composite(role_img, (130 + 204 * r, 180 + 240 * n))
|
||||
r += 1
|
||||
n += 1
|
||||
bg_img = pil2b64(bg_img, 75)
|
||||
bg_img = MessageSegment.image(bg_img)
|
||||
return bg_img
|
||||
|
||||
return MessageBuild.Image(bg_img, quality=75)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
from ..utils.util import pil2b64
|
||||
from ..utils.http_util import aiorequests
|
||||
from utils import aiorequests
|
||||
from utils.message_util import MessageBuild
|
||||
|
||||
blue = {
|
||||
'胡桃': ['火', (0, 1886)],
|
||||
@ -62,6 +62,5 @@ async def get_blue_pic(name):
|
||||
if c[0] == name:
|
||||
img = await aiorequests.get_img(url=f'https://static.cherishmoon.fun/LittlePaimon/blue/{c[1][0]}.jpg')
|
||||
img = img.crop((0, int(c[1][1][0]), 1080, int(c[1][1][1])))
|
||||
img = pil2b64(img, 100)
|
||||
return img
|
||||
return MessageBuild.Image(img)
|
||||
return None
|
||||
|
@ -69,6 +69,9 @@
|
||||
- `原神猜语音`不再需要`我猜`,直接回答角色别名即可参与猜猜看
|
||||
- 异步请求库从`aiohttp`改用`httpx`,需安装依赖库`pip install httpx`
|
||||
- 修复`60秒读世界`在频道无法关闭推送的BUG
|
||||
+ 5.20
|
||||
- 修复`ysc`缺少资源问题
|
||||
- 封装部分常用方法,优化导包
|
||||
|
||||
## 功能列表
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
104
utils/aiorequests.py
Normal file
104
utils/aiorequests.py
Normal file
@ -0,0 +1,104 @@
|
||||
import base64
|
||||
from typing import Dict, Optional, Any, Union, Tuple
|
||||
from pathlib import Path
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
import httpx
|
||||
|
||||
|
||||
async def get(url: str,
|
||||
*,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
timeout: Optional[int] = 20,
|
||||
**kwargs) -> httpx.Response:
|
||||
"""
|
||||
说明:
|
||||
httpx的get请求封装
|
||||
参数:
|
||||
:param url: url
|
||||
:param headers: 请求头
|
||||
:param params: params
|
||||
:param timeout: 超时时间
|
||||
"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
return await client.get(url,
|
||||
headers=headers,
|
||||
params=params,
|
||||
timeout=timeout,
|
||||
**kwargs)
|
||||
|
||||
|
||||
async def post(url: str,
|
||||
*,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
data: Optional[Dict[str, Any]] = None,
|
||||
json: Optional[Dict[str, Union[Any, str]]] = None,
|
||||
timeout: Optional[int] = 20,
|
||||
**kwargs) -> httpx.Response:
|
||||
"""
|
||||
说明:
|
||||
httpx的post请求封装
|
||||
参数:
|
||||
:param url: url
|
||||
:param headers: 请求头
|
||||
:param params: params
|
||||
:param data: data
|
||||
:param json: json
|
||||
:param timeout: 超时时间
|
||||
"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
return await client.post(url,
|
||||
headers=headers,
|
||||
params=params,
|
||||
data=data,
|
||||
json=json,
|
||||
timeout=timeout,
|
||||
**kwargs)
|
||||
|
||||
|
||||
async def get_img(url: str,
|
||||
*,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
timeout: Optional[int] = 20,
|
||||
save_path: Optional[Union[str, Path]] = None,
|
||||
size: Optional[Tuple[int, int]] = None,
|
||||
mode: Optional[str] = None,
|
||||
to_b64: bool = False,
|
||||
**kwargs) -> Union[str, Image.Image]:
|
||||
"""
|
||||
说明:
|
||||
httpx的get请求封装,获取图片
|
||||
参数:
|
||||
:param url: url
|
||||
:param headers: 请求头
|
||||
:param params: params
|
||||
:param timeout: 超时时间
|
||||
:param save_path: 保存路径,为空则不保存
|
||||
:param size: 图片尺寸,为空则不做修改
|
||||
:param mode: 图片模式,为空则不做修改
|
||||
:param to_b64: 是否转b64
|
||||
"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(url,
|
||||
|
||||
headers=headers,
|
||||
params=params,
|
||||
timeout=timeout,
|
||||
**kwargs)
|
||||
if to_b64:
|
||||
return 'base64://' + base64.b64encode(resp.read()).decode()
|
||||
else:
|
||||
img = Image.open(BytesIO(resp.read()))
|
||||
if size:
|
||||
img = img.resize(size, Image.ANTIALIAS)
|
||||
if mode:
|
||||
img = img.convert(mode)
|
||||
if save_path:
|
||||
if isinstance(save_path, str):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
img.save(save_path)
|
||||
return img
|
@ -1,109 +1,18 @@
|
||||
import hashlib
|
||||
from collections import defaultdict
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
import random
|
||||
import base64
|
||||
import datetime
|
||||
from time import time
|
||||
import re
|
||||
import string
|
||||
import functools
|
||||
import inspect
|
||||
import hashlib
|
||||
import json
|
||||
import asyncio
|
||||
from json import JSONDecodeError
|
||||
from nonebot import get_bot
|
||||
import random
|
||||
import string
|
||||
from collections import defaultdict
|
||||
from time import time
|
||||
|
||||
from nonebot import logger
|
||||
from nonebot.exception import FinishedException
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
|
||||
from . import aiorequests
|
||||
from .db_util import get_cookie_cache, update_cookie_cache, delete_cookie_cache
|
||||
from .db_util import get_private_cookie, delete_cookie
|
||||
from .db_util import get_public_cookie, limit_public_cookie
|
||||
from .db_util import get_cookie_cache, update_cookie_cache, delete_cookie_cache
|
||||
from .db_util import get_last_query, update_last_query
|
||||
from .http_util import aiorequests
|
||||
|
||||
|
||||
def auto_withdraw(seconds: int = -1):
|
||||
def wrapper(func):
|
||||
|
||||
@functools.wraps(func)
|
||||
async def wrapped(**kwargs):
|
||||
try:
|
||||
message_id = await func(**kwargs)
|
||||
if message_id and seconds >= 1:
|
||||
await asyncio.sleep(seconds)
|
||||
await get_bot().delete_msg(message_id=message_id['message_id'])
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
return wrapped
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
# 缓存装饰器 ttl为过期时间 参数use_cache决定是否使用缓存,默认为True
|
||||
def cache(ttl=datetime.timedelta(hours=1), **kwargs):
|
||||
def wrap(func):
|
||||
cache_data = {}
|
||||
|
||||
@functools.wraps(func)
|
||||
async def wrapped(*args, **kw):
|
||||
nonlocal cache_data
|
||||
bound = inspect.signature(func).bind(*args, **kw)
|
||||
bound.apply_defaults()
|
||||
ins_key = '|'.join(['%s_%s' % (k, v) for k, v in bound.arguments.items()])
|
||||
default_data = {"time": None, "value": None}
|
||||
data = cache_data.get(ins_key, default_data)
|
||||
now = datetime.datetime.now()
|
||||
if 'use_cache' not in kw:
|
||||
kw['use_cache'] = True
|
||||
if not kw['use_cache'] or not data['time'] or now - data['time'] > ttl:
|
||||
try:
|
||||
data['value'] = await func(*args, **kw)
|
||||
data['time'] = now
|
||||
cache_data[ins_key] = data
|
||||
except Exception as e:
|
||||
raise e
|
||||
return data['value']
|
||||
|
||||
return wrapped
|
||||
|
||||
return wrap
|
||||
|
||||
|
||||
# 异常处理装饰器
|
||||
def exception_handler():
|
||||
def wrapper(func):
|
||||
|
||||
@functools.wraps(func)
|
||||
async def wrapped(**kwargs):
|
||||
event = kwargs['event']
|
||||
try:
|
||||
await func(**kwargs)
|
||||
except FinishedException:
|
||||
raise
|
||||
except ActionFailed:
|
||||
logger.exception('账号可能被风控,消息发送失败')
|
||||
await get_bot().send(event, f'派蒙可能被风控,也可能是没有该图片资源,消息发送失败')
|
||||
except JSONDecodeError:
|
||||
await get_bot().send(event, '派蒙获取信息失败,重试一下吧')
|
||||
# except IndexError or KeyError as e:
|
||||
# await get_bot().send(event, f'派蒙获取信息失败,请确认参数无误,{e}')
|
||||
# except TypeError or AttributeError as e:
|
||||
# await get_bot().send(event, f'派蒙好像没有该UID的绑定信息, {e}')
|
||||
except FileNotFoundError as e:
|
||||
file_name = re.search(r'\'(.*)\'', str(e)).group(1)
|
||||
file_name = file_name.replace('\\\\', '/').split('/')
|
||||
file_name = file_name[-2] + '\\' + file_name[-1]
|
||||
await get_bot().send(event, f"派蒙缺少{file_name}资源,请联系开发者补充")
|
||||
except Exception as e:
|
||||
await get_bot().send(event, f'派蒙好像出了点问题,{e}')
|
||||
|
||||
return wrapped
|
||||
|
||||
return wrapper
|
||||
from .message_util import send_cookie_delete_msg
|
||||
|
||||
|
||||
# 冷却时间限制器
|
||||
@ -138,19 +47,6 @@ class FreqLimiter2:
|
||||
return int(self.next_time[key1][key2] - time()) + 1
|
||||
|
||||
|
||||
# # 从网络url中获取图片
|
||||
# async def get_pic(url: str, size: tuple = None, mode: str = None):
|
||||
# async with ClientSession() as session:
|
||||
# res = await session.get(url)
|
||||
# res = await res.read()
|
||||
# img = Image.open(BytesIO(res))
|
||||
# if size:
|
||||
# img = img.resize(size)
|
||||
# if mode:
|
||||
# img = img.convert(mode)
|
||||
# return img
|
||||
|
||||
|
||||
# 获取可用的cookie
|
||||
async def get_use_cookie(user_id, uid='', mys_id='', action=''):
|
||||
cache_cookie = await get_cookie_cache(uid, 'uid')
|
||||
@ -222,44 +118,6 @@ async def check_retcode(data, cookie, uid):
|
||||
return True
|
||||
|
||||
|
||||
# 图片转b64,q为质量(压缩比例)
|
||||
def pil2b64(data, q=85):
|
||||
bio = BytesIO()
|
||||
data = data.convert("RGB")
|
||||
data.save(bio, format='JPEG', quality=q)
|
||||
base64_str = base64.b64encode(bio.getvalue()).decode()
|
||||
return 'base64://' + base64_str
|
||||
|
||||
|
||||
# 获取message中的艾特对象
|
||||
async def get_at_target(msg):
|
||||
for msg_seg in msg:
|
||||
if msg_seg.type == "at":
|
||||
return msg_seg.data['qq']
|
||||
return None
|
||||
|
||||
|
||||
# message预处理,获取uid、干净的msg、user_id、是否缓存
|
||||
async def get_uid_in_msg(event: MessageEvent, msg: Message):
|
||||
msg = str(msg).strip()
|
||||
if not msg:
|
||||
uid = await get_last_query(str(event.user_id))
|
||||
return uid, '', str(event.user_id), True
|
||||
user_id = await get_at_target(event.message) or str(event.user_id)
|
||||
msg = re.sub(r'\[CQ.*?\]', '', msg)
|
||||
use_cache = False if '-r' in msg else True
|
||||
msg = msg.replace('-r', '').strip()
|
||||
find_uid = r'(?P<uid>(1|2|5)\d{8})'
|
||||
for msg_seg in event.message:
|
||||
if msg_seg.type == 'text':
|
||||
match = re.search(find_uid, msg_seg.data['text'])
|
||||
if match:
|
||||
await update_last_query(user_id, match.group('uid'), 'uid')
|
||||
return match.group('uid'), msg.replace(match.group('uid'), '').strip(), user_id, use_cache
|
||||
uid = await get_last_query(user_id)
|
||||
return uid, msg.strip(), user_id, use_cache
|
||||
|
||||
|
||||
# md5加密
|
||||
def md5(text: str) -> str:
|
||||
md5 = hashlib.md5()
|
||||
@ -348,43 +206,5 @@ async def check_cookie(cookie):
|
||||
return True
|
||||
|
||||
|
||||
# 向超级用户私聊发送cookie删除信息
|
||||
async def send_cookie_delete_msg(cookie_info):
|
||||
msg = ''
|
||||
if cookie_info['type'] == 'public':
|
||||
msg = f'公共池的{cookie_info["no"]}号cookie已失效'
|
||||
elif cookie_info['type'] == 'private':
|
||||
if cookie_info['uid']:
|
||||
msg = f'用户{cookie_info["user_id"]}的uid{cookie_info["uid"]}的cookie已失效'
|
||||
elif cookie_info['mys_id']:
|
||||
msg = f'用户{cookie_info["user_id"]}的mys_id{cookie_info["mys_id"]}的cookie已失效'
|
||||
if msg:
|
||||
logger.info(f'---{msg}---')
|
||||
for superuser in get_bot().config.superusers:
|
||||
try:
|
||||
await get_bot().send_private_msg(user_id=superuser, message=msg + ',派蒙帮你删除啦!')
|
||||
except Exception as e:
|
||||
logger.error(f'发送cookie删除消息失败: {e}')
|
||||
|
||||
|
||||
def load_data(data_file):
|
||||
data_path = Path() / 'data' / 'LittlePaimon' / data_file
|
||||
if not data_path.exists():
|
||||
save_data({}, data_file)
|
||||
return json.load(data_path.open('r', encoding='utf-8'))
|
||||
|
||||
|
||||
def save_data(data, data_file):
|
||||
data_path = Path() / 'data' / 'LittlePaimon' / data_file
|
||||
data_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
json.dump(data, data_path.open('w', encoding='utf-8'), ensure_ascii=False, indent=2)
|
||||
|
||||
|
||||
def get_id(event):
|
||||
if event.message_type == 'private':
|
||||
return event.user_id
|
||||
elif event.message_type == 'group':
|
||||
return event.group_id
|
||||
elif event.message_type == 'guild':
|
||||
return event.channel_id
|
||||
|
91
utils/decorator.py
Normal file
91
utils/decorator.py
Normal file
@ -0,0 +1,91 @@
|
||||
import asyncio
|
||||
import functools
|
||||
import datetime
|
||||
import inspect
|
||||
import re
|
||||
from json import JSONDecodeError
|
||||
|
||||
from nonebot import get_bot, logger
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
from nonebot.exception import FinishedException
|
||||
|
||||
|
||||
def auto_withdraw(seconds: int = -1):
|
||||
def wrapper(func):
|
||||
|
||||
@functools.wraps(func)
|
||||
async def wrapped(**kwargs):
|
||||
try:
|
||||
message_id = await func(**kwargs)
|
||||
if message_id and seconds >= 1:
|
||||
await asyncio.sleep(seconds)
|
||||
await get_bot().delete_msg(message_id=message_id['message_id'])
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
return wrapped
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
# 缓存装饰器 ttl为过期时间 参数use_cache决定是否使用缓存,默认为True
|
||||
def cache(ttl=datetime.timedelta(hours=1)):
|
||||
def wrap(func):
|
||||
cache_data = {}
|
||||
|
||||
@functools.wraps(func)
|
||||
async def wrapped(*args, **kw):
|
||||
nonlocal cache_data
|
||||
bound = inspect.signature(func).bind(*args, **kw)
|
||||
bound.apply_defaults()
|
||||
ins_key = '|'.join(['%s_%s' % (k, v) for k, v in bound.arguments.items()])
|
||||
default_data = {"time": None, "value": None}
|
||||
data = cache_data.get(ins_key, default_data)
|
||||
now = datetime.datetime.now()
|
||||
if 'use_cache' not in kw:
|
||||
kw['use_cache'] = True
|
||||
if not kw['use_cache'] or not data['time'] or now - data['time'] > ttl:
|
||||
try:
|
||||
data['value'] = await func(*args, **kw)
|
||||
data['time'] = now
|
||||
cache_data[ins_key] = data
|
||||
except Exception as e:
|
||||
raise e
|
||||
return data['value']
|
||||
|
||||
return wrapped
|
||||
|
||||
return wrap
|
||||
|
||||
|
||||
# 异常处理装饰器
|
||||
def exception_handler():
|
||||
def wrapper(func):
|
||||
|
||||
@functools.wraps(func)
|
||||
async def wrapped(**kwargs):
|
||||
event = kwargs['event']
|
||||
try:
|
||||
await func(**kwargs)
|
||||
except FinishedException:
|
||||
raise
|
||||
except ActionFailed:
|
||||
logger.exception('账号可能被风控,消息发送失败')
|
||||
await get_bot().send(event, f'派蒙可能被风控,也可能是没有该图片资源,消息发送失败')
|
||||
except JSONDecodeError:
|
||||
await get_bot().send(event, '派蒙获取信息失败,重试一下吧')
|
||||
# except IndexError or KeyError as e:
|
||||
# await get_bot().send(event, f'派蒙获取信息失败,请确认参数无误,{e}')
|
||||
# except TypeError or AttributeError as e:
|
||||
# await get_bot().send(event, f'派蒙好像没有该UID的绑定信息, {e}')
|
||||
except FileNotFoundError as e:
|
||||
file_name = re.search(r'\'(.*)\'', str(e)).group(1)
|
||||
file_name = file_name.replace('\\\\', '/').split('/')
|
||||
file_name = file_name[-2] + '\\' + file_name[-1]
|
||||
await get_bot().send(event, f"派蒙缺少{file_name}资源,请联系开发者补充")
|
||||
except Exception as e:
|
||||
await get_bot().send(event, f'派蒙好像出了点问题,{e}')
|
||||
|
||||
return wrapped
|
||||
|
||||
return wrapper
|
41
utils/file_handler.py
Normal file
41
utils/file_handler.py
Normal file
@ -0,0 +1,41 @@
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
from typing import Union, Optional, Tuple
|
||||
import json
|
||||
|
||||
|
||||
def load_image(
|
||||
path: Union[Path, str],
|
||||
*,
|
||||
size: Optional[Union[Tuple[int, int], float]] = None,
|
||||
mode: Optional[str] = 'RGB'
|
||||
):
|
||||
img = Image.open(path)
|
||||
if size:
|
||||
if isinstance(size, float):
|
||||
img = img.resize((int(img.size[0] * size), int(img.size[1] * size)), Image.ANTIALIAS)
|
||||
elif isinstance(size, tuple):
|
||||
img = img.resize(size, Image.ANTIALIAS)
|
||||
img = img.convert(mode)
|
||||
return img
|
||||
|
||||
|
||||
def load_json(file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8'):
|
||||
if file and not path:
|
||||
path = Path() / 'data' / 'LittlePaimon' / file
|
||||
elif path:
|
||||
if isinstance(path, str):
|
||||
path = Path(path)
|
||||
if not path.exists():
|
||||
save_json({}, file, path, encoding)
|
||||
return json.load(path.open('r', encoding=encoding))
|
||||
|
||||
|
||||
def save_json(data, file: str = None, path: Union[Path, str] = None, encoding: str = 'utf-8'):
|
||||
if file and not path:
|
||||
path = Path() / 'data' / 'LittlePaimon' / file
|
||||
elif path:
|
||||
if isinstance(path, str):
|
||||
path = Path(path)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
json.dump(data, path.open('w', encoding=encoding), ensure_ascii=False, indent=4)
|
@ -1,77 +0,0 @@
|
||||
import base64
|
||||
from typing import Dict, Optional, Any, Union, Tuple
|
||||
from pathlib import Path
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
import httpx
|
||||
|
||||
|
||||
class aiorequests:
|
||||
|
||||
@classmethod
|
||||
async def get(cls,
|
||||
url: str,
|
||||
*,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
timeout: Optional[int] = 20,
|
||||
**kwargs) -> httpx.Response:
|
||||
async with httpx.AsyncClient() as client:
|
||||
return await client.get(url,
|
||||
headers=headers,
|
||||
params=params,
|
||||
timeout=timeout,
|
||||
**kwargs)
|
||||
|
||||
@classmethod
|
||||
async def post(cls,
|
||||
url: str,
|
||||
*,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
data: Optional[Dict[str, Any]] = None,
|
||||
json: Optional[Dict[str, Union[Any, str]]] = None,
|
||||
timeout: Optional[int] = 20,
|
||||
**kwargs) -> httpx.Response:
|
||||
async with httpx.AsyncClient() as client:
|
||||
return await client.post(url,
|
||||
headers=headers,
|
||||
params=params,
|
||||
data=data,
|
||||
json=json,
|
||||
timeout=timeout,
|
||||
**kwargs)
|
||||
|
||||
@classmethod
|
||||
async def get_img(cls,
|
||||
url: str,
|
||||
*,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
timeout: Optional[int] = 20,
|
||||
save_path: Optional[Union[str, Path]] = None,
|
||||
size: Optional[Tuple[int, int]] = None,
|
||||
mode: Optional[str] = None,
|
||||
to_b64: bool = False,
|
||||
**kwargs) -> Union[str, Image.Image]:
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(url,
|
||||
|
||||
headers=headers,
|
||||
params=params,
|
||||
timeout=timeout,
|
||||
**kwargs)
|
||||
if to_b64:
|
||||
return 'base64://' + base64.b64encode(resp.read()).decode()
|
||||
else:
|
||||
img = Image.open(BytesIO(resp.read()))
|
||||
if size:
|
||||
img = img.resize(size, Image.ANTIALIAS)
|
||||
if mode:
|
||||
img = img.convert(mode)
|
||||
if save_path:
|
||||
if isinstance(save_path, str):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
img.save(save_path)
|
||||
return img
|
99
utils/message_util.py
Normal file
99
utils/message_util.py
Normal file
@ -0,0 +1,99 @@
|
||||
# 获取message中的艾特对象
|
||||
import re
|
||||
import base64
|
||||
|
||||
from PIL import Image
|
||||
from pathlib import Path
|
||||
from typing import Union, Optional, Tuple
|
||||
from io import BytesIO
|
||||
|
||||
from nonebot import get_bot, logger
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment
|
||||
|
||||
from .db_util import get_last_query, update_last_query
|
||||
from .file_handler import load_image
|
||||
|
||||
|
||||
class MessageBuild:
|
||||
|
||||
@classmethod
|
||||
def Image(cls,
|
||||
img: Union[Image.Image, Path, str],
|
||||
*,
|
||||
size: Optional[Union[Tuple[int, int], float]] = None,
|
||||
quality: Optional[int] = 100,
|
||||
mode: Optional[str] = 'RGB'
|
||||
) -> MessageSegment:
|
||||
if isinstance(img, str) or isinstance(img, Path):
|
||||
img = load_image(path=img, size=size, mode=mode)
|
||||
bio = BytesIO()
|
||||
img = img.convert(mode)
|
||||
img.save(bio, format='JPEG' if mode == 'RGB' else 'PNG', quality=quality)
|
||||
img_b64 = 'base64://' + base64.b64encode(bio.getvalue()).decode()
|
||||
return MessageSegment.image(img_b64)
|
||||
|
||||
@classmethod
|
||||
def Text(cls, text: str) -> MessageSegment:
|
||||
# TODO 过滤负面文本
|
||||
return MessageSegment.text(text)
|
||||
|
||||
@classmethod
|
||||
def Record(cls, path: str) -> MessageSegment:
|
||||
# TODO 网络语音
|
||||
return MessageSegment.record(path)
|
||||
|
||||
|
||||
async def get_at_target(msg):
|
||||
for msg_seg in msg:
|
||||
if msg_seg.type == "at":
|
||||
return msg_seg.data['qq']
|
||||
return None
|
||||
|
||||
|
||||
# message预处理,获取uid、干净的msg、user_id、是否缓存
|
||||
async def get_uid_in_msg(event: MessageEvent, msg: Message):
|
||||
msg = str(msg).strip()
|
||||
if not msg:
|
||||
uid = await get_last_query(str(event.user_id))
|
||||
return uid, '', str(event.user_id), True
|
||||
user_id = await get_at_target(event.message) or str(event.user_id)
|
||||
msg = re.sub(r'\[CQ.*?\]', '', msg)
|
||||
use_cache = False if '-r' in msg else True
|
||||
msg = msg.replace('-r', '').strip()
|
||||
find_uid = r'(?P<uid>(1|2|5)\d{8})'
|
||||
for msg_seg in event.message:
|
||||
if msg_seg.type == 'text':
|
||||
match = re.search(find_uid, msg_seg.data['text'])
|
||||
if match:
|
||||
await update_last_query(user_id, match.group('uid'), 'uid')
|
||||
return match.group('uid'), msg.replace(match.group('uid'), '').strip(), user_id, use_cache
|
||||
uid = await get_last_query(user_id)
|
||||
return uid, msg.strip(), user_id, use_cache
|
||||
|
||||
|
||||
# 向超级用户私聊发送cookie删除信息
|
||||
async def send_cookie_delete_msg(cookie_info):
|
||||
msg = ''
|
||||
if cookie_info['type'] == 'public':
|
||||
msg = f'公共池的{cookie_info["no"]}号cookie已失效'
|
||||
elif cookie_info['type'] == 'private':
|
||||
if cookie_info['uid']:
|
||||
msg = f'用户{cookie_info["user_id"]}的uid{cookie_info["uid"]}的cookie已失效'
|
||||
elif cookie_info['mys_id']:
|
||||
msg = f'用户{cookie_info["user_id"]}的mys_id{cookie_info["mys_id"]}的cookie已失效'
|
||||
if msg:
|
||||
logger.info(f'---{msg}---')
|
||||
for superuser in get_bot().config.superusers:
|
||||
try:
|
||||
await get_bot().send_private_msg(user_id=superuser, message=msg + ',派蒙帮你删除啦!')
|
||||
except Exception as e:
|
||||
logger.error(f'发送cookie删除消息失败: {e}')
|
||||
|
||||
|
||||
def get_message_id(event):
|
||||
if event.message_type == 'private':
|
||||
return event.user_id
|
||||
elif event.message_type == 'group':
|
||||
return event.group_id
|
||||
elif event.message_type == 'guild':
|
||||
return event.channel_id
|
Loading…
x
Reference in New Issue
Block a user