forked from MirrorHub/synapse
Convert media repo's FileInfo to attrs. (#10785)
This is mostly an internal change, but improves type hints in the media code.
This commit is contained in:
parent
319b8b6bef
commit
b996782df5
5 changed files with 138 additions and 106 deletions
1
changelog.d/10785.misc
Normal file
1
changelog.d/10785.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Convert the internal `FileInfo` class to attrs and add type hints.
|
|
@ -18,6 +18,8 @@ import os
|
||||||
import urllib
|
import urllib
|
||||||
from typing import Awaitable, Dict, Generator, List, Optional, Tuple
|
from typing import Awaitable, Dict, Generator, List, Optional, Tuple
|
||||||
|
|
||||||
|
import attr
|
||||||
|
|
||||||
from twisted.internet.interfaces import IConsumer
|
from twisted.internet.interfaces import IConsumer
|
||||||
from twisted.protocols.basic import FileSender
|
from twisted.protocols.basic import FileSender
|
||||||
from twisted.web.server import Request
|
from twisted.web.server import Request
|
||||||
|
@ -287,44 +289,62 @@ class Responder:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
||||||
|
class ThumbnailInfo:
|
||||||
|
"""Details about a generated thumbnail."""
|
||||||
|
|
||||||
|
width: int
|
||||||
|
height: int
|
||||||
|
method: str
|
||||||
|
# Content type of thumbnail, e.g. image/png
|
||||||
|
type: str
|
||||||
|
# The size of the media file, in bytes.
|
||||||
|
length: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
||||||
class FileInfo:
|
class FileInfo:
|
||||||
"""Details about a requested/uploaded file.
|
"""Details about a requested/uploaded file."""
|
||||||
|
|
||||||
Attributes:
|
# The server name where the media originated from, or None if local.
|
||||||
server_name (str): The server name where the media originated from,
|
server_name: Optional[str]
|
||||||
or None if local.
|
# The local ID of the file. For local files this is the same as the media_id
|
||||||
file_id (str): The local ID of the file. For local files this is the
|
file_id: str
|
||||||
same as the media_id
|
# If the file is for the url preview cache
|
||||||
url_cache (bool): If the file is for the url preview cache
|
url_cache: bool = False
|
||||||
thumbnail (bool): Whether the file is a thumbnail or not.
|
# Whether the file is a thumbnail or not.
|
||||||
thumbnail_width (int)
|
thumbnail: Optional[ThumbnailInfo] = None
|
||||||
thumbnail_height (int)
|
|
||||||
thumbnail_method (str)
|
|
||||||
thumbnail_type (str): Content type of thumbnail, e.g. image/png
|
|
||||||
thumbnail_length (int): The size of the media file, in bytes.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
# The below properties exist to maintain compatibility with third-party modules.
|
||||||
self,
|
@property
|
||||||
server_name,
|
def thumbnail_width(self):
|
||||||
file_id,
|
if not self.thumbnail:
|
||||||
url_cache=False,
|
return None
|
||||||
thumbnail=False,
|
return self.thumbnail.width
|
||||||
thumbnail_width=None,
|
|
||||||
thumbnail_height=None,
|
@property
|
||||||
thumbnail_method=None,
|
def thumbnail_height(self):
|
||||||
thumbnail_type=None,
|
if not self.thumbnail:
|
||||||
thumbnail_length=None,
|
return None
|
||||||
):
|
return self.thumbnail.height
|
||||||
self.server_name = server_name
|
|
||||||
self.file_id = file_id
|
@property
|
||||||
self.url_cache = url_cache
|
def thumbnail_method(self):
|
||||||
self.thumbnail = thumbnail
|
if not self.thumbnail:
|
||||||
self.thumbnail_width = thumbnail_width
|
return None
|
||||||
self.thumbnail_height = thumbnail_height
|
return self.thumbnail.method
|
||||||
self.thumbnail_method = thumbnail_method
|
|
||||||
self.thumbnail_type = thumbnail_type
|
@property
|
||||||
self.thumbnail_length = thumbnail_length
|
def thumbnail_type(self):
|
||||||
|
if not self.thumbnail:
|
||||||
|
return None
|
||||||
|
return self.thumbnail.type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def thumbnail_length(self):
|
||||||
|
if not self.thumbnail:
|
||||||
|
return None
|
||||||
|
return self.thumbnail.length
|
||||||
|
|
||||||
|
|
||||||
def get_filename_from_headers(headers: Dict[bytes, List[bytes]]) -> Optional[str]:
|
def get_filename_from_headers(headers: Dict[bytes, List[bytes]]) -> Optional[str]:
|
||||||
|
|
|
@ -42,6 +42,7 @@ from synapse.util.stringutils import random_string
|
||||||
from ._base import (
|
from ._base import (
|
||||||
FileInfo,
|
FileInfo,
|
||||||
Responder,
|
Responder,
|
||||||
|
ThumbnailInfo,
|
||||||
get_filename_from_headers,
|
get_filename_from_headers,
|
||||||
respond_404,
|
respond_404,
|
||||||
respond_with_responder,
|
respond_with_responder,
|
||||||
|
@ -210,7 +211,7 @@ class MediaRepository:
|
||||||
upload_name = name if name else media_info["upload_name"]
|
upload_name = name if name else media_info["upload_name"]
|
||||||
url_cache = media_info["url_cache"]
|
url_cache = media_info["url_cache"]
|
||||||
|
|
||||||
file_info = FileInfo(None, media_id, url_cache=url_cache)
|
file_info = FileInfo(None, media_id, url_cache=bool(url_cache))
|
||||||
|
|
||||||
responder = await self.media_storage.fetch_media(file_info)
|
responder = await self.media_storage.fetch_media(file_info)
|
||||||
await respond_with_responder(
|
await respond_with_responder(
|
||||||
|
@ -514,7 +515,7 @@ class MediaRepository:
|
||||||
t_height: int,
|
t_height: int,
|
||||||
t_method: str,
|
t_method: str,
|
||||||
t_type: str,
|
t_type: str,
|
||||||
url_cache: Optional[str],
|
url_cache: bool,
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
input_path = await self.media_storage.ensure_media_is_in_local_cache(
|
input_path = await self.media_storage.ensure_media_is_in_local_cache(
|
||||||
FileInfo(None, media_id, url_cache=url_cache)
|
FileInfo(None, media_id, url_cache=url_cache)
|
||||||
|
@ -548,11 +549,12 @@ class MediaRepository:
|
||||||
server_name=None,
|
server_name=None,
|
||||||
file_id=media_id,
|
file_id=media_id,
|
||||||
url_cache=url_cache,
|
url_cache=url_cache,
|
||||||
thumbnail=True,
|
thumbnail=ThumbnailInfo(
|
||||||
thumbnail_width=t_width,
|
width=t_width,
|
||||||
thumbnail_height=t_height,
|
height=t_height,
|
||||||
thumbnail_method=t_method,
|
method=t_method,
|
||||||
thumbnail_type=t_type,
|
type=t_type,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
output_path = await self.media_storage.store_file(
|
output_path = await self.media_storage.store_file(
|
||||||
|
@ -585,7 +587,7 @@ class MediaRepository:
|
||||||
t_type: str,
|
t_type: str,
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
input_path = await self.media_storage.ensure_media_is_in_local_cache(
|
input_path = await self.media_storage.ensure_media_is_in_local_cache(
|
||||||
FileInfo(server_name, file_id, url_cache=False)
|
FileInfo(server_name, file_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -616,11 +618,12 @@ class MediaRepository:
|
||||||
file_info = FileInfo(
|
file_info = FileInfo(
|
||||||
server_name=server_name,
|
server_name=server_name,
|
||||||
file_id=file_id,
|
file_id=file_id,
|
||||||
thumbnail=True,
|
thumbnail=ThumbnailInfo(
|
||||||
thumbnail_width=t_width,
|
width=t_width,
|
||||||
thumbnail_height=t_height,
|
height=t_height,
|
||||||
thumbnail_method=t_method,
|
method=t_method,
|
||||||
thumbnail_type=t_type,
|
type=t_type,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
output_path = await self.media_storage.store_file(
|
output_path = await self.media_storage.store_file(
|
||||||
|
@ -742,12 +745,13 @@ class MediaRepository:
|
||||||
file_info = FileInfo(
|
file_info = FileInfo(
|
||||||
server_name=server_name,
|
server_name=server_name,
|
||||||
file_id=file_id,
|
file_id=file_id,
|
||||||
thumbnail=True,
|
|
||||||
thumbnail_width=t_width,
|
|
||||||
thumbnail_height=t_height,
|
|
||||||
thumbnail_method=t_method,
|
|
||||||
thumbnail_type=t_type,
|
|
||||||
url_cache=url_cache,
|
url_cache=url_cache,
|
||||||
|
thumbnail=ThumbnailInfo(
|
||||||
|
width=t_width,
|
||||||
|
height=t_height,
|
||||||
|
method=t_method,
|
||||||
|
type=t_type,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
with self.media_storage.store_into_file(file_info) as (f, fname, finish):
|
with self.media_storage.store_into_file(file_info) as (f, fname, finish):
|
||||||
|
|
|
@ -176,9 +176,9 @@ class MediaStorage:
|
||||||
self.filepaths.remote_media_thumbnail_rel_legacy(
|
self.filepaths.remote_media_thumbnail_rel_legacy(
|
||||||
server_name=file_info.server_name,
|
server_name=file_info.server_name,
|
||||||
file_id=file_info.file_id,
|
file_id=file_info.file_id,
|
||||||
width=file_info.thumbnail_width,
|
width=file_info.thumbnail.width,
|
||||||
height=file_info.thumbnail_height,
|
height=file_info.thumbnail.height,
|
||||||
content_type=file_info.thumbnail_type,
|
content_type=file_info.thumbnail.type,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -220,9 +220,9 @@ class MediaStorage:
|
||||||
legacy_path = self.filepaths.remote_media_thumbnail_rel_legacy(
|
legacy_path = self.filepaths.remote_media_thumbnail_rel_legacy(
|
||||||
server_name=file_info.server_name,
|
server_name=file_info.server_name,
|
||||||
file_id=file_info.file_id,
|
file_id=file_info.file_id,
|
||||||
width=file_info.thumbnail_width,
|
width=file_info.thumbnail.width,
|
||||||
height=file_info.thumbnail_height,
|
height=file_info.thumbnail.height,
|
||||||
content_type=file_info.thumbnail_type,
|
content_type=file_info.thumbnail.type,
|
||||||
)
|
)
|
||||||
legacy_local_path = os.path.join(self.local_media_directory, legacy_path)
|
legacy_local_path = os.path.join(self.local_media_directory, legacy_path)
|
||||||
if os.path.exists(legacy_local_path):
|
if os.path.exists(legacy_local_path):
|
||||||
|
@ -255,10 +255,10 @@ class MediaStorage:
|
||||||
if file_info.thumbnail:
|
if file_info.thumbnail:
|
||||||
return self.filepaths.url_cache_thumbnail_rel(
|
return self.filepaths.url_cache_thumbnail_rel(
|
||||||
media_id=file_info.file_id,
|
media_id=file_info.file_id,
|
||||||
width=file_info.thumbnail_width,
|
width=file_info.thumbnail.width,
|
||||||
height=file_info.thumbnail_height,
|
height=file_info.thumbnail.height,
|
||||||
content_type=file_info.thumbnail_type,
|
content_type=file_info.thumbnail.type,
|
||||||
method=file_info.thumbnail_method,
|
method=file_info.thumbnail.method,
|
||||||
)
|
)
|
||||||
return self.filepaths.url_cache_filepath_rel(file_info.file_id)
|
return self.filepaths.url_cache_filepath_rel(file_info.file_id)
|
||||||
|
|
||||||
|
@ -267,10 +267,10 @@ class MediaStorage:
|
||||||
return self.filepaths.remote_media_thumbnail_rel(
|
return self.filepaths.remote_media_thumbnail_rel(
|
||||||
server_name=file_info.server_name,
|
server_name=file_info.server_name,
|
||||||
file_id=file_info.file_id,
|
file_id=file_info.file_id,
|
||||||
width=file_info.thumbnail_width,
|
width=file_info.thumbnail.width,
|
||||||
height=file_info.thumbnail_height,
|
height=file_info.thumbnail.height,
|
||||||
content_type=file_info.thumbnail_type,
|
content_type=file_info.thumbnail.type,
|
||||||
method=file_info.thumbnail_method,
|
method=file_info.thumbnail.method,
|
||||||
)
|
)
|
||||||
return self.filepaths.remote_media_filepath_rel(
|
return self.filepaths.remote_media_filepath_rel(
|
||||||
file_info.server_name, file_info.file_id
|
file_info.server_name, file_info.file_id
|
||||||
|
@ -279,10 +279,10 @@ class MediaStorage:
|
||||||
if file_info.thumbnail:
|
if file_info.thumbnail:
|
||||||
return self.filepaths.local_media_thumbnail_rel(
|
return self.filepaths.local_media_thumbnail_rel(
|
||||||
media_id=file_info.file_id,
|
media_id=file_info.file_id,
|
||||||
width=file_info.thumbnail_width,
|
width=file_info.thumbnail.width,
|
||||||
height=file_info.thumbnail_height,
|
height=file_info.thumbnail.height,
|
||||||
content_type=file_info.thumbnail_type,
|
content_type=file_info.thumbnail.type,
|
||||||
method=file_info.thumbnail_method,
|
method=file_info.thumbnail.method,
|
||||||
)
|
)
|
||||||
return self.filepaths.local_media_filepath_rel(file_info.file_id)
|
return self.filepaths.local_media_filepath_rel(file_info.file_id)
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ from synapse.rest.media.v1.media_storage import MediaStorage
|
||||||
|
|
||||||
from ._base import (
|
from ._base import (
|
||||||
FileInfo,
|
FileInfo,
|
||||||
|
ThumbnailInfo,
|
||||||
parse_media_id,
|
parse_media_id,
|
||||||
respond_404,
|
respond_404,
|
||||||
respond_with_file,
|
respond_with_file,
|
||||||
|
@ -114,7 +115,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
thumbnail_infos,
|
thumbnail_infos,
|
||||||
media_id,
|
media_id,
|
||||||
media_id,
|
media_id,
|
||||||
url_cache=media_info["url_cache"],
|
url_cache=bool(media_info["url_cache"]),
|
||||||
server_name=None,
|
server_name=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -149,11 +150,12 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
server_name=None,
|
server_name=None,
|
||||||
file_id=media_id,
|
file_id=media_id,
|
||||||
url_cache=media_info["url_cache"],
|
url_cache=media_info["url_cache"],
|
||||||
thumbnail=True,
|
thumbnail=ThumbnailInfo(
|
||||||
thumbnail_width=info["thumbnail_width"],
|
width=info["thumbnail_width"],
|
||||||
thumbnail_height=info["thumbnail_height"],
|
height=info["thumbnail_height"],
|
||||||
thumbnail_type=info["thumbnail_type"],
|
type=info["thumbnail_type"],
|
||||||
thumbnail_method=info["thumbnail_method"],
|
method=info["thumbnail_method"],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
t_type = file_info.thumbnail_type
|
t_type = file_info.thumbnail_type
|
||||||
|
@ -173,7 +175,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
desired_height,
|
desired_height,
|
||||||
desired_method,
|
desired_method,
|
||||||
desired_type,
|
desired_type,
|
||||||
url_cache=media_info["url_cache"],
|
url_cache=bool(media_info["url_cache"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
if file_path:
|
if file_path:
|
||||||
|
@ -210,11 +212,12 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
file_info = FileInfo(
|
file_info = FileInfo(
|
||||||
server_name=server_name,
|
server_name=server_name,
|
||||||
file_id=media_info["filesystem_id"],
|
file_id=media_info["filesystem_id"],
|
||||||
thumbnail=True,
|
thumbnail=ThumbnailInfo(
|
||||||
thumbnail_width=info["thumbnail_width"],
|
width=info["thumbnail_width"],
|
||||||
thumbnail_height=info["thumbnail_height"],
|
height=info["thumbnail_height"],
|
||||||
thumbnail_type=info["thumbnail_type"],
|
type=info["thumbnail_type"],
|
||||||
thumbnail_method=info["thumbnail_method"],
|
method=info["thumbnail_method"],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
t_type = file_info.thumbnail_type
|
t_type = file_info.thumbnail_type
|
||||||
|
@ -271,7 +274,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
thumbnail_infos,
|
thumbnail_infos,
|
||||||
media_id,
|
media_id,
|
||||||
media_info["filesystem_id"],
|
media_info["filesystem_id"],
|
||||||
url_cache=None,
|
url_cache=False,
|
||||||
server_name=server_name,
|
server_name=server_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -285,7 +288,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
thumbnail_infos: List[Dict[str, Any]],
|
thumbnail_infos: List[Dict[str, Any]],
|
||||||
media_id: str,
|
media_id: str,
|
||||||
file_id: str,
|
file_id: str,
|
||||||
url_cache: Optional[str] = None,
|
url_cache: bool,
|
||||||
server_name: Optional[str] = None,
|
server_name: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -299,7 +302,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
desired_type: The desired content-type of the thumbnail.
|
desired_type: The desired content-type of the thumbnail.
|
||||||
thumbnail_infos: A list of dictionaries of candidate thumbnails.
|
thumbnail_infos: A list of dictionaries of candidate thumbnails.
|
||||||
file_id: The ID of the media that a thumbnail is being requested for.
|
file_id: The ID of the media that a thumbnail is being requested for.
|
||||||
url_cache: The URL cache value.
|
url_cache: True if this is from a URL cache.
|
||||||
server_name: The server name, if this is a remote thumbnail.
|
server_name: The server name, if this is a remote thumbnail.
|
||||||
"""
|
"""
|
||||||
if thumbnail_infos:
|
if thumbnail_infos:
|
||||||
|
@ -318,13 +321,16 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
respond_404(request)
|
respond_404(request)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# The thumbnail property must exist.
|
||||||
|
assert file_info.thumbnail is not None
|
||||||
|
|
||||||
responder = await self.media_storage.fetch_media(file_info)
|
responder = await self.media_storage.fetch_media(file_info)
|
||||||
if responder:
|
if responder:
|
||||||
await respond_with_responder(
|
await respond_with_responder(
|
||||||
request,
|
request,
|
||||||
responder,
|
responder,
|
||||||
file_info.thumbnail_type,
|
file_info.thumbnail.type,
|
||||||
file_info.thumbnail_length,
|
file_info.thumbnail.length,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -351,18 +357,18 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
server_name,
|
server_name,
|
||||||
file_id=file_id,
|
file_id=file_id,
|
||||||
media_id=media_id,
|
media_id=media_id,
|
||||||
t_width=file_info.thumbnail_width,
|
t_width=file_info.thumbnail.width,
|
||||||
t_height=file_info.thumbnail_height,
|
t_height=file_info.thumbnail.height,
|
||||||
t_method=file_info.thumbnail_method,
|
t_method=file_info.thumbnail.method,
|
||||||
t_type=file_info.thumbnail_type,
|
t_type=file_info.thumbnail.type,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await self.media_repo.generate_local_exact_thumbnail(
|
await self.media_repo.generate_local_exact_thumbnail(
|
||||||
media_id=media_id,
|
media_id=media_id,
|
||||||
t_width=file_info.thumbnail_width,
|
t_width=file_info.thumbnail.width,
|
||||||
t_height=file_info.thumbnail_height,
|
t_height=file_info.thumbnail.height,
|
||||||
t_method=file_info.thumbnail_method,
|
t_method=file_info.thumbnail.method,
|
||||||
t_type=file_info.thumbnail_type,
|
t_type=file_info.thumbnail.type,
|
||||||
url_cache=url_cache,
|
url_cache=url_cache,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -370,8 +376,8 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
await respond_with_responder(
|
await respond_with_responder(
|
||||||
request,
|
request,
|
||||||
responder,
|
responder,
|
||||||
file_info.thumbnail_type,
|
file_info.thumbnail.type,
|
||||||
file_info.thumbnail_length,
|
file_info.thumbnail.length,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.info("Failed to find any generated thumbnails")
|
logger.info("Failed to find any generated thumbnails")
|
||||||
|
@ -385,7 +391,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
desired_type: str,
|
desired_type: str,
|
||||||
thumbnail_infos: List[Dict[str, Any]],
|
thumbnail_infos: List[Dict[str, Any]],
|
||||||
file_id: str,
|
file_id: str,
|
||||||
url_cache: Optional[str],
|
url_cache: bool,
|
||||||
server_name: Optional[str],
|
server_name: Optional[str],
|
||||||
) -> Optional[FileInfo]:
|
) -> Optional[FileInfo]:
|
||||||
"""
|
"""
|
||||||
|
@ -398,7 +404,7 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
desired_type: The desired content-type of the thumbnail.
|
desired_type: The desired content-type of the thumbnail.
|
||||||
thumbnail_infos: A list of dictionaries of candidate thumbnails.
|
thumbnail_infos: A list of dictionaries of candidate thumbnails.
|
||||||
file_id: The ID of the media that a thumbnail is being requested for.
|
file_id: The ID of the media that a thumbnail is being requested for.
|
||||||
url_cache: The URL cache value.
|
url_cache: True if this is from a URL cache.
|
||||||
server_name: The server name, if this is a remote thumbnail.
|
server_name: The server name, if this is a remote thumbnail.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -495,12 +501,13 @@ class ThumbnailResource(DirectServeJsonResource):
|
||||||
file_id=file_id,
|
file_id=file_id,
|
||||||
url_cache=url_cache,
|
url_cache=url_cache,
|
||||||
server_name=server_name,
|
server_name=server_name,
|
||||||
thumbnail=True,
|
thumbnail=ThumbnailInfo(
|
||||||
thumbnail_width=thumbnail_info["thumbnail_width"],
|
width=thumbnail_info["thumbnail_width"],
|
||||||
thumbnail_height=thumbnail_info["thumbnail_height"],
|
height=thumbnail_info["thumbnail_height"],
|
||||||
thumbnail_type=thumbnail_info["thumbnail_type"],
|
type=thumbnail_info["thumbnail_type"],
|
||||||
thumbnail_method=thumbnail_info["thumbnail_method"],
|
method=thumbnail_info["thumbnail_method"],
|
||||||
thumbnail_length=thumbnail_info["thumbnail_length"],
|
length=thumbnail_info["thumbnail_length"],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# No matching thumbnail was found.
|
# No matching thumbnail was found.
|
||||||
|
|
Loading…
Reference in a new issue