From 6a23509ae3c15820e975990943b7763c1aa48395 Mon Sep 17 00:00:00 2001 From: xtaodada Date: Fri, 18 Aug 2023 21:28:16 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=94=AF=E6=8C=81=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E6=94=B6=E8=97=8F=E5=A4=B9=E5=88=B0=E9=A2=91=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.gen.ini | 7 +- defs/bilibili_download.py | 31 ++++++--- defs/bilibili_fav.py | 104 ++++++++++++++++++++++++++++++ defs/fragment.py | 2 +- defs/glover.py | 12 ++++ defs/lofter.py | 2 +- defs/post.py | 2 +- defs/splash.py | 2 +- models/models/__init__.py | 0 models/models/bilifav.py | 14 ++++ models/services/__init__.py | 0 models/services/bilifav.py | 42 ++++++++++++ models/{ => services}/fragment.py | 10 +-- models/{ => services}/lofter.py | 4 +- models/{ => services}/splash.py | 8 +-- models/sqlite.py | 12 ++-- modules/bilibili.py | 8 ++- modules/bilibili_download.py | 27 ++++++-- modules/bilibili_fav.py | 103 +++++++++++++++++++++++++++++ modules/fragment.py | 2 +- 20 files changed, 349 insertions(+), 43 deletions(-) create mode 100644 defs/bilibili_fav.py create mode 100644 models/models/__init__.py create mode 100644 models/models/bilifav.py create mode 100644 models/services/__init__.py create mode 100644 models/services/bilifav.py rename models/{ => services}/fragment.py (94%) rename models/{ => services}/lofter.py (91%) rename models/{ => services}/splash.py (86%) create mode 100644 modules/bilibili_fav.py diff --git a/config.gen.ini b/config.gen.ini index d07a9f0..e375433 100644 --- a/config.gen.ini +++ b/config.gen.ini @@ -2,9 +2,6 @@ api_id = ID_HERE api_hash = HASH_HERE -[plugins] -root = modules - [proxy] enabled = False hostname = 127.0.0.1 @@ -19,8 +16,12 @@ lofter_channel = 0 lofter_channel_username = username splash_channel = 0 splash_channel_username = username +bilifav_id = 0 +bilifav_channel = 0 +bilifav_channel_username = username [api] amap_key = ABCD bili_cookie = ABCD bili_auth_user = 777000,111000 +bili_auth_chat = 777000,111000 diff --git a/defs/bilibili_download.py b/defs/bilibili_download.py index b5b5f1e..e47829d 100644 --- a/defs/bilibili_download.py +++ b/defs/bilibili_download.py @@ -217,7 +217,9 @@ async def take_screenshot(info: Dict) -> Optional[BytesIO]: return None -async def audio_download(a: Audio, m: Message): +async def audio_download( + a: Audio, m: Message, push_id: int = None +) -> Optional[Message]: try: info = await a.get_info() download_url_data = await a.get_download_url() @@ -243,12 +245,12 @@ async def audio_download(a: Audio, m: Message): text = f"{info['title']}\n\n简介过长,无法显示\n\nhttps://www.bilibili.com/audio/au{a.get_auid()}" else: text = f"{info['title']}\n\nhttps://www.bilibili.com/audio/au{a.get_auid()}" - await bot.send_audio( - chat_id=m.chat.id, + msg = await bot.send_audio( + chat_id=push_id or m.chat.id, audio=media, caption=text, parse_mode=ParseMode.HTML, - reply_to_message_id=m.reply_to_message_id, + reply_to_message_id=m.reply_to_message_id if not push_id else None, thumb=thumb, title=info.get("title"), duration=info.get("duration"), @@ -256,12 +258,17 @@ async def audio_download(a: Audio, m: Message): ) except BilibiliDownloaderError as e: await fail_edit(m, e.MSG) + return except Exception as e: logger.exception("Downloading audio failed") await fail_edit(m, f"下载/上传失败:{e}") + return + with contextlib.suppress(Exception): + await m.delete() + return msg -async def go_download(v: Video, p_num: int, m: Message): +async def go_download(v: Video, p_num: int, m: Message, task: bool = True): video_path = cache_dir / f"{v.get_aid()}_{p_num}.mp4" safe_remove(video_path) flv_temp_path = cache_dir / f"{v.get_aid()}_{p_num}_temp.flv" @@ -298,7 +305,8 @@ async def go_download(v: Video, p_num: int, m: Message): ) if result != 0: raise FFmpegError - bot.loop.create_task(go_upload(v, p_num, m)) + if task: + bot.loop.create_task(go_upload(v, p_num, m)) except BilibiliDownloaderError as e: await fail_edit(m, e.MSG) except Exception as e: @@ -328,7 +336,9 @@ async def go_upload_progress(current: int, total: int, m: Message): await message_edit(total, current, chunk, chunk_time, m, "上传") -async def go_upload(v: Video, p_num: int, m: Message): +async def go_upload( + v: Video, p_num: int, m: Message, push_id: int = None +) -> Optional[Message]: video_path = cache_dir / f"{v.get_aid()}_{p_num}.mp4" if not video_path.exists(): await fail_edit(m, "视频文件不存在") @@ -346,8 +356,8 @@ async def go_upload(v: Video, p_num: int, m: Message): video_jpg = None caption = f"https://b23.tv/{v.get_bvid()}" logger.info(f"Uploading {video_path}") - await bot.send_video( - chat_id=m.chat.id, + msg = await bot.send_video( + chat_id=push_id or m.chat.id, video=str(video_path), caption=caption, parse_mode=ParseMode.HTML, @@ -358,7 +368,7 @@ async def go_upload(v: Video, p_num: int, m: Message): supports_streaming=True, progress=go_upload_progress, progress_args=(m,), - reply_to_message_id=m.reply_to_message_id, + reply_to_message_id=m.reply_to_message_id if not push_id else None, ) logger.info(f"Upload {video_path} success") except BilibiliDownloaderError as e: @@ -376,3 +386,4 @@ async def go_upload(v: Video, p_num: int, m: Message): del UPLOAD_MESSAGE_MAP[m.id] with contextlib.suppress(Exception): await m.delete() + return msg diff --git a/defs/bilibili_fav.py b/defs/bilibili_fav.py new file mode 100644 index 0000000..1ec623f --- /dev/null +++ b/defs/bilibili_fav.py @@ -0,0 +1,104 @@ +import time +from enum import Enum +from typing import Optional + +from bilibili_api.favorite_list import FavoriteList +from pydantic import BaseModel, ValidationError +from pyrogram.types import Message + +from defs.bilibili import credential, create_video, create_audio +from defs.bilibili_download import go_download, go_upload, audio_download +from defs.glover import bilifav_id, bilifav_channel +from models.models.bilifav import BiliFav +from models.services.bilifav import BiliFavAction +from init import logger + +fav = FavoriteList(media_id=bilifav_id, credential=credential) + + +class BilibiliFavException(Exception): + pass + + +class MediaType(int, Enum): + video = 2 + audio = 12 + + +class Media(BaseModel): + id: int + bvid: str + type: MediaType + title: str + cover: Optional[str] + """ 封面 """ + intro: Optional[str] + """ 简介 """ + + +async def process_video(data: Media, m: Message): + """处理视频""" + video = create_video(data.bvid) + await go_download(video, 0, m, task=False) + msg = await go_upload(video, 0, m, push_id=bilifav_channel) + if not msg: + raise BilibiliFavException + video_db = BiliFav( + id=data.id, + bv_id=data.bvid.lower(), + type=data.type.value, + title=data.title, + cover=data.cover, + message_id=msg.id, + file_id=msg.video.file_id, + timestamp=int(time.time()), + ) + await BiliFavAction.add_bili_fav(video_db) + + +async def process_audio(data: Media, m: Message): + """处理音频""" + audio = create_audio(f"au{data.id}") + msg = await audio_download(audio, m, push_id=bilifav_channel) + if not msg: + raise BilibiliFavException + audio_db = BiliFav( + id=data.id, + bv_id=data.bvid.lower(), + type=data.type.value, + title=data.title, + cover=data.cover, + message_id=msg.id, + file_id=msg.audio.file_id, + timestamp=int(time.time()), + ) + await BiliFavAction.add_bili_fav(audio_db) + + +async def check_update(m: Message): + """检查收藏夹是否更新""" + logger.info("Check bilibili favorite list") + try: + info = await fav.get_content() + except Exception as e: + logger.exception("Check bilibili favorite list failed") + await m.edit(f"获取收藏夹信息失败:{e}") + return + for media in info.get("medias", [])[::-1]: + try: + data = Media(**media) + except ValidationError as _: + logger.exception("Validate media failed") + continue + if await BiliFavAction.get_by_bv_id(data.bvid): + continue + n = await m.reply(f"处理 {data.type.name} {data.bvid} 中...") + try: + if data.type == MediaType.video: + await process_video(data, n) + elif data.type == MediaType.audio: + await process_audio(data, n) + except BilibiliFavException: + continue + await m.edit("收藏夹数据获取完毕") + logger.info("Check bilibili favorite list success") diff --git a/defs/fragment.py b/defs/fragment.py index 5d21f15..b919d66 100644 --- a/defs/fragment.py +++ b/defs/fragment.py @@ -5,7 +5,7 @@ from typing import Optional from bs4 import BeautifulSoup from init import request -from models.fragment import ( +from models.services.fragment import ( AuctionStatus, UserName, TON_TO_USD_RATE, diff --git a/defs/glover.py b/defs/glover.py index 50be3b3..ce67615 100644 --- a/defs/glover.py +++ b/defs/glover.py @@ -13,9 +13,13 @@ lofter_channel: int = 0 lofter_channel_username: str = "" splash_channel: int = 0 splash_channel_username: str = "" +bilifav_id: int = 0 +bilifav_channel: int = 0 +bilifav_channel_username: str = "" # [api] amap_key: str = "" bili_auth_user_str: str = "" +bili_auth_chat_str: str = "" config = RawConfigParser() config.read("config.ini") api_id = config.getint("pyrogram", "api_id", fallback=api_id) @@ -30,12 +34,20 @@ splash_channel = config.getint("post", "splash_channel", fallback=splash_channel splash_channel_username = config.get( "post", "splash_channel_username", fallback=splash_channel_username ) +bilifav_id = config.getint("post", "bilifav_id", fallback=bilifav_id) +bilifav_channel = config.getint("post", "bilifav_channel", fallback=bilifav_channel) +bilifav_channel_username = config.get( + "post", "bilifav_channel_username", fallback=bilifav_channel_username +) amap_key = config.get("api", "amap_key", fallback=amap_key) bili_auth_user_str = config.get("api", "bili_auth_user", fallback=bili_auth_user_str) +bili_auth_chat_str = config.get("api", "bili_auth_chat", fallback=bili_auth_chat_str) try: bili_auth_user: List[int] = list(map(int, bili_auth_user_str.split(","))) + bili_auth_chat: List[int] = list(map(int, bili_auth_chat_str.split(","))) except ValueError: bili_auth_user: List[int] = [] + bili_auth_chat: List[int] = [] try: ipv6 = bool(strtobool(ipv6)) except ValueError: diff --git a/defs/lofter.py b/defs/lofter.py index f6019f2..526acf4 100644 --- a/defs/lofter.py +++ b/defs/lofter.py @@ -17,7 +17,7 @@ from pyrogram.types import ( ) from defs.glover import lofter_channel_username -from models.lofter import LofterPost as LofterPostModel +from models.services.lofter import LofterPost as LofterPostModel from init import request diff --git a/defs/post.py b/defs/post.py index 5267d80..5a69bb4 100644 --- a/defs/post.py +++ b/defs/post.py @@ -12,7 +12,7 @@ from pyrogram.types import Message from defs.glover import lofter_channel from defs.lofter import lofter_link -from models.lofter import LofterPost as LofterPostModel +from models.services.lofter import LofterPost as LofterPostModel from models.models.lofter import Lofter as LofterModel from init import request, bot diff --git a/defs/splash.py b/defs/splash.py index 48fd461..b3b7338 100644 --- a/defs/splash.py +++ b/defs/splash.py @@ -12,7 +12,7 @@ from defs.request import cache_file from init import bot, request, logger from models.models.splash import Splash as SplashModel from models.apis.splash import Splash as SplashApi -from models.splash import SplashService +from models.services.splash import SplashService async def get_splash() -> List[SplashApi]: diff --git a/models/models/__init__.py b/models/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/models/bilifav.py b/models/models/bilifav.py new file mode 100644 index 0000000..9b46a99 --- /dev/null +++ b/models/models/bilifav.py @@ -0,0 +1,14 @@ +from sqlmodel import SQLModel, Field + + +class BiliFav(SQLModel, table=True): + __table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci") + + id: int = Field(primary_key=True) + bv_id: str = Field() + type: int = Field(default=2) + title: str = Field() + cover: str = Field() + message_id: int = Field(default=0) + file_id: str = Field() + timestamp: int = Field(default=0) diff --git a/models/services/__init__.py b/models/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/services/bilifav.py b/models/services/bilifav.py new file mode 100644 index 0000000..026f5da --- /dev/null +++ b/models/services/bilifav.py @@ -0,0 +1,42 @@ +from typing import cast, Optional + +from sqlalchemy import select +from sqlmodel.ext.asyncio.session import AsyncSession + +from init import sqlite +from models.models.bilifav import BiliFav + + +class BiliFavAction: + @staticmethod + async def get_by_id(id_: int) -> Optional[BiliFav]: + async with sqlite.session() as session: + session = cast(AsyncSession, session) + statement = select(BiliFav).where(BiliFav.id == id_) + results = await session.exec(statement) + return post[0] if (post := results.first()) else None + + @staticmethod + async def get_by_bv_id(bv_id: str) -> Optional[BiliFav]: + if not bv_id: + return None + async with sqlite.session() as session: + session = cast(AsyncSession, session) + statement = select(BiliFav).where(BiliFav.bv_id == bv_id.lower()) + results = await session.exec(statement) + return post[0] if (post := results.first()) else None + + @staticmethod + async def add_bili_fav(bili_fav: BiliFav): + async with sqlite.session() as session: + session = cast(AsyncSession, session) + session.add(bili_fav) + await session.commit() + + @staticmethod + async def update_bili_fav(bili_fav: BiliFav): + async with sqlite.session() as session: + session = cast(AsyncSession, session) + session.add(bili_fav) + await session.commit() + await session.refresh(bili_fav) diff --git a/models/fragment.py b/models/services/fragment.py similarity index 94% rename from models/fragment.py rename to models/services/fragment.py index 9f133a1..84aa78e 100644 --- a/models/fragment.py +++ b/models/services/fragment.py @@ -99,7 +99,7 @@ class FragmentSubText(Enum): class FragmentSub: @staticmethod async def subscribe(cid: int, username: str): - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) data = Fragment(cid=cid, username=username) session.add(data) @@ -107,14 +107,14 @@ class FragmentSub: @staticmethod async def unsubscribe(data: Fragment): - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) await session.delete(data) await session.commit() @staticmethod async def get_by_cid_and_username(cid: int, username: str) -> Optional[Fragment]: - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) statement = ( select(Fragment) @@ -126,7 +126,7 @@ class FragmentSub: @staticmethod async def get_by_cid(cid: int) -> List[Fragment]: - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) statement = select(Fragment).where(Fragment.cid == cid) results = await session.exec(statement) @@ -134,7 +134,7 @@ class FragmentSub: @staticmethod async def get_all() -> List[Fragment]: - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) statement = select(Fragment) results = await session.exec(statement) diff --git a/models/lofter.py b/models/services/lofter.py similarity index 91% rename from models/lofter.py rename to models/services/lofter.py index 9259f0c..9de34e8 100644 --- a/models/lofter.py +++ b/models/services/lofter.py @@ -10,7 +10,7 @@ from models.models.lofter import Lofter class LofterPost: @staticmethod async def get_by_post_and_user_id(user_id: str, post_id: str) -> Optional[Lofter]: - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) if user_id != "0": check = Lofter.post_id == post_id and Lofter.user_id == user_id @@ -26,7 +26,7 @@ class LofterPost: @staticmethod async def add_post(post: Lofter): - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) session.add(post) await session.commit() diff --git a/models/splash.py b/models/services/splash.py similarity index 86% rename from models/splash.py rename to models/services/splash.py index e62c0ae..2ee4b4e 100644 --- a/models/splash.py +++ b/models/services/splash.py @@ -10,7 +10,7 @@ from models.models.splash import Splash class SplashService: @staticmethod async def get_by_splash_id(splash_id: int) -> Optional[Splash]: - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) check = Splash.id == splash_id statement = select(Splash).where(check) @@ -19,7 +19,7 @@ class SplashService: @staticmethod async def get_all_splashes() -> List[Optional[Splash]]: - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) statement = select(Splash) results = await session.exec(statement) @@ -27,14 +27,14 @@ class SplashService: @staticmethod async def add_splash(splash: Splash): - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) session.add(splash) await session.commit() @staticmethod async def update_splash(splash: Splash): - async with sqlite.Session() as session: + async with sqlite.session() as session: session = cast(AsyncSession, session) session.add(splash) await session.commit() diff --git a/models/sqlite.py b/models/sqlite.py index 636a371..a7cd592 100644 --- a/models/sqlite.py +++ b/models/sqlite.py @@ -1,9 +1,11 @@ from sqlmodel import SQLModel +from models.models.bilifav import BiliFav from models.models.lofter import Lofter from models.models.fragment import Fragment +from models.models.splash import Splash -__all__ = ["Lofter", "Fragment", "Sqlite"] +__all__ = ["BiliFav", "Lofter", "Fragment", "Splash", "Sqlite"] from sqlalchemy.ext.asyncio import create_async_engine from sqlalchemy.orm import sessionmaker @@ -13,15 +15,11 @@ from sqlmodel.ext.asyncio.session import AsyncSession class Sqlite: def __init__(self): self.engine = create_async_engine("sqlite+aiosqlite:///data/data.db") - self.Session = sessionmaker(bind=self.engine, class_=AsyncSession) + self.session = sessionmaker(bind=self.engine, class_=AsyncSession) async def create_db_and_tables(self): async with self.engine.begin() as session: await session.run_sync(SQLModel.metadata.create_all) - async def get_session(self): - async with self.Session() as session: - yield session - def stop(self): - self.Session.close_all() + self.session.close_all() diff --git a/modules/bilibili.py b/modules/bilibili.py index 423642c..be0d5bb 100644 --- a/modules/bilibili.py +++ b/modules/bilibili.py @@ -12,7 +12,7 @@ from defs.bilibili import ( check_and_refresh_credential, ) from defs.button import gen_button, Button -from defs.glover import bili_auth_user +from defs.glover import bili_auth_user, bili_auth_chat from init import bot from scheduler import scheduler @@ -21,7 +21,7 @@ from scheduler import scheduler filters.incoming & filters.text & filters.regex(r"av(\d{1,12})|BV(1[A-Za-z0-9]{2}4.1.7[A-Za-z0-9]{2})|b23.tv") - & ~(filters.command(["download"]) & filters.user(bili_auth_user)) + & ~(filters.command(["download", "bilibili_fav"]) & filters.user(bili_auth_user)) ) async def bili_resolve(_: Client, message: Message): """ @@ -37,7 +37,9 @@ async def bili_resolve(_: Client, message: Message): if video_info: image = await binfo_image_create(video_info) buttons = [Button(0, "Link", "https://b23.tv/" + video_info["bvid"])] - if message.from_user and message.from_user.id in bili_auth_user: + if (message.from_user and message.from_user.id in bili_auth_user) or ( + message.chat and message.chat.id in bili_auth_chat + ): buttons.append(Button(1, "Download", "download_" + video_info["bvid"])) await message.reply_photo( image, diff --git a/modules/bilibili_download.py b/modules/bilibili_download.py index 6a2dc8c..051343b 100644 --- a/modules/bilibili_download.py +++ b/modules/bilibili_download.py @@ -5,14 +5,15 @@ from pyrogram.types import Message, CallbackQuery from defs.bilibili import b23_extract, create_video, create_audio from defs.bilibili_download import go_download, audio_download -from defs.glover import bili_auth_user +from defs.glover import bili_auth_user, bilifav_channel_username, bili_auth_chat from init import bot +from models.services.bilifav import BiliFavAction @bot.on_message( filters.incoming & filters.text - & filters.user(bili_auth_user) + & (filters.user(bili_auth_user) | filters.chat(bili_auth_chat)) & filters.command(["download"]) ) async def bili_download_resolve(_: Client, message: Message): @@ -29,6 +30,13 @@ async def bili_download_resolve(_: Client, message: Message): p_num = p_.search(message.text) p_num = int(p_num[0][2:]) if p_num else 0 video = create_video(video_number) + if video_db := await BiliFavAction.get_by_bv_id(video.get_bvid()): + await message.reply_video( + video_db.file_id, + caption=f"详细信息:https://t.me/{bilifav_channel_username}/{video_db.message_id}", + quote=True, + ) + raise ContinuePropagation m = await message.reply("开始获取视频数据", quote=True) bot.loop.create_task(go_download(video, p_num, m)) @@ -51,11 +59,22 @@ async def bili_download_resolve_cb(_: Client, callback_query: CallbackQuery): if not callback_query.from_user: await callback_query.answer("请私聊机器人") return - if callback_query.from_user.id not in bili_auth_user: - await callback_query.answer("你没有权限使用此功能") + if ( + callback_query.message.chat.id not in bili_auth_chat + and callback_query.from_user.id not in bili_auth_user + ): + await callback_query.answer("你没有权限") return video_number = callback_query.matches[0].group(1) video = create_video(video_number) + if video_db := await BiliFavAction.get_by_bv_id(video.get_bvid()): + await callback_query.answer("找到缓存") + await callback_query.message.reply_video( + video_db.file_id, + caption=f"详细信息:https://t.me/{bilifav_channel_username}/{video_db.message_id}", + quote=True, + ) + raise ContinuePropagation m = await callback_query.message.reply("开始获取视频数据", quote=True) bot.loop.create_task(go_download(video, 0, m)) await callback_query.answer("开始下载") diff --git a/modules/bilibili_fav.py b/modules/bilibili_fav.py new file mode 100644 index 0000000..60d94b4 --- /dev/null +++ b/modules/bilibili_fav.py @@ -0,0 +1,103 @@ +import re +import time + +from pyrogram import filters, Client, ContinuePropagation +from pyrogram.types import Message, CallbackQuery + +from defs.bilibili import b23_extract, create_video, create_audio +from defs.bilibili_download import go_download, go_upload, audio_download +from defs.bilibili_fav import check_update +from defs.glover import admin, bilifav_channel +from init import bot, logger +from models.models.bilifav import BiliFav +from models.services.bilifav import BiliFavAction + + +async def process_audio(video_number: str, message: Message): + id_ = int(video_number[2:]) + if await BiliFavAction.get_by_id(id_): + await message.reply("该音频已经存在") + raise ContinuePropagation + audio = create_audio(video_number) + info = await audio.get_info() + m = await message.reply("开始获取音频数据", quote=True) + msg = await audio_download(audio, m, push_id=bilifav_channel) + if not msg: + raise ContinuePropagation + audio_db = BiliFav( + id=id_, + bv_id=info.get("bvid", "").lower(), + type=12, + title=info.get("title", ""), + cover=info.get("cover", ""), + message_id=msg.id, + file_id=msg.audio.file_id, + timestamp=int(time.time()), + ) + await BiliFavAction.add_bili_fav(audio_db) + + +async def process_video(video_number: str, p_num: int, message: Message): + video = create_video(video_number) + if await BiliFavAction.get_by_bv_id(video.get_bvid()): + await message.edit("该视频已经存在") + raise ContinuePropagation + info = await video.get_info() + id_ = info.get("aid", 0) + if not id_: + await message.edit("未找到视频 AV 号") + raise ContinuePropagation + m = await message.reply("开始获取视频数据", quote=True) + await go_download(video, p_num, m, task=False) + msg = await go_upload(video, p_num, m, push_id=bilifav_channel) + if not msg: + raise ContinuePropagation + audio_db = BiliFav( + id=id_, + bv_id=info.get("bvid", "").lower(), + type=2, + title=info.get("title", ""), + cover=info.get("pic", ""), + message_id=msg.id, + file_id=msg.video.file_id, + timestamp=int(time.time()), + ) + await BiliFavAction.add_bili_fav(audio_db) + + +@bot.on_message( + filters.incoming + & filters.text + & filters.user(admin) + & filters.command(["bilibili_fav"]) +) +async def bilibili_fav_parse(_: Client, message: Message): + if len(message.command) <= 1: + m = await message.reply("正在获取收藏夹数据", quote=True) + await check_update(m) + return + if "b23.tv" in message.text: + message.text = await b23_extract(message.text) + p = re.compile(r"av(\d{1,12})|BV(1[A-Za-z0-9]{2}4.1.7[A-Za-z0-9]{2})|au(\d{1,12})") + video_number = p.search(message.text) + if video_number: + video_number = video_number[0] + else: + await message.reply("未找到视频 BV 号、 AV 或 AU 号") + raise ContinuePropagation + p_ = re.compile(r"p=(\d{1,3})") + p_num = p_.search(message.text) + p_num = int(p_num[0][2:]) if p_num else 0 + m = await message.reply("开始获取数据", quote=True) + try: + if video_number.startswith("au"): + await process_audio(video_number, m) + else: + await process_video(video_number, p_num, m) + except ContinuePropagation: + raise ContinuePropagation + except Exception as e: + logger.exception("Processing bilibili favorite single push failed") + await m.edit(f"处理失败: {e}") + await m.edit("处理完成") + raise ContinuePropagation diff --git a/modules/fragment.py b/modules/fragment.py index 4cff253..4d2e8c3 100644 --- a/modules/fragment.py +++ b/modules/fragment.py @@ -12,7 +12,7 @@ from pyrogram.types import ( Message, ) -from models.fragment import FragmentSubText, FragmentSub, AuctionStatus +from models.services.fragment import FragmentSubText, FragmentSub, AuctionStatus from defs.fragment import parse_fragment, NotAvailable, parse_sub from init import bot from scheduler import scheduler, add_delete_message_job