diff --git a/file/exporter.go b/file/exporter.go index e300f98..099ef87 100644 --- a/file/exporter.go +++ b/file/exporter.go @@ -3,6 +3,7 @@ package file import ( "encoding/json" "net/http" + "os" "path/filepath" "github.com/b3log/wide/util" @@ -26,8 +27,13 @@ func GetZip(w http.ResponseWriter, r *http.Request) { return } + filename := filepath.Base(path) + + w.Header().Set("Content-Disposition", "attachment; filename="+filename) w.Header().Set("Content-type", "application/zip") http.ServeFile(w, r, path) + + os.Remove(path) } // CreateZip handles request of creating zip. diff --git a/i18n/en_US.json b/i18n/en_US.json index 5aa0646..251545a 100644 --- a/i18n/en_US.json +++ b/i18n/en_US.json @@ -133,5 +133,6 @@ "go_format": "Go Format", "locale": "Locale", "apply": "Apply", - "clearOutput": "Clear Output" + "clearOutput": "Clear Output", + "export": "Export" } \ No newline at end of file diff --git a/i18n/ja_JP.json b/i18n/ja_JP.json index e3b4d56..338c342 100644 --- a/i18n/ja_JP.json +++ b/i18n/ja_JP.json @@ -133,5 +133,6 @@ "go_format": "Go フォーマット", "locale": "ロケール", "apply": "適用する", - "clearOutput": "空の出力" + "clearOutput": "空の出力", + "export": "輸出" } diff --git a/i18n/zh_CN.json b/i18n/zh_CN.json index e9a8de3..2b02ea6 100644 --- a/i18n/zh_CN.json +++ b/i18n/zh_CN.json @@ -133,5 +133,6 @@ "go_format": "Go 格式化", "locale": "语言环境", "apply": "应用", - "clearOutput": "清空输出" + "clearOutput": "清空输出", + "export": "导出" } \ No newline at end of file diff --git a/i18n/zh_TW.json b/i18n/zh_TW.json index dc0ed24..a4519fc 100644 --- a/i18n/zh_TW.json +++ b/i18n/zh_TW.json @@ -133,5 +133,6 @@ "go_format": "Go 格式化", "locale": "語言環境", "apply": "應用", - "clearOutput": "清空輸出" + "clearOutput": "清空輸出", + "export": "導出" } \ No newline at end of file diff --git a/static/js/tree.js b/static/js/tree.js index 159ef0b..1bba33a 100644 --- a/static/js/tree.js +++ b/static/js/tree.js @@ -150,6 +150,35 @@ var tree = { $("#fileRMenu").hide(); $("#dialogRenamePrompt").dialog("open"); }, + export: function (it) { + if (it) { + if ($(it).hasClass("disabled")) { + return false; + } + } + + var request = newWideRequest(); + request.path = wide.curNode.path; + + $.ajax({ + type: 'POST', + url: '/file/zip/new', + data: JSON.stringify(request), + dataType: "json", + success: function (data) { + if (!data.succ) { + $("#dialogAlert").dialog("open", data.msg); + + return false; + } + + window.open('/file/zip?path=' + wide.curNode.path + '.zip'); + } + }); + + $("#dirRMenu").hide(); + $("#fileRMenu").hide(); + }, init: function () { $("#file").click(function () { $(this).focus(); @@ -289,7 +318,7 @@ var tree = { var w = window.open(data.path); return false; } - + if (!tempCursor) { tempCursor = CodeMirror.Pos(0, 0); } diff --git a/util/go.go b/util/go.go index 79e9ce5..f33e24f 100644 --- a/util/go.go +++ b/util/go.go @@ -1,6 +1,7 @@ package util import ( + "path/filepath" "path" "runtime" "strings" @@ -21,7 +22,7 @@ func (*mygo) GetAPIPath() string { ret = runtime.GOROOT() + "/src" // Go 1.4 and after } - return path.Clean(ret) + return filepath.FromSlash(path.Clean(ret)) } // IsAPI determines whether the specified path belongs to Go API. diff --git a/util/zip.go b/util/zip.go index 09d594b..41f5243 100644 --- a/util/zip.go +++ b/util/zip.go @@ -28,32 +28,52 @@ func (*myzip) Create(filename string) (*ZipFile, error) { } func (z *ZipFile) Close() error { - err := z.zipFile.Close() // close the underlying writer + err := z.writer.Close() if nil != err { return err } - return z.writer.Close() + return z.zipFile.Close() // close the underlying writer } -func (z *ZipFile) AddEntryN(dir string, names ...string) error { +func (z *ZipFile) AddEntryN(path string, names ...string) error { for _, name := range names { - zipPath := filepath.Join(dir, name) + zipPath := filepath.Join(path, name) err := z.AddEntry(zipPath, name) if err != nil { return err } } - return nil } -func (z *ZipFile) AddEntry(dir, name string) error { - entry, err := z.writer.Create(dir) +func (z *ZipFile) AddEntry(path, name string) error { + fi, err := os.Stat(name) if err != nil { return err } + fh, err := zip.FileInfoHeader(fi) + if err != nil { + return err + } + + fh.Name = filepath.ToSlash(filepath.Clean(path)) + fh.Method = zip.Deflate // data compression algorithm + + if fi.IsDir() { + fh.Name = fh.Name + "/" // be care the ending separator + } + + entry, err := z.writer.CreateHeader(fh) + if err != nil { + return err + } + + if fi.IsDir() { + return nil + } + file, err := os.Open(name) if err != nil { return err @@ -65,18 +85,17 @@ func (z *ZipFile) AddEntry(dir, name string) error { return err } -func (z *ZipFile) AddDirectoryN(dir string, names ...string) error { +func (z *ZipFile) AddDirectoryN(path string, names ...string) error { for _, name := range names { - err := z.AddDirectory(dir, name) + err := z.AddDirectory(path, name) if err != nil { return err } } - return nil } -func (z *ZipFile) AddDirectory(dir, dirName string) error { +func (z *ZipFile) AddDirectory(path, dirName string) error { files, err := ioutil.ReadDir(dirName) if err != nil { return err @@ -84,17 +103,16 @@ func (z *ZipFile) AddDirectory(dir, dirName string) error { for _, file := range files { localPath := filepath.Join(dirName, file.Name()) - zipPath := filepath.Join(dir, file.Name()) + zipPath := filepath.Join(path, file.Name()) err = nil if file.IsDir() { - z.AddEntry(dir, dirName) + z.AddEntry(path, dirName) err = z.AddDirectory(zipPath, localPath) } else { err = z.AddEntry(zipPath, localPath) } - if err != nil { return err } diff --git a/views/index.html b/views/index.html index b8e01dd..0a0c82b 100644 --- a/views/index.html +++ b/views/index.html @@ -138,6 +138,8 @@
  • {{.i18n.create_dir}}
  • {{.i18n.delete}}
  • {{.i18n.rename}}
  • +
  • +
  • {{.i18n.export}}
  • @@ -146,6 +148,8 @@