More renaming; renamed channel details module
This commit is contained in:
parent
d822aaa899
commit
2250695a3e
9 changed files with 64 additions and 64 deletions
2
.iex.exs
2
.iex.exs
|
|
@ -11,4 +11,4 @@ alias Pinchflat.Media
|
|||
alias Pinchflat.Profiles
|
||||
alias Pinchflat.MediaSource
|
||||
|
||||
alias Pinchflat.MediaClient.{ChannelDetails, VideoDownloader}
|
||||
alias Pinchflat.MediaClient.{SourceDetails, VideoDownloader}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ defmodule Pinchflat.Media do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Returns a list of pending media_items for a given channel, where
|
||||
Returns a list of pending media_items for a given source, where
|
||||
pending means the `media_filepath` is `nil`.
|
||||
|
||||
Returns [%MediaItem{}, ...].
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.Channel do
|
|||
"""
|
||||
|
||||
use Pinchflat.MediaClient.Backends.YtDlp.VideoCollection
|
||||
alias Pinchflat.MediaClient.ChannelDetails
|
||||
alias Pinchflat.MediaClient.SourceDetails
|
||||
|
||||
@doc """
|
||||
Gets a channel's ID and name from its URL.
|
||||
|
|
@ -13,14 +13,14 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.Channel do
|
|||
instead we're fetching just the first video (using playlist_end: 1)
|
||||
and parsing the channel ID and name from _its_ metadata
|
||||
|
||||
Returns {:ok, %ChannelDetails{}} | {:error, any, ...}.
|
||||
Returns {:ok, %SourceDetails{}} | {:error, any, ...}.
|
||||
"""
|
||||
def get_source_details(channel_url) do
|
||||
opts = [:skip_download, playlist_end: 1]
|
||||
|
||||
with {:ok, output} <- backend_runner().run(channel_url, opts, "%(.{channel,channel_id})j"),
|
||||
{:ok, parsed_json} <- Phoenix.json_library().decode(output) do
|
||||
{:ok, ChannelDetails.new(parsed_json["channel_id"], parsed_json["channel"])}
|
||||
{:ok, SourceDetails.new(parsed_json["channel_id"], parsed_json["channel"])}
|
||||
else
|
||||
err -> err
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
defmodule Pinchflat.MediaClient.ChannelDetails do
|
||||
defmodule Pinchflat.MediaClient.SourceDetails do
|
||||
@moduledoc """
|
||||
This is the integration layer for actually working with channels.
|
||||
This is the integration layer for actually working with sources.
|
||||
|
||||
Technically hardcodes the yt-dlp backend for now, but should leave
|
||||
it open-ish for future expansion (just in case).
|
||||
|
|
@ -16,24 +16,24 @@ defmodule Pinchflat.MediaClient.ChannelDetails do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Gets a channel's ID and name from its URL, using the given backend.
|
||||
Gets a source's ID and name from its URL, using the given backend.
|
||||
|
||||
Returns {:ok, map()} | {:error, any, ...}.
|
||||
"""
|
||||
def get_source_details(channel_url, backend \\ :yt_dlp) do
|
||||
channel_module(backend).get_source_details(channel_url)
|
||||
def get_source_details(source_url, backend \\ :yt_dlp) do
|
||||
source_module(backend).get_source_details(source_url)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns a list of video IDs for the given channel URL, using the given backend.
|
||||
Returns a list of video IDs for the given source URL, using the given backend.
|
||||
|
||||
Returns {:ok, list(binary())} | {:error, any, ...}.
|
||||
"""
|
||||
def get_video_ids(channel_url, backend \\ :yt_dlp) do
|
||||
channel_module(backend).get_video_ids(channel_url)
|
||||
def get_video_ids(source_url, backend \\ :yt_dlp) do
|
||||
source_module(backend).get_video_ids(source_url)
|
||||
end
|
||||
|
||||
defp channel_module(backend) do
|
||||
defp source_module(backend) do
|
||||
case backend do
|
||||
:yt_dlp -> YtDlpChannel
|
||||
end
|
||||
|
|
@ -10,25 +10,25 @@ defmodule Pinchflat.MediaSource do
|
|||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks.SourceTasks
|
||||
alias Pinchflat.MediaSource.Source
|
||||
alias Pinchflat.MediaClient.ChannelDetails
|
||||
alias Pinchflat.MediaClient.SourceDetails
|
||||
|
||||
@doc """
|
||||
Returns the list of channels. Returns [%Source{}, ...]
|
||||
Returns the list of sources. Returns [%Source{}, ...]
|
||||
"""
|
||||
def list_sources do
|
||||
Repo.all(Source)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single channel.
|
||||
Gets a single source.
|
||||
|
||||
Returns %Source{}. Raises `Ecto.NoResultsError` if the Channel does not exist.
|
||||
"""
|
||||
def get_source!(id), do: Repo.get!(Source, id)
|
||||
|
||||
@doc """
|
||||
Creates a channel. May attempt to pull additional channel details from the
|
||||
original_url (if provided). Will attempt to start indexing the channel's
|
||||
Creates a source. May attempt to pull additional source details from the
|
||||
original_url (if provided). Will attempt to start indexing the source's
|
||||
media if successfully inserted.
|
||||
|
||||
Returns {:ok, %Source{}} | {:error, %Ecto.Changeset{}}
|
||||
|
|
@ -46,7 +46,7 @@ defmodule Pinchflat.MediaSource do
|
|||
Returns [%MediaItem{}, ...] | [%Ecto.Changeset{}, ...]
|
||||
"""
|
||||
def index_media_items(%Source{} = source) do
|
||||
{:ok, media_ids} = ChannelDetails.get_video_ids(source.original_url)
|
||||
{:ok, media_ids} = SourceDetails.get_video_ids(source.original_url)
|
||||
|
||||
media_ids
|
||||
|> Enum.map(fn media_id ->
|
||||
|
|
@ -60,8 +60,8 @@ defmodule Pinchflat.MediaSource do
|
|||
end
|
||||
|
||||
@doc """
|
||||
Updates a channel. May attempt to pull additional channel details from the
|
||||
original_url (if changed). May attempt to start indexing the channel's
|
||||
Updates a source. May attempt to pull additional source details from the
|
||||
original_url (if changed). May attempt to start indexing the source's
|
||||
media if the indexing frequency has been changed.
|
||||
|
||||
Existing indexing tasks will be cancelled if the indexing frequency has been
|
||||
|
|
@ -69,58 +69,58 @@ defmodule Pinchflat.MediaSource do
|
|||
|
||||
Returns {:ok, %Source{}} | {:error, %Ecto.Changeset{}}
|
||||
"""
|
||||
def update_source(%Source{} = channel, attrs) do
|
||||
channel
|
||||
def update_source(%Source{} = source, attrs) do
|
||||
source
|
||||
|> change_source_from_url(attrs)
|
||||
|> commit_and_start_indexing()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a channel and it's associated tasks (of any state).
|
||||
Deletes a source and it's associated tasks (of any state).
|
||||
|
||||
Returns {:ok, %Source{}} | {:error, %Ecto.Changeset{}}
|
||||
"""
|
||||
def delete_source(%Source{} = channel) do
|
||||
Tasks.delete_tasks_for(channel)
|
||||
Repo.delete(channel)
|
||||
def delete_source(%Source{} = source) do
|
||||
Tasks.delete_tasks_for(source)
|
||||
Repo.delete(source)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking channel changes.
|
||||
Returns an `%Ecto.Changeset{}` for tracking source changes.
|
||||
"""
|
||||
def change_source(%Source{} = channel, attrs \\ %{}) do
|
||||
Source.changeset(channel, attrs)
|
||||
def change_source(%Source{} = source, attrs \\ %{}) do
|
||||
Source.changeset(source, attrs)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking channel changes and additionally
|
||||
fetches channel details from the original_url (if provided). If the channel
|
||||
Returns an `%Ecto.Changeset{}` for tracking source changes and additionally
|
||||
fetches source details from the original_url (if provided). If the source
|
||||
details cannot be fetched, an error is added to the changeset.
|
||||
|
||||
Note that this fetches channel details as long as the `original_url` is present.
|
||||
Note that this fetches source details as long as the `original_url` is present.
|
||||
This means that it'll go for it even if a changeset is otherwise invalid. This
|
||||
is pretty easy to change, but for MVP I'm not concerned.
|
||||
"""
|
||||
def change_source_from_url(%Source{} = channel, attrs) do
|
||||
case change_source(channel, attrs) do
|
||||
def change_source_from_url(%Source{} = source, attrs) do
|
||||
case change_source(source, attrs) do
|
||||
%Ecto.Changeset{changes: %{original_url: _}} = changeset ->
|
||||
add_source_details_to_changeset(channel, changeset)
|
||||
add_source_details_to_changeset(source, changeset)
|
||||
|
||||
changeset ->
|
||||
changeset
|
||||
end
|
||||
end
|
||||
|
||||
defp add_source_details_to_changeset(channel, changeset) do
|
||||
defp add_source_details_to_changeset(source, changeset) do
|
||||
%Ecto.Changeset{changes: changes} = changeset
|
||||
|
||||
case ChannelDetails.get_source_details(changes.original_url) do
|
||||
{:ok, %ChannelDetails{} = channel_details} ->
|
||||
case SourceDetails.get_source_details(changes.original_url) do
|
||||
{:ok, %SourceDetails{} = source_details} ->
|
||||
change_source(
|
||||
channel,
|
||||
source,
|
||||
Map.merge(changes, %{
|
||||
name: channel_details.name,
|
||||
collection_id: channel_details.id
|
||||
name: source_details.name,
|
||||
collection_id: source_details.id
|
||||
})
|
||||
)
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ defmodule Pinchflat.MediaSource do
|
|||
Ecto.Changeset.add_error(
|
||||
changeset,
|
||||
:original_url,
|
||||
"could not fetch channel details from URL",
|
||||
"could not fetch source details from URL",
|
||||
error: runner_error
|
||||
)
|
||||
end
|
||||
|
|
@ -136,27 +136,27 @@ defmodule Pinchflat.MediaSource do
|
|||
|
||||
defp commit_and_start_indexing(changeset) do
|
||||
case Repo.insert_or_update(changeset) do
|
||||
{:ok, %Source{} = channel} ->
|
||||
maybe_run_indexing_task(changeset, channel)
|
||||
{:ok, %Source{} = source} ->
|
||||
maybe_run_indexing_task(changeset, source)
|
||||
|
||||
{:ok, channel}
|
||||
{:ok, source}
|
||||
|
||||
err ->
|
||||
err
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_run_indexing_task(changeset, channel) do
|
||||
defp maybe_run_indexing_task(changeset, source) do
|
||||
case changeset.data do
|
||||
# If the changeset is new (not persisted), attempt indexing no matter what
|
||||
%{__meta__: %{state: :built}} ->
|
||||
SourceTasks.kickoff_indexing_task(channel)
|
||||
SourceTasks.kickoff_indexing_task(source)
|
||||
|
||||
# If the record has been persisted, only attempt indexing if the
|
||||
# indexing frequency has been changed
|
||||
%{__meta__: %{state: :loaded}} ->
|
||||
if Map.has_key?(changeset.changes, :index_frequency_minutes) do
|
||||
SourceTasks.kickoff_indexing_task(channel)
|
||||
SourceTasks.kickoff_indexing_task(source)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ defmodule Pinchflat.Tasks do
|
|||
def create_task(%Oban.Job{} = job, attached_record) do
|
||||
attached_record_attr =
|
||||
case attached_record do
|
||||
%Source{} = channel -> %{source_id: channel.id}
|
||||
%Source{} = source -> %{source_id: source.id}
|
||||
%MediaItem{} = media_item -> %{media_item_id: media_item.id}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.ChannelTest do
|
|||
use ExUnit.Case, async: true
|
||||
import Mox
|
||||
|
||||
alias Pinchflat.MediaClient.ChannelDetails
|
||||
alias Pinchflat.MediaClient.SourceDetails
|
||||
alias Pinchflat.MediaClient.Backends.YtDlp.Channel
|
||||
|
||||
@channel_url "https://www.youtube.com/c/TheUselessTrials"
|
||||
|
|
@ -10,13 +10,13 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.ChannelTest do
|
|||
setup :verify_on_exit!
|
||||
|
||||
describe "get_source_details/1" do
|
||||
test "it returns a %ChannelDetails{} with data on success" do
|
||||
test "it returns a %SourceDetails{} with data on success" do
|
||||
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
|
||||
{:ok, "{\"channel\": \"TheUselessTrials\", \"channel_id\": \"UCQH2\"}"}
|
||||
end)
|
||||
|
||||
assert {:ok, res} = Channel.get_source_details(@channel_url)
|
||||
assert %ChannelDetails{id: "UCQH2", name: "TheUselessTrials"} = res
|
||||
assert %SourceDetails{id: "UCQH2", name: "TheUselessTrials"} = res
|
||||
end
|
||||
|
||||
test "it passes the expected args to the backend runner" do
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
defmodule Pinchflat.MediaClient.ChannelDetailsTest do
|
||||
defmodule Pinchflat.MediaClient.SourceDetailsTest do
|
||||
use ExUnit.Case, async: true
|
||||
import Mox
|
||||
|
||||
alias Pinchflat.MediaClient.ChannelDetails
|
||||
alias Pinchflat.MediaClient.SourceDetails
|
||||
|
||||
@channel_url "https://www.youtube.com/c/TheUselessTrials"
|
||||
|
||||
|
|
@ -10,8 +10,8 @@ defmodule Pinchflat.MediaClient.ChannelDetailsTest do
|
|||
|
||||
describe "new/2" do
|
||||
test "it returns a struct with the given values" do
|
||||
assert %ChannelDetails{id: "UCQH2", name: "TheUselessTrials"} =
|
||||
ChannelDetails.new("UCQH2", "TheUselessTrials")
|
||||
assert %SourceDetails{id: "UCQH2", name: "TheUselessTrials"} =
|
||||
SourceDetails.new("UCQH2", "TheUselessTrials")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ defmodule Pinchflat.MediaClient.ChannelDetailsTest do
|
|||
{:ok, "{\"channel\": \"TheUselessTrials\", \"channel_id\": \"UCQH2\"}"}
|
||||
end)
|
||||
|
||||
assert {:ok, _} = ChannelDetails.get_source_details(@channel_url)
|
||||
assert {:ok, _} = SourceDetails.get_source_details(@channel_url)
|
||||
end
|
||||
|
||||
test "it returns a struct composed of the returned data" do
|
||||
|
|
@ -32,8 +32,8 @@ defmodule Pinchflat.MediaClient.ChannelDetailsTest do
|
|||
{:ok, "{\"channel\": \"TheUselessTrials\", \"channel_id\": \"UCQH2\"}"}
|
||||
end)
|
||||
|
||||
assert {:ok, res} = ChannelDetails.get_source_details(@channel_url)
|
||||
assert %ChannelDetails{id: "UCQH2", name: "TheUselessTrials"} = res
|
||||
assert {:ok, res} = SourceDetails.get_source_details(@channel_url)
|
||||
assert %SourceDetails{id: "UCQH2", name: "TheUselessTrials"} = res
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ defmodule Pinchflat.MediaClient.ChannelDetailsTest do
|
|||
{:ok, ""}
|
||||
end)
|
||||
|
||||
assert {:ok, _} = ChannelDetails.get_video_ids(@channel_url)
|
||||
assert {:ok, _} = SourceDetails.get_video_ids(@channel_url)
|
||||
end
|
||||
|
||||
test "it returns a list of strings" do
|
||||
|
|
@ -54,7 +54,7 @@ defmodule Pinchflat.MediaClient.ChannelDetailsTest do
|
|||
{:ok, "video1\nvideo2\nvideo3"}
|
||||
end)
|
||||
|
||||
assert {:ok, ["video1", "video2", "video3"]} = ChannelDetails.get_video_ids(@channel_url)
|
||||
assert {:ok, ["video1", "video2", "video3"]} = SourceDetails.get_video_ids(@channel_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -301,7 +301,7 @@ defmodule Pinchflat.MediaSourceTest do
|
|||
})
|
||||
|
||||
assert %Ecto.Changeset{} = changeset
|
||||
assert errors_on(changeset).original_url == ["could not fetch channel details from URL"]
|
||||
assert errors_on(changeset).original_url == ["could not fetch source details from URL"]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue