defmodule FeedParser.Parser.RSSInJSON do @moduledoc """ A `FeedParser.Parser` that handles [RSS-in-JSON feeds](https://github.com/scripting/Scripting-News/blob/2347bb8751d94dc76d25074997db4fde682585f9/rss-in-json/README.md). """ @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"] last_updated = channel["lastBuildDate"] |> Timex.parse("{RFC1123}") |> case do {:ok, date} -> date _ -> nil end 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, links: [{link, nil}], title: title, content: content, date: pubDate } end) {:ok, %FeedParser.Feed{ site_url: link, title: title, image_url: image, last_updated: last_updated, items: items }} end end