diff --git a/src/formatters.nim b/src/formatters.nim index bb8698c..28bfa1c 100644 --- a/src/formatters.nim +++ b/src/formatters.nim @@ -60,11 +60,11 @@ proc replaceUrls*(body: string; prefs: Prefs; absolute=""): string = result = result.replace("/c/", "/") if prefs.replaceTwitter.len > 0 and ("twitter.com" in body or tco in body): - result = result.replace(tco, https & prefs.replaceTwitter & "/t.co") + result = result.replace(tco, &"{https}{prefs.replaceTwitter}/t.co") result = result.replace(cards, prefs.replaceTwitter & "/cards") result = result.replace(twRegex, prefs.replaceTwitter) result = result.replacef(twLinkRegex, a( - prefs.replaceTwitter & "$2", href = https & prefs.replaceTwitter & "$1")) + prefs.replaceTwitter & "$2", href = &"{https}{prefs.replaceTwitter}$1")) if prefs.replaceReddit.len > 0 and ("reddit.com" in result or "redd.it" in result): result = result.replace(rdShortRegex, prefs.replaceReddit & "/comments/") @@ -76,7 +76,7 @@ proc replaceUrls*(body: string; prefs: Prefs; absolute=""): string = result = result.replace(igRegex, prefs.replaceInstagram) if absolute.len > 0 and "href" in result: - result = result.replace("href=\"/", "href=\"" & absolute & "/") + result = result.replace("href=\"/", &"href=\"{absolute}/") proc getM3u8Url*(content: string): string = var matches: array[1, string] diff --git a/src/query.nim b/src/query.nim index cf9b0e6..d128f6f 100644 --- a/src/query.nim +++ b/src/query.nim @@ -93,11 +93,11 @@ proc genQueryUrl*(query: Query): string = if query.text.len > 0: params.add "q=" & encodeUrl(query.text) for f in query.filters: - params.add "f-" & f & "=on" + params.add &"f-{f}=on" for e in query.excludes: - params.add "e-" & e & "=on" + params.add &"e-{e}=on" for i in query.includes.filterIt(it != "nativeretweets"): - params.add "i-" & i & "=on" + params.add &"i-{i}=on" if query.since.len > 0: params.add "since=" & query.since diff --git a/src/routes/embed.nim b/src/routes/embed.nim index 1a93d40..8690357 100644 --- a/src/routes/embed.nim +++ b/src/routes/embed.nim @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -import asyncdispatch, strutils, options +import asyncdispatch, strutils, strformat, options import jester, karax/vdom import ".."/[types, api] import ../views/[embed, tweet, general] @@ -31,6 +31,6 @@ proc createEmbedRouter*(cfg: Config) = let id = @"id" if id.len > 0: - redirect("/i/status/" & id & "/embed") + redirect(&"/i/status/{id}/embed") else: resp Http404 diff --git a/src/routes/list.nim b/src/routes/list.nim index d466080..c97b1c1 100644 --- a/src/routes/list.nim +++ b/src/routes/list.nim @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -import strutils, uri +import strutils, strformat, uri import jester @@ -10,14 +10,17 @@ export getListTimeline, getGraphList template respList*(list, timeline, title, vnode: typed) = if list.id.len == 0 or list.name.len == 0: - resp Http404, showError("List " & @"id" & " not found", cfg) + resp Http404, showError(&"""List "{@"id"}" not found""", cfg) let html = renderList(vnode, timeline.query, list) - rss = "/i/lists/$1/rss" % [@"id"] + rss = &"""/i/lists/{@"id"}/rss""" resp renderMain(html, request, cfg, prefs, titleText=title, rss=rss, banner=list.banner) +proc title*(list: List): string = + &"@{list.username}/{list.name}" + proc createListRouter*(cfg: Config) = router list: get "/@name/lists/@slug/?": @@ -28,24 +31,22 @@ proc createListRouter*(cfg: Config) = slug = decodeUrl(@"slug") list = await getCachedList(@"name", slug) if list.id.len == 0: - resp Http404, showError("List \"" & @"slug" & "\" not found", cfg) - redirect("/i/lists/" & list.id) + resp Http404, showError(&"""List "{@"slug"}" not found""", cfg) + redirect(&"/i/lists/{list.id}") get "/i/lists/@id/?": cond '.' notin @"id" let prefs = cookiePrefs() list = await getCachedList(id=(@"id")) - title = "@" & list.username & "/" & list.name timeline = await getListTimeline(list.id, getCursor()) vnode = renderTimelineTweets(timeline, prefs, request.path) - respList(list, timeline, title, vnode) + respList(list, timeline, list.title, vnode) get "/i/lists/@id/members": cond '.' notin @"id" let prefs = cookiePrefs() list = await getCachedList(id=(@"id")) - title = "@" & list.username & "/" & list.name members = await getGraphListMembers(list, getCursor()) - respList(list, members, title, renderTimelineUsers(members, prefs, request.path)) + respList(list, members, list.title, renderTimelineUsers(members, prefs, request.path)) diff --git a/src/routes/rss.nim b/src/routes/rss.nim index 40aa6a7..700c215 100644 --- a/src/routes/rss.nim +++ b/src/routes/rss.nim @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -import asyncdispatch, strutils, tables, times, hashes, uri +import asyncdispatch, strutils, strformat, tables, times, hashes, uri import jester @@ -42,8 +42,8 @@ proc timelineRss*(req: Request; cfg: Config; query: Query): Future[Rss] {.async. template respRss*(rss, page) = if rss.cursor.len == 0: let info = case page - of "User": " \"$1\" " % @"name" - of "List": " $1 " % @"id" + of "User": &""" "{@"name"}" """ + of "List": &""" "{@"id"}" """ else: " " resp Http404, showError(page & info & "not found", cfg) @@ -67,7 +67,7 @@ proc createRssRouter*(cfg: Config) = let cursor = getCursor() - key = "search:" & $hash(genQueryUrl(query)) & ":" & cursor + key = &"search:{hash(genQueryUrl(query))}:cursor" var rss = await getCachedRss(key) if rss.cursor.len > 0: @@ -86,7 +86,7 @@ proc createRssRouter*(cfg: Config) = let cursor = getCursor() name = @"name" - key = "twitter:" & name & ":" & cursor + key = &"twitter:{name}:{cursor}" var rss = await getCachedRss(key) if rss.cursor.len > 0: @@ -109,7 +109,7 @@ proc createRssRouter*(cfg: Config) = of "search": initQuery(params(request), name=name) else: Query(fromUser: @[name]) - var key = @"tab" & ":" & @"name" & ":" + var key = &"""{@"tab"}:{@"name"}:""" if @"tab" == "search": key &= $hash(genQueryUrl(query)) & ":" key &= getCursor() @@ -132,11 +132,11 @@ proc createRssRouter*(cfg: Config) = cursor = getCursor() if list.id.len == 0: - resp Http404, showError("List \"" & @"slug" & "\" not found", cfg) + resp Http404, showError(&"""List "{@"slug"}" not found""", cfg) - let url = "/i/lists/" & list.id & "/rss" + let url = &"/i/lists/{list.id}/rss" if cursor.len > 0: - redirect(url & "?cursor=" & encodeUrl(cursor, false)) + redirect(&"{url}?cursor={encodeUrl(cursor, false)}") else: redirect(url) @@ -146,7 +146,7 @@ proc createRssRouter*(cfg: Config) = cursor = getCursor() key = if cursor.len == 0: "lists:" & @"id" - else: "lists:" & @"id" & ":" & cursor + else: &"""lists:{@"id"}:{cursor}""" var rss = await getCachedRss(key) if rss.cursor.len > 0: diff --git a/src/routes/search.nim b/src/routes/search.nim index 3fc44a9..554f2f6 100644 --- a/src/routes/search.nim +++ b/src/routes/search.nim @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -import strutils, uri +import strutils, strformat, uri import jester @@ -37,7 +37,7 @@ proc createSearchRouter*(cfg: Config) = resp Http404, showError("Invalid search", cfg) get "/hashtag/@hash": - redirect("/search?q=" & encodeUrl("#" & @"hash")) + redirect(&"""/search?q={encodeUrl("#" & @"hash")}""") get "/opensearch": let url = getUrlPrefix(cfg) & "/search?q=" diff --git a/src/routes/timeline.nim b/src/routes/timeline.nim index a0a6e21..9d97c29 100644 --- a/src/routes/timeline.nim +++ b/src/routes/timeline.nim @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -import asyncdispatch, strutils, sequtils, uri, options, times +import asyncdispatch, strutils, strformat, sequtils, uri, options, times import jester, karax/vdom import router_utils @@ -102,7 +102,7 @@ proc showTimeline*(request: Request; query: Query; cfg: Config; prefs: Prefs; template respTimeline*(timeline: typed) = let t = timeline if t.len == 0: - resp Http404, showError("User \"" & @"name" & "\" not found", cfg) + resp Http404, showError(&"""User "{@"name"}" not found""", cfg) resp t template respUserId*() = diff --git a/src/views/general.nim b/src/views/general.nim index b18dae5..f242e66 100644 --- a/src/views/general.nim +++ b/src/views/general.nim @@ -81,7 +81,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; title: if titleText.len > 0: - text titleText & " | " & cfg.title + text &"{titleText}|{cfg.title}" else: text cfg.title diff --git a/src/views/renderutils.nim b/src/views/renderutils.nim index 3e0cd19..bab01cd 100644 --- a/src/views/renderutils.nim +++ b/src/views/renderutils.nim @@ -1,11 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-only -import strutils +import strutils, strformat import karax/[karaxdsl, vdom, vstyles] import ".."/[types, utils] proc icon*(icon: string; text=""; title=""; class=""; href=""): VNode = var c = "icon-" & icon - if class.len > 0: c = c & " " & class + if class.len > 0: c = &"{c} {class}" buildHtml(tdiv(class="icon-container")): if href.len > 0: a(class=c, title=title, href=href) diff --git a/src/views/rss.nimf b/src/views/rss.nimf index f910f92..96f6466 100644 --- a/src/views/rss.nimf +++ b/src/views/rss.nimf @@ -117,7 +117,7 @@ ${renderRssTweets(profile.tweets.content, cfg)} ${xmltree.escape(list.name)} / @${list.username} ${link} - ${getDescription(list.name & " by @" & list.username, cfg)} + ${getDescription(&"{list.name} by @{list.username}", cfg)} en-us 40 ${renderRssTweets(tweets, cfg)} @@ -135,7 +135,7 @@ ${renderRssTweets(tweets, cfg)} Search results for "${escName}" ${link} - ${getDescription("Search \"" & escName & "\"", cfg)} + ${getDescription(&"Search \"{escName}\"", cfg)} en-us 40 ${renderRssTweets(tweets, cfg)} diff --git a/src/views/tweet.nim b/src/views/tweet.nim index 671ff36..5bee864 100644 --- a/src/views/tweet.nim +++ b/src/views/tweet.nim @@ -154,7 +154,7 @@ proc renderPoll(poll: Poll): VNode = span(class="poll-choice-value"): text percStr span(class="poll-choice-option"): text poll.options[i] span(class="poll-info"): - text insertSep($poll.votes, ',') & " votes • " & poll.status + text &"{insertSep($poll.votes, ',')} votes • {poll.status}" proc renderCardImage(card: Card): VNode = buildHtml(tdiv(class="card-image-container")):