[WIP] added basic index function

This commit is contained in:
Kieran Eglin 2024-01-24 20:25:14 -08:00
parent 9fc7f7b860
commit 73bb7803af
No known key found for this signature in database
GPG key ID: 193984967FCF432D
6 changed files with 41 additions and 8 deletions

View file

@ -7,6 +7,8 @@ defmodule Pinchflat.Media.MediaItem do
@required_fields ~w(media_id channel_id)a @required_fields ~w(media_id channel_id)a
@allowed_fields ~w(title media_id video_filepath channel_id)a @allowed_fields ~w(title media_id video_filepath channel_id)a
# TODO: consider making an attached `metadata` model to store the JSON response from whatever backend is used
schema "media_items" do schema "media_items" do
field :title, :string field :title, :string
field :media_id, :string field :media_id, :string
@ -22,5 +24,6 @@ defmodule Pinchflat.Media.MediaItem do
media_item media_item
|> cast(attrs, @allowed_fields) |> cast(attrs, @allowed_fields)
|> validate_required(@required_fields) |> validate_required(@required_fields)
|> unique_constraint([:media_id, :channel_id])
end end
end end

View file

@ -15,7 +15,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.Channel do
Returns {:ok, %ChannelDetails{}} | {:error, any, ...}. Returns {:ok, %ChannelDetails{}} | {:error, any, ...}.
""" """
def get_channel_info(channel_url) do def get_channel_details(channel_url) do
opts = [print: "%(.{channel,channel_id})j", playlist_end: 1] opts = [print: "%(.{channel,channel_id})j", playlist_end: 1]
with {:ok, output} <- backend_runner().run(channel_url, opts), with {:ok, output} <- backend_runner().run(channel_url, opts),

View file

@ -21,7 +21,14 @@ defmodule Pinchflat.MediaClient.ChannelDetails do
Returns {:ok, map()} | {:error, any, ...}. Returns {:ok, map()} | {:error, any, ...}.
""" """
def get_channel_details(channel_url, backend \\ :yt_dlp) do def get_channel_details(channel_url, backend \\ :yt_dlp) do
channel_module(backend).get_channel_info(channel_url) channel_module(backend).get_channel_details(channel_url)
end
@doc """
TODO: test
"""
def get_video_ids(channel_url, backend \\ :yt_dlp) do
channel_module(backend).get_video_ids(channel_url)
end end
defp channel_module(backend) do defp channel_module(backend) do

View file

@ -6,6 +6,7 @@ defmodule Pinchflat.MediaSource do
import Ecto.Query, warn: false import Ecto.Query, warn: false
alias Pinchflat.Repo alias Pinchflat.Repo
alias Pinchflat.Media
alias Pinchflat.MediaSource.Channel alias Pinchflat.MediaSource.Channel
alias Pinchflat.MediaClient.ChannelDetails alias Pinchflat.MediaClient.ChannelDetails
@ -32,6 +33,28 @@ defmodule Pinchflat.MediaSource do
|> Repo.insert() |> Repo.insert()
end end
@doc """
Given a media source, creates (indexes) the media by creating media_items for each
media ID in the source.
Returns [%MediaItem{}, ...] | [%Ecto.Changeset{}, ...]
TODO: test
"""
def index_media_items(%Channel{} = channel) do
{:ok, media_ids} = ChannelDetails.get_video_ids(channel.original_url)
media_ids
|> Enum.map(fn media_id ->
attrs = %{channel_id: channel.id, media_id: media_id}
case Media.create_media_item(attrs) do
{:ok, media_item} -> media_item
{:error, changeset} -> changeset
end
end)
end
@doc """ @doc """
Updates a channel. Returns {:ok, %Channel{}} | {:error, %Ecto.Changeset{}} Updates a channel. Returns {:ok, %Channel{}} | {:error, %Ecto.Changeset{}}
""" """

View file

@ -12,6 +12,6 @@ defmodule Pinchflat.Repo.Migrations.CreateMediaItems do
end end
create index(:media_items, [:channel_id]) create index(:media_items, [:channel_id])
create unique_index(:media_items, [:channel_id, :media_id]) create unique_index(:media_items, [:media_id, :channel_id])
end end
end end

View file

@ -9,13 +9,13 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.ChannelTest do
setup :verify_on_exit! setup :verify_on_exit!
describe "get_channel_info/1" do describe "get_channel_details/1" do
test "it returns a %ChannelDetails{} with data on success" do test "it returns a %ChannelDetails{} with data on success" do
expect(YtDlpRunnerMock, :run, fn _url, _opts -> expect(YtDlpRunnerMock, :run, fn _url, _opts ->
{:ok, "{\"channel\": \"TheUselessTrials\", \"channel_id\": \"UCQH2\"}"} {:ok, "{\"channel\": \"TheUselessTrials\", \"channel_id\": \"UCQH2\"}"}
end) end)
assert {:ok, res} = Channel.get_channel_info(@channel_url) assert {:ok, res} = Channel.get_channel_details(@channel_url)
assert %ChannelDetails{id: "UCQH2", name: "TheUselessTrials"} = res assert %ChannelDetails{id: "UCQH2", name: "TheUselessTrials"} = res
end end
@ -26,19 +26,19 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.ChannelTest do
{:ok, "{}"} {:ok, "{}"}
end) end)
assert {:ok, _} = Channel.get_channel_info(@channel_url) assert {:ok, _} = Channel.get_channel_details(@channel_url)
end end
test "it returns an error if the runner returns an error" do test "it returns an error if the runner returns an error" do
expect(YtDlpRunnerMock, :run, fn _url, _opts -> {:error, "Big issue", 1} end) expect(YtDlpRunnerMock, :run, fn _url, _opts -> {:error, "Big issue", 1} end)
assert {:error, "Big issue", 1} = Channel.get_channel_info(@channel_url) assert {:error, "Big issue", 1} = Channel.get_channel_details(@channel_url)
end end
test "it returns an error if the output is not JSON" do test "it returns an error if the output is not JSON" do
expect(YtDlpRunnerMock, :run, fn _url, _opts -> {:ok, "Not JSON"} end) expect(YtDlpRunnerMock, :run, fn _url, _opts -> {:ok, "Not JSON"} end)
assert {:error, %Jason.DecodeError{}} = Channel.get_channel_info(@channel_url) assert {:error, %Jason.DecodeError{}} = Channel.get_channel_details(@channel_url)
end end
end end
end end