229 lines
6.5 KiB
Go
229 lines
6.5 KiB
Go
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)
|
|
}
|