136 lines
4.1 KiB
Go
136 lines
4.1 KiB
Go
package pkg
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/ente-io/cli/pkg/model"
|
|
"github.com/ente-io/cli/pkg/model/export"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"path/filepath"
|
|
)
|
|
|
|
func (c *ClICtrl) createLocalFolderForRemoteAlbums(ctx context.Context, account model.Account) error {
|
|
path := account.ExportDir
|
|
albums, err := c.getRemoteAlbums(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
userID := ctx.Value("user_id").(int64)
|
|
folderToMetaMap, albumIDToMetaMap, err := readFolderMetadata(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, album := range albums {
|
|
if album.IsDeleted {
|
|
if meta, ok := albumIDToMetaMap[album.ID]; ok {
|
|
log.Printf("Deleting album %s as it is deleted", meta.AlbumName)
|
|
if err = os.RemoveAll(filepath.Join(path, meta.FolderName)); err != nil {
|
|
return err
|
|
}
|
|
delete(folderToMetaMap, meta.FolderName)
|
|
delete(albumIDToMetaMap, meta.ID)
|
|
}
|
|
continue
|
|
}
|
|
metaByID := albumIDToMetaMap[album.ID]
|
|
|
|
if metaByID != nil {
|
|
if strings.EqualFold(metaByID.AlbumName, album.AlbumName) {
|
|
//log.Printf("Skipping album %s as it already exists", album.AlbumName)
|
|
continue
|
|
}
|
|
}
|
|
|
|
albumFolderName := filepath.Clean(album.AlbumName)
|
|
// replace : with _
|
|
albumFolderName = strings.ReplaceAll(albumFolderName, ":", "_")
|
|
albumFolderName = strings.ReplaceAll(albumFolderName, "/", "_")
|
|
albumID := album.ID
|
|
|
|
if _, ok := folderToMetaMap[albumFolderName]; ok {
|
|
for i := 1; ; i++ {
|
|
newAlbumName := fmt.Sprintf("%s_%d", albumFolderName, i)
|
|
if _, ok := folderToMetaMap[newAlbumName]; !ok {
|
|
albumFolderName = newAlbumName
|
|
break
|
|
}
|
|
}
|
|
}
|
|
// Create album and meta folders if they don't exist
|
|
albumPath := filepath.Clean(filepath.Join(path, albumFolderName))
|
|
metaPath := filepath.Join(albumPath, ".meta")
|
|
if metaByID == nil {
|
|
log.Printf("Adding folder %s for album %s", albumFolderName, album.AlbumName)
|
|
for _, p := range []string{albumPath, metaPath} {
|
|
if _, err := os.Stat(p); os.IsNotExist(err) {
|
|
if err = os.Mkdir(p, 0755); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// rename meta.FolderName to albumFolderName
|
|
oldAlbumPath := filepath.Join(path, metaByID.FolderName)
|
|
log.Printf("Renaming path from %s to %s for album %s", oldAlbumPath, albumPath, album.AlbumName)
|
|
if err = os.Rename(oldAlbumPath, albumPath); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
// Handle meta file
|
|
metaFilePath := filepath.Join(path, albumFolderName, albumMetaFolder, albumMetaFile)
|
|
metaData := export.AlbumMetadata{
|
|
ID: album.ID,
|
|
OwnerID: album.OwnerID,
|
|
AlbumName: album.AlbumName,
|
|
IsDeleted: album.IsDeleted,
|
|
AccountOwnerIDs: []int64{userID},
|
|
FolderName: albumFolderName,
|
|
}
|
|
if err = writeJSONToFile(metaFilePath, metaData); err != nil {
|
|
return err
|
|
}
|
|
folderToMetaMap[albumFolderName] = &metaData
|
|
albumIDToMetaMap[albumID] = &metaData
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// readFolderMetadata returns a map of folder name to album metadata for all folders in the given path
|
|
// and a map of album ID to album metadata for all albums in the given path.
|
|
func readFolderMetadata(path string) (map[string]*export.AlbumMetadata, map[int64]*export.AlbumMetadata, error) {
|
|
result := make(map[string]*export.AlbumMetadata)
|
|
albumIdToMetadataMap := make(map[int64]*export.AlbumMetadata)
|
|
// Read the top-level directories in the given path
|
|
entries, err := os.ReadDir(path)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
for _, entry := range entries {
|
|
if entry.IsDir() {
|
|
dirName := entry.Name()
|
|
metaFilePath := filepath.Join(path, dirName, albumMetaFolder, albumMetaFile)
|
|
// Initialize as nil, will remain nil if JSON file is not found or not readable
|
|
result[dirName] = nil
|
|
// Read the JSON file if it exists
|
|
if _, err := os.Stat(metaFilePath); err == nil {
|
|
var metaData export.AlbumMetadata
|
|
metaDataBytes, err := os.ReadFile(metaFilePath)
|
|
if err != nil {
|
|
continue // Skip this entry if reading fails
|
|
}
|
|
|
|
if err := json.Unmarshal(metaDataBytes, &metaData); err == nil {
|
|
metaData.FolderName = dirName
|
|
result[dirName] = &metaData
|
|
albumIdToMetadataMap[metaData.ID] = &metaData
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result, albumIdToMetadataMap, nil
|
|
}
|