Add hashes for each book

Check if the uploaded book is already in the library
This commit is contained in:
Las Zenow 2020-05-03 09:35:17 +00:00
parent 154867c50c
commit a1ee320eba
4 changed files with 41 additions and 5 deletions

View file

@ -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

View file

@ -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);

View file

@ -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")
} }

View file

@ -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)