diff --git a/lib/annot_at/feeds.ex b/lib/annot_at/feeds.ex index d4e1559..aaadffe 100644 --- a/lib/annot_at/feeds.ex +++ b/lib/annot_at/feeds.ex @@ -13,14 +13,17 @@ defmodule AnnotAt.Feeds do @feed_formats %{ "application/rss+xml" => :rss, "application/atom+xml" => :atom, - "application/feed+json" => :json + "application/feed+json" => :json, + "text/rss+xml" => :rss, + "application/xml" => :unknown, + "text/xml" => :unknown } @feed_rels ~w(alternate feed) @feed_mappings for rel <- @feed_rels, type <- Map.keys(@feed_formats), - do: ~s(link[rel="#{rel}"][type="#{type}"]) + do: ~s(link[rel="#{rel}"][type^="#{type}"]) @feed_selector Enum.join(@feed_mappings, ", ") @@ -103,16 +106,22 @@ defmodule AnnotAt.Feeds do case attributes do %{"href" => href, "type" => type} -> - url = - base_url - |> URI.merge(href) - |> URI.to_string() - - %Source{ - url: url, - title: attributes["title"], - format: Map.fetch!(@feed_formats, type) - } + case Map.fetch(@feed_formats, normalize_type(type)) do + {:ok, format} -> + url = + base_url + |> URI.merge(href) + |> URI.to_string() + + %Source{ + url: url, + title: attributes["title"], + format: format + } + + _ -> + nil + end _ -> nil @@ -157,4 +166,9 @@ defmodule AnnotAt.Feeds do trimmed -> trimmed end end + + defp normalize_type(type) do + [first | _] = String.split(type, ";") + String.trim(first) + end end diff --git a/test/annot_at/feeds_test.exs b/test/annot_at/feeds_test.exs index bcba4e0..b0a54c6 100644 --- a/test/annot_at/feeds_test.exs +++ b/test/annot_at/feeds_test.exs @@ -28,16 +28,31 @@ defmodule AnnotAt.FeedsTest do href="https://blog.example.com/atom"> + """ - assert [main, atom, json] = Feeds.discover(html, "https://blog.example.com") + assert [main, atom, json, feed] = Feeds.discover(html, "https://blog.example.com") assert %Feeds.Source{url: "https://blog.example.com/feed.xml", title: "Main", format: :rss} = main assert %Feeds.Source{url: "https://blog.example.com/atom", title: nil, format: :atom} = atom assert %Feeds.Source{format: :json, title: "JSON"} = json + # rel=feed + assert %Feeds.Source{format: :json, title: "Legacy"} = feed + end + + test "matches feed links whose type has parameters" do + html = """ + + + + """ + + assert [%Feeds.Source{format: :rss, url: "https://blog.example.com/feed.xml"}] = + Feeds.discover(html, "https://blog.example.com") end test "ignores non-feed alternates and dedupes by url" do