123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- package pkg
- import (
- "context"
- "encoding/base64"
- "fmt"
- "github.com/ente-io/cli/internal"
- "github.com/ente-io/cli/internal/api"
- "github.com/ente-io/cli/pkg/model"
- bolt "go.etcd.io/bbolt"
- "log"
- "time"
- )
- func (c *ClICtrl) Export() error {
- accounts, err := c.GetAccounts(context.Background())
- if err != nil {
- return err
- }
- if len(accounts) == 0 {
- fmt.Printf("No accounts to sync\n Add account using `account add` cmd\n")
- return nil
- }
- for _, account := range accounts {
- log.SetPrefix(fmt.Sprintf("[%s-%s] ", account.App, account.Email))
- if account.ExportDir == "" {
- log.Printf("Skip account %s: no export directory configured", account.Email)
- continue
- }
- _, err = internal.ValidateDirForWrite(account.ExportDir)
- if err != nil {
- log.Printf("Skip export, error: %v while validing exportDir %s\n", err, account.ExportDir)
- continue
- }
- if account.App == api.AppAuth {
- log.Printf("Skip account %s: auth export is not supported", account.Email)
- continue
- }
- log.Println("start sync")
- retryCount := 0
- for {
- err = c.SyncAccount(account)
- if err != nil {
- if model.ShouldRetrySync(err) && retryCount < 20 {
- retryCount = retryCount + 1
- timeInSecond := time.Duration(retryCount*10) * time.Second
- log.Printf("Connection err, waiting for %s before trying again", timeInSecond.String())
- time.Sleep(timeInSecond)
- continue
- }
- fmt.Printf("Error syncing account %s: %s\n", account.Email, err)
- return err
- } else {
- log.Println("sync done")
- break
- }
- }
- }
- return nil
- }
- func (c *ClICtrl) SyncAccount(account model.Account) error {
- secretInfo, err := c.KeyHolder.LoadSecrets(account)
- if err != nil {
- return err
- }
- ctx := c.buildRequestContext(context.Background(), account)
- err = createDataBuckets(c.DB, account)
- if err != nil {
- return err
- }
- c.Client.AddToken(account.AccountKey(), base64.URLEncoding.EncodeToString(secretInfo.Token))
- err = c.fetchRemoteCollections(ctx)
- if err != nil {
- log.Printf("Error fetching collections: %s", err)
- return err
- }
- err = c.fetchRemoteFiles(ctx)
- if err != nil {
- log.Printf("Error fetching files: %s", err)
- return err
- }
- err = c.createLocalFolderForRemoteAlbums(ctx, account)
- if err != nil {
- log.Printf("Error creating local folders: %s", err)
- return err
- }
- err = c.syncFiles(ctx, account)
- if err != nil {
- log.Printf("Error syncing files: %s", err)
- return err
- }
- return nil
- }
- func (c *ClICtrl) buildRequestContext(ctx context.Context, account model.Account) context.Context {
- ctx = context.WithValue(ctx, "app", string(account.App))
- ctx = context.WithValue(ctx, "account_key", account.AccountKey())
- ctx = context.WithValue(ctx, "user_id", account.UserID)
- return ctx
- }
- func createDataBuckets(db *bolt.DB, account model.Account) error {
- return db.Update(func(tx *bolt.Tx) error {
- dataBucket, err := tx.CreateBucketIfNotExists([]byte(account.AccountKey()))
- if err != nil {
- return fmt.Errorf("create bucket: %s", err)
- }
- for _, subBucket := range []model.PhotosStore{model.KVConfig, model.RemoteAlbums, model.RemoteFiles, model.RemoteAlbumEntries} {
- _, err := dataBucket.CreateBucketIfNotExists([]byte(subBucket))
- if err != nil {
- return err
- }
- }
- return nil
- })
- }
|