Parse Last.fm session

This commit is contained in:
Claudio Ortolina
2025-05-05 20:25:30 +01:00
parent 299cc468b6
commit 95e80bc432
3 changed files with 87 additions and 1 deletions
+62
View File
@@ -0,0 +1,62 @@
defmodule LastFm.Session do
require Record
defstruct [:name, :key, :pro]
Record.defrecord(
:xmlAttribute,
Record.extract(:xmlAttribute, from_lib: "xmerl/include/xmerl.hrl")
)
Record.defrecord(:xmlText, Record.extract(:xmlText, from_lib: "xmerl/include/xmerl.hrl"))
def parse(xml_string) do
doc = scan(xml_string)
name =
doc
|> first("//lfm/session/name")
|> text()
key =
doc
|> first("//lfm/session/key")
|> text()
subscriber =
doc
|> first("//lfm/session/subscriber")
|> text()
%__MODULE__{
name: name,
key: key,
pro: subscriber == "1"
}
end
defp scan(xml_string) do
{doc, []} =
xml_string
|> :binary.bin_to_list()
|> :xmerl_scan.string(quiet: true)
doc
end
defp first(node, path), do: node |> xpath(path) |> take_one
defp take_one([head | _]), do: head
defp take_one(_), do: nil
defp xpath(nil, _), do: []
defp xpath(node, path) do
:xmerl_xpath.string(to_charlist(path), node)
end
def text(node), do: node |> xpath(~c"./text()") |> extract_text
defp extract_text([xmlText(value: value)]), do: List.to_string(value)
defp extract_text(_x), do: nil
end
+1 -1
View File
@@ -20,7 +20,7 @@ defmodule MusicLibrary.MixProject do
def application do
[
mod: {MusicLibrary.Application, []},
extra_applications: [:logger, :runtime_tools]
extra_applications: [:logger, :runtime_tools, :xmerl]
]
end
+24
View File
@@ -0,0 +1,24 @@
defmodule LastFm.SessionTest do
use ExUnit.Case, async: true
alias LastFm.Session
@xml """
<?xml version="1.0" encoding="UTF-8"?>
<lfm status="ok">
<session>
<name>cloud8421</name>
<key>super-secret</key>
<subscriber>1</subscriber>
</session>
</lfm>
"""
test "parse/1" do
assert %Session{
name: "cloud8421",
key: "super-secret",
pro: true
} == Session.parse(@xml)
end
end