diff --git a/internal/promt.go b/internal/promt.go index 5a9145333..e616934b3 100644 --- a/internal/promt.go +++ b/internal/promt.go @@ -75,3 +75,70 @@ func GetCode(promptText string, length int) (string, error) { return ott, nil } } + +func GetExportDir() string { + for { + exportDir, err := GetUserInput("Enter export directory") + if err != nil { + return "" + } + if exportDir == "" { + fmt.Printf("invalid export directory: %s\n", err) + continue + } + exportDir, err = ResolvePath(exportDir) + if err != nil { + fmt.Printf("invalid export directory: %s\n", err) + continue + } + _, err = ValidateDirForWrite(exportDir) + if err != nil { + fmt.Printf("invalid export directory: %s\n", err) + continue + } + + return exportDir + } +} + +func ValidateDirForWrite(dir string) (bool, error) { + // Check if the path exists + fileInfo, err := os.Stat(dir) + if err != nil { + if os.IsNotExist(err) { + return false, fmt.Errorf("path does not exist: %s", dir) + } + return false, err + } + + // Check if the path is a directory + if !fileInfo.IsDir() { + return false, fmt.Errorf("path is not a directory") + } + + // Check for write permission + // Check for write permission by creating a temp file + tempFile, err := os.CreateTemp(dir, "write_test_") + if err != nil { + return false, fmt.Errorf("write permission denied: %v", err) + } + + // Delete temp file + defer os.Remove(tempFile.Name()) + if err != nil { + return false, err + } + + return true, nil +} + +func ResolvePath(path string) (string, error) { + if path[:2] != "~/" { + return path, nil + } + home, err := os.UserHomeDir() + if err != nil { + return "", err + } + return home + path[1:], nil +} diff --git a/pkg/account.go b/pkg/account.go index 6ac1e6018..7d5524f97 100644 --- a/pkg/account.go +++ b/pkg/account.go @@ -24,6 +24,11 @@ func (c *ClICtrl) AddAccount(cxt context.Context) { }() app := internal.GetAppType() cxt = context.WithValue(cxt, "app", string(app)) + dir := internal.GetExportDir() + if dir == "" { + flowErr = fmt.Errorf("export directory not set") + return + } email, flowErr := internal.GetUserInput("Enter email address") if flowErr != nil { return @@ -61,7 +66,8 @@ func (c *ClICtrl) AddAccount(cxt context.Context) { flowErr = decErr return } - err := c.storeAccount(cxt, email, authResponse.ID, app, secretInfo) + + err := c.storeAccount(cxt, email, authResponse.ID, app, secretInfo, dir) if err != nil { flowErr = err return @@ -70,7 +76,7 @@ func (c *ClICtrl) AddAccount(cxt context.Context) { } } -func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, secretInfo *model.AccSecretInfo) error { +func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, secretInfo *model.AccSecretInfo, exportDir string) error { // get password err := c.DB.Update(func(tx *bolt.Tx) error { b, err := tx.CreateBucketIfNotExists([]byte(AccBucket)) @@ -85,6 +91,7 @@ func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, ap Token: *model.MakeEncString(secretInfo.Token, c.KeyHolder.DeviceKey), App: app, PublicKey: encoding.EncodeBase64(secretInfo.PublicKey), + ExportDir: exportDir, } accInfoBytes, err := json.Marshal(accInfo) if err != nil { @@ -150,7 +157,7 @@ func (c *ClICtrl) UpdateAccount(ctx context.Context, params model.UpdateAccountP return fmt.Errorf("account not found") } if params.ExportDir != nil && *params.ExportDir != "" { - _, err := validateExportDirectory(*params.ExportDir) + _, err := internal.ValidateDirForWrite(*params.ExportDir) if err != nil { return err } diff --git a/pkg/disk.go b/pkg/disk.go index 67568dc27..adb9345fc 100644 --- a/pkg/disk.go +++ b/pkg/disk.go @@ -5,7 +5,6 @@ import ( "cli-go/pkg/model/export" "encoding/json" "errors" - "fmt" "os" ) @@ -97,34 +96,3 @@ func readJSONFromFile(filePath string, data interface{}) error { decoder := json.NewDecoder(file) return decoder.Decode(data) } - -func validateExportDirectory(dir string) (bool, error) { - // Check if the path exists - fileInfo, err := os.Stat(dir) - if err != nil { - if os.IsNotExist(err) { - return false, fmt.Errorf("path does not exist: %s", dir) - } - return false, err - } - - // Check if the path is a directory - if !fileInfo.IsDir() { - return false, fmt.Errorf("path is not a directory") - } - - // Check for write permission - // Check for write permission by creating a temp file - tempFile, err := os.CreateTemp(dir, "write_test_") - if err != nil { - return false, fmt.Errorf("write permission denied: %v", err) - } - - // Delete temp file - defer os.Remove(tempFile.Name()) - if err != nil { - return false, err - } - - return true, nil -} diff --git a/pkg/remote_sync.go b/pkg/remote_sync.go index 44e7a31cc..0b1886473 100644 --- a/pkg/remote_sync.go +++ b/pkg/remote_sync.go @@ -55,7 +55,6 @@ func (c *ClICtrl) fetchRemoteFiles(ctx context.Context) error { } for _, album := range albums { if album.IsDeleted { - log.Printf("Skipping album %s as it is deleted", album.AlbumName) continue } diff --git a/pkg/sync.go b/pkg/sync.go index f87826bb0..504ffbd3d 100644 --- a/pkg/sync.go +++ b/pkg/sync.go @@ -1,6 +1,7 @@ package pkg import ( + "cli-go/internal" "cli-go/pkg/model" "context" "encoding/base64" @@ -25,7 +26,7 @@ func (c *ClICtrl) StartSync() error { log.Printf("Skip account %s: no export directory configured", account.Email) continue } - _, err = validateExportDirectory(account.ExportDir) + _, err = internal.ValidateDirForWrite(account.ExportDir) if err != nil { log.Printf("Skip export, error: %v while validing exportDir %s\n", err, account.ExportDir) continue