mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-08 17:13:56 +00:00
Returned back InputFile.from_url(url) method.
This commit is contained in:
parent
e04c4d05da
commit
5dacbdd2a5
1 changed files with 83 additions and 0 deletions
|
|
@ -1,10 +1,15 @@
|
|||
import io
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
|
||||
import aiohttp
|
||||
|
||||
from . import base
|
||||
from ..bot import api
|
||||
|
||||
CHUNK_SIZE = 65536
|
||||
|
||||
log = logging.getLogger('aiogram')
|
||||
|
||||
|
||||
|
|
@ -76,6 +81,84 @@ class InputFile(base.TelegramObject):
|
|||
"""
|
||||
return self.file
|
||||
|
||||
@classmethod
|
||||
async def from_url(cls, url, filename=None, chunk_size=65536):
|
||||
"""
|
||||
Download file from URL
|
||||
|
||||
Manually is not required action. You can send urls instead!
|
||||
|
||||
:param url: target URL
|
||||
:param filename: optional. set custom file name
|
||||
:param chunk_size:
|
||||
|
||||
:return: InputFile
|
||||
"""
|
||||
conf = {
|
||||
'downloaded': True,
|
||||
'url': url
|
||||
}
|
||||
|
||||
# Let's do magic with the filename
|
||||
if filename:
|
||||
filename_prefix, _, ext = filename.rpartition('.')
|
||||
file_suffix = '.' + ext if ext else ''
|
||||
else:
|
||||
filename_prefix, _, ext = url.rpartition('/')[-1].rpartition('.')
|
||||
file_suffix = '.' + ext if ext else ''
|
||||
filename = filename_prefix + file_suffix
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
start = time.time()
|
||||
async with session.get(url) as response:
|
||||
# Save file in memory
|
||||
file = await cls._process_stream(response, io.BytesIO(), chunk_size=chunk_size)
|
||||
|
||||
log.debug(f"File successful downloaded at {round(time.time() - start, 2)} seconds from '{url}'")
|
||||
return cls(file, filename, conf=conf)
|
||||
|
||||
def save(self, filename, chunk_size=65536):
|
||||
"""
|
||||
Write file to disk
|
||||
|
||||
:param filename:
|
||||
:param chunk_size:
|
||||
"""
|
||||
with open(filename, 'wb') as fp:
|
||||
while True:
|
||||
# Chunk writer
|
||||
data = self.file.read(chunk_size)
|
||||
if not data:
|
||||
break
|
||||
fp.write(data)
|
||||
# Flush all data
|
||||
fp.flush()
|
||||
|
||||
# Go to start of file.
|
||||
if self.file.seekable():
|
||||
self.file.seek(0)
|
||||
|
||||
@classmethod
|
||||
async def _process_stream(cls, response, writer, chunk_size=65536):
|
||||
"""
|
||||
Transfer data
|
||||
|
||||
:param response:
|
||||
:param writer:
|
||||
:param chunk_size:
|
||||
:return:
|
||||
"""
|
||||
while True:
|
||||
chunk = await response.content.read(chunk_size)
|
||||
if not chunk:
|
||||
break
|
||||
writer.write(chunk)
|
||||
|
||||
if writer.seekable():
|
||||
writer.seek(0)
|
||||
|
||||
return writer
|
||||
|
||||
def to_python(self):
|
||||
raise TypeError('Object of this type is not exportable!')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue