aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/feednim/atom.nim15
-rw-r--r--src/feednim/rss.nim50
-rwxr-xr-xtests/test_atombin493736 -> 493736 bytes
-rwxr-xr-xtests/test_rssbin0 -> 449976 bytes
-rw-r--r--tests/test_rss.nim88
-rw-r--r--tests/test_rss.xml59
6 files changed, 189 insertions, 23 deletions
diff --git a/src/feednim/atom.nim b/src/feednim/atom.nim
index 431bd5e..a432844 100644
--- a/src/feednim/atom.nim
+++ b/src/feednim/atom.nim
@@ -12,7 +12,7 @@ import streams
import sugar
type
- AtomCommon = ref object of RootObj
+ AtomCommon = ref object of RootObj # These properties aren't gathered yet
xmlbase*: string
xmllang*: string
@@ -92,7 +92,7 @@ type
# Promotes text node to the top of an AtomText object if caller expects a string
-converter toString*(obj: AtomText): string =
+converter atomToString*(obj: AtomText): string =
return obj.text
@@ -250,16 +250,13 @@ proc parseAtom* ( data: string ): Atom =
else:
atom.author = AtomAuthor()
- # If there are no entries:
- if node.child("entry") == nil:
+
+ if node.child("entry") == nil: # If there are no entries:
atom.entries = @[]
return atom
- # Otherwise, add the entries.
- if node.child("entry") != nil:
+ if node.child("entry") != nil: # Otherwise, add the entries.
atom.entries = map( node.findAll("entry"), parseEntry )
# Return the Atom data.
- return atom
-
-
+ return atom \ No newline at end of file
diff --git a/src/feednim/rss.nim b/src/feednim/rss.nim
index abd4883..91fc0a4 100644
--- a/src/feednim/rss.nim
+++ b/src/feednim/rss.nim
@@ -24,18 +24,24 @@ type
webMaster*: string
pubDate*: string
lastBuildDate*: string
- category*: seq[string]
+ categories*: seq[RSSCategory]
generator*: string
docs*: string
cloud*: RSSCloud
- ttl*: string
+ ttl*: int
image*: RSSImage
rating*: string
textInput*: RSSTextInput
- skipHours*: seq[string]
+ skipHours*: seq[int]
skipDays*: seq[string]
items*: seq[RSSItem]
+ RSSText = ref object of RootObj
+ text*: string
+
+ RSSCategory = ref object of RSSText
+ domain*: string
+
RSSEnclosure* = object
url*: string
length*: string
@@ -62,20 +68,36 @@ type
name*: string
link*: string
+ RSSSource* = ref object of RSSText
+ url*: string
+
RSSItem* = object
title*: string
link*: string
description*: string
author*: string
- category*: seq[string]
+ categories*: seq[RSSCategory]
comments*: string
enclosure*: RSSEnclosure
guid*: string
pubDate*: string
- sourceUrl*: string
- sourceText*: string
+ source*: RSSSource
+
+converter rssToString*(obj: RSSText): string =
+ return obj.text
+
+func parseCategories( node: XmlNode ): seq[RSSCategory] =
+ var categories:seq[RSSCategory]
+ for cat_node in node.findAll("category"):
+ var category: RSSCategory = RSSCategory()
+ if cat_node.attr("domain") != "": category.domain = cat_node.attr("domain")
+ category.text = cat_node.innerText
+ categories.add(category)
+ if categories.len == 0: return @[]
+ return categories
+
-proc parseItem( node: XmlNode) : RSSItem =
+func parseItem( node: XmlNode) : RSSItem =
var item: RSSItem = RSSItem()
if node.child("title") != nil: item.title = node.child("title").innerText
@@ -86,8 +108,7 @@ proc parseItem( node: XmlNode) : RSSItem =
for key in @["author", "dc:creator"]:
if node.child(key) != nil: item.author = node.child(key).innerText
- if node.child("category") != nil:
- item.category = map(node.findAll("category"), (x: XmlNode) -> string => x.innerText)
+ if node.child("category") != nil: item.categories = node.parseCategories()
if node.child("comments") != nil: item.comments = node.child("comments").innerText
@@ -103,8 +124,9 @@ proc parseItem( node: XmlNode) : RSSItem =
if node.child("pubDate") != nil: item.pubDate = node.child("pubDate").innerText
if node.child("source") != nil:
- item.sourceUrl = node.child("source").attr("url")
- item.sourceText = node.child("source").innerText
+ item.source = RSSSource()
+ item.source.url = node.child("source").attr("url")
+ item.source.text = node.child("source").innerText
return item
@@ -140,7 +162,7 @@ proc parseRSS*(data: string): RSS =
if channel.child("lastBuildDate") != nil: rss.lastBuildDate = channel.child("lastBuildDate").innerText
- if channel.child("category") != nil: rss.category = map(channel.findAll("category"), (x: XmlNode) -> string => x.innerText)
+ if channel.child("category") != nil: rss.categories = channel.parseCategories()
for key in @["generator", "dc:publisher"]:
if channel.child(key) != nil: rss.generator = channel.child(key).innerText
@@ -156,7 +178,7 @@ proc parseRSS*(data: string): RSS =
cloud.protocol = channel.child("cloud").attr("protocol")
rss.cloud = cloud
- if channel.child("ttl") != nil: rss.ttl = channel.child("ttl").innerText
+ if channel.child("ttl") != nil: rss.ttl = channel.child("ttl").innerText.parseInt()
if channel.child("image") != nil:
var image: RSSImage = RSSImage()
@@ -181,7 +203,7 @@ proc parseRSS*(data: string): RSS =
rss.textInput = textInput
if channel.child("skipHours") != nil:
- rss.skipHours = map(channel.findAll("hour"), (x: XmlNode) -> string => x.innerText)
+ rss.skipHours = map(channel.findAll("hour"), (x: XmlNode) -> int => x.innerText.parseInt() )
if channel.child("skipDays") != nil:
rss.skipDays = map(channel.findAll("day"), (x: XmlNode) -> string => x.innerText)
diff --git a/tests/test_atom b/tests/test_atom
index 6df3143..2c75d21 100755
--- a/tests/test_atom
+++ b/tests/test_atom
Binary files differ
diff --git a/tests/test_rss b/tests/test_rss
new file mode 100755
index 0000000..7521afe
--- /dev/null
+++ b/tests/test_rss
Binary files differ
diff --git a/tests/test_rss.nim b/tests/test_rss.nim
new file mode 100644
index 0000000..b5dc044
--- /dev/null
+++ b/tests/test_rss.nim
@@ -0,0 +1,88 @@
+# This is just an example to get you started. You may wish to put all of your
+# tests into a single file, or separate them into multiple `test1`, `test2`
+# etc. files (better names are recommended, just make sure the name starts with
+# the letter 't').
+#
+# To run these tests, simply execute `nimble test`.
+
+import unittest
+
+import marshal
+
+import feednim
+import ../src/feednim/Rss
+
+test "Read Valid Rss Feed":
+ let feed = "./tests/test_rss.xml".loadRss()
+
+ check feed.title == "Bloggs's Planes Trains and Automobiles"
+
+ check feed.link == "http://joe.bloggs"
+
+ check feed.description == "About Trains, Planes, and Automobiles."
+
+ check feed.language == "en-uk"
+ check feed.copyright == "Copyright Joe and Jane Bloggs"
+ check feed.managingEditor == "mail@joe.bloggs (Joe Bloggs)"
+ check feed.webMaster == "master@joe.bloggs (Joe Bloggs)"
+ check feed.pubDate == "Sat, 07 Sep 2002 00:00:01 GMT"
+ check feed.lastBuildDate == "Sat, 07 Sep 2002 00:00:01 GMT"
+
+ var feed_categories_0:string = feed.categories[0]
+ var feed_categories_1:string = feed.categories[1]
+ var feed_categories_2:string = feed.categories[2]
+ check feed.categories[0].domain == "http://awesomecategories.org"
+ check feed_categories_0 == "Planes"
+ check feed_categories_1 == "Trains"
+ check feed_categories_2 == "Automobiles"
+
+ check feed.generator == "Jester"
+ check feed.docs == "http://blogs.law.harvard.edu/tech/rss"
+
+ check feed.cloud.domain == "rpc.sys.com"
+ check feed.cloud.port == "80"
+ check feed.cloud.path == "/RPC2"
+ check feed.cloud.registerProcedure == "pingMe"
+ check feed.cloud.protocol == "soap"
+
+ check feed.ttl == 60
+
+ check feed.image.url == "http://joe.bloggs/mug.jpg"
+ check feed.image.title == "Bloggs's Planes Trains and Automobiles"
+ check feed.image.link == "http://joe.bloggs"
+
+ check feed.rating == "AO"
+
+ check feed.skipHours[0] == 0
+ check feed.skipHours[1] == 1
+ check feed.skipHours[2] == 2
+ check feed.skipHours[3] == 3
+ check feed.skipHours[4] == 4
+
+ check feed.skipDays[0] == "Saturday"
+ check feed.skipDays[1] == "Sunday"
+
+ check feed.textInput.title == "Search"
+ check feed.textInput.description == "Search for Trains!"
+ check feed.textInput.name == "Search Term"
+ check feed.textInput.link == "http://joe.bloggs/search.cgi"
+
+ check feed.items[0].title == "Aeroplanes not Airplanes"
+ check feed.items[0].link == "http://joe.bloggs/posts/1"
+ check feed.items[0].pubDate == "Sat, 07 Sep 2002 00:00:01 GMT"
+ check feed.items[0].description == "Aero- not air-, fools!"
+ check feed.items[0].author == "jane@joe.bloggs (Jane Bloggs)"
+
+ var feed_items_0_category_0:string = feed.items[0].categories[0]
+ check feed.items[0].categories[0].domain == "http://awesomecategories.org"
+ check feed_items_0_category_0 == "Words"
+
+ check feed.items[0].comments == "http://joe.bloggs/posts/1/comments"
+ check feed.items[0].enclosure.url == "http://www.scripting.com/mp3s/weatherReportSuite.mp3"
+ check feed.items[0].enclosure.length == "12216320"
+ check feed.items[0].enclosure.enclosureType == "audio/mpeg"
+ check feed.items[0].guid == "http://joe.bloggs/posts/1"
+
+ var feed_items_0_source:string = feed.items[0].source
+ check feed.items[0].source.url == "http://dictionary.com"
+ check feed_items_0_source == "The Dictionary"
diff --git a/tests/test_rss.xml b/tests/test_rss.xml
new file mode 100644
index 0000000..4432d9e
--- /dev/null
+++ b/tests/test_rss.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0">
+ <channel>
+ <title>Bloggs's Planes Trains and Automobiles</title>
+
+ <link>http://joe.bloggs</link>
+
+ <description>About Trains, Planes, and Automobiles.</description>
+
+ <language>en-uk</language>
+ <copyright>Copyright Joe and Jane Bloggs</copyright>
+ <managingEditor>mail@joe.bloggs (Joe Bloggs)</managingEditor>
+ <webMaster>master@joe.bloggs (Joe Bloggs)</webMaster>
+ <pubDate>Sat, 07 Sep 2002 00:00:01 GMT</pubDate>
+ <lastBuildDate>Sat, 07 Sep 2002 00:00:01 GMT</lastBuildDate>
+
+ <category domain="http://awesomecategories.org">Planes</category>
+ <category>Trains</category>
+ <category>Automobiles</category>
+
+ <generator>Jester</generator>
+ <docs>http://blogs.law.harvard.edu/tech/rss</docs>
+
+ <cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="pingMe" protocol="soap" />
+
+ <ttl>60</ttl>
+ <image>
+ <url>http://joe.bloggs/mug.jpg</url>
+ <title>Bloggs's Planes Trains and Automobiles</title>
+ <link>http://joe.bloggs</link>
+ </image>
+
+ <rating>AO</rating>
+
+ <skipHours><hour>0</hour><hour>1</hour><hour>2</hour><hour>3</hour><hour>4</hour></skipHours>
+ <skipDays><day>Saturday</day><day>Sunday</day></skipDays>
+
+ <textInput>
+ <title>Search</title>
+ <description>Search for Trains!</description>
+ <name>Search Term</name>
+ <link>http://joe.bloggs/search.cgi</link>
+ </textInput>
+
+ <item>
+ <title>Aeroplanes not Airplanes</title>
+ <link>http://joe.bloggs/posts/1</link>
+ <pubDate>Sat, 07 Sep 2002 00:00:01 GMT</pubDate>
+ <description>Aero- not air-, fools!</description>
+ <author>jane@joe.bloggs (Jane Bloggs)</author>
+ <category domain="http://awesomecategories.org" >Words</category>
+ <comments>http://joe.bloggs/posts/1/comments</comments>
+ <enclosure url="http://www.scripting.com/mp3s/weatherReportSuite.mp3" length="12216320" type="audio/mpeg" />
+ <guid>http://joe.bloggs/posts/1</guid>
+ <source url="http://dictionary.com">The Dictionary</source>
+ </item>
+
+ </channel>
+</rss> \ No newline at end of file