Support filtering by type
This commit is contained in:
@@ -60,6 +60,9 @@ defmodule MusicLibrary.Records do
|
|||||||
{:format, format}, search ->
|
{:format, format}, search ->
|
||||||
search |> where([r], r.format == ^format)
|
search |> where([r], r.format == ^format)
|
||||||
|
|
||||||
|
{:type, type}, search ->
|
||||||
|
search |> where([r], r.type == ^type)
|
||||||
|
|
||||||
{:query, raw_query}, search ->
|
{:query, raw_query}, search ->
|
||||||
search
|
search
|
||||||
|> where(
|
|> where(
|
||||||
@@ -82,6 +85,15 @@ defmodule MusicLibrary.Records do
|
|||||||
Repo.all(q)
|
Repo.all(q)
|
||||||
end
|
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_record!(id), do: Repo.get!(Record, id)
|
||||||
|
|
||||||
def get_latest_record! do
|
def get_latest_record! do
|
||||||
|
|||||||
@@ -105,6 +105,20 @@ defmodule MusicLibrary.Records.Record do
|
|||||||
def format_long_label(:dvd), do: "DVD"
|
def format_long_label(:dvd), do: "DVD"
|
||||||
def format_long_label(:multi), do: "Multi"
|
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(nil), do: "N/A"
|
||||||
|
|
||||||
def format_release(release) do
|
def format_release(release) do
|
||||||
|
|||||||
@@ -42,7 +42,21 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
choice([concat(format_filter, formats), ignore(invalid_format)])
|
choice([concat(format_filter, formats), ignore(invalid_format)])
|
||||||
|> tag(: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)
|
defparsecp(:search_parser, search)
|
||||||
|
|
||||||
@@ -63,6 +77,10 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
{:ok, %{artist: "the pineapple thief", format: :cd}}
|
{:ok, %{artist: "the pineapple thief", format: :cd}}
|
||||||
iex> MusicLibrary.Records.SearchParser.parse("format:vin")
|
iex> MusicLibrary.Records.SearchParser.parse("format:vin")
|
||||||
{:ok, %{query: ""}}
|
{: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: ""}}
|
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)
|
|> Enum.find_value(fn {key, value} -> if value == format, do: key end)
|
||||||
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
|
defp normalize(result) do
|
||||||
Enum.reduce(result, %{}, fn
|
Enum.reduce(result, %{}, fn
|
||||||
{:artist, [{:query, [value]}]}, acc ->
|
{:artist, [{:query, [value]}]}, acc ->
|
||||||
@@ -91,6 +114,9 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
{:format, [value]}, acc ->
|
{:format, [value]}, acc ->
|
||||||
Map.put(acc, :format, value)
|
Map.put(acc, :format, value)
|
||||||
|
|
||||||
|
{:type, [value]}, acc ->
|
||||||
|
Map.put(acc, :type, value)
|
||||||
|
|
||||||
{:query, [value]}, acc ->
|
{:query, [value]}, acc ->
|
||||||
Map.update(acc, :query, value, &(&1 <> " " <> value))
|
Map.update(acc, :query, value, &(&1 <> " " <> value))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user