Compare commits
	
		
			7 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c00be8c1fc | |||
| 96ee649bf6 | |||
| 69177ffa17 | |||
| 8b6405441a | |||
| aff927b4f4 | |||
| 7c7695b891 | |||
| 6ab23c7c84 | 
							
								
								
									
										1
									
								
								.tool-versions
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.tool-versions
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					nim 1.6.20
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
## Personal Time Keeping API Interface
 | 
					## Personal Time Keeping API Interface
 | 
				
			||||||
## ===================================
 | 
					## ===================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import asyncdispatch, base64, bcrypt, cliutils, docopt, jester, json, logging,
 | 
					import asyncdispatch, base64, bcrypt, cliutils, docopt, httpcore, jester, json, logging,
 | 
				
			||||||
  sequtils, strutils, os, tables, times, uuids
 | 
					  sequtils, strutils, os, tables, times, uuids
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import nre except toSeq
 | 
					import nre except toSeq
 | 
				
			||||||
@@ -61,10 +61,10 @@ template checkAuth(cfg: PtkApiCfg) =
 | 
				
			|||||||
  var user {.inject.}: PtkUser = PtkUser()
 | 
					  var user {.inject.}: PtkUser = PtkUser()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  try:
 | 
					  try:
 | 
				
			||||||
    if not request.headers.hasKey("Authorization"):
 | 
					    if not headers(request).hasKey("Authorization"):
 | 
				
			||||||
      raiseEx "No auth token."
 | 
					      raiseEx "No auth token."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let headerVal = request.headers["Authorization"]
 | 
					    let headerVal = headers(request)["Authorization"]
 | 
				
			||||||
    if not headerVal.startsWith("Basic "):
 | 
					    if not headerVal.startsWith("Basic "):
 | 
				
			||||||
      raiseEx "Invalid Authorization type (only 'Basic' is supported)."
 | 
					      raiseEx "Invalid Authorization type (only 'Basic' is supported)."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,18 @@ const ISO_TIME_FORMAT* = "yyyy-MM-dd'T'HH:mm:ss"
 | 
				
			|||||||
  ## The canonical time format used by PTK.
 | 
					  ## The canonical time format used by PTK.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TIME_FORMATS* = @[
 | 
					const TIME_FORMATS* = @[
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM-dd'T'HH:mm:sszzz", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM-dd HH:mm:sszzz", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM-dd'T'HH:mm:sszz", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM-dd HH:mm:sszz", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM-dd'T'HH:mm:ssz", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM-dd HH:mm:ssz", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
    (fmtStr: "yyyy-MM-dd'T'HH:mm:ss", offsetFrom: OffsetFrom.None),
 | 
					    (fmtStr: "yyyy-MM-dd'T'HH:mm:ss", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
    (fmtStr: "yyyy-MM-dd HH:mm:ss", offsetFrom: OffsetFrom.None),
 | 
					    (fmtStr: "yyyy-MM-dd HH:mm:ss", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
    (fmtStr: "yyyy-MM-dd'T'HH:mm", offsetFrom: OffsetFrom.None),
 | 
					    (fmtStr: "yyyy-MM-dd'T'HH:mm", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
    (fmtStr: "yyyy-MM-dd HH:mm", offsetFrom: OffsetFrom.None),
 | 
					    (fmtStr: "yyyy-MM-dd HH:mm", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM-dd", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
 | 
					    (fmtStr: "yyyy-MM", offsetFrom: OffsetFrom.None),
 | 
				
			||||||
    (fmtStr: "MM-dd'T'HH:mm:ss", offsetFrom: OffsetFrom.Year),
 | 
					    (fmtStr: "MM-dd'T'HH:mm:ss", offsetFrom: OffsetFrom.Year),
 | 
				
			||||||
    (fmtStr: "MM-dd HH:mm:ss", offsetFrom: OffsetFrom.Year),
 | 
					    (fmtStr: "MM-dd HH:mm:ss", offsetFrom: OffsetFrom.Year),
 | 
				
			||||||
    (fmtStr: "MM-dd'T'HH:mm", offsetFrom: OffsetFrom.Year),
 | 
					    (fmtStr: "MM-dd'T'HH:mm", offsetFrom: OffsetFrom.Year),
 | 
				
			||||||
@@ -48,15 +56,16 @@ proc getIfExists*(n: JsonNode, key: string): JsonNode =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
proc parseTime*(timeStr: string): DateTime =
 | 
					proc parseTime*(timeStr: string): DateTime =
 | 
				
			||||||
  ## Helper to parse time strings trying multiple known formats.
 | 
					  ## Helper to parse time strings trying multiple known formats.
 | 
				
			||||||
 | 
					  let now = now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for fmt in TIME_FORMATS:
 | 
					  for fmt in TIME_FORMATS:
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
      let now = now()
 | 
					 | 
				
			||||||
      let parsed = parse(timeStr, fmt.fmtStr)
 | 
					      let parsed = parse(timeStr, fmt.fmtStr)
 | 
				
			||||||
      case fmt.offsetFrom:
 | 
					      case fmt.offsetFrom:
 | 
				
			||||||
        of OffsetFrom.None:
 | 
					        of OffsetFrom.None:
 | 
				
			||||||
          return parsed
 | 
					          return parsed
 | 
				
			||||||
        of OffsetFrom.Year:
 | 
					        of OffsetFrom.Year:
 | 
				
			||||||
          return initDateTime(parsed.monthday, parsed.month, now.year,
 | 
					          return dateTime(now.year, parsed.month, parsed.monthday,
 | 
				
			||||||
            parsed.hour, parsed.minute, parsed.second, parsed.nanosecond,
 | 
					            parsed.hour, parsed.minute, parsed.second, parsed.nanosecond,
 | 
				
			||||||
            now.timezone)
 | 
					            now.timezone)
 | 
				
			||||||
        of OffsetFrom.Month:
 | 
					        of OffsetFrom.Month:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
const PTK_VERSION* = "1.0.8"
 | 
					const PTK_VERSION* = "1.0.14"
 | 
				
			||||||
							
								
								
									
										35
									
								
								ptk.nim
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								ptk.nim
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
## Simple time keeping CLI
 | 
					## Simple time keeping CLI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import algorithm, docopt, json, langutils, logging, os, nre, std/wordwrap,
 | 
					import algorithm, docopt, json, langutils, logging, os, nre, std/wordwrap,
 | 
				
			||||||
  sequtils, sets, strutils, tempfile, terminal, times, uuids
 | 
					  sequtils, sets, strutils, sugar, tempfile, terminal, times, uuids
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import timeutils except `-`
 | 
					import timeutils except `-`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,8 +43,7 @@ proc writeMarks(timeline: Timeline, indices: seq[int], includeNotes = false): vo
 | 
				
			|||||||
    writeLine(stdout, "No marks match the given criteria.")
 | 
					    writeLine(stdout, "No marks match the given criteria.")
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var idxs = indices.sorted(
 | 
					  var idxs = indices.sorted((a, b) => cmp(marks[a].time, marks[b].time))
 | 
				
			||||||
    proc(a, b: int): int = cmp(marks[a].time, marks[b].time))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let largestInterval = now - marks[idxs.first].time
 | 
					  let largestInterval = now - marks[idxs.first].time
 | 
				
			||||||
  let timeFormat =
 | 
					  let timeFormat =
 | 
				
			||||||
@@ -279,8 +278,9 @@ Options:
 | 
				
			|||||||
  -e --edit               Open the mark in an editor.
 | 
					  -e --edit               Open the mark in an editor.
 | 
				
			||||||
  -f --file <file>        Use the given timeline file.
 | 
					  -f --file <file>        Use the given timeline file.
 | 
				
			||||||
  -g --tags <tags>        Add the given tags (comma-separated) to the selected marks.
 | 
					  -g --tags <tags>        Add the given tags (comma-separated) to the selected marks.
 | 
				
			||||||
  -G --remove-tags <tagx> Remove the given tag from the selected marks.
 | 
					  -G --remove-tags <tags> Remove the given tag from the selected marks.
 | 
				
			||||||
  -h --help               Print this usage information.
 | 
					  -h --help               Print this usage information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  -m --matching <pattern> Restric the selection to marks matching <pattern>.
 | 
					  -m --matching <pattern> Restric the selection to marks matching <pattern>.
 | 
				
			||||||
  -n --notes <notes>      For add and amend, set the notes for a time mark.
 | 
					  -n --notes <notes>      For add and amend, set the notes for a time mark.
 | 
				
			||||||
  -t --time <time>        For add and amend, use this time instead of the current time.
 | 
					  -t --time <time>        For add and amend, use this time instead of the current time.
 | 
				
			||||||
@@ -307,27 +307,21 @@ Options:
 | 
				
			|||||||
    quit()
 | 
					    quit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Find and parse the .ptkrc file
 | 
					  # Find and parse the .ptkrc file
 | 
				
			||||||
  let ptkrcLocations = @[
 | 
					  let ptkrcLocations =
 | 
				
			||||||
    if args["--config"]: $args["--config"] else:"",
 | 
					    if args["--config"]: @[$args["--config"]]
 | 
				
			||||||
    ".ptkrc", $getEnv("PTKRC"), $getEnv("HOME") & "/.ptkrc"]
 | 
					    else: @[".ptkrc", $getEnv("PTKRC"), $getEnv("HOME") & "/.ptkrc"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var ptkrcFilename: string =
 | 
					  let foundPtkrcLocations =
 | 
				
			||||||
    foldl(ptkrcLocations, if len(a) > 0: a elif fileExists(b): b else: "")
 | 
					    ptkrcLocations.filterIt(it.len > 0 and fileExists(it))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var cfg: JsonNode
 | 
					  var cfg: JsonNode
 | 
				
			||||||
  var cfgFile: File
 | 
					  if foundPtkrcLocations.len < 1:
 | 
				
			||||||
  if not fileExists(ptkrcFilename):
 | 
					 | 
				
			||||||
    warn "ptk: could not find .ptkrc file."
 | 
					    warn "ptk: could not find .ptkrc file."
 | 
				
			||||||
    ptkrcFilename = $getEnv("HOME") & "/.ptkrc"
 | 
					    debug "ptk: considered the following locations:\n\t" & ptkrcLocations.join("\n\t")
 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
      cfgFile = open(ptkrcFilename, fmWrite)
 | 
					 | 
				
			||||||
      cfgFile.write("{\"timelineLogFile\": \"timeline.log.json\"}")
 | 
					 | 
				
			||||||
    except: warn "ptk: could not write default .ptkrc to " & ptkrcFilename
 | 
					 | 
				
			||||||
    finally: close(cfgFile)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  try: cfg = parseFile(ptkrcFilename)
 | 
					  try: cfg = parseFile(foundPtkrcLocations[0])
 | 
				
			||||||
  except: raise newException(IOError,
 | 
					  except: raise newException(IOError,
 | 
				
			||||||
    "unable to read config file: " & ptkrcFilename &
 | 
					    "unable to read config file: " & foundPtkrcLocations[0] &
 | 
				
			||||||
    "\x0D\x0A" & getCurrentExceptionMsg())
 | 
					    "\x0D\x0A" & getCurrentExceptionMsg())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Find the time log file
 | 
					  # Find the time log file
 | 
				
			||||||
@@ -491,8 +485,7 @@ Options:
 | 
				
			|||||||
        mark.tags = mark.tags.deduplicate
 | 
					        mark.tags = mark.tags.deduplicate
 | 
				
			||||||
      if args["--remove-tags"]:
 | 
					      if args["--remove-tags"]:
 | 
				
			||||||
        let tagsToRemove = (args["--remove-tags"] ?: "").split({',', ';'})
 | 
					        let tagsToRemove = (args["--remove-tags"] ?: "").split({',', ';'})
 | 
				
			||||||
        mark.tags = mark.tags.filter(proc (t: string): bool =
 | 
					        mark.tags = mark.tags.filter((t) => not anyIt(tagsToRemove, it == t))
 | 
				
			||||||
          anyIt(tagsToRemove, it == t))
 | 
					 | 
				
			||||||
      if args["--time"]:
 | 
					      if args["--time"]:
 | 
				
			||||||
        try: mark.time = parseTime($args["--time"])
 | 
					        try: mark.time = parseTime($args["--time"])
 | 
				
			||||||
        except: raise newException(ValueError,
 | 
					        except: raise newException(ValueError,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								ptk.nimble
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ptk.nimble
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
# Package
 | 
					# Package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
version       = "1.0.8"
 | 
					version       = "1.0.14"
 | 
				
			||||||
author        = "Jonathan Bernard"
 | 
					author        = "Jonathan Bernard"
 | 
				
			||||||
description   = "Personal Time Keeper"
 | 
					description   = "Personal Time Keeper"
 | 
				
			||||||
license       = "MIT"
 | 
					license       = "MIT"
 | 
				
			||||||
@@ -16,10 +16,10 @@ requires @[
 | 
				
			|||||||
  "isaac >= 0.1.3",
 | 
					  "isaac >= 0.1.3",
 | 
				
			||||||
  "bcrypt",
 | 
					  "bcrypt",
 | 
				
			||||||
  "jester 0.5.0",
 | 
					  "jester 0.5.0",
 | 
				
			||||||
  "https://git.jdb-labs.com/jdb/nim-lang-utils.git",
 | 
					  "https://git.jdb-software.com/jdb/nim-lang-utils.git",
 | 
				
			||||||
  "https://git.jdb-labs.com/jdb/nim-cli-utils.git >= 0.6.5",
 | 
					  "https://git.jdb-software.com/jdb/nim-cli-utils.git >= 0.6.5",
 | 
				
			||||||
  "https://git.jdb-labs.com/jdb/nim-time-utils.git >= 0.5.2",
 | 
					  "https://git.jdb-software.com/jdb/nim-time-utils.git >= 0.5.2",
 | 
				
			||||||
  "https://git.jdb-labs.com/jdb/update-nim-package-version"
 | 
					  "https://git.jdb-software.com/jdb/update-nim-package-version"
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
task updateVersion, "Update the version of this package.":
 | 
					task updateVersion, "Update the version of this package.":
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user