From b1aebceda24d6ba1c9c86fb5846946cc8917e28a Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Mon, 15 May 2017 20:40:27 +0200 Subject: [PATCH] Show asciicast2gif instructions when request for .gif --- brunch-config.js | 3 +- docker/nginx/asciinema.conf | 4 +++ lib/asciinema/endpoint.ex | 2 ++ lib/asciinema/trailing_format.ex | 28 +++++++++++++++++++ .../asciicast_animation_controller.ex | 12 ++++++++ web/models/asciicast.ex | 25 +++++++++++++++++ web/router.ex | 13 +++++++-- web/static/css/simple-layout.sass | 18 ++++++++++++ .../asciicast_animation/show.html.eex | 14 ++++++++++ web/templates/layout/simple.html.eex | 23 +++++++++++++++ web/views/asciicast_animation_view.ex | 7 +++++ 11 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 lib/asciinema/trailing_format.ex create mode 100644 web/controllers/asciicast_animation_controller.ex create mode 100644 web/models/asciicast.ex create mode 100644 web/static/css/simple-layout.sass create mode 100644 web/templates/asciicast_animation/show.html.eex create mode 100644 web/templates/layout/simple.html.eex create mode 100644 web/views/asciicast_animation_view.ex diff --git a/brunch-config.js b/brunch-config.js index b1f25e6..70e3a9a 100644 --- a/brunch-config.js +++ b/brunch-config.js @@ -34,7 +34,8 @@ exports.config = { "web/static/css/users.sass", "web/static/css/preview.sass", "web/static/css/player.sass", - "web/static/css/contributing.sass" + "web/static/css/contributing.sass", + "web/static/css/simple-layout.sass", ] } }, diff --git a/docker/nginx/asciinema.conf b/docker/nginx/asciinema.conf index 19bedde..7b313c7 100644 --- a/docker/nginx/asciinema.conf +++ b/docker/nginx/asciinema.conf @@ -28,6 +28,10 @@ server { try_files $uri $uri/index.html $uri.html @clj; } + location ~ ^/a/[^.]+\.gif$ { + try_files $uri $uri/index.html $uri.html @phoenix; + } + location / { try_files $uri $uri/index.html $uri.html @rails; } diff --git a/lib/asciinema/endpoint.ex b/lib/asciinema/endpoint.ex index 6c857f9..f221ed4 100644 --- a/lib/asciinema/endpoint.ex +++ b/lib/asciinema/endpoint.ex @@ -41,5 +41,7 @@ defmodule Asciinema.Endpoint do key_digest: :sha, serializer: Poison + plug Asciinema.TrailingFormat + plug Asciinema.Router end diff --git a/lib/asciinema/trailing_format.ex b/lib/asciinema/trailing_format.ex new file mode 100644 index 0000000..f07103a --- /dev/null +++ b/lib/asciinema/trailing_format.ex @@ -0,0 +1,28 @@ +defmodule Asciinema.TrailingFormat do + @known_extensions ["json", "png", "gif"] + + def init(opts), do: opts + + def call(conn, _opts) do + case conn.path_info do + [] -> + conn + path_info -> + %{conn | path_info: rewrite_path_info(path_info)} + end + end + + defp rewrite_path_info(path_info) do + path_info + |> List.last + |> String.split(".") + |> Enum.reverse + |> case do + [format | fragments] when format in @known_extensions -> + id = fragments |> Enum.reverse |> Enum.join(".") + path_info |> List.replace_at(-1, id) |> List.insert_at(-1, format) + _ -> + path_info + end + end +end diff --git a/web/controllers/asciicast_animation_controller.ex b/web/controllers/asciicast_animation_controller.ex new file mode 100644 index 0000000..b72a98c --- /dev/null +++ b/web/controllers/asciicast_animation_controller.ex @@ -0,0 +1,12 @@ +defmodule Asciinema.AsciicastAnimationController do + use Asciinema.Web, :controller + alias Asciinema.{Repo, Asciicast} + + def show(conn, %{"id" => id}) do + asciicast = Repo.one!(Asciicast.by_id_or_secret_token(id)) + + conn + |> put_layout("simple.html") + |> render("show.html", asciicast: asciicast) + end +end diff --git a/web/models/asciicast.ex b/web/models/asciicast.ex new file mode 100644 index 0000000..86df24c --- /dev/null +++ b/web/models/asciicast.ex @@ -0,0 +1,25 @@ +defmodule Asciinema.Asciicast do + use Asciinema.Web, :model + + schema "asciicasts" do + field :version, :integer + field :file, :string + field :stdout_data, :string + field :stdout_timing, :string + field :private, :boolean + field :secret_token, :string + end + + def by_id_or_secret_token(thing) do + if String.length(thing) == 25 do + from a in __MODULE__, where: a.secret_token == ^thing + else + case Integer.parse(thing) do + {id, ""} -> + from a in __MODULE__, where: a.private == false and a.id == ^id + :error -> + from a in __MODULE__, where: a.id == -1 # TODO fixme + end + end + end +end diff --git a/web/router.ex b/web/router.ex index 48fe0e1..a873d0f 100644 --- a/web/router.ex +++ b/web/router.ex @@ -10,13 +10,22 @@ defmodule Asciinema.Router do plug Asciinema.Auth end - pipeline :api do - plug :accepts, ["json"] + pipeline :asciicast_animation do + plug :accepts, ["html"] + end + + scope "/", Asciinema do + pipe_through :asciicast_animation + + # rewritten by TrailingFormat from /a/123.gif to /a/123/gif + get "/a/:id/gif", AsciicastAnimationController, :show end scope "/", Asciinema do pipe_through :browser # Use the default browser stack + get "/a/:id", AsciicastController, :show + get "/docs", DocController, :index get "/docs/:topic", DocController, :show end diff --git a/web/static/css/simple-layout.sass b/web/static/css/simple-layout.sass new file mode 100644 index 0000000..65f1e48 --- /dev/null +++ b/web/static/css/simple-layout.sass @@ -0,0 +1,18 @@ +.simple-layout + margin-top: 30px + margin-left: 24px + margin-right: 24px + + p + font-size: 20px + + pre + font-size: 16px + overflow: auto + white-space: pre + + p, pre + margin-bottom: 24px + + h1 + margin-bottom: 40px diff --git a/web/templates/asciicast_animation/show.html.eex b/web/templates/asciicast_animation/show.html.eex new file mode 100644 index 0000000..8dcc234 --- /dev/null +++ b/web/templates/asciicast_animation/show.html.eex @@ -0,0 +1,14 @@ +

