parse and aggregate
This commit is contained in:
parent
d6f89af4f6
commit
60b16577ae
5 changed files with 154 additions and 0 deletions
2
Containerfile
Normal file
2
Containerfile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ARG fedoraVersion=40
|
||||
FROM quay.io/fedora/fedora-minimal:${fedoraVersion}
|
||||
1
config.nims
Normal file
1
config.nims
Normal file
|
|
@ -0,0 +1 @@
|
|||
switch("d", "ssl")
|
||||
19
rssmix.nimble
Normal file
19
rssmix.nimble
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Package
|
||||
|
||||
version = "0.1.0"
|
||||
author = "mr-boneman"
|
||||
description = "mix rss feeds"
|
||||
license = "MIT"
|
||||
srcDir = "src"
|
||||
bin = @["rssmix"]
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
requires "nim >= 2.0.8"
|
||||
requires "mummy"
|
||||
requires "parsetoml"
|
||||
requires "jsony"
|
||||
requires "rssatom"
|
||||
requires "puppy"
|
||||
requires "pretty"
|
||||
80
src/rssmix.nim
Normal file
80
src/rssmix.nim
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import std/[algorithm, json, xmltree, times, options, sequtils]
|
||||
import pkg/[mummy, rssatom, puppy, pretty]
|
||||
|
||||
const
|
||||
atomTimeFormat {.strdefine.} = "yyyy-MM-dd'T'HH:mm:ss'Z'"
|
||||
rssv2TimeFormat {.strdefine.} = "ddd',' dd MMM yyyy HH:mm:ss ZZZ"
|
||||
|
||||
type RssFeed = object # name:string
|
||||
url: string
|
||||
kind: FeedType
|
||||
|
||||
proc parseAtomTime(s: string): DateTime =
|
||||
parse(s, atomTimeFormat)
|
||||
|
||||
proc parseRSSv2Time(s: string): DateTime =
|
||||
parse(s, rssv2TimeFormat)
|
||||
|
||||
proc getrssv2Time(r:RssItem):DateTime=
|
||||
result = dateTime(0, Month.low, MonthdayRange.low)
|
||||
if r.pubDate.isSome():
|
||||
result = parseRssv2Time(r.pubDate.get())
|
||||
|
||||
|
||||
proc getTime(r: RssItem): DateTime =
|
||||
result = dateTime(0, Month.low, MonthdayRange.low)
|
||||
if r.updated.isSome():
|
||||
result = parseAtomTime(r.updated.get())
|
||||
elif r.pubDate.isSome():
|
||||
result = parseAtomTime(r.pubDate.get())
|
||||
|
||||
proc cmpRssItem(x, y: RssItem): int =
|
||||
cmp(x.getTime(), y.getTime())
|
||||
|
||||
proc mixRssFeeds(feeds: seq[RssFeed]): RSS =
|
||||
result = RSS()
|
||||
result.id = "https://example.com/".some()
|
||||
result.title = "This is a test".some()
|
||||
result.link = "link.com".some()
|
||||
result.author.name = "Samuel R.".some()
|
||||
result.description = "this is a test for this and that".some()
|
||||
var entries: seq[RSS]
|
||||
for feed in feeds:
|
||||
case feed.kind
|
||||
of Atom:
|
||||
entries.add parseAtom(fetch(feed.url))
|
||||
of RSSv2:
|
||||
entries.add parseRss(fetch(feed.url))
|
||||
|
||||
entries[^1].items = entries[^1].items.mapIt(
|
||||
block:
|
||||
var item = it
|
||||
item.pubdate = some(getRssv2Time(item).format(atomTimeFormat))
|
||||
item
|
||||
)
|
||||
|
||||
for feed in entries:
|
||||
result.items.add feed.items
|
||||
|
||||
result.items.sort(cmp = cmpRssItem, order = Descending)
|
||||
|
||||
proc assembleAtom(r: RSS): XmlNode =
|
||||
result = buildAtom(r)
|
||||
result.attrs = {
|
||||
"xmlns": "http://www.w3.org/2005/Atom",
|
||||
"xmlns:thr": "http://purl.org/syndication/thread/1.0",
|
||||
"xml:lang": "en-EN"
|
||||
}.toXmlAttributes()
|
||||
|
||||
discard
|
||||
|
||||
echo assembleAtom(
|
||||
mixRssFeeds(
|
||||
@[
|
||||
RssFeed(kind: Atom, url: "https://github.com/nim-lang/Nim/releases.atom"),
|
||||
RssFeed(kind: Atom, url: "https://github.com/fatedier/frp/releases.atom"),
|
||||
RssFeed(kind: RSSv2, url: "https://fedoramagazine.org/rss"),
|
||||
RssFeed(kind: RSSv2, url: "http://communityblog.fedoraproject.org/?feed=rss2"),
|
||||
]
|
||||
)
|
||||
)
|
||||
52
src/tomlToJson.nim
Normal file
52
src/tomlToJson.nim
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import std/[json, math, tables, sequtils]
|
||||
import pkg/parsetoml
|
||||
|
||||
proc customToJson*(table: parsetoml.TomlTableRef): JsonNode
|
||||
|
||||
proc customToJson*(value: parsetoml.TomlValueRef): JsonNode =
|
||||
case value.kind
|
||||
of TomlValueKind.Int:
|
||||
%*value.intVal
|
||||
of TomlValueKind.Float:
|
||||
if classify(value.floatVal) == fcNan:
|
||||
if value.forcedSign != Pos:
|
||||
%*value.floatVal
|
||||
else:
|
||||
%*value.floatVal
|
||||
else:
|
||||
%*value.floatVal
|
||||
of TomlValueKind.Bool:
|
||||
%* $value.boolVal
|
||||
of TomlValueKind.Datetime:
|
||||
if value.dateTimeVal.shift == false:
|
||||
%*value.dateTimeVal
|
||||
else:
|
||||
%*value.dateTimeVal
|
||||
of TomlValueKind.Date:
|
||||
%*value.dateVal
|
||||
of TomlValueKind.Time:
|
||||
%*value.timeVal
|
||||
of TomlValueKind.String:
|
||||
%*value.stringVal
|
||||
of TomlValueKind.Array:
|
||||
if value.arrayVal.len == 0:
|
||||
when defined(newtestsuite):
|
||||
%[]
|
||||
else:
|
||||
%*[]
|
||||
elif value.arrayVal[0].kind == TomlValueKind.Table:
|
||||
%value.arrayVal.map(customToJson)
|
||||
else:
|
||||
when defined(newtestsuite):
|
||||
%*value.arrayVal.map(customToJson)
|
||||
else:
|
||||
%*value.arrayVal.map(customToJson)
|
||||
of TomlValueKind.Table:
|
||||
value.tableVal.customToJson()
|
||||
of TomlValueKind.None:
|
||||
%*{"type": "ERROR"}
|
||||
|
||||
proc customToJson*(table: parsetoml.TomlTableRef): JsonNode =
|
||||
result = newJObject()
|
||||
for key, value in pairs(table):
|
||||
result[key] = value.customToJson
|
||||
Loading…
Add table
Add a link
Reference in a new issue