Updated source's friendly_name to default to the collection_name (#29)
This commit is contained in:
parent
1ec1a48235
commit
01042ebd1b
9 changed files with 101 additions and 3 deletions
1
ideas.md
1
ideas.md
|
|
@ -1,3 +1,4 @@
|
||||||
- Write media datbase ID as metadata/to file/whatever so it gives us an option to retroactively match media to the DB down the line. Useful if someone moves the media without informing the UI
|
- Write media datbase ID as metadata/to file/whatever so it gives us an option to retroactively match media to the DB down the line. Useful if someone moves the media without informing the UI
|
||||||
- Use a UUID for the media database ID (or at least alongside it)
|
- Use a UUID for the media database ID (or at least alongside it)
|
||||||
- Look into this and its recommended plugins https://hexdocs.pm/ex_check/readme.html
|
- Look into this and its recommended plugins https://hexdocs.pm/ex_check/readme.html
|
||||||
|
- Add output template option for the source's friendly name
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ defmodule Pinchflat.Sources.Source do
|
||||||
|
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
import Pinchflat.Utils.ChangesetUtils
|
||||||
|
|
||||||
alias Pinchflat.Media.MediaItem
|
alias Pinchflat.Media.MediaItem
|
||||||
alias Pinchflat.Profiles.MediaProfile
|
alias Pinchflat.Profiles.MediaProfile
|
||||||
|
|
@ -25,6 +26,7 @@ defmodule Pinchflat.Sources.Source do
|
||||||
collection_name
|
collection_name
|
||||||
collection_id
|
collection_id
|
||||||
collection_type
|
collection_type
|
||||||
|
friendly_name
|
||||||
download_media
|
download_media
|
||||||
original_url
|
original_url
|
||||||
media_profile_id
|
media_profile_id
|
||||||
|
|
@ -53,6 +55,7 @@ defmodule Pinchflat.Sources.Source do
|
||||||
def changeset(source, attrs) do
|
def changeset(source, attrs) do
|
||||||
source
|
source
|
||||||
|> cast(attrs, @allowed_fields)
|
|> cast(attrs, @allowed_fields)
|
||||||
|
|> dynamic_default(:friendly_name, fn cs -> get_field(cs, :collection_name) end)
|
||||||
|> validate_required(@required_fields)
|
|> validate_required(@required_fields)
|
||||||
|> unique_constraint([:collection_id, :media_profile_id])
|
|> unique_constraint([:collection_id, :media_profile_id])
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ defmodule Pinchflat.Sources do
|
||||||
|
|
||||||
defp add_source_details_by_collection_type(source, changeset, source_details) do
|
defp add_source_details_by_collection_type(source, changeset, source_details) do
|
||||||
%Ecto.Changeset{changes: changes} = changeset
|
%Ecto.Changeset{changes: changes} = changeset
|
||||||
collection_type = source.collection_type || changes[:collection_type]
|
collection_type = Ecto.Changeset.get_field(changeset, :collection_type)
|
||||||
|
|
||||||
collection_changes =
|
collection_changes =
|
||||||
case collection_type do
|
case collection_type do
|
||||||
|
|
|
||||||
19
lib/pinchflat/utils/changeset_utils.ex
Normal file
19
lib/pinchflat/utils/changeset_utils.ex
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
defmodule Pinchflat.Utils.ChangesetUtils do
|
||||||
|
@moduledoc """
|
||||||
|
Utility methods for working with changesets
|
||||||
|
"""
|
||||||
|
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Sets the default value of a field if it is nil by applying the given function.
|
||||||
|
|
||||||
|
Returns %Ecto.Changeset{}.
|
||||||
|
"""
|
||||||
|
def dynamic_default(changeset, key, value_fn) do
|
||||||
|
case get_field(changeset, key) do
|
||||||
|
nil -> put_change(changeset, key, value_fn.(changeset))
|
||||||
|
_ -> changeset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
defmodule Pinchflat.Utils.FunctionUtils do
|
defmodule Pinchflat.Utils.FunctionUtils do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Utility functions for working with functions
|
Utility methods for working with functions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
defmodule Pinchflat.Utils.StringUtils do
|
defmodule Pinchflat.Utils.StringUtils do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Utility functions for working with strings
|
Utility methods for working with strings
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
defmodule Pinchflat.Repo.Migrations.AddNotNullToFriendlyName do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:sources) do
|
||||||
|
remove :friendly_name, :string
|
||||||
|
end
|
||||||
|
|
||||||
|
alter table(:sources) do
|
||||||
|
add :friendly_name, :string, null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -59,6 +59,35 @@ defmodule Pinchflat.SourcesTest do
|
||||||
assert String.starts_with?(source.collection_id, "some_playlist_id_")
|
assert String.starts_with?(source.collection_id, "some_playlist_id_")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "you can specify a custom friendly_name" do
|
||||||
|
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||||
|
|
||||||
|
valid_attrs = %{
|
||||||
|
media_profile_id: media_profile_fixture().id,
|
||||||
|
original_url: "https://www.youtube.com/channel/abc123",
|
||||||
|
collection_type: "channel",
|
||||||
|
friendly_name: "some custom name"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:ok, %Source{} = source} = Sources.create_source(valid_attrs)
|
||||||
|
|
||||||
|
assert source.friendly_name == "some custom name"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "friendly name is pulled from collection_name if not specified" do
|
||||||
|
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||||
|
|
||||||
|
valid_attrs = %{
|
||||||
|
media_profile_id: media_profile_fixture().id,
|
||||||
|
original_url: "https://www.youtube.com/channel/abc123",
|
||||||
|
collection_type: "channel"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:ok, %Source{} = source} = Sources.create_source(valid_attrs)
|
||||||
|
|
||||||
|
assert source.friendly_name == "some channel name"
|
||||||
|
end
|
||||||
|
|
||||||
test "creation with invalid data returns error changeset" do
|
test "creation with invalid data returns error changeset" do
|
||||||
assert {:error, %Ecto.Changeset{}} = Sources.create_source(@invalid_source_attrs)
|
assert {:error, %Ecto.Changeset{}} = Sources.create_source(@invalid_source_attrs)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
33
test/pinchflat/utils/changeset_utils_test.exs
Normal file
33
test/pinchflat/utils/changeset_utils_test.exs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
defmodule Pinchflat.Utils.ChangesetUtilsTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
defmodule MockSchema do
|
||||||
|
use Ecto.Schema
|
||||||
|
import Ecto.Changeset
|
||||||
|
import Pinchflat.Utils.ChangesetUtils
|
||||||
|
|
||||||
|
schema "mock_schemas" do
|
||||||
|
field :title, :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(data, attrs) do
|
||||||
|
data
|
||||||
|
|> cast(attrs, [:title])
|
||||||
|
|> dynamic_default(:title, fn _ -> "default" end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "dynamic_default/3" do
|
||||||
|
test "sets the default value if the field is nil" do
|
||||||
|
changeset = MockSchema.changeset(%MockSchema{}, %{})
|
||||||
|
|
||||||
|
assert Ecto.Changeset.get_change(changeset, :title) == "default"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "does not set the default value if the field is not nil" do
|
||||||
|
changeset = MockSchema.changeset(%MockSchema{}, %{title: "custom"})
|
||||||
|
|
||||||
|
assert Ecto.Changeset.get_change(changeset, :title) == "custom"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue