Skip to content

Commit 64a9184

Browse files
committed
Merge branch 'develop'
2 parents 24b5040 + f08ab26 commit 64a9184

File tree

23 files changed

+272
-230
lines changed

23 files changed

+272
-230
lines changed

assets/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assets/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"devDependencies": {
1313
"@babel/core": "^7.21.0",
1414
"@babel/preset-env": "^7.20.2",
15-
"asciinema-player": "3.8.0",
15+
"asciinema-player": "3.8.1",
1616
"babel-loader": "^8.3.0",
1717
"bootstrap": "^4.5.0",
1818
"copy-webpack-plugin": "^11.0.0",

config/test.exs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ config :asciinema, Asciinema.Repo,
99
pool: Ecto.Adapters.SQL.Sandbox,
1010
pool_size: 10
1111

12-
if db_url = System.get_env("TEST_DATABASE_URL") do
13-
System.put_env("DATABASE_URL", db_url)
14-
end
15-
1612
# In test we don't send emails.
1713
config :asciinema, Asciinema.Emails.Mailer, adapter: Swoosh.Adapters.Test
1814

flake.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
devShells.default = pkgs.mkShell {
2626
nativeBuildInputs = with pkgs; [
2727
otp.elixir_1_14
28+
otp.elixir-ls
2829
nodejs_18
29-
(rust-bin.stable."1.78.0".default)
30+
(rust-bin.stable."1.78.0".default.override { extensions = [ "rust-src" "rust-analyzer" ]; })
3031
inotify-tools
3132
librsvg
3233
];

lib/asciinema/recordings/snapshot.ex

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,13 @@ defmodule Asciinema.Recordings.Snapshot do
180180
case {k, v} do
181181
{"fg", c} when is_number(c) and c < 8 -> "3#{c}"
182182
{"fg", c} when is_number(c) -> "38;5;#{c}"
183-
{"fg", "rgb(" <> _} -> "38;2;#{parse_rgb(v)}"
183+
{"fg", "#" <> _} -> "38;2;#{parse_hex_color(v)}"
184+
{"fg", "rgb(" <> _} -> "38;2;#{parse_rgb_color(v)}"
184185
{"fg", [r, g, b]} -> "38;2;#{r};#{g};#{b}"
185186
{"bg", c} when is_number(c) and c < 8 -> "4#{c}"
186187
{"bg", c} when is_number(c) -> "48;5;#{c}"
187-
{"bg", "rgb(" <> _} -> "48;2;#{parse_rgb(v)}"
188+
{"bg", "#" <> _} -> "48;2;#{parse_hex_color(v)}"
189+
{"bg", "rgb(" <> _} -> "48;2;#{parse_rgb_color(v)}"
188190
{"bg", [r, g, b]} -> "48;2;#{r};#{g};#{b}"
189191
{"bold", true} -> "1"
190192
{"faint", true} -> "2"
@@ -200,7 +202,15 @@ defmodule Asciinema.Recordings.Snapshot do
200202

201203
defp sgr_params([]), do: []
202204

203-
defp parse_rgb("rgb(" <> c) do
205+
defp parse_hex_color(<<"#", r::binary-size(2), g::binary-size(2), b::binary-size(2)>>) do
206+
r = String.to_integer(r, 16)
207+
g = String.to_integer(g, 16)
208+
b = String.to_integer(b, 16)
209+
210+
"#{r};#{g};#{b}"
211+
end
212+
213+
defp parse_rgb_color("rgb(" <> c) do
204214
c
205215
|> String.slice(0, String.length(c) - 1)
206216
|> String.split(",")

lib/asciinema_web.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ defmodule AsciinemaWeb do
2626

2727
import Plug.Conn
2828
import AsciinemaWeb.Gettext
29-
import AsciinemaWeb.Router.Helpers.Extra
29+
import AsciinemaWeb.UrlHelpers
3030

3131
import AsciinemaWeb.Authentication,
3232
only: [require_current_user: 2, log_in: 2, log_out: 1, get_basic_auth: 1]
@@ -118,7 +118,7 @@ defmodule AsciinemaWeb do
118118
import AsciinemaWeb.ErrorHelpers
119119
alias AsciinemaWeb.Router.Helpers, as: Routes
120120

121-
import AsciinemaWeb.Router.Helpers.Extra
121+
import AsciinemaWeb.UrlHelpers
122122
import AsciinemaWeb.ApplicationView
123123

124124
# Routes generation with the ~p sigil
@@ -131,7 +131,7 @@ defmodule AsciinemaWeb do
131131
use Phoenix.Component
132132
import Phoenix.View
133133
import AsciinemaWeb.ApplicationView
134-
import AsciinemaWeb.Router.Helpers.Extra
134+
import AsciinemaWeb.UrlHelpers
135135

136136
# Include general helpers for rendering HTML
137137
unquote(html_helpers())
@@ -159,7 +159,7 @@ defmodule AsciinemaWeb do
159159
def json do
160160
quote do
161161
import AsciinemaWeb.ErrorHelpers
162-
import AsciinemaWeb.Router.Helpers.Extra
162+
import AsciinemaWeb.UrlHelpers
163163

164164
# Routes generation with the ~p sigil
165165
unquote(verified_routes())

lib/asciinema_web/controllers/api/live_stream_controller.ex

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
defmodule AsciinemaWeb.Api.LiveStreamController do
22
use AsciinemaWeb, :controller
33
alias Asciinema.{Accounts, Streaming}
4-
alias AsciinemaWeb.Router.Helpers.Extra, as: Routes
4+
alias AsciinemaWeb.UrlHelpers
55

66
plug :accepts, ~w(json)
77
plug :authenticate
88

99
def show(conn, params) do
10-
id = params["id"]
10+
get_stream(conn, params["id"])
11+
end
12+
13+
def create(conn, _params) do
14+
# TODO add mode (config option) where new streams are actually created here
15+
get_stream(conn, nil)
16+
end
1117

18+
defp get_stream(conn, id) do
1219
if stream = Streaming.get_live_stream(conn.assigns.current_user, id) do
1320
json(conn, %{
1421
url: url(~p"/s/#{stream}"),
15-
ws_producer_url: Routes.ws_producer_url(stream)
22+
ws_producer_url: UrlHelpers.ws_producer_url(stream)
1623
})
1724
else
1825
conn

lib/asciinema_web/controllers/recording_controller.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ defmodule AsciinemaWeb.RecordingController do
163163
conn
164164
|> put_layout("simple.html")
165165
|> render("gif.html",
166-
file_url: asciicast_file_url(conn, asciicast),
166+
file_url: asciicast_file_url(asciicast),
167167
asciicast_id: asciicast.id
168168
)
169169
end

lib/asciinema_web/controllers/session_controller.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ defmodule AsciinemaWeb.SessionController do
5353
conn
5454
|> log_out()
5555
|> put_flash(:info, "See you later!")
56-
|> redirect(to: root_path())
56+
|> redirect(to: ~p"/")
5757
end
5858
end

lib/asciinema_web/controllers/username_html/new.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<br />
66

77
<p>
8-
Every asciinema user gets a profile page at <a href="#"><%= root_url() %>/~<strong>username</strong></a>.
8+
Every asciinema user gets a profile page at <a href="#"><%= url(~p"/") %>/~<strong>username</strong></a>.
99
</p>
1010

1111
<.form :let={f} for={@changeset} action={~p"/username"} class="username-form" method="post">

lib/asciinema_web/trailing_format.ex renamed to lib/asciinema_web/plug/trailing_format.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule AsciinemaWeb.TrailingFormat do
1+
defmodule AsciinemaWeb.Plug.TrailingFormat do
22
@known_exts ["js", "json", "cast", "txt", "svg", "png", "gif", "xml"]
33

44
def init(opts), do: opts

lib/asciinema_web/router.ex

Lines changed: 11 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,12 @@ defmodule AsciinemaWeb.Router do
1212
end
1313

1414
pipeline :asciicast do
15-
plug AsciinemaWeb.TrailingFormat
15+
plug AsciinemaWeb.Plug.TrailingFormat
1616
plug :accepts, ["html", "js", "json", "cast", "txt", "svg", "png", "gif"]
1717
plug :format_specific_plugs
1818
plug :put_secure_browser_headers
1919
end
2020

21-
defp format_specific_plugs(conn, []) do
22-
format_specific_plugs(conn, Phoenix.Controller.get_format(conn))
23-
end
24-
25-
defp format_specific_plugs(conn, "html") do
26-
conn
27-
|> fetch_session([])
28-
|> fetch_flash([])
29-
|> protect_from_forgery([])
30-
|> AsciinemaWeb.Plug.Authn.call([])
31-
end
32-
33-
defp format_specific_plugs(conn, _other), do: conn
34-
3521
pipeline :oembed do
3622
plug :accepts, ["json", "xml"]
3723
plug :put_secure_browser_headers
@@ -97,6 +83,7 @@ defmodule AsciinemaWeb.Router do
9783

9884
scope "/api", AsciinemaWeb.Api, as: :api do
9985
post "/asciicasts", RecordingController, :create
86+
post "/streams", LiveStreamController, :create
10087

10188
scope "/user" do
10289
get "/stream", LiveStreamController, :show
@@ -110,76 +97,18 @@ defmodule AsciinemaWeb.Router do
11097
forward "/mailbox", Plug.Swoosh.MailboxPreview
11198
end
11299
end
113-
end
114-
115-
defmodule AsciinemaWeb.Router.Helpers.Extra do
116-
alias AsciinemaWeb.Router.Helpers, as: H
117-
alias AsciinemaWeb.Endpoint
118-
119-
def root_path do
120-
Endpoint.path("/")
121-
end
122-
123-
def root_url do
124-
Endpoint.url()
125-
end
126-
127-
def profile_path(_conn, user) do
128-
profile_path(user)
129-
end
130100

131-
def profile_path(%Plug.Conn{} = conn) do
132-
profile_path(conn.assigns.current_user)
133-
end
134-
135-
def profile_path(%{id: id, username: username}) do
136-
if username do
137-
Endpoint.path("/~#{username}")
138-
else
139-
Endpoint.path("/u/#{id}")
140-
end
141-
end
142-
143-
def profile_url(user) do
144-
Endpoint.url() <> profile_path(user)
145-
end
146-
147-
def asciicast_file_path(conn, asciicast) do
148-
H.recording_path(conn, :show, asciicast) <> "." <> ext(asciicast)
149-
end
150-
151-
def asciicast_file_url(asciicast) do
152-
asciicast_file_url(AsciinemaWeb.Endpoint, asciicast)
153-
end
154-
155-
def asciicast_file_url(conn, asciicast) do
156-
H.recording_url(conn, :show, asciicast) <> "." <> ext(asciicast)
157-
end
158-
159-
@http_to_ws %{"http" => "ws", "https" => "wss"}
160-
161-
def ws_producer_url(stream) do
162-
uri = Endpoint.struct_url()
163-
scheme = @http_to_ws[uri.scheme]
164-
path = "/ws/S/#{stream.producer_token}"
165-
166-
to_string(%{uri | scheme: scheme, path: path})
101+
defp format_specific_plugs(conn, []) do
102+
format_specific_plugs(conn, Phoenix.Controller.get_format(conn))
167103
end
168104

169-
def ws_public_url(stream) do
170-
uri = Endpoint.struct_url()
171-
scheme = @http_to_ws[uri.scheme]
172-
param = Phoenix.Param.to_param(stream)
173-
path = "/ws/s/#{param}"
174-
175-
to_string(%{uri | scheme: scheme, path: path})
105+
defp format_specific_plugs(conn, "html") do
106+
conn
107+
|> fetch_session([])
108+
|> fetch_flash([])
109+
|> protect_from_forgery([])
110+
|> AsciinemaWeb.Plug.Authn.call([])
176111
end
177112

178-
defp ext(asciicast) do
179-
case asciicast.version do
180-
0 -> "json"
181-
1 -> "json"
182-
_ -> "cast"
183-
end
184-
end
113+
defp format_specific_plugs(conn, _other), do: conn
185114
end

lib/asciinema_web/templates/layout/_header.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<header>
22
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
33
<div class="container">
4-
<a class="navbar-brand" href={root_path()}>
4+
<a class="navbar-brand" href={~p"/"}>
55
<img src={Routes.static_path(@conn, "/images/logo-red.svg")} />
66
</a>
77

lib/asciinema_web/url_helpers.ex

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
defmodule AsciinemaWeb.UrlHelpers do
2+
use Phoenix.VerifiedRoutes,
3+
endpoint: AsciinemaWeb.Endpoint,
4+
router: AsciinemaWeb.Router
5+
6+
alias AsciinemaWeb.Endpoint
7+
8+
def profile_path(_conn, user), do: profile_path(user)
9+
10+
def profile_path(%Plug.Conn{} = conn), do: profile_path(conn.assigns.current_user)
11+
12+
def profile_path(%{id: id, username: username}) do
13+
if username do
14+
~p"/~#{username}"
15+
else
16+
~p"/u/#{id}"
17+
end
18+
end
19+
20+
def profile_url(user) do
21+
Endpoint.url() <> profile_path(user)
22+
end
23+
24+
def asciicast_file_path(asciicast) do
25+
~p"/a/#{asciicast}" <> "." <> ext(asciicast)
26+
end
27+
28+
def asciicast_file_url(asciicast) do
29+
url(~p"/a/#{asciicast}") <> "." <> ext(asciicast)
30+
end
31+
32+
defp ext(asciicast) do
33+
case asciicast.version do
34+
1 -> "json"
35+
2 -> "cast"
36+
end
37+
end
38+
39+
@http_to_ws %{"http" => "ws", "https" => "wss"}
40+
41+
def ws_producer_url(stream) do
42+
uri = Endpoint.struct_url()
43+
scheme = @http_to_ws[uri.scheme]
44+
path = "/ws/S/#{stream.producer_token}"
45+
46+
to_string(%{uri | scheme: scheme, path: path})
47+
end
48+
49+
def ws_public_url(stream) do
50+
uri = Endpoint.struct_url()
51+
scheme = @http_to_ws[uri.scheme]
52+
param = Phoenix.Param.to_param(stream)
53+
path = "/ws/s/#{param}"
54+
55+
to_string(%{uri | scheme: scheme, path: path})
56+
end
57+
end

lib/asciinema_web/views/media_view.ex

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ defmodule AsciinemaWeb.MediaView do
2424
profile_path(user)
2525
end
2626

27-
def author_profile_url(%{user: user}) do
28-
profile_url(user)
29-
end
30-
3127
def theme_options do
3228
for theme <- Themes.terminal_themes() do
3329
{Themes.display_name(theme), theme}

0 commit comments

Comments
 (0)