67 lines
2.1 KiB
Nim

# Nim CLI Wrapper for the ESV API
# © 2023 Jonathan Bernard
## Simple command-line wrapper around the ESV API.
import std/[httpclient, json, logging, os, re, strutils, uri]
import cliutils, docopt, zero_functional
when isMainModule:
const USAGE = """Usage:
esv_api <reference> [options]
Options:
--debug Log debug information.
--echo-args Echo back the arguments that were passed on the
command line for debugging purposes.
-t, --esv-api-token <token> Provide the API token on the command line. By
default this will be read either from the
.esv_api.cfg.json file or the ESV_API_TOKEN
envionment variable.
"""
let consoleLogger = newConsoleLogger(
levelThreshold=lvlInfo,
fmtStr="esv_api - $levelname: ")
logging.addHandler(consoleLogger)
try:
# Parse arguments
let args = docopt(USAGE, version = "0.1.0")
if args["--debug"]:
consoleLogger.levelThreshold = lvlDebug
if args["--echo-args"]: stderr.writeLine($args)
let cfgFilePath = getEnv("HOME") / ".esv_api.cfg.json"
var cfgFileJson = newJObject()
if fileExists(cfgFilePath):
debug "Loading config from " & cfgFilePath
cfgFileJson = parseFile(cfgFilePath)
let cfg = CombinedConfig(docopt: args, json: cfgFileJson)
let apiToken = cfg.getVal("esv-api-token")
let apiRoot = cfg.getVal("esv-api-root", "https://api.esv.org")
let reference = $args["<reference>"]
let http = newHttpClient()
http.headers = newHttpHeaders({"Authorization": "Token " & apiToken})
let urlPath = apiRoot & "/v3/passage/text/?q=" & encodeUrl(reference)
debug "requesting " & urlPath
let respJson = parseJson(http.getContent(urlPath))
let formattedPassages = respJson["passages"].getElems -->
map(it.getStr.multiReplace([(re"\[(\d+)\]", "$1")]))
echo formattedPassages.join("\p")
except CatchableError:
fatal getCurrentExceptionMsg()
debug getCurrentException().getStackTrace()
quit(QuitFailure)