mirror of
https://github.com/tropicoo/yt-dlp-bot.git
synced 2024-09-20 06:46:08 +08:00
Version 1.4.1
This commit is contained in:
parent
af8b65ddf2
commit
26371b2a0a
|
@ -2,7 +2,7 @@
|
|||
|
||||
Simple and reliable YouTube Download Telegram Bot.
|
||||
|
||||
Version: 1.4. [Release details](RELEASES.md).
|
||||
Version: 1.4.1. [Release details](RELEASES.md).
|
||||
|
||||
![frames](.assets/download_success.png)
|
||||
|
||||
|
|
18
RELEASES.md
18
RELEASES.md
|
@ -1,3 +1,21 @@
|
|||
## Release 1.4.1
|
||||
|
||||
Release date: March 29, 2023
|
||||
|
||||
## New Features
|
||||
|
||||
N/A
|
||||
|
||||
## Important
|
||||
|
||||
N/A
|
||||
|
||||
## Misc
|
||||
|
||||
- Maintenance release: added `uvloop`.
|
||||
|
||||
---
|
||||
|
||||
## Release 1.4
|
||||
|
||||
Release date: March 29, 2023
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import uvicorn
|
||||
|
||||
from api.core.app import app # noqa
|
||||
from api.core.app import app # noqa: F401
|
||||
|
||||
if __name__ == '__main__':
|
||||
uvicorn.run('main:app', host='0.0.0.0', port=8000)
|
||||
|
|
|
@ -13,6 +13,8 @@ from bot.core.utils import bold
|
|||
class VideoBot(Client):
|
||||
"""Extended Pyrogram's `Client` class."""
|
||||
|
||||
_RUN_FOREVER_SLEEP_SECONDS = 86400
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.conf = get_main_config()
|
||||
super().__init__(
|
||||
|
@ -33,7 +35,7 @@ class VideoBot(Client):
|
|||
if not self.is_initialized:
|
||||
raise RuntimeError('Bot was not started (initialized).')
|
||||
while True:
|
||||
await asyncio.sleep(86400)
|
||||
await asyncio.sleep(self._RUN_FOREVER_SLEEP_SECONDS)
|
||||
|
||||
def get_startup_users(self) -> list[int]:
|
||||
user_ids = []
|
||||
|
|
|
@ -3,11 +3,10 @@ import logging
|
|||
from pyrogram.enums import ParseMode
|
||||
from pyrogram.types import Message
|
||||
from yt_shared.emoji import SUCCESS_EMOJI
|
||||
from yt_shared.utils.user import get_user_id
|
||||
|
||||
from bot.core.bot import VideoBot
|
||||
from bot.core.service import UrlParser, UrlService
|
||||
from bot.core.utils import bold
|
||||
from bot.core.utils import bold, get_user_id
|
||||
|
||||
|
||||
class TelegramCallback:
|
||||
|
@ -37,7 +36,7 @@ class TelegramCallback:
|
|||
urls=urls, regexes=client.conf.telegram.url_validation_regexes
|
||||
)
|
||||
if not urls:
|
||||
self._log.info('No urls to download, skipping message')
|
||||
self._log.debug('No urls to download, skipping message')
|
||||
return
|
||||
|
||||
urls = self._url_parser.parse_urls(urls=urls, message=message, user=user)
|
||||
|
|
|
@ -5,6 +5,7 @@ import string
|
|||
from datetime import datetime
|
||||
from uuid import uuid4
|
||||
|
||||
from pyrogram.enums import ChatType
|
||||
from pyrogram.types import Message
|
||||
|
||||
|
||||
|
@ -46,6 +47,19 @@ def get_user_info(message: Message) -> str:
|
|||
)
|
||||
|
||||
|
||||
def get_user_id(message: Message) -> int:
|
||||
"""Make explicit selection to not forget how this works since we just can return
|
||||
`message.chat.id` for all cases.
|
||||
"""
|
||||
match message.chat.type:
|
||||
case ChatType.PRIVATE:
|
||||
return message.from_user.id
|
||||
case ChatType.GROUP:
|
||||
return message.chat.id
|
||||
case _:
|
||||
return message.chat.id
|
||||
|
||||
|
||||
def build_command_presentation(commands: dict[str, list]) -> str:
|
||||
groups = []
|
||||
for desc, cmds in commands.items():
|
||||
|
|
|
@ -1 +1 @@
|
|||
__version__ = '1.4'
|
||||
__version__ = '1.4.1'
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
"""Bot Launcher Module."""
|
||||
import asyncio
|
||||
|
||||
import uvloop
|
||||
|
||||
from bot.core.bot import BotLauncher
|
||||
from bot.core.log import setup_logging
|
||||
|
||||
|
@ -12,4 +14,5 @@ async def main() -> None:
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
uvloop.install()
|
||||
asyncio.run(main())
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import asyncio
|
||||
|
||||
import uvloop
|
||||
|
||||
from worker.core.launcher import WorkerLauncher
|
||||
from worker.core.log import setup_logging
|
||||
|
||||
|
||||
def main() -> None:
|
||||
async def main() -> None:
|
||||
setup_logging()
|
||||
WorkerLauncher().start()
|
||||
await WorkerLauncher().start()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
uvloop.install()
|
||||
asyncio.run(main())
|
||||
|
|
|
@ -7,27 +7,29 @@ from yt_shared.db.session import get_db
|
|||
from yt_shared.rabbit import get_rabbitmq
|
||||
from yt_shared.rabbit.rabbit_config import INPUT_QUEUE
|
||||
from yt_shared.repositories.ytdlp import YtdlpRepository
|
||||
from yt_shared.utils.common import register_shutdown
|
||||
|
||||
from worker.core.callbacks import rmq_callbacks as cb
|
||||
from worker.core.config import settings
|
||||
|
||||
|
||||
class WorkerLauncher:
|
||||
_RUN_FOREVER_SLEEP_SECONDS = 86400
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._log = logging.getLogger(self.__class__.__name__)
|
||||
self._rabbit_mq = get_rabbitmq()
|
||||
|
||||
def start(self) -> None:
|
||||
async def start(self) -> None:
|
||||
self._log.info('Starting download worker instance')
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(self._start())
|
||||
try:
|
||||
loop.run_forever()
|
||||
finally:
|
||||
loop.run_until_complete(self.stop())
|
||||
await self._start()
|
||||
|
||||
async def _start(self) -> None:
|
||||
await self._perform_setup()
|
||||
await self._run_forever()
|
||||
|
||||
async def _run_forever(self) -> None:
|
||||
await asyncio.sleep(self._RUN_FOREVER_SLEEP_SECONDS)
|
||||
|
||||
async def _perform_setup(self) -> None:
|
||||
await asyncio.gather(
|
||||
|
@ -37,6 +39,7 @@ class WorkerLauncher:
|
|||
self._create_intermediate_directories(),
|
||||
)
|
||||
)
|
||||
self._register_shutdown()
|
||||
|
||||
async def _setup_rabbit(self) -> None:
|
||||
self._log.info('Setting up RabbitMQ connection')
|
||||
|
@ -69,6 +72,10 @@ class WorkerLauncher:
|
|||
os.makedirs(tmp_download_path, exist_ok=True)
|
||||
os.makedirs(tmp_downloaded_path, exist_ok=True)
|
||||
|
||||
async def stop(self) -> None:
|
||||
def _register_shutdown(self) -> None:
|
||||
register_shutdown(self.stop)
|
||||
|
||||
def stop(self, *args) -> None:
|
||||
self._log.info('Shutting down %s', self.__class__.__name__)
|
||||
loop = asyncio.get_running_loop()
|
||||
loop.run_until_complete(self._rabbit_mq.close())
|
||||
loop.create_task(self._rabbit_mq.close())
|
||||
|
|
|
@ -4,3 +4,4 @@ aio-pika==9.0.5
|
|||
aiohttp==3.8.4
|
||||
asyncpg==0.27.0
|
||||
pydantic==1.10.7
|
||||
uvloop==0.17.0
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import logging
|
||||
from asyncio import get_running_loop
|
||||
|
||||
import aio_pika
|
||||
|
@ -13,6 +14,7 @@ class RabbitMQ:
|
|||
RABBITMQ_RECONNECT_INTERVAL = 2
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._log = logging.getLogger(self.__class__.__name__)
|
||||
self._config = get_rabbit_config()
|
||||
|
||||
self.connection: RobustConnection = None
|
||||
|
@ -52,8 +54,10 @@ class RabbitMQ:
|
|||
self.queues[queue_name] = queue
|
||||
|
||||
async def close(self) -> None:
|
||||
self._log.debug('[RabbitMQ] Closing connection')
|
||||
await self.channel.close()
|
||||
await self.connection.close()
|
||||
self._log.debug('[RabbitMQ] Connection closed')
|
||||
|
||||
|
||||
_rabbit_mq = RabbitMQ()
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import asyncio
|
||||
import atexit
|
||||
import random
|
||||
import signal
|
||||
from functools import partial, wraps
|
||||
from string import ascii_lowercase
|
||||
from typing import Any
|
||||
from typing import Any, Callable
|
||||
|
||||
ASYNC_LOCK = asyncio.Lock()
|
||||
|
||||
|
@ -53,3 +55,9 @@ def wrap(func):
|
|||
|
||||
def random_string(number: int) -> str:
|
||||
return ''.join(random.choice(ascii_lowercase) for _ in range(number))
|
||||
|
||||
|
||||
def register_shutdown(callback: Callable) -> None:
|
||||
atexit.register(callback)
|
||||
signal.signal(signal.SIGTERM, callback)
|
||||
signal.signal(signal.SIGINT, callback)
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
from pyrogram.enums import ChatType
|
||||
from pyrogram.types import Message
|
||||
|
||||
|
||||
def get_user_id(message: Message) -> int:
|
||||
"""Make explicit selection to not forget how this works since we just can return
|
||||
`message.chat.id` for all cases.
|
||||
"""
|
||||
match message.chat.type:
|
||||
case ChatType.PRIVATE:
|
||||
return message.from_user.id
|
||||
case ChatType.GROUP:
|
||||
return message.chat.id
|
||||
case _:
|
||||
return message.chat.id
|
Loading…
Reference in a new issue