GraphQL API and utilities for the rpdata project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

207 lines
5.2 KiB

package services
import (
"context"
"errors"
"git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changekeys"
"git.aiterp.net/rpdata/api/models/changes"
"git.aiterp.net/rpdata/api/repositories"
"git.aiterp.net/rpdata/api/services/loaders"
"sort"
"strings"
)
type CharacterService struct {
characters repositories.CharacterRepository
loader *loaders.CharacterLoader
}
// Find uses the loader to find the character by the ID.
func (s *CharacterService) Find(ctx context.Context, id string) (*models.Character, error) {
return s.loader.Load(id)
}
// Find uses the loader to find the character by the ID.
func (s *CharacterService) FindNick(ctx context.Context, nick string) (*models.Character, error) {
return s.characters.FindNick(ctx, nick)
}
// List lists the characters. If the only filter active is `IDs`, the loader is used to batch together requests.
func (s *CharacterService) List(ctx context.Context, filter models.CharacterFilter) ([]*models.Character, error) {
if len(filter.IDs) > 0 && len(filter.Names) == 0 && len(filter.Nicks) == 0 && filter.Author == nil && filter.Search == nil {
characters, errs := s.loader.LoadAll(filter.IDs)
if len(characters) == 0 && len(errs) > 0 {
if errs[0] == repositories.ErrNotFound {
return []*models.Character{}, nil
} else {
return nil, errs[0]
}
}
if err := ctx.Err(); err != nil {
return nil, err
}
var badIndices []int
for i, character := range characters {
if character == nil {
badIndices = append(badIndices, i-len(badIndices))
}
}
for _, index := range badIndices {
characters = append(characters[:index], characters[index+1:]...)
}
sort.Slice(characters, func(i, j int) bool {
return strings.Compare(characters[i].ID, characters[j].ID) < 0
})
return characters, nil
}
return s.characters.List(ctx, filter)
}
func (s *CharacterService) Create(ctx context.Context, nick, name, shortName, author, description string) (*models.Character, error) {
token := auth.TokenFromContext(ctx)
if token == nil {
return nil, auth.ErrUnauthenticated
}
if name == "" {
return nil, errors.New("Name cannot be empty")
}
if author == "" {
author = token.UserID
}
if shortName == "" {
split := strings.SplitN(name, " ", 2)
shortName = split[0]
}
character := &models.Character{
Name: name,
ShortName: shortName,
Author: author,
Nicks: []string{nick},
Description: description,
}
err := auth.CheckPermission(ctx, "add", character)
if err != nil {
return nil, err
}
character, err = s.characters.Insert(ctx, *character)
if err != nil {
return nil, err
}
//TODO: New change submit system
go changes.Submit("Character", "add", token.UserID, true, changekeys.Listed(character), character)
return character, nil
}
func (s *CharacterService) Update(ctx context.Context, id string, name, shortName, description *string) (*models.Character, error) {
character, err := s.characters.Find(ctx, id)
if err != nil {
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
character, err = s.characters.Update(ctx, *character, models.CharacterUpdate{
Name: name,
ShortName: shortName,
Description: description,
})
if err != nil {
return nil, err
}
s.loader.Clear(character.ID)
s.loader.Prime(character.ID, character)
//TODO: New change submit system
token := auth.TokenFromContext(ctx)
go changes.Submit("Character", "edit", token.UserID, true, changekeys.Listed(character), character)
return character, nil
}
func (s *CharacterService) AddNick(ctx context.Context, id string, nick string) (*models.Character, error) {
character, err := s.characters.Find(ctx, id)
if err != nil {
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
character, err = s.characters.AddNick(ctx, *character, nick)
if err != nil {
return nil, err
}
//TODO: New change submit system
token := auth.TokenFromContext(ctx)
go changes.Submit("Character", "edit", token.UserID, true, changekeys.Listed(character), character)
return character, nil
}
func (s *CharacterService) RemoveNick(ctx context.Context, id string, nick string) (*models.Character, error) {
character, err := s.characters.Find(ctx, id)
if err != nil {
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
character, err = s.characters.RemoveNick(ctx, *character, nick)
if err != nil {
return nil, err
}
//TODO: New change submit system
token := auth.TokenFromContext(ctx)
go changes.Submit("Character", "edit", token.UserID, true, changekeys.Listed(character), character)
return character, nil
}
func (s *CharacterService) Delete(ctx context.Context, id string) (*models.Character, error) {
character, err := s.characters.Find(ctx, id)
if err != nil {
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
err = s.characters.Delete(ctx, *character)
if err != nil {
return nil, err
}
//TODO: New change submit system
token := auth.TokenFromContext(ctx)
go changes.Submit("Character", "remove", token.UserID, true, changekeys.Listed(character), character)
return character, nil
}