diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/soon/agenda.nim | 17 | ||||
| -rw-r--r-- | src/soon/conditionchecker.nim | 28 | ||||
| -rw-r--r-- | src/soon/todos.nim | 34 |
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) |
