web/models/custom_cast_downloader.ex
defmodule Caster.DownloaderBehaviour do
@moduledoc """
Used to define common behaviours for dowloaders
"""
@doc "fetches data from an external source"
@callback get_title(%{}) :: {:ok, term}
@callback get_filepath(%{}) :: {:ok, term}
@callback download!(%{}) :: {:ok}
end
defmodule Caster.CustomCastDownloader do
defmodule ProdClient do
@moduledoc """
This is the model for fetching records from youtubedl
"""
alias Caster.CustomCast
alias Caster.Cast
alias Caster.Repo
@behaviour Caster.DownloaderBehaviour
@download_subdirectory "custom"
def get_title(%CustomCast{url: url}) do
{title, 0} = System.cmd("youtube-dl", ["-e", url])
{:ok, String.trim_trailing(title)}
end
def get_info(%{url: url}) do
case System.cmd("youtube-dl", ["-J", "--flat-playlist", url]) do
{info, 0} -> Poison.Parser.parse! info
_ -> :error
end
end
def get_id(%{url: url}) do
{get_id, 0} = System.cmd("youtube-dl", ["--get-id", url])
get_id
|> String.trim
end
def get_filepath(%Cast{url: url}) do
{filepath, 0} = System.cmd("youtube-dl", ["--restrict-filenames", "--get-filename", url])
filepath = "#{get_id(%{url: url})}_#{filepath}"
# we are going to append our get_id to the start of the filename
filepath = Path.expand("#{Application.get_env(:caster, :root_downloads_directory)}/#{@download_subdirectory}/#{String.trim_trailing(filepath)}", Application.app_dir(:caster, "priv"))
{:ok, filepath}
end
def download!(cast = %Cast{url: url}) do
Task.Supervisor.async_nolink(Caster.TaskSupervisor, fn ->
{:ok, filepath} = get_filepath(cast)
Mix.Generator.create_directory(Path.dirname(filepath))
System.cmd("youtube-dl", ["-o", filepath, url])
# now the filepath may have been updated, so get the ID again.
id = get_id(%{url: url})
filepath = String.split(filepath, id)
|> List.first
|> Kernel.<>(id)
|> Kernel.<>("*")
|> Path.wildcard
|> List.first
changeset = CustomCast.changeset(cast, %{file_location: filepath})
Repo.update!(changeset)
# the broadcasting _really_ shouldn't be here.
Caster.Endpoint.broadcast("casts:cast#{cast.id}", "downloaded", %{msg: "downloaded"})
end)
end
end
defmodule TestClient do
@moduledoc """
This is the model for fetching records from youtubedl
"""
alias Caster.Cast
alias Caster.CustomCast
alias Caster.Repo
@behaviour Caster.DownloaderBehaviour
@download_subdirectory "custom"
def get_title(_) do
{:ok, "my happy title"}
end
def get_filepath(_) do
{:ok, "test/filepath"}
end
def download!(cast = %Cast{}) do
{:ok, filepath} = get_filepath(cast)
changeset = CustomCast.changeset(cast, %{file_location: filepath})
Repo.update!(changeset)
{:ok}
end
end
end