diff --git a/config/config.json.example b/config/config.json.example index 43fdc873..194dcca0 100644 --- a/config/config.json.example +++ b/config/config.json.example @@ -13,17 +13,28 @@ }, "telegram": { "token": "", + "notice": { + "INFO": { + "name": "", + "char_id": + }, + "ERROR": { + "name": "", + "char_id": + } + }, + "channel": { + "POST": { + "name": "", + "char_id": + } + } + } "administrators": [ { "username": "", - "userid": , - "type": 0 - }, - { - "username": "", - "userid": , - "type": 1 + "userid": } ] } diff --git a/main.py b/main.py index b0d84331..4467a993 100644 --- a/main.py +++ b/main.py @@ -10,6 +10,7 @@ from plugins.gacha import Gacha from plugins.get_user import GetUser from plugins.inline import Inline from plugins.job_queue import JobQueue +from plugins.post import Post from plugins.quiz import Quiz from plugins.sign import Sign from plugins.start import start, help_command, emergency_food, ping, reply_keyboard_remove @@ -35,7 +36,7 @@ def main() -> None: application.add_handler(CommandHandler("ping", ping, block=False)) # application.add_handler(MessageHandler(filters.StatusUpdate.NEW_CHAT_MEMBERS, new_chat_members)) auth = Auth(service) - new_chat_members_handler = NewChatMembersHandler(service,auth.new_mem) + new_chat_members_handler = NewChatMembersHandler(service, auth.new_mem) application.add_handler(MessageHandler(filters.StatusUpdate.NEW_CHAT_MEMBERS, new_chat_members_handler.new_member, block=False)) application.add_handler(CallbackQueryHandler(auth.query, pattern=r"^auth_challenge\|", block=False)) @@ -97,6 +98,15 @@ def main() -> None: }, fallbacks=[CommandHandler('cancel', quiz.cancel, block=False)] ) + _post = Post(service) + post_handler = ConversationHandler( + entry_points=[CommandHandler('post', _post.command_start, block=False)], + states={ + _post.CHECK_POST: [MessageHandler(filters.TEXT & ~filters.COMMAND, _post.check_post, block=False)], + _post.SEND_POST: [MessageHandler(filters.TEXT & ~filters.COMMAND, _post.send_post, block=False)], + }, + fallbacks=[CommandHandler('cancel', _post.cancel, block=False)] + ) gacha = Gacha(service) application.add_handler(CommandHandler("gacha", gacha.command_start, block=False)) admin = Admin(service) @@ -109,6 +119,7 @@ def main() -> None: application.add_handler(quiz_handler) application.add_handler(cookies_handler) application.add_handler(get_user_handler) + application.add_handler(post_handler) inline = Inline(service) application.add_handler(InlineQueryHandler(inline.inline_query, block=False)) job_queue = JobQueue(service) diff --git a/model/genshinhelper/mihoyo.py b/model/genshinhelper/mihoyo.py index 69f9f1b7..de1b362e 100644 --- a/model/genshinhelper/mihoyo.py +++ b/model/genshinhelper/mihoyo.py @@ -1,4 +1,5 @@ import asyncio +import re from typing import List import httpx from httpx import AsyncClient @@ -9,14 +10,30 @@ from .helpers import get_ds, get_device_id class Mihoyo: POST_FULL_URL = "https://bbs-api.mihoyo.com/post/wapi/getPostFull" POST_FULL_IN_COLLECTION_URL = "https://bbs-api.mihoyo.com/post/wapi/getPostFullInCollection" + GET_NEW_LIST_URL = "https://bbs-api.mihoyo.com/post/wapi/getNewsList" USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " \ "Chrome/90.0.4430.72 Safari/537.36" def __init__(self): self.client = httpx.AsyncClient(headers=self.get_headers()) - def get_info_url(self, post_id: int) -> str: - return f"{self.POST_FULL_URL}?gids=2&post_id={post_id}&read=1" + @staticmethod + def extract_post_id(text: str) -> int: + """ + :param text: + # https://bbs.mihoyo.com/ys/article/8808224 + # https://m.bbs.mihoyo.com/ys/article/8808224 + :return: post_id + """ + rgx = re.compile(r"(?:bbs\.)?mihoyo\.com/[^.]+/article/(\d+)") + args = rgx.split(text) + if args is None: + return -1 + try: + art_id = int(args[1]) + except (IndexError, ValueError): + return -1 + return art_id def get_headers(self, referer: str = "https://bbs.mihoyo.com/"): return { @@ -65,16 +82,31 @@ class Mihoyo: return BaseResponseData(error_message="请求错误") return BaseResponseData(response.json()) - async def get_artwork_info(self, post_id: int) -> MiHoYoBBSResponse: - url = self.get_info_url(post_id) - headers = self.get_headers() - response = await self.client.get(url=url, headers=headers) + async def get_artwork_info(self, gids: int, post_id: int, read: int = 1) -> MiHoYoBBSResponse: + params = { + "gids": gids, + "post_id": post_id, + "read": read + } + response = await self.client.get(self.POST_FULL_URL, params=params) if response.is_error: return MiHoYoBBSResponse(error_message="请求错误") return MiHoYoBBSResponse(response.json()) - async def get_images_by_post_id(self, post_id: int) -> List[ArtworkImage]: - artwork_info = await self.get_artwork_info(post_id) + async def get_post_full_info(self, gids: int, post_id: int, read: int = 1) -> BaseResponseData: + params = { + "gids": gids, + "post_id": post_id, + "read": read + } + response = await self.client.get(self.POST_FULL_URL, params=params) + if response.is_error: + return BaseResponseData(error_message="请求错误") + return BaseResponseData(response.json()) + + + async def get_images_by_post_id(self, gids: int, post_id: int) -> List[ArtworkImage]: + artwork_info = await self.get_artwork_info(gids, post_id) if artwork_info.error: return [] urls = artwork_info.results.image_url_list @@ -99,6 +131,21 @@ class Mihoyo: return ArtworkImage(art_id, page, True) return ArtworkImage(art_id, page, data=response.content) + async def get_new_list(self, gids: int, type_id: int, page_size: int = 20): + """ + ?gids=2&page_size=20&type=3 + :return: + """ + params = { + "gids": gids, + "page_size": page_size, + "type": type_id + } + response = await self.client.get(url=self.GET_NEW_LIST_URL, params=params) + if response.is_error: + return BaseResponseData(error_message="请求错误") + return BaseResponseData(response.json()) + async def close(self): await self.client.aclose() diff --git a/plugins/job_queue.py b/plugins/job_queue.py index c394d2d5..e6118572 100644 --- a/plugins/job_queue.py +++ b/plugins/job_queue.py @@ -1,6 +1,10 @@ +import asyncio +from typing import List + from telegram.ext import CallbackContext from logger import Log +from model.genshinhelper import Mihoyo from plugins.base import BasePlugins from service import BaseService @@ -9,6 +13,8 @@ class JobQueue(BasePlugins): def __init__(self, service: BaseService): super().__init__(service) + self.mihoyo = Mihoyo() + self.new_post_id_list_cache: List[int] = [] async def start_job(self, _: CallbackContext) -> None: Log.info("初始Job启动成功,正在初始化必要任务") @@ -16,9 +22,27 @@ class JobQueue(BasePlugins): try: await self.service.template.get_browser() except TimeoutError as err: - Log.error("初始化浏览器超时,请检查日记查看错误", err) + Log.error("初始化浏览器超时,请检查日记查看错误 \n", err) except AttributeError as err: - Log.error("初始化浏览器时变量为空,请检查日记查看错误", err) + Log.error("初始化浏览器时变量为空,请检查日记查看错误 \n", err) else: Log.info("初始化浏览器成功") Log.info("初始化Job成功") + + async def post_job(self, _: CallbackContext) -> None: + while True: + new_post_id_list_cache: List[int] = [] + new_list = await self.mihoyo.get_new_list(2, 2) + if new_list.code == 0: + for post in new_list.data["list"]: + post_id = post["post"]["post_id"] + new_post_id_list_cache.append(post_id) + new_list = await self.mihoyo.get_new_list(2, 3) + if new_list.code == 0: + for post in new_list.data["list"]: + post_id = post["post"]["post_id"] + new_post_id_list_cache.append(post_id) + if len(self.new_post_id_list_cache) == 0: + return + + await asyncio.sleep(60) diff --git a/requirements.txt b/requirements.txt index a43d9f3b..3f9d4b28 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,5 @@ asyncio>=3.4.3 Jinja2>=3.1.1 aiofiles>=0.8.0 playwright>=1.20.1 -PyMySQL>=0.9.3 \ No newline at end of file +PyMySQL>=0.9.3 +beautifulsoup4>=4.11.1 \ No newline at end of file diff --git a/service/game.py b/service/game.py index d0ab8c5a..a0c29daf 100644 --- a/service/game.py +++ b/service/game.py @@ -37,6 +37,6 @@ class GetGameInfo: if post_id == -1: await self.cache.set_str_list(qname, [""], 3600) return "" - artwork_info = await self.mihoyo.get_artwork_info(post_id) + artwork_info = await self.mihoyo.get_artwork_info(2, post_id) await self.cache.set_str_list(qname, artwork_info.results.image_url_list, 3600) return artwork_info.results.image_url_list[0]