From 7a0d01796564a9d0ae0be0c0e14d127cd57af99a Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Mon, 14 Oct 2024 22:30:14 +0100 Subject: [PATCH] Support filtering by type --- lib/music_library/records.ex | 12 ++++++++++ lib/music_library/records/record.ex | 14 +++++++++++ lib/music_library/records/search_parser.ex | 28 +++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/music_library/records.ex b/lib/music_library/records.ex index 9894d374..cf0d6caa 100644 --- a/lib/music_library/records.ex +++ b/lib/music_library/records.ex @@ -60,6 +60,9 @@ defmodule MusicLibrary.Records do {:format, format}, search -> search |> where([r], r.format == ^format) + {:type, type}, search -> + search |> where([r], r.type == ^type) + {:query, raw_query}, search -> search |> where( @@ -82,6 +85,15 @@ defmodule MusicLibrary.Records do Repo.all(q) end + def count_records_by_type do + q = + from r in Record, + group_by: r.type, + select: {r.type, count(r.id)} + + Repo.all(q) + end + def get_record!(id), do: Repo.get!(Record, id) def get_latest_record! do diff --git a/lib/music_library/records/record.ex b/lib/music_library/records/record.ex index d88c2237..5964e6e6 100644 --- a/lib/music_library/records/record.ex +++ b/lib/music_library/records/record.ex @@ -105,6 +105,20 @@ defmodule MusicLibrary.Records.Record do def format_long_label(:dvd), do: "DVD" def format_long_label(:multi), do: "Multi" + def type_short_label(:album), do: "ALB" + def type_short_label(:ep), do: "EP" + def type_short_label(:live), do: "LIVE" + def type_short_label(:compilation), do: "CMP" + def type_short_label(:single), do: "SNG" + def type_short_label(:other), do: "OTH" + + def type_long_label(:album), do: "Album" + def type_long_label(:ep), do: "EP" + def type_long_label(:live), do: "Live" + def type_long_label(:compilation), do: "Comp" + def type_long_label(:single), do: "Single" + def type_long_label(:other), do: "Other" + def format_release(nil), do: "N/A" def format_release(release) do diff --git a/lib/music_library/records/search_parser.ex b/lib/music_library/records/search_parser.ex index 7148b45e..67c8df36 100644 --- a/lib/music_library/records/search_parser.ex +++ b/lib/music_library/records/search_parser.ex @@ -42,7 +42,21 @@ defmodule MusicLibrary.Records.SearchParser do choice([concat(format_filter, formats), ignore(invalid_format)]) |> tag(:format) - search = repeat(choice([artist, album, mbid, space, format, query])) + type_filter = ignore(string("type:")) + + types = + Ecto.Enum.dump_values(MusicLibrary.Records.Record, :type) + |> Enum.map(&string/1) + |> choice() + |> map({__MODULE__, :resolve_type, []}) + + invalid_type = concat(type_filter, word) + + type = + choice([concat(type_filter, types), ignore(invalid_type)]) + |> tag(:type) + + search = repeat(choice([artist, album, mbid, space, format, type, query])) defparsecp(:search_parser, search) @@ -63,6 +77,10 @@ defmodule MusicLibrary.Records.SearchParser do {:ok, %{artist: "the pineapple thief", format: :cd}} iex> MusicLibrary.Records.SearchParser.parse("format:vin") {:ok, %{query: ""}} + iex> MusicLibrary.Records.SearchParser.parse("type:alb") + {:ok, %{query: ""}} + iex> MusicLibrary.Records.SearchParser.parse("type:album") + {:ok, %{type: :album}} """ def parse(""), do: {:ok, %{query: ""}} @@ -77,6 +95,11 @@ defmodule MusicLibrary.Records.SearchParser do |> Enum.find_value(fn {key, value} -> if value == format, do: key end) end + def resolve_type(type) do + Ecto.Enum.mappings(MusicLibrary.Records.Record, :type) + |> Enum.find_value(fn {key, value} -> if value == type, do: key end) + end + defp normalize(result) do Enum.reduce(result, %{}, fn {:artist, [{:query, [value]}]}, acc -> @@ -91,6 +114,9 @@ defmodule MusicLibrary.Records.SearchParser do {:format, [value]}, acc -> Map.put(acc, :format, value) + {:type, [value]}, acc -> + Map.put(acc, :type, value) + {:query, [value]}, acc -> Map.update(acc, :query, value, &(&1 <> " " <> value))