-
Notifications
You must be signed in to change notification settings - Fork 2
/
endive.go
183 lines (168 loc) · 4.41 KB
/
endive.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package main
import (
"os"
b "github.com/barsanuphe/endive/book"
"github.com/barsanuphe/endive/db"
en "github.com/barsanuphe/endive/endive"
i "github.com/barsanuphe/endive/index"
l "github.com/barsanuphe/endive/library"
u "github.com/barsanuphe/helpers/ui"
"github.com/barsanuphe/helpers"
)
// Endive is the main struct here.
type Endive struct {
hashes en.KnownHashes
Config en.Config
UI u.UserInterface
Library l.Library
}
// NewEndive constructs a valid new Epub
func NewEndive() (*Endive, error) {
// init ui
var ui u.UserInterface
ui = &u.UI{}
if err := ui.InitLogger(en.XdgLogPath); err != nil {
return nil, err
}
// init known hashes
hashesPath, err := en.GetKnownHashesPath()
if err != nil {
return nil, err
}
hashes := en.KnownHashes{Filename: hashesPath}
err = hashes.Load()
if err != nil {
return nil, err
}
// create Endive
e := &Endive{UI: ui, hashes: hashes}
// open Config
if err := e.openConfig(); err != nil {
return e, err
}
// open library
if err := e.openLibrary(); err != nil {
return e, err
}
// set lock
err = en.SetLock()
return e, err
}
func (e *Endive) openConfig() error {
// config
configPath, err := en.GetConfigPath()
if err != nil {
return err
}
e.Config = en.Config{Filename: configPath}
// config load
e.UI.Debugf("Loading Config %s.\n", e.Config.Filename)
err = e.Config.Load()
if err != nil {
if err == en.WarningGoodReadsAPIKeyMissing {
e.UI.Warning(err.Error())
} else {
e.UI.Error(err.Error())
}
return err
}
// check config
e.UI.Debug("Checking Config...")
err = e.Config.Check()
if err == en.WarningNonRetailSourceDoesNotExist || err == en.WarningRetailSourceDoesNotExist {
e.UI.Warning(err.Error())
}
return err
}
// OpenLibrary constucts a valid new Library
func (e *Endive) openLibrary() error {
// index
index := &i.Index{}
index.SetPath(en.GetIndexPath())
// db
db := &db.JSONDB{}
db.SetPath(e.Config.DatabaseFile)
e.Library = l.Library{Collection: &b.Books{}, Config: e.Config, Index: index, UI: e.UI, DB: db}
return e.Library.Load()
}
// Refresh current DB
func (e *Endive) Refresh() (renamed int, err error) {
e.UI.Info("Refreshing database...")
// scan for new epubs
foundCandidates, err := en.ScanForEpubs(e.Config.LibraryRoot, e.hashes, e.Library.Collection)
if err != nil {
return
}
// compare allEpubs with l.Epubs
var newEpubs en.EpubCandidates
for _, epub := range foundCandidates {
_, err = e.Library.Collection.FindByFullPath(epub.Filename)
// no error == found Epub
if err != nil {
// check if hash is known
gBook, err := e.Library.Collection.FindByHash(epub.Hash)
if err != nil {
// else, it's a new epub, import
e.UI.Info("NEW EPUB " + epub.Filename + " , will be imported as non-retail.")
newEpubs = append(newEpubs, epub)
} else {
var book *b.Book
book = gBook.(*b.Book)
// if it is, rename found file to filename in DB
destination := book.RetailEpub.FullPath()
if book.NonRetailEpub.Hash == epub.Hash {
destination = book.NonRetailEpub.FullPath()
}
// check if retail epub already exists
_, err := helpers.FileExists(destination)
if err == nil {
// file already exists
e.UI.Errorf("Found epub %s with the same hash as %s, ignoring.", epub.Filename, destination)
} else {
e.UI.Warningf("Found epub %s which is called %s in the database, renaming.", epub.Filename, destination)
// rename found file to retail name in db
err = os.Rename(epub.Filename, destination)
if err != nil {
return 0, err
}
}
}
}
}
if len(newEpubs.Importable()) != 0 {
// import new books as non-retail
err = e.ImportEpubs(newEpubs.Importable(), false)
if err != nil {
return
}
}
// refresh all books
deletedBooks := []int{}
for i := range e.Library.Collection.Books() {
wasRenamed, _, err := e.Library.Collection.Books()[i].Refresh()
if err != nil {
return renamed, err
}
if !e.Library.Collection.Books()[i].HasEpub() {
// mark for deletion
deletedBooks = append(deletedBooks, e.Library.Collection.Books()[i].ID())
}
if wasRenamed[0] {
renamed++
}
if wasRenamed[1] {
renamed++
}
}
// remove empty books
for _, id := range deletedBooks {
e.UI.Infof("REMOVING from db Book with ID %d\n", id)
err := e.Library.Collection.RemoveByID(id)
if err != nil {
return renamed, err
}
}
// remove all empty dirs
err = helpers.DeleteEmptyFolders(e.Config.LibraryRoot, e.UI)
return
}