+122
-6
@@ -1,6 +1,9 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Change represents a change in the rpdata history through the API.
|
||||
type Change struct {
|
||||
@@ -22,15 +25,55 @@ type Change struct {
|
||||
Comments []Comment `bson:"comments"`
|
||||
}
|
||||
|
||||
// ChangeKey is a key for a change that can be used when subscribing to them.
|
||||
type ChangeKey struct {
|
||||
Model ChangeModel `bson:"model"`
|
||||
ID string `bson:"id"`
|
||||
// AddObject adds the model into the appropriate array.
|
||||
func (change *Change) AddObject(object interface{}) bool {
|
||||
if v := reflect.ValueOf(object); v.Kind() == reflect.Ptr {
|
||||
return change.AddObject(v.Elem().Interface())
|
||||
}
|
||||
|
||||
switch object := object.(type) {
|
||||
case Log:
|
||||
change.Logs = append(change.Logs, object)
|
||||
case []Log:
|
||||
change.Logs = append(change.Logs, object...)
|
||||
case Character:
|
||||
change.Characters = append(change.Characters, object)
|
||||
case []Character:
|
||||
change.Characters = append(change.Characters, object...)
|
||||
case Channel:
|
||||
change.Channels = append(change.Channels, object)
|
||||
case []Channel:
|
||||
change.Channels = append(change.Channels, object...)
|
||||
case Post:
|
||||
change.Posts = append(change.Posts, object)
|
||||
case []Post:
|
||||
change.Posts = append(change.Posts, object...)
|
||||
case Story:
|
||||
change.Stories = append(change.Stories, object)
|
||||
case []Story:
|
||||
change.Stories = append(change.Stories, object...)
|
||||
case Tag:
|
||||
change.Tags = append(change.Tags, object)
|
||||
case []Tag:
|
||||
change.Tags = append(change.Tags, object...)
|
||||
case Chapter:
|
||||
change.Chapters = append(change.Chapters, object)
|
||||
case []Chapter:
|
||||
change.Chapters = append(change.Chapters, object...)
|
||||
case Comment:
|
||||
change.Comments = append(change.Comments, object)
|
||||
case []Comment:
|
||||
change.Comments = append(change.Comments, object...)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Objects makes a combined, mixed array of all the models stored in this change.
|
||||
func (change *Change) Objects() []interface{} {
|
||||
data := make([]interface{}, 0, len(change.Logs)+len(change.Characters)+len(change.Channels)+len(change.Posts)+len(change.Stories)+len(change.Tags)+len(change.Chapters)+len(change.Comments))
|
||||
data := make([]interface{}, 0, 8)
|
||||
|
||||
for _, log := range change.Logs {
|
||||
data = append(data, &log)
|
||||
@@ -59,3 +102,76 @@ func (change *Change) Objects() []interface{} {
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func (change *Change) PassesFilter(filter ChangeFilter) bool {
|
||||
if filter.PassAll {
|
||||
return true
|
||||
}
|
||||
|
||||
if filter.Author != nil && change.Author != *filter.Author {
|
||||
return false
|
||||
}
|
||||
|
||||
// For unlisted changes, pass it only if the filter refers to the specific index.
|
||||
if !change.Listed {
|
||||
hasSpecificKey := false
|
||||
|
||||
KeyFindLoop:
|
||||
for _, key := range filter.Keys {
|
||||
if key.ID == "*" {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, changeKey := range change.Keys {
|
||||
if changeKey.Model == key.Model && changeKey.ID == key.ID {
|
||||
hasSpecificKey = true
|
||||
break KeyFindLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !hasSpecificKey {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if filter.EarliestDate != nil && filter.EarliestDate.Before(change.Date) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(filter.Keys) > 0 {
|
||||
foundKey := false
|
||||
|
||||
KeyFindLoop2:
|
||||
for _, key := range filter.Keys {
|
||||
for _, changeKey := range change.Keys {
|
||||
if changeKey == key {
|
||||
foundKey = true
|
||||
break KeyFindLoop2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !foundKey {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// ChangeKey is a key for a change that can be used when subscribing to them.
|
||||
type ChangeKey struct {
|
||||
Model ChangeModel `bson:"model"`
|
||||
ID string `bson:"id"`
|
||||
}
|
||||
|
||||
// ChangeFilter is a filter for listing changes.
|
||||
type ChangeFilter struct {
|
||||
Keys []ChangeKey
|
||||
EarliestDate *time.Time
|
||||
Author *string
|
||||
Limit *int
|
||||
|
||||
PassAll bool // DO NOT EXPOSE
|
||||
}
|
||||
|
||||
+1
-17
@@ -1,14 +1,11 @@
|
||||
package changes
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.aiterp.net/rpdata/api/internal/store"
|
||||
"git.aiterp.net/rpdata/api/models"
|
||||
"github.com/globalsign/mgo"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var collection *mgo.Collection
|
||||
@@ -24,18 +21,5 @@ func list(query bson.M, limit int) ([]models.Change, error) {
|
||||
func init() {
|
||||
store.HandleInit(func(db *mgo.Database) {
|
||||
collection = db.C("common.changes")
|
||||
|
||||
collection.EnsureIndexKey("date")
|
||||
collection.EnsureIndexKey("author")
|
||||
collection.EnsureIndexKey("keys")
|
||||
|
||||
err := collection.EnsureIndex(mgo.Index{
|
||||
Name: "expiry",
|
||||
Key: []string{"date"},
|
||||
ExpireAfter: time.Hour * 2400, // 100 days
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user