/* * 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 cleaned.") 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 := getJpegsWithoutRawSideCar(jpgFiles) logrus.Infof("Found %d of %d images to delete in %s", len(filesWithMissingSidecar), len(jpgFiles), imagesRootFolder) //todo: this check needs to be performed by each directory and if true, skip the directory but not all 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) { logrus.Infof("Starting to delete %d files...", len(filesWithMissingSidecar)) 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 getJpegsWithoutRawSideCar(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 } }