diff --git a/synapse/media/v1/base_resource.py b/synapse/media/v1/base_resource.py
index 1e57a1465f..81f2456343 100644
--- a/synapse/media/v1/base_resource.py
+++ b/synapse/media/v1/base_resource.py
@@ -37,6 +37,7 @@ class BaseMediaResource(Resource):
def __init__(self, hs, filepaths):
Resource.__init__(self)
+ self.auth = hs.get_auth()
self.client = hs.get_http_client()
self.clock = hs.get_clock()
self.server_name = hs.hostname
@@ -120,6 +121,12 @@ class BaseMediaResource(Resource):
send_cors=True
)
+ @staticmethod
+ def _makedirs(filepath):
+ dirname = os.path.dirname(filepath)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
@defer.inlineCallbacks
def _download_remote_file(self, server_name, media_id):
file_id = random_string(24)
@@ -127,13 +134,13 @@ class BaseMediaResource(Resource):
fname = self.filepaths.remote_media_filepath(
server_name, file_id
)
- os.makedirs(os.path.dirname(fname))
+ self._makedirs(fname)
try:
with open(fname, "wb") as f:
request_path = "/".join((
"/_matrix/media/v1/download", server_name, media_id,
- )),
+ ))
length, headers = yield self.client.get_file(
server_name, request_path, output_stream=f,
)
@@ -147,7 +154,7 @@ class BaseMediaResource(Resource):
time_now_ms=self.clock.time_msec(),
upload_name=None,
media_length=length,
- file_id=file_id,
+ filesystem_id=file_id,
)
except:
os.remove(fname)
@@ -158,7 +165,7 @@ class BaseMediaResource(Resource):
"media_length": length,
"upload_name": None,
"created_ts": time_now_ms,
- "file_id": file_id,
+ "filesystem_id": file_id,
}
yield self._generate_remote_thumbnails(
@@ -215,7 +222,7 @@ class BaseMediaResource(Resource):
if not requirements:
return
- input_path = self.filepaths.local_media_path(media_id)
+ input_path = self.filepaths.local_media_filepath(media_id)
thumbnailer = Thumbnailer(input_path)
m_width = thumbnailer.width
m_height = thumbnailer.height
@@ -235,6 +242,7 @@ class BaseMediaResource(Resource):
t_path = self.filepaths.local_media_thumbnail(
media_id, t_width, t_height, t_type, t_method
)
+ self._makedirs(t_path)
t_len = thumbnailer.scale(t_path, t_width, t_height, t_type)
yield self.store.store_local_thumbnail(
media_id, t_width, t_height, t_type, t_method, t_len
@@ -250,6 +258,7 @@ class BaseMediaResource(Resource):
t_path = self.filepaths.local_media_thumbnail(
media_id, t_width, t_height, t_type, t_method
)
+ self._makedirs(t_path)
t_len = thumbnailer.crop(t_path, t_width, t_height, t_type)
yield self.store.store_local_thumbnail(
media_id, t_width, t_height, t_type, t_method, t_len
@@ -264,11 +273,11 @@ class BaseMediaResource(Resource):
def _generate_remote_thumbnails(self, server_name, media_id, media_info):
media_type = media_info["media_type"]
file_id = media_info["filesystem_id"]
- requirements = self._get_requirements(media_type)
+ requirements = self._get_thumbnail_requirements(media_type)
if not requirements:
return
- input_path = self.filepaths.remote_media_path(server_name, file_id)
+ input_path = self.filepaths.remote_media_filepath(server_name, file_id)
thumbnailer = Thumbnailer(input_path)
m_width = thumbnailer.width
m_height = thumbnailer.height
@@ -286,9 +295,9 @@ class BaseMediaResource(Resource):
for t_width, t_height, t_type in scales:
t_method = "scale"
t_path = self.filepaths.remote_media_thumbnail(
- server_name, media_id, file_id,
- media_id, t_width, t_height, t_type, t_method
+ server_name, file_id, t_width, t_height, t_type, t_method
)
+ self._makedirs(t_path)
t_len = thumbnailer.scale(t_path, t_width, t_height, t_type)
yield self.store.store_remote_media_thumbnail(
server_name, media_id, file_id,
@@ -303,9 +312,9 @@ class BaseMediaResource(Resource):
continue
t_method = "crop"
t_path = self.filepaths.remote_media_thumbnail(
- server_name, media_id, file_id,
- t_width, t_height, t_type, t_method
+ server_name, file_id, t_width, t_height, t_type, t_method
)
+ self._makedirs(t_path)
t_len = thumbnailer.crop(t_path, t_width, t_height, t_type)
yield self.store.store_remote_media_thumbnail(
server_name, media_id, file_id,
diff --git a/synapse/media/v1/download_resource.py b/synapse/media/v1/download_resource.py
index 31c6f25968..6de0932ba3 100644
--- a/synapse/media/v1/download_resource.py
+++ b/synapse/media/v1/download_resource.py
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from .base_media_resource import BaseMediaResource
+from .base_resource import BaseMediaResource
from twisted.web.server import NOT_DONE_YET
from twisted.internet import defer
@@ -52,7 +52,7 @@ class DownloadResource(BaseMediaResource):
media_type = media_info["media_type"]
file_path = self.filepaths.local_media_filepath(media_id)
- yield self.respond_with_file(request, media_type, file_path)
+ yield self._respond_with_file(request, media_type, file_path)
@defer.inlineCallbacks
def _respond_remote_file(self, request, server_name, media_id):
@@ -72,4 +72,4 @@ class DownloadResource(BaseMediaResource):
server_name, filesystem_id
)
- yield self.respond_with_file(request, media_type, file_path)
+ yield self._respond_with_file(request, media_type, file_path)
diff --git a/synapse/media/v1/media_repository.py b/synapse/media/v1/media_repository.py
index e0a4cd01ee..2bd29d2288 100644
--- a/synapse/media/v1/media_repository.py
+++ b/synapse/media/v1/media_repository.py
@@ -15,6 +15,7 @@
from .upload_resource import UploadResource
from .download_resource import DownloadResource
+from .thumbnail_resource import ThumbnailResource
from .filepath import MediaFilePaths
from twisted.web.resource import Resource
@@ -64,3 +65,4 @@ class MediaRepositoryResource(Resource):
filepaths = MediaFilePaths(hs.config.media_store_path)
self.putChild("upload", UploadResource(hs, filepaths))
self.putChild("download", DownloadResource(hs, filepaths))
+ self.putChild("thumbnail", ThumbnailResource(hs, filepaths))
diff --git a/synapse/media/v1/thumbnail_resource.py b/synapse/media/v1/thumbnail_resource.py
index 331ba87e00..fd08c7ecd2 100644
--- a/synapse/media/v1/thumbnail_resource.py
+++ b/synapse/media/v1/thumbnail_resource.py
@@ -14,7 +14,7 @@
# limitations under the License.
-from .base_media_resource import BaseMediaResource
+from .base_resource import BaseMediaResource
from twisted.web.server import NOT_DONE_YET
from twisted.internet import defer
@@ -59,26 +59,25 @@ class ThumbnailResource(BaseMediaResource):
self._respond_404(request)
return
- thumbnail_infos = yield self.store.get_local_thumbnail(media_id)
+ thumbnail_infos = yield self.store.get_local_media_thumbnails(media_id)
if thumbnail_infos:
thumbnail_info = self._select_thumbnail(
width, height, method, m_type, thumbnail_infos
)
- thumbnail_width = thumbnail_info["thumbnail_width"]
- thumbnail_height = thumbnail_info["thumbnail_height"]
- thumbnail_type = thumbnail_info["thumbnail_type"]
- thumbnail_method = thumbnail_info["thumbnail_method"]
+ t_width = thumbnail_info["thumbnail_width"]
+ t_height = thumbnail_info["thumbnail_height"]
+ t_type = thumbnail_info["thumbnail_type"]
+ t_method = thumbnail_info["thumbnail_method"]
file_path = self.filepaths.local_media_thumbnail(
- media_id, thumbnail_width, thumbnail_height, thumbnail_type,
- thumbnail_method,
+ media_id, t_width, t_height, t_type, t_method,
)
- yield self._respond_with_file(request, thumbnail_type, file_path)
+ yield self._respond_with_file(request, t_type, file_path)
else:
yield self._respond_default_thumbnail(
- self, request, media_info, width, height, method, m_type,
+ request, media_info, width, height, method, m_type,
)
@defer.inlineCallbacks
@@ -103,19 +102,19 @@ class ThumbnailResource(BaseMediaResource):
thumbnail_info = self._select_thumbnail(
width, height, method, m_type, thumbnail_infos
)
- thumbnail_width = thumbnail_info["thumbnail_width"]
- thumbnail_height = thumbnail_info["thumbnail_height"]
- thumbnail_type = thumbnail_info["thumbnail_type"]
- thumbnail_method = thumbnail_info["thumbnail_method"]
+ t_width = thumbnail_info["thumbnail_width"]
+ t_height = thumbnail_info["thumbnail_height"]
+ t_type = thumbnail_info["thumbnail_type"]
+ t_method = thumbnail_info["thumbnail_method"]
+ file_id = thumbnail_info["filesystem_id"]
file_path = self.filepaths.remote_media_thumbnail(
- server_name, media_id, thumbnail_width, thumbnail_height,
- thumbnail_type, thumbnail_method,
+ server_name, file_id, t_width, t_height, t_type, t_method,
)
- yield self._respond_with_file(request, thumbnail_type, file_path)
+ yield self._respond_with_file(request, t_type, file_path)
else:
yield self._respond_default_thumbnail(
- self, request, media_info, width, height, method, m_type,
+ request, media_info, width, height, method, m_type,
)
@defer.inlineCallbacks
@@ -143,16 +142,15 @@ class ThumbnailResource(BaseMediaResource):
width, height, "crop", m_type, thumbnail_infos
)
- thumbnail_width = thumbnail_info["thumbnail_width"]
- thumbnail_height = thumbnail_info["thumbnail_height"]
- thumbnail_type = thumbnail_info["thumbnail_type"]
- thumbnail_method = thumbnail_info["thumbnail_method"]
+ t_width = thumbnail_info["thumbnail_width"]
+ t_height = thumbnail_info["thumbnail_height"]
+ t_type = thumbnail_info["thumbnail_type"]
+ t_method = thumbnail_info["thumbnail_method"]
file_path = self.filepaths.default_thumbnail(
- top_level_type, sub_type, thumbnail_width, thumbnail_height,
- thumbnail_type, thumbnail_method,
+ top_level_type, sub_type, t_width, t_height, t_type, t_method,
)
- yield self.respond_with_file(request, thumbnail_type, file_path)
+ yield self.respond_with_file(request, t_type, file_path)
def _select_thumbnail(self, desired_width, desired_height, desired_method,
desired_type, thumbnail_infos):
@@ -164,7 +162,7 @@ class ThumbnailResource(BaseMediaResource):
for info in thumbnail_infos:
t_w = info["thumbnail_width"]
t_h = info["thumbnail_height"]
- t_method = info["thumnail_method"]
+ t_method = info["thumbnail_method"]
if t_method == "scale" or t_method == "crop":
aspect_quality = abs(d_w * t_h - d_h * t_w)
size_quality = abs((d_w - t_w) * (d_h - t_h))
@@ -180,7 +178,7 @@ class ThumbnailResource(BaseMediaResource):
for info in thumbnail_infos:
t_w = info["thumbnail_width"]
t_h = info["thumbnail_height"]
- t_method = info["thumnail_method"]
+ t_method = info["thumbnail_method"]
if t_method == "scale" and (t_w >= d_w or t_h >= d_h):
size_quality = abs((d_w - t_w) * (d_h - t_h))
type_quality = desired_type != info["thumbnail_type"]
diff --git a/synapse/media/v1/upload_resource.py b/synapse/media/v1/upload_resource.py
index a78cc3cff3..b2449ff03d 100644
--- a/synapse/media/v1/upload_resource.py
+++ b/synapse/media/v1/upload_resource.py
@@ -23,9 +23,7 @@ from synapse.api.errors import (
from twisted.web.server import NOT_DONE_YET
from twisted.internet import defer
-from .baseresource import BaseMediaResource
-
-import os
+from .base_resource import BaseMediaResource
import logging
@@ -75,7 +73,7 @@ class UploadResource(BaseMediaResource):
media_id = random_string(24)
fname = self.filepaths.local_media_filepath(media_id)
- os.makedirs(os.path.dirname(fname))
+ self._makedirs(fname)
# This shouldn't block for very long because the content will have
# already been uploaded at this point.
@@ -95,7 +93,7 @@ class UploadResource(BaseMediaResource):
"media_length": content_length,
}
- yield self._generate_local_thumbnails(self, media_id, media_info)
+ yield self._generate_local_thumbnails(media_id, media_info)
respond_with_json(
request, 200, {"content_token": media_id}, send_cors=True
diff --git a/synapse/storage/media_repository.py b/synapse/storage/media_repository.py
index a848662716..18c068d3d9 100644
--- a/synapse/storage/media_repository.py
+++ b/synapse/storage/media_repository.py
@@ -19,6 +19,9 @@ from _base import SQLBaseStore
class MediaRepositoryStore(SQLBaseStore):
"""Persistence for attachments and avatars"""
+ def get_default_thumbnails(self, top_level_type, sub_type):
+ return []
+
def get_local_media(self, media_id):
"""Get the metadata for a local piece of media
Returns:
@@ -47,7 +50,7 @@ class MediaRepositoryStore(SQLBaseStore):
def get_local_media_thumbnails(self, media_id):
return self._simple_select_list(
- "local_media_thumbnails",
+ "local_media_repository_thumbnails",
{"media_id": media_id},
(
"thumbnail_width", "thumbnail_height", "thumbnail_method",
@@ -59,7 +62,7 @@ class MediaRepositoryStore(SQLBaseStore):
thumbnail_height, thumbnail_type,
thumbnail_method, thumbnail_length):
return self._simple_insert(
- "local_media_thumbnails",
+ "local_media_repository_thumbnails",
{
"media_id": media_id,
"thumbnail_width": thumbnail_width,
@@ -100,11 +103,10 @@ class MediaRepositoryStore(SQLBaseStore):
def get_remote_media_thumbnails(self, origin, media_id):
return self._simple_select_list(
"remote_media_cache_thumbnails",
- {"origin": origin, "media_id": media_id},
+ {"media_origin": origin, "media_id": media_id},
(
- "thumbnail_width", "thumbnail_height", "thumbnail_method"
- "thumbnail_type", "thumbnail_length",
- "filesystem_id"
+ "thumbnail_width", "thumbnail_height", "thumbnail_method",
+ "thumbnail_type", "thumbnail_length", "filesystem_id",
)
)
|