diff --git a/cmd/root.go b/cmd/root.go index ee75215f8..6ed7c380a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -11,7 +11,7 @@ import ( "github.com/spf13/cobra" ) -const AppVersion = "0.1.9" +const AppVersion = "0.1.10" var ctrl *pkg.ClICtrl diff --git a/internal/api/api_error.go b/internal/api/api_error.go new file mode 100644 index 000000000..0b59eb180 --- /dev/null +++ b/internal/api/api_error.go @@ -0,0 +1,27 @@ +package api + +import ( + "fmt" + "strings" +) + +type ApiError struct { + Message string + StatusCode int +} + +func (e *ApiError) Error() string { + return fmt.Sprintf("status %d with err: %s", e.StatusCode, e.Message) +} + +func IsApiError(err error) bool { + _, ok := err.(*ApiError) + return ok +} + +func IsFileNotInAlbumError(err error) bool { + if apiErr, ok := err.(*ApiError); ok { + return strings.Contains(apiErr.Message, "FILE_NOT_FOUND_IN_ALBUM") + } + return false +} diff --git a/internal/api/collection.go b/internal/api/collection.go index 6af702381..f8c4c24d4 100644 --- a/internal/api/collection.go +++ b/internal/api/collection.go @@ -42,3 +42,23 @@ func (c *Client) GetFiles(ctx context.Context, collectionID, sinceTime int64) ([ } return res.Files, res.HasMore, err } + +// GetFile .. +func (c *Client) GetFile(ctx context.Context, collectionID, fileID int64) (*File, error) { + var res struct { + File File `json:"file"` + } + r, err := c.restClient.R(). + SetContext(ctx). + SetQueryParam("collectionID", strconv.FormatInt(collectionID, 10)). + SetQueryParam("fileID", strconv.FormatInt(fileID, 10)). + SetResult(&res). + Get("/collections/file") + if r.IsError() { + return nil, &ApiError{ + StatusCode: r.StatusCode(), + Message: r.String(), + } + } + return &res.File, err +} diff --git a/internal/api/login_type.go b/internal/api/login_type.go index 9c60d4eb1..50149aed7 100644 --- a/internal/api/login_type.go +++ b/internal/api/login_type.go @@ -1,8 +1,6 @@ package api import ( - "fmt" - "github.com/google/uuid" ) @@ -15,15 +13,6 @@ type SRPAttributes struct { IsEmailMFAEnabled bool `json:"isEmailMFAEnabled" binding:"required"` } -type ApiError struct { - Message string - StatusCode int -} - -func (e *ApiError) Error() string { - return fmt.Sprintf("status %d with err: %s", e.StatusCode, e.Message) -} - type CreateSRPSessionResponse struct { SessionID uuid.UUID `json:"sessionID" binding:"required"` SRPB string `json:"srpB" binding:"required"` diff --git a/pkg/remote_to_disk_file.go b/pkg/remote_to_disk_file.go index 382751853..91a105032 100644 --- a/pkg/remote_to_disk_file.go +++ b/pkg/remote_to_disk_file.go @@ -32,18 +32,17 @@ func (c *ClICtrl) syncFiles(ctx context.Context, account model.Account) error { model.SortAlbumFileEntry(entries) defer utils.TimeTrack(time.Now(), "process_files") var albumDiskInfo *albumDiskInfo - for i, entry := range entries { - if entry.SyncedLocally { + for i, albumFileEntry := range entries { + if albumFileEntry.SyncedLocally { continue } - albumInfo, ok := albumIDToMetaMap[entry.AlbumID] + albumInfo, ok := albumIDToMetaMap[albumFileEntry.AlbumID] if !ok { - log.Printf("Album %d not found in local metadata", entry.AlbumID) + log.Printf("Album %d not found in local metadata", albumFileEntry.AlbumID) continue } - if albumInfo.IsDeleted { - putErr := c.DeleteAlbumEntry(ctx, entry) + putErr := c.DeleteAlbumEntry(ctx, albumFileEntry) if putErr != nil { return putErr } @@ -56,7 +55,7 @@ func (c *ClICtrl) syncFiles(ctx context.Context, account model.Account) error { return err } } - fileBytes, err := c.GetValue(ctx, model.RemoteFiles, []byte(fmt.Sprintf("%d", entry.FileID))) + fileBytes, err := c.GetValue(ctx, model.RemoteFiles, []byte(fmt.Sprintf("%d", albumFileEntry.FileID))) if err != nil { return err } @@ -67,7 +66,7 @@ func (c *ClICtrl) syncFiles(ctx context.Context, account model.Account) error { return err } log.Printf("[%d/%d] Sync %s for album %s", i, len(entries), existingEntry.GetTitle(), albumInfo.AlbumName) - err = c.downloadEntry(ctx, albumDiskInfo, *existingEntry, entry) + err = c.downloadEntry(ctx, albumDiskInfo, *existingEntry, albumFileEntry) if err != nil { if errors.Is(err, model.ErrDecryption) { continue @@ -81,7 +80,15 @@ func (c *ClICtrl) syncFiles(ctx context.Context, account model.Account) error { } } } else { - log.Fatalf("File %d not found in remote", entry.FileID) + // file metadata is missing in the localDB + if albumFileEntry.IsDeleted { + delErr := c.DeleteAlbumEntry(ctx, albumFileEntry) + if delErr != nil { + log.Fatalf("Error deleting album entry %d (deleted: %v) %v", albumFileEntry.FileID, albumFileEntry.IsDeleted, delErr) + } + } else { + log.Fatalf("Failed to find entry in db for file %d (deleted: %v)", albumFileEntry.FileID, albumFileEntry.IsDeleted) + } } }