Fix edge cases with parser
- Remove front_matter dependency, and use a hand-rolled simpler parser which is suitable for the data to parse (which is well-formed). - Fix a couple of edge cases with years and titles with commas
This commit is contained in:
@@ -1,24 +1,49 @@
|
||||
defmodule MusicLibrary.Records.Parser do
|
||||
alias MusicLibrary.Records.Record
|
||||
|
||||
def from_entry_contents(entry_contents) do
|
||||
with {:ok, meta, _body} <- FrontMatter.parse(entry_contents) do
|
||||
with {:ok, [meta]} <- parse_frontmatter(entry_contents) do
|
||||
{:ok,
|
||||
%Record{
|
||||
%{
|
||||
type: parse_subtype(meta["subType"]),
|
||||
musicbrainz_id: meta["id"],
|
||||
title: meta["title"],
|
||||
year: meta["year"],
|
||||
year: meta["year"] |> maybe_parse_year(),
|
||||
image: meta["image"],
|
||||
genres: meta["genres"]
|
||||
}}
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_frontmatter(entry_contents) do
|
||||
case entry_contents do
|
||||
"---\n" <> rest ->
|
||||
case String.split(rest, "\n---\n") do
|
||||
[frontmatter, _] ->
|
||||
case YamlElixir.read_all_from_string(frontmatter) do
|
||||
{:ok, meta} -> {:ok, meta}
|
||||
{:error, _} -> {:error, "Invalid frontmatter"}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:error, "Invalid frontmatter"}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:error, "Invalid frontmatter"}
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_subtype("Album"), do: :album
|
||||
defp parse_subtype("ep"), do: :ep
|
||||
defp parse_subtype("Live"), do: :live
|
||||
defp parse_subtype("Compilation"), do: :compilation
|
||||
defp parse_subtype("Single"), do: :single
|
||||
defp parse_subtype(_), do: :other
|
||||
|
||||
defp maybe_parse_year(nil), do: nil
|
||||
defp maybe_parse_year(year) when is_integer(year), do: year
|
||||
|
||||
defp maybe_parse_year(year) when is_binary(year) do
|
||||
{integer, _remainder} = Integer.parse(year, 10)
|
||||
integer
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,7 +38,7 @@ defmodule MusicLibrary.MixProject do
|
||||
{:ecto_sqlite3, ">= 0.0.0"},
|
||||
{:phoenix_html, "~> 4.1"},
|
||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||
{:front_matter, "~> 1.0"},
|
||||
{:yaml_elixir, "~> 2.11"},
|
||||
# TODO bump on release to {:phoenix_live_view, "~> 1.0.0"},
|
||||
{:phoenix_live_view, "~> 1.0.0-rc.1", override: true},
|
||||
{:floki, ">= 0.30.0", only: :test},
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"exqlite": {:hex, :exqlite, "0.23.0", "6e851c937a033299d0784994c66da24845415072adbc455a337e20087bce9033", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "404341cceec5e6466aaed160cf0b58be2019b60af82588c215e1224ebd3ec831"},
|
||||
"file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
|
||||
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
|
||||
"front_matter": {:hex, :front_matter, "1.0.1", "caca2cb16336e1d82ca5c5e9d94f88fd6d4ce84c1f05253e76d357650d4c46a9", [:mix], [{:yaml_elixir, "~> 2.5.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "1c4daa17c071b245e3706795b98814392fe0ce6bbbfb7c6543be63db86a4e953"},
|
||||
"gettext": {:hex, :gettext, "0.26.1", "38e14ea5dcf962d1fc9f361b63ea07c0ce715a8ef1f9e82d3dfb8e67e0416715", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "01ce56f188b9dc28780a52783d6529ad2bc7124f9744e571e1ee4ea88bf08734"},
|
||||
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]},
|
||||
"hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
|
||||
@@ -38,5 +37,5 @@
|
||||
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
||||
"websock_adapter": {:hex, :websock_adapter, "0.5.7", "65fa74042530064ef0570b75b43f5c49bb8b235d6515671b3d250022cb8a1f9e", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "d0f478ee64deddfec64b800673fd6e0c8888b079d9f3444dd96d2a98383bdbd1"},
|
||||
"yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"},
|
||||
"yaml_elixir": {:hex, :yaml_elixir, "2.5.0", "45de762be6d75fa5a8b5f44ddff8c30f64c26526eab5b1d72e36d616007b7796", [:mix], [{:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "80fe4e43f05582f2a90f2dcd73fc6171fbd65f2e6836f71fe4ce2154ef358c36"},
|
||||
"yaml_elixir": {:hex, :yaml_elixir, "2.11.0", "9e9ccd134e861c66b84825a3542a1c22ba33f338d82c07282f4f1f52d847bd50", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "53cc28357ee7eb952344995787f4bb8cc3cecbf189652236e9b163e8ce1bc242"},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
defmodule MusicLibrary.Records.ParserTest do
|
||||
use ExUnit.Case, async: true
|
||||
alias MusicLibrary.Records.{Parser, Record}
|
||||
alias MusicLibrary.Records.Parser
|
||||
|
||||
@obsidian_entry_path Path.expand("../../support/fixtures/marillion-marbles.md", __DIR__)
|
||||
|
||||
@@ -9,7 +9,7 @@ defmodule MusicLibrary.Records.ParserTest do
|
||||
|
||||
assert Parser.from_entry_contents(entry_contents) ==
|
||||
{:ok,
|
||||
%Record{
|
||||
%{
|
||||
type: :album,
|
||||
musicbrainz_id: "20790e26-98e4-3ad3-a67f-b674758b942d",
|
||||
title: "Marbles",
|
||||
@@ -27,4 +27,42 @@ defmodule MusicLibrary.Records.ParserTest do
|
||||
]
|
||||
}}
|
||||
end
|
||||
|
||||
test "handles special characters in titles" do
|
||||
entry_contents = """
|
||||
---
|
||||
type: "musicRelease"
|
||||
subType: "Album"
|
||||
title: "Guardians of the Galaxy: Awesome Mix, Vol. 1"
|
||||
englishTitle: "Guardians of the Galaxy: Awesome Mix, Vol. 1"
|
||||
year: "2014"
|
||||
dataSource: "MusicBrainz API"
|
||||
url: "https://musicbrainz.org/release-group/950092d6-45f6-4269-87da-99a9ff2fcc52"
|
||||
id: "950092d6-45f6-4269-87da-99a9ff2fcc52"
|
||||
genres:
|
||||
- "classic rock"
|
||||
- "pop"
|
||||
- "pop rock"
|
||||
- "rock"
|
||||
artists:
|
||||
- "Various Artists"
|
||||
image: "https://coverartarchive.org/release-group/950092d6-45f6-4269-87da-99a9ff2fcc52/front"
|
||||
rating: 9.6
|
||||
personalRating: 0
|
||||
tags: "mediaDB/music/Album"
|
||||
---
|
||||
"""
|
||||
|
||||
assert Parser.from_entry_contents(entry_contents) ==
|
||||
{:ok,
|
||||
%{
|
||||
genres: ["classic rock", "pop", "pop rock", "rock"],
|
||||
image:
|
||||
"https://coverartarchive.org/release-group/950092d6-45f6-4269-87da-99a9ff2fcc52/front",
|
||||
musicbrainz_id: "950092d6-45f6-4269-87da-99a9ff2fcc52",
|
||||
title: "Guardians of the Galaxy: Awesome Mix, Vol. 1",
|
||||
type: :album,
|
||||
year: 2014
|
||||
}}
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user