A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1// SiYuan - Refactor your thinking
2// Copyright (c) 2020-present, b3log.org
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Affero General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Affero General Public License for more details.
13//
14// You should have received a copy of the GNU Affero General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17package api
18
19import (
20 "io"
21 "net/http"
22 "os"
23 "path/filepath"
24 "strings"
25
26 "github.com/88250/gulu"
27 "github.com/gin-gonic/gin"
28 "github.com/siyuan-note/logging"
29 "github.com/siyuan-note/siyuan/kernel/model"
30 "github.com/siyuan-note/siyuan/kernel/util"
31)
32
33func importSY(c *gin.Context) {
34 ret := gulu.Ret.NewResult()
35 defer c.JSON(200, ret)
36
37 util.PushEndlessProgress(model.Conf.Language(73))
38 defer util.ClearPushProgress(100)
39
40 form, err := c.MultipartForm()
41 if err != nil {
42 logging.LogErrorf("parse import .sy.zip failed: %s", err)
43 ret.Code = -1
44 ret.Msg = err.Error()
45 return
46 }
47
48 files := form.File["file"]
49 if 1 > len(files) {
50 logging.LogErrorf("parse import .sy.zip failed, no file found")
51 ret.Code = -1
52 ret.Msg = "no file found"
53 return
54 }
55 file := files[0]
56 reader, err := file.Open()
57 if err != nil {
58 logging.LogErrorf("read import .sy.zip failed: %s", err)
59 ret.Code = -1
60 ret.Msg = err.Error()
61 return
62 }
63
64 importDir := filepath.Join(util.TempDir, "import")
65 if err = os.MkdirAll(importDir, 0755); err != nil {
66 logging.LogErrorf("make import dir [%s] failed: %s", importDir, err)
67 ret.Code = -1
68 ret.Msg = err.Error()
69 return
70 }
71 writePath := filepath.Join(util.TempDir, "import", file.Filename)
72 defer os.RemoveAll(writePath)
73 writer, err := os.OpenFile(writePath, os.O_RDWR|os.O_CREATE, 0644)
74 if err != nil {
75 logging.LogErrorf("open import .sy.zip [%s] failed: %s", writePath, err)
76 ret.Code = -1
77 ret.Msg = err.Error()
78 return
79 }
80 if _, err = io.Copy(writer, reader); err != nil {
81 logging.LogErrorf("write import .sy.zip failed: %s", err)
82 ret.Code = -1
83 ret.Msg = err.Error()
84 return
85 }
86 writer.Close()
87 reader.Close()
88
89 notebook := form.Value["notebook"][0]
90 toPath := form.Value["toPath"][0]
91
92 err = model.ImportSY(writePath, notebook, toPath)
93 if err != nil {
94 ret.Code = -1
95 ret.Msg = err.Error()
96 return
97 }
98}
99
100func importData(c *gin.Context) {
101 ret := gulu.Ret.NewResult()
102 defer c.JSON(http.StatusOK, ret)
103
104 util.PushEndlessProgress(model.Conf.Language(73))
105 defer util.ClearPushProgress(100)
106
107 form, err := c.MultipartForm()
108 if err != nil {
109 logging.LogErrorf("import data failed: %s", err)
110 ret.Code = -1
111 ret.Msg = err.Error()
112 return
113 }
114
115 if 1 > len(form.File["file"]) {
116 logging.LogErrorf("import data failed: %s", err)
117 ret.Code = -1
118 ret.Msg = "file not found"
119 return
120 }
121
122 tmpImport := filepath.Join(util.TempDir, "import")
123 err = os.MkdirAll(tmpImport, 0755)
124 if err != nil {
125 ret.Code = -1
126 ret.Msg = "create temp import dir failed"
127 return
128 }
129 dataZipPath := filepath.Join(tmpImport, util.CurrentTimeSecondsStr()+".zip")
130 defer os.RemoveAll(dataZipPath)
131 dataZipFile, err := os.Create(dataZipPath)
132 if err != nil {
133 logging.LogErrorf("create temp file failed: %s", err)
134 ret.Code = -1
135 ret.Msg = "create temp file failed"
136 return
137 }
138 file := form.File["file"][0]
139 logging.LogInfof("import data [name=%s, size=%d]", file.Filename, file.Size)
140 fileReader, err := file.Open()
141 if err != nil {
142 logging.LogErrorf("open upload file failed: %s", err)
143 ret.Code = -1
144 ret.Msg = "open file failed"
145 return
146 }
147 _, err = io.Copy(dataZipFile, fileReader)
148 if err != nil {
149 logging.LogErrorf("read upload file failed: %s", err)
150 ret.Code = -1
151 ret.Msg = "read file failed"
152 return
153 }
154 if err = dataZipFile.Close(); err != nil {
155 logging.LogErrorf("close file failed: %s", err)
156 ret.Code = -1
157 ret.Msg = "close file failed"
158 return
159 }
160 fileReader.Close()
161
162 err = model.ImportData(dataZipPath)
163 if err != nil {
164 ret.Code = -1
165 ret.Msg = err.Error()
166 return
167 }
168}
169
170func importStdMd(c *gin.Context) {
171 ret := gulu.Ret.NewResult()
172 defer c.JSON(http.StatusOK, ret)
173
174 arg, ok := util.JsonArg(c, ret)
175 if !ok {
176 return
177 }
178
179 notebook := arg["notebook"].(string)
180 localPath := arg["localPath"].(string)
181 toPath := arg["toPath"].(string)
182 err := model.ImportFromLocalPath(notebook, localPath, toPath)
183 if err != nil {
184 ret.Code = -1
185 ret.Msg = err.Error()
186 return
187 }
188}
189
190func importZipMd(c *gin.Context) {
191 ret := gulu.Ret.NewResult()
192 defer c.JSON(200, ret)
193
194 util.PushEndlessProgress(model.Conf.Language(73))
195 defer util.ClearPushProgress(100)
196
197 form, err := c.MultipartForm()
198 if err != nil {
199 logging.LogErrorf("parse import .zip failed: %s", err)
200 ret.Code = -1
201 ret.Msg = err.Error()
202 return
203 }
204
205 files := form.File["file"]
206 if 1 > len(files) {
207 logging.LogErrorf("parse import .zip failed, no file found")
208 ret.Code = -1
209 ret.Msg = "no file found"
210 return
211 }
212 file := files[0]
213 reader, err := file.Open()
214 if err != nil {
215 logging.LogErrorf("read import .zip failed: %s", err)
216 ret.Code = -1
217 ret.Msg = err.Error()
218 return
219 }
220
221 importDir := filepath.Join(util.TempDir, "import")
222 if err = os.MkdirAll(importDir, 0755); err != nil {
223 logging.LogErrorf("make import dir [%s] failed: %s", importDir, err)
224 ret.Code = -1
225 ret.Msg = err.Error()
226 return
227 }
228 writePath := filepath.Join(util.TempDir, "import", file.Filename)
229 defer os.RemoveAll(writePath)
230 writer, err := os.OpenFile(writePath, os.O_RDWR|os.O_CREATE, 0644)
231 if err != nil {
232 logging.LogErrorf("open import .zip [%s] failed: %s", writePath, err)
233 ret.Code = -1
234 ret.Msg = err.Error()
235 return
236 }
237 if _, err = io.Copy(writer, reader); err != nil {
238 logging.LogErrorf("write import .zip failed: %s", err)
239 ret.Code = -1
240 ret.Msg = err.Error()
241 return
242 }
243 writer.Close()
244 reader.Close()
245
246 notebook := form.Value["notebook"][0]
247 toPath := form.Value["toPath"][0]
248
249 // 准备解压路径
250 filenameMain := strings.TrimSuffix(file.Filename, filepath.Ext(file.Filename))
251 unzipPath := filepath.Join(util.TempDir, "import", filenameMain)
252
253 defer os.RemoveAll(unzipPath)
254
255 // 解压 writePath 的 zip 到 unzipPath
256 err = gulu.Zip.Unzip(writePath, unzipPath)
257 if err != nil {
258 logging.LogErrorf("unzip import .zip failed: %s", err)
259 ret.Code = -1
260 ret.Msg = err.Error()
261 return
262 }
263
264 // 调用本地导入逻辑
265 err = model.ImportFromLocalPath(notebook, unzipPath, toPath)
266
267 if err != nil {
268 ret.Code = -1
269 ret.Msg = err.Error()
270 return
271 }
272}