diff --git a/lib/music_library/records/parser.ex b/lib/music_library/records/parser.ex new file mode 100644 index 00000000..389e8008 --- /dev/null +++ b/lib/music_library/records/parser.ex @@ -0,0 +1,24 @@ +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 + {:ok, + %Record{ + type: parse_subtype(meta["subType"]), + musicbrainz_id: meta["id"], + title: meta["title"], + year: meta["year"], + image: meta["image"], + genres: meta["genres"] + }} + 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 +end diff --git a/mix.exs b/mix.exs index 56dfbc8c..58008df8 100644 --- a/mix.exs +++ b/mix.exs @@ -38,6 +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"}, # 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}, diff --git a/mix.lock b/mix.lock index b1984909..8093efa1 100644 --- a/mix.lock +++ b/mix.lock @@ -14,6 +14,7 @@ "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"}, @@ -36,4 +37,6 @@ "thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"}, "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"}, } diff --git a/test/music_library/records/parser_test.exs b/test/music_library/records/parser_test.exs new file mode 100644 index 00000000..66df826b --- /dev/null +++ b/test/music_library/records/parser_test.exs @@ -0,0 +1,30 @@ +defmodule MusicLibrary.Records.ParserTest do + use ExUnit.Case, async: true + alias MusicLibrary.Records.{Parser, Record} + + @obsidian_entry_path Path.expand("../../support/fixtures/marillion-marbles.md", __DIR__) + + test "parses the content of the Obsidian album entry" do + entry_contents = File.read!(@obsidian_entry_path) + + assert Parser.from_entry_contents(entry_contents) == + {:ok, + %Record{ + type: :album, + musicbrainz_id: "20790e26-98e4-3ad3-a67f-b674758b942d", + title: "Marbles", + year: 2004, + image: + "https://coverartarchive.org/release-group/20790e26-98e4-3ad3-a67f-b674758b942d/front", + genres: [ + "alternative rock", + "art rock", + "baroque pop", + "pop rock", + "progressive rock", + "psychedelic pop", + "rock" + ] + }} + end +end diff --git a/test/music_library/records_test.exs b/test/music_library/records_test.exs index 38a86bc7..f475bac3 100644 --- a/test/music_library/records_test.exs +++ b/test/music_library/records_test.exs @@ -8,7 +8,14 @@ defmodule MusicLibrary.RecordsTest do import MusicLibrary.RecordsFixtures - @invalid_attrs %{type: nil, title: nil, image: nil, year: nil, musicbrainz_id: nil, genres: nil} + @invalid_attrs %{ + type: nil, + title: nil, + image: nil, + year: nil, + musicbrainz_id: nil, + genres: nil + } test "list_records/0 returns all records" do record = record_fixture() @@ -21,7 +28,14 @@ defmodule MusicLibrary.RecordsTest do end test "create_record/1 with valid data creates a record" do - valid_attrs = %{type: :album, title: "some title", image: "some image", year: 42, musicbrainz_id: "7488a646-e31f-11e4-aace-600308960662", genres: ["option1", "option2"]} + valid_attrs = %{ + type: :album, + title: "some title", + image: "some image", + year: 42, + musicbrainz_id: "7488a646-e31f-11e4-aace-600308960662", + genres: ["option1", "option2"] + } assert {:ok, %Record{} = record} = Records.create_record(valid_attrs) assert record.type == :album @@ -38,7 +52,15 @@ defmodule MusicLibrary.RecordsTest do test "update_record/2 with valid data updates the record" do record = record_fixture() - update_attrs = %{type: :ep, title: "some updated title", image: "some updated image", year: 43, musicbrainz_id: "7488a646-e31f-11e4-aace-600308960668", genres: ["option1"]} + + update_attrs = %{ + type: :ep, + title: "some updated title", + image: "some updated image", + year: 43, + musicbrainz_id: "7488a646-e31f-11e4-aace-600308960668", + genres: ["option1"] + } assert {:ok, %Record{} = record} = Records.update_record(record, update_attrs) assert record.type == :ep diff --git a/test/support/fixtures/marillion-marbles.md b/test/support/fixtures/marillion-marbles.md new file mode 100644 index 00000000..6f935f65 --- /dev/null +++ b/test/support/fixtures/marillion-marbles.md @@ -0,0 +1,25 @@ +--- +type: musicRelease +subType: Album +title: Marbles +englishTitle: Marbles +year: 2004 +dataSource: MusicBrainz API +url: https://musicbrainz.org/release-group/20790e26-98e4-3ad3-a67f-b674758b942d +id: 20790e26-98e4-3ad3-a67f-b674758b942d +genres: + - alternative rock + - art rock + - baroque pop + - pop rock + - progressive rock + - psychedelic pop + - rock +artists: + - Marillion +image: https://coverartarchive.org/release-group/20790e26-98e4-3ad3-a67f-b674758b942d/front +rating: 8.8 +personalRating: 0 +tags: + - mediaDB/music/Album +---