Skip to content

Instantly share code, notes, and snippets.

@umurgdk
Created September 12, 2015 17:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save umurgdk/3219ea7e73bd96f2c1b7 to your computer and use it in GitHub Desktop.
Save umurgdk/3219ea7e73bd96f2c1b7 to your computer and use it in GitHub Desktop.
defmodule Feedme.Parsers.RSS2 do
alias Feedme.Feed
alias Feedme.Entry
alias Feedme.MetaData
alias Feedme.Image
alias Feedme.Enclosure
def valid?(document) do
has_version = document
|> XmlNode.first("/rss")
|> XmlNode.attr("version") == "2.0"
has_one_channel = document
|> XmlNode.first("/rss/channel") != nil
Enum.all? [ has_version, has_one_channel ]
end
def parse(document) do
%Feed{meta: parse_meta(document), entries: parse_entries(document)}
end
def parse_meta(document) do
# struct will be filled
meta_data = %MetaData{}
# image like fields has their own structs and they need special threatment
skip_fields = [:image, :skip_hours, :skip_days]
# Structs are basically Maps
[_ | string_fields] = Map.keys(meta_data)
|> Enum.reject(&Enum.member?(skip_fields, &1))
channel = XmlNode.first(document, "/rss/channel")
get_text = fn(name) -> XmlNode.text_for_node(channel, name) end
# try to read all string typed fields from xml into struct
meta_data = Enum.reduce string_fields, meta_data, fn(key, meta_data) ->
Map.put meta_data, key, get_text.(key)
end
# TODO: read special fields like image
meta_data
end
defp parse_image(node) do
# TODO: parse image node
end
def parse_entries(document) do
entries = XmlNode.all(document, "/rss/channel/item")
Enum.map entries, &parse_entry(&1)
end
def parse_entry(node) do
title = XmlNode.text_for_node(node, "title")
link = XmlNode.text_for_node(node, "link")
description = XmlNode.text_for_node(node, "description")
%Entry{title: title, link: link, description: description}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment