100 lines
3.6 KiB
Nim
Raw Normal View History

import std/json, std/options, std/sequtils, std/times
import timeutils
const NOTION_MAX_PAGE_SIZE* = 100
const NOTION_DATE_FORMAT = "YYYY-MM-dd"
proc parseDate(str: string): DateTime =
try: result = parseIso8601(str)
except: result = times.parse(str, NOTION_DATE_FORMAT)
## Utility functions for creating Page property values
## ---------------------------------------------------
proc makeDateProp*(d: Option[DateTime]): JsonNode =
if d.isSome: return %*{ "date": { "start": format(d.get, NOTION_DATE_FORMAT) } }
else: return %*{ "date": nil }
proc makeDateTimeProp*(d: Option[DateTime]): JsonNode =
if d.isSome: return %*{ "date": { "start": formatIso8601(d.get) } }
else: return %*{ "date": nil }
proc makeIntervalProp*(s: Option[DateTime], e: Option[DateTime]): JsonNode =
if not s.isSome: result = %*{ "date": nil }
result = %*{ "date": { "start": formatIso8601(s.get) } }
if e.isSome: result["date"]["end"] = %formatIso8601(e.get)
proc makeMultiSelectProp*(values: seq[string]): JsonNode =
if values.len == 0: return %*{ "multi_select": [] }
return %*{ "multi_select": values.mapIt(%*{ "name": it }) }
proc makeRelationProp*(ids: seq[string]): JsonNode =
if ids.len == 0: return %*{ "relation": [] }
return %*{ "relation": ids.mapIt(%*{ "id": it }) }
proc makeSelectProp*(value: string): JsonNode =
return %*{ "select": { "name": value } }
proc makeTextProp*(propType: string, value: string): JsonNode =
return %*{
propType: [
{
"type": "text",
"text": { "content": value }
}
]
}
## Utility functions for reading Page property values
## --------------------------------------------------
proc getPropNode*(page: JsonNode, propType, propName: string): JsonNode =
result = page{"properties", propName, propType}
if isNil(result):
raise newException(ValueError,
"could not find a " & propType & " property named '" & propName &
"' in the Notion page (id: " & page["id"].getStr & ")")
proc getEmail*(page: JsonNode, propName: string): string =
let propNode = page.getPropNode("email", propName)
return propNode.getStr
proc getMultiSelect*(page: JsonNode, propName: string): seq[string] =
let propNode = page.getPropNode("multi_select", propName)
return propNode.getElems.mapIt(it["name"].getStr)
proc getPhone*(page: JsonNode, propName: string): string =
let propNode = page.getPropNode("phone_number", propName)
return propNode.getStr
proc getRelationIds*(page: JsonNode, propName: string): seq[string] =
let propNode = page.getPropNode("relation", propName)
return propNode.getElems.mapIt(it["id"].getStr)
proc getRolledupDisplayValues*(page: JsonNode, propName: string): seq[string] =
let propNode = page.getPropNode("rollup", propName)
return propNode.getElems.mapIt(it{"formula", "string"}.getStr)
proc getText*(page: JsonNode, propName: string): string =
let propNode = page.getPropNode("rich_text", propName)
if propNode.len == 0: return ""
return propNode[0]["plain_text"].getStr
proc getTitle*(page: JsonNode, propName: string): string =
let propNode = page.getPropNode("title", propName)
if propNode.len == 0: return ""
return propNode[0]["plain_text"].getStr
proc getSelect*(page: JsonNode, propName: string): string =
let propNode = page.getPropNode("select", propName)
if propNode.kind == JNull: return ""
return propNode["name"].getStr
proc getDateTime*(page: JsonNode, propName: string): Option[DateTime] =
let propNode = page.getPropNode("date", propName)
if propNode.kind == JNull: result = none[DateTime]()
else: result = some(parseDate(propNode["start"].getStr))