diff --git a/lib/asciinema/asciicasts.ex b/lib/asciinema/asciicasts.ex index 842c783..0966a93 100644 --- a/lib/asciinema/asciicasts.ex +++ b/lib/asciinema/asciicasts.ex @@ -28,7 +28,7 @@ defmodule Asciinema.Asciicasts do file: filename, private: user.asciicasts_private_by_default} - files = [{:file, upload}] + files = [{:file, upload, true}] with {:ok, json} <- File.read(path), {:ok, attrs} <- Poison.decode(json), @@ -58,7 +58,7 @@ defmodule Asciinema.Asciicasts do attrs = Map.merge(attrs, overrides) attrs = if attrs[:uname], do: Map.drop(attrs, [:user_agent]), else: attrs changeset = Asciicast.create_changeset(asciicast, attrs) - files = [{:stdout_data, data}, {:stdout_timing, timing}] + files = [{:stdout_data, data, false}, {:stdout_timing, timing, false}] case do_create_asciicast(changeset, files) do {:ok, %Asciicast{} = asciicast} -> @@ -103,7 +103,7 @@ defmodule Asciinema.Asciicasts do {_, result} = Repo.transaction(fn -> case Repo.insert(changeset) do {:ok, %Asciicast{} = asciicast} -> - Enum.each(files, fn {type, upload} -> save_file(asciicast, type, upload) end) + Enum.each(files, &save_file(asciicast, &1)) {:ok, asciicast} otherwise -> otherwise @@ -113,9 +113,9 @@ defmodule Asciinema.Asciicasts do result end - defp save_file(asciicast, type, %{path: tmp_file_path, content_type: content_type}) do + defp save_file(asciicast, {type, %{path: tmp_path, content_type: content_type}, compress}) do file_store_path = Asciicast.file_store_path(asciicast, type) - :ok = FileStore.put_file(file_store_path, tmp_file_path, content_type) + :ok = FileStore.put_file(file_store_path, tmp_path, content_type, compress) end def stdout_stream(%Asciicast{version: 0} = asciicast) do diff --git a/lib/asciinema/file_store.ex b/lib/asciinema/file_store.ex index 0105ca2..32ea779 100644 --- a/lib/asciinema/file_store.ex +++ b/lib/asciinema/file_store.ex @@ -1,6 +1,6 @@ defmodule Asciinema.FileStore do @doc "Puts file at given path in store" - @callback put_file(dst_path :: String.t, src_local_path :: String.t, content_type :: String.t) :: :ok | {:error, term} + @callback put_file(dst_path :: String.t, src_local_path :: String.t, content_type :: String.t, compress :: boolean) :: :ok | {:error, term} @doc "Serves file at given path in store" @callback serve_file(conn :: %Plug.Conn{}, path :: String.t, filename :: String.t) :: %Plug.Conn{} @@ -29,8 +29,8 @@ defmodule Asciinema.FileStore do # Shortcuts - def put_file(dst_path, src_local_path, content_type) do - instance().put_file(dst_path, src_local_path, content_type) + def put_file(dst_path, src_local_path, content_type, compress \\ false) do + instance().put_file(dst_path, src_local_path, content_type, compress) end def open_file(path, f) do diff --git a/lib/asciinema/file_store/cached.ex b/lib/asciinema/file_store/cached.ex index e614a0b..fd92598 100644 --- a/lib/asciinema/file_store/cached.ex +++ b/lib/asciinema/file_store/cached.ex @@ -2,9 +2,9 @@ defmodule Asciinema.FileStore.Cached do use Asciinema.FileStore alias Plug.MIME - def put_file(dst_path, src_local_path, content_type) do - with :ok <- remote_store().put_file(dst_path, src_local_path, content_type), - :ok <- cache_store().put_file(dst_path, src_local_path, content_type) do + def put_file(dst_path, src_local_path, content_type, compress \\ false) do + with :ok <- remote_store().put_file(dst_path, src_local_path, content_type, compress), + :ok <- cache_store().put_file(dst_path, src_local_path, content_type, compress) do :ok else otherwise -> otherwise diff --git a/lib/asciinema/file_store/local.ex b/lib/asciinema/file_store/local.ex index 447ab1c..040ca2a 100644 --- a/lib/asciinema/file_store/local.ex +++ b/lib/asciinema/file_store/local.ex @@ -3,7 +3,7 @@ defmodule Asciinema.FileStore.Local do import Plug.Conn alias Plug.MIME - def put_file(dst_path, src_local_path, _content_type) do + def put_file(dst_path, src_local_path, _content_type, _compress \\ false) do full_dst_path = base_path() <> dst_path parent_dir = Path.dirname(full_dst_path) diff --git a/lib/asciinema/file_store/s3.ex b/lib/asciinema/file_store/s3.ex index bff6b55..8cef4fb 100644 --- a/lib/asciinema/file_store/s3.ex +++ b/lib/asciinema/file_store/s3.ex @@ -3,9 +3,16 @@ defmodule Asciinema.FileStore.S3 do import Phoenix.Controller, only: [redirect: 2] alias ExAws.S3 - def put_file(dst_path, src_local_path, content_type) do - body = File.read!(src_local_path) - opts = [{:content_type, content_type}] + def put_file(dst_path, src_local_path, content_type, compress \\ false) do + {body, opts} = if compress do + body = File.read!(src_local_path) |> :zlib.gzip + opts = [{:content_type, content_type}, {:content_encoding, "gzip"}] + {body, opts} + else + body = File.read!(src_local_path) + opts = [{:content_type, content_type}] + {body, opts} + end case make_request(S3.put_object(bucket(), base_path() <> dst_path, body, opts)) do {:ok, _} -> :ok @@ -33,7 +40,13 @@ defmodule Asciinema.FileStore.S3 do response = S3.get_object(bucket(), base_path() <> path) |> make_request case response do - {:ok, %{body: body}} -> + {:ok, %{headers: headers, body: body}} -> + body = + case List.keyfind(headers, "Content-Encoding", 0) do + {"Content-Encoding", "gzip"} -> :zlib.gunzip(body) + _ -> body + end + if function do File.open(body, [:ram, :binary, :read], function) else