Initial commit
- Notion Page property manipulation. - HTTP client instantiation
This commit is contained in:
commit
2803e7c913
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.*.sw?
|
13
notion_utils.nimble
Normal file
13
notion_utils.nimble
Normal file
@ -0,0 +1,13 @@
|
||||
# Package
|
||||
|
||||
version = "0.1.0"
|
||||
author = "Jonathan Bernard"
|
||||
description = "Utilities and bindings for the Notion API."
|
||||
license = "GPL-3.0-or-later"
|
||||
srcDir = "src"
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
requires "nim >= 1.4.8"
|
||||
requires "https://git.jdb-software.com/jdb/nim-time-utils.git >= 0.5.0"
|
110
src/notion_utils.nim
Normal file
110
src/notion_utils.nim
Normal file
@ -0,0 +1,110 @@
|
||||
import std/httpclient, std/json, std/logging, std/options, std/sequtils,
|
||||
std/strutils, std/times
|
||||
import timeutils
|
||||
|
||||
const NOTION_MAX_PAGE_SIZE* = 100
|
||||
|
||||
proc parseDate(str: string): DateTime =
|
||||
try: result = parseIso8601(str)
|
||||
except: result = times.parse(str, "YYYY-MM-dd")
|
||||
|
||||
## Utility functions for creating Page property values
|
||||
## ---------------------------------------------------
|
||||
|
||||
proc makeDateTimeProp*(d: Option[DateTime]): JsonNode =
|
||||
if d.isSome: return %*{ "date": { "start": formatIso8601(d.get) } }
|
||||
else: return %*{ "date": nil }
|
||||
|
||||
proc makeMultiSelectProp*(values: seq[string]): JsonNode =
|
||||
return %*{ "multi_select": [ values.mapIt(%*{ "name": it }) ] }
|
||||
|
||||
proc makeRelationProp*(ids: seq[string]): JsonNode =
|
||||
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 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))
|
||||
|
||||
proc newNotionClient*(apiVersion, integrationToken: string): HttpClient =
|
||||
return newHttpClient(headers = newHttpHeaders([
|
||||
("Content-Type", "application/json"),
|
||||
("Authorization", "Bearer " & integrationToken),
|
||||
("Notion-Version", apiVersion)
|
||||
], true))
|
||||
|
||||
proc fetchAllPages*(
|
||||
http: HttpClient,
|
||||
url: string,
|
||||
bodyTemplate = %*{ "page_size": NOTION_MAX_PAGE_SIZE}): seq[JsonNode] =
|
||||
|
||||
result = @[]
|
||||
var nextCursor: string = ""
|
||||
|
||||
while true:
|
||||
let body = parseJson($bodyTemplate)
|
||||
if not nextCursor.isEmptyOrWhitespace: body["start_cursor"] = %nextCursor
|
||||
|
||||
debug "Fetching pages from database:\n\tPOST " & url & "\n\t" & $body
|
||||
let jsonResp = parseJson(http.postContent(url, $body))
|
||||
|
||||
result = result & jsonResp["results"].getElems
|
||||
if jsonResp.hasKey("next_cursor") and jsonResp["next_cursor"].kind != JNull:
|
||||
nextCursor = jsonResp["next_cursor"].getStr
|
||||
|
||||
if nextCursor.isEmptyOrWhitespace: break
|
1
tests/config.nims
Normal file
1
tests/config.nims
Normal file
@ -0,0 +1 @@
|
||||
switch("path", "$projectDir/../src")
|
Loading…
x
Reference in New Issue
Block a user