"""Bot's callbacks implementation"""
import asyncio
import glob
import html
import os
import shutil
import traceback
from mab import MatrixBot
from mab.types import VideoFileProperties
from mab.filters.text import TextFilter, TextStartsWithFilter, TextEndsWithFilter
from nio import MatrixRoom, RoomMessageText
from downloader import Downloader
#
# PRIVATE DATA
#
_bot: MatrixBot
_tasks: set[asyncio.Task] = set()
#
# PRIVATE
#
async def worker_download(room: MatrixRoom, text: RoomMessageText) -> None:
# respond
response = (
f"Скачивание видео по "
f"вашей ссылке"
)
await _bot.send_text_to_room(room.room_id, response, True)
# get formats
d = Downloader(text.body)
try:
result = await d.download_video("temp")
except:
await _bot.send_text_to_room(room.room_id, traceback.format_exc(), False)
return
await _bot.send_text_to_room(room.room_id, "Скачано, загрузка в Matrix...", True)
# upload
try:
await _bot.send_video_to_room(room.room_id, result, caption=f"Скачано из {text.body}")
except:
await _bot.send_text_to_room(room.room_id, traceback.format_exc(), False)
finally:
os.unlink(result)
#
# CALLBACKS
#
async def command_help(room: MatrixRoom, text: RoomMessageText) -> None:
"""!help"""
if text.sender == _bot.get_client().user_id:
return
resp = "2026-matrix-down
"
resp += "Этот бот используется для скачивания видео/аудио с хостингов, "
resp += "поддерживаемых yt-dlp. Просто отправьте ссылку в эту "
resp += "комнату, чтобы бот предложил варианты загрузки."
await _bot.send_text_to_room(room.room_id, resp, True)
async def command_http_https(room: MatrixRoom, text: RoomMessageText) -> None:
"""The message starts with `http://` or `https://`"""
if text.sender == _bot.get_client().user_id:
return
t = asyncio.create_task(worker_download(room, text))
_tasks.add(t)
t.add_done_callback(_tasks.discard)
async def command_test(room: MatrixRoom, text: RoomMessageText) -> None:
"""The message ends with ` TesT` (case matters)"""
if text.sender == _bot.get_client().user_id:
return
# glob patterns to use
glob_img = ["*.png", "*.jpg", ".jpeg", "*.gif", "*.webp"]
glob_vid = ["*.mp4", "*.avi", "*.mkv"]
# TODO
glob_aud = ["*.mp3", "*.m4a", ".wav", "*.ogg", "*.flac"]
# help message
resp = "Сообщение заканчивается на TesT.
"
resp += "Сейчас будут отправлены все файлы из директории test_media"
resp += ", у которых следующие расширения:
"
resp += f"
{g}" for g in glob_img])}{g}" for g in glob_vid])}{html.escape(file)}",
is_html=True
)
except:
await _bot.send_text_to_room(room.room_id, traceback.format_exc(), False)
await asyncio.sleep(0.5)
# send videos
for g in [f"test_media/{g}" for g in glob_vid]:
imgs = glob.glob(g)
for file in imgs:
try:
await _bot.send_video_to_room(
room.room_id,
file,
caption=f"Видео {html.escape(file)}",
is_html=True
)
except:
await _bot.send_text_to_room(room.room_id, traceback.format_exc(), False)
await asyncio.sleep(0.5)
#
# PUBLIC
#
async def initialize(bot: MatrixBot) -> None:
"""This function initializes the bot. It does not start it."""
global _bot
shutil.rmtree("temp", ignore_errors=True)
os.makedirs("temp", exist_ok=True)
_bot = bot
bot.add_event_callback(command_http_https, TextStartsWithFilter(["https://", "http://"]))
bot.add_event_callback(command_test, TextEndsWithFilter(" TesT", any_case=False))
bot.add_event_callback(command_help, TextFilter())
async def deinitizalize(bot: MatrixBot) -> None:
"""This function deinitializes the bot. It does not stop it."""
shutil.rmtree("temp", ignore_errors=True)