From 7d147899103bf1a21b291641fd4230a02ba48fab Mon Sep 17 00:00:00 2001 From: Zed Date: Mon, 18 Sep 2023 18:24:23 +0000 Subject: [PATCH] Improve guest accounts loading, add JSONL support --- .gitignore | 1 + src/experimental/parser/guestaccount.nim | 20 ++++++++++++++++++++ src/experimental/types/guestaccount.nim | 4 ++++ src/nitter.nim | 4 +--- src/tokens.nim | 23 +++++++++++++++-------- 5 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 src/experimental/parser/guestaccount.nim create mode 100644 src/experimental/types/guestaccount.nim diff --git a/.gitignore b/.gitignore index d43cc3f..ea520dc 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ nitter /public/css/style.css /public/md/*.html nitter.conf +guest_accounts.json* dump.rdb diff --git a/src/experimental/parser/guestaccount.nim b/src/experimental/parser/guestaccount.nim new file mode 100644 index 0000000..4d8ff47 --- /dev/null +++ b/src/experimental/parser/guestaccount.nim @@ -0,0 +1,20 @@ +import jsony +import ../types/guestaccount +from ../../types import GuestAccount + +proc toGuestAccount(account: RawAccount): GuestAccount = + let id = account.oauthToken[0 ..< account.oauthToken.find('-')] + result = GuestAccount( + id: id, + oauthToken: account.oauthToken, + oauthSecret: account.oauthTokenSecret + ) + +proc parseGuestAccount*(raw: string): GuestAccount = + let rawAccount = raw.fromJson(RawAccount) + result = rawAccount.toGuestAccount + +proc parseGuestAccounts*(path: string): seq[GuestAccount] = + let rawAccounts = readFile(path).fromJson(seq[RawAccount]) + for account in rawAccounts: + result.add account.toGuestAccount diff --git a/src/experimental/types/guestaccount.nim b/src/experimental/types/guestaccount.nim new file mode 100644 index 0000000..244edb3 --- /dev/null +++ b/src/experimental/types/guestaccount.nim @@ -0,0 +1,4 @@ +type + RawAccount* = object + oauthToken*: string + oauthTokenSecret*: string diff --git a/src/nitter.nim b/src/nitter.nim index 4a4ec13..1b4862b 100644 --- a/src/nitter.nim +++ b/src/nitter.nim @@ -3,7 +3,6 @@ import asyncdispatch, strformat, logging from net import Port from htmlgen import a from os import getEnv -from json import parseJson import jester @@ -21,9 +20,8 @@ let (cfg, fullCfg) = getConfig(configPath) accountsPath = getEnv("NITTER_ACCOUNTS_FILE", "./guest_accounts.json") - accounts = parseJson(readFile(accountsPath)) -initAccountPool(cfg, parseJson(readFile(accountsPath))) +initAccountPool(cfg, accountsPath) if not cfg.enableDebug: # Silence Jester's query warning diff --git a/src/tokens.nim b/src/tokens.nim index 3e20597..b8a50e3 100644 --- a/src/tokens.nim +++ b/src/tokens.nim @@ -1,6 +1,7 @@ #SPDX-License-Identifier: AGPL-3.0-only -import asyncdispatch, times, json, random, strutils, tables, sets +import asyncdispatch, times, json, random, strutils, tables, sets, os import types +import experimental/parser/guestaccount # max requests at a time per account to avoid race conditions const @@ -141,12 +142,18 @@ proc setRateLimit*(account: GuestAccount; api: Api; remaining, reset: int) = account.apis[api] = RateLimit(remaining: remaining, reset: reset) -proc initAccountPool*(cfg: Config; accounts: JsonNode) = +proc initAccountPool*(cfg: Config; path: string) = enableLogging = cfg.enableDebug - for account in accounts: - accountPool.add GuestAccount( - id: account{"user", "id_str"}.getStr, - oauthToken: account{"oauth_token"}.getStr, - oauthSecret: account{"oauth_token_secret"}.getStr, - ) + let jsonlPath = if path.endsWith(".json"): (path & 'l') else: path + + if fileExists(jsonlPath): + log "Parsing JSONL guest accounts file: ", jsonlPath + for line in jsonlPath.lines: + accountPool.add parseGuestAccount(line) + elif fileExists(path): + log "Parsing JSON guest accounts file: ", path + accountPool = parseGuestAccounts(path) + else: + echo "[accounts] ERROR: ", path, " not found. This file is required to authenticate API requests." + quit 1