2019-02-25 23:36:18 +01:00
package app
2019-02-25 23:51:18 +01:00
import (
2019-03-03 23:44:13 +01:00
"git.haefelfinger.net/piwigo/PiwigoDirectoryUploader/internal/pkg/localFileStructure"
2019-03-11 21:42:20 +01:00
"git.haefelfinger.net/piwigo/PiwigoDirectoryUploader/internal/pkg/piwigo"
2019-03-02 00:21:01 +01:00
"github.com/sirupsen/logrus"
2019-03-17 23:05:17 +01:00
"path/filepath"
2019-02-25 23:51:18 +01:00
)
2019-02-25 23:36:18 +01:00
2019-03-17 23:05:17 +01:00
// to make use of the new local data store, we have to rethink and refactor the whole local detection process
// extend the storage of the images to keep track of upload state
// TBD: How to deal with updates -> delete / upload all based on md5 sums
2019-03-19 23:08:28 +01:00
type fileChecksumCalculator func ( filePath string ) ( string , error )
// Update the local image metadata by walking through all found files and check if the modification date has changed
// or if they are new to the local database. If the files is new or changed, the md5sum will be rebuilt as well.
2019-03-17 23:05:17 +01:00
func synchronizeLocalImageMetadata ( metadataStorage ImageMetadataProvider , fileSystemNodes map [ string ] * localFileStructure . FilesystemNode , checksumCalculator fileChecksumCalculator ) error {
2019-03-17 23:57:28 +01:00
logrus . Debugf ( "Starting synchronizeLocalImageMetadata" )
2019-03-17 23:05:17 +01:00
logrus . Info ( "Synchronizing local image metadata database with local available images" )
2019-02-27 23:26:18 +01:00
2019-03-17 23:05:17 +01:00
for _ , file := range fileSystemNodes {
if file . IsDir {
// we are only interested in files not directories
continue
}
2019-02-25 23:36:18 +01:00
2019-03-19 21:19:38 +01:00
metadata , err := metadataStorage . ImageMetadata ( file . Key )
2019-03-17 23:05:17 +01:00
if err == ErrorRecordNotFound {
logrus . Debugf ( "No metadata for %s found. Creating new entry." , file . Key )
metadata = ImageMetaData { }
metadata . Filename = file . Name
metadata . RelativeImagePath = file . Key
metadata . CategoryPath = filepath . Dir ( file . Key )
} else if err != nil {
logrus . Errorf ( "Could not get metadata due to trouble. Cancelling - %s" , err )
return err
}
2019-03-02 00:32:15 +01:00
2019-03-17 23:05:17 +01:00
if metadata . LastChange . Equal ( file . ModTime ) {
logrus . Infof ( "No changed detected on file %s -> keeping current state" , file . Key )
continue
}
2019-03-02 00:32:15 +01:00
2019-03-17 23:05:17 +01:00
metadata . LastChange = file . ModTime
metadata . UploadRequired = true
metadata . Md5Sum , err = checksumCalculator ( file . Path )
if err != nil {
logrus . Warnf ( "Could not calculate checksum for file %s. Skipping..." , file . Path )
continue
}
2019-03-01 00:14:52 +01:00
2019-03-17 23:05:17 +01:00
err = metadataStorage . SaveImageMetadata ( metadata )
2019-03-01 00:14:52 +01:00
if err != nil {
return err
}
}
2019-03-17 23:57:28 +01:00
logrus . Debugf ( "Finished synchronizeLocalImageMetadata" )
2019-03-01 00:14:52 +01:00
return nil
2019-02-25 23:36:18 +01:00
}
2019-03-17 23:05:17 +01:00
2019-03-19 23:08:28 +01:00
// This method agregates the check for files with missing piwigoids and if changed files need to be uploaded again.
func synchronizePiwigoMetadata ( piwigoCtx * piwigo . PiwigoContext , metadataStorage ImageMetadataProvider ) error {
// TODO: check if category has to be assigned (image possibly added to two albums -> only uploaded once but assigned multiple times) -> implement later
2019-03-17 23:57:28 +01:00
logrus . Debugf ( "Starting synchronizePiwigoMetadata" )
2019-03-19 23:08:28 +01:00
err := updatePiwigoIdIfAlreadyUploaded ( metadataStorage , piwigoCtx )
if err != nil {
2019-03-17 23:57:28 +01:00
return err
}
2019-03-19 23:08:28 +01:00
err = checkPiwigoForChangedImages ( metadataStorage , piwigoCtx )
if err != nil {
return err
2019-03-17 23:57:28 +01:00
}
2019-03-19 23:08:28 +01:00
return nil
2019-03-17 23:57:28 +01:00
}
2019-03-17 23:05:17 +01:00
2019-03-19 23:08:28 +01:00
// Check all images with upload required if they are really changed and need to be uploaded to the server.
func checkPiwigoForChangedImages ( provider ImageMetadataProvider , piwigoCtx * piwigo . PiwigoContext ) error {
logrus . Infof ( "checking for pending files that are already on piwigo and updating piwigoids..." )
2019-03-17 23:05:17 +01:00
2019-03-19 23:08:28 +01:00
images , err := provider . ImageMetadataToUpload ( )
if err != nil {
return err
}
for _ , img := range images {
if img . PiwigoId == 0 {
continue
}
2019-03-20 00:14:10 +01:00
state , err := piwigoCtx . ImageCheckFile ( img . PiwigoId , img . Md5Sum )
2019-03-19 23:08:28 +01:00
if err != nil {
logrus . Warnf ( "Error during file change check of file %s" , img . RelativeImagePath )
continue
}
if state == piwigo . ImageStateUptodate {
logrus . Debugf ( "File %s - %d has not changed" , img . RelativeImagePath , img . PiwigoId )
img . UploadRequired = false
2019-03-20 00:14:10 +01:00
err = provider . SaveImageMetadata ( img )
2019-03-19 23:08:28 +01:00
if err != nil {
logrus . Warnf ( "Could not save image data of image %s" , img . RelativeImagePath )
}
}
}
2019-03-17 23:05:17 +01:00
return nil
}
2019-03-19 23:08:28 +01:00
// This function calls piwigo and checks if the given md5sum is already present.
// Only files without a piwigo id are used to query the server.
2019-03-20 00:14:10 +01:00
func updatePiwigoIdIfAlreadyUploaded ( provider ImageMetadataProvider , piwigoCtx * piwigo . PiwigoContext ) error {
2019-03-19 23:08:28 +01:00
logrus . Infof ( "checking for pending files that are already on piwigo and updating piwigoids..." )
images , err := provider . ImageMetadataToUpload ( )
if err != nil {
return err
}
logrus . Debugln ( "Preparing lookuplist for missing piwigo ids..." )
files := make ( [ ] string , 0 , len ( images ) )
for _ , img := range images {
if img . PiwigoId == 0 {
files = append ( files , img . Md5Sum )
}
}
2019-03-20 00:14:10 +01:00
missingResults , err := piwigoCtx . ImagesExistOnPiwigo ( files )
2019-03-19 23:08:28 +01:00
if err != nil {
return err
}
for md5sum , piwigoId := range missingResults {
logrus . Debugf ( "Setting piwigo id of %s to %d" , md5sum , piwigoId )
err = provider . SavePiwigoIdAndUpdateUploadFlag ( md5sum , piwigoId )
if err != nil {
logrus . Warnf ( "Could not save piwigo id %d for file %s" , piwigoId , md5sum )
}
}
return nil
}
// STEP 3: Upload missing images
// - upload file in chunks
// - assign image to category
2019-03-17 23:05:17 +01:00
//
//func uploadImages(context *appContext, missingFiles []*localFileStructure.ImageNode, existingCategories map[string]*piwigo.PiwigoCategory) error {
//
// // We sort the files by path to populate per category and not random by file
// sort.Slice(missingFiles, func(i, j int) bool {
// return missingFiles[i].Path < missingFiles[j].Path
// })
//
// for _, file := range missingFiles {
// categoryId := existingCategories[file.CategoryName].Id
//
// imageId, err := piwigo.UploadImage(context.piwigo, file.Path, file.Md5Sum, categoryId)
// if err != nil {
// return err
// }
// file.ImageId = imageId
// }
//
// return nil
//}