-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzip-compactor.go
151 lines (123 loc) · 3.35 KB
/
zip-compactor.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
140
141
142
143
144
145
146
147
148
149
150
151
package main
import (
"archive/zip"
"flag"
"io"
"os"
"os/exec"
"runtime"
"strings"
"github.com/ncruces/zenity"
)
var fromFlag *string
var toFlag *string
var quietFlag *bool
var selected []string
var target string
var Version string // Dinamic, generated in build time.
func init() {
// Flags
fromFlag = flag.String("from", "", "path of the file to be ziped")
toFlag = flag.String("to", "", "path to create the ziped file")
quietFlag = flag.Bool("q", false, "quit, to not open the explorer after finished")
vFlag := flag.Bool("v", false, "get version of software")
versionFlag := flag.Bool("version", false, "get version of software")
flag.Parse()
if (*vFlag) || (*versionFlag) {
println(Version)
os.Exit(0)
}
}
func main() {
hasFF := len(*fromFlag) != 0
hasTF := len(*toFlag) != 0
if hasFF || hasTF {
// Use CLI
cliUsage(hasFF, hasTF)
} else {
// Use GUI
guiUsage()
}
// Validate the given paths
validateInputs()
ZipItems(target, selected)
openExplorer()
}
// Handle with CLI usage to deal with user inputs and determinate what is the target and the selecteds paths.
func cliUsage(hasFF, hasTF bool) {
// If just one of two flags is given
if hasFF && !hasTF || !hasFF && hasTF {
println("The 'from' and 'to' flags are required!")
os.Exit(1)
}
selected = []string{*fromFlag}
target = *toFlag
}
// Handle with GUI usage to deal with user inputs and determinate what is the target and the selecteds paths.
func guiUsage() {
selected, _ = zenity.SelectFileMutiple(zenity.Title("Selecione um item para compactar"))
target, _ = zenity.SelectFileSave(
zenity.Title("Selecione o destino"),
zenity.FileFilter{Patterns: []string{"*.zip", "*.ZIP"}},
zenity.ConfirmOverwrite(),
)
}
// Handle with target input. If the target not have the suffix ".zip" it'll applied.
func validateInputs() {
if len(selected) == 0 || len(target) == 0 {
println("The file to be zipped and path to result are required!")
os.Exit(1)
}
if !strings.HasSuffix(strings.ToLower(target), ".zip") {
target += ".zip"
}
}
// Handle with the files to be zipped.
func ZipItems(filename string, items []string) {
newZipFile, err := os.Create(filename)
he(err)
defer newZipFile.Close()
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
for _, item := range items {
if err := AddItemToZip(zipWriter, item); err != nil {
he(err)
}
}
}
// Handle with the action of zip a file.
func AddItemToZip(zipWriter *zip.Writer, filename string) error {
itemToZip, err := os.Open(filename)
he(err)
defer itemToZip.Close()
info, err := itemToZip.Stat()
he(err)
header, err := zip.FileInfoHeader(info)
he(err)
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
he(err)
_, err = io.Copy(writer, itemToZip)
return err
}
// Handle with the action of open the explorer (windows).
func openExplorer() {
if *quietFlag {
return
}
if runtime.GOOS == "windows" {
splitedTargetPath := strings.Split(target, string(os.PathSeparator))
parentOfTarget := strings.Join(splitedTargetPath[0:len(splitedTargetPath)-1], string(os.PathSeparator))
err := exec.Command("explorer", parentOfTarget).Run()
if err != nil {
zenity.CancelLabel("error: " + err.Error())
os.Exit(0)
}
}
}
// he Handle with errors to evit the repetion of handling with the same code
func he(err error, msg ...interface{}) {
if err != nil {
panic(err.Error())
}
}