Skip to content

Instantly share code, notes, and snippets.

@StachuDotNet StachuDotNet/dynalist.fs Secret
Last active Sep 17, 2019

Embed
What would you like to do?
namespace Dynalist
open System
open Newtonsoft.Json
open System.Net.Http
open System.Text
open Newtonsoft.Json.Serialization
type File =
{ Id: string
Title: string
Children: (string list) option
Type: string }
type private DocumentDto =
{ Title: string
Nodes: DocumentNode seq
Version: int }
and Document =
{ Id: string
Title: string
Nodes: DocumentNode seq
Version: int }
and DocumentNode =
{ Id: string
Content: string
Note: string
Children: string list
Created: string
Modified: string }
type private GetDocumentsRequestBody = { Token: string }
type private GetDocumentRequestBody = { Token: string; FileId: string }
type private GetDocumentsResponse = { Files: File list}
type DynalistClient(apiToken: string) =
let httpClient = new HttpClient()
let serializerSettings =
let settings = JsonSerializerSettings()
settings.ContractResolver <- CamelCasePropertyNamesContractResolver()
//settings.Converters.Add(OptionConverter())
settings
member __.GetDocuments() =
async {
let outgoingRequest = new HttpRequestMessage()
outgoingRequest.Method <- HttpMethod.Post
outgoingRequest.RequestUri <- Uri("https://dynalist.io/api/v1/file/list")
outgoingRequest.Content <-
let requestBodyContents: GetDocumentsRequestBody = { Token = apiToken }
let requestBodyStr = JsonConvert.SerializeObject(requestBodyContents, serializerSettings)
new StringContent(requestBodyStr, Encoding.UTF8, "application/json" )
outgoingRequest.Headers.Add("Accept", "application/json")
let! response = httpClient.SendAsync outgoingRequest |> Async.AwaitTask
let! responseStr = response.Content.ReadAsStringAsync() |> Async.AwaitTask
let responseBody = JsonConvert.DeserializeObject<GetDocumentsResponse>(responseStr, serializerSettings)
return responseBody.Files
}
member __.GetDocument fileId: Async<Document> =
async {
let outgoingRequest = new HttpRequestMessage()
outgoingRequest.Method <- HttpMethod.Post
outgoingRequest.RequestUri <- Uri("https://dynalist.io/api/v1/file/list")
outgoingRequest.Content <-
let requestBodyContents: GetDocumentRequestBody = { Token = apiToken; FileId = fileId }
new StringContent(
JsonConvert.SerializeObject(requestBodyContents, serializerSettings),
Encoding.UTF8,
"application/json"
)
outgoingRequest.Headers.Add("Accept", "application/json")
let! response = httpClient.SendAsync outgoingRequest |> Async.AwaitTask
let! responseStr = response.Content.ReadAsStringAsync() |> Async.AwaitTask
let responseBody = JsonConvert.DeserializeObject<DocumentDto>(responseStr, serializerSettings)
return { Id = fileId; Title = responseBody.Title; Nodes = responseBody.Nodes; Version = responseBody.Version }
}
type Result = ResultItem seq
and ResultItem = { Title: string; Todos: string list }
[<EntryPoint>]
let main _argv =
let dynalistClient = DynalistClient(apiKey)
async {
let! documents = dynalistClient.GetDocuments()
let todosDocuments =
documents
|> Seq.filter(fun doc ->
doc.Title = "TODOs" && doc.Type = "document"
)
let docTitleMap =
todosDocuments
|> Seq.map(fun (z: Dynalist.File) ->
let docId = z.Id
let parentTitle =
documents
|> Seq.find(fun doc ->
match doc.Children with
| Some children -> children |> Seq.exists ((=) docId)
| None -> false
)
|> (fun parent -> parent.Title)
docId, parentTitle
)
|> Map
let! docs =
todosDocuments
|> Seq.map(fun doc -> dynalistClient.GetDocument doc.Id)
|> Async.Parallel
docs
|> Seq.map(fun doc ->
let rootNode = doc.Nodes |> Seq.find(fun node -> node.Content = "root")
let todos =
doc.Nodes
|> Seq.filter(fun node -> rootNode.Children |> List.contains node.Id)
|> Seq.map(fun node -> node.Content)
|> Seq.toList
let parentTitle = docTitleMap.[doc.Id]
{ Title = parentTitle; Todos = todos }
)
|> Seq.iter(fun doc ->
printfn "%s has %i todos" doc.Title doc.Todos.Length
)
return 0 // return an integer exit code
} |> Async.RunSynchronously
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.