add unzip support when upload

This commit is contained in:
codeskyblue
2019-02-15 17:28:46 +08:00
parent 6d5aae4dde
commit a16f689e99
5 changed files with 77 additions and 9 deletions

View File

@@ -55,6 +55,7 @@ Tested with go-1.10, go-1.11
1. [x] Show folder size
1. [x] Create folder
1. [x] Skip delete confirm when alt pressed
1. [x] Support unzip zip file when upload(with form: unzip=true)
## Installation
```
@@ -198,6 +199,13 @@ $ curl -F file=@foo.txt -F filename=hi.txt localhost:8000/somedir
{"destination":"somedir/hi.txt","success":true}
```
Upload zip file and unzip it (zip file will be delete when finished unzip)
```
$ curl -F file=@pkg.zip -F unzip=true localhost:8000/somedir
{"success": true}
```
Note: `\/:*<>|` are not allowed in filenames.
### Deploy with nginx

3
go.mod
View File

@@ -15,13 +15,14 @@ require (
github.com/gorilla/handlers v1.4.0
github.com/gorilla/mux v1.6.2
github.com/gorilla/sessions v1.1.3
github.com/mholt/archiver v3.1.1+incompatible
github.com/nwaples/rardecode v1.0.0 // indirect
github.com/pkg/errors v0.8.0
github.com/shogo82148/androidbinary v0.0.0-20180627093851-01c4bfa8b3b5
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371
github.com/shurcooL/vfsgen v0.0.0-20181020040650-a97a25d856ca
github.com/stretchr/testify v1.3.0
github.com/ulikunitz/xz v0.5.5 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a
golang.org/x/text v0.3.0
)

View File

@@ -242,14 +242,20 @@ func (s *HTTPStaticServer) hUpload(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=utf-8")
if req.FormValue("unzip") == "true" {
err = archiver.Unarchive(dstPath, dirpath)
err = unzipFile(dstPath, dirpath)
dst.Close()
os.Remove(dstPath)
message := "success"
if err != nil {
message = err.Error()
}
json.NewEncoder(w).Encode(map[string]interface{}{
"success": err == nil,
"description": fmt.Sprintf("unarchive err = %v", err),
"description": message,
})
return
}
json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"destination": dstPath,
@@ -336,7 +342,6 @@ func (s *HTTPStaticServer) hUnzip(w http.ResponseWriter, r *http.Request) {
}
}
func combineURL(r *http.Request, path string) *url.URL {
return &url.URL{
Scheme: r.URL.Scheme,

52
zip.go
View File

@@ -13,8 +13,8 @@ import (
"strconv"
"strings"
"github.com/mholt/archiver"
dkignore "github.com/codeskyblue/dockerignore"
"golang.org/x/text/encoding/simplifiedchinese"
)
type Zip struct {
@@ -131,3 +131,53 @@ func ExtractFromZip(zipFile, path string, w io.Writer) (err error) {
}
return fmt.Errorf("File %s not found", strconv.Quote(path))
}
func unzipFile(filename, dest string) error {
zr, err := zip.OpenReader(filename)
if err != nil {
return err
}
defer zr.Close()
if dest == "" {
dest = filepath.Dir(filename)
}
for _, f := range zr.File {
rc, err := f.Open()
if err != nil {
return err
}
defer rc.Close()
fpath := filepath.Join(dest, f.Name)
// filename maybe GBK or UTF-8
// Ref: https://studygolang.com/articles/3114
if f.Flags & (1<<11) == 0 { // GBK
tr := simplifiedchinese.GB18030.NewDecoder()
fpathUtf8, err := tr.String(fpath)
if err == nil {
fpath = fpathUtf8
}
}
if f.FileInfo().IsDir() {
os.MkdirAll(fpath, os.ModePerm)
continue
}
os.MkdirAll(filepath.Dir(fpath), os.ModePerm)
outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}
_, err = io.Copy(outFile, rc)
outFile.Close()
if err != nil {
return err
}
}
return nil
}

View File

@@ -2,14 +2,18 @@ package main
import (
"bytes"
"github.com/stretchr/testify/assert"
"testing"
)
func TestExtractFromZip(t *testing.T) {
buf := bytes.NewBuffer(nil)
err := ExtractFromZip("testdata/test.zip", "**/foo.txt", buf)
if err != nil {
t.Fatal(err)
}
assert.NotNil(t, err)
t.Log("Content: " + buf.String())
}
//func TestUnzipTo(t *testing.T){
// err := unzipFile("testdata.zip", "./tmp")
// assert.Nil(t, err)
//}