From e1b3e9db7612875b9967875be3e3f2aa43a4d237 Mon Sep 17 00:00:00 2001 From: Zed <zedeus@pm.me> Date: Fri, 8 Jan 2021 02:25:43 +0100 Subject: [PATCH] Add proper http support Fixes #223 --- src/config.nim | 1 - src/formatters.nim | 8 +++- src/nitter.nim | 3 +- src/routes/rss.nim | 14 +++---- src/routes/search.nim | 7 +--- src/types.nim | 1 - src/views/general.nim | 8 +--- src/views/rss.nimf | 97 +++++++++++++++++++++++-------------------- 8 files changed, 70 insertions(+), 69 deletions(-) diff --git a/src/config.nim b/src/config.nim index 89e81e3..f24e9aa 100644 --- a/src/config.nim +++ b/src/config.nim @@ -24,7 +24,6 @@ proc getConfig*(path: string): (Config, parseCfg.Config) = base64Media: cfg.get("Config", "base64Media", false), minTokens: cfg.get("Config", "tokenCount", 10), - cacheDir: cfg.get("Cache", "directory", "/tmp/nitter"), listCacheTime: cfg.get("Cache", "listMinutes", 120), rssCacheTime: cfg.get("Cache", "rssMinutes", 10), diff --git a/src/formatters.nim b/src/formatters.nim index 5707393..5136701 100644 --- a/src/formatters.nim +++ b/src/formatters.nim @@ -18,6 +18,10 @@ const twitter = parseUri("https://twitter.com") +proc getUrlPrefix*(cfg: Config): string = + if cfg.useHttps: "https://" & cfg.hostname + else: "http://" & cfg.hostname + proc stripHtml*(text: string): string = var html = parseHtml(text) for el in html.findAll("a"): @@ -48,7 +52,7 @@ proc replaceUrl*(url: string; prefs: Prefs; absolute=""): string = result = result.replace(cards, prefs.replaceTwitter & "/cards") result = result.replace(twRegex, prefs.replaceTwitter) if absolute.len > 0: - result = result.replace("href=\"/", "href=\"https://" & absolute & "/") + result = result.replace("href=\"/", "href=\"" & absolute & "/") proc getM3u8Url*(content: string): string = var m: RegexMatch @@ -69,7 +73,7 @@ proc getUserpic*(profile: Profile; style=""): string = getUserPic(profile.userpic, style) proc getVideoEmbed*(cfg: Config; id: int64): string = - &"https://{cfg.hostname}/i/videos/{id}" + &"{getUrlPrefix(cfg)}/i/videos/{id}" proc pageTitle*(profile: Profile): string = &"{profile.fullname} (@{profile.username})" diff --git a/src/nitter.nim b/src/nitter.nim index 586cd4e..3eee87b 100644 --- a/src/nitter.nim +++ b/src/nitter.nim @@ -21,8 +21,7 @@ when defined(release): addHandler(newConsoleLogger()) setLogFilter(lvlError) -let http = if cfg.useHttps: "https" else: "http" -stdout.write &"Starting Nitter at {http}://{cfg.hostname}\n" +stdout.write &"Starting Nitter at {getUrlPrefix(cfg)}\n" stdout.flushFile updateDefaultPrefs(fullCfg) diff --git a/src/routes/rss.nim b/src/routes/rss.nim index 2ecef89..69264a6 100644 --- a/src/routes/rss.nim +++ b/src/routes/rss.nim @@ -9,7 +9,7 @@ include "../views/rss.nimf" export times, hashes, supersnappy -proc showRss*(req: Request; hostname: string; query: Query): Future[Rss] {.async.} = +proc timelineRss*(req: Request; cfg: Config; query: Query): Future[Rss] {.async.} = var profile: Profile var timeline: Timeline let @@ -35,8 +35,7 @@ proc showRss*(req: Request; hostname: string; query: Query): Future[Rss] {.async return Rss(feed: profile.username, cursor: "suspended") if profile.fullname.len > 0: - let rss = compress renderTimelineRss(timeline, profile, hostname, - multi=(names.len > 1)) + let rss = compress renderTimelineRss(timeline, profile, cfg, multi=(names.len > 1)) return Rss(feed: rss, cursor: timeline.bottom) template respRss*(rss) = @@ -44,6 +43,7 @@ template respRss*(rss) = resp Http404, showError("User \"" & @"name" & "\" not found", cfg) elif rss.cursor.len == 9 and rss.cursor == "suspended": resp Http404, showError(getSuspended(rss.feed), cfg) + let headers = {"Content-Type": "application/rss+xml; charset=utf-8", "Min-Id": rss.cursor} resp Http200, headers, uncompress rss.feed @@ -69,7 +69,7 @@ proc createRssRouter*(cfg: Config) = let tweets = await getSearch[Tweet](query, cursor) rss.cursor = tweets.bottom rss.feed = compress renderSearchRss(tweets.content, query.text, - genQueryUrl(query), cfg.hostname) + genQueryUrl(query), cfg) await cacheRss(key, rss) respRss(rss) @@ -85,7 +85,7 @@ proc createRssRouter*(cfg: Config) = if rss.cursor.len > 0: respRss(rss) - rss = await showRss(request, cfg.hostname, Query(fromUser: @[name])) + rss = await timelineRss(request, cfg, Query(fromUser: @[name])) await cacheRss(key, rss) respRss(rss) @@ -110,7 +110,7 @@ proc createRssRouter*(cfg: Config) = if rss.cursor.len > 0: respRss(rss) - rss = await showRss(request, cfg.hostname, query) + rss = await timelineRss(request, cfg, query) await cacheRss(key, rss) respRss(rss) @@ -129,7 +129,7 @@ proc createRssRouter*(cfg: Config) = list = await getCachedList(@"name", @"list") timeline = await getListTimeline(list.id, cursor) rss.cursor = timeline.bottom - rss.feed = compress renderListRss(timeline.content, list, cfg.hostname) + rss.feed = compress renderListRss(timeline.content, list, cfg) await cacheRss(key, rss) respRss(rss) diff --git a/src/routes/search.nim b/src/routes/search.nim index 9eba1ea..329d955 100644 --- a/src/routes/search.nim +++ b/src/routes/search.nim @@ -39,10 +39,7 @@ proc createSearchRouter*(cfg: Config) = redirect("/search?q=" & encodeUrl("#" & @"hash")) get "/opensearch": - var url = "" - if cfg.useHttps: - url = "https://" & cfg.hostname & "/search?q=" - else: - url = "http://" & cfg.hostname & "/search?q=" + var url = if cfg.useHttps: "https://" else: "http://" + url &= cfg.hostname & "/search?q=" resp Http200, {"Content-Type": "application/opensearchdescription+xml"}, generateOpenSearchXML(cfg.title, cfg.hostname, url) diff --git a/src/types.nim b/src/types.nim index 756b277..4c48020 100644 --- a/src/types.nim +++ b/src/types.nim @@ -211,7 +211,6 @@ type base64Media*: bool minTokens*: int - cacheDir*: string rssCacheTime*: int listCacheTime*: int diff --git a/src/views/general.nim b/src/views/general.nim index 26ccf80..341e3c0 100644 --- a/src/views/general.nim +++ b/src/views/general.nim @@ -40,11 +40,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; titleText=""; desc=""; video=""; elif images.len > 0: "photo" else: "article" - var opensearchUrl = "" - if cfg.useHttps: - opensearchUrl = "https://" & cfg.hostname & "/opensearch" - else: - opensearchUrl = "http://" & cfg.hostname & "/opensearch" + let opensearchUrl = getUrlPrefix(cfg) & "/opensearch" buildHtml(head): link(rel="stylesheet", type="text/css", href="/css/style.css?v=3") @@ -93,7 +89,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; titleText=""; desc=""; video=""; let preloadUrl = getPicUrl(url & suffix) link(rel="preload", type="image/png", href=preloadUrl, `as`="image") - let image = "https://" & cfg.hostname & getPicUrl(url) + let image = getUrlPrefix(cfg) & getPicUrl(url) meta(property="og:image", content=image) meta(property="twitter:image:src", content=image) diff --git a/src/views/rss.nimf b/src/views/rss.nimf index f690a46..720a3ed 100644 --- a/src/views/rss.nimf +++ b/src/views/rss.nimf @@ -19,51 +19,58 @@ #end if #end proc # -#proc renderRssTweet(tweet: Tweet; prefs: Prefs; hostname: string): string = +#proc getDescription(desc: string; cfg: Config): string = +Twitter feed for: ${desc}. Generated by ${cfg.hostname} +#end proc +# +#proc renderRssTweet(tweet: Tweet; prefs: Prefs; cfg: Config): string = #let tweet = tweet.retweet.get(tweet) -#let text = replaceUrl(tweet.text, prefs, absolute=hostname) +#let urlPrefix = getUrlPrefix(cfg) +#let text = replaceUrl(tweet.text, prefs, absolute=urlPrefix) #if tweet.quote.isSome and get(tweet.quote).available: -#let quoteLink = hostname & getLink(get(tweet.quote)) -<p>${text}<br><a href="https://${quoteLink}">${quoteLink}</a></p> +# let quoteLink = getLink(get(tweet.quote)) +<p>${text}<br><a href="${urlPrefix}${quoteLink}">${cfg.hostname}${quoteLink}</a></p> #else: <p>${text}</p> #end if #if tweet.photos.len > 0: -#for photo in tweet.photos: -<img src="https://${hostname}${getPicUrl(photo)}" style="max-width:250px;" /> -#end for +# for photo in tweet.photos: +<img src="${urlPrefix}${getPicUrl(photo)}" style="max-width:250px;" /> +# end for #elif tweet.video.isSome: -<img src="https://${hostname}${getPicUrl(get(tweet.video).thumb)}" style="max-width:250px;" /> +<img src="${urlPrefix}${getPicUrl(get(tweet.video).thumb)}" style="max-width:250px;" /> #elif tweet.gif.isSome: -#let thumb = &"https://{hostname}{getPicUrl(get(tweet.gif).thumb)}" -#let url = &"https://{hostname}{getPicUrl(get(tweet.gif).url)}" +# let thumb = &"{urlPrefix}{getPicUrl(get(tweet.gif).thumb)}" +# let url = &"{urlPrefix}{getPicUrl(get(tweet.gif).url)}" <video poster="${thumb}" autoplay muted loop style="max-width:250px;"> <source src="${url}" type="video/mp4"</source></video> #end if #end proc # -#proc renderRssTweets(tweets: seq[Tweet]; prefs: Prefs; hostname: string): string = +#proc renderRssTweets(tweets: seq[Tweet]; prefs: Prefs; cfg: Config): string = +#let urlPrefix = getUrlPrefix(cfg) #var links: seq[string] #for t in tweets: -#let retweet = if t.retweet.isSome: t.profile.username else: "" -#let tweet = if retweet.len > 0: t.retweet.get else: t -#let link = getLink(tweet) -#if link in links: continue -#end if -#links.add link -<item> - <title>${getTitle(tweet, prefs, retweet)}</title> - <dc:creator>@${tweet.profile.username}</dc:creator> - <description><![CDATA[${renderRssTweet(tweet, prefs, hostname).strip(chars={'\n'})}]]></description> - <pubDate>${getRfc822Time(tweet)}</pubDate> - <guid>https://${hostname & link}</guid> - <link>https://${hostname & link}</link> -</item> +# let retweet = if t.retweet.isSome: t.profile.username else: "" +# let tweet = if retweet.len > 0: t.retweet.get else: t +# let link = getLink(tweet) +# if link in links: continue +# end if +# links.add link + <item> + <title>${getTitle(tweet, prefs, retweet)}</title> + <dc:creator>@${tweet.profile.username}</dc:creator> + <description><![CDATA[${renderRssTweet(tweet, prefs, cfg).strip(chars={'\n'})}]]></description> + <pubDate>${getRfc822Time(tweet)}</pubDate> + <guid>${urlPrefix & link}</guid> + <link>${urlPrefix & link}</link> + </item> #end for #end proc # -#proc renderTimelineRss*(timeline: Timeline; profile: Profile; hostname: string; multi=false): string = -#let prefs = Prefs(replaceTwitter: hostname, replaceYouTube: "invidious.snopyta.org") +#proc renderTimelineRss*(timeline: Timeline; profile: Profile; cfg: Config; multi=false): string = +#let prefs = Prefs(replaceTwitter: cfg.hostname, replaceYouTube: "invidious.snopyta.org") +#let urlPrefix = getUrlPrefix(cfg) #result = "" #let user = (if multi: "" else: "@") & profile.username #var title = profile.fullname @@ -73,29 +80,29 @@ <?xml version="1.0" encoding="UTF-8"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"> <channel> - <atom:link href="https://${hostname}/${profile.username}/rss" rel="self" type="application/rss+xml" /> + <atom:link href="${urlPrefix}/${profile.username}/rss" rel="self" type="application/rss+xml" /> <title>${title}</title> - <link>https://${hostname}/${profile.username}</link> - <description>Twitter feed for: ${user}. Generated by ${hostname}</description> + <link>${urlPrefix}/${profile.username}</link> + <description>${getDescription(user, cfg)}</description> <language>en-us</language> <ttl>40</ttl> <image> <title>${title}</title> - <link>https://${hostname}/${profile.username}</link> - <url>https://${hostname}${getPicUrl(profile.getUserPic(style="_400x400"))}</url> + <link>${urlPrefix}/${profile.username}</link> + <url>${urlPrefix}${getPicUrl(profile.getUserPic(style="_400x400"))}</url> <width>128</width> <height>128</height> </image> - #if timeline.content.len > 0: - ${renderRssTweets(timeline.content, prefs, hostname)} - #end if +#if timeline.content.len > 0: +${renderRssTweets(timeline.content, prefs, cfg)} +#end if </channel> </rss> #end proc # -#proc renderListRss*(tweets: seq[Tweet]; list: List; hostname: string): string = -#let prefs = Prefs(replaceTwitter: hostname, replaceYouTube: "invidious.snopyta.org") -#let link = &"https://{hostname}/{list.username}/lists/{list.name}" +#proc renderListRss*(tweets: seq[Tweet]; list: List; cfg: Config): string = +#let prefs = Prefs(replaceTwitter: cfg.hostname, replaceYouTube: "invidious.snopyta.org") +#let link = &"{getUrlPrefix(cfg)}/{list.username}/lists/{list.name}" #result = "" <?xml version="1.0" encoding="UTF-8"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"> @@ -103,17 +110,17 @@ <atom:link href="${link}" rel="self" type="application/rss+xml" /> <title>${xmltree.escape(list.name)} / @${list.username}</title> <link>${link}</link> - <description>Twitter feed for: ${list.name} by @${list.username}. Generated by ${hostname}</description> + <description>${getDescription(list.name & " by @" & list.username, cfg)}</description> <language>en-us</language> <ttl>40</ttl> - ${renderRssTweets(tweets, prefs, hostname)} +${renderRssTweets(tweets, prefs, cfg)} </channel> </rss> #end proc # -#proc renderSearchRss*(tweets: seq[Tweet]; name, param, hostname: string): string = -#let prefs = Prefs(replaceTwitter: hostname, replaceYouTube: "invidious.snopyta.org") -#let link = &"https://{hostname}/search" +#proc renderSearchRss*(tweets: seq[Tweet]; name, param: string; cfg: Config): string = +#let prefs = Prefs(replaceTwitter: cfg.hostname, replaceYouTube: "invidious.snopyta.org") +#let link = &"{getUrlPrefix(cfg)}/search" #let escName = xmltree.escape(name) #result = "" <?xml version="1.0" encoding="UTF-8"?> @@ -122,10 +129,10 @@ <atom:link href="${link}" rel="self" type="application/rss+xml" /> <title>Search results for "${escName}"</title> <link>${link}</link> - <description>Twitter feed for search "${escName}". Generated by ${hostname}</description> + <description>${getDescription("Search \"" & escName & "\"", cfg)}</description> <language>en-us</language> <ttl>40</ttl> - ${renderRssTweets(tweets, prefs, hostname)} +${renderRssTweets(tweets, prefs, cfg)} </channel> </rss> #end proc -- GitLab