Fix #222
This commit is contained in:
parent
af808c2024
commit
fce39ce4e2
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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"
|
||||||
}
|
}
|
|
@ -176,5 +176,6 @@
|
||||||
"embeded": "埋め込む",
|
"embeded": "埋め込む",
|
||||||
"git_clone": "Git クローン",
|
"git_clone": "Git クローン",
|
||||||
"terms": "利用規約",
|
"terms": "利用規約",
|
||||||
"download": "ダウンロード"
|
"download": "ダウンロード",
|
||||||
|
"decompress": "解凍する"
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,5 +176,6 @@
|
||||||
"embeded": "嵌入",
|
"embeded": "嵌入",
|
||||||
"git_clone": "Git 克隆",
|
"git_clone": "Git 克隆",
|
||||||
"terms": "使用条款",
|
"terms": "使用条款",
|
||||||
"download": "下载"
|
"download": "下载",
|
||||||
|
"decompress": "解压缩"
|
||||||
}
|
}
|
|
@ -176,5 +176,6 @@
|
||||||
"embeded": "嵌入",
|
"embeded": "嵌入",
|
||||||
"git_clone": "Git 克隆",
|
"git_clone": "Git 克隆",
|
||||||
"terms": "使用條款",
|
"terms": "使用條款",
|
||||||
"download": "下載"
|
"download": "下載",
|
||||||
|
"decompress": "解壓縮"
|
||||||
}
|
}
|
1
main.go
1
main.go
|
@ -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))
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
58
util/zip.go
58
util/zip.go
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue