Store and serve asciicast json files gzipped

new-login
Marcin Kulik 7 years ago
parent 370e1702eb
commit 6c36e0de43

@ -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

@ -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

@ -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

@ -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)

@ -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

Loading…
Cancel
Save