242 lines
4.9 KiB
Go
242 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"labix.org/v2/mgo"
|
|
"labix.org/v2/mgo/bson"
|
|
"time"
|
|
)
|
|
|
|
var db *DB
|
|
|
|
type Book struct {
|
|
Id string `bson:"_id"`
|
|
Title string
|
|
Author []string
|
|
Contributor string
|
|
Publisher string
|
|
Description string
|
|
Subject []string
|
|
Date string
|
|
Lang []string
|
|
Isbn string
|
|
Type string
|
|
Format string
|
|
Source string
|
|
Relation string
|
|
Coverage string
|
|
Rights string
|
|
Meta string
|
|
File bson.ObjectId
|
|
Cover bson.ObjectId
|
|
CoverSmall bson.ObjectId
|
|
Active bool
|
|
Keywords []string
|
|
}
|
|
|
|
type News struct {
|
|
Date time.Time
|
|
Text string
|
|
}
|
|
|
|
type DB struct {
|
|
session *mgo.Session
|
|
books *mgo.Collection
|
|
user *mgo.Collection
|
|
news *mgo.Collection
|
|
stats *mgo.Collection
|
|
mr *MR
|
|
}
|
|
|
|
func initDB() *DB {
|
|
var err error
|
|
d := new(DB)
|
|
d.session, err = mgo.Dial(DB_IP)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
database := d.session.DB(DB_NAME)
|
|
d.books = database.C(BOOKS_COLL)
|
|
d.user = database.C(USERS_COLL)
|
|
d.news = database.C(NEWS_COLL)
|
|
d.stats = database.C(STATS_COLL)
|
|
d.mr = NewMR(database)
|
|
return d
|
|
}
|
|
|
|
func (d *DB) Close() {
|
|
d.session.Close()
|
|
}
|
|
|
|
func md5Pass(pass string) []byte {
|
|
h := md5.New()
|
|
hash := h.Sum(([]byte)(PASS_SALT + pass))
|
|
return hash
|
|
}
|
|
|
|
func (d *DB) SetPassword(user string, pass string) error {
|
|
hash := md5Pass(pass)
|
|
return d.user.Update(bson.M{"user": user}, bson.M{"$set": bson.M{"pass": hash}})
|
|
}
|
|
|
|
func (d *DB) UserValid(user string, pass string) bool {
|
|
hash := md5Pass(pass)
|
|
n, err := d.user.Find(bson.M{"user": user, "pass": hash}).Count()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return n != 0
|
|
}
|
|
|
|
func (d *DB) UserRole(user string) string {
|
|
type result struct {
|
|
Role string
|
|
}
|
|
res := result{}
|
|
err := d.user.Find(bson.M{"user": user}).One(&res)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return res.Role
|
|
}
|
|
|
|
func (d *DB) AddNews(text string) error {
|
|
var news News
|
|
news.Text = text
|
|
news.Date = time.Now()
|
|
return d.news.Insert(news)
|
|
}
|
|
|
|
func (d *DB) GetNews(num int, days int) (news []News, err error) {
|
|
query := bson.M{}
|
|
if days != 0 {
|
|
duration := time.Duration(-24*days) * time.Hour
|
|
date := time.Now().Add(duration)
|
|
query = bson.M{"date": bson.M{"$gt": date}}
|
|
}
|
|
q := d.news.Find(query).Sort("-date").Limit(num)
|
|
err = q.All(&news)
|
|
return
|
|
}
|
|
|
|
func (d *DB) InsertStats(stats interface{}) error {
|
|
return d.stats.Insert(stats)
|
|
}
|
|
|
|
func (d *DB) InsertBook(book interface{}) error {
|
|
return d.books.Insert(book)
|
|
}
|
|
|
|
func (d *DB) RemoveBook(id bson.ObjectId) error {
|
|
return d.books.Remove(bson.M{"_id": id})
|
|
}
|
|
|
|
func (d *DB) UpdateBook(id bson.ObjectId, data interface{}) error {
|
|
return d.books.Update(bson.M{"_id": id}, bson.M{"$set": data})
|
|
}
|
|
|
|
/* optional parameters: length and start index
|
|
*
|
|
* Returns: list of books, number found and err
|
|
*/
|
|
func (d *DB) GetBooks(query bson.M, r ...int) (books []Book, num int, err error) {
|
|
var start, length int
|
|
if len(r) > 0 {
|
|
length = r[0]
|
|
if len(r) > 1 {
|
|
start = r[1]
|
|
}
|
|
}
|
|
q := d.books.Find(query).Sort("-_id")
|
|
num, err = q.Count()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if start != 0 {
|
|
q = q.Skip(start)
|
|
}
|
|
if length != 0 {
|
|
q = q.Limit(length)
|
|
}
|
|
|
|
err = q.All(&books)
|
|
for i, b := range books {
|
|
books[i].Id = bson.ObjectId(b.Id).Hex()
|
|
}
|
|
return
|
|
}
|
|
|
|
/* Get the most visited books
|
|
*/
|
|
func (d *DB) GetVisitedBooks(num int) (books []Book, err error) {
|
|
bookId, err := d.mr.GetMostVisited(num, d.stats)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
books = make([]Book, num)
|
|
for i, id := range bookId {
|
|
d.books.Find(bson.M{"_id": id}).One(&books[i])
|
|
books[i].Id = bson.ObjectId(books[i].Id).Hex()
|
|
}
|
|
return
|
|
}
|
|
|
|
/* Get the most downloaded books
|
|
*/
|
|
func (d *DB) GetDownloadedBooks(num int) (books []Book, err error) {
|
|
bookId, err := d.mr.GetMostDownloaded(num, d.stats)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
books = make([]Book, num)
|
|
for i, id := range bookId {
|
|
d.books.Find(bson.M{"_id": id}).One(&books[i])
|
|
books[i].Id = bson.ObjectId(books[i].Id).Hex()
|
|
}
|
|
return
|
|
}
|
|
|
|
/* optional parameters: length and start index
|
|
*
|
|
* Returns: list of books, number found and err
|
|
*/
|
|
func (d *DB) GetNewBooks(r ...int) (books []Book, num int, err error) {
|
|
return d.GetBooks(bson.M{"$nor": []bson.M{{"active": true}}}, r...)
|
|
}
|
|
|
|
func (d *DB) BookActive(id bson.ObjectId) bool {
|
|
var book Book
|
|
err := d.books.Find(bson.M{"_id": id}).One(&book)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return book.Active
|
|
}
|
|
|
|
func (d *DB) GetFS(prefix string) *mgo.GridFS {
|
|
return d.session.DB(DB_NAME).GridFS(prefix)
|
|
}
|
|
|
|
func (d *DB) GetTags(numTags int) ([]string, error) {
|
|
return d.mr.GetTags(numTags, d.books)
|
|
}
|
|
|
|
type Visits struct {
|
|
Date int64 "_id"
|
|
Count int "value"
|
|
}
|
|
|
|
func (d *DB) GetHourVisits(start time.Time) ([]Visits, error) {
|
|
return d.mr.GetHourVisits(start, d.stats)
|
|
}
|
|
|
|
func (d *DB) GetDayVisits(start time.Time) ([]Visits, error) {
|
|
return d.mr.GetDayVisits(start, d.stats)
|
|
}
|
|
|
|
func (d *DB) GetMonthVisits(start time.Time) ([]Visits, error) {
|
|
return d.mr.GetMonthVisits(start, d.stats)
|
|
}
|