node build fixed
This commit is contained in:
235
seanime-2.9.10/internal/torrentstream/collection.go
Normal file
235
seanime-2.9.10/internal/torrentstream/collection.go
Normal file
@@ -0,0 +1,235 @@
|
||||
package torrentstream
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"seanime/internal/api/anilist"
|
||||
"seanime/internal/api/metadata"
|
||||
"seanime/internal/hook"
|
||||
"seanime/internal/library/anime"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type (
|
||||
// StreamCollection is used to "complete" the anime.LibraryCollection if the user chooses
|
||||
// to include torrent streams in the library view.
|
||||
StreamCollection struct {
|
||||
ContinueWatchingList []*anime.Episode `json:"continueWatchingList"`
|
||||
Anime []*anilist.BaseAnime `json:"anime"`
|
||||
ListData map[int]*anime.EntryListData `json:"listData"`
|
||||
}
|
||||
|
||||
HydrateStreamCollectionOptions struct {
|
||||
AnimeCollection *anilist.AnimeCollection
|
||||
LibraryCollection *anime.LibraryCollection
|
||||
MetadataProvider metadata.Provider
|
||||
}
|
||||
)
|
||||
|
||||
func (r *Repository) HydrateStreamCollection(opts *HydrateStreamCollectionOptions) {
|
||||
|
||||
reqEvent := new(anime.AnimeLibraryStreamCollectionRequestedEvent)
|
||||
reqEvent.AnimeCollection = opts.AnimeCollection
|
||||
reqEvent.LibraryCollection = opts.LibraryCollection
|
||||
err := hook.GlobalHookManager.OnAnimeLibraryStreamCollectionRequested().Trigger(reqEvent)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
opts.AnimeCollection = reqEvent.AnimeCollection
|
||||
opts.LibraryCollection = reqEvent.LibraryCollection
|
||||
|
||||
lists := opts.AnimeCollection.MediaListCollection.GetLists()
|
||||
// Get the anime that are currently being watched
|
||||
var currentlyWatching *anilist.AnimeCollection_MediaListCollection_Lists
|
||||
for _, list := range lists {
|
||||
if list.Status == nil {
|
||||
continue
|
||||
}
|
||||
if *list.Status == anilist.MediaListStatusCurrent {
|
||||
//currentlyWatching = list.CopyT()
|
||||
currentlyWatching = &anilist.AnimeCollection_MediaListCollection_Lists{
|
||||
Status: lo.ToPtr(anilist.MediaListStatusCurrent),
|
||||
Name: lo.ToPtr("CURRENT"),
|
||||
IsCustomList: lo.ToPtr(false),
|
||||
Entries: list.Entries,
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
for _, list := range lists {
|
||||
if list.Status == nil {
|
||||
continue
|
||||
}
|
||||
if *list.Status == anilist.MediaListStatusRepeating {
|
||||
if currentlyWatching == nil {
|
||||
currentlyWatching = list
|
||||
} else {
|
||||
for _, entry := range list.Entries {
|
||||
currentlyWatching.Entries = append(currentlyWatching.Entries, entry)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if currentlyWatching == nil {
|
||||
return
|
||||
}
|
||||
|
||||
ret := &StreamCollection{
|
||||
ContinueWatchingList: make([]*anime.Episode, 0),
|
||||
Anime: make([]*anilist.BaseAnime, 0),
|
||||
ListData: make(map[int]*anime.EntryListData),
|
||||
}
|
||||
|
||||
visitedMediaIds := make(map[int]struct{})
|
||||
|
||||
animeAdded := make(map[int]*anilist.AnimeListEntry)
|
||||
|
||||
// Go through each entry in the currently watching list
|
||||
wg := sync.WaitGroup{}
|
||||
mu := sync.Mutex{}
|
||||
wg.Add(len(currentlyWatching.Entries))
|
||||
for _, entry := range currentlyWatching.Entries {
|
||||
go func(entry *anilist.AnimeListEntry) {
|
||||
defer wg.Done()
|
||||
|
||||
mu.Lock()
|
||||
if _, found := visitedMediaIds[entry.GetMedia().GetID()]; found {
|
||||
mu.Unlock()
|
||||
return
|
||||
}
|
||||
// Get the next episode to watch
|
||||
// i.e. if the user has watched episode 1, the next episode to watch is 2
|
||||
nextEpisodeToWatch := entry.GetProgressSafe() + 1
|
||||
if nextEpisodeToWatch > entry.GetMedia().GetCurrentEpisodeCount() {
|
||||
mu.Unlock()
|
||||
return // Skip this entry if the user has watched all episodes
|
||||
}
|
||||
mediaId := entry.GetMedia().GetID()
|
||||
visitedMediaIds[mediaId] = struct{}{}
|
||||
mu.Unlock()
|
||||
// Check if the anime's "next episode to watch" is already in the library collection
|
||||
// If it is, we don't need to add it to the stream collection
|
||||
for _, libraryEp := range opts.LibraryCollection.ContinueWatchingList {
|
||||
if libraryEp.BaseAnime.ID == mediaId && libraryEp.GetProgressNumber() == nextEpisodeToWatch {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if *entry.GetMedia().GetStatus() == anilist.MediaStatusNotYetReleased {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the media info
|
||||
animeMetadata, err := opts.MetadataProvider.GetAnimeMetadata(metadata.AnilistPlatform, mediaId)
|
||||
if err != nil {
|
||||
r.logger.Error().Err(err).Msg("torrentstream: could not fetch AniDB media")
|
||||
return
|
||||
}
|
||||
|
||||
_, found := animeMetadata.FindEpisode(strconv.Itoa(nextEpisodeToWatch))
|
||||
//if !found {
|
||||
// r.logger.Error().Msg("torrentstream: could not find episode in AniDB")
|
||||
// return
|
||||
//}
|
||||
|
||||
progressOffset := 0
|
||||
anidbEpisode := strconv.Itoa(nextEpisodeToWatch)
|
||||
if anime.FindDiscrepancy(entry.GetMedia(), animeMetadata) == anime.DiscrepancyAniListCountsEpisodeZero {
|
||||
progressOffset = 1
|
||||
if nextEpisodeToWatch == 1 {
|
||||
anidbEpisode = "S1"
|
||||
}
|
||||
}
|
||||
|
||||
// Add the anime & episode
|
||||
episode := anime.NewEpisode(&anime.NewEpisodeOptions{
|
||||
LocalFile: nil,
|
||||
OptionalAniDBEpisode: anidbEpisode,
|
||||
AnimeMetadata: animeMetadata,
|
||||
Media: entry.GetMedia(),
|
||||
ProgressOffset: progressOffset,
|
||||
IsDownloaded: false,
|
||||
MetadataProvider: r.metadataProvider,
|
||||
})
|
||||
if !found {
|
||||
episode.EpisodeTitle = entry.GetMedia().GetPreferredTitle()
|
||||
episode.DisplayTitle = fmt.Sprintf("Episode %d", nextEpisodeToWatch)
|
||||
episode.ProgressNumber = nextEpisodeToWatch
|
||||
episode.EpisodeNumber = nextEpisodeToWatch
|
||||
episode.EpisodeMetadata = &anime.EpisodeMetadata{
|
||||
Image: entry.GetMedia().GetBannerImageSafe(),
|
||||
}
|
||||
}
|
||||
|
||||
if episode == nil {
|
||||
r.logger.Error().Msg("torrentstream: could not get anime entry episode")
|
||||
return
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
ret.ContinueWatchingList = append(ret.ContinueWatchingList, episode)
|
||||
animeAdded[mediaId] = entry
|
||||
mu.Unlock()
|
||||
}(entry)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
libraryAnimeMap := make(map[int]struct{})
|
||||
|
||||
// Remove anime that are already in the library collection
|
||||
for _, list := range opts.LibraryCollection.Lists {
|
||||
if list.Status == anilist.MediaListStatusCurrent {
|
||||
for _, entry := range list.Entries {
|
||||
libraryAnimeMap[entry.MediaId] = struct{}{}
|
||||
if _, found := animeAdded[entry.MediaId]; found {
|
||||
delete(animeAdded, entry.MediaId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, entry := range currentlyWatching.Entries {
|
||||
if _, found := libraryAnimeMap[entry.GetMedia().GetID()]; found {
|
||||
continue
|
||||
}
|
||||
if *entry.GetMedia().GetStatus() == anilist.MediaStatusNotYetReleased {
|
||||
continue
|
||||
}
|
||||
animeAdded[entry.GetMedia().GetID()] = entry
|
||||
}
|
||||
|
||||
for _, a := range animeAdded {
|
||||
ret.Anime = append(ret.Anime, a.GetMedia())
|
||||
ret.ListData[a.GetMedia().GetID()] = &anime.EntryListData{
|
||||
Progress: a.GetProgressSafe(),
|
||||
Score: a.GetScoreSafe(),
|
||||
Status: a.GetStatus(),
|
||||
Repeat: a.GetRepeatSafe(),
|
||||
StartedAt: anilist.FuzzyDateToString(a.StartedAt),
|
||||
CompletedAt: anilist.FuzzyDateToString(a.CompletedAt),
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret.ContinueWatchingList) == 0 && len(ret.Anime) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
sc := &anime.StreamCollection{
|
||||
ContinueWatchingList: ret.ContinueWatchingList,
|
||||
Anime: ret.Anime,
|
||||
ListData: ret.ListData,
|
||||
}
|
||||
|
||||
event := new(anime.AnimeLibraryStreamCollectionEvent)
|
||||
event.StreamCollection = sc
|
||||
err = hook.GlobalHookManager.OnAnimeLibraryStreamCollection().Trigger(event)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
opts.LibraryCollection.Stream = event.StreamCollection
|
||||
}
|
||||
Reference in New Issue
Block a user