66 "errors"
77 "fmt"
88 "io"
9- "io/ioutil"
109 "os"
10+ "strconv"
1111 "time"
1212
1313 "github.com/google/uuid"
@@ -19,8 +19,6 @@ import (
1919 "github.com/juruen/rmapi/util"
2020)
2121
22- var ErrorNotImplemented = errors .New ("not implemented" )
23-
2422// An ApiCtx allows you interact with the remote reMarkable API
2523type ApiCtx struct {
2624 Http * transport.HttpClientCtx
@@ -29,10 +27,45 @@ type ApiCtx struct {
2927 hashTree * HashTree
3028}
3129
30+ // max number of concurrent requests
31+ var concurrent = 20
32+
33+ func init () {
34+ c := os .Getenv ("RMAPI_CONCURRENT" )
35+ if u , err := strconv .Atoi (c ); err == nil {
36+ concurrent = u
37+ }
38+ }
39+
40+ func CreateCtx (http * transport.HttpClientCtx ) (* ApiCtx , error ) {
41+ apiStorage := NewBlobStorage (http )
42+ cacheTree , err := loadTree ()
43+ if err != nil {
44+ fmt .Print (err )
45+ return nil , err
46+ }
47+ err = cacheTree .Mirror (apiStorage , concurrent )
48+ if err != nil {
49+ return nil , err
50+ }
51+ saveTree (cacheTree )
52+ tree := DocumentsFileTree (cacheTree )
53+ return & ApiCtx {http , tree , apiStorage , cacheTree }, nil
54+ }
55+
3256func (ctx * ApiCtx ) Filetree () * filetree.FileTreeCtx {
3357 return ctx .ft
3458}
3559
60+ func (ctx * ApiCtx ) Refresh () error {
61+ err := ctx .hashTree .Mirror (ctx .blobStorage , concurrent )
62+ if err != nil {
63+ return err
64+ }
65+ ctx .ft = DocumentsFileTree (ctx .hashTree )
66+ return nil
67+ }
68+
3669// Nuke removes all documents from the account
3770func (ctx * ApiCtx ) Nuke () (err error ) {
3871 err = Sync (ctx .blobStorage , ctx .hashTree , func (t * HashTree ) error {
@@ -54,7 +87,7 @@ func (ctx *ApiCtx) FetchDocument(docId, dstPath string) error {
5487 return err
5588 }
5689
57- tmp , err := ioutil . TempFile ("" , "rmapizip" )
90+ tmp , err := os . CreateTemp ("" , "rmapizip" )
5891
5992 if err != nil {
6093 log .Error .Println ("failed to create tmpfile for zip dir" , err )
@@ -104,7 +137,7 @@ func (ctx *ApiCtx) CreateDir(parentId, name string, notify bool) (*model.Documen
104137
105138 files := & archive.DocumentFiles {}
106139
107- tmpDir , err := ioutil . TempDir ("" , "rmupload" )
140+ tmpDir , err := os . MkdirTemp ("" , "rmupload" )
108141 if err != nil {
109142 return nil , err
110143 }
@@ -219,10 +252,11 @@ func Sync(b *BlobStorage, tree *HashTree, operation func(t *HashTree) error) err
219252
220253 log .Info .Println ("wrong generation, re-reading remote tree" )
221254 //resync and try again
222- err = tree .Mirror (b )
255+ err = tree .Mirror (b , concurrent )
223256 if err != nil {
224257 return err
225258 }
259+ log .Warning .Println ("remote tree has changed, refresh the file tree" )
226260 }
227261 return saveTree (tree )
228262}
@@ -258,10 +292,10 @@ func (ctx *ApiCtx) MoveEntry(src, dstDir *model.Node, name string) (*model.Node,
258292 if err != nil {
259293 return err
260294 }
261- doc .MetadataFile .Version += 1
262- doc .MetadataFile .DocName = name
263- doc .MetadataFile .Parent = dstDir .Id ()
264- doc .MetadataFile .MetadataModified = true
295+ doc .Metadata .Version += 1
296+ doc .Metadata .DocName = name
297+ doc .Metadata .Parent = dstDir .Id ()
298+ doc .Metadata .MetadataModified = true
265299
266300 hashStr , reader , err := doc .MetadataHashAndReader ()
267301 if err != nil {
@@ -306,7 +340,7 @@ func (ctx *ApiCtx) MoveEntry(src, dstDir *model.Node, name string) (*model.Node,
306340 return nil , err
307341 }
308342
309- return & model.Node {d .ToDocument (), src .Children , dstDir }, nil
343+ return & model.Node {Document : d .ToDocument (), Children : src .Children , Parent : dstDir }, nil
310344}
311345
312346// UploadDocument uploads a local document given by sourceDocPath under the parentId directory
@@ -324,7 +358,7 @@ func (ctx *ApiCtx) UploadDocument(parentId string, sourceDocPath string, notify
324358
325359 var err error
326360
327- tmpDir , err := ioutil . TempDir ("" , "rmupload" )
361+ tmpDir , err := os . MkdirTemp ("" , "rmupload" )
328362 if err != nil {
329363 return nil , err
330364 }
@@ -391,33 +425,14 @@ func (ctx *ApiCtx) UploadDocument(parentId string, sourceDocPath string, notify
391425 return doc .ToDocument (), nil
392426}
393427
394- func CreateCtx (http * transport.HttpClientCtx ) (* ApiCtx , error ) {
395- apiStorage := & BlobStorage {http }
396- cacheTree , err := loadTree ()
397- if err != nil {
398- fmt .Print (err )
399- return nil , err
400- }
401- err = cacheTree .Mirror (apiStorage )
402- if err != nil {
403- return nil , err
404- }
405- saveTree (cacheTree )
406- tree , err := DocumentsFileTree (cacheTree )
407- if err != nil {
408- return nil , fmt .Errorf ("failed to fetch document tree %v" , err )
409- }
410- return & ApiCtx {http , tree , apiStorage , cacheTree }, nil
411- }
412-
413428// DocumentsFileTree reads your remote documents and builds a file tree
414429// structure to represent them
415- func DocumentsFileTree (tree * HashTree ) ( * filetree.FileTreeCtx , error ) {
430+ func DocumentsFileTree (tree * HashTree ) * filetree.FileTreeCtx {
416431
417432 documents := make ([]* model.Document , 0 )
418433 for _ , d := range tree .Docs {
419434 //dont show deleted (already cached)
420- if d .Deleted {
435+ if d .Metadata . Deleted {
421436 continue
422437 }
423438 doc := d .ToDocument ()
@@ -434,7 +449,7 @@ func DocumentsFileTree(tree *HashTree) (*filetree.FileTreeCtx, error) {
434449 log .Trace .Println (d .Name (), d .IsFile ())
435450 }
436451
437- return & fileTree , nil
452+ return & fileTree
438453}
439454
440455// SyncComplete notfies that somethings has changed (triggers tablet sync)
0 commit comments