128 lines
2.6 KiB
Go

package arn
import (
"sort"
"sync"
"github.com/aerogo/nano"
)
// AnimeRelations is a list of relations for an anime.
type AnimeRelations struct {
AnimeID AnimeID `json:"animeId" primary:"true"`
Items []*AnimeRelation `json:"items" editable:"true"`
sync.Mutex
}
// Link returns the link for that object.
func (relations *AnimeRelations) Link() string {
return "/anime/" + relations.AnimeID + "/relations"
}
// SortByStartDate ...
func (relations *AnimeRelations) SortByStartDate() {
relations.Lock()
defer relations.Unlock()
sort.Slice(relations.Items, func(i, j int) bool {
a := relations.Items[i].Anime()
b := relations.Items[j].Anime()
if a == nil {
return false
}
if b == nil {
return true
}
if a.StartDate == b.StartDate {
return a.Title.Canonical < b.Title.Canonical
}
return a.StartDate < b.StartDate
})
}
// Anime returns the anime the relations list refers to.
func (relations *AnimeRelations) Anime() *Anime {
anime, _ := GetAnime(relations.AnimeID)
return anime
}
// String implements the default string serialization.
func (relations *AnimeRelations) String() string {
return relations.Anime().String()
}
// GetID returns the anime ID.
func (relations *AnimeRelations) GetID() string {
return relations.AnimeID
}
// TypeName returns the type name.
func (relations *AnimeRelations) TypeName() string {
return "AnimeRelations"
}
// Self returns the object itself.
func (relations *AnimeRelations) Self() Loggable {
return relations
}
// Find returns the relation with the specified anime ID, if available.
func (relations *AnimeRelations) Find(animeID AnimeID) *AnimeRelation {
relations.Lock()
defer relations.Unlock()
for _, item := range relations.Items {
if item.AnimeID == animeID {
return item
}
}
return nil
}
// Remove removes the anime ID from the relations.
func (relations *AnimeRelations) Remove(animeID AnimeID) bool {
relations.Lock()
defer relations.Unlock()
for index, item := range relations.Items {
if item.AnimeID == animeID {
relations.Items = append(relations.Items[:index], relations.Items[index+1:]...)
return true
}
}
return false
}
// GetAnimeRelations ...
func GetAnimeRelations(animeID AnimeID) (*AnimeRelations, error) {
obj, err := DB.Get("AnimeRelations", animeID)
if err != nil {
return nil, err
}
return obj.(*AnimeRelations), nil
}
// StreamAnimeRelations returns a stream of all anime relations.
func StreamAnimeRelations() <-chan *AnimeRelations {
channel := make(chan *AnimeRelations, nano.ChannelBufferSize)
go func() {
for obj := range DB.All("AnimeRelations") {
channel <- obj.(*AnimeRelations)
}
close(channel)
}()
return channel
}