2023-08-23 04:13:56 +03:00
|
|
|
import asyncio
|
|
|
|
import json
|
|
|
|
import concurrent.futures as pool
|
2023-08-24 03:28:55 +03:00
|
|
|
import multiprocessing
|
|
|
|
from functools import partial
|
2023-08-23 04:13:56 +03:00
|
|
|
from multiprocessing import freeze_support
|
|
|
|
from collections import deque
|
|
|
|
|
|
|
|
from fastapi import HTTPException
|
|
|
|
from aio_pika import connect
|
|
|
|
from aio_pika.abc import AbstractIncomingMessage
|
|
|
|
|
|
|
|
from src.core.send import body
|
|
|
|
from src.core.ydl import VideoDownloader
|
|
|
|
from src.exceptions.download_exceptions import SiteNotImplementedException
|
|
|
|
|
|
|
|
|
2023-08-24 03:28:55 +03:00
|
|
|
async def on_message(message: AbstractIncomingMessage, queue) -> None:
|
2023-08-23 04:13:56 +03:00
|
|
|
async with message.process():
|
|
|
|
# print(f" [x] Received message {message!r}")
|
2023-08-24 03:28:55 +03:00
|
|
|
await queue.put(json.loads(message.body))
|
2023-08-23 04:13:56 +03:00
|
|
|
print(f" Message body is: {message.body!r}")
|
|
|
|
|
|
|
|
|
2023-08-24 03:28:55 +03:00
|
|
|
async def get_messages(inner_queue) -> None:
|
2023-08-23 04:13:56 +03:00
|
|
|
# Perform connection
|
|
|
|
connection = await connect("amqp://guest:guest@localhost/")
|
|
|
|
|
|
|
|
async with connection:
|
|
|
|
# Creating a channel
|
|
|
|
channel = await connection.channel()
|
|
|
|
await channel.set_qos(prefetch_count=1)
|
|
|
|
|
|
|
|
# Declaring queue
|
|
|
|
queue = await channel.declare_queue(
|
|
|
|
"hello",
|
|
|
|
durable=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Start listening the queue with name 'task_queue'
|
2023-08-24 03:28:55 +03:00
|
|
|
await queue.consume(partial(on_message, queue=inner_queue))
|
2023-08-23 04:13:56 +03:00
|
|
|
|
|
|
|
print(" [*] Waiting for messages. To exit press CTRL+C")
|
|
|
|
await asyncio.Future()
|
|
|
|
|
|
|
|
|
|
|
|
def get_url_for_download_video(data: str):
|
|
|
|
file_name = VideoDownloader.get_unique_video_filename()
|
|
|
|
ydl_opts = {
|
|
|
|
"format": data["format"],
|
|
|
|
"merge_output_format": data["merge_output_format"],
|
|
|
|
'outtmpl': data["outtmpl"],
|
|
|
|
}
|
|
|
|
downloader = VideoDownloader(link=data["link"], ydl_opts=ydl_opts)
|
|
|
|
try:
|
|
|
|
result = downloader.download()
|
|
|
|
except SiteNotImplementedException as ex:
|
|
|
|
raise HTTPException(
|
|
|
|
status_code=400,
|
|
|
|
detail=ex.message
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
async def create_workers(queue):
|
2023-08-24 03:28:55 +03:00
|
|
|
link = await queue.get()
|
|
|
|
get_url_for_download_video(link)
|
|
|
|
|
2023-08-23 04:13:56 +03:00
|
|
|
|
2023-08-24 03:28:55 +03:00
|
|
|
class MasterService:
|
|
|
|
def __init__(self):
|
|
|
|
self.MAX_EXECUTOR_WORKERS = 8
|
|
|
|
self.executor = pool.ProcessPoolExecutor(max_workers=self.MAX_EXECUTOR_WORKERS)
|
|
|
|
self.queue = asyncio.Queue()
|
|
|
|
self.rabbit_consumer = get_messages
|
2023-08-23 04:13:56 +03:00
|
|
|
|
2023-08-24 03:28:55 +03:00
|
|
|
async def run(self):
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
tasks = [loop.run_in_executor(self.executor, create_workers, self.queue) for i in range(self.MAX_EXECUTOR_WORKERS)]
|
|
|
|
await asyncio.gather(self.rabbit_consumer(self.queue), *tasks)
|
2023-08-23 04:13:56 +03:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
freeze_support()
|
2023-08-24 03:28:55 +03:00
|
|
|
ms = MasterService()
|
|
|
|
asyncio.run(ms.run())
|