Browse Source

graph2: Added logging changes for Channel, Log, Post and Character.

1.0
Gisle Aune 6 years ago
parent
commit
34f86d5037
  1. 19
      graph2/queries/channel.go
  2. 48
      graph2/queries/character.go
  3. 28
      graph2/queries/log.go
  4. 32
      graph2/queries/post.go
  5. 33
      models/change.go
  6. 31
      models/changes/db.go
  7. 48
      models/changes/submit.go

19
graph2/queries/channel.go

@ -7,6 +7,7 @@ import (
"git.aiterp.net/rpdata/api/graph2/input" "git.aiterp.net/rpdata/api/graph2/input"
"git.aiterp.net/rpdata/api/internal/auth" "git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/models" "git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changes"
"git.aiterp.net/rpdata/api/models/channels" "git.aiterp.net/rpdata/api/models/channels"
) )
@ -45,7 +46,14 @@ func (r *mutationResolver) AddChannel(ctx context.Context, input input.ChannelAd
locationName = *input.LocationName locationName = *input.LocationName
} }
return channels.Add(input.Name, logged, hub, eventName, locationName)
channel, err := channels.Add(input.Name, logged, hub, eventName, locationName)
if err != nil {
return models.Channel{}, errors.New("Failed to add channel: " + err.Error())
}
go changes.Submit("Channel", "add", token.UserID, channel)
return channel, nil
} }
func (r *mutationResolver) EditChannel(ctx context.Context, input input.ChannelEditInput) (models.Channel, error) { func (r *mutationResolver) EditChannel(ctx context.Context, input input.ChannelEditInput) (models.Channel, error) {
@ -59,5 +67,12 @@ func (r *mutationResolver) EditChannel(ctx context.Context, input input.ChannelE
return models.Channel{}, errors.New("Channel not found") return models.Channel{}, errors.New("Channel not found")
} }
return channels.Edit(channel, input.Logged, input.Hub, input.EventName, input.LocationName)
channel, err = channels.Edit(channel, input.Logged, input.Hub, input.EventName, input.LocationName)
if err != nil {
return models.Channel{}, errors.New("Failed to edit channel: " + err.Error())
}
go changes.Submit("Channel", "edit", token.UserID, channel)
return channel, nil
} }

48
graph2/queries/character.go

@ -8,6 +8,7 @@ import (
"git.aiterp.net/rpdata/api/graph2/input" "git.aiterp.net/rpdata/api/graph2/input"
"git.aiterp.net/rpdata/api/internal/auth" "git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/models" "git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changes"
"git.aiterp.net/rpdata/api/models/characters" "git.aiterp.net/rpdata/api/models/characters"
"git.aiterp.net/rpdata/api/models/logs" "git.aiterp.net/rpdata/api/models/logs"
) )
@ -62,7 +63,14 @@ func (r *mutationResolver) AddCharacter(ctx context.Context, input input.Charact
logs.ScheduleFullUpdate() logs.ScheduleFullUpdate()
return characters.Add(input.Nick, input.Name, shortName, author, description)
character, err := characters.Add(input.Nick, input.Name, shortName, author, description)
if err != nil {
return models.Character{}, errors.New("Adding character failed: " + err.Error())
}
go changes.Submit("Character", "add", token.UserID, character)
return character, nil
} }
func (r *mutationResolver) AddCharacterNick(ctx context.Context, input input.CharacterNickInput) (models.Character, error) { func (r *mutationResolver) AddCharacterNick(ctx context.Context, input input.CharacterNickInput) (models.Character, error) {
@ -82,7 +90,15 @@ func (r *mutationResolver) AddCharacterNick(ctx context.Context, input input.Cha
logs.ScheduleFullUpdate() logs.ScheduleFullUpdate()
return characters.AddNick(character, input.Nick)
character, err = characters.AddNick(character, input.Nick)
if err != nil {
return models.Character{}, errors.New("Failed to add nick: " + err.Error())
}
go logs.ScheduleFullUpdate()
go changes.Submit("Character", "edit", token.UserID, character)
return character, nil
} }
func (r *mutationResolver) RemoveCharacterNick(ctx context.Context, input input.CharacterNickInput) (models.Character, error) { func (r *mutationResolver) RemoveCharacterNick(ctx context.Context, input input.CharacterNickInput) (models.Character, error) {
@ -96,9 +112,15 @@ func (r *mutationResolver) RemoveCharacterNick(ctx context.Context, input input.
return models.Character{}, errors.New("You are not permitted to edit this character") return models.Character{}, errors.New("You are not permitted to edit this character")
} }
logs.ScheduleFullUpdate()
character, err = characters.RemoveNick(character, input.Nick)
if err != nil {
return models.Character{}, errors.New("Failed to remove nick: " + err.Error())
}
go logs.ScheduleFullUpdate()
go changes.Submit("Character", "edit", token.UserID, character)
return characters.RemoveNick(character, input.Nick)
return character, nil
} }
func (r *mutationResolver) EditCharacter(ctx context.Context, input input.CharacterEditInput) (models.Character, error) { func (r *mutationResolver) EditCharacter(ctx context.Context, input input.CharacterEditInput) (models.Character, error) {
@ -119,7 +141,14 @@ func (r *mutationResolver) EditCharacter(ctx context.Context, input input.Charac
return models.Character{}, errors.New("You are not permitted to edit this character") return models.Character{}, errors.New("You are not permitted to edit this character")
} }
return characters.Edit(character, input.Name, input.ShortName, input.Description)
character, err = characters.Edit(character, input.Name, input.ShortName, input.Description)
if err != nil {
return models.Character{}, errors.New("Failed to edit character: " + err.Error())
}
go changes.Submit("Character", "edit", token.UserID, character)
return character, nil
} }
func (r *mutationResolver) RemoveCharacter(ctx context.Context, input input.CharacterRemoveInput) (models.Character, error) { func (r *mutationResolver) RemoveCharacter(ctx context.Context, input input.CharacterRemoveInput) (models.Character, error) {
@ -133,5 +162,12 @@ func (r *mutationResolver) RemoveCharacter(ctx context.Context, input input.Char
return models.Character{}, errors.New("You are not permitted to remove this character") return models.Character{}, errors.New("You are not permitted to remove this character")
} }
return characters.Remove(character)
character, err = characters.Remove(character)
if err != nil {
return models.Character{}, errors.New("Failed to remove character: " + err.Error())
}
go changes.Submit("Character", "remove", token.UserID, character)
return character, nil
} }

