Compare commits

..

No commits in common. "main" and "0.4.3" have entirely different histories.
main ... 0.4.3

5 changed files with 22 additions and 38 deletions

View File

@ -1,14 +0,0 @@
# Hope Family Fellowship Notion API Client
## Building
### Software Packages
`hff_notion_api_client` depends on a number of packages which are not yet
available in he official Nim repository. The easiest way to get access to these
packages is to add a new `PackageList` to your [nimble configuration] for the
[JDB Software Nim packages repository]. The url is
`https://git.jdb-software.com/jdb/nim-packages/raw/main/packages.json`
[nimble configuration]: https://github.com/nim-lang/nimble#configuration
[JDB Software Nim packages]: https://git.jdb-software.com/jdb/nim-packages

View File

@ -1,6 +1,6 @@
# Package # Package
version = "0.5.0" version = "0.4.3"
author = "Jonathan Bernard" author = "Jonathan Bernard"
description = "Utilities and bindings for HFF's Notion API." description = "Utilities and bindings for HFF's Notion API."
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
@ -9,6 +9,6 @@ srcDir = "src"
# Dependencies # Dependencies
requires "nim >= 1.4.8" requires "nim >= 1.4.8"
requires "https://git.jdb-software.com/jdb/buffoonery"
# packages from git.jdb-software.com/jdb/nim-packages requires "https://git.jdb-software.com/jdb/nim-time-utils.git >= 0.5.0"
requires @["buffoonery", "timeutils >= 0.5.0", "namespaced_logging >= 0.3.1"] requires "https://git.jdb-software.com/jdb/nim-namespaced-logging"

View File

@ -1,8 +1,11 @@
import std/[httpclient, json, logging, options, sequtils, tables, strutils] import std/httpclient, std/json, std/logging, std/sequtils, std/tables, std/strutils
import buffoonery/jsonutils import buffoonery/jsonutils
import hff_notion_api_client/[config, models, sequtils_ext, utils] import hff_notion_api_client/config
import hff_notion_api_client/models
import hff_notion_api_client/sequtils_ext
import hff_notion_api_client/utils
type type
NotionClientConfig* = object NotionClientConfig* = object
@ -58,19 +61,20 @@ proc fetchAllPages*(
bodyTemplate = %*{ "page_size": NOTION_MAX_PAGE_SIZE}): seq[JsonNode] = bodyTemplate = %*{ "page_size": NOTION_MAX_PAGE_SIZE}): seq[JsonNode] =
result = @[] result = @[]
var nextCursor: Option[string] = none[string]() var nextCursor: string = ""
while true: while true:
let body = parseJson($bodyTemplate) let body = parseJson($bodyTemplate)
if nextCursor.isSome: body["start_cursor"] = %nextCursor.get if not nextCursor.isEmptyOrWhitespace: body["start_cursor"] = %nextCursor
debug "Fetching pages from database:\n\tPOST " & url & "\n\t" & $body debug "Fetching pages from database:\n\tPOST " & url & "\n\t" & $body
let jsonResp = parseJson(http.postContent(url, $body)) let jsonResp = parseJson(http.postContent(url, $body))
result = result & jsonResp["results"].getElems result = result & jsonResp["results"].getElems
if jsonResp.hasKey("next_cursor") and jsonResp["next_cursor"].kind != JNull: if jsonResp.hasKey("next_cursor") and jsonResp["next_cursor"].kind != JNull:
nextCursor = some(jsonResp["next_cursor"].getStr) nextCursor = jsonResp["next_cursor"].getStr
else: break
if nextCursor.isEmptyOrWhitespace: break
template fetchDatabaseObject*(notion: NotionClient, dbId: string): untyped = template fetchDatabaseObject*(notion: NotionClient, dbId: string): untyped =
let resp = notion.http.get(notion.apiBaseUrl & "/databases/" & dbId) let resp = notion.http.get(notion.apiBaseUrl & "/databases/" & dbId)

