-
Notifications
You must be signed in to change notification settings - Fork 0
/
import.go
139 lines (121 loc) · 3.19 KB
/
import.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"fmt"
"io"
"log"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time"
)
type fileInformation struct {
name string
path string
}
func whitelistedExtension(path string) bool {
whitelist := []string{".jpeg", ".jpg", ".cr3", ".png"}
extension := strings.ToLower(filepath.Ext(path))
for _, ext := range whitelist {
if ext == extension {
return true
}
}
return false
}
func main() {
var files []fileInformation
var totalBytes int64
if len(os.Args) < 3 {
fmt.Println("Missing arguments")
fmt.Println("Usage: import <srcPath> <dstPath>")
return
}
srcPath := os.Args[1]
err := filepath.Walk(srcPath, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
fi := fileInformation{name: info.Name(), path: path}
if whitelistedExtension(path) {
files = append(files, fi)
log.Printf("scanning: " + path)
totalBytes += info.Size()
}
}
return nil
})
if err != nil {
log.Fatal(err)
}
var totalInGB = float32(totalBytes) / 1000000000
var transferredBytes int64
var timeSpent float32
var totalTime float32
var transferSpeed float32
var existingFile int64
then := time.Now().UnixNano()
for i, file := range files {
fileInfo, err := os.Stat(file.path)
if err != nil {
log.Fatal(err)
}
clear()
photoDate := fileInfo.ModTime()
dstPath := os.Args[2]
if dstPath[len(dstPath)-1:] != "/" {
dstPath = dstPath + "/"
}
dstPath = dstPath + strconv.Itoa(photoDate.Year()) + "/" + strconv.Itoa(int(photoDate.Month())) + " - " + photoDate.Month().String() + "/"
timeLeft := (float32(totalBytes-transferredBytes) / 1000000) / transferSpeed
timeElapsed := (time.Now().UnixNano() - then) / 1000000000
fmt.Printf("Copying %d of %d\n", i+1, len(files))
fmt.Printf("%.3f GB / %.3f GB @ %.3f MB/s\n", float32(transferredBytes)/1000000000, totalInGB, transferSpeed)
fmt.Printf("Time Elapsed: %02d : %02d : %02d; Time Left: %02d : %02d : %02d\n", timeElapsed/3600, timeElapsed/60%60, timeElapsed%60, int64(timeLeft)/3600, int64(timeLeft)/60%60, int64(timeLeft)%60)
fmt.Println(dstPath + file.name)
transferredBytes += fileInfo.Size()
os.MkdirAll(dstPath, 0700)
timeSpent = copyFile(file.path, dstPath+file.name)
if timeSpent == -1 {
existingFile += fileInfo.Size()
}
if timeSpent != -1 {
totalTime += timeSpent
transferSpeed = (float32(transferredBytes-existingFile) / 1000000) / totalTime
}
}
}
func clear() {
cmd := exec.Command("cmd", "/c", "cls")
cmd.Stdout = os.Stdout
cmd.Run()
}
func copyFile(src string, dst string) float32 {
_, err := os.Stat(dst)
if err == nil {
log.Printf("File already exists.")
return -1
}
sourceFile, err := os.Open(src)
if err != nil {
log.Fatal(err)
}
defer sourceFile.Close()
destinationFile, err := os.Create(dst)
if err != nil {
log.Fatal(err)
}
defer destinationFile.Close()
then := time.Now().UnixNano()
bytesWritten, err := io.Copy(destinationFile, sourceFile)
if err != nil {
log.Fatal(err)
}
now := time.Now().UnixNano()
var timeSpent float32 = (float32(now - then)) / 1000000000
log.Printf("Copied %d bytes in %.3f seconds", bytesWritten, timeSpent)
err = destinationFile.Sync()
if err != nil {
log.Fatal(err)
}
return timeSpent
}