aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soon/agenda.nim17
-rw-r--r--src/soon/conditionchecker.nim28
-rw-r--r--src/soon/todos.nim34
3 files changed, 63 insertions, 16 deletions
diff --git a/src/soon/agenda.nim b/src/soon/agenda.nim
index 8d43272..6e3b2ba 100644
--- a/src/soon/agenda.nim
+++ b/src/soon/agenda.nim
@@ -1,4 +1,4 @@
-import std/[times, strutils, sequtils, tables, terminal, strtabs]
+import std/[times, strutils, sequtils, tables, terminal, strtabs, sets]
import conditionchecker, typechecker, parsetime, columnize, archive
type Event* = object
@@ -119,6 +119,7 @@ proc getDaysEvents(cal: seq[string], date: DateTime, format: string,
proc printAgenda*(calendar: seq[string], past: int, future: int,
conf: StringTableRef, arch: archive.ArchiveData) =
+ clearInvalidConditions()
let now = now()
let today = dateTime(now.year, now.month, now.monthday, 00, 00, 00, 00, local())
var agenda = newSeq[Line]()
@@ -136,3 +137,17 @@ proc printAgenda*(calendar: seq[string], past: int, future: int,
let curDay = today + day.days
agenda = agenda.concat(getDaysEvents(calendar, curDay, "ddd yyyy MMM dd", arch, conf))
columnize.echo(agenda)
+ if invalidConditions.len > 0:
+ var seen: HashSet[string]
+ for line in calendar:
+ let stripped = line.strip
+ if stripped.len == 0 or stripped[0] in {'#', '-', '+'}: continue
+ let split = line.split(",", maxsplit = 1)
+ if split.len < 2: continue
+ let tokens = splitWhitespaceExceptParens(split[0].strip)
+ for token in tokens:
+ if token in invalidConditions:
+ if not seen.contains(line):
+ seen.incl(line)
+ stderr.writeLine("WARN: Invalid conditions: ", line)
+ break
diff --git a/src/soon/conditionchecker.nim b/src/soon/conditionchecker.nim
index 8c9284d..691c42a 100644
--- a/src/soon/conditionchecker.nim
+++ b/src/soon/conditionchecker.nim
@@ -1,9 +1,14 @@
-import std/[times, strutils, tables, re]
+import std/[times, strutils, tables, re, sets]
import typechecker
# Forward declarations
proc checkCond*(cond: string, date: DateTime): bool
+var invalidConditions*: HashSet[string]
+
+proc clearInvalidConditions*() =
+ clear(invalidConditions)
+
proc fixCase(s: string): string =
return s.toLower.capitalizeAscii
@@ -67,10 +72,10 @@ proc checkWeekday(condition: string, date: DateTime): bool =
return condition == date.format("ddd") or condition == date.format("dddd")
proc checkFirstWeek(condition: string, date: DateTime): bool =
- return parseInt(condition[0..1]) == getWeek(date)
+ return parseInt(condition[0..^2]) == getWeek(date)
proc checkLastWeek(condition: string, date: DateTime): bool =
- return parseInt(condition[0..1]) == getWeekFromEnd(date)
+ return parseInt(condition[0..^2]) == getWeekFromEnd(date)
proc checkJulian(condition: string, date: DateTime): bool=
var jDate: int = date.modifiedJulianDay
@@ -113,6 +118,8 @@ proc conditionToInt(c: string): int =
return monthToInt(c)
of "day":
return parseInt(c)
+ else:
+ return -1
proc dateGroupStringToTable(s: string): Table[string, int] =
# This used to be s.len-2 for some reason and I don't know why, but it left off the last condition
@@ -127,7 +134,14 @@ proc dateGroupStringToDate*(s: string, comparisonDate: DateTime): DateTime =
var t = dateGroupStringToTable(s)
if not t.hasKey("year"):
t["year"] = comparisonDate.year
- return dateTime(t["year"], Month(t["month"]), t["day"])
+ if not t.hasKey("month") or not t.hasKey("day") or t["month"] < 1 or t["month"] > 12:
+ invalidConditions.incl(s)
+ return dateTime(1, mJan, 1, 0, 0, 0, 0, utc())
+ try:
+ return dateTime(t["year"], Month(t["month"]), t["day"], 0, 0, 0, 0, utc())
+ except CatchableError:
+ invalidConditions.incl(s)
+ return dateTime(1, mJan, 1, 0, 0, 0, 0, utc())
proc isValidDateGroupRange(s: string): bool =
let dates = s.split('-')
@@ -135,10 +149,10 @@ proc isValidDateGroupRange(s: string): bool =
let right = dateGroupStringToTable(dates[1])
for c in ["year", "month", "day"]:
if left.hasKey(c) != right.hasKey(c):
- echo "Error: Left group conditions don't match right group: ", s
+ invalidConditions.incl(s)
return false
if c != "year" and (not left.hasKey(c) or not right.hasKey(c)):
- echo "Error: Missing ", c, " in groups: ", s
+ invalidConditions.incl(s)
return false
return true
@@ -229,7 +243,7 @@ proc checkCond*(cond: string, date: DateTime): bool =
of "onesidedyear": found = checkOneSidedYear(condition, date)
of "onesideddategroup": found = checkOneSidedDateGroup(condition, date)
else:
- echo "ERROR: Unknown condition: ", condition
+ invalidConditions.incl(condition)
if invert:
return not found
return found
diff --git a/src/soon/todos.nim b/src/soon/todos.nim
index c3040a0..6c471aa 100644
--- a/src/soon/todos.nim
+++ b/src/soon/todos.nim
@@ -1,4 +1,4 @@
-import std/[times, strutils, re, options, terminal]
+import std/[times, strutils, re, options, terminal, sets]
import conditionchecker, columnize
type
@@ -31,7 +31,10 @@ proc getTodosFromCalendar*(calendar: seq[string]): seq[Todo] =
proc getDeadline(attachment: string): Option[DateTime] =
var matches: array[1, string]
if find(attachment, re("^\\s*\\+\\s*Due:(.*)", flags = {reIgnoreCase}), matches) > -1:
- return some(conditionchecker.dateGroupStringToDate(matches[0], now()))
+ try:
+ return some(conditionchecker.dateGroupStringToDate(matches[0], now()))
+ except CatchableError:
+ return none[DateTime]()
else:
return none[DateTime]()
@@ -62,14 +65,29 @@ proc toLine(todo: Todo): Line =
# TODO: Sort on deadlines
proc printDeadlineTodos*(calendar: seq[string]) =
+ clearInvalidConditions()
let todos = getTodosFromCalendar(calendar)
let (regulars, deadlines) = splitRegularAndDeadlineTodos(todos)
- if deadlines.len == 0: return
- echo "\nUpcoming Deadlines:"
- var lines = newSeq[Line]()
- for todo in deadlines:
- lines.add(todo.toLine)
- columnize.echo(lines)
+ if deadlines.len == 0 and invalidConditions.len == 0: return
+ if deadlines.len > 0:
+ echo "\nUpcoming Deadlines:"
+ var lines = newSeq[Line]()
+ for todo in deadlines:
+ lines.add(todo.toLine)
+ columnize.echo(lines)
+ if invalidConditions.len > 0:
+ var seen: HashSet[string]
+ for line in calendar:
+ let stripped = line.strip
+ if stripped.len == 0: continue
+ if stripped[0] != '-': continue
+ for token in invalidConditions:
+ if token in stripped:
+ var todoLine = line
+ if not seen.contains(todoLine):
+ seen.incl(todoLine)
+ stderr.writeLine("WARN: Invalid conditions: ", todoLine)
+ break
proc printTodos*(calendar: seq[string]) =
let todos = getTodosFromCalendar(calendar)