Looking for GIF?

+ +

While we cannot automatically generate GIF from this asciicast (the process + is very resource intensive), you can use asciicast2gif to do it + yourself. Once you have it installed run the following command in your + terminal:

+ +
asciicast2gif <%= asciicast_file_url(@conn, @asciicast) %> demo.gif 
+ +

If you have Docker installed then just + run this command:

+ +
docker run --rm -v $PWD:/data asciinema/asciicast2gif <%= asciicast_file_url(@conn, @asciicast) %> demo.gif
diff --git a/web/templates/layout/simple.html.eex b/web/templates/layout/simple.html.eex new file mode 100644 index 0000000..7105c3b --- /dev/null +++ b/web/templates/layout/simple.html.eex @@ -0,0 +1,23 @@ + + + + + + + <%= page_title @conn %> + "> + "> + + + + + +
+
+
+ <%= render @view_module, @view_template, assigns %> +
+
+
+ + diff --git a/web/views/asciicast_animation_view.ex b/web/views/asciicast_animation_view.ex new file mode 100644 index 0000000..3273d9c --- /dev/null +++ b/web/views/asciicast_animation_view.ex @@ -0,0 +1,7 @@ +defmodule Asciinema.AsciicastAnimationView do + use Asciinema.Web, :view + + def asciicast_file_url(conn, asciicast) do + "#{asciicast_url(conn, :show, asciicast)}.json" # TODO: use route helper + end +end