node build fixed

This commit is contained in:
ra_ma
2025-09-20 14:08:38 +01:00
parent c6ebbe069d
commit 3d298fa434
1516 changed files with 535727 additions and 2 deletions

View 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
}