2017-05-15 18:40:27 +00:00
|
|
|
defmodule Asciinema.Asciicast do
|
|
|
|
use Asciinema.Web, :model
|
2017-05-27 08:56:20 +00:00
|
|
|
alias Asciinema.{User, Asciicast}
|
|
|
|
alias Asciinema.PngGenerator.PngParams
|
|
|
|
|
|
|
|
@default_png_scale 2
|
|
|
|
@default_theme "asciinema"
|
2017-05-15 18:40:27 +00:00
|
|
|
|
|
|
|
schema "asciicasts" do
|
|
|
|
field :version, :integer
|
|
|
|
field :file, :string
|
2017-06-07 14:26:10 +00:00
|
|
|
field :terminal_columns, :integer
|
|
|
|
field :terminal_lines, :integer
|
2017-05-15 18:40:27 +00:00
|
|
|
field :stdout_data, :string
|
|
|
|
field :stdout_timing, :string
|
2017-05-16 12:54:13 +00:00
|
|
|
field :stdout_frames, :string
|
2017-05-15 18:40:27 +00:00
|
|
|
field :private, :boolean
|
|
|
|
field :secret_token, :string
|
2017-05-21 11:26:41 +00:00
|
|
|
field :duration, :float
|
2017-06-07 18:57:39 +00:00
|
|
|
field :title, :string
|
2017-05-27 08:56:20 +00:00
|
|
|
field :theme_name, :string
|
|
|
|
field :snapshot_at, :float
|
|
|
|
|
2017-06-07 14:26:10 +00:00
|
|
|
timestamps(inserted_at: :created_at)
|
|
|
|
|
2017-05-27 08:56:20 +00:00
|
|
|
belongs_to :user, User
|
2017-05-15 18:40:27 +00:00
|
|
|
end
|
|
|
|
|
2017-06-07 18:57:39 +00:00
|
|
|
def changeset(struct, attrs \\ %{}) do
|
2017-06-07 14:26:10 +00:00
|
|
|
struct
|
2017-06-07 18:57:39 +00:00
|
|
|
|> cast(attrs, [:title])
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_changeset(struct, attrs) do
|
|
|
|
struct
|
|
|
|
|> changeset(attrs)
|
|
|
|
|> cast(attrs, [:user_id, :version, :file, :duration, :terminal_columns, :terminal_lines])
|
|
|
|
|> generate_secret_token
|
2017-06-07 14:26:10 +00:00
|
|
|
|> validate_required([:user_id, :version, :duration, :terminal_columns, :terminal_lines, :secret_token])
|
|
|
|
end
|
|
|
|
|
2017-06-07 18:57:39 +00:00
|
|
|
defp generate_secret_token(changeset) do
|
|
|
|
put_change(changeset, :secret_token, random_token(25))
|
|
|
|
end
|
|
|
|
|
|
|
|
defp random_token(length) do
|
|
|
|
length
|
|
|
|
|> :crypto.strong_rand_bytes
|
|
|
|
|> Base.url_encode64
|
|
|
|
|> String.replace(~r/[_=-]/, "")
|
|
|
|
|> binary_part(0, length)
|
|
|
|
end
|
|
|
|
|
2017-05-15 18:40:27 +00:00
|
|
|
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
|
2017-05-16 12:54:13 +00:00
|
|
|
|
|
|
|
def json_store_path(%__MODULE__{id: id, file: file}) when is_binary(file) do
|
|
|
|
"asciicast/file/#{id}/#{file}"
|
|
|
|
end
|
|
|
|
def json_store_path(%__MODULE__{id: id, stdout_frames: stdout_frames}) when is_binary(stdout_frames) do
|
|
|
|
"asciicast/stdout_frames/#{id}/#{stdout_frames}"
|
|
|
|
end
|
2017-05-27 08:56:20 +00:00
|
|
|
|
|
|
|
def snapshot_at(%Asciicast{snapshot_at: snapshot_at, duration: duration}) do
|
|
|
|
snapshot_at || duration / 2
|
|
|
|
end
|
|
|
|
|
|
|
|
def theme_name(%Asciicast{theme_name: a_theme_name}, %User{theme_name: u_theme_name}) do
|
|
|
|
a_theme_name || u_theme_name || @default_theme
|
|
|
|
end
|
|
|
|
|
|
|
|
def png_params(%Asciicast{} = asciicast, %User{} = user) do
|
|
|
|
%PngParams{snapshot_at: snapshot_at(asciicast),
|
|
|
|
theme: theme_name(asciicast, user),
|
|
|
|
scale: @default_png_scale}
|
|
|
|
end
|
2017-05-15 18:40:27 +00:00
|
|
|
end
|