diff --git a/file/exporter.go b/file/exporter.go new file mode 100644 index 0000000..dcb4775 --- /dev/null +++ b/file/exporter.go @@ -0,0 +1,50 @@ +package file + +import ( + "encoding/json" + "net/http" + "path/filepath" + + "github.com/b3log/wide/util" + "github.com/golang/glog" +) + +// CreateZip handles request of creating zip. +func CreateZip(w http.ResponseWriter, r *http.Request) { + data := map[string]interface{}{"succ": true} + defer util.RetJSON(w, r, data) + + var args map[string]interface{} + + if err := json.NewDecoder(r.Body).Decode(&args); err != nil { + glog.Error(err) + data["succ"] = false + + return + } + + path := args["path"].(string) + base := filepath.Base(path) + + if !util.File.IsExist(path) { + data["succ"] = false + data["msg"] = "Can't find file [" + path + "]" + + return + } + + zipFile, err := util.Zip.Create(path + ".zip") + if nil != err { + glog.Error(err) + data["succ"] = false + + return + } + defer zipFile.Close() + + if util.File.IsDir(path) { + zipFile.AddDirectory(base, path) + } else { + zipFile.AddEntry(base, path) + } +} diff --git a/main.go b/main.go index 907e8e3..3d7689a 100644 --- a/main.go +++ b/main.go @@ -281,6 +281,9 @@ func main() { http.HandleFunc("/file/search/text", handlerWrapper(file.SearchText)) http.HandleFunc("/file/find/name", handlerWrapper(file.Find)) + // file export/import + http.HandleFunc("/file/zip", handlerWrapper(file.CreateZip)) + // editor http.HandleFunc("/editor/ws", handlerWrapper(editor.WSHandler)) http.HandleFunc("/go/fmt", handlerWrapper(editor.GoFmtHandler)) diff --git a/util/zip.go b/util/zip.go new file mode 100644 index 0000000..09d594b --- /dev/null +++ b/util/zip.go @@ -0,0 +1,104 @@ +package util + +import ( + "archive/zip" + "io" + "io/ioutil" + "os" + "path/filepath" +) + +type myzip struct{} + +// Zip utilities. +var Zip = myzip{} + +type ZipFile struct { + zipFile *os.File + writer *zip.Writer +} + +func (*myzip) Create(filename string) (*ZipFile, error) { + file, err := os.Create(filename) + if err != nil { + return nil, err + } + + return &ZipFile{zipFile: file, writer: zip.NewWriter(file)}, nil +} + +func (z *ZipFile) Close() error { + err := z.zipFile.Close() // close the underlying writer + if nil != err { + return err + } + + return z.writer.Close() +} + +func (z *ZipFile) AddEntryN(dir string, names ...string) error { + for _, name := range names { + zipPath := filepath.Join(dir, 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) + if err != nil { + return err + } + + file, err := os.Open(name) + if err != nil { + return err + } + defer file.Close() + + _, err = io.Copy(entry, file) + + return err +} + +func (z *ZipFile) AddDirectoryN(dir string, names ...string) error { + for _, name := range names { + err := z.AddDirectory(dir, name) + if err != nil { + return err + } + } + + return nil +} + +func (z *ZipFile) AddDirectory(dir, dirName string) error { + files, err := ioutil.ReadDir(dirName) + if err != nil { + return err + } + + for _, file := range files { + localPath := filepath.Join(dirName, file.Name()) + zipPath := filepath.Join(dir, file.Name()) + + err = nil + if file.IsDir() { + z.AddEntry(dir, dirName) + + err = z.AddDirectory(zipPath, localPath) + } else { + err = z.AddEntry(zipPath, localPath) + } + + if err != nil { + return err + } + } + + return nil +}