Add bad quality flag
This commit is contained in:
parent
45efecbfc8
commit
f5363e17bc
6 changed files with 97 additions and 10 deletions
|
@ -36,6 +36,7 @@ type Book struct {
|
||||||
FileSize int
|
FileSize int
|
||||||
Cover bool
|
Cover bool
|
||||||
Active bool
|
Active bool
|
||||||
|
BadQuality int `bad_quality`
|
||||||
Keywords []string
|
Keywords []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +51,10 @@ func indexBooks(coll *mgo.Collection) {
|
||||||
Key: []string{"active", "-_id"},
|
Key: []string{"active", "-_id"},
|
||||||
Background: true,
|
Background: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Key: []string{"active", "-bad_quality", "-_id"},
|
||||||
|
Background: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, k := range []string{"keywords", "lang", "title", "author", "subject"} {
|
for _, k := range []string{"keywords", "lang", "title", "author", "subject"} {
|
||||||
idx := mgo.Index{
|
idx := mgo.Index{
|
||||||
|
@ -81,7 +86,13 @@ func getNewBooks(coll *mgo.Collection, length int, start int) (books []Book, num
|
||||||
}
|
}
|
||||||
|
|
||||||
func _getBooks(coll *mgo.Collection, query bson.M, length int, start int) (books []Book, num int, err error) {
|
func _getBooks(coll *mgo.Collection, query bson.M, length int, start int) (books []Book, num int, err error) {
|
||||||
q := coll.Find(query).Sort("-_id")
|
sort := []string{}
|
||||||
|
if _, present := query["bad_quality"]; present {
|
||||||
|
sort = append(sort, "-bad_quality")
|
||||||
|
}
|
||||||
|
sort = append(sort, "-_id")
|
||||||
|
|
||||||
|
q := coll.Find(query).Sort(sort...)
|
||||||
num, err = q.Count()
|
num, err = q.Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -121,6 +132,10 @@ func updateBook(coll *mgo.Collection, id string, data map[string]interface{}) er
|
||||||
return coll.Update(bson.M{"id": id}, bson.M{"$set": data})
|
return coll.Update(bson.M{"id": id}, bson.M{"$set": data})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flagBadQuality(coll *mgo.Collection, id string) error {
|
||||||
|
return coll.Update(bson.M{"id": id}, bson.M{"$inc": bson.M{"bad_quality": 1}})
|
||||||
|
}
|
||||||
|
|
||||||
func activeBook(coll *mgo.Collection, id string) error {
|
func activeBook(coll *mgo.Collection, id string) error {
|
||||||
data := map[string]interface{}{"active": true}
|
data := map[string]interface{}{"active": true}
|
||||||
return coll.Update(bson.M{"id": id}, bson.M{"$set": data})
|
return coll.Update(bson.M{"id": id}, bson.M{"$set": data})
|
||||||
|
@ -142,7 +157,11 @@ func buildQuery(q string) bson.M {
|
||||||
for _, w := range words {
|
for _, w := range words {
|
||||||
tag := strings.SplitN(w, ":", 2)
|
tag := strings.SplitN(w, ":", 2)
|
||||||
if len(tag) > 1 {
|
if len(tag) > 1 {
|
||||||
query[tag[0]] = bson.RegEx{tag[1], "i"}
|
if tag[0] == "flag" {
|
||||||
|
query[tag[1]] = bson.M{"$gt": 0}
|
||||||
|
} else {
|
||||||
|
query[tag[0]] = bson.RegEx{tag[1], "i"} //FIXME: this should be a list
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toks := tokens(w)
|
toks := tokens(w)
|
||||||
keywords = append(keywords, toks...)
|
keywords = append(keywords, toks...)
|
||||||
|
|
|
@ -77,9 +77,55 @@ func TestUpdateBookKeywords(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFlag(t *testing.T) {
|
||||||
|
db := Init(test_host, test_coll)
|
||||||
|
defer db.del()
|
||||||
|
|
||||||
|
tAddBook(t, db)
|
||||||
|
id, _ := book["id"].(string)
|
||||||
|
db.ActiveBook(id)
|
||||||
|
id2 := "tfgrBvd2ps_K4iYt"
|
||||||
|
b2 := book
|
||||||
|
b2["id"] = id2
|
||||||
|
err := db.AddBook(b2)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("db.AddBook(", book, ") return an error:", err)
|
||||||
|
}
|
||||||
|
db.ActiveBook(id2)
|
||||||
|
id3 := "tfgrBvd2ps_K4iY2"
|
||||||
|
b3 := book
|
||||||
|
b3["id"] = id3
|
||||||
|
err = db.AddBook(b3)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("db.AddBook(", book, ") return an error:", err)
|
||||||
|
}
|
||||||
|
db.ActiveBook(id3)
|
||||||
|
|
||||||
|
db.FlagBadQuality(id)
|
||||||
|
db.FlagBadQuality(id)
|
||||||
|
db.FlagBadQuality(id3)
|
||||||
|
|
||||||
|
b, _ := db.GetBookId(id)
|
||||||
|
if b.BadQuality != 2 {
|
||||||
|
t.Error("The bad quality flag was not increased")
|
||||||
|
}
|
||||||
|
b, _ = db.GetBookId(id3)
|
||||||
|
if b.BadQuality != 1 {
|
||||||
|
t.Error("The bad quality flag was not increased")
|
||||||
|
}
|
||||||
|
|
||||||
|
books, _, _ := db.GetBooks("flag:bad_quality", 2, 0)
|
||||||
|
if len(books) != 2 {
|
||||||
|
t.Fatal("Not the right number of results to the flag search:", len(books))
|
||||||
|
}
|
||||||
|
if books[0].Id != id {
|
||||||
|
t.Error("Search for flag bad_quality is not sort right")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func tAddBook(t *testing.T, db *DB) {
|
func tAddBook(t *testing.T, db *DB) {
|
||||||
err := db.AddBook(book)
|
err := db.AddBook(book)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("db.AddBook(", book, ") return an error: ", err)
|
t.Error("db.AddBook(", book, ") return an error:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,11 @@ func (db *DB) UpdateBook(id string, data map[string]interface{}) error {
|
||||||
return updateBook(booksColl, id, data)
|
return updateBook(booksColl, id, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) FlagBadQuality(id string) error {
|
||||||
|
booksColl := db.session.DB(db.name).C(books_coll)
|
||||||
|
return flagBadQuality(booksColl, id)
|
||||||
|
}
|
||||||
|
|
||||||
func (db *DB) ActiveBook(id string) error {
|
func (db *DB) ActiveBook(id string) error {
|
||||||
booksColl := db.session.DB(db.name).C(books_coll)
|
booksColl := db.session.DB(db.name).C(books_coll)
|
||||||
return activeBook(booksColl, id)
|
return activeBook(booksColl, id)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
User-agent: *
|
User-agent: *
|
||||||
|
Disallow: /flag/
|
||||||
Disallow: /delete/
|
Disallow: /delete/
|
||||||
Disallow: /edit/
|
Disallow: /edit/
|
||||||
Disallow: /save/
|
Disallow: /save/
|
||||||
|
|
|
@ -25,7 +25,7 @@ function delBook(){
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{if .Cover}}
|
{{if .Cover}}
|
||||||
<div class="span4">
|
<div class="span4">
|
||||||
<img src="/cover/{{.Id}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="pull-right" />
|
<img src="/cover/{{.Id}}/big/{{.Title}}.jpg" alt="{{.Title}}" class="pull-right" />
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
@ -43,20 +43,24 @@ function delBook(){
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="span3">
|
<div class="span3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="btn-group pull-right">
|
||||||
|
<a href="/download/{{.Id}}/{{.Title}}.epub" class="btn btn-large btn-inverse"><i class="icon-download-alt icon-white"></i> download</a>
|
||||||
|
<a href="/read/{{.Id}}" class="btn btn-large btn-warning"><i class="icon-eye-open icon-white"></i> read it!</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{if $isAdmin}}
|
{{if $isAdmin}}
|
||||||
|
<div class="row"><p></p></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<a href="/edit/{{.Id}}" class="btn btn-primary"><i class="icon-pencil"></i> Edit</a>
|
<a href="/edit/{{.Id}}" class="btn btn-primary"><i class="icon-pencil"></i> Edit</a>
|
||||||
<a href="#" onClick="delBook();" class="btn btn-danger"><i class="icon-trash"></i> Delete</a>
|
<a href="#" onClick="delBook();" class="btn btn-danger"><i class="icon-trash"></i> Delete</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row"><p></p></div>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="row">
|
<div class="pull-right">
|
||||||
<div class="btn-group pull-right">
|
<br />
|
||||||
<a href="/download/{{.Id}}/{{.Title}}.epub" class="btn btn-large btn-inverse"><i class="icon-download-alt icon-white"></i> download</a>
|
<a href="/flag/bad_quality/{{.Id}}" class="btn btn-small"><i class="icon-warning-sign"></i> Report bad quality</a>
|
||||||
<a href="/read/{{.Id}}" class="btn btn-large btn-warning"><i class="icon-eye-open icon-white"></i> read it!</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
12
trantor.go
12
trantor.go
|
@ -88,6 +88,17 @@ func downloadHandler(h handler) {
|
||||||
io.Copy(h.w, f)
|
io.Copy(h.w, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flagHandler(h handler) {
|
||||||
|
id := mux.Vars(h.r)["id"]
|
||||||
|
err := h.db.FlagBadQuality(id)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("An error ocurred while flaging ", id, ": ", err)
|
||||||
|
}
|
||||||
|
h.sess.Notify("Flagged!", "Book marked as bad quality, thank you", "success")
|
||||||
|
h.sess.Save(h.w, h.r)
|
||||||
|
http.Redirect(h.w, h.r, h.r.Referer(), http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
type indexData struct {
|
type indexData struct {
|
||||||
S Status
|
S Status
|
||||||
Books []database.Book
|
Books []database.Book
|
||||||
|
@ -176,6 +187,7 @@ func initRouter(db *database.DB, sg *StatsGatherer) {
|
||||||
r.HandleFunc("/download/{id:"+id_pattern+"}/{epub:.*}", sg.Gather(downloadHandler))
|
r.HandleFunc("/download/{id:"+id_pattern+"}/{epub:.*}", sg.Gather(downloadHandler))
|
||||||
r.HandleFunc("/cover/{id:"+id_pattern+"}/{size}/{img:.*}", sg.Gather(coverHandler))
|
r.HandleFunc("/cover/{id:"+id_pattern+"}/{size}/{img:.*}", sg.Gather(coverHandler))
|
||||||
r.HandleFunc("/stats/", sg.Gather(statsHandler))
|
r.HandleFunc("/stats/", sg.Gather(statsHandler))
|
||||||
|
r.HandleFunc("/flag/bad_quality/{id:"+id_pattern+"}", sg.Gather(flagHandler))
|
||||||
|
|
||||||
r.HandleFunc("/login/", sg.Gather(loginHandler)).Methods("GET")
|
r.HandleFunc("/login/", sg.Gather(loginHandler)).Methods("GET")
|
||||||
r.HandleFunc("/login/", sg.Gather(loginPostHandler)).Methods("POST")
|
r.HandleFunc("/login/", sg.Gather(loginPostHandler)).Methods("POST")
|
||||||
|
|
Reference in a new issue