Add REST API. Refactor config logic.

The REST API is simply a wrapper around the command line (and actually
invokes the command line). It relies on the command line tool validating
its input.

Currently only the `/list` endpoint is implemented, exposing the `list`
command.
This commit is contained in:
Jonathan Bernard
2018-05-18 16:06:58 -05:00
parent 6f247032a3
commit 29959a6a8d
6 changed files with 246 additions and 67 deletions

View File

@ -1,4 +1,5 @@
import cliutils, options, os, ospaths, sequtils, strutils, tables, times, timeutils, uuids
import cliutils, docopt, json, logging, options, os, ospaths, sequtils,
strutils, tables, times, timeutils, uuids
from nre import re, match
type
@ -21,6 +22,11 @@ type
properties*: TableRef[string, string]
completedRange*: tuple[b, e: DateTime]
PitConfig* = ref object
tasksDir*: string
contexts*: TableRef[string, string]
cfg*: CombinedConfig
const DONE_FOLDER_FORMAT* = "yyyy-MM"
let ISSUE_FILE_PATTERN = re"[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}\.txt"
@ -189,3 +195,52 @@ proc filter*(issues: seq[Issue], filter: IssueFilter): seq[Issue] =
filter.completedRange.b,
filter.completedRange.e))
### Configuration utilities
proc loadConfig*(args: Table[string, Value] = initTable[string, Value]()): PitConfig =
let pitrcLocations = @[
if args["--config"]: $args["--config"] else: "",
".pitrc", $getEnv("PITRC"), $getEnv("HOME") & "/.pitrc"]
var pitrcFilename: string =
foldl(pitrcLocations, if len(a) > 0: a elif existsFile(b): b else: "")
if not existsFile(pitrcFilename):
warn "pit: could not find .pitrc file: " & pitrcFilename
if isNilOrWhitespace(pitrcFilename):
pitrcFilename = $getEnv("HOME") & "/.pitrc"
var cfgFile: File
try:
cfgFile = open(pitrcFilename, fmWrite)
cfgFile.write("{\"tasksDir\": \"/path/to/tasks\"}")
except: warn "pit: could not write default .pitrc to " & pitrcFilename
finally: close(cfgFile)
var cfgJson: JsonNode
try: cfgJson = parseFile(pitrcFilename)
except: raise newException(IOError,
"unable to read config file: " & pitrcFilename &
"\x0D\x0A" & getCurrentExceptionMsg())
let cfg = CombinedConfig(docopt: args, json: cfgJson)
result = PitConfig(
cfg: cfg,
contexts: newTable[string,string](),
tasksDir: cfg.getVal("tasks-dir", ""))
if cfgJson.hasKey("contexts"):
for k, v in cfgJson["contexts"]:
result.contexts[k] = v.getStr()
if isNilOrWhitespace(result.tasksDir):
raise newException(Exception, "no tasks directory configured")
if not existsDir(result.tasksDir):
raise newException(Exception, "cannot find tasks dir: " & result.tasksDir)
# Create our tasks directory structure if needed
for s in IssueState:
if not existsDir(result.tasksDir / $s):
(result.tasksDir / $s).createDir

View File

@ -0,0 +1 @@
const PIT_VERSION = "4.1.0"