diff --git a/lib/feed_parser.ex b/lib/feed_parser.ex index 87005b3..b241700 100644 --- a/lib/feed_parser.ex +++ b/lib/feed_parser.ex @@ -1,9 +1,14 @@ defmodule FeedParser do - @default_parsers [FeedParser.RSS2.Parser, FeedParser.Atom.Parser, FeedParser.JSONFeed.Parser] + @default_parsers [ + FeedParser.RSS2.Parser, + FeedParser.Atom.Parser, + FeedParser.JSONFeed.Parser, + FeedParser.RSSInJSON.Parser + ] - @spec parse_feed(data :: String.t(), content_type :: String.t(), parsers :: [module()]) :: + @spec parse(data :: String.t(), content_type :: String.t(), parsers :: [module()]) :: {:ok, feed :: FeedParser.Feed.t()} | {:error, reason :: String.t()} - def parse_feed(data, content_type, parsers \\ @default_parsers) when is_binary(data) do + def parse(data, content_type, parsers \\ @default_parsers) when is_binary(data) do parsers |> Enum.reduce_while(false, fn parser, acc -> case parser.accepts(data, content_type) do diff --git a/lib/rssinjson/parser.ex b/lib/rssinjson/parser.ex new file mode 100644 index 0000000..54687c7 --- /dev/null +++ b/lib/rssinjson/parser.ex @@ -0,0 +1,61 @@ +defmodule FeedParser.RSSInJSON.Parser do + @behaviour FeedParser.Parser + + @impl FeedParser.Parser + def accepts(data, content_type) do + with "application/json" <- content_type, + {:ok, json} <- Poison.decode(data), + %{"rss" => %{"version" => "2.0"} = rss} <- json do + {true, rss} + else + _ -> + false + end + end + + @impl FeedParser.Parser + def parse_feed(rss) do + channel = rss["channel"] + title = channel["title"] + link = channel["link"] + + image = + case channel do + %{"image" => %{"url" => url}} -> url + _ -> nil + end + + items = + channel["item"] + |> Enum.map(fn item -> + guid = item["guid"] + link = item["link"] + title = Map.get(item, "title") + content = item["description"] + + pubDate = + item["pubDate"] + |> Timex.parse("{RFC1123}") + |> case do + {:ok, date} -> date + _ -> nil + end + + %FeedParser.Item{ + guid: guid, + url: link, + title: title, + content: content, + date: pubDate + } + end) + + {:ok, + %FeedParser.Feed{ + site_url: link, + title: title, + image_url: image, + items: items + }} + end +end