Skip to content

Commit

Permalink
progress bar - rename files if exist
Browse files Browse the repository at this point in the history
  • Loading branch information
mgerb committed Feb 7, 2019
1 parent 47fcfa2 commit 1dcc5e8
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 34 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/vendor
/ignore
/dist
17 changes: 16 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 45 additions & 23 deletions file-util.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,47 @@ package main
import (
"io"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"strconv"
"strings"
)

func fileExists(path string) bool {
if _, err := os.Stat(path); os.IsNotExist(err) {
return false
}
return true
}

func getFileSuffix(n int) string {
return "_" + strconv.Itoa(n)
}

// if file already exists
// append _1 to the end.
// Keep incrementing until file
// does not exist.
func renameIfFileExists(path string) string {
fileSuffix := 1
for fileExists(path) {
extension := filepath.Ext(path)
pathPrefix := path[0 : len(path)-len(extension)]

previousFileSuffix := getFileSuffix(fileSuffix - 1)
if strings.HasSuffix(pathPrefix, previousFileSuffix) {
pathPrefix = pathPrefix[0 : len(pathPrefix)-len(previousFileSuffix)]
}

path = pathPrefix + getFileSuffix(fileSuffix) + extension
fileSuffix++
}

return path
}

func createDirIfNotExists(dir string) {
if _, err := os.Stat(dir); os.IsNotExist(err) {
os.MkdirAll(dir, 0755)
Expand Down Expand Up @@ -45,41 +82,26 @@ func copyFile(src, dest string) error {
return nil
}

// recursively read files in directory
func readFiles(dir string, processMetaData bool) []*MediaFile {
// recursively read directory and get all file paths
func getAllFilePaths(dir string) []string {

mediaFiles := []*MediaFile{}
filePaths := []string{}
files, err := ioutil.ReadDir(dir)

if err != nil {
return mediaFiles
log.Println(err)
return filePaths
}

for _, f := range files {

if f.IsDir() {
mediaFiles = append(mediaFiles, readFiles(path.Join(dir, f.Name()), processMetaData)...)
filePaths = append(filePaths, getAllFilePaths(path.Join(dir, f.Name()))...)
} else {

mediaFile := NewMediaFile(path.Join(dir, f.Name()), processMetaData)

if mediaFile != nil {
mediaFiles = append(mediaFiles, mediaFile)
}
filePaths = append(filePaths, path.Join(dir, f.Name()))
}
}

return mediaFiles
}

func scanMediaDirectory(path string, processMetaData bool) map[[20]byte]*MediaFile {
mediaFiles := readFiles(path, processMetaData)

outputMap := map[[20]byte]*MediaFile{}

for _, m := range mediaFiles {
outputMap[m.sha1] = m
}

return outputMap
return filePaths
}
68 changes: 59 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,30 @@ package main
import (
"errors"
"flag"
"fmt"
"os"
)

var (
inputPath string
outputPath string
copyDuplicates bool
version = "undefined"
)

func init() {

if version != "undefined" {
println("mgphoto ", version, "\n")
}

outputPtr := flag.String("o", "./output", "Output path - defaults to ./output")
dupPtr := flag.Bool("d", false, "Copy duplicates to 'duplicates' folder")

flag.Parse()

if len(flag.Args()) < 1 {
exit(errors.New("Invalid arguments - please supply a source directory"))
println(errors.New("Invalid arguments - please supply a source directory"))
os.Exit(0)
}

outputPath = *outputPtr
Expand All @@ -33,15 +38,60 @@ func main() {

createDirIfNotExists(outputPath)

sourceFiles := scanMediaDirectory(inputPath, true)
destFiles := scanMediaDirectory(outputPath, false)
sourceFiles := getAllFilePaths(inputPath)
destFiles := getAllFilePaths(outputPath)

println("Processing source files...")
sourceMediaFiles := getMediaFiles(sourceFiles, true)

for k, val := range sourceFiles {
val.writeToDestination(outputPath, copyDuplicates && destFiles[k] != nil)
println("Scanning destination for duplicates...")
destMediaFiles := getMediaFiles(destFiles, false)

// if we are not copying duplicates omit them
if !copyDuplicates {
for k := range sourceMediaFiles {
if destMediaFiles[k] != nil {
delete(sourceMediaFiles, k)
}
}
}

if len(sourceMediaFiles) == 0 {
println("No new files to copy.")
return
}

println("Copying new files to destination...")
progressBar := NewProgressBar(len(sourceMediaFiles))
for k, val := range sourceMediaFiles {
val.writeToDestination(outputPath, copyDuplicates && destMediaFiles[k] != nil)
progressBar.increment()
}

progressBar.wait()
}

func exit(err error) {
fmt.Println(err)
os.Exit(0)
// get media file objects from file path list
func getMediaFiles(paths []string, processMetaData bool) map[[20]byte]*MediaFile {

outputMap := map[[20]byte]*MediaFile{}

if len(paths) < 1 {
return outputMap
}

progressBar := NewProgressBar(len(paths))

for _, path := range paths {
mediaFile := NewMediaFile(path, processMetaData)

if mediaFile != nil {
outputMap[mediaFile.sha1] = mediaFile
}
progressBar.increment()
}

progressBar.wait()

return outputMap
}
15 changes: 15 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
VERSION := $(shell git describe --tags)

linux:
GOOS=darwin GOARCH=386 go build -o ./dist/mgphoto-linux -ldflags="-X main.version=${VERSION}" ./*.go

mac:
GOOS=darwin GOARCH=amd64 go build -o ./dist/mgphoto-mac -ldflags="-X main.version=${VERSION}" ./*.go

windows:
GOOS=windows GOARCH=386 go build -o ./dist/mgphoto-windows.exe -ldflags="-X main.version=${VERSION}" ./*.go

clean:
rm -rf ./dist

all: linux mac windows
4 changes: 3 additions & 1 deletion media-file.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ func (m *MediaFile) writeToDestination(dest string, copyDuplicates bool) error {

createDirIfNotExists(dir)

err := copyFile(m.path, path.Join(dir, m.name))
fullPath := renameIfFileExists(path.Join(dir, m.name))

err := copyFile(m.path, fullPath)

if err != nil {
log.Println(err)
Expand Down
41 changes: 41 additions & 0 deletions progress-bar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"time"

"github.com/vbauerster/mpb"
"github.com/vbauerster/mpb/decor"
)

type ProgressBar struct {
progress *mpb.Progress
bar *mpb.Bar
start time.Time
}

// NewProgressBar - get new progress bar
func NewProgressBar(total int) *ProgressBar {

progressBar := new(ProgressBar)

progressBar.progress = mpb.New(mpb.WithWidth(64), mpb.WithRefreshRate(180*time.Millisecond))

progressBar.bar = progressBar.progress.AddBar(int64(total),
mpb.PrependDecorators(
decor.CountersNoUnit("%d / %d", decor.WCSyncWidth),
),
mpb.AppendDecorators(decor.Elapsed(decor.ET_STYLE_MMSS)),
)

progressBar.start = time.Now()

return progressBar
}

func (p *ProgressBar) increment() {
p.bar.IncrBy(1, time.Since(p.start))
}

func (p *ProgressBar) wait() {
p.progress.Wait()
}

0 comments on commit 1dcc5e8

Please sign in to comment.