28
graph2/queries/log.go

@ -9,6 +9,7 @@ import (
"git.aiterp.net/rpdata/api/internal/auth" "git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/internal/loader" "git.aiterp.net/rpdata/api/internal/loader"
"git.aiterp.net/rpdata/api/models" "git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changes"
"git.aiterp.net/rpdata/api/models/logs" "git.aiterp.net/rpdata/api/models/logs"
"github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql"
) )
@ -71,7 +72,14 @@ func (r *mutationResolver) AddLog(ctx context.Context, input input.LogAddInput)
description = *input.Description description = *input.Description
} }
return logs.Add(input.Date, input.Channel, title, event, description, open)
log, err := logs.Add(input.Date, input.Channel, title, event, description, open)
if !token.Authenticated() || !token.Permitted("log.add") {
return models.Log{}, errors.New("Failed to create log: " + err.Error())
}
go changes.Submit("Log", "add", token.UserID, log)
return log, nil
} }
func (r *mutationResolver) EditLog(ctx context.Context, input input.LogEditInput) (models.Log, error) { func (r *mutationResolver) EditLog(ctx context.Context, input input.LogEditInput) (models.Log, error) {
@ -85,7 +93,14 @@ func (r *mutationResolver) EditLog(ctx context.Context, input input.LogEditInput
return models.Log{}, errors.New("Log not found") return models.Log{}, errors.New("Log not found")
} }
return logs.Edit(log, input.Title, input.Event, input.Description, input.Open)
log, err = logs.Edit(log, input.Title, input.Event, input.Description, input.Open)
if err != nil {
return models.Log{}, errors.New("Failed to edit log: " + err.Error())
}
go changes.Submit("Log", "edit", token.UserID, log)
return log, nil
} }
func (r *mutationResolver) RemoveLog(ctx context.Context, input input.LogRemoveInput) (models.Log, error) { func (r *mutationResolver) RemoveLog(ctx context.Context, input input.LogRemoveInput) (models.Log, error) {
@ -99,5 +114,12 @@ func (r *mutationResolver) RemoveLog(ctx context.Context, input input.LogRemoveI
return models.Log{}, errors.New("Log not found") return models.Log{}, errors.New("Log not found")
} }
return logs.Remove(log)
log, err = logs.Remove(log)
if err != nil {
return models.Log{}, errors.New("Failed to remove log: " + err.Error())
}
go changes.Submit("Log", "remove", token.UserID, log)
return log, nil
} }

