news_parse_ex.ex (1286B)
- # NewsParseEx: RSS/Atom parser
- # Copyright © 2022-2023 Haelwenn (lanodan) Monnier <contact+news_parse_ex@hacktivis.me>
- # SPDX-License-Identifier: AGPL-3.0-only
- defmodule NewsParseEx do
- alias NewsParseEx.XML
- defp get_feed_parser(doc) do
- with {:ok, root_name} <- XML.string_from_xpath(~s[name()], doc) do
- get_feed_parser(doc, root_name)
- end
- end
- defp get_feed_parser(doc, "feed") do
- with {:ok, namespace} <- XML.string_from_xpath(~s{/feed/namespace::*[name()='']}, doc) do
- if namespace == "http://www.w3.org/2005/Atom" do
- {:ok, NewsParseEx.Atom}
- else
- {:error, "Atom feed with wrong root namespace: #{namespace}"}
- end
- end
- end
- defp get_feed_parser(doc, "rss") do
- with {:ok, version} <- XML.string_from_xpath(~s{/rss/@version}, doc) do
- case version do
- "2.0" -> {:ok, NewsParseEx.RSS2_0}
- version -> {:error, "RSS with unknown version: #{version}"}
- end
- end
- end
- defp get_feed_parser(_doc, root_name) do
- {:error, "XML root isn't <feed> but <#{root_name}>"}
- end
- def parse(str) when is_bitstring(str) do
- with {_, {:ok, doc}} <- {:parse, XML.parse_document(str)},
- {_, {:ok, parser}} <- {:parser, get_feed_parser(doc)} do
- parser.parse(doc)
- end
- end
- end