package arn import ( "errors" "fmt" "reflect" "github.com/aerogo/aero" "github.com/aerogo/api" ) // Force interface implementations var ( _ Likeable = (*Character)(nil) _ Publishable = (*Character)(nil) _ PostParent = (*Character)(nil) _ fmt.Stringer = (*Character)(nil) _ api.Newable = (*Character)(nil) _ api.Editable = (*Character)(nil) _ api.Deletable = (*Character)(nil) ) // Actions func init() { API.RegisterActions("Character", []*api.Action{ // Publish PublishAction(), // Unpublish UnpublishAction(), // Like character LikeAction(), // Unlike character UnlikeAction(), }) } // Create sets the data for a new character with data we received from the API request. func (character *Character) Create(ctx aero.Context) error { user := GetUserFromContext(ctx) if user == nil { return errors.New("Not logged in") } character.ID = GenerateID("Character") character.Created = DateTimeUTC() character.CreatedBy = user.ID // Write log entry logEntry := NewEditLogEntry(user.ID, "create", "Character", character.ID, "", "", "") logEntry.Save() return character.Unpublish() } // Authorize returns an error if the given API request is not authorized. func (character *Character) Authorize(ctx aero.Context, action string) error { user := GetUserFromContext(ctx) if user == nil { return errors.New("Not logged in") } // Allow custom actions (like, unlike) for normal users if action == "like" || action == "unlike" { return nil } if user.Role != "editor" && user.Role != "admin" { return errors.New("Insufficient permissions") } return nil } // Edit creates an edit log entry. func (character *Character) Edit(ctx aero.Context, key string, value reflect.Value, newValue reflect.Value) (consumed bool, err error) { return edit(character, ctx, key, value, newValue) } // OnAppend saves a log entry. func (character *Character) OnAppend(ctx aero.Context, key string, index int, obj interface{}) { onAppend(character, ctx, key, index, obj) } // OnRemove saves a log entry. func (character *Character) OnRemove(ctx aero.Context, key string, index int, obj interface{}) { onRemove(character, ctx, key, index, obj) } // DeleteInContext deletes the character in the given context. func (character *Character) DeleteInContext(ctx aero.Context) error { user := GetUserFromContext(ctx) // Write log entry logEntry := NewEditLogEntry(user.ID, "delete", "Character", character.ID, "", fmt.Sprint(character), "") logEntry.Save() return character.Delete() } // Delete deletes the object from the database. func (character *Character) Delete() error { if character.IsDraft { draftIndex := character.Creator().DraftIndex() draftIndex.CharacterID = "" draftIndex.Save() } // Delete from anime characters for list := range StreamAnimeCharacters() { list.Lock() for index, animeCharacter := range list.Items { if animeCharacter.CharacterID == character.ID { list.Items = append(list.Items[:index], list.Items[index+1:]...) list.Save() break } } list.Unlock() } // Delete from quotes for quote := range StreamQuotes() { if quote.CharacterID == character.ID { err := quote.Delete() if err != nil { return err } } } // Delete image files character.DeleteImages() // Delete character DB.Delete("Character", character.ID) return nil } // Save saves the character in the database. func (character *Character) Save() { DB.Set("Character", character.ID, character) }