diff --git a/internal/app/app.go b/internal/app/app.go index e61b2ff..7a45465 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/sirupsen/logrus" "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure" + "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/matcher" "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/authentication" "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/category" @@ -29,50 +30,58 @@ func Run() { if err != nil { os.Exit(2) } - //ScanLocalDirectories(context) - GetAllCategoriesFromServer(context) + filesystemNodes := scanLocalDirectories(context) + categories := getAllCategoriesFromServer(context) - //FindMissingAlbums() - //CreateMissingAlbums() - //FindMissingImages() - //UploadImages() + synchronizeCategories(filesystemNodes, categories) + + + findMissingImages() + uploadImages() _ = authentication.Logout(context.Piwigo) } -func ScanLocalDirectories(context *AppContext) { - fileNodes, err := localFileStructure.ScanLocalFileStructure(context.LocalRootPath) - if err != nil { - panic(err) - } - for _, node := range fileNodes { - logrus.Debugln("found path entry:", node.Key) - } +func synchronizeCategories(filesystemNodes map[string]*localFileStructure.FilesystemNode, categories map[string]*category.PiwigoCategory) { + missingCategories := findMissingCategories(filesystemNodes, categories) + createMissingCategories(missingCategories) } -func GetAllCategoriesFromServer(context *AppContext) { - - err := category.GetAllCategories(context.Piwigo) +func scanLocalDirectories(context *AppContext) map[string]*localFileStructure.FilesystemNode { + fileNodes, err := localFileStructure.ScanLocalFileStructure(context.LocalRootPath) if err != nil { os.Exit(3) } - + return fileNodes } -func FindMissingAlbums() { - logrus.Warnln("Looking up missing albums (NotImplemented)") +func getAllCategoriesFromServer(context *AppContext) map[string]*category.PiwigoCategory { + + categories, err := category.GetAllCategories(context.Piwigo) + if err != nil { + os.Exit(4) + } + + return categories } -func CreateMissingAlbums() { +func findMissingCategories(fileSystem map[string]*localFileStructure.FilesystemNode, categories map[string]*category.PiwigoCategory) []string { + return matcher.FindMissingCategories(fileSystem, categories) +} + +func createMissingCategories(categories []string) { logrus.Warnln("Creating missing albums (NotImplemented)") + for _, c := range categories { + logrus.Debug(c) + } } -func FindMissingImages() { +func findMissingImages() { logrus.Warnln("Finding missing images (NotImplemented)") } -func UploadImages() { +func uploadImages() { logrus.Warnln("Uploading missing images (NotImplemented)") } diff --git a/internal/pkg/localFileStructure/filesystemScanner.go b/internal/pkg/localFileStructure/filesystemScanner.go index 1ae15d7..0dff1a5 100644 --- a/internal/pkg/localFileStructure/filesystemScanner.go +++ b/internal/pkg/localFileStructure/filesystemScanner.go @@ -3,10 +3,13 @@ package localFileStructure import ( "os" "path/filepath" + "strings" ) -func ScanLocalFileStructure(path string) (map[string]FilesystemNode, error) { - fileMap := make(map[string]FilesystemNode) +func ScanLocalFileStructure(path string) (map[string]*FilesystemNode, error) { + fileMap := make(map[string]*FilesystemNode) + + relativeRoot := filepath.Base(path)+"/" err := filepath.Walk(path, func(p string, info os.FileInfo, err error) error { if path == p { @@ -15,8 +18,10 @@ func ScanLocalFileStructure(path string) (map[string]FilesystemNode, error) { //TODO: Only allow jpg and png files here - fileMap[p] = FilesystemNode{ - Key: p, + key := strings.Replace(p,relativeRoot,"",1) + + fileMap[p] = &FilesystemNode{ + Key: key, Name: info.Name(), IsDir: info.IsDir(), } diff --git a/internal/pkg/matcher/category.go b/internal/pkg/matcher/category.go new file mode 100644 index 0000000..def6645 --- /dev/null +++ b/internal/pkg/matcher/category.go @@ -0,0 +1,27 @@ +package matcher + +import ( + "github.com/sirupsen/logrus" + "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure" + "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/category" +) + +func FindMissingCategories(fileSystem map[string]*localFileStructure.FilesystemNode, categories map[string]*category.PiwigoCategory) []string { + missingCategories := []string{} + for _, file := range fileSystem { + if !file.IsDir { + continue + } + + _, exists := categories[file.Key] + + if !exists { + logrus.Infof("Found missing category %s", file.Key) + missingCategories = append(missingCategories, file.Key) + } else { + logrus.Debugf("Found existing category %s", file.Key) + } + } + + return missingCategories +} diff --git a/internal/pkg/piwigo/category/query.go b/internal/pkg/piwigo/category/query.go index 28dfa2b..467547b 100644 --- a/internal/pkg/piwigo/category/query.go +++ b/internal/pkg/piwigo/category/query.go @@ -3,16 +3,17 @@ package category import ( "encoding/json" "errors" + "fmt" "github.com/sirupsen/logrus" "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "net/http" "net/url" ) -func GetAllCategories(context *piwigo.PiwigoContext) error { +func GetAllCategories(context *piwigo.PiwigoContext) (map[string]*PiwigoCategory, error) { logrus.Debugln("Starting GetAllCategories") if context.Cookies == nil { - return errors.New("Not logged in and no cookies found! Can not get the category list!") + return nil, errors.New("Not logged in and no cookies found! Can not get the category list!") } formData := url.Values{} @@ -24,25 +25,61 @@ func GetAllCategories(context *piwigo.PiwigoContext) error { if err != nil { logrus.Errorln("The HTTP request failed with error %s", err) - return err + return nil, err } var statusResponse getCategoryListResponse if err := json.NewDecoder(response.Body).Decode(&statusResponse); err != nil { logrus.Errorln(err) - return err + return nil, err } if statusResponse.Status != "ok" { logrus.Errorf("Got state %s while loading categories", statusResponse.Status) - return errors.New("Could not load categories") + return nil, errors.New("Could not load categories") } logrus.Infof("Successfully got all categories from %s", context.Url) - for _, category := range statusResponse.Result.Categories { - logrus.Debugf("Category %d - %s", category.ID, category.Name) - } + categories := buildCategoryMap(&statusResponse) + buildCategoryKeys(categories) + categoryLookups := buildLookupMap(categories) - return nil + return categoryLookups, nil +} + +func buildLookupMap(categories map[int]*PiwigoCategory) map[string]*PiwigoCategory { + categoryLookups := map[string]*PiwigoCategory{} + for _, category := range categories { + logrus.Debugf("Category %s", category.Key) + categoryLookups[category.Key] = category + } + return categoryLookups +} + +func buildCategoryMap(statusResponse *getCategoryListResponse) map[int]*PiwigoCategory { + categories := map[int]*PiwigoCategory{} + for _, category := range statusResponse.Result.Categories { + categories[category.ID] = &PiwigoCategory{Id: category.ID, ParentId: category.IDUppercat, Name: category.Name, Key: category.Name} + } + return categories +} + +func buildCategoryKeys(categories map[int]*PiwigoCategory) { + for _, category := range categories { + if category.ParentId == 0 { + category.Key = category.Name + continue + } + + key := category.Name + parentId := category.ParentId + for parentId != 0 { + parent := categories[parentId] + key = fmt.Sprintf("%s/%s", parent.Name, key) + parentId = parent.ParentId + } + + category.Key = key + } } diff --git a/internal/pkg/piwigo/category/types.go b/internal/pkg/piwigo/category/types.go index 4e4a84f..fa58409 100644 --- a/internal/pkg/piwigo/category/types.go +++ b/internal/pkg/piwigo/category/types.go @@ -1,31 +1,32 @@ package category type PiwigoCategory struct { - Id int - Name string - Key string + Id int + ParentId int + Name string + Key string } type getCategoryListResponse struct { - Status string `json:"stat"` + Status string `json:"stat"` Result struct { Categories []struct { - ID int `json:"id"` - Name string `json:"name"` - Comment string `json:"comment"` - Permalink interface{} `json:"permalink"` - Status string `json:"status"` - Uppercats string `json:"uppercats"` - GlobalRank string `json:"global_rank"` - IDUppercat interface{} `json:"id_uppercat"` - NbImages int `json:"nb_images"` - TotalNbImages int `json:"total_nb_images"` - RepresentativePictureID string `json:"representative_picture_id"` - DateLast interface{} `json:"date_last"` - MaxDateLast string `json:"max_date_last"` - NbCategories int `json:"nb_categories"` - URL string `json:"url"` - TnURL string `json:"tn_url"` + ID int `json:"id"` + Name string `json:"name"` + Comment string `json:"comment,omitempty"` + Permalink string `json:"permalink,omitempty"` + Status string `json:"status,omitempty"` + Uppercats string `json:"uppercats,omitempty"` + GlobalRank string `json:"global_rank,omitempty"` + IDUppercat int `json:"id_uppercat,string,omitempty"` + NbImages int `json:"nb_images,omitempty"` + TotalNbImages int `json:"total_nb_images,omitempty"` + RepresentativePictureID string `json:"representative_picture_id,omitempty"` + DateLast string `json:"date_last,omitempty"` + MaxDateLast string `json:"max_date_last,omitempty"` + NbCategories int `json:"nb_categories,omitempty"` + URL string `json:"url,omitempty"` + TnURL string `json:"tn_url,omitempty"` } `json:"categories"` } `json:"result"` }