diff options
| author | John Conway <john.a.conway@gmail.com> | 2019-05-08 10:37:10 +0100 |
|---|---|---|
| committer | John Conway <john.a.conway@gmail.com> | 2019-05-08 10:37:10 +0100 |
| commit | f45b14403744f99ae265cff2e05e98e74836e501 (patch) | |
| tree | fa2bc6022bb42411bf8b001f857a107f4b6ed71f /src/feednim/atom.nim | |
| parent | ed9adeb45b0f8d25585df8fdc5e769be021fa1b2 (diff) | |
| download | feed-nim-f45b14403744f99ae265cff2e05e98e74836e501.tar.gz feed-nim-f45b14403744f99ae265cff2e05e98e74836e501.zip | |
Changed tothe Nimble package structure
Diffstat (limited to 'src/feednim/atom.nim')
| -rw-r--r-- | src/feednim/atom.nim | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/src/feednim/atom.nim b/src/feednim/atom.nim new file mode 100644 index 0000000..cce9c44 --- /dev/null +++ b/src/feednim/atom.nim @@ -0,0 +1,187 @@ +# Nim Atom Syndication Format module + +# Written by John Conway +# Released under the MIT open source license. + +import httpclient +import strutils +import sequtils +import xmlparser +import xmltree +import streams +import sugar + +type + Atom* = object + author: AtomAuthor # Sugar, not in Atom spec. Returns the first author. + id*: string # Required Atom field + title*: string # Required Atom field + updated*: string # Required Atom field + authors*: seq[AtomAuthor] # Pleuralised because the Atom spec allows more than one + category*: seq[string] + generator*: string + icon*: string + link*: AtomLink + logo*: string + rights*: string + subtitle*: string + entrys*: seq[AtomEntry] + + AtomAuthor* = object + name*: string # Required Atom field + url*: string + email*: string + + AtomImage* = object + url*: string + title*: string + link*: string + width*: string + height*: string + description*: string + + AtomLink* = object + href*: string + rel*: string + linktype*: string + hreflang*: string + title*: string + length*: string + + AtomEntry* = object + id*: string # Required Atom field + title*: string # Required Atom field + updated*: string # Required Atom field + author: AtomAuthor # Sugar, not in Atom spec. Returns the first author. + authors*: seq[AtomAuthor] # Pleuralised because the Atom spec allows more than one + category*: seq[string] + content*: string + contentSrc*: string + contentType*: string + link*: AtomLink + published*: string + rights*: string + source*: string + summary*: string + + +proc parseEntry( node: XmlNode) : AtomEntry = + var entry: AtomEntry = AtomEntry() + + # Fill the required fields + entry.id = node.child("id").innerText + entry.title = node.child("title").innerText + entry.updated = node.child("updated").innerText + + # Fill the optinal fields + if node.child("author") != nil: + for athr_node in node.findAll("author"): + var author: AtomAuthor = AtomAuthor() + author.name = athr_node.child("name").innerText + if athr_node.child("url") != nil: author.url = athr_node.child("url").innerText + if athr_node.child("email") != nil: author.email = athr_node.child("email").innerText + entry.authors.add(author) + + if node.child("category") != nil: + entry.category = map(node.findAll("category"), (x: XmlNode) -> string => x.innerText) + + if node.child("content") != nil: + entry.content = node.child("content").innerText + if node.attrs != nil: + if node.attr("type") != "": entry.contentType = node.attr("type") + if node.attr("src") != "": entry.contentSrc = node.attr("src") + + if node.child("contributer") != nil: + for con_node in node.findAll("author"): + var author: AtomAuthor = AtomAuthor() + if con_node.child("name") != nil: author.name = con_node.child("name").innerText + if con_node.child("url") != nil: author.url = con_node.child("url").innerText + if con_node.child("email") != nil: author.email = con_node.child("email").innerText + entry.authors.add(author) + + if node.child("link") != nil: + if node.attrs != nil: + if node.attr("href") != "": entry.link.href = node.attr("href") + if node.attr("rel") != "": entry.link.rel = node.attr("rel") + if node.attr("type") != "": entry.link.linktype = node.attr("type") + if node.attr("hreflang") != "": entry.link.rel = node.attr("hreflang") + if node.attr("title") != "": entry.link.rel = node.attr("title") + if node.attr("length") != "": entry.link.rel = node.attr("length") + + if node.child("published") != nil: entry.published = node.child("published").innerText + + if node.child("rights") != nil: entry.rights = node.child("rights").innerText + + if node.child("summary") != nil: entry.summary = node.child("summary").innerText + + # SUGAR an easy way to access an author + if entry.authors.len() > 0: + entry.author = entry.authors[0] + else: + entry.author = AtomAuthor() + + return entry + +proc parseAtom*(data: string): Atom = + ## Parses the Atom from the given string. + + # Parse into XML. + let node: XmlNode = parseXML(newStringStream(data)) + + # Create the return object. + var atom: Atom = Atom() + + # Fill in the required fields + atom.id = node.child("id").innerText + atom.title = node.child("title").innerText + atom.updated = node.child("updated").innerText + + # Fill in the optional fields + if node.child("author") != nil: + for athr_node in node.findAll("author"): + var author: AtomAuthor = AtomAuthor() + author.name = athr_node.child("name").innerText + if athr_node.child("url") != nil: author.url = athr_node.child("url").innerText + if athr_node.child("email") != nil: author.email = athr_node.child("email").innerText + atom.authors.add(author) + + if node.child("category") != nil: + atom.category = map(node.findAll("category"), (x: XmlNode) -> string => x.innerText) + + if node.child("generator") != nil: atom.generator = node.child("generator").innerText + + if node.child("icon") != nil: atom.icon = node.child("icon").innerText + + if node.child("link") != nil: + if node.attrs != nil: + if node.attr("href") != "": atom.link.href = node.attr("href") + if node.attr("rel") != "": atom.link.rel = node.attr("rel") + if node.attr("type") != "": atom.link.linktype = node.attr("type") + if node.attr("hreflang") != "": atom.link.rel = node.attr("hreflang") + if node.attr("title") != "": atom.link.rel = node.attr("title") + if node.attr("length") != "": atom.link.rel = node.attr("length") + + if node.child("logo") != nil: atom.logo = node.child("logo").innerText + + if node.child("rights") != nil: atom.rights = node.child("rights").innerText + + if node.child("subtitle") != nil: atom.subtitle = node.child("subtitle").innerText + + if atom.authors.len() > 0: + atom.author = atom.authors[0] + else: + atom.author = AtomAuthor() + + # If there are no entrys: + if node.child("entry") == nil: + atom.entrys = @[] + return atom + + # Otherwise, add the entrys. + if node.child("entry") != nil: + atom.entrys = map( node.findAll("entry"), parseEntry ) + + # Return the Atom data. + return atom + + |