View File

@ -11,7 +11,6 @@ type
city*: string city*: string
state*: string state*: string
street*: string street*: string
suiteOrBuilding*: string
zipCode*: string zipCode*: string
createdAt*: Option[DateTime] createdAt*: Option[DateTime]
lastUpdatedAt*: Option[DateTime] lastUpdatedAt*: Option[DateTime]
@ -128,7 +127,6 @@ func toPage*(a: Address): JsonNode =
"City": makeTextProp("rich_text", a.city), "City": makeTextProp("rich_text", a.city),
"State": makeSelectProp(a.state), "State": makeSelectProp(a.state),
"Street Address": makeTextProp("title", a.street), "Street Address": makeTextProp("title", a.street),
"Suite or Building": makeTextProp("rich_text", a.suiteOrBuilding),
"Zip Code": makeTextProp("rich_text", a.zipCode) "Zip Code": makeTextProp("rich_text", a.zipCode)
} }
} }
@ -184,7 +182,6 @@ proc addressFromPage*(page: JsonNode): Address =
city: page.getText("City"), city: page.getText("City"),
state: page.getSelect("State"), state: page.getSelect("State"),
street: page.getTitle("Street Address"), street: page.getTitle("Street Address"),
suiteOrBuilding: page.getText("Suite or Building"),
zipCode: page.getText("Zip Code"), zipCode: page.getText("Zip Code"),
createdAt: some(parseIso8601(page["created_time"].getStr)), createdAt: some(parseIso8601(page["created_time"].getStr)),
lastUpdatedAt: some(parseIso8601(page["last_edited_time"].getStr))) lastUpdatedAt: some(parseIso8601(page["last_edited_time"].getStr)))

View File

@ -8,7 +8,7 @@ const NOTION_DATE_FORMAT = "YYYY-MM-dd"
var logNs {.threadvar.}: LoggingNamespace var logNs {.threadvar.}: LoggingNamespace
template log(): untyped = template log(): untyped =
if logNs.isNil: logNs = getLoggerForNamespace("hff_notion_api_client/utils", lvlInfo) if logNs.isNil: logNs = initLoggingNamespace("hff_notion_api_client/utils", lvlInfo)
logNs logNs
proc parseDate(str: string): DateTime = proc parseDate(str: string): DateTime =
@ -87,18 +87,15 @@ proc getRollupArrayValues*(page: JsonNode, propName: string): seq[JsonNode] =
proc getRolledupRecordTitles*(page: JsonNode, propName: string): seq[string] = proc getRolledupRecordTitles*(page: JsonNode, propName: string): seq[string] =
let rollups = page.getPropNode("rollup", propName)["array"] let rollups = page.getPropNode("rollup", propName)["array"]
if rollups.getElems.len == 0: return @[] if rollups.getElems.len == 0: return @[]
elif rollups.getElems.len != 1 or not rollups.getElems[0].hasKey("title"):
result = @[] log().debug "Expected exactly one item of type 'title'. Received: \n" & rollups.pretty
for rollupItem in rollups.getElems:
if not rollupItem.hasKey("title") or rollupItem["title"].getElems.len != 1:
log().debug "Expected exactly one item of type 'title'. Received: \n" &
rollupItem.pretty
raise newException( raise newException(
ValueError, ValueError,
"unexpected format of rollup value for '" & propName & "' property") "unexpected format of rollup value for '" & propName & "' property")
result.add(rollupItem["title"].getElems[0]["plain_text"].getStr) let titleElems = rollups.getElems[0]["title"]
return titleElems.getElems.mapIt(it["plain_text"].getStr)
proc getText*(page: JsonNode, propName: string): string = proc getText*(page: JsonNode, propName: string): string =
let propNode = page.getPropNode("rich_text", propName) let propNode = page.getPropNode("rich_text", propName)