File size: 3,796 Bytes
00c68f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import math, asyncio, subprocess
from telethon import TelegramClient
from aiohttp import web

import logging

logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)


class Download:
    client: TelegramClient
    route: str
    offset: int
    handler: None
    file: None
    limit: int
    file_size: float

    def __init__(self, handler):
        self.handler = handler
        self.file = handler.message.media
        self.file_size = handler.message.file.size
        self.limit = handler.sanity.limit
        self.offset = handler.sanity.offset
        self.client = handler.client
        self.mime_type = handler.message.file.mime_type

    async def download(self):
        part_size = int(512 * 1024) * 2
        first_part_cut = self.offset % part_size
        first_part = math.floor(self.offset / part_size)
        last_part_cut = part_size - (self.limit % part_size)
        last_part = math.ceil(self.limit / part_size)
        part_count = math.ceil(self.file_size / part_size)
        part = first_part
        try:
            async for chunk in self.client.iter_download(
                self.file, offset=first_part * part_size, request_size=part_size
            ):

                if part == first_part:
                    yield chunk[first_part_cut:]
                elif part == last_part:
                    yield chunk[:last_part_cut]
                else:
                    yield chunk
                logging.debug(f"Part {part}/{last_part} (total {part_count}) served!")
                part += 1
            logging.debug("serving finished")
        except (GeneratorExit, StopAsyncIteration, asyncio.CancelledError):
            logging.debug("file serve interrupted")

            raise
        except Exception as e:
            print(e)
            logging.debug("file serve errored", exc_info=True)

    async def handle_request(self):
        headers = {
            "content-type": self.mime_type,
            "content-range": f"bytes {self.offset}-{self.limit-1}/{self.file_size}",
            "content-length": str(self.limit - self.offset),
            "accept-ranges": "bytes",
            "content-transfer-encoding": "Binary",
            "content-disposition": f'{self.handler.route}; filename="{self.handler.message.file.name}"',
        }
        logging.info(
            f"Serving file in {self.handler.message.file.name}) ; Range: {self.offset} - {self.limit}"
        )
        if self.handler.head:
            body = None
        else:

            body = self.download()
            # if body:

            #     ffmpeg = "ffmpeg"

            #     cmd = [
            #         ffmpeg,
            #         "ffmpeg",
            #         "-i",
         

            #         "pipe:0",
            #         "-c",
            #         "copy",
            #         "-re",
              
            #         "pipe:1",
            #     ]
            #     ffmpeg_cmd = subprocess.Popen(
            #         cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False
            #     )
            #     body = await body.__anext__()
            #     ffmpeg_cmd.stdin.write(body.tobytes())
            #     ffmpeg_cmd.stdin.close()
            #     body = b""
            #     while True:
            #         print(body)
            #         output = ffmpeg_cmd.stdout.read()

            #         if len(output) > 0:
            #             body += output
            #             ffmpeg_cmd.stdout.close()

            #         else:
            #             error_msg = ffmpeg_cmd.poll()
            #             if error_msg is not None:
            #                 break

        return web.Response(
            body=body, headers=headers, status=206 if self.offset else 200
        )