/
folder.go
159 lines (148 loc) · 4.72 KB
/
folder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package types
import (
"errors"
"os"
"path/filepath"
"sync"
"github.com/yumenaka/comi/logger"
"github.com/yumenaka/comi/util"
)
// Folder 本地总书库,扫描后生成。可以有多个子书库。
type Folder struct {
Path string
SortBy string //新字段 //排序方式
SubFolders sync.Map //key为路径 存储 *subFolder
}
// 对应某个扫描路径的子书库
type subFolder struct {
Path string //路径
SortBy string //排序方式
BookMap sync.Map //拥有的书籍,key是BookID,存储 *BookInfo
BookGroupMap sync.Map //拥有的书籍组,通过扫描书库生成,key是BookID,存储 *BookInfo。需要通过Depth从深到浅生成
}
// InitFolder 生成书籍组
func (folder *Folder) InitFolder() (e error) {
//遍历所有子书库
folder.SubFolders.Range(func(_, value interface{}) bool {
s := value.(*subFolder)
err := s.AnalyzeFolder()
if err != nil {
e = err
}
return true
})
return e
}
func (s *subFolder) AnalyzeFolder() error {
count := 0
s.BookMap.Range(func(key, value interface{}) bool {
count++
return true
})
if count == 0 {
return errors.New("empty Bookstore")
}
depthBooksMap := make(map[int][]BookInfo) //key是Depth的临时map
maxDepth := 0
s.BookMap.Range(func(key, value interface{}) bool {
b := value.(*BookInfo)
depthBooksMap[b.Depth] = append(depthBooksMap[b.Depth], *b)
if b.Depth > maxDepth {
maxDepth = b.Depth
}
return true
})
//从深往浅遍历
//如果有几本书同时有同一个父文件夹,那么应该【新建]一本书(组),并加入到depth-1层里面
for depth := maxDepth; depth >= 0; depth-- {
//用父文件夹做key的parentMap,后面遍历用
parentTempMap := make(map[string][]BookInfo)
////遍历depth等于i的所有book
for _, b := range depthBooksMap[depth] {
parentTempMap[b.ParentFolder] = append(parentTempMap[b.ParentFolder], b)
}
//循环parentMap,把有相同parent的书创建为一个书组
for parent, sameParentBookList := range parentTempMap {
//新建一本书,类型是书籍组
// 获取文件夹信息
pathInfo, err := os.Stat(sameParentBookList[0].FilePath)
if err != nil {
return err
}
// 获取修改时间
modTime := pathInfo.ModTime()
newBookGroup, err := NewBookGroup(filepath.Dir(sameParentBookList[0].FilePath), modTime, 0, s.Path, depth-1, TypeBooksGroup)
if err != nil {
logger.Info(err)
continue
}
//书名应该设置成parent
if newBookGroup.Title != parent {
newBookGroup.Title = parent
}
//初始化ChildBook
//然后把同一parent的书,都加进某个书籍组
for i, bookInList := range sameParentBookList {
//顺便设置一下封面,只设置一次
if i == 0 {
newBookGroup.Cover = bookInList.Cover //
}
newBookGroup.ChildBook.Store(bookInList.BookID, &sameParentBookList[i])
}
newBookGroup.ChildBookNum = len(sameParentBookList)
//如果书籍组的子书籍数量大于等于1,且从来没有添加过,将书籍组加到上一层
if newBookGroup.ChildBookNum == 0 {
continue
}
//检测是否已经生成并添加过
Added := false
mapBookGroup.Range(func(_, value interface{}) bool {
group := value.(*BookGroup)
if group.FilePath == newBookGroup.FilePath {
Added = true
}
return true
})
//添加过的不需要添加
if Added {
continue
}
depthBooksMap[depth-1] = append(depthBooksMap[depth-1], newBookGroup.BookInfo)
newBookGroup.Author, _ = util.GetAuthor(newBookGroup.Title)
//将这本书加到子书库的BookGroup表(Images.BookGroupMap)里面去
s.BookGroupMap.Store(newBookGroup.BookID, &newBookGroup.BookInfo)
//将这本书加到BookGroup总表(mapBookGroup)里面去
mapBookGroup.Store(newBookGroup.BookID, newBookGroup)
}
}
return nil
}
// AddSubFolder 创建一个新文件夹
func (folder *Folder) AddSubFolder(basePath string) error {
if _, ok := folder.SubFolders.Load(basePath); ok {
// 已经有这个key了
return errors.New("add Bookstore Error: The key already exists [" + basePath + "]")
}
s := subFolder{
Path: basePath,
}
folder.SubFolders.Store(basePath, &s)
return nil
}
// AddBookToSubFolder 将某一本书,放到BookMap里面去
func (folder *Folder) AddBookToSubFolder(searchPath string, b *BookInfo) error {
if f, ok := folder.SubFolders.Load(searchPath); !ok {
//创建一个新子书库,并添加一本书
newStore := subFolder{
Path: searchPath,
}
newStore.BookMap.Store(b.BookID, b)
folder.SubFolders.Store(searchPath, &newStore)
return errors.New("add Bookstore Error: The key not found [" + searchPath + "]")
} else {
//给已有子书库添加一本书
temp := f.(*subFolder)
temp.BookMap.Store(b.BookID, b)
return nil
}
}