32
graph2/queries/post.go

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"git.aiterp.net/rpdata/api/models/changes"
"git.aiterp.net/rpdata/api/models/logs" "git.aiterp.net/rpdata/api/models/logs"
"git.aiterp.net/rpdata/api/graph2/input" "git.aiterp.net/rpdata/api/graph2/input"
@ -58,6 +59,7 @@ func (r *mutationResolver) AddPost(ctx context.Context, input input.PostAddInput
} }
go logs.UpdateCharacters(log) go logs.UpdateCharacters(log)
go changes.Submit("Post", "add", token.UserID, post)
return post, nil return post, nil
} }
@ -84,7 +86,14 @@ func (r *mutationResolver) EditPost(ctx context.Context, input input.PostEditInp
}() }()
} }
return posts.Edit(post, input.Time, input.Kind, input.Nick, input.Text)
post, err = posts.Edit(post, input.Time, input.Kind, input.Nick, input.Text)
if err != nil {
return models.Post{}, errors.New("Adding post failed: " + err.Error())
}
go changes.Submit("Post", "edit", token.UserID, post)
return post, nil
} }
func (r *mutationResolver) MovePost(ctx context.Context, input input.PostMoveInput) ([]models.Post, error) { func (r *mutationResolver) MovePost(ctx context.Context, input input.PostMoveInput) ([]models.Post, error) {
@ -98,7 +107,18 @@ func (r *mutationResolver) MovePost(ctx context.Context, input input.PostMoveInp
return nil, errors.New("Post not found") return nil, errors.New("Post not found")
} }
return posts.Move(post, input.ToPosition)
posts, err := posts.Move(post, input.ToPosition)
if err != nil {
return nil, errors.New("Moving posts failed: " + err.Error())
}
posts2 := make([]interface{}, len(posts))
for i := range posts {
posts2[i] = posts[i]
}
go changes.Submit("Post", "move", token.UserID, posts2...)
return posts, nil
} }
func (r *mutationResolver) RemovePost(ctx context.Context, input input.PostRemoveInput) (models.Post, error) { func (r *mutationResolver) RemovePost(ctx context.Context, input input.PostRemoveInput) (models.Post, error) {
@ -112,6 +132,11 @@ func (r *mutationResolver) RemovePost(ctx context.Context, input input.PostRemov
return models.Post{}, errors.New("Post not found (before removing, of course)") return models.Post{}, errors.New("Post not found (before removing, of course)")
} }
post, err = posts.Remove(post)
if err != nil {
return models.Post{}, errors.New("Could not remove post: " + err.Error())
}
go func() { go func() {
log, err := logs.FindID(post.LogID) log, err := logs.FindID(post.LogID)
if err != nil { if err != nil {
@ -120,6 +145,7 @@ func (r *mutationResolver) RemovePost(ctx context.Context, input input.PostRemov
logs.UpdateCharacters(log) logs.UpdateCharacters(log)
}() }()
go changes.Submit("Post", "remove", token.UserID, post)
return posts.Remove(post)
return post, nil
} }

33
models/change.go

@ -0,0 +1,33 @@
package models
import "time"
// Change represents a change in the rpdata history through the API.
type Change struct {
ID string `bson:"_id"`
Model string `bson:"model"`
Op string `bson:"op"`
Author string `bson:"author"`
Date time.Time `bson:"date"`
Logs []Log `bson:"logs"`
Characters []Character `bson:"characters"`
Posts []Post `bson:"posts"`
}
// Data makes a combined, mixed array of all the models stored in this change.
func (change *Change) Data() []interface{} {
data := make([]interface{}, 0, len(change.Logs)+len(change.Characters)+len(change.Posts))
for _, log := range change.Logs {
data = append(data, log)
}
for _, character := range change.Characters {
data = append(data, character)
}
for _, post := range change.Posts {
data = append(data, post)
}
return data
}

31
models/changes/db.go

@ -0,0 +1,31 @@
package changes
import (
"log"
"sync"
"time"
"git.aiterp.net/rpdata/api/internal/store"
"github.com/globalsign/mgo"
)
var collection *mgo.Collection
var submitMutex sync.Mutex
func init() {
store.HandleInit(func(db *mgo.Database) {
collection = db.C("common.changes")
collection.EnsureIndexKey("date")
collection.EnsureIndexKey("author")
err := collection.EnsureIndex(mgo.Index{
Name: "expiry",
Key: []string{"date"},
ExpireAfter: time.Hour * 2400, // 100 days
})
if err != nil {
log.Fatalln(err)
}
})
}

48
models/changes/submit.go

@ -0,0 +1,48 @@
package changes
import (
"strconv"
"time"
"git.aiterp.net/rpdata/api/internal/counter"
"git.aiterp.net/rpdata/api/models"
)
// Submit a change to the database
func Submit(model, op, author string, objects ...interface{}) (models.Change, error) {
submitMutex.Lock()
defer submitMutex.Unlock()
id, err := counter.Next("auto_increment", "Change")
if err != nil {
return models.Change{}, err
}
change := models.Change{
ID: "Change_" + strconv.Itoa(id),
Model: model,
Date: time.Now(),
Op: op,
Author: author,
}
for _, object := range objects {
switch object := object.(type) {
case models.Log:
change.Logs = append(change.Logs, object)
case models.Character:
change.Characters = append(change.Characters, object)
case models.Post:
change.Posts = append(change.Posts, object)
}
}
// TODO: Push to subscribers
err = collection.Insert(&change)
if err != nil {
return models.Change{}, err
}
return change, nil
}
Loading…
Cancel
Save