aboutsummaryrefslogtreecommitdiff
path: root/src/soon/agenda.nim
blob: 4288f0a62d88af876f4df95f39a51a50c8c4e9bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import std/[times, strutils, strbasics, strscans, tables]
import conditionchecker, typechecker

# Splits a string on whitespace, but maintains whitespace in date groups
proc splitWhitespaceExceptParens(str:string): seq[string] =
  var output: seq[string] = newSeq[string]()
  var inParens = false
  for token in str.splitWhitespace:
    if inParens:
      output.add(output.pop & ' ' & token)
    else:
      output.add(token)
    for c in token:
      if c == '(': inParens = true
      if c == ')': inParens = false
  return output

# Returns Table[conditionType, seq of conditions]
proc parseDateToTable(date:string): Table[string, seq[string]] =
  var table = initTable[string,seq[string]]()
  let conditions = splitWhitespaceExceptParens(date)
  for c in conditions:
    let condType = typechecker.checkType(c)
    if not table.hasKey(condType):
      table[condType] = @[]
    table[condType].add(c)
  return table

proc allConditionsMet(dateConditions: string, date: DateTime): bool =
  let conditions  = parseDateToTable(dateConditions.strip)
  if conditions.hasKey("unknown"): return false
  for k,cs in conditions:
    var keyMatched = false
    for c in cs:
      if conditionchecker.checkCond(c, date):
        keyMatched = true
        break
    if not keyMatched:
      return false
  return true

# Returns Table[event, attachments]
proc getEventsForDate(cal: seq[string], date: DateTime): Table[string, seq[string]] =
  var lastInsertion = ""
  for line in cal:
    var (success, dateConditions, event) = scanTuple(line, "$*,$*")
    if success:
      if allConditionsMet(dateConditions, date):
        event.strip
        result[event] = @[]
        lastInsertion = event
    elif line.strip[0] == '+':
      if result.hasKey(lastInsertion):
        result[lastInsertion].add(line)
    elif line[0..1] == "- ":
      lastInsertion = ""
    else:
      echo "WARNING: Cannot parse line: ", line

proc printEvents(cal: seq[string], date: DateTime, format: string) =
  let events = getEventsForDate(cal, date)
  if events.len > 0:
    for e in events.keys:
        echo date.format(format), "  ", e
        for attachment in events[e]:
          let space = date.format(format).len + 2
          echo attachment.indent(space)

proc printAgenda*(calendar: seq[string], past: int, future: int) =
  let now = now()
  var today = dateTime(now.year, now.month, now.monthday, 00, 00, 00, 00, local())
  for i in past..future:
    let curDay = today + i.days
    printEvents(calendar, curDay, "ddd  yyyy MMM dd")