added first version of the app
This commit is contained in:
parent
e0eedbc2b1
commit
642a20c56f
BIN
SideCarJpegCleaner
Executable file
BIN
SideCarJpegCleaner
Executable file
Binary file not shown.
34
cmd/SideCarJpegCleaner/SideCarJpegCleaner.go
Normal file
34
cmd/SideCarJpegCleaner/SideCarJpegCleaner.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Philipp Haefelfinger (http://www.haefelfinger.ch/). All Rights Reserved.
|
||||||
|
* This application is licensed under GPLv2. See the LICENSE file in the root directory of the project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"git.haefelfinger.net/philipp.haefelfinger/SideCarJpegCleaner/internal/app"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/vharitonsky/iniflags"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
logLevel = flag.String("logLevel", "info", "The minimum log level required to write out a log message. (panic,fatal,error,warn,info,debug,trace)")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
iniflags.Parse()
|
||||||
|
initializeLog()
|
||||||
|
logrus.Infoln("Starting jpeg cleaner...")
|
||||||
|
app.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func initializeLog() {
|
||||||
|
level, err := logrus.ParseLevel(*logLevel)
|
||||||
|
if err != nil {
|
||||||
|
level = logrus.DebugLevel
|
||||||
|
}
|
||||||
|
logrus.SetLevel(level)
|
||||||
|
logrus.SetOutput(os.Stdout)
|
||||||
|
}
|
8
go.mod
Normal file
8
go.mod
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module git.haefelfinger.net/philipp.haefelfinger/SideCarJpegCleaner
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/sirupsen/logrus v1.4.2
|
||||||
|
github.com/vharitonsky/iniflags v0.0.0-20180513140207-a33cd0b5f3de
|
||||||
|
)
|
11
go.sum
Normal file
11
go.sum
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/vharitonsky/iniflags v0.0.0-20180513140207-a33cd0b5f3de h1:fkw+7JkxF3U1GzQoX9h69Wvtvxajo5Rbzy6+YMMzPIg=
|
||||||
|
github.com/vharitonsky/iniflags v0.0.0-20180513140207-a33cd0b5f3de/go.mod h1:irMhzlTz8+fVFj6CH2AN2i+WI5S6wWFtK3MBCIxIpyI=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
125
internal/app/app.go
Normal file
125
internal/app/app.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Philipp Haefelfinger (http://www.haefelfinger.ch/). All Rights Reserved.
|
||||||
|
* This application is licensed under GPLv2. See the LICENSE file in the root directory of the project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
imagesRootPath = flag.String("imagesRootPath", "", "This is the images root path that should be mirrored to piwigo.")
|
||||||
|
dryRun = flag.Bool("dryRun", true, "If set to true, all actions are run except the real filesystem modifications")
|
||||||
|
)
|
||||||
|
|
||||||
|
func Run() {
|
||||||
|
imagesRootFolder := *imagesRootPath
|
||||||
|
if imagesRootFolder == "" {
|
||||||
|
logErrorAndExit(errors.New("No images root folder set, exiting."), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
err, jpgFiles := findAllJpgFiles(imagesRootFolder)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("Could not clean up %s", imagesRootFolder)
|
||||||
|
logErrorAndExit(err, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
filesWithMissingSidecar := getJpesWithoutRawSideCar(jpgFiles)
|
||||||
|
logrus.Infof("Found %d of %d images to delete in %s", len(filesWithMissingSidecar), len(jpgFiles), imagesRootFolder)
|
||||||
|
|
||||||
|
if len(jpgFiles) == len(filesWithMissingSidecar) {
|
||||||
|
logrus.Warnf("Did not find any sidecar files in %s. Are you sure this is the right path to look for jpgs without raw sidecars? Cancelling executing!", imagesRootFolder)
|
||||||
|
logErrorAndExit(errors.New("Total files of jpegs and missing sidecars are the same, cancelling!"), 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(*dryRun) {
|
||||||
|
deleteFiles(filesWithMissingSidecar)
|
||||||
|
} else {
|
||||||
|
logrus.Warnln("Skipping delete of images as flag dryRun is set to true!")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteFiles(filesWithMissingSidecar []string) {
|
||||||
|
for _, fileToDelete := range filesWithMissingSidecar {
|
||||||
|
logrus.Infof("Deleting %s", fileToDelete)
|
||||||
|
err := os.Remove(fileToDelete)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("Could not delete %s because of %v", fileToDelete, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logErrorAndExit(err error, exitCode int) {
|
||||||
|
logrus.Errorln(err)
|
||||||
|
os.Exit(exitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getJpesWithoutRawSideCar(jpgFiles []string) []string {
|
||||||
|
var filesWithMissingSidecar []string
|
||||||
|
for _, jpgFile := range jpgFiles {
|
||||||
|
dir, fileName := filepath.Split(jpgFile)
|
||||||
|
|
||||||
|
newFileName := filenameWithoutExtension(fileName) + ".cr2"
|
||||||
|
newFilePath := filepath.Join(dir, newFileName)
|
||||||
|
|
||||||
|
if exists, err := fileExists(newFilePath); exists {
|
||||||
|
logrus.Debugf("Found exising sidecar, keeping jpeg %s", jpgFile)
|
||||||
|
|
||||||
|
} else if err == nil && !exists {
|
||||||
|
logrus.Infof("Found jpeg with missing raw file, schedule for delete %s", jpgFile)
|
||||||
|
filesWithMissingSidecar = append(filesWithMissingSidecar, jpgFile)
|
||||||
|
} else {
|
||||||
|
logrus.Errorf("There was an error on checking %s: %v", jpgFile, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filesWithMissingSidecar
|
||||||
|
}
|
||||||
|
|
||||||
|
func findAllJpgFiles(basePath string) (error, []string) {
|
||||||
|
var files []string
|
||||||
|
|
||||||
|
err := filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if strings.HasPrefix(info.Name(), ".") {
|
||||||
|
logrus.Debugf("Skipping hidden file or directory %s", path)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
extension := strings.ToLower(filepath.Ext(path))
|
||||||
|
if (extension != ".jpg" && extension != ".jpeg") || info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("Found file %s", path)
|
||||||
|
files = append(files, path)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err, files
|
||||||
|
}
|
||||||
|
|
||||||
|
func filenameWithoutExtension(fn string) string {
|
||||||
|
return strings.TrimSuffix(fn, path.Ext(fn))
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileExists(filePath string) (bool, error) {
|
||||||
|
_, err := os.Stat(filePath)
|
||||||
|
if err == nil {
|
||||||
|
logrus.Debugf("file %s exists", filePath)
|
||||||
|
return true, nil
|
||||||
|
} else if os.IsNotExist(err) {
|
||||||
|
logrus.Debugf("file %s does not exist", filePath)
|
||||||
|
return false, nil
|
||||||
|
} else {
|
||||||
|
logrus.Debugf("file %s stat error: %v", filePath, err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user