Packages
livebook
0.19.1
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/open_live/url_component.ex
defmodule LivebookWeb.OpenLive.UrlComponent do
use LivebookWeb, :live_component
import Ecto.Changeset
@impl true
def mount(socket) do
{:ok, assign(socket, changeset: changeset(), error_message: nil)}
end
defp changeset(attrs \\ %{}) do
data = %{url: nil}
types = %{url: :string}
cast({data, types}, attrs, [:url])
|> validate_required([:url])
|> Livebook.Utils.validate_url(:url, allow_file_scheme: true)
|> Livebook.Utils.validate_not_s3_url(
:url,
~s{invalid s3:// URL scheme, you must first connect to the Cloud Storage in your Workspace page and then choose the relevant file in "From storage"}
)
end
@impl true
def update(assigns, socket) do
if url = assigns[:url] do
{:ok, do_import(socket, %{url: url})}
else
{:ok, socket}
end
end
@impl true
def render(assigns) do
~H"""
<div class="flex-col space-y-5">
<div :if={@error_message} class="error-box">
{@error_message}
</div>
<p class="text-gray-700" id="import-from-url">
Paste the URL to a .livemd file, to a GitHub file, or to a Gist.
</p>
<.form
:let={f}
for={@changeset}
as={:data}
phx-submit="import"
phx-change="validate"
phx-target={@myself}
autocomplete="off"
>
<.text_field
field={f[:url]}
label="Notebook URL"
autofocus
aria-labelledby="import-from-url"
spellcheck="false"
/>
<div class="mt-5">
<.button type="submit" disabled={not @changeset.valid?}>
Import
</.button>
</div>
</.form>
</div>
"""
end
@impl true
def handle_event("validate", %{"data" => data}, socket) do
changeset = data |> changeset() |> Map.replace!(:action, :validate)
{:noreply, assign(socket, changeset: changeset)}
end
def handle_event("import", %{"data" => data}, socket) do
{:noreply, do_import(socket, data)}
end
defp do_import(socket, data) do
data
|> changeset()
|> apply_action(:insert)
|> case do
{:ok, data} ->
origin = Livebook.Notebook.ContentLoader.url_to_location(data.url)
files_url = Livebook.Utils.expand_url(data.url, "files/")
origin
|> Livebook.Notebook.ContentLoader.fetch_content_from_location()
|> case do
{:ok, content} ->
opts = [origin: origin, files_source: {:url, files_url}]
send(self(), {:import_source, content, opts})
socket
{:error, message} ->
assign(socket,
changeset: changeset(data),
error_message: Livebook.Utils.upcase_first(message)
)
end
{:error, changeset} ->
assign(socket, changeset: changeset)
end
end
end