mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 22:50:13 +01:00
🎨 Support importing markdown zip on the browser (#14950)
This commit is contained in:
parent
88c7a66e68
commit
12cc17bd06
3 changed files with 122 additions and 17 deletions
|
|
@ -761,24 +761,43 @@ export const genImportMenu = (notebookId: string, pathString: string) => {
|
||||||
id: "import",
|
id: "import",
|
||||||
icon: "iconDownload",
|
icon: "iconDownload",
|
||||||
label: window.siyuan.languages.import,
|
label: window.siyuan.languages.import,
|
||||||
submenu: [{
|
submenu: [
|
||||||
id: "importSiYuanZip",
|
{
|
||||||
icon: "iconSiYuan",
|
id: "importSiYuanZip",
|
||||||
label: 'SiYuan .sy.zip<input class="b3-form__upload" type="file" accept="application/zip">',
|
icon: "iconSiYuan",
|
||||||
bind: (element) => {
|
label: 'SiYuan .sy.zip<input class="b3-form__upload" type="file" accept="application/zip">',
|
||||||
element.querySelector(".b3-form__upload").addEventListener("change", (event: InputEvent & {
|
bind: (element) => {
|
||||||
target: HTMLInputElement
|
element.querySelector(".b3-form__upload").addEventListener("change", (event: InputEvent & {
|
||||||
}) => {
|
target: HTMLInputElement
|
||||||
const formData = new FormData();
|
}) => {
|
||||||
formData.append("file", event.target.files[0]);
|
const formData = new FormData();
|
||||||
formData.append("notebook", notebookId);
|
formData.append("file", event.target.files[0]);
|
||||||
formData.append("toPath", pathString);
|
formData.append("notebook", notebookId);
|
||||||
fetchPost("/api/import/importSY", formData, () => {
|
formData.append("toPath", pathString);
|
||||||
reloadDocTree();
|
fetchPost("/api/import/importSY", formData, () => {
|
||||||
|
reloadDocTree();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
},
|
||||||
},
|
{
|
||||||
|
id: "importMarkdownZip",
|
||||||
|
icon: "iconMarkdown",
|
||||||
|
label: 'Markdown .zip<input class="b3-form__upload" type="file" accept="application/zip">',
|
||||||
|
bind: (element) => {
|
||||||
|
element.querySelector(".b3-form__upload").addEventListener("change", (event: InputEvent & {
|
||||||
|
target: HTMLInputElement
|
||||||
|
}) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", event.target.files[0]);
|
||||||
|
formData.append("notebook", notebookId);
|
||||||
|
formData.append("toPath", pathString);
|
||||||
|
fetchPost("/api/import/importZipMd", formData, () => {
|
||||||
|
reloadDocTree();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
/// #if !BROWSER
|
/// #if !BROWSER
|
||||||
importstdmd("Markdown " + window.siyuan.languages.doc, true),
|
importstdmd("Markdown " + window.siyuan.languages.doc, true),
|
||||||
importstdmd("Markdown " + window.siyuan.languages.folder)
|
importstdmd("Markdown " + window.siyuan.languages.folder)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/88250/gulu"
|
"github.com/88250/gulu"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
@ -185,3 +186,87 @@ func importStdMd(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func importZipMd(c *gin.Context) {
|
||||||
|
ret := gulu.Ret.NewResult()
|
||||||
|
defer c.JSON(200, ret)
|
||||||
|
|
||||||
|
util.PushEndlessProgress(model.Conf.Language(73))
|
||||||
|
defer util.ClearPushProgress(100)
|
||||||
|
|
||||||
|
form, err := c.MultipartForm()
|
||||||
|
if err != nil {
|
||||||
|
logging.LogErrorf("parse import .zip failed: %s", err)
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
files := form.File["file"]
|
||||||
|
if 1 > len(files) {
|
||||||
|
logging.LogErrorf("parse import .zip failed, no file found")
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = "no file found"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file := files[0]
|
||||||
|
reader, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
logging.LogErrorf("read import .zip failed: %s", err)
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
importDir := filepath.Join(util.TempDir, "import")
|
||||||
|
if err = os.MkdirAll(importDir, 0755); err != nil {
|
||||||
|
logging.LogErrorf("make import dir [%s] failed: %s", importDir, err)
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
writePath := filepath.Join(util.TempDir, "import", file.Filename)
|
||||||
|
defer os.RemoveAll(writePath)
|
||||||
|
writer, err := os.OpenFile(writePath, os.O_RDWR|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
logging.LogErrorf("open import .zip [%s] failed: %s", writePath, err)
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err = io.Copy(writer, reader); err != nil {
|
||||||
|
logging.LogErrorf("write import .zip failed: %s", err)
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
writer.Close()
|
||||||
|
reader.Close()
|
||||||
|
|
||||||
|
notebook := form.Value["notebook"][0]
|
||||||
|
toPath := form.Value["toPath"][0]
|
||||||
|
|
||||||
|
// 准备解压路径
|
||||||
|
filenameMain := strings.TrimSuffix(file.Filename, filepath.Ext(file.Filename))
|
||||||
|
unzipPath := filepath.Join(util.TempDir, "import", filenameMain)
|
||||||
|
|
||||||
|
defer os.RemoveAll(unzipPath)
|
||||||
|
|
||||||
|
// 解压 writePath 的 zip 到 unzipPath
|
||||||
|
err = gulu.Zip.Unzip(writePath, unzipPath)
|
||||||
|
if err != nil {
|
||||||
|
logging.LogErrorf("unzip import .zip failed: %s", err)
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用本地导入逻辑
|
||||||
|
err = model.ImportFromLocalPath(notebook, unzipPath, toPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ret.Code = -1
|
||||||
|
ret.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,7 @@ func ServeAPI(ginServer *gin.Engine) {
|
||||||
ginServer.Handle("POST", "/api/export/exportAttributeView", model.CheckAuth, model.CheckAdminRole, exportAttributeView)
|
ginServer.Handle("POST", "/api/export/exportAttributeView", model.CheckAuth, model.CheckAdminRole, exportAttributeView)
|
||||||
|
|
||||||
ginServer.Handle("POST", "/api/import/importStdMd", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importStdMd)
|
ginServer.Handle("POST", "/api/import/importStdMd", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importStdMd)
|
||||||
|
ginServer.Handle("POST", "/api/import/importZipMd", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importZipMd)
|
||||||
ginServer.Handle("POST", "/api/import/importData", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importData)
|
ginServer.Handle("POST", "/api/import/importData", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importData)
|
||||||
ginServer.Handle("POST", "/api/import/importSY", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importSY)
|
ginServer.Handle("POST", "/api/import/importSY", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importSY)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue