package handlers import ( "errors" "seanime/internal/api/anilist" "seanime/internal/onlinestream" "github.com/labstack/echo/v4" ) // HandleGetOnlineStreamEpisodeList // // @summary returns the episode list for the given media and provider. // @desc It returns the episode list for the given media and provider. // @desc The episodes are cached using a file cache. // @desc The episode list is just a list of episodes with no video sources, it's what the client uses to display the episodes and subsequently fetch the sources. // @desc The episode list might be nil or empty if nothing could be found, but the media will always be returned. // @route /api/v1/onlinestream/episode-list [POST] // @returns onlinestream.EpisodeListResponse func (h *Handler) HandleGetOnlineStreamEpisodeList(c echo.Context) error { type body struct { MediaId int `json:"mediaId"` Dubbed bool `json:"dubbed"` Provider string `json:"provider,omitempty"` // Can be empty since we still have the media id } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } if h.App.Settings == nil || !h.App.Settings.GetLibrary().EnableOnlinestream { return h.RespondWithError(c, errors.New("enable online streaming in the settings")) } // Get media // This is cached media, err := h.App.OnlinestreamRepository.GetMedia(c.Request().Context(), b.MediaId) if err != nil { return h.RespondWithError(c, err) } if media.Status == nil || *media.Status == anilist.MediaStatusNotYetReleased { return h.RespondWithError(c, errors.New("unavailable")) } // Get episode list // This is cached using file cache episodes, err := h.App.OnlinestreamRepository.GetMediaEpisodes(b.Provider, media, b.Dubbed) //if err != nil { // return h.RespondWithError(c, err) //} ret := onlinestream.EpisodeListResponse{ Episodes: episodes, Media: media, } h.App.FillerManager.HydrateOnlinestreamFillerData(b.MediaId, ret.Episodes) return h.RespondWithData(c, ret) } // HandleGetOnlineStreamEpisodeSource // // @summary returns the video sources for the given media, episode number and provider. // @route /api/v1/onlinestream/episode-source [POST] // @returns onlinestream.EpisodeSource func (h *Handler) HandleGetOnlineStreamEpisodeSource(c echo.Context) error { type body struct { EpisodeNumber int `json:"episodeNumber"` MediaId int `json:"mediaId"` Provider string `json:"provider"` Dubbed bool `json:"dubbed"` } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } // Get media // This is cached media, err := h.App.OnlinestreamRepository.GetMedia(c.Request().Context(), b.MediaId) if err != nil { return h.RespondWithError(c, err) } sources, err := h.App.OnlinestreamRepository.GetEpisodeSources(c.Request().Context(), b.Provider, b.MediaId, b.EpisodeNumber, b.Dubbed, media.GetStartYearSafe()) if err != nil { return h.RespondWithError(c, err) } return h.RespondWithData(c, sources) } // HandleOnlineStreamEmptyCache // // @summary empties the cache for the given media. // @route /api/v1/onlinestream/cache [DELETE] // @returns bool func (h *Handler) HandleOnlineStreamEmptyCache(c echo.Context) error { type body struct { MediaId int `json:"mediaId"` } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } err := h.App.OnlinestreamRepository.EmptyCache(b.MediaId) if err != nil { return h.RespondWithError(c, err) } return h.RespondWithData(c, true) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // HandleOnlinestreamManualSearch // // @summary returns search results for a manual search. // @desc Returns search results for a manual search. // @route /api/v1/onlinestream/search [POST] // @returns []hibikeonlinestream.SearchResult func (h *Handler) HandleOnlinestreamManualSearch(c echo.Context) error { type body struct { Provider string `json:"provider"` Query string `json:"query"` Dubbed bool `json:"dubbed"` } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } ret, err := h.App.OnlinestreamRepository.ManualSearch(b.Provider, b.Query, b.Dubbed) if err != nil { return h.RespondWithError(c, err) } return h.RespondWithData(c, ret) } // HandleOnlinestreamManualMapping // // @summary manually maps an anime entry to an anime ID from the provider. // @desc This is used to manually map an anime entry to an anime ID from the provider. // @desc The client should re-fetch the chapter container after this. // @route /api/v1/onlinestream/manual-mapping [POST] // @returns bool func (h *Handler) HandleOnlinestreamManualMapping(c echo.Context) error { type body struct { Provider string `json:"provider"` MediaId int `json:"mediaId"` AnimeId string `json:"animeId"` } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } err := h.App.OnlinestreamRepository.ManualMapping(b.Provider, b.MediaId, b.AnimeId) if err != nil { return h.RespondWithError(c, err) } return h.RespondWithData(c, true) } // HandleGetOnlinestreamMapping // // @summary returns the mapping for an anime entry. // @desc This is used to get the mapping for an anime entry. // @desc An empty string is returned if there's no manual mapping. If there is, the anime ID will be returned. // @route /api/v1/onlinestream/get-mapping [POST] // @returns onlinestream.MappingResponse func (h *Handler) HandleGetOnlinestreamMapping(c echo.Context) error { type body struct { Provider string `json:"provider"` MediaId int `json:"mediaId"` } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } mapping := h.App.OnlinestreamRepository.GetMapping(b.Provider, b.MediaId) return h.RespondWithData(c, mapping) } // HandleRemoveOnlinestreamMapping // // @summary removes the mapping for an anime entry. // @desc This is used to remove the mapping for an anime entry. // @desc The client should re-fetch the chapter container after this. // @route /api/v1/onlinestream/remove-mapping [POST] // @returns bool func (h *Handler) HandleRemoveOnlinestreamMapping(c echo.Context) error { type body struct { Provider string `json:"provider"` MediaId int `json:"mediaId"` } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } err := h.App.OnlinestreamRepository.RemoveMapping(b.Provider, b.MediaId) if err != nil { return h.RespondWithError(c, err) } return h.RespondWithData(c, true) }