This commit is contained in:
Van 2015-03-21 14:39:26 +08:00
parent af808c2024
commit fce39ce4e2
9 changed files with 156 additions and 6 deletions

57
file/decompress.go Normal file
View File

@ -0,0 +1,57 @@
// Copyright (c) 2014-2015, b3log.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package file
import (
"encoding/json"
"net/http"
"path/filepath"
"github.com/b3log/wide/util"
)
// DecompressHandler handles request of decompressing zip/tar.gz.
func DecompressHandler(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 {
logger.Error(err)
data["succ"] = false
return
}
path := args["path"].(string)
// base := filepath.Base(path)
dir := filepath.Dir(path)
if !util.File.IsExist(path) {
data["succ"] = false
data["msg"] = "Can't find file [" + path + "] to descompress"
return
}
err := util.Zip.Unzip(path, dir)
if nil != err {
logger.Error(err)
data["succ"] = false
return
}
}

View File

@ -176,5 +176,6 @@
"embeded": "Embeded", "embeded": "Embeded",
"git_clone": "Git Clone", "git_clone": "Git Clone",
"terms": "Terms", "terms": "Terms",
"download": "Download" "download": "Download",
"decompress": "Decompress"
} }

View File

@ -176,5 +176,6 @@
"embeded": "埋め込む", "embeded": "埋め込む",
"git_clone": "Git クローン", "git_clone": "Git クローン",
"terms": "利用規約", "terms": "利用規約",
"download": "ダウンロード" "download": "ダウンロード",
"decompress": "解凍する"
} }

View File

@ -176,5 +176,6 @@
"embeded": "嵌入", "embeded": "嵌入",
"git_clone": "Git 克隆", "git_clone": "Git 克隆",
"terms": "使用条款", "terms": "使用条款",
"download": "下载" "download": "下载",
"decompress": "解压缩"
} }

View File

@ -176,5 +176,6 @@
"embeded": "嵌入", "embeded": "嵌入",
"git_clone": "Git 克隆", "git_clone": "Git 克隆",
"terms": "使用條款", "terms": "使用條款",
"download": "下載" "download": "下載",
"decompress": "解壓縮"
} }

View File

@ -143,6 +143,7 @@ func main() {
http.HandleFunc(conf.Wide.Context+"/file/zip/new", handlerWrapper(file.CreateZipHandler)) http.HandleFunc(conf.Wide.Context+"/file/zip/new", handlerWrapper(file.CreateZipHandler))
http.HandleFunc(conf.Wide.Context+"/file/zip", handlerWrapper(file.GetZipHandler)) http.HandleFunc(conf.Wide.Context+"/file/zip", handlerWrapper(file.GetZipHandler))
http.HandleFunc(conf.Wide.Context+"/file/upload", handlerWrapper(file.UploadHandler)) http.HandleFunc(conf.Wide.Context+"/file/upload", handlerWrapper(file.UploadHandler))
http.HandleFunc(conf.Wide.Context+"/file/decompress", handlerWrapper(file.DecompressHandler))
// editor // editor
http.HandleFunc(conf.Wide.Context+"/editor/ws", handlerWrapper(editor.WSHandler)) http.HandleFunc(conf.Wide.Context+"/editor/ws", handlerWrapper(editor.WSHandler))

View File

@ -170,6 +170,27 @@ var tree = {
window.open(config.context + '/file/zip?path=' + wide.curNode.path + ".zip"); window.open(config.context + '/file/zip?path=' + wide.curNode.path + ".zip");
} }
}, },
decompress: function () {
var request = newWideRequest();
request.path = wide.curNode.path;
$.ajax({
async: false,
type: 'POST',
url: config.context + '/file/decompress',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
$("#dialogAlert").dialog("open", data.msg);
return false;
}
isSucc = true;
}
});
},
refresh: function (it) { refresh: function (it) {
if (it) { if (it) {
if ($(it).hasClass("disabled")) { if ($(it).hasClass("disabled")) {
@ -248,12 +269,18 @@ var tree = {
wide.curNode = treeNode; wide.curNode = treeNode;
tree.fileTree.selectNode(treeNode); tree.fileTree.selectNode(treeNode);
if (!tree.isDir()) { // 如果右击了文件 if (!tree.isDir()) { // if right click on a file
if (wide.curNode.removable) { if (wide.curNode.removable) {
$fileRMenu.find(".remove").removeClass("disabled"); $fileRMenu.find(".remove").removeClass("disabled");
} else { } else {
$fileRMenu.find(".remove").addClass("disabled"); $fileRMenu.find(".remove").addClass("disabled");
} }
if (wide.curNode.path.indexOf("zip", wide.curNode.path.length - "zip".length) === -1) { // !path.endsWith("zip")
$fileRMenu.find(".decompress").hide();
} else {
$fileRMenu.find(".decompress").show();
}
var top = event.clientY - 10; var top = event.clientY - 10;
if ($fileRMenu.height() + top > $('.content').height()) { if ($fileRMenu.height() + top > $('.content').height()) {

View File

@ -141,3 +141,61 @@ func (z *ZipFile) AddDirectory(path, dirName string) error {
return nil return nil
} }
func cloneZipItem(f *zip.File, dest string) error {
// create full directory path
path := filepath.Join(dest, f.Name)
err := os.MkdirAll(filepath.Dir(path), os.ModeDir|os.ModePerm)
if nil != err {
return err
}
if f.FileInfo().IsDir() {
return nil
}
// clone if item is a file
rc, err := f.Open()
if nil != err {
return err
}
defer rc.Close()
// use os.Create() since Zip don't store file permissions.
fileCopy, err := os.Create(path)
if nil != err {
return err
}
defer fileCopy.Close()
_, err = io.Copy(fileCopy, rc)
if nil != err {
return err
}
return nil
}
// Unzip extracts a zip file specified by the zipFilePath to the destination.
func (*myzip) Unzip(zipFilePath, destination string) error {
r, err := zip.OpenReader(zipFilePath)
if nil != err {
return err
}
defer r.Close()
for _, f := range r.File {
err = cloneZipItem(f, destination)
if nil != err {
return err
}
}
return nil
}

View File

@ -457,9 +457,12 @@
<span class="space"></span> {{.i18n.rename}} <span class="space"></span> {{.i18n.rename}}
</li> </li>
<li class="hr"></li> <li class="hr"></li>
<li class="" onclick="tree.export(this);"> <li class="export" onclick="tree.export(this);">
<span class="ico-export font-ico"></span> {{.i18n.export}} <span class="ico-export font-ico"></span> {{.i18n.export}}
</li> </li>
<li class="decompress" onclick="tree.decompress(this);">
<span class="space"></span> {{.i18n.decompress}}
</li>
</ul> </ul>
</div> </div>
</div> </div>