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-20 23:15:41 +01:00
func synchronizeLocalImageMetadata ( metadataStorage ImageMetadataProvider , fileSystemNodes map [ string ] * localFileStructure . FilesystemNode , categories map [ string ] * piwigo . PiwigoCategory , 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-20 23:15:41 +01:00
metadata , err := metadataStorage . ImageMetadata ( file . Path )
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
2019-03-20 23:15:41 +01:00
metadata . FullImagePath = file . Path
2019-03-17 23:05:17 +01:00
metadata . CategoryPath = filepath . Dir ( file . Key )
2019-03-20 23:15:41 +01:00
category , exist := categories [ metadata . CategoryPath ]
if exist {
metadata . CategoryId = category . Id
} else {
logrus . Warnf ( "No category found for image %s" , file . Path )
}
2019-03-17 23:05:17 +01:00
} 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-20 23:15:41 +01:00
// Uploads the pending images to the piwigo gallery and assign the category of to the image.
// Update local metadata and set upload flag to false. Also updates the piwigo image id if there was a difference.
func uploadImages ( piwigoCtx piwigo . PiwigoImageApi , metadataProvider ImageMetadataProvider ) error {
logrus . Debugf ( "Starting uploadImages" )
images , err := metadataProvider . ImageMetadataToUpload ( )
if err != nil {
return err
}
logrus . Infof ( "Uploading %d images to piwigo" , len ( images ) )
for _ , img := range images {
imgId , err := piwigoCtx . UploadImage ( img . PiwigoId , img . FullImagePath , img . Md5Sum , img . CategoryId )
if err != nil {
logrus . Warnf ( "could not upload image %s. Continuing with the next image." , img . FullImagePath )
continue
}
if imgId > 0 && imgId != img . PiwigoId {
img . PiwigoId = imgId
logrus . Debugf ( "Updating image %d with piwigo id %d" , img . ImageId , img . PiwigoId )
}
logrus . Infof ( "Successfully uploaded %s" , img . FullImagePath )
img . UploadRequired = false
err = metadataProvider . SaveImageMetadata ( img )
if err != nil {
logrus . Warnf ( "could not save uploaded image %s. Continuing with the next image." , img . FullImagePath )
continue
}
}
logrus . Debugf ( "Finished uploadImages successfully" )
return nil
}
// This method aggregates the check for files with missing piwigoids and if changed files need to be uploaded again.
func synchronizePiwigoMetadata ( piwigoCtx piwigo . PiwigoImageApi , metadataProvider ImageMetadataProvider ) error {
2019-03-19 23:08:28 +01:00
// 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-20 23:15:41 +01:00
err := updatePiwigoIdIfAlreadyUploaded ( metadataProvider , piwigoCtx )
2019-03-19 23:08:28 +01:00
if err != nil {
2019-03-17 23:57:28 +01:00
return err
}
2019-03-20 23:15:41 +01:00
err = checkPiwigoForChangedImages ( metadataProvider , piwigoCtx )
2019-03-19 23:08:28 +01:00
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.
2019-03-20 21:41:41 +01:00
func checkPiwigoForChangedImages ( provider ImageMetadataProvider , piwigoCtx piwigo . PiwigoImageApi ) error {
2019-03-20 00:31:23 +01:00
logrus . Infof ( "Checking pending files if they really differ from the version in piwigo..." )
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
}
2019-03-20 00:31:23 +01:00
if len ( images ) == 0 {
logrus . Info ( "There are no existing images to check for modification on the server." )
return nil
}
2019-03-19 23:08:28 +01:00
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 {
2019-03-20 23:15:41 +01:00
logrus . Warnf ( "Error during file change check of file %s" , img . FullImagePath )
2019-03-19 23:08:28 +01:00
continue
}
if state == piwigo . ImageStateUptodate {
2019-03-20 23:15:41 +01:00
logrus . Debugf ( "File %s - %d has not changed" , img . FullImagePath , img . PiwigoId )
2019-03-19 23:08:28 +01:00
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 {
2019-03-20 23:15:41 +01:00
logrus . Warnf ( "Could not save image data of image %s" , img . FullImagePath )
2019-03-19 23:08:28 +01:00
}
}
}
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 21:41:41 +01:00
func updatePiwigoIdIfAlreadyUploaded ( provider ImageMetadataProvider , piwigoCtx piwigo . PiwigoImageApi ) 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
}
2019-03-20 00:31:23 +01:00
if len ( images ) == 0 {
logrus . Info ( "There are no existing images to check for modification on the server." )
return nil
}
2019-03-19 23:08:28 +01:00
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:31:23 +01:00
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
}