diff options
| -rw-r--r-- | src/feednim/atom.nim | 15 | ||||
| -rw-r--r-- | src/feednim/rss.nim | 50 | ||||
| -rwxr-xr-x | tests/test_atom | bin | 493736 -> 493736 bytes | |||
| -rwxr-xr-x | tests/test_rss | bin | 0 -> 449976 bytes | |||
| -rw-r--r-- | tests/test_rss.nim | 88 | ||||
| -rw-r--r-- | tests/test_rss.xml | 59 |
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 Binary files differindex 6df3143..2c75d21 100755 --- a/tests/test_atom +++ b/tests/test_atom diff --git a/tests/test_rss b/tests/test_rss Binary files differnew file mode 100755 index 0000000..7521afe --- /dev/null +++ b/tests/test_rss 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 |
