Ensure media is in local cache before thumbnailing

This commit is contained in:
Erik Johnston 2018-01-16 10:52:32 +00:00
parent be0dfcd4a2
commit 4a53f3a3e8
3 changed files with 40 additions and 10 deletions

View file

@ -445,8 +445,10 @@ class MediaRepository(object):
@defer.inlineCallbacks
def generate_local_exact_thumbnail(self, media_id, t_width, t_height,
t_method, t_type):
input_path = self.filepaths.local_media_filepath(media_id)
t_method, t_type, url_cache):
input_path = yield self.media_storage.ensure_media_is_in_local_cache(FileInfo(
None, media_id, url_cache=url_cache,
))
thumbnailer = Thumbnailer(input_path)
t_byte_source = yield make_deferred_yieldable(threads.deferToThread(
@ -459,6 +461,7 @@ class MediaRepository(object):
file_info = FileInfo(
server_name=None,
file_id=media_id,
url_cache=url_cache,
thumbnail=True,
thumbnail_width=t_width,
thumbnail_height=t_height,
@ -485,7 +488,9 @@ class MediaRepository(object):
@defer.inlineCallbacks
def generate_remote_exact_thumbnail(self, server_name, file_id, media_id,
t_width, t_height, t_method, t_type):
input_path = self.filepaths.remote_media_filepath(server_name, file_id)
input_path = yield self.media_storage.ensure_media_is_in_local_cache(FileInfo(
server_name, file_id, url_cache=False,
))
thumbnailer = Thumbnailer(input_path)
t_byte_source = yield make_deferred_yieldable(threads.deferToThread(
@ -543,12 +548,9 @@ class MediaRepository(object):
if not requirements:
return
if server_name:
input_path = self.filepaths.remote_media_filepath(server_name, file_id)
elif url_cache:
input_path = self.filepaths.url_cache_filepath(media_id)
else:
input_path = self.filepaths.local_media_filepath(media_id)
input_path = yield self.media_storage.ensure_media_is_in_local_cache(FileInfo(
server_name, file_id, url_cache=url_cache,
))
thumbnailer = Thumbnailer(input_path)
m_width = thumbnailer.width

View file

@ -15,6 +15,7 @@
from twisted.internet import defer, threads
from twisted.protocols.basic import FileSender
from twisted.protocols.ftp import FileConsumer # This isn't FTP specific
from ._base import Responder
@ -151,6 +152,32 @@ class MediaStorage(object):
defer.returnValue(None)
@defer.inlineCallbacks
def ensure_media_is_in_local_cache(self, file_info):
"""Ensures that the given file is in the local cache. Attempts to
download it from storage providers if it isn't.
Args:
file_info (FileInfo)
Returns:
Deferred[str]: Full path to local file
"""
path = self._file_info_to_path(file_info)
local_path = os.path.join(self.local_media_directory, path)
if os.path.exists(local_path):
defer.returnValue(local_path)
for provider in self.storage_providers:
res = yield provider.fetch(path, file_info)
if res:
with res:
with open(local_path, "w") as f:
res.write_to_consumer(FileConsumer(f))
defer.returnValue(local_path)
raise Exception("file could not be found")
def _file_info_to_path(self, file_info):
"""Converts file_info into a relative path.

View file

@ -162,7 +162,8 @@ class ThumbnailResource(Resource):
# Okay, so we generate one.
file_path = yield self.media_repo.generate_local_exact_thumbnail(
media_id, desired_width, desired_height, desired_method, desired_type
media_id, desired_width, desired_height, desired_method, desired_type,
url_cache=media_info["url_cache"],
)
if file_path: