mirror of https://github.com/schollz/croc.git
remove wina nd zipper
This commit is contained in:
parent
7a8801f8f1
commit
1661bbb221
|
@ -1,24 +0,0 @@
|
|||
VERSION=$(shell git describe --tags --abbrev=0)
|
||||
LDFLAGS=-ldflags "-X main.Version=${VERSION}"
|
||||
|
||||
.PHONY: linux
|
||||
linux:
|
||||
GO111MODULE=off qtdeploy ${LDFLAGS} --tags='wincroc' --debug build desktop
|
||||
|
||||
.PHONY: fast
|
||||
fast:
|
||||
GO111MODULE=off qtdeploy ${LDFLAGS} --fast --tags='wincroc' --debug build desktop
|
||||
|
||||
windows:
|
||||
GO111MODULE=off qtdeploy ${LDFLAGS} --tags='wincroc' --debug --docker build windows_64_static
|
||||
|
||||
release: linux windows
|
||||
mv deploy/linux/win croc
|
||||
tar -czvf croc_${VERSION}_Linux-64bit_GUI.tar.gz croc
|
||||
mv deploy/windows/win.exe croc.exe
|
||||
zip croc_${VERSION}_Windows-64bit_GUI.zip croc.exe
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
mv *zip dist/
|
||||
mv *tar.gz dist/
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
REM getting the output of an executed command in a batch file is not trivial, we use a temp file for it
|
||||
git describe --tags --abbrev=0 > temp.txt
|
||||
set /P VERSION=< temp.txt
|
||||
echo %VERSION%
|
||||
del temp.txt
|
||||
|
||||
REM build a 32 bit Windows application, this way it will run on both 32 but and 64 bit Windows machines
|
||||
set GOARCH=386
|
||||
|
||||
REM -s and -w strip the program of debugging information, making it smaller
|
||||
REM -H=windowsgui makes the program not have a console window on start-up
|
||||
go build -ldflags="-s -w -H=windowsgui -X main.Version=%VERSION%" -o croc.exe
|
||||
|
||||
if errorlevel 1 pause
|
3028
src/win/icon.go
3028
src/win/icon.go
File diff suppressed because it is too large
Load Diff
BIN
src/win/icon.ico
BIN
src/win/icon.ico
Binary file not shown.
Before Width: | Height: | Size: 35 KiB |
|
@ -1 +0,0 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "icon.ico"
|
Binary file not shown.
Binary file not shown.
230
src/win/main.go
230
src/win/main.go
|
@ -1,230 +0,0 @@
|
|||
// +build wincroc
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
"github.com/schollz/croc/src/cli"
|
||||
"github.com/schollz/croc/src/croc"
|
||||
"github.com/schollz/croc/src/utils"
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
"github.com/therecipe/qt/core"
|
||||
"github.com/therecipe/qt/widgets"
|
||||
)
|
||||
|
||||
type CustomLabel struct {
|
||||
widgets.QLabel
|
||||
|
||||
_ func(string) `signal:"updateTextFromGoroutine,auto(this.QLabel.setText)"` //TODO: support this.setText as well
|
||||
}
|
||||
|
||||
var Version string
|
||||
|
||||
func main() {
|
||||
if len(os.Args) > 1 {
|
||||
cli.Run()
|
||||
return
|
||||
}
|
||||
|
||||
var isWorking bool
|
||||
app := widgets.NewQApplication(len(os.Args), os.Args)
|
||||
|
||||
window := widgets.NewQMainWindow(nil, 0)
|
||||
if runtime.GOOS == "windows" {
|
||||
window.SetFixedSize2(300, 150)
|
||||
window.SetWindowTitle("croc " + Version)
|
||||
} else {
|
||||
window.SetFixedSize2(400, 150)
|
||||
window.SetWindowTitle("🐊📦 croc " + Version)
|
||||
}
|
||||
|
||||
widget := widgets.NewQWidget(nil, 0)
|
||||
widget.SetLayout(widgets.NewQVBoxLayout())
|
||||
window.SetCentralWidget(widget)
|
||||
|
||||
labels := make([]*CustomLabel, 3)
|
||||
for i := range labels {
|
||||
label := NewCustomLabel(nil, 0)
|
||||
label.SetAlignment(core.Qt__AlignCenter)
|
||||
widget.Layout().AddWidget(label)
|
||||
labels[i] = label
|
||||
}
|
||||
labels[0].SetText("secure data transfer")
|
||||
labels[1].SetText("Click 'Send' or 'Receive' to start")
|
||||
|
||||
button := widgets.NewQPushButton2("Send", nil)
|
||||
button.ConnectClicked(func(bool) {
|
||||
if isWorking {
|
||||
dialog("Can only do one send or receive at a time")
|
||||
return
|
||||
}
|
||||
isWorking = true
|
||||
|
||||
var fileDialog = widgets.NewQFileDialog2(window, "Open file to send...", "", "")
|
||||
fileDialog.SetAcceptMode(widgets.QFileDialog__AcceptOpen)
|
||||
fileDialog.SetFileMode(widgets.QFileDialog__AnyFile)
|
||||
if fileDialog.Exec() != int(widgets.QDialog__Accepted) {
|
||||
isWorking = false
|
||||
return
|
||||
}
|
||||
var fn = fileDialog.SelectedFiles()[0]
|
||||
if len(fn) == 0 {
|
||||
dialog(fmt.Sprintf("No file selected"))
|
||||
isWorking = false
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
cr := croc.Init(false)
|
||||
done := make(chan bool)
|
||||
codePhrase := utils.GetRandomName()
|
||||
_, fname := filepath.Split(fn)
|
||||
labels[0].UpdateTextFromGoroutine(fmt.Sprintf("Sending '%s'", fname))
|
||||
labels[1].UpdateTextFromGoroutine(fmt.Sprintf("Code phrase: %s", codePhrase))
|
||||
|
||||
go func(done chan bool) {
|
||||
for {
|
||||
if cr.OtherIP != "" && cr.FileInfo.SentName != "" {
|
||||
bytesString := humanize.Bytes(uint64(cr.FileInfo.Size))
|
||||
fileOrFolder := "file"
|
||||
if cr.FileInfo.IsDir {
|
||||
fileOrFolder = "folder"
|
||||
}
|
||||
labels[0].UpdateTextFromGoroutine(fmt.Sprintf("Sending %s %s '%s' to %s", bytesString, fileOrFolder, cr.FileInfo.SentName, cr.OtherIP))
|
||||
}
|
||||
if cr.Bar != nil {
|
||||
barState := cr.Bar.State()
|
||||
labels[1].UpdateTextFromGoroutine(fmt.Sprintf("%2.1f%% [%2.0fs:%2.0fs]", barState.CurrentPercent*100, barState.SecondsSince, barState.SecondsLeft))
|
||||
}
|
||||
labels[2].UpdateTextFromGoroutine(cr.StateString)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
select {
|
||||
case _ = <-done:
|
||||
labels[2].UpdateTextFromGoroutine(cr.StateString)
|
||||
return
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}(done)
|
||||
|
||||
cr.Send(fn, codePhrase)
|
||||
done <- true
|
||||
isWorking = false
|
||||
}()
|
||||
})
|
||||
widget.Layout().AddWidget(button)
|
||||
|
||||
receiveButton := widgets.NewQPushButton2("Receive", nil)
|
||||
receiveButton.ConnectClicked(func(bool) {
|
||||
if isWorking {
|
||||
dialog("Can only do one send or receive at a time")
|
||||
return
|
||||
}
|
||||
labels[1].SetText("")
|
||||
labels[2].SetText("please wait...")
|
||||
isWorking = true
|
||||
defer func() {
|
||||
isWorking = false
|
||||
}()
|
||||
|
||||
// determine the folder to save the file
|
||||
var folderDialog = widgets.NewQFileDialog2(window, "Open folder to receive file...", "", "")
|
||||
folderDialog.SetAcceptMode(widgets.QFileDialog__AcceptOpen)
|
||||
folderDialog.SetFileMode(widgets.QFileDialog__DirectoryOnly)
|
||||
if folderDialog.Exec() != int(widgets.QDialog__Accepted) {
|
||||
return
|
||||
}
|
||||
var fn = folderDialog.SelectedFiles()[0]
|
||||
if len(fn) == 0 {
|
||||
labels[2].SetText(fmt.Sprintf("No folder selected"))
|
||||
return
|
||||
}
|
||||
|
||||
var codePhrase = widgets.QInputDialog_GetText(window, "croc", "Enter code phrase:",
|
||||
widgets.QLineEdit__Normal, "", true, core.Qt__Dialog, core.Qt__ImhNone)
|
||||
if len(codePhrase) < 3 {
|
||||
labels[2].SetText(fmt.Sprintf("Invalid codephrase: '%s'", codePhrase))
|
||||
return
|
||||
}
|
||||
|
||||
cr := croc.Init(false)
|
||||
cr.WindowRecipientPrompt = true
|
||||
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
// change into the receiving directory
|
||||
cwd, _ := os.Getwd()
|
||||
defer os.Chdir(cwd)
|
||||
os.Chdir(fn)
|
||||
err := cr.Receive(codePhrase)
|
||||
if err == nil {
|
||||
open.Run(fn)
|
||||
}
|
||||
done <- true
|
||||
done <- true
|
||||
isWorking = false
|
||||
}()
|
||||
go func() {
|
||||
for {
|
||||
if cr.Bar != nil {
|
||||
barState := cr.Bar.State()
|
||||
labels[1].UpdateTextFromGoroutine(fmt.Sprintf("%2.1f%% [%2.0fs:%2.0fs]", barState.CurrentPercent*100, barState.SecondsSince, barState.SecondsLeft))
|
||||
}
|
||||
if cr.StateString != "" {
|
||||
labels[2].UpdateTextFromGoroutine(cr.StateString)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
select {
|
||||
case _ = <-done:
|
||||
labels[2].UpdateTextFromGoroutine(cr.StateString)
|
||||
return
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
if cr.WindowReceivingString != "" {
|
||||
var question = widgets.QMessageBox_Question(window, "croc", fmt.Sprintf("%s?", cr.WindowReceivingString), widgets.QMessageBox__Yes|widgets.QMessageBox__No, 0)
|
||||
if question == widgets.QMessageBox__Yes {
|
||||
cr.WindowRecipientAccept = true
|
||||
labels[0].SetText(cr.WindowReceivingString)
|
||||
} else {
|
||||
cr.WindowRecipientAccept = false
|
||||
labels[2].SetText("canceled")
|
||||
}
|
||||
cr.WindowRecipientPrompt = false
|
||||
cr.WindowReceivingString = ""
|
||||
break
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
select {
|
||||
case _ = <-done:
|
||||
labels[2].SetText(cr.StateString)
|
||||
return
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
widget.Layout().AddWidget(receiveButton)
|
||||
|
||||
window.Show()
|
||||
app.Exec()
|
||||
}
|
||||
|
||||
func dialog(s string) {
|
||||
var info = widgets.NewQMessageBox(nil)
|
||||
info.SetWindowTitle("Info")
|
||||
info.SetText(s)
|
||||
info.Exec()
|
||||
}
|
|
@ -1,250 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
"github.com/gonutz/w32"
|
||||
"github.com/gonutz/wui"
|
||||
"github.com/schollz/croc/src/cli"
|
||||
"github.com/schollz/croc/src/croc"
|
||||
"github.com/schollz/croc/src/utils"
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
)
|
||||
|
||||
var Version string
|
||||
|
||||
func main() {
|
||||
if len(os.Args) > 1 {
|
||||
cli.Run()
|
||||
return
|
||||
}
|
||||
|
||||
var isWorking bool
|
||||
|
||||
font, _ := wui.NewFont(wui.FontDesc{
|
||||
Name: "Tahoma",
|
||||
Height: -11,
|
||||
})
|
||||
|
||||
window := wui.NewWindow()
|
||||
window.SetFont(font)
|
||||
window.SetIconFromMem(icon)
|
||||
window.SetStyle(w32.WS_OVERLAPPED | w32.WS_CAPTION | w32.WS_SYSMENU | w32.WS_MINIMIZEBOX)
|
||||
if runtime.GOOS == "windows" {
|
||||
window.SetClientSize(300, 150)
|
||||
window.SetTitle("croc " + Version)
|
||||
} else {
|
||||
window.SetClientSize(400, 150)
|
||||
window.SetTitle("🐊📦 croc " + Version)
|
||||
}
|
||||
|
||||
labels := make([]*wui.Label, 3)
|
||||
for i := range labels {
|
||||
label := wui.NewLabel()
|
||||
label.SetCenterAlign()
|
||||
label.SetBounds(0, 10+i*20, window.ClientWidth(), 20)
|
||||
window.Add(label)
|
||||
labels[i] = label
|
||||
}
|
||||
labels[0].SetText("secure data transfer")
|
||||
labels[1].SetText("Click 'Send' or 'Receive' to start")
|
||||
|
||||
button := wui.NewButton()
|
||||
button.SetText("Send")
|
||||
window.Add(button)
|
||||
button.SetBounds(10, window.ClientHeight()-70, window.ClientWidth()-20, 25)
|
||||
button.SetOnClick(func() {
|
||||
if isWorking {
|
||||
wui.MessageBoxError(window, "Error", "Can only do one send or receive at a time")
|
||||
return
|
||||
}
|
||||
isWorking = true
|
||||
|
||||
fileDialog := wui.NewFileOpenDialog()
|
||||
fileDialog.SetTitle("Open file to send...")
|
||||
accepted, fn := fileDialog.ExecuteSingleSelection(window)
|
||||
if !accepted {
|
||||
isWorking = false
|
||||
return
|
||||
}
|
||||
if fn == "" {
|
||||
wui.MessageBoxError(window, "Error", "No file selected")
|
||||
isWorking = false
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
cr := croc.Init(false)
|
||||
done := make(chan bool)
|
||||
codePhrase := utils.GetRandomName()
|
||||
_, fname := filepath.Split(fn)
|
||||
labels[0].SetText(fmt.Sprintf("Sending '%s'", fname))
|
||||
labels[1].SetText(fmt.Sprintf("Code phrase: %s", codePhrase))
|
||||
|
||||
go func(done chan bool) {
|
||||
for {
|
||||
if cr.OtherIP != "" && cr.FileInfo.SentName != "" {
|
||||
bytesString := humanize.Bytes(uint64(cr.FileInfo.Size))
|
||||
fileOrFolder := "file"
|
||||
if cr.FileInfo.IsDir {
|
||||
fileOrFolder = "folder"
|
||||
}
|
||||
labels[0].SetText(fmt.Sprintf("Sending %s %s '%s' to %s", bytesString, fileOrFolder, cr.FileInfo.SentName, cr.OtherIP))
|
||||
}
|
||||
if cr.Bar != nil {
|
||||
barState := cr.Bar.State()
|
||||
labels[1].SetText(fmt.Sprintf("%2.1f%% [%2.0fs:%2.0fs]", barState.CurrentPercent*100, barState.SecondsSince, barState.SecondsLeft))
|
||||
}
|
||||
labels[2].SetText(cr.StateString)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
select {
|
||||
case _ = <-done:
|
||||
labels[2].SetText(cr.StateString)
|
||||
return
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}(done)
|
||||
|
||||
cr.Send(fn, codePhrase)
|
||||
done <- true
|
||||
isWorking = false
|
||||
}()
|
||||
})
|
||||
|
||||
receiveButton := wui.NewButton()
|
||||
receiveButton.SetText("Receive")
|
||||
window.Add(receiveButton)
|
||||
receiveButton.SetBounds(10, window.ClientHeight()-35, window.ClientWidth()-20, 25)
|
||||
receiveButton.SetOnClick(func() {
|
||||
if isWorking {
|
||||
wui.MessageBoxError(window, "Error", "Can only do one send or receive at a time")
|
||||
return
|
||||
}
|
||||
labels[1].SetText("")
|
||||
labels[2].SetText("please wait...")
|
||||
isWorking = true
|
||||
defer func() {
|
||||
isWorking = false
|
||||
}()
|
||||
|
||||
// determine the folder to save the file
|
||||
folderDialog := wui.NewFolderSelectDialog()
|
||||
folderDialog.SetTitle("Open folder to receive file...")
|
||||
accepted, fn := folderDialog.Execute(window)
|
||||
if !accepted {
|
||||
return
|
||||
}
|
||||
if len(fn) == 0 {
|
||||
labels[2].SetText(fmt.Sprintf("No folder selected"))
|
||||
return
|
||||
}
|
||||
|
||||
passDlg := wui.NewDialogWindow()
|
||||
passDlg.SetTitle("Enter code phrase")
|
||||
passDlg.SetClientSize(window.ClientWidth()-20, 40)
|
||||
pass := wui.NewEditLine()
|
||||
passDlg.Add(pass)
|
||||
pass.SetPassword(true)
|
||||
pass.SetBounds(10, 10, passDlg.ClientWidth()-20, 20)
|
||||
var passAccepted bool
|
||||
passDlg.SetShortcut(wui.ShortcutKeys{Key: w32.VK_RETURN}, func() {
|
||||
passAccepted = true
|
||||
passDlg.Close()
|
||||
})
|
||||
passDlg.SetShortcut(wui.ShortcutKeys{Key: w32.VK_ESCAPE}, func() {
|
||||
passDlg.Close()
|
||||
})
|
||||
var codePhrase string
|
||||
passDlg.SetOnShow(func() {
|
||||
passDlg.SetX(window.X() + (window.Width()-passDlg.Width())/2)
|
||||
passDlg.SetY(window.Y() + (window.Height()-passDlg.Height())/2)
|
||||
pass.Focus()
|
||||
})
|
||||
passDlg.SetOnClose(func() {
|
||||
if passAccepted {
|
||||
codePhrase = pass.Text()
|
||||
}
|
||||
})
|
||||
passDlg.ShowModal(window)
|
||||
passDlg.Destroy()
|
||||
if len(codePhrase) < 3 {
|
||||
labels[2].SetText(fmt.Sprintf("Invalid codephrase: '%s'", codePhrase))
|
||||
return
|
||||
}
|
||||
|
||||
cr := croc.Init(false)
|
||||
cr.WindowRecipientPrompt = true
|
||||
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
// change into the receiving directory
|
||||
cwd, _ := os.Getwd()
|
||||
defer os.Chdir(cwd)
|
||||
os.Chdir(fn)
|
||||
err := cr.Receive(codePhrase)
|
||||
if err == nil {
|
||||
open.Run(fn)
|
||||
}
|
||||
done <- true
|
||||
done <- true
|
||||
isWorking = false
|
||||
}()
|
||||
go func() {
|
||||
for {
|
||||
if cr.Bar != nil {
|
||||
barState := cr.Bar.State()
|
||||
labels[1].SetText(fmt.Sprintf("%2.1f%% [%2.0fs:%2.0fs]", barState.CurrentPercent*100, barState.SecondsSince, barState.SecondsLeft))
|
||||
}
|
||||
if cr.StateString != "" {
|
||||
labels[2].SetText(cr.StateString)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
select {
|
||||
case _ = <-done:
|
||||
labels[2].SetText(cr.StateString)
|
||||
return
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
if cr.WindowReceivingString != "" {
|
||||
question := wui.MessageBoxYesNo(
|
||||
window,
|
||||
"croc",
|
||||
fmt.Sprintf("%s?", cr.WindowReceivingString),
|
||||
)
|
||||
if question {
|
||||
cr.WindowRecipientAccept = true
|
||||
labels[0].SetText(cr.WindowReceivingString)
|
||||
} else {
|
||||
cr.WindowRecipientAccept = false
|
||||
labels[2].SetText("canceled")
|
||||
}
|
||||
cr.WindowRecipientPrompt = false
|
||||
cr.WindowReceivingString = ""
|
||||
break
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
select {
|
||||
case _ = <-done:
|
||||
labels[2].SetText(cr.StateString)
|
||||
return
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
window.Show()
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
package zipper
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"compress/flate"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
log "github.com/cihub/seelog"
|
||||
"github.com/schollz/croc/src/logger"
|
||||
)
|
||||
|
||||
var DebugLevel string
|
||||
|
||||
func init() {
|
||||
DebugLevel = "info"
|
||||
}
|
||||
|
||||
// UnzipFile will unzip the src directory into the dest
|
||||
func UnzipFile(src, dest string) (err error) {
|
||||
logger.SetLogLevel(DebugLevel)
|
||||
|
||||
r, err := zip.OpenReader(src)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
for _, f := range r.File {
|
||||
var rc io.ReadCloser
|
||||
rc, err = f.Open()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
// Store filename/path for returning and using later on
|
||||
fpath := filepath.Join(dest, f.Name)
|
||||
log.Debugf("unzipping %s", fpath)
|
||||
fpath = filepath.FromSlash(fpath)
|
||||
|
||||
if f.FileInfo().IsDir() {
|
||||
|
||||
// Make Folder
|
||||
os.MkdirAll(fpath, os.ModePerm)
|
||||
|
||||
} else {
|
||||
|
||||
// Make File
|
||||
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var outFile *os.File
|
||||
outFile, err = os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = io.Copy(outFile, rc)
|
||||
|
||||
// Close the file without defer to close before next iteration of loop
|
||||
outFile.Close()
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
log.Debugf("unzipped %s to %s", src, dest)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ZipFiles will zip all the files and the folders as if they were in the same directory
|
||||
func ZipFiles(fnames []string, compress bool) (writtenFilename string, err error) {
|
||||
logger.SetLogLevel(DebugLevel)
|
||||
if len(fnames) == 0 {
|
||||
err = fmt.Errorf("must provide files to zip")
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("zipping %s with compression? %v", fnames, compress)
|
||||
writtenFilename = fmt.Sprintf("%d_files.croc.zip", len(fnames))
|
||||
err = makeZip(writtenFilename, fnames, compress)
|
||||
return
|
||||
}
|
||||
|
||||
// ZipFile will zip the folder
|
||||
func ZipFile(fname string, compress bool) (writtenFilename string, err error) {
|
||||
logger.SetLogLevel(DebugLevel)
|
||||
|
||||
// get path to file and the filename
|
||||
_, filename := filepath.Split(fname)
|
||||
writtenFilename = filename + ".croc.zip"
|
||||
err = makeZip(writtenFilename, []string{fname}, compress)
|
||||
return
|
||||
}
|
||||
|
||||
func makeZip(writtenFilename string, fnames []string, compress bool) (err error) {
|
||||
log.Debugf("creating file: %s", writtenFilename)
|
||||
f, err := os.Create(writtenFilename)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
zipWriter := zip.NewWriter(f)
|
||||
zipWriter.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
|
||||
if compress {
|
||||
return flate.NewWriter(out, flate.BestSpeed)
|
||||
} else {
|
||||
return flate.NewWriter(out, flate.NoCompression)
|
||||
}
|
||||
})
|
||||
defer zipWriter.Close()
|
||||
|
||||
err = zipFiles(fnames, compress, zipWriter)
|
||||
if err == nil {
|
||||
log.Debugf("wrote zip file to %s", writtenFilename)
|
||||
} else {
|
||||
log.Error(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func zipFiles(fnames []string, compress bool, zipWriter *zip.Writer) (err error) {
|
||||
for _, fname := range fnames {
|
||||
// get absolute filename
|
||||
absPath, err := filepath.Abs(filepath.Clean(fname))
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
absPath = filepath.ToSlash(absPath)
|
||||
|
||||
// get path to file and the filename
|
||||
fpath, fname := filepath.Split(absPath)
|
||||
|
||||
// Get the file information for the target
|
||||
log.Debugf("checking %s", absPath)
|
||||
ftarget, err := os.Open(absPath)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
defer ftarget.Close()
|
||||
info, err := ftarget.Stat()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// write header informaiton
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var writer io.Writer
|
||||
if info.IsDir() {
|
||||
baseDir := filepath.Clean(path.Join(fpath, fname))
|
||||
log.Debugf("walking base dir: %s", baseDir)
|
||||
filepath.Walk(baseDir, func(curpath string, info os.FileInfo, err error) error {
|
||||
curpath = filepath.Clean(curpath)
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if baseDir != "" {
|
||||
header.Name = path.Join(fname, strings.TrimPrefix(curpath, baseDir))
|
||||
}
|
||||
header.Name = filepath.ToSlash(filepath.Clean(header.Name))
|
||||
log.Debug(header.Name)
|
||||
|
||||
if info.IsDir() {
|
||||
header.Name += "/"
|
||||
} else {
|
||||
header.Method = zip.Deflate
|
||||
}
|
||||
|
||||
writer, err = zipWriter.CreateHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := os.Open(curpath)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
_, err = io.Copy(writer, file)
|
||||
return err
|
||||
})
|
||||
} else {
|
||||
writer, err = zipWriter.CreateHeader(header)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(writer, ftarget)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package zipper
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
log "github.com/cihub/seelog"
|
||||
"github.com/schollz/croc/src/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestZip(t *testing.T) {
|
||||
defer log.Flush()
|
||||
DebugLevel = "debug"
|
||||
writtenFilename1, err := ZipFile("../croc", true)
|
||||
assert.Nil(t, err)
|
||||
err = UnzipFile(writtenFilename1, ".")
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, utils.Exists("croc"))
|
||||
|
||||
writtenFilename2, err := ZipFile("../../README.md", false)
|
||||
assert.Nil(t, err)
|
||||
err = UnzipFile(writtenFilename2, ".")
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, utils.Exists("README.md"))
|
||||
|
||||
os.Remove("README.md")
|
||||
os.RemoveAll("croc")
|
||||
os.Remove(writtenFilename1)
|
||||
os.Remove(writtenFilename2)
|
||||
}
|
||||
|
||||
func TestZipFiles(t *testing.T) {
|
||||
defer log.Flush()
|
||||
DebugLevel = "debug"
|
||||
writtenFilename, err := ZipFiles([]string{"../../LICENSE", "../win/Makefile", "../utils"}, true)
|
||||
assert.Nil(t, err)
|
||||
err = UnzipFile(writtenFilename, "zipfilestest")
|
||||
assert.Nil(t, err)
|
||||
assert.True(t, utils.Exists("zipfilestest/LICENSE"))
|
||||
assert.True(t, utils.Exists("zipfilestest/Makefile"))
|
||||
assert.True(t, utils.Exists("zipfilestest/utils/exists.go"))
|
||||
os.RemoveAll("zipfilestest")
|
||||
err = os.Remove(path.Join(".", writtenFilename))
|
||||
assert.Nil(t, err)
|
||||
}
|
Loading…
Reference in New Issue