defp handle_preview(conn, url) do
with {:ok, %{status: status} = head_response} when status in 200..299 <-
- Tesla.head(url, opts: [adapter: [timeout: preview_head_request_timeout()]]) do
+ Tesla.head(url,
+ opts: [adapter: [timeout: preview_head_request_timeout(), follow_redirect: true]]
+ ) do
content_type = Tesla.get_header(head_response, "content-type")
handle_preview(content_type, conn, url)
else
end
end
+ # TODO: find a workaround so avatar_static and banner_static can work.
+ # Those only permit GIFs for animation, so we have to permit a way to
+ # allow those to get real static variants.
+ defp handle_preview("image/gif" = _content_type, conn, url) do
+ mediaproxy_url = url |> MediaProxy.url()
+
+ redirect(conn, external: mediaproxy_url)
+ end
+
+ defp handle_preview("image/png" <> _ = _content_type, conn, url) do
+ handle_png_preview(conn, url)
+ end
+
defp handle_preview("image/" <> _ = _content_type, conn, url) do
- handle_image_preview(conn, url)
+ handle_jpeg_preview(conn, url)
end
defp handle_preview("video/" <> _ = _content_type, conn, url) do
- mediaproxy_url = url |> MediaProxy.url()
-
- redirect(conn, external: mediaproxy_url)
+ handle_video_preview(conn, url)
end
defp handle_preview(content_type, conn, _url) do
send_resp(conn, :unprocessable_entity, "Unsupported content type: #{content_type}.")
end
- defp handle_image_preview(%{params: params} = conn, url) do
+ defp handle_png_preview(%{params: params} = conn, url) do
+ quality = Config.get!([:media_preview_proxy, :image_quality])
+
+ with {thumbnail_max_width, thumbnail_max_height} <- thumbnail_max_dimensions(params),
+ {:ok, thumbnail_binary} <-
+ MediaHelper.image_resize(
+ url,
+ %{
+ max_width: thumbnail_max_width,
+ max_height: thumbnail_max_height,
+ quality: quality,
+ format: "png"
+ }
+ ) do
+ conn
+ |> put_resp_header("content-type", "image/png")
+ |> put_resp_header("content-disposition", "inline; filename=\"preview.png\"")
+ |> send_resp(200, thumbnail_binary)
+ else
+ _ ->
+ send_resp(conn, :failed_dependency, "Can't handle preview.")
+ end
+ end
+
+ defp handle_jpeg_preview(%{params: params} = conn, url) do
quality = Config.get!([:media_preview_proxy, :image_quality])
with {thumbnail_max_width, thumbnail_max_height} <- thumbnail_max_dimensions(params),
end
end
+ defp handle_video_preview(conn, url) do
+ with {:ok, thumbnail_binary} <-
+ MediaHelper.video_framegrab(url) do
+ conn
+ |> put_resp_header("content-type", "image/jpeg")
+ |> put_resp_header("content-disposition", "inline; filename=\"preview.jpg\"")
+ |> send_resp(200, thumbnail_binary)
+ else
+ _ ->
+ send_resp(conn, :failed_dependency, "Can't handle preview.")
+ end
+ end
+
defp thumbnail_max_dimensions(params) do
config = Config.get([:media_preview_proxy], [])