Add hashes for each book
Check if the uploaded book is already in the library
This commit is contained in:
parent
154867c50c
commit
a1ee320eba
4 changed files with 41 additions and 5 deletions
|
@ -1,6 +1,8 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
log "github.com/cihub/seelog"
|
||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -17,9 +19,10 @@ type Book struct {
|
||||||
Description string
|
Description string
|
||||||
Tags []string `pg:"tags,array"`
|
Tags []string `pg:"tags,array"`
|
||||||
Date string
|
Date string
|
||||||
Lang string `pg:"type:varchar(3)"`
|
Lang string `pg:"type:varchar(3)"`
|
||||||
Isbn string `pg:"type:varchar(13)"`
|
Isbn string `pg:"type:varchar(13)"`
|
||||||
FileSize int `pg:"type:integer"`
|
FileSize int `pg:"type:integer"`
|
||||||
|
FileHash []byte
|
||||||
Cover bool `pg:",notnull"`
|
Cover bool `pg:",notnull"`
|
||||||
Active bool `pg:",notnull"`
|
Active bool `pg:",notnull"`
|
||||||
UploadDate time.Time `pg:"type:timestamp"`
|
UploadDate time.Time `pg:"type:timestamp"`
|
||||||
|
@ -165,6 +168,18 @@ func (db *pgDB) IsBookActive(id string) bool {
|
||||||
return active[0]
|
return active[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExistsBookHash checks if the given hash matches the hash of any book in the lbirary
|
||||||
|
func (db *pgDB) ExistsBookHash(hash []byte) bool {
|
||||||
|
count, err := db.sql.Model(&Book{}).
|
||||||
|
Where("file_hash = ?", hash).
|
||||||
|
Count()
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("There was an error looking for the hash: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return count > 0
|
||||||
|
}
|
||||||
|
|
||||||
type columnq struct {
|
type columnq struct {
|
||||||
column string
|
column string
|
||||||
value string
|
value string
|
||||||
|
|
|
@ -17,6 +17,7 @@ type DB interface {
|
||||||
UpdateBook(id string, data map[string]interface{}) error
|
UpdateBook(id string, data map[string]interface{}) error
|
||||||
ActiveBook(id string) error
|
ActiveBook(id string) error
|
||||||
IsBookActive(id string) bool
|
IsBookActive(id string) bool
|
||||||
|
ExistsBookHash(hash []byte) bool
|
||||||
AddUser(name string, pass string) error
|
AddUser(name string, pass string) error
|
||||||
AddRawUser(name string, hpass []byte, salt []byte, role string) error
|
AddRawUser(name string, hpass []byte, salt []byte, role string) error
|
||||||
SetAdminUser(name string, pass string) error
|
SetAdminUser(name string, pass string) error
|
||||||
|
@ -149,6 +150,7 @@ ALTER TABLE books ALTER COLUMN active SET DEFAULT false ;
|
||||||
CREATE INDEX IF NOT EXISTS books_lang_idx ON books (lang);
|
CREATE INDEX IF NOT EXISTS books_lang_idx ON books (lang);
|
||||||
CREATE INDEX IF NOT EXISTS books_isbn_idx ON books (isbn);
|
CREATE INDEX IF NOT EXISTS books_isbn_idx ON books (isbn);
|
||||||
CREATE INDEX IF NOT EXISTS books_active_idx ON books (active);
|
CREATE INDEX IF NOT EXISTS books_active_idx ON books (active);
|
||||||
|
CREATE INDEX IF NOT EXISTS books_file_hash_idx ON books (file_hash);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,10 @@ func (db *roDB) IsBookActive(id string) bool {
|
||||||
return db.db.IsBookActive(id)
|
return db.db.IsBookActive(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *roDB) ExistsBookHash(hash []byte) bool {
|
||||||
|
return db.db.ExistsBookHash(hash)
|
||||||
|
}
|
||||||
|
|
||||||
func (db *roDB) AddUser(name string, pass string) error {
|
func (db *roDB) AddUser(name string, pass string) error {
|
||||||
return errors.New("RO database")
|
return errors.New("RO database")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package trantor
|
package trantor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
|
|
||||||
log "github.com/cihub/seelog"
|
log "github.com/cihub/seelog"
|
||||||
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"io"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/meskio/epubgo"
|
"github.com/meskio/epubgo"
|
||||||
"gitlab.com/trantor/trantor/lib/database"
|
"gitlab.com/trantor/trantor/lib/database"
|
||||||
|
@ -41,6 +42,19 @@ func uploadWorker(database database.DB, store storage.Store) {
|
||||||
func (req uploadRequest) processFile(db database.DB, store storage.Store) {
|
func (req uploadRequest) processFile(db database.DB, store storage.Store) {
|
||||||
defer req.file.Close()
|
defer req.file.Close()
|
||||||
|
|
||||||
|
h := sha256.New()
|
||||||
|
if _, err := io.Copy(h, req.file); err != nil {
|
||||||
|
log.Warn("Can't read uploaded file ", req.header.Filename, ": ", err)
|
||||||
|
db.UpdateSubmission(req.id, "There was a problem with the uploaded book, try again later.", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fileHash := h.Sum(nil)
|
||||||
|
if db.ExistsBookHash(fileHash) {
|
||||||
|
log.Info("Uploaded file ", req.header.Filename, " already in the library.")
|
||||||
|
db.UpdateSubmission(req.id, "The uploaded book is already in the library (it could be in the moderation queue)", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
epub, err := epubgo.Load(req.file, req.header.Size)
|
epub, err := epubgo.Load(req.file, req.header.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Not valid epub uploaded file ", req.header.Filename, ": ", err)
|
log.Warn("Not valid epub uploaded file ", req.header.Filename, ": ", err)
|
||||||
|
@ -61,6 +75,7 @@ func (req uploadRequest) processFile(db database.DB, store storage.Store) {
|
||||||
}
|
}
|
||||||
|
|
||||||
book.FileSize = int(size)
|
book.FileSize = int(size)
|
||||||
|
book.FileHash = fileHash
|
||||||
book.Cover = GetCover(epub, book.ID, store)
|
book.Cover = GetCover(epub, book.ID, store)
|
||||||
|
|
||||||
err = db.AddBook(book)
|
err = db.AddBook(book)
|
||||||
|
|
Reference in a new issue