Add server config file

このコミットが含まれているのは:
Zed 2019-07-31 02:15:43 +02:00
コミット 6a9d182249
8個のファイルの変更53行の追加23行の削除

ファイルの表示

@ -28,7 +28,6 @@ is on implementing missing features.
- Search (images/videos, hashtags, etc.)
- Custom timeline filter
- Nitter link previews
- Server configuration
- More caching (waiting for [moigagoo/norm#19](https://github.com/moigagoo/norm/pull/19))
- Simple account system with customizable feed
- Video support with hls.js

9
nitter.conf ノーマルファイル
ファイルの表示

@ -0,0 +1,9 @@
[Server]
address = "0.0.0.0"
port = 8080
title = "nitter"
staticDir = "./public"
[Cache]
directory = "/tmp/niter"
profileMinutes = 10 # how long to cache profiles

ファイルの表示

@ -450,6 +450,7 @@ video {
text-overflow: ellipsis;
max-width: 100%;
font-weight: bold;
overflow-wrap: break-word;
}
.profile-card-username {

ファイルの表示

@ -26,3 +26,6 @@ proc getCachedProfile*(username: string; force=false): Future[Profile] {.async.}
result = await getProfile(username)
if result.username.len > 0:
result.insert()
proc setProfileCacheTime*(minutes: int) =
profileCacheTime = initDuration(minutes=minutes)

ファイルの表示

@ -69,10 +69,7 @@ proc getUserpic*(profile: Profile; style=""): string =
getUserPic(profile.userpic, style)
proc pageTitle*(profile: Profile): string =
&"{profile.fullname} (@{profile.username}) | Nitter"
proc pageTitle*(page: string): string =
&"{page} | Nitter"
&"{profile.fullname} (@{profile.username})"
proc getTime*(tweet: Tweet): string =
tweet.time.format("d/M/yyyy', ' HH:mm:ss")

ファイルの表示

@ -1,11 +1,13 @@
import asyncdispatch, asyncfile, httpclient, strutils, strformat, uri, os
from net import Port
import jester, regex
import api, utils, types, cache, formatters, search
import api, utils, types, cache, formatters, search, config
import views/[general, profile, status]
const cacheDir {.strdefine.} = "/tmp/nitter"
const configPath {.strdefine.} = "./nitter.conf"
let cfg = getConfig(configPath)
proc showTimeline(name, after: string; query: Option[Query]): Future[string] {.async.} =
let
@ -24,20 +26,27 @@ proc showTimeline(name, after: string; query: Option[Query]): Future[string] {.a
return ""
let profileHtml = renderProfile(profile, await timelineFut, await railFut)
return renderMain(profileHtml, title=pageTitle(profile))
return renderMain(profileHtml, title=cfg.title, titleText=pageTitle(profile))
template respTimeline(timeline: typed) =
if timeline.len == 0:
resp Http404, showError("User \"" & @"name" & "\" not found")
resp Http404, showError("User \"" & @"name" & "\" not found", cfg.title)
resp timeline
setProfileCacheTime(cfg.profileCacheTime)
settings:
port = Port(cfg.port)
staticDir = cfg.staticDir
bindAddr = cfg.address
routes:
get "/":
resp renderMain(renderSearch(), title=pageTitle("Search"))
resp renderMain(renderSearch(), title=cfg.title, titleText="Search")
post "/search":
if @"query".len == 0:
resp Http404, showError("Please enter a username.")
resp Http404, showError("Please enter a username.", cfg.title)
redirect("/" & @"query")
get "/@name/?":
@ -62,7 +71,7 @@ routes:
let conversation = await getTweet(@"name", @"id")
if conversation == nil or conversation.tweet.id.len == 0:
resp Http404, showError("Tweet not found")
resp Http404, showError("Tweet not found", cfg.title)
let title = pageTitle(conversation.tweet.profile)
resp renderMain(renderConversation(conversation), title=title)
@ -74,13 +83,13 @@ routes:
let
uri = parseUri(decodeUrl(@"url"))
path = uri.path.split("/")[2 .. ^1].join("/")
filename = cacheDir / cleanFilename(path & uri.query)
filename = cfg.cacheDir / cleanFilename(path & uri.query)
if getHmac($uri) != @"sig":
resp showError("Failed to verify signature")
resp showError("Failed to verify signature", cfg.title)
if not existsDir(cacheDir):
createDir(cacheDir)
if not existsDir(cfg.cacheDir):
createDir(cfg.cacheDir)
if not existsFile(filename):
let client = newAsyncHttpClient()
@ -92,6 +101,7 @@ routes:
let file = openAsync(filename)
defer: file.close()
resp await readAll(file), mimetype(filename)
get "/video/@sig/@url":
@ -100,7 +110,7 @@ routes:
let url = decodeUrl(@"url")
if getHmac(url) != @"sig":
resp showError("Failed to verify signature")
resp showError("Failed to verify signature", cfg.title)
let
client = newAsyncHttpClient()

ファイルの表示

@ -147,5 +147,13 @@ type
beginning*: bool
query*: Option[Query]
Config* = ref object
address*: string
port*: int
title*: string
staticDir*: string
cacheDir*: string
profileCacheTime*: int
proc contains*(thread: Thread; tweet: Tweet): bool =
thread.tweets.anyIt(it.id == tweet.id)

ファイルの表示

@ -2,17 +2,20 @@ import karax/[karaxdsl, vdom]
const doctype = "<!DOCTYPE html>\n"
proc renderMain*(body: VNode; title="Nitter"): string =
proc renderMain*(body: VNode; title="Nitter"; titleText=""): string =
let node = buildHtml(html(lang="en")):
head:
title: text title
if titleText.len > 0:
title: text titleText & " | " & title
else:
title: text title
link(rel="stylesheet", `type`="text/css", href="/style.css")
body:
nav(id="nav", class="nav-bar container"):
tdiv(class="inner-nav"):
tdiv(class="item"):
a(href="/", class="site-name"): text "nitter"
a(href="/", class="site-name"): text title
tdiv(id="content", class="container"):
body
@ -31,5 +34,5 @@ proc renderError*(error: string): VNode =
tdiv(class="error-panel"):
span: text error
proc showError*(error: string): string =
renderMain(renderError(error), title = "Error | Nitter")
proc showError*(error: string; title: string): string =
renderMain(renderError(error), title=title, titleText="Error")