defmodule Gluttony do @moduledoc """ Parses RSS 2.0 and Atom 1.0 feeds. # References - RSS 2.0 Specs: https://www.rssboard.org/rss-specification - Atom 1.0 Specs: https://xml2rfc.tools.ietf.org/public/rfc/html/rfc4287.html ## Extra information - W3C Feed Docs: https://validator.w3.org/feed/docs/ - RSS 2.0 and Atom 1.0 compared: http://www.intertwingly.net/wiki/pie/Rss20AndAtom10Compared """ @doc """ Parses the given string and returns the values. # Examples Parsing a xml string from a RSS feed: {:ok, %{feed: feed, entries: entries}} = Gluttony.parse_string(xml) When a error happens, the reason is returned: {:error, reason} = Gluttony.parse_string(xml) You can retrieve a common result interface by specifing the `raw` option as `false`. This might be usefull to retrieve only relevant and common information, since RSS 2.0 and Atom 1.0 are very different specs: {:ok, %Gluttony.Feed{}} = Gluttony.parse_string(xml, raw: false) """ def parse_string(xml, opts \\ []), do: parse(xml, opts) @doc """ Fetches the given url and parses the response. See `parse_string/2` for more information on the result values. """ def fetch_feed(url, opts \\ []) do with {:ok, response} <- HTTPoison.get(url), {:ok, result} <- parse(response.body, opts) do {:ok, result} end end @doc """ Parses a stream of input and returns the values. # Examples Parsing an XML stream from an RSS feed: stream = File.stream!("rss_feed.xml", :line, [encoding: :utf8]) {:ok, %{feed: feed, entries: entries}} = Gluttony.parse_stream(stream) """ def parse_stream(stream, opts \\ []) do case Saxy.parse_stream(stream, Gluttony.Parser, opts) do {:ok, result} -> {:ok, result} {:halt, reason, _buffer} -> {:error, reason} {:error, reason} -> {:error, reason} end end defp parse(xml, opts) do case Saxy.parse_string(xml, Gluttony.Parser, opts) do {:ok, result} -> {:ok, result} {:halt, reason, _buffer} -> {:error, reason} {:error, reason} -> {:error, reason} end end end