mirror of
https://github.com/Xtao-Labs/iShotaBot.git
synced 2024-11-21 14:48:23 +00:00
✨ 支持同步收藏夹到频道
This commit is contained in:
parent
a93093ea80
commit
6a23509ae3
@ -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
|
||||
|
@ -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"<b>{info['title']}</b>\n\n简介过长,无法显示\n\nhttps://www.bilibili.com/audio/au{a.get_auid()}"
|
||||
else:
|
||||
text = f"<b>{info['title']}</b>\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
|
||||
|
104
defs/bilibili_fav.py
Normal file
104
defs/bilibili_fav.py
Normal file
@ -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")
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]:
|
||||
|
0
models/models/__init__.py
Normal file
0
models/models/__init__.py
Normal file
14
models/models/bilifav.py
Normal file
14
models/models/bilifav.py
Normal file
@ -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)
|
0
models/services/__init__.py
Normal file
0
models/services/__init__.py
Normal file
42
models/services/bilifav.py
Normal file
42
models/services/bilifav.py
Normal file
@ -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)
|
@ -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)
|
@ -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()
|
@ -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()
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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("开始下载")
|
||||
|
103
modules/bilibili_fav.py
Normal file
103
modules/bilibili_fav.py
Normal file
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user