Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Convert FileInfo to attrs. #10785

Merged
merged 9 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/10785.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Convert the internal `FileInfo` class to attrs and add type hints.
57 changes: 20 additions & 37 deletions synapse/rest/media/v1/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import urllib
from typing import Awaitable, Dict, Generator, List, Optional, Tuple

import attr

from twisted.internet.interfaces import IConsumer
from twisted.protocols.basic import FileSender
from twisted.web.server import Request
Expand Down Expand Up @@ -287,44 +289,25 @@ def __exit__(self, exc_type, exc_val, exc_tb):
pass


@attr.s(slots=True, frozen=True, auto_attribs=True)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly certain this can be frozen.

class FileInfo:
"""Details about a requested/uploaded file.

Attributes:
server_name (str): The server name where the media originated from,
or None if local.
file_id (str): The local ID of the file. For local files this is the
same as the media_id
url_cache (bool): If the file is for the url preview cache
thumbnail (bool): Whether the file is a thumbnail or not.
thumbnail_width (int)
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__(
self,
server_name,
file_id,
url_cache=False,
thumbnail=False,
thumbnail_width=None,
thumbnail_height=None,
thumbnail_method=None,
thumbnail_type=None,
thumbnail_length=None,
):
self.server_name = server_name
self.file_id = file_id
self.url_cache = url_cache
self.thumbnail = thumbnail
self.thumbnail_width = thumbnail_width
self.thumbnail_height = thumbnail_height
self.thumbnail_method = thumbnail_method
self.thumbnail_type = thumbnail_type
self.thumbnail_length = thumbnail_length
"""Details about a requested/uploaded file."""

# The server name where the media originated from, or None if local.
server_name: Optional[str]
# The local ID of the file. For local files this is the same as the media_id
file_id: str
# If the file is for the url preview cache
url_cache: Optional[str] = None
clokep marked this conversation as resolved.
Show resolved Hide resolved
# Whether the file is a thumbnail or not.
thumbnail: bool = False
thumbnail_width: Optional[int] = None
thumbnail_height: Optional[int] = None
thumbnail_method: Optional[str] = None
# Content type of thumbnail, e.g. image/png
thumbnail_type: Optional[str] = None
# The size of the media file, in bytes.
thumbnail_length: Optional[int] = None
clokep marked this conversation as resolved.
Show resolved Hide resolved


def get_filename_from_headers(headers: Dict[bytes, List[bytes]]) -> Optional[str]:
Expand Down
4 changes: 2 additions & 2 deletions synapse/rest/media/v1/media_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ async def generate_remote_exact_thumbnail(
t_type: str,
) -> Optional[str]:
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:
Expand Down Expand Up @@ -655,7 +655,7 @@ async def _generate_thumbnails(
media_id: str,
file_id: str,
media_type: str,
url_cache: bool = False,
url_cache: Optional[str] = None,
) -> Optional[dict]:
"""Generate and store thumbnails for an image.

Expand Down
28 changes: 28 additions & 0 deletions synapse/rest/media/v1/media_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ async def fetch_media(self, file_info: FileInfo) -> Optional[Responder]:

# fallback for remote thumbnails with no method in the filename
if file_info.thumbnail and file_info.server_name:
# These must exist if it is a thumbnail.
assert file_info.thumbnail_width is not None
assert file_info.thumbnail_height is not None
assert file_info.thumbnail_type is not None

paths.append(
self.filepaths.remote_media_thumbnail_rel_legacy(
server_name=file_info.server_name,
Expand Down Expand Up @@ -217,6 +222,11 @@ async def ensure_media_is_in_local_cache(self, file_info: FileInfo) -> str:
# Fallback for paths without method names
# Should be removed in the future
if file_info.thumbnail and file_info.server_name:
# These must exist if it is a thumbnail.
assert file_info.thumbnail_width is not None
assert file_info.thumbnail_height is not None
assert file_info.thumbnail_type is not None

legacy_path = self.filepaths.remote_media_thumbnail_rel_legacy(
server_name=file_info.server_name,
file_id=file_info.file_id,
Expand Down Expand Up @@ -253,6 +263,12 @@ def _file_info_to_path(self, file_info: FileInfo) -> str:
"""
if file_info.url_cache:
if file_info.thumbnail:
# These must exist if it is a thumbnail.
assert file_info.thumbnail_width is not None
assert file_info.thumbnail_height is not None
assert file_info.thumbnail_type is not None
assert file_info.thumbnail_method is not None

return self.filepaths.url_cache_thumbnail_rel(
media_id=file_info.file_id,
width=file_info.thumbnail_width,
Expand All @@ -264,6 +280,12 @@ def _file_info_to_path(self, file_info: FileInfo) -> str:

if file_info.server_name:
if file_info.thumbnail:
# These must exist if it is a thumbnail.
assert file_info.thumbnail_width is not None
assert file_info.thumbnail_height is not None
assert file_info.thumbnail_type is not None
assert file_info.thumbnail_method is not None

return self.filepaths.remote_media_thumbnail_rel(
server_name=file_info.server_name,
file_id=file_info.file_id,
Expand All @@ -277,6 +299,12 @@ def _file_info_to_path(self, file_info: FileInfo) -> str:
)

if file_info.thumbnail:
# These must exist if it is a thumbnail.
assert file_info.thumbnail_width is not None
assert file_info.thumbnail_height is not None
assert file_info.thumbnail_type is not None
assert file_info.thumbnail_method is not None

return self.filepaths.local_media_thumbnail_rel(
media_id=file_info.file_id,
width=file_info.thumbnail_width,
Expand Down
6 changes: 3 additions & 3 deletions synapse/rest/media/v1/preview_url_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ async def _do_preview(self, url: str, user: str, ts: int) -> bytes:
if _is_media(media_info.media_type):
file_id = media_info.filesystem_id
dims = await self.media_repo._generate_thumbnails(
None, file_id, file_id, media_info.media_type, url_cache=True
None, file_id, file_id, media_info.media_type, url_cache=url
)

og = {
Expand Down Expand Up @@ -300,7 +300,7 @@ async def _do_preview(self, url: str, user: str, ts: int) -> bytes:
# TODO: make sure we don't choke on white-on-transparent images
file_id = image_info.filesystem_id
dims = await self.media_repo._generate_thumbnails(
None, file_id, file_id, image_info.media_type, url_cache=True
None, file_id, file_id, image_info.media_type, url_cache=url
)
if dims:
og["og:image:width"] = dims["width"]
Expand Down Expand Up @@ -355,7 +355,7 @@ async def _download_url(self, url: str, user: str) -> MediaInfo:

file_id = datetime.date.today().isoformat() + "_" + random_string(16)

file_info = FileInfo(server_name=None, file_id=file_id, url_cache=True)
file_info = FileInfo(server_name=None, file_id=file_id, url_cache=url)

# If this URL can be accessed via oEmbed, use that instead.
url_to_download: Optional[str] = url
Expand Down
7 changes: 7 additions & 0 deletions synapse/rest/media/v1/thumbnail_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,13 @@ async def _select_and_respond_with_thumbnail(
respond_404(request)
return

# These must exist if it is a thumbnail.
assert file_info.thumbnail_width is not None
assert file_info.thumbnail_height is not None
assert file_info.thumbnail_type is not None
assert file_info.thumbnail_method is not None
assert file_info.thumbnail_length is not None

responder = await self.media_storage.fetch_media(file_info)
if responder:
await respond_with_responder(
Expand Down