diff --git a/plugins/genshin/daily/material.py b/plugins/genshin/daily/material.py index 25da0c56..b962e161 100644 --- a/plugins/genshin/daily/material.py +++ b/plugins/genshin/daily/material.py @@ -1,5 +1,4 @@ import asyncio -import itertools import re from asyncio import Lock from ctypes import c_double @@ -7,10 +6,11 @@ from datetime import datetime from multiprocessing import Value from pathlib import Path from ssl import SSLZeroReturnError -from typing import Any, Dict, Iterable, List, Literal, Optional, Tuple +from typing import Any, Dict, Iterable, Iterator, List, Literal, Optional, Tuple import ujson as json from aiofiles import open as async_open +from arkowrapper import ArkoWrapper from bs4 import BeautifulSoup from genshin import Client from httpx import AsyncClient, HTTPError @@ -31,7 +31,7 @@ from utils.bot import get_all_args from utils.decorators.admins import bot_admins_rights_check from utils.decorators.error import error_callable from utils.decorators.restricts import restricts -from utils.helpers import get_genshin_client, is_number +from utils.helpers import get_genshin_client from utils.log import logger DATA_TYPE = Dict[str, List[List[str]]] @@ -45,18 +45,44 @@ WEEK_MAP = ['一', '二', '三', '四', '五', '六', '日'] def sort_item(items: List['ItemData']) -> Iterable['ItemData']: """对武器和角色进行排序 - 角色排序规则:星级>等级>命座 - 武器排序规则:星级>等级>精炼度 + 排序规则:持有(星级 > 等级 > 命座/精炼) > 未持有(星级 > 等级 > 命座/精炼) """ - result_a = [] - for _, group_a in itertools.groupby(sorted(items, key=lambda x: x.rarity, reverse=True), lambda x: x.rarity): - result_b = [] - for _, group_b in itertools.groupby( - sorted(group_a, key=lambda x: x.level or -1, reverse=True), lambda x: x.level or -1 - ): - result_b.append(sorted(group_b, key=lambda x: x.constellation or x.refinement or -1, reverse=True)) - result_a.append(itertools.chain(*result_b)) - return itertools.chain(*result_a) + return ( + ArkoWrapper(items) + .sort(lambda x: x.level or -1, reverse=True) + .groupby(lambda x: x.level is None) # 根据持有与未持有进行分组并排序 + .map( + lambda x: ( + ArkoWrapper(x[1]) + .sort(lambda y: y.rarity, reverse=True) + .groupby(lambda y: y.rarity) # 根据星级分组并排序 + .map(lambda y: ( + ArkoWrapper(y[1]) + .sort(lambda z: z.refinement or z.constellation or -1, reverse=True) + .groupby(lambda z: z.refinement or z.constellation or -1) # 根据命座/精炼进行分组并排序 + .map(lambda i: ArkoWrapper(i[1]).sort(lambda j: j.id)) + )) + ) + ).flat(3) + ) + + +def get_material_serial_name(names: Iterable[str]) -> str: + """获取材料的系列名""" + + def all_substrings(string: str) -> Iterator[str]: + """获取字符串的所有连续字串""" + length = len(string) + for i in range(length): + for j in range(i + 1, length + 1): + yield string[i:j] + + result = [] + for name_a, name_b in ArkoWrapper(names).repeat(1).group(2).unique(list): + for sub_string in all_substrings(name_a): + if sub_string in ArkoWrapper(all_substrings(name_b)): + result.append(sub_string) + return ArkoWrapper(result).sort(len, reverse=True)[0].strip('的') class DailyMaterial(Plugin, BasePlugin): @@ -126,26 +152,19 @@ class DailyMaterial(Plugin, BasePlugin): args = get_all_args(context) now = datetime.now() - if args and is_number(args[0]): - # 适配出现 负数、小数、数字大于 7 、Nan 和 1e-10的状况 - try: - weekday = (_ := int(args[0])) - (_ > 0) - weekday = (weekday % 7 + 7) % 7 - time = title = f"星期{WEEK_MAP[weekday]}" - except ValueError: - title = "今日" - weekday = now.weekday() - (1 if now.hour < 4 else 0) - weekday = 6 if weekday < 0 else weekday - time = now.strftime("%m-%d %H:%M") + " 星期" + WEEK_MAP[weekday] - else: # 获取今日是星期几,判定了是否过了凌晨4点 + try: + weekday = (_ := int(args[0])) - (_ > 0) + weekday = (weekday % 7 + 7) % 7 + time = title = f"星期{WEEK_MAP[weekday]}" + except (ValueError, IndexError): title = "今日" weekday = now.weekday() - (1 if now.hour < 4 else 0) weekday = 6 if weekday < 0 else weekday time = now.strftime("%m-%d %H:%M") + " 星期" + WEEK_MAP[weekday] - full = args and args[-1] == 'full' # 判定最后一个参数是不是 full + full = bool(args and args[-1] == 'full') # 判定最后一个参数是不是 full logger.info( - f"用户 {user.full_name}[{user.id}] 每日素材命令请求 || 参数 weekday={WEEK_MAP[weekday]} full={full}") + f"用户 {user.full_name}[{user.id}] 每日素材命令请求 || 参数 weekday=\"{WEEK_MAP[weekday]}\" full={full}") if weekday == 6: await update.message.reply_text( @@ -193,7 +212,6 @@ class DailyMaterial(Plugin, BasePlugin): if i.rarity > 3: # 跳过 3 星及以下的武器 items.append(i) added = True - break if added: continue item = HONEY_ID_MAP[type_][id_] @@ -208,7 +226,10 @@ class DailyMaterial(Plugin, BasePlugin): path = (await self.assets_service.material(mid).icon()).as_uri() material = HONEY_ID_MAP['material'][mid] materials.append(ItemData(id=mid, icon=path, name=material[0], rarity=material[1])) - areas.append(AreaData(name=area_data['name'], materials=materials, items=sort_item(items))) + areas.append(AreaData( + name=area_data['name'], materials=materials, items=sort_item(items), + material_name=get_material_serial_name(map(lambda x: x.name, materials)) + )) setattr(render_data, type_, areas) await update.message.reply_chat_action(ChatAction.TYPING) @@ -363,6 +384,7 @@ class ItemData(BaseModel): class AreaData(BaseModel): name: Literal['蒙德', '璃月', '稻妻', '须弥'] # 区域名 + material_name: str # 区域的材料系列名 materials: List[ItemData] = [] # 区域材料 items: Iterable[ItemData] = [] # 可培养的角色或武器 diff --git a/poetry.lock b/poetry.lock index 58a26d11..dabb0632 100644 --- a/poetry.lock +++ b/poetry.lock @@ -117,6 +117,20 @@ tornado = ["tornado (>=4.3)"] twisted = ["twisted"] zookeeper = ["kazoo"] +[[package]] +name = "arko-wrapper" +version = "0.2.3" +description = "给你的Python迭代器加上魔法" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +typing-extensions = "*" + +[package.extras] +test = ["pytest", "pytest-rerunfailures"] + [[package]] name = "async-timeout" version = "4.0.2" @@ -1093,7 +1107,7 @@ test = ["pytest", "pytest-asyncio", "flaky"] [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "ced17568ebbf432d28ae730835330b86fed0b7d210feb0d720e149c9ff1f3c18" +content-hash = "f81ae57fa3826c77165605e7c30d9064e29f957825d5858ed6094df4f506e7a8" [metadata.files] aiofiles = [ @@ -1198,6 +1212,10 @@ APScheduler = [ {file = "APScheduler-3.9.1-py2.py3-none-any.whl", hash = "sha256:ddc25a0ddd899de44d7f451f4375fb971887e65af51e41e5dcf681f59b8b2c9a"}, {file = "APScheduler-3.9.1.tar.gz", hash = "sha256:65e6574b6395498d371d045f2a8a7e4f7d50c6ad21ef7313d15b1c7cf20df1e3"}, ] +arko-wrapper = [ + {file = "arko-wrapper-0.2.3.tar.gz", hash = "sha256:61927ac03c39c48d2514705b9af3642df30a200a7dd09e010131ebfe29774044"}, + {file = "arko_wrapper-0.2.3-py3-none-any.whl", hash = "sha256:25f41c22b265324db44508ec8b1875bafd7193b667d5e64164d8fa638301b8a5"}, +] async-timeout = [ {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, @@ -1692,8 +1710,8 @@ Pillow = [ {file = "Pillow-9.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e"}, {file = "Pillow-9.2.0-cp310-cp310-win32.whl", hash = "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28"}, {file = "Pillow-9.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d"}, - {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc"}, - {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9"}, {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004"}, {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0"}, {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4"}, diff --git a/pyproject.toml b/pyproject.toml index e062af93..9e8d92bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ pytest = { version = "^7.1.3", optional = true } pytest-asyncio = { version = "^0.19.0", optional = true } flaky = { version = "^3.7.0", optional = true } lxml = "^4.9.1" +arko-wrapper = "^0.2.3" [tool.poetry.extras] pyro = ["Pyrogram", "TgCrypto"] diff --git a/resources/genshin/daily_material/character.html b/resources/genshin/daily_material/character.html index 2242f0d6..f59a9219 100644 --- a/resources/genshin/daily_material/character.html +++ b/resources/genshin/daily_material/character.html @@ -22,8 +22,11 @@ {% for area in data.character %}
- {{ area.name }} - {{ area.name }} + + {{ area.name }} +
{{ area.name }}
+
+ {{ area.material_name }} {% for material in area.materials %}
@@ -42,7 +45,11 @@
{% for item in area.items %} -
+
{% if item.level != none %} diff --git a/resources/genshin/daily_material/example.html b/resources/genshin/daily_material/example.html index 30793592..c0083a98 100644 --- a/resources/genshin/daily_material/example.html +++ b/resources/genshin/daily_material/example.html @@ -18,42 +18,47 @@
角色培养素材
- 蒙德 - 蒙德 + + 蒙德 +
蒙德
+
+ + 自由 + -
-
- -
-
- star - star -
+
+
+
-
-
- -
-
- star - star - star -
+
+ star + star
-
-
- -
-
- star - star - star - star -
+
+
+
+
-
+
+ star + star + star +
+
+
+
+ +
+
+ star + star + star + star +
+
+
- +
star @@ -66,7 +71,7 @@
-
+
Lv.90
6命
@@ -125,33 +130,47 @@
- 蒙德 - 蒙德 + + 蒙德 +
蒙德
+
+ + 自由 + -
-
- -
-
- star - star - star -
+
+
+
-
-
- -
-
- star - star - star - star -
+
+ star + star
-
+
+
+
+ +
+
+ star + star + star +
+
+
+
+ +
+
+ star + star + star + star +
+
+
- +
star @@ -164,6 +183,16 @@
+
+
+
Lv.90
+
6命
+ 神里绫华 +
+
+
神里绫华
+
+
Lv.90
@@ -184,6 +213,31 @@
神里绫华
+
+
+
Lv.90
+ 神里绫华 +
+
+
神里绫华
+
+
+
+
+ 神里绫华 +
+
+
神里绫华
+
+
+
+
+ 神里绫华 +
+
+
神里绫华
+
+
@@ -192,42 +246,47 @@
武器培养素材
- 蒙德 - 蒙德 + + 稻妻 +
稻妻
+
+ + 雾海云间 + -
-
- -
-
- star - star -
+
+
+
-
-
- -
-
- star - star - star -
+
+ star + star
-
-
- -
-
- star - star - star - star -
+
+
+
+
-
+
+ star + star + star +
+
+
+
+ +
+
+ star + star + star + star +
+
+
- +
star diff --git a/resources/genshin/daily_material/style.css b/resources/genshin/daily_material/style.css index 1accaed7..ab5662ec 100644 --- a/resources/genshin/daily_material/style.css +++ b/resources/genshin/daily_material/style.css @@ -69,23 +69,16 @@ body { .area { width: calc(100% - 20px); padding: 0 10px; + margin: 40px 0; } .area-head { - background-image: url("bg/title/01.png"); - background-size: contain; width: calc(100% - 20px); height: 80px; - filter: drop-shadow(5px 5px 5px var(--shadow)); position: relative; padding-left: 15px; } -.area-head > img { - height: inherit; - filter: drop-shadow(3px 3px 5px black); -} - .area-head > span { font-size: 23px; position: absolute; @@ -93,6 +86,46 @@ body { transform: translateY(-50%); } +.area-name { + background-image: url("bg/title/01.png"); + background-size: contain; + height: inherit; + width: 356px; + filter: drop-shadow(3px 3px 5px rgba(0, 0, 0, 0.8)); +} + +.area-name > img { + height: inherit; + filter: drop-shadow(3px 3px 5px black); + position: relative; + left: 5px; +} + +.area-name > div { + position: absolute; + top: 50%; + left: 88px; + transform: translateY(-50%); + font-size: 28px; +} + +.material-name { + top: 0 !important; + right: 269px; + z-index: 2; + padding: 2px 20px; + min-width: 100px; + min-height: 40px; + border-radius: 20px 5px 20px 20px; + background-color: rgb(246 222 169 / 50%); + backdrop-filter: blur(5px); + display: flex; + justify-content: center; + align-items: center; + box-shadow: 3px 3px 5px rgb(0 0 0 / 50%); + font-size: 24px !important; +} + .materials { width: 335px; height: inherit; @@ -105,6 +138,26 @@ body { position: relative; top: 50%; transform: translateY(-50%); + filter: drop-shadow(3px 3px 5px rgba(0, 0, 0, 0.8)); +} + +.materials > div:not(.material) { + position: absolute; + width: 100px; + height: 35px; + background: rgb(246 222 169 / 80%); + left: -35px; + top: -15px; + z-index: 2; + box-shadow: 1px 1px 10px rgb(0 0 0 / 20%); + border-radius: 20px 5px 20px 20px; + backdrop-filter: blur(10px); + text-align: center; + display: flex; + justify-content: center; + align-items: center; + font-size: 20px; + color: rgb(255 255 255); } .material { diff --git a/resources/genshin/daily_material/weapon.html b/resources/genshin/daily_material/weapon.html index 4d64e9b4..25049b75 100644 --- a/resources/genshin/daily_material/weapon.html +++ b/resources/genshin/daily_material/weapon.html @@ -22,8 +22,11 @@ {% for area in data.weapon %}
- {{ area.name }} - {{ area.name }} + + {{ area.name }} +
{{ area.name }}
+
+ {{ area.material_name }} {% for material in area.materials %}
@@ -42,7 +45,11 @@
{% for item in area.items %} -
+
= 81) %} + style="filter: grayscale(80%);" + {% endif %} + > {% if item.c_path != none %}
@@ -58,9 +65,10 @@
精炼5
- {% else %} + {% elif item.refinement != 1 %}
- 精炼{{ item.refinement }}
+ 精炼{{ item.refinement }} +
{% endif %} {% endif %} {{ item.name }} diff --git a/utils/helpers.py b/utils/helpers.py index 6b022a04..404f0291 100644 --- a/utils/helpers.py +++ b/utils/helpers.py @@ -1,9 +1,7 @@ -import asyncio import hashlib import os -from multiprocessing import RLock from pathlib import Path -from typing import Optional, Tuple, Union, cast +from typing import Iterator, Optional, Tuple, Union, cast import aiofiles import genshin @@ -150,19 +148,3 @@ def mkdir(path: Path) -> Path: path_list.pop().mkdir(exist_ok=True) return path - - -def is_number(target: str) -> bool: - """判断字符串是否是数字""" - try: # 尝试将字符串转为浮点数 - float(target) - return True - except ValueError: - pass - try: - import unicodedata # 处理ASCii码的包 - unicodedata.numeric(target) # 把一个表示数字的字符串转换为浮点数返回的函数 - return True - except (TypeError, ValueError): - pass - return False