Skip to content

Commit a814d95

Browse files
committed
merge devb
2 parents a5480d2 + d3ac739 commit a814d95

File tree

12 files changed

+189
-123
lines changed

12 files changed

+189
-123
lines changed

controllers/BookController.go

Lines changed: 81 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package controllers
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"errors"
67
"fmt"
@@ -64,9 +65,11 @@ func (this *BookController) Index() {
6465
this.Data["SettingBook"] = true
6566
this.TplName = "book/index.html"
6667
private, _ := this.GetInt("private", 1) //是否是私有文档
68+
wd := this.GetString("wd", "")
6769
this.Data["Private"] = private
70+
this.Data["Wd"] = wd
6871
pageIndex, _ := this.GetInt("page", 1)
69-
books, totalCount, _ := models.NewBook().FindToPager(pageIndex, conf.PageSize, this.Member.MemberId, private)
72+
books, totalCount, _ := models.NewBook().FindToPager(pageIndex, conf.PageSize, this.Member.MemberId, wd, private)
7073
ebookStats := make(map[int]map[string]models.Ebook)
7174
modelEbook := models.NewEbook()
7275
for _, book := range books {
@@ -75,7 +78,7 @@ func (this *BookController) Index() {
7578
ebookJSON, _ := json.Marshal(ebookStats)
7679
this.Data["EbookStats"] = template.JS(string(ebookJSON))
7780
if totalCount > 0 {
78-
this.Data["PageHtml"] = utils.NewPaginations(conf.RollPage, totalCount, conf.PageSize, pageIndex, beego.URLFor("BookController.Index"), fmt.Sprintf("&private=%v", private))
81+
this.Data["PageHtml"] = utils.NewPaginations(conf.RollPage, totalCount, conf.PageSize, pageIndex, beego.URLFor("BookController.Index"), fmt.Sprintf("&private=%v&wd=%s", private, url.QueryEscape(wd)))
7982
} else {
8083
this.Data["PageHtml"] = ""
8184
}
@@ -1059,7 +1062,8 @@ func (this *BookController) unzipToData(bookId int, identify, zipFile, originFil
10591062
//读取文件,把图片文档录入oss
10601063
if files, err := filetil.ScanFiles(unzipPath); err == nil {
10611064
projectRoot = this.getProjectRoot(files)
1062-
this.replaceToAbs(projectRoot, identify)
1065+
1066+
this.fixFileLinks(projectRoot, identify)
10631067

10641068
ModelStore := new(models.DocumentStore)
10651069
//文档对应的标识
@@ -1069,11 +1073,11 @@ func (this *BookController) unzipToData(bookId int, identify, zipFile, originFil
10691073
if ok, _ := imgMap[ext]; ok { //图片,录入oss
10701074
switch utils.StoreType {
10711075
case utils.StoreOss:
1072-
if err := store.ModelStoreOss.MoveToOss(file.Path, "projects/"+identify+strings.TrimPrefix(file.Path, projectRoot), false, false); err != nil {
1076+
if err := store.ModelStoreOss.MoveToOss(file.Path, filepath.Join("projects/"+identify, strings.TrimPrefix(file.Path, projectRoot)), false, false); err != nil {
10731077
beego.Error(err)
10741078
}
10751079
case utils.StoreLocal:
1076-
if err := store.ModelStoreLocal.MoveToStore(file.Path, "uploads/projects/"+identify+strings.TrimPrefix(file.Path, projectRoot)); err != nil {
1080+
if err := store.ModelStoreLocal.MoveToStore(file.Path, filepath.Join("uploads/projects/"+identify, strings.TrimPrefix(file.Path, projectRoot))); err != nil {
10771081
beego.Error(err)
10781082
}
10791083
}
@@ -1082,13 +1086,9 @@ func (this *BookController) unzipToData(bookId int, identify, zipFile, originFil
10821086
var mdcont string
10831087
var htmlStr string
10841088
if b, err := ioutil.ReadFile(file.Path); err == nil {
1085-
if ext == ".md" || ext == ".markdown" {
1086-
mdcont = strings.TrimSpace(string(b))
1087-
htmlStr = mdtil.Md2html(mdcont)
1088-
} else {
1089-
htmlStr = string(b)
1090-
mdcont = html2md.Convert(htmlStr)
1091-
}
1089+
mdcont = strings.TrimSpace(string(b))
1090+
htmlStr = mdtil.Md2html(mdcont)
1091+
10921092
if !strings.HasPrefix(mdcont, "[TOC]") {
10931093
mdcont = "[TOC]\r\n\r\n" + mdcont
10941094
}
@@ -1151,7 +1151,7 @@ func (this *BookController) loadByFolder(bookId int, identify, folder string) {
11511151
return
11521152
}
11531153

1154-
this.replaceToAbs(folder, identify)
1154+
this.fixFileLinks(folder, identify)
11551155

11561156
ModelStore := new(models.DocumentStore)
11571157

@@ -1211,21 +1211,17 @@ func (this *BookController) loadByFolder(bookId int, identify, folder string) {
12111211

12121212
//获取书籍的根目录
12131213
func (this *BookController) getProjectRoot(fl []filetil.FileList) (root string) {
1214-
//获取书籍的根目录(感觉这个函数封装的不是很好,有更好的方法,请通过issue告知我,谢谢。)
1215-
i := 1000
1214+
var strs []string
12161215
for _, f := range fl {
12171216
if !f.IsDir {
1218-
if cnt := strings.Count(f.Path, "/"); cnt < i {
1219-
root = filepath.Dir(f.Path)
1220-
i = cnt
1221-
}
1217+
strs = append(strs, f.Path)
12221218
}
12231219
}
1224-
return
1220+
return utils.LongestCommonPrefix(strs)
12251221
}
12261222

12271223
//查找并替换markdown文件中的路径,把图片链接替换成url的相对路径,把文档间的链接替换成【$+文档标识链接】
1228-
func (this *BookController) replaceToAbs(projectRoot string, identify string) {
1224+
func (this *BookController) fixFileLinks(projectRoot string, identify string) {
12291225
imgBaseUrl := "/uploads/projects/" + identify
12301226
switch utils.StoreType {
12311227
case utils.StoreLocal:
@@ -1236,67 +1232,74 @@ func (this *BookController) replaceToAbs(projectRoot string, identify string) {
12361232
}
12371233
files, _ := filetil.ScanFiles(projectRoot)
12381234
for _, file := range files {
1239-
if ext := strings.ToLower(filepath.Ext(file.Path)); ext == ".md" || ext == ".markdown" {
1240-
//mdb ==> markdown byte
1241-
mdb, _ := ioutil.ReadFile(file.Path)
1242-
mdCont := string(mdb)
1243-
basePath := filepath.Dir(file.Path)
1244-
basePath = strings.Trim(strings.Replace(basePath, "\\", "/", -1), "/")
1245-
basePathSlice := strings.Split(basePath, "/")
1246-
l := len(basePathSlice)
1247-
b, _ := ioutil.ReadFile(file.Path)
1248-
output := blackfriday.Run(b)
1249-
doc, _ := goquery.NewDocumentFromReader(strings.NewReader(string(output)))
1250-
1251-
//图片链接处理
1252-
doc.Find("img").Each(func(i int, selection *goquery.Selection) {
1253-
//非http://、// 和 https:// 开头的图片地址,即是相对地址
1254-
src, ok := selection.Attr("src")
1255-
lowerSrc := strings.ToLower(src)
1256-
if ok &&
1257-
!strings.HasPrefix(lowerSrc, "http://") &&
1258-
!strings.HasPrefix(lowerSrc, "https://") {
1259-
newSrc := src //默认为旧地址
1260-
if strings.HasPrefix(lowerSrc, "//") {
1261-
newSrc = "https:" + newSrc
1262-
} else {
1263-
if cnt := strings.Count(src, "../"); cnt < l { //以或者"../"开头的路径
1264-
newSrc = strings.Join(basePathSlice[0:l-cnt], "/") + "/" + strings.TrimLeft(src, "./")
1265-
}
1266-
newSrc = imgBaseUrl + "/" + strings.TrimLeft(strings.TrimPrefix(strings.TrimLeft(newSrc, "./"), projectRoot), "/")
1235+
ext := strings.ToLower(filepath.Ext(file.Path))
1236+
if !(ext == ".md" || ext == ".markdown" || ext == ".html" || ext == ".xhtml") {
1237+
continue
1238+
}
1239+
1240+
//mdb ==> markdown byte
1241+
mdb, _ := ioutil.ReadFile(file.Path)
1242+
mdCont := string(mdb)
1243+
if ext == ".html" || ext == ".xhtml" {
1244+
mdCont = html2md.Convert(mdCont)
1245+
}
1246+
1247+
basePath := filepath.Dir(file.Path)
1248+
basePath = strings.Trim(strings.Replace(basePath, "\\", "/", -1), "/")
1249+
basePathSlice := strings.Split(basePath, "/")
1250+
l := len(basePathSlice)
1251+
b, _ := ioutil.ReadFile(file.Path)
1252+
output := blackfriday.Run(b)
1253+
doc, _ := goquery.NewDocumentFromReader(bytes.NewReader(output))
1254+
1255+
//图片链接处理
1256+
doc.Find("img").Each(func(i int, selection *goquery.Selection) {
1257+
//非http://、// 和 https:// 开头的图片地址,即是相对地址
1258+
src, ok := selection.Attr("src")
1259+
lowerSrc := strings.ToLower(src)
1260+
if ok &&
1261+
!strings.HasPrefix(lowerSrc, "http://") &&
1262+
!strings.HasPrefix(lowerSrc, "https://") {
1263+
newSrc := src //默认为旧地址
1264+
if strings.HasPrefix(lowerSrc, "//") {
1265+
newSrc = "https:" + newSrc
1266+
} else {
1267+
if cnt := strings.Count(src, "../"); cnt < l { //以或者"../"开头的路径
1268+
newSrc = strings.Join(basePathSlice[0:l-cnt], "/") + "/" + strings.TrimLeft(src, "./")
12671269
}
1268-
mdCont = strings.Replace(mdCont, src, newSrc, -1)
1270+
newSrc = imgBaseUrl + "/" + strings.TrimLeft(strings.TrimPrefix(strings.TrimLeft(newSrc, "./"), projectRoot), "/")
12691271
}
1270-
})
1271-
1272-
//a标签链接处理。要注意判断有锚点的情况
1273-
doc.Find("a").Each(func(i int, selection *goquery.Selection) {
1274-
href, ok := selection.Attr("href")
1275-
lowerHref := strings.TrimSpace(strings.ToLower(href))
1276-
// 链接存在,且不以 // 、 http、https、mailto 开头
1277-
if ok &&
1278-
!strings.HasPrefix(lowerHref, "//") &&
1279-
!strings.HasPrefix(lowerHref, "http://") &&
1280-
!strings.HasPrefix(lowerHref, "https://") &&
1281-
!strings.HasPrefix(lowerHref, "mailto:") &&
1282-
!strings.HasPrefix(lowerHref, "#") {
1283-
newHref := href //默认
1284-
if cnt := strings.Count(href, "../"); cnt < l {
1285-
newHref = strings.Join(basePathSlice[0:l-cnt], "/") + "/" + strings.TrimLeft(href, "./")
1286-
}
1287-
newHref = strings.TrimPrefix(strings.Trim(newHref, "/"), projectRoot)
1288-
if !strings.HasPrefix(href, "$") { //原链接不包含$符开头,否则表示已经替换过了。
1289-
newHref = "$" + strings.Replace(strings.Trim(newHref, "/"), "/", "-", -1)
1290-
slice := strings.Split(newHref, "$")
1291-
if ll := len(slice); ll > 0 {
1292-
newHref = "$" + slice[ll-1]
1293-
}
1294-
mdCont = strings.Replace(mdCont, "]("+href, "]("+newHref, -1)
1272+
mdCont = strings.Replace(mdCont, src, newSrc, -1)
1273+
}
1274+
})
1275+
1276+
//a标签链接处理。要注意判断有锚点的情况
1277+
doc.Find("a").Each(func(i int, selection *goquery.Selection) {
1278+
href, ok := selection.Attr("href")
1279+
lowerHref := strings.TrimSpace(strings.ToLower(href))
1280+
// 链接存在,且不以 // 、 http、https、mailto 开头
1281+
if ok &&
1282+
!strings.HasPrefix(lowerHref, "//") &&
1283+
!strings.HasPrefix(lowerHref, "http://") &&
1284+
!strings.HasPrefix(lowerHref, "https://") &&
1285+
!strings.HasPrefix(lowerHref, "mailto:") &&
1286+
!strings.HasPrefix(lowerHref, "#") {
1287+
newHref := href //默认
1288+
if cnt := strings.Count(href, "../"); cnt < l {
1289+
newHref = strings.Join(basePathSlice[0:l-cnt], "/") + "/" + strings.TrimLeft(href, "./")
1290+
}
1291+
newHref = strings.TrimPrefix(strings.Trim(newHref, "/"), projectRoot)
1292+
if !strings.HasPrefix(href, "$") { //原链接不包含$符开头,否则表示已经替换过了。
1293+
newHref = "$" + strings.Replace(strings.Trim(newHref, "/"), "/", "-", -1)
1294+
slice := strings.Split(newHref, "$")
1295+
if ll := len(slice); ll > 0 {
1296+
newHref = "$" + slice[ll-1]
12951297
}
1298+
mdCont = strings.Replace(mdCont, "]("+href, "]("+newHref, -1)
12961299
}
1297-
})
1298-
ioutil.WriteFile(file.Path, []byte(mdCont), os.ModePerm)
1299-
}
1300+
}
1301+
})
1302+
ioutil.WriteFile(file.Path, []byte(mdCont), os.ModePerm)
13001303
}
13011304
}
13021305

controllers/UserController.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func (this *UserController) Index() {
4646
if page < 1 {
4747
page = 1
4848
}
49-
books, totalCount, _ := models.NewBook().FindToPager(page, pageSize, this.UcenterMember.MemberId, 0)
49+
books, totalCount, _ := models.NewBook().FindToPager(page, pageSize, this.UcenterMember.MemberId, "", 0)
5050
this.Data["Books"] = books
5151

5252
if totalCount > 0 {

controllers/api/CommonController.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ func (this *CommonController) UserReleaseBook() {
377377
size, _ := this.GetInt("size", 10)
378378
size = utils.RangeNumber(size, 10, maxPageSize)
379379

380-
res, totalCount, err := models.NewBook().FindToPager(page, size, uid, 0)
380+
res, totalCount, err := models.NewBook().FindToPager(page, size, uid, "", 0)
381381
if err != nil {
382382
this.Response(http.StatusInternalServerError, messageInternalServerError)
383383
}

models/book.go

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -230,33 +230,47 @@ func (m *Book) FindByIdentify(identify string, cols ...string) (book *Book, err
230230

231231
//分页查询指定用户的书籍
232232
//按照最新的进行排序
233-
func (m *Book) FindToPager(pageIndex, pageSize, memberId int, PrivatelyOwned ...int) (books []*BookResult, totalCount int, err error) {
234-
233+
func (m *Book) FindToPager(pageIndex, pageSize, memberId int, wd string, PrivatelyOwned ...int) (books []*BookResult, totalCount int, err error) {
234+
var args = []interface{}{memberId}
235235
relationship := NewRelationship()
236-
237236
o := orm.NewOrm()
238-
sql1 := "SELECT COUNT(book.book_id) AS total_count FROM " + m.TableNameWithPrefix() + " AS book LEFT JOIN " +
237+
sqlCount := "SELECT COUNT(book.book_id) AS total_count FROM " + m.TableNameWithPrefix() + " AS book LEFT JOIN " +
239238
relationship.TableNameWithPrefix() + " AS rel ON book.book_id=rel.book_id AND rel.member_id = ? WHERE rel.relationship_id > 0 "
240239
if len(PrivatelyOwned) > 0 {
241-
sql1 = sql1 + " and book.privately_owned=" + strconv.Itoa(PrivatelyOwned[0])
240+
sqlCount = sqlCount + " and book.privately_owned=" + strconv.Itoa(PrivatelyOwned[0])
242241
}
243-
err = o.Raw(sql1, memberId).QueryRow(&totalCount)
242+
243+
if wd = strings.TrimSpace(wd); wd != "" {
244+
wd = "%" + wd + "%"
245+
sqlCount = sqlCount + " and (book.book_name like ? or book.description like ?)"
246+
args = append(args, wd, wd)
247+
}
248+
249+
err = o.Raw(sqlCount, args...).QueryRow(&totalCount)
244250
if err != nil {
251+
beego.Error(err)
245252
return
246253
}
247254

248255
offset := (pageIndex - 1) * pageSize
249-
sql2 := "SELECT book.*,rel.member_id,rel.role_id,m.account as create_name FROM " + m.TableNameWithPrefix() + " AS book" +
256+
sqlQuery := "SELECT book.*,rel.member_id,rel.role_id,m.account as create_name FROM " + m.TableNameWithPrefix() + " AS book" +
250257
" LEFT JOIN " + relationship.TableNameWithPrefix() + " AS rel ON book.book_id=rel.book_id AND rel.member_id = ? " +
251258
" LEFT JOIN " + NewMember().TableNameWithPrefix() + " AS m ON rel.member_id=m.member_id " +
252259
" WHERE rel.relationship_id > 0 %v ORDER BY book.book_id DESC LIMIT " + fmt.Sprintf("%d,%d", offset, pageSize)
253260

261+
cond := []string{}
262+
if wd != "" { // 不需要处理 wd 和 args,因为在上面已处理过
263+
cond = append(cond, " and (book.book_name like ? or book.description like ?)")
264+
}
265+
254266
if len(PrivatelyOwned) > 0 {
255-
sql2 = fmt.Sprintf(sql2, " and book.privately_owned="+strconv.Itoa(PrivatelyOwned[0]))
267+
cond = append(cond, " and book.privately_owned="+strconv.Itoa(PrivatelyOwned[0]))
256268
}
257-
_, err = o.Raw(sql2, memberId).QueryRows(&books)
269+
sqlQuery = fmt.Sprintf(sqlQuery, strings.Join(cond, " "))
270+
271+
_, err = o.Raw(sqlQuery, args...).QueryRows(&books)
258272
if err != nil {
259-
logs.Error("分页查询书籍列表 => ", err)
273+
beego.Error("分页查询书籍列表 => ", err, sqlQuery)
260274
return
261275
}
262276

models/ebook.go

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,14 @@ func (m *Ebook) generate(bookID int) {
267267
}
268268
}
269269

270+
o := orm.NewOrm()
270271
docStore := NewDocumentStore()
271272
baseUrl := "http://localhost:" + strconv.Itoa(beego.AppConfig.DefaultInt("httport", 8181))
272273
for _, doc := range docs {
273274
content := strings.TrimSpace(docStore.GetFiledById(doc.DocumentId, "content"))
274275
if utils.GetTextFromHtml(content) == "" { //内容为空,渲染文档内容,并再重新获取文档内容
275276
utils.RenderDocumentById(doc.DocumentId)
276-
orm.NewOrm().Read(doc, "document_id")
277+
o.Read(doc, "document_id")
277278
}
278279

279280
//将图片链接更换成绝对链接
@@ -348,16 +349,6 @@ func (m *Ebook) generate(bookID int) {
348349

349350
cfgFile := folder + "config.json"
350351
ioutil.WriteFile(cfgFile, []byte(util.InterfaceToJson(cfg)), os.ModePerm)
351-
if Convert, err := converter.NewConverter(cfgFile, debug); err == nil {
352-
// 电子书生成回调
353-
Convert.Callback = m.callback
354-
if err := Convert.Convert(); err != nil && strings.TrimSpace(err.Error()) != "" {
355-
beego.Error(err.Error())
356-
}
357-
} else {
358-
beego.Error(err.Error())
359-
}
360-
361352
Convert, err := converter.NewConverter(cfgFile, debug)
362353
if err != nil {
363354
beego.Error(err.Error())
@@ -366,9 +357,11 @@ func (m *Ebook) generate(bookID int) {
366357

367358
// 设置电子书生成回调
368359
Convert.Callback = m.callback
369-
if err = Convert.Convert(); err != nil {
360+
if err = Convert.Convert(); err != nil && err.Error() != "" {
370361
beego.Error(err.Error())
371362
}
363+
// 转换已经结束,还处在转换状态的电子书为失败的电子书
364+
o.QueryTable(m).Filter("book_id", book.BookId).Filter("status", EBookStatusProccessing).Update(orm.Params{"status": EBookStatusFailure})
372365
}
373366

374367
func (m *Ebook) deleteBook(bookId int) {
@@ -437,4 +430,28 @@ func (m *Ebook) callback(identify, ebookPath string, errConvert error) {
437430
ebook.Path = "/" + newEbookPath
438431
ebook.Status = EBookStatusSuccess
439432
o.Update(&ebook)
433+
m.DeleteOldEbook(ebook.BookID, ebook.Ext, ebook.Id)
434+
}
435+
436+
// DeleteOldEbook 删除旧电子书
437+
// 1. 相同ext,状态为 Success 之外的记录以及电子书文件
438+
func (m *Ebook) DeleteOldEbook(bookId int, ext string, ignoreEbookId int) {
439+
var (
440+
ebooks []Ebook
441+
o = orm.NewOrm()
442+
)
443+
444+
query := o.QueryTable(m).Filter("book_id", bookId).Filter("ext", ext)
445+
query.All(&ebooks)
446+
if len(ebooks) == 0 {
447+
return
448+
}
449+
450+
for _, ebook := range ebooks {
451+
if ebook.Id == ignoreEbookId {
452+
continue
453+
}
454+
utils.DeleteFile(ebook.Path)
455+
o.QueryTable(m).Filter("id", ebook.Id).Delete()
456+
}
440457
}

0 commit comments

Comments
 (0)