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",
|
||||
"git_clone": "Git Clone",
|
||||
"terms": "Terms",
|
||||
"download": "Download"
|
||||
"download": "Download",
|
||||
"decompress": "Decompress"
|
||||
}
|
|
@ -176,5 +176,6 @@
|
|||
"embeded": "埋め込む",
|
||||
"git_clone": "Git クローン",
|
||||
"terms": "利用規約",
|
||||
"download": "ダウンロード"
|
||||
"download": "ダウンロード",
|
||||
"decompress": "解凍する"
|
||||
}
|
||||
|
|
|
@ -176,5 +176,6 @@
|
|||
"embeded": "嵌入",
|
||||
"git_clone": "Git 克隆",
|
||||
"terms": "使用条款",
|
||||
"download": "下载"
|
||||
"download": "下载",
|
||||
"decompress": "解压缩"
|
||||
}
|
|
@ -176,5 +176,6 @@
|
|||
"embeded": "嵌入",
|
||||
"git_clone": "Git 克隆",
|
||||
"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", handlerWrapper(file.GetZipHandler))
|
||||
http.HandleFunc(conf.Wide.Context+"/file/upload", handlerWrapper(file.UploadHandler))
|
||||
http.HandleFunc(conf.Wide.Context+"/file/decompress", handlerWrapper(file.DecompressHandler))
|
||||
|
||||
// editor
|
||||
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");
|
||||
}
|
||||
},
|
||||
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) {
|
||||
if (it) {
|
||||
if ($(it).hasClass("disabled")) {
|
||||
|
@ -248,13 +269,19 @@ var tree = {
|
|||
wide.curNode = treeNode;
|
||||
tree.fileTree.selectNode(treeNode);
|
||||
|
||||
if (!tree.isDir()) { // 如果右击了文件
|
||||
if (!tree.isDir()) { // if right click on a file
|
||||
if (wide.curNode.removable) {
|
||||
$fileRMenu.find(".remove").removeClass("disabled");
|
||||
} else {
|
||||
$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;
|
||||
if ($fileRMenu.height() + top > $('.content').height()) {
|
||||
top = top - $fileRMenu.height() - 25;
|
||||
|
|
58
util/zip.go
58
util/zip.go
|
@ -141,3 +141,61 @@ func (z *ZipFile) AddDirectory(path, dirName string) error {
|
|||
|
||||
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}}
|
||||
</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}}
|
||||
</li>
|
||||
<li class="decompress" onclick="tree.decompress(this);">
|
||||
<span class="space"></span> {{.i18n.decompress}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue