node build fixed
This commit is contained in:
560
seanime-2.9.10/internal/handlers/routes.go
Normal file
560
seanime-2.9.10/internal/handlers/routes.go
Normal file
@@ -0,0 +1,560 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"seanime/internal/core"
|
||||
util "seanime/internal/util/proxies"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/ziflex/lecho/v3"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
App *core.App
|
||||
}
|
||||
|
||||
func InitRoutes(app *core.App, e *echo.Echo) {
|
||||
// CORS middleware
|
||||
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
|
||||
AllowOrigins: []string{"*"},
|
||||
AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Cookie", "Authorization",
|
||||
"X-Seanime-Token", "X-Seanime-Nakama-Token", "X-Seanime-Nakama-Username", "X-Seanime-Nakama-Server-Version", "X-Seanime-Nakama-Peer-Id"},
|
||||
AllowCredentials: true,
|
||||
}))
|
||||
|
||||
lechoLogger := lecho.From(*app.Logger)
|
||||
|
||||
urisToSkip := []string{
|
||||
"/internal/metrics",
|
||||
"/_next",
|
||||
"/icons",
|
||||
"/events",
|
||||
"/api/v1/image-proxy",
|
||||
"/api/v1/mediastream/transcode/",
|
||||
"/api/v1/torrent-client/list",
|
||||
"/api/v1/proxy",
|
||||
}
|
||||
|
||||
// Logging middleware
|
||||
e.Use(lecho.Middleware(lecho.Config{
|
||||
Logger: lechoLogger,
|
||||
Skipper: func(c echo.Context) bool {
|
||||
path := c.Request().URL.RequestURI()
|
||||
if filepath.Ext(c.Request().URL.Path) == ".txt" ||
|
||||
filepath.Ext(c.Request().URL.Path) == ".png" ||
|
||||
filepath.Ext(c.Request().URL.Path) == ".ico" {
|
||||
return true
|
||||
}
|
||||
for _, uri := range urisToSkip {
|
||||
if uri == path || strings.HasPrefix(path, uri) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
Enricher: func(c echo.Context, logger zerolog.Context) zerolog.Context {
|
||||
// Add which file the request came from
|
||||
return logger.Str("file", c.Path())
|
||||
},
|
||||
}))
|
||||
|
||||
// Recovery middleware
|
||||
e.Use(middleware.Recover())
|
||||
|
||||
// Client ID middleware
|
||||
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
// Check if the client has a UUID cookie
|
||||
cookie, err := c.Cookie("Seanime-Client-Id")
|
||||
|
||||
if err != nil || cookie.Value == "" {
|
||||
// Generate a new UUID for the client
|
||||
u := uuid.New().String()
|
||||
|
||||
// Create a cookie with the UUID
|
||||
newCookie := new(http.Cookie)
|
||||
newCookie.Name = "Seanime-Client-Id"
|
||||
newCookie.Value = u
|
||||
newCookie.HttpOnly = false // Make the cookie accessible via JS
|
||||
newCookie.Expires = time.Now().Add(24 * time.Hour)
|
||||
newCookie.Path = "/"
|
||||
newCookie.Domain = ""
|
||||
newCookie.SameSite = http.SameSiteDefaultMode
|
||||
newCookie.Secure = false
|
||||
|
||||
// Set the cookie
|
||||
c.SetCookie(newCookie)
|
||||
|
||||
// Store the UUID in the context for use in the request
|
||||
c.Set("Seanime-Client-Id", u)
|
||||
} else {
|
||||
// Store the existing UUID in the context for use in the request
|
||||
c.Set("Seanime-Client-Id", cookie.Value)
|
||||
}
|
||||
|
||||
return next(c)
|
||||
}
|
||||
})
|
||||
|
||||
e.Use(headMethodMiddleware)
|
||||
|
||||
h := &Handler{App: app}
|
||||
|
||||
e.GET("/events", h.webSocketEventHandler)
|
||||
|
||||
v1 := e.Group("/api").Group("/v1") // Commented out for now, will be used later
|
||||
|
||||
//
|
||||
// Auth middleware
|
||||
//
|
||||
v1.Use(h.OptionalAuthMiddleware)
|
||||
|
||||
imageProxy := &util.ImageProxy{}
|
||||
v1.GET("/image-proxy", imageProxy.ProxyImage)
|
||||
|
||||
v1.GET("/proxy", util.VideoProxy)
|
||||
v1.HEAD("/proxy", util.VideoProxy)
|
||||
|
||||
v1.GET("/status", h.HandleGetStatus)
|
||||
v1.GET("/log/*", h.HandleGetLogContent)
|
||||
v1.GET("/logs/filenames", h.HandleGetLogFilenames)
|
||||
v1.DELETE("/logs", h.HandleDeleteLogs)
|
||||
v1.GET("/logs/latest", h.HandleGetLatestLogContent)
|
||||
|
||||
v1.GET("/memory/stats", h.HandleGetMemoryStats)
|
||||
v1.GET("/memory/profile", h.HandleGetMemoryProfile)
|
||||
v1.GET("/memory/goroutine", h.HandleGetGoRoutineProfile)
|
||||
v1.GET("/memory/cpu", h.HandleGetCPUProfile)
|
||||
v1.POST("/memory/gc", h.HandleForceGC)
|
||||
|
||||
v1.POST("/announcements", h.HandleGetAnnouncements)
|
||||
|
||||
// Auth
|
||||
v1.POST("/auth/login", h.HandleLogin)
|
||||
v1.POST("/auth/logout", h.HandleLogout)
|
||||
|
||||
// Settings
|
||||
v1.GET("/settings", h.HandleGetSettings)
|
||||
v1.PATCH("/settings", h.HandleSaveSettings)
|
||||
v1.POST("/start", h.HandleGettingStarted)
|
||||
v1.PATCH("/settings/auto-downloader", h.HandleSaveAutoDownloaderSettings)
|
||||
|
||||
// Auto Downloader
|
||||
v1.POST("/auto-downloader/run", h.HandleRunAutoDownloader)
|
||||
v1.GET("/auto-downloader/rule/:id", h.HandleGetAutoDownloaderRule)
|
||||
v1.GET("/auto-downloader/rule/anime/:id", h.HandleGetAutoDownloaderRulesByAnime)
|
||||
v1.GET("/auto-downloader/rules", h.HandleGetAutoDownloaderRules)
|
||||
v1.POST("/auto-downloader/rule", h.HandleCreateAutoDownloaderRule)
|
||||
v1.PATCH("/auto-downloader/rule", h.HandleUpdateAutoDownloaderRule)
|
||||
v1.DELETE("/auto-downloader/rule/:id", h.HandleDeleteAutoDownloaderRule)
|
||||
|
||||
v1.GET("/auto-downloader/items", h.HandleGetAutoDownloaderItems)
|
||||
v1.DELETE("/auto-downloader/item", h.HandleDeleteAutoDownloaderItem)
|
||||
|
||||
// Other
|
||||
v1.POST("/test-dump", h.HandleTestDump)
|
||||
|
||||
v1.POST("/directory-selector", h.HandleDirectorySelector)
|
||||
|
||||
v1.POST("/open-in-explorer", h.HandleOpenInExplorer)
|
||||
|
||||
v1.POST("/media-player/start", h.HandleStartDefaultMediaPlayer)
|
||||
|
||||
//
|
||||
// AniList
|
||||
//
|
||||
|
||||
v1Anilist := v1.Group("/anilist")
|
||||
|
||||
v1Anilist.GET("/collection", h.HandleGetAnimeCollection)
|
||||
v1Anilist.POST("/collection", h.HandleGetAnimeCollection)
|
||||
|
||||
v1Anilist.GET("/collection/raw", h.HandleGetRawAnimeCollection)
|
||||
v1Anilist.POST("/collection/raw", h.HandleGetRawAnimeCollection)
|
||||
|
||||
v1Anilist.GET("/media-details/:id", h.HandleGetAnilistAnimeDetails)
|
||||
|
||||
v1Anilist.GET("/studio-details/:id", h.HandleGetAnilistStudioDetails)
|
||||
|
||||
v1Anilist.POST("/list-entry", h.HandleEditAnilistListEntry)
|
||||
|
||||
v1Anilist.DELETE("/list-entry", h.HandleDeleteAnilistListEntry)
|
||||
|
||||
v1Anilist.POST("/list-anime", h.HandleAnilistListAnime)
|
||||
|
||||
v1Anilist.POST("/list-recent-anime", h.HandleAnilistListRecentAiringAnime)
|
||||
|
||||
v1Anilist.GET("/list-missed-sequels", h.HandleAnilistListMissedSequels)
|
||||
|
||||
v1Anilist.GET("/stats", h.HandleGetAniListStats)
|
||||
|
||||
//
|
||||
// MAL
|
||||
//
|
||||
|
||||
v1.POST("/mal/auth", h.HandleMALAuth)
|
||||
|
||||
v1.POST("/mal/logout", h.HandleMALLogout)
|
||||
|
||||
//
|
||||
// Library
|
||||
//
|
||||
|
||||
v1Library := v1.Group("/library")
|
||||
|
||||
v1Library.POST("/scan", h.HandleScanLocalFiles)
|
||||
|
||||
v1Library.DELETE("/empty-directories", h.HandleRemoveEmptyDirectories)
|
||||
|
||||
v1Library.GET("/local-files", h.HandleGetLocalFiles)
|
||||
v1Library.POST("/local-files", h.HandleLocalFileBulkAction)
|
||||
v1Library.PATCH("/local-files", h.HandleUpdateLocalFiles)
|
||||
v1Library.DELETE("/local-files", h.HandleDeleteLocalFiles)
|
||||
v1Library.GET("/local-files/dump", h.HandleDumpLocalFilesToFile)
|
||||
v1Library.POST("/local-files/import", h.HandleImportLocalFiles)
|
||||
v1Library.PATCH("/local-file", h.HandleUpdateLocalFileData)
|
||||
|
||||
v1Library.GET("/collection", h.HandleGetLibraryCollection)
|
||||
v1Library.GET("/schedule", h.HandleGetAnimeCollectionSchedule)
|
||||
|
||||
v1Library.GET("/scan-summaries", h.HandleGetScanSummaries)
|
||||
|
||||
v1Library.GET("/missing-episodes", h.HandleGetMissingEpisodes)
|
||||
|
||||
v1Library.GET("/anime-entry/:id", h.HandleGetAnimeEntry)
|
||||
v1Library.POST("/anime-entry/suggestions", h.HandleFetchAnimeEntrySuggestions)
|
||||
v1Library.POST("/anime-entry/manual-match", h.HandleAnimeEntryManualMatch)
|
||||
v1Library.PATCH("/anime-entry/bulk-action", h.HandleAnimeEntryBulkAction)
|
||||
v1Library.POST("/anime-entry/open-in-explorer", h.HandleOpenAnimeEntryInExplorer)
|
||||
v1Library.POST("/anime-entry/update-progress", h.HandleUpdateAnimeEntryProgress)
|
||||
v1Library.POST("/anime-entry/update-repeat", h.HandleUpdateAnimeEntryRepeat)
|
||||
v1Library.GET("/anime-entry/silence/:id", h.HandleGetAnimeEntrySilenceStatus)
|
||||
v1Library.POST("/anime-entry/silence", h.HandleToggleAnimeEntrySilenceStatus)
|
||||
|
||||
v1Library.POST("/unknown-media", h.HandleAddUnknownMedia)
|
||||
|
||||
//
|
||||
// Anime
|
||||
//
|
||||
v1.GET("/anime/episode-collection/:id", h.HandleGetAnimeEpisodeCollection)
|
||||
|
||||
//
|
||||
// Torrent / Torrent Client
|
||||
//
|
||||
|
||||
v1.POST("/torrent/search", h.HandleSearchTorrent)
|
||||
v1.POST("/torrent-client/download", h.HandleTorrentClientDownload)
|
||||
v1.GET("/torrent-client/list", h.HandleGetActiveTorrentList)
|
||||
v1.POST("/torrent-client/action", h.HandleTorrentClientAction)
|
||||
v1.POST("/torrent-client/rule-magnet", h.HandleTorrentClientAddMagnetFromRule)
|
||||
|
||||
//
|
||||
// Download
|
||||
//
|
||||
|
||||
v1.POST("/download-torrent-file", h.HandleDownloadTorrentFile)
|
||||
|
||||
//
|
||||
// Updates
|
||||
//
|
||||
|
||||
v1.GET("/latest-update", h.HandleGetLatestUpdate)
|
||||
v1.GET("/changelog", h.HandleGetChangelog)
|
||||
v1.POST("/install-update", h.HandleInstallLatestUpdate)
|
||||
v1.POST("/download-release", h.HandleDownloadRelease)
|
||||
|
||||
//
|
||||
// Theme
|
||||
//
|
||||
|
||||
v1.GET("/theme", h.HandleGetTheme)
|
||||
v1.PATCH("/theme", h.HandleUpdateTheme)
|
||||
|
||||
//
|
||||
// Playback Manager
|
||||
//
|
||||
|
||||
v1.POST("/playback-manager/sync-current-progress", h.HandlePlaybackSyncCurrentProgress)
|
||||
v1.POST("/playback-manager/start-playlist", h.HandlePlaybackStartPlaylist)
|
||||
v1.POST("/playback-manager/playlist-next", h.HandlePlaybackPlaylistNext)
|
||||
v1.POST("/playback-manager/cancel-playlist", h.HandlePlaybackCancelCurrentPlaylist)
|
||||
v1.POST("/playback-manager/next-episode", h.HandlePlaybackPlayNextEpisode)
|
||||
v1.GET("/playback-manager/next-episode", h.HandlePlaybackGetNextEpisode)
|
||||
v1.POST("/playback-manager/autoplay-next-episode", h.HandlePlaybackAutoPlayNextEpisode)
|
||||
v1.POST("/playback-manager/play", h.HandlePlaybackPlayVideo)
|
||||
v1.POST("/playback-manager/play-random", h.HandlePlaybackPlayRandomVideo)
|
||||
//------------
|
||||
v1.POST("/playback-manager/manual-tracking/start", h.HandlePlaybackStartManualTracking)
|
||||
v1.POST("/playback-manager/manual-tracking/cancel", h.HandlePlaybackCancelManualTracking)
|
||||
|
||||
//
|
||||
// Playlists
|
||||
//
|
||||
|
||||
v1.GET("/playlists", h.HandleGetPlaylists)
|
||||
v1.POST("/playlist", h.HandleCreatePlaylist)
|
||||
v1.PATCH("/playlist", h.HandleUpdatePlaylist)
|
||||
v1.DELETE("/playlist", h.HandleDeletePlaylist)
|
||||
v1.GET("/playlist/episodes/:id/:progress", h.HandleGetPlaylistEpisodes)
|
||||
|
||||
//
|
||||
// Onlinestream
|
||||
//
|
||||
|
||||
v1.POST("/onlinestream/episode-source", h.HandleGetOnlineStreamEpisodeSource)
|
||||
v1.POST("/onlinestream/episode-list", h.HandleGetOnlineStreamEpisodeList)
|
||||
v1.DELETE("/onlinestream/cache", h.HandleOnlineStreamEmptyCache)
|
||||
|
||||
v1.POST("/onlinestream/search", h.HandleOnlinestreamManualSearch)
|
||||
v1.POST("/onlinestream/manual-mapping", h.HandleOnlinestreamManualMapping)
|
||||
v1.POST("/onlinestream/get-mapping", h.HandleGetOnlinestreamMapping)
|
||||
v1.POST("/onlinestream/remove-mapping", h.HandleRemoveOnlinestreamMapping)
|
||||
|
||||
//
|
||||
// Metadata Provider
|
||||
//
|
||||
|
||||
v1.POST("/metadata-provider/filler", h.HandlePopulateFillerData)
|
||||
v1.DELETE("/metadata-provider/filler", h.HandleRemoveFillerData)
|
||||
|
||||
//
|
||||
// Manga
|
||||
//
|
||||
|
||||
v1Manga := v1.Group("/manga")
|
||||
v1Manga.POST("/anilist/collection", h.HandleGetAnilistMangaCollection)
|
||||
v1Manga.GET("/anilist/collection/raw", h.HandleGetRawAnilistMangaCollection)
|
||||
v1Manga.POST("/anilist/collection/raw", h.HandleGetRawAnilistMangaCollection)
|
||||
v1Manga.POST("/anilist/list", h.HandleAnilistListManga)
|
||||
v1Manga.GET("/collection", h.HandleGetMangaCollection)
|
||||
v1Manga.GET("/latest-chapter-numbers", h.HandleGetMangaLatestChapterNumbersMap)
|
||||
v1Manga.POST("/refetch-chapter-containers", h.HandleRefetchMangaChapterContainers)
|
||||
v1Manga.GET("/entry/:id", h.HandleGetMangaEntry)
|
||||
v1Manga.GET("/entry/:id/details", h.HandleGetMangaEntryDetails)
|
||||
v1Manga.DELETE("/entry/cache", h.HandleEmptyMangaEntryCache)
|
||||
v1Manga.POST("/chapters", h.HandleGetMangaEntryChapters)
|
||||
v1Manga.POST("/pages", h.HandleGetMangaEntryPages)
|
||||
v1Manga.POST("/update-progress", h.HandleUpdateMangaProgress)
|
||||
|
||||
v1Manga.GET("/downloaded-chapters/:id", h.HandleGetMangaEntryDownloadedChapters)
|
||||
v1Manga.GET("/downloads", h.HandleGetMangaDownloadsList)
|
||||
v1Manga.POST("/download-chapters", h.HandleDownloadMangaChapters)
|
||||
v1Manga.POST("/download-data", h.HandleGetMangaDownloadData)
|
||||
v1Manga.DELETE("/download-chapter", h.HandleDeleteMangaDownloadedChapters)
|
||||
v1Manga.GET("/download-queue", h.HandleGetMangaDownloadQueue)
|
||||
v1Manga.POST("/download-queue/start", h.HandleStartMangaDownloadQueue)
|
||||
v1Manga.POST("/download-queue/stop", h.HandleStopMangaDownloadQueue)
|
||||
v1Manga.DELETE("/download-queue", h.HandleClearAllChapterDownloadQueue)
|
||||
v1Manga.POST("/download-queue/reset-errored", h.HandleResetErroredChapterDownloadQueue)
|
||||
|
||||
v1Manga.POST("/search", h.HandleMangaManualSearch)
|
||||
v1Manga.POST("/manual-mapping", h.HandleMangaManualMapping)
|
||||
v1Manga.POST("/get-mapping", h.HandleGetMangaMapping)
|
||||
v1Manga.POST("/remove-mapping", h.HandleRemoveMangaMapping)
|
||||
|
||||
v1Manga.GET("/local-page/:path", h.HandleGetLocalMangaPage)
|
||||
|
||||
//
|
||||
// File Cache
|
||||
//
|
||||
|
||||
v1FileCache := v1.Group("/filecache")
|
||||
v1FileCache.GET("/total-size", h.HandleGetFileCacheTotalSize)
|
||||
v1FileCache.DELETE("/bucket", h.HandleRemoveFileCacheBucket)
|
||||
v1FileCache.GET("/mediastream/videofiles/total-size", h.HandleGetFileCacheMediastreamVideoFilesTotalSize)
|
||||
v1FileCache.DELETE("/mediastream/videofiles", h.HandleClearFileCacheMediastreamVideoFiles)
|
||||
|
||||
//
|
||||
// Discord
|
||||
//
|
||||
|
||||
v1Discord := v1.Group("/discord")
|
||||
v1Discord.POST("/presence/manga", h.HandleSetDiscordMangaActivity)
|
||||
v1Discord.POST("/presence/legacy-anime", h.HandleSetDiscordLegacyAnimeActivity)
|
||||
v1Discord.POST("/presence/anime", h.HandleSetDiscordAnimeActivityWithProgress)
|
||||
v1Discord.POST("/presence/anime-update", h.HandleUpdateDiscordAnimeActivityWithProgress)
|
||||
v1Discord.POST("/presence/cancel", h.HandleCancelDiscordActivity)
|
||||
|
||||
//
|
||||
// Media Stream
|
||||
//
|
||||
v1.GET("/mediastream/settings", h.HandleGetMediastreamSettings)
|
||||
v1.PATCH("/mediastream/settings", h.HandleSaveMediastreamSettings)
|
||||
v1.POST("/mediastream/request", h.HandleRequestMediastreamMediaContainer)
|
||||
v1.POST("/mediastream/preload", h.HandlePreloadMediastreamMediaContainer)
|
||||
// Transcode
|
||||
v1.POST("/mediastream/shutdown-transcode", h.HandleMediastreamShutdownTranscodeStream)
|
||||
v1.GET("/mediastream/transcode/*", h.HandleMediastreamTranscode)
|
||||
v1.GET("/mediastream/subs/*", h.HandleMediastreamGetSubtitles)
|
||||
v1.GET("/mediastream/att/*", h.HandleMediastreamGetAttachments)
|
||||
v1.GET("/mediastream/direct", h.HandleMediastreamDirectPlay)
|
||||
v1.HEAD("/mediastream/direct", h.HandleMediastreamDirectPlay)
|
||||
v1.GET("/mediastream/file", h.HandleMediastreamFile)
|
||||
|
||||
//
|
||||
// Direct Stream
|
||||
//
|
||||
v1.POST("/directstream/play/localfile", h.HandleDirectstreamPlayLocalFile)
|
||||
v1.GET("/directstream/stream", echo.WrapHandler(h.HandleDirectstreamGetStream()))
|
||||
v1.HEAD("/directstream/stream", echo.WrapHandler(h.HandleDirectstreamGetStream()))
|
||||
v1.GET("/directstream/att/*", h.HandleDirectstreamGetAttachments)
|
||||
|
||||
//
|
||||
// Torrent stream
|
||||
//
|
||||
v1.GET("/torrentstream/settings", h.HandleGetTorrentstreamSettings)
|
||||
v1.PATCH("/torrentstream/settings", h.HandleSaveTorrentstreamSettings)
|
||||
v1.POST("/torrentstream/start", h.HandleTorrentstreamStartStream)
|
||||
v1.POST("/torrentstream/stop", h.HandleTorrentstreamStopStream)
|
||||
v1.POST("/torrentstream/drop", h.HandleTorrentstreamDropTorrent)
|
||||
v1.POST("/torrentstream/torrent-file-previews", h.HandleGetTorrentstreamTorrentFilePreviews)
|
||||
v1.POST("/torrentstream/batch-history", h.HandleGetTorrentstreamBatchHistory)
|
||||
v1.GET("/torrentstream/stream/*", h.HandleTorrentstreamServeStream)
|
||||
|
||||
//
|
||||
// Extensions
|
||||
//
|
||||
|
||||
v1Extensions := v1.Group("/extensions")
|
||||
v1Extensions.POST("/playground/run", h.HandleRunExtensionPlaygroundCode)
|
||||
v1Extensions.POST("/external/fetch", h.HandleFetchExternalExtensionData)
|
||||
v1Extensions.POST("/external/install", h.HandleInstallExternalExtension)
|
||||
v1Extensions.POST("/external/uninstall", h.HandleUninstallExternalExtension)
|
||||
v1Extensions.POST("/external/edit-payload", h.HandleUpdateExtensionCode)
|
||||
v1Extensions.POST("/external/reload", h.HandleReloadExternalExtensions)
|
||||
v1Extensions.POST("/external/reload", h.HandleReloadExternalExtension)
|
||||
v1Extensions.POST("/all", h.HandleGetAllExtensions)
|
||||
v1Extensions.GET("/updates", h.HandleGetExtensionUpdateData)
|
||||
v1Extensions.GET("/list", h.HandleListExtensionData)
|
||||
v1Extensions.GET("/payload/:id", h.HandleGetExtensionPayload)
|
||||
v1Extensions.GET("/list/development", h.HandleListDevelopmentModeExtensions)
|
||||
v1Extensions.GET("/list/manga-provider", h.HandleListMangaProviderExtensions)
|
||||
v1Extensions.GET("/list/onlinestream-provider", h.HandleListOnlinestreamProviderExtensions)
|
||||
v1Extensions.GET("/list/anime-torrent-provider", h.HandleListAnimeTorrentProviderExtensions)
|
||||
v1Extensions.GET("/user-config/:id", h.HandleGetExtensionUserConfig)
|
||||
v1Extensions.POST("/user-config", h.HandleSaveExtensionUserConfig)
|
||||
v1Extensions.GET("/marketplace", h.HandleGetMarketplaceExtensions)
|
||||
v1Extensions.GET("/plugin-settings", h.HandleGetPluginSettings)
|
||||
v1Extensions.POST("/plugin-settings/pinned-trays", h.HandleSetPluginSettingsPinnedTrays)
|
||||
v1Extensions.POST("/plugin-permissions/grant", h.HandleGrantPluginPermissions)
|
||||
|
||||
//
|
||||
// Continuity
|
||||
//
|
||||
v1Continuity := v1.Group("/continuity")
|
||||
v1Continuity.PATCH("/item", h.HandleUpdateContinuityWatchHistoryItem)
|
||||
v1Continuity.GET("/item/:id", h.HandleGetContinuityWatchHistoryItem)
|
||||
v1Continuity.GET("/history", h.HandleGetContinuityWatchHistory)
|
||||
|
||||
//
|
||||
// Sync
|
||||
//
|
||||
v1Local := v1.Group("/local")
|
||||
v1Local.GET("/track", h.HandleLocalGetTrackedMediaItems)
|
||||
v1Local.POST("/track", h.HandleLocalAddTrackedMedia)
|
||||
v1Local.DELETE("/track", h.HandleLocalRemoveTrackedMedia)
|
||||
v1Local.GET("/track/:id/:type", h.HandleLocalGetIsMediaTracked)
|
||||
v1Local.POST("/local", h.HandleLocalSyncData)
|
||||
v1Local.GET("/queue", h.HandleLocalGetSyncQueueState)
|
||||
v1Local.POST("/anilist", h.HandleLocalSyncAnilistData)
|
||||
v1Local.POST("/updated", h.HandleLocalSetHasLocalChanges)
|
||||
v1Local.GET("/updated", h.HandleLocalGetHasLocalChanges)
|
||||
v1Local.GET("/storage/size", h.HandleLocalGetLocalStorageSize)
|
||||
v1Local.POST("/sync-simulated-to-anilist", h.HandleLocalSyncSimulatedDataToAnilist)
|
||||
|
||||
v1Local.POST("/offline", h.HandleSetOfflineMode)
|
||||
|
||||
//
|
||||
// Debrid
|
||||
//
|
||||
|
||||
v1.GET("/debrid/settings", h.HandleGetDebridSettings)
|
||||
v1.PATCH("/debrid/settings", h.HandleSaveDebridSettings)
|
||||
v1.POST("/debrid/torrents", h.HandleDebridAddTorrents)
|
||||
v1.POST("/debrid/torrents/download", h.HandleDebridDownloadTorrent)
|
||||
v1.POST("/debrid/torrents/cancel", h.HandleDebridCancelDownload)
|
||||
v1.DELETE("/debrid/torrent", h.HandleDebridDeleteTorrent)
|
||||
v1.GET("/debrid/torrents", h.HandleDebridGetTorrents)
|
||||
v1.POST("/debrid/torrents/info", h.HandleDebridGetTorrentInfo)
|
||||
v1.POST("/debrid/torrents/file-previews", h.HandleDebridGetTorrentFilePreviews)
|
||||
v1.POST("/debrid/stream/start", h.HandleDebridStartStream)
|
||||
v1.POST("/debrid/stream/cancel", h.HandleDebridCancelStream)
|
||||
|
||||
//
|
||||
// Report
|
||||
//
|
||||
|
||||
v1.POST("/report/issue", h.HandleSaveIssueReport)
|
||||
v1.GET("/report/issue/download", h.HandleDownloadIssueReport)
|
||||
|
||||
//
|
||||
// Nakama
|
||||
//
|
||||
|
||||
v1Nakama := v1.Group("/nakama")
|
||||
v1Nakama.GET("/ws", h.HandleNakamaWebSocket)
|
||||
v1Nakama.POST("/message", h.HandleSendNakamaMessage)
|
||||
v1Nakama.POST("/reconnect", h.HandleNakamaReconnectToHost)
|
||||
v1Nakama.POST("/cleanup", h.HandleNakamaRemoveStaleConnections)
|
||||
v1Nakama.GET("/host/anime/library", h.HandleGetNakamaAnimeLibrary)
|
||||
v1Nakama.GET("/host/anime/library/collection", h.HandleGetNakamaAnimeLibraryCollection)
|
||||
v1Nakama.GET("/host/anime/library/files/:id", h.HandleGetNakamaAnimeLibraryFiles)
|
||||
v1Nakama.GET("/host/anime/library/files", h.HandleGetNakamaAnimeAllLibraryFiles)
|
||||
v1Nakama.POST("/play", h.HandleNakamaPlayVideo)
|
||||
v1Nakama.GET("/host/torrentstream/stream", h.HandleNakamaHostTorrentstreamServeStream)
|
||||
v1Nakama.GET("/host/anime/library/stream", h.HandleNakamaHostAnimeLibraryServeStream)
|
||||
v1Nakama.GET("/host/debridstream/stream", h.HandleNakamaHostDebridstreamServeStream)
|
||||
v1Nakama.GET("/host/debridstream/url", h.HandleNakamaHostGetDebridstreamURL)
|
||||
v1Nakama.GET("/stream", h.HandleNakamaProxyStream)
|
||||
v1Nakama.POST("/watch-party/create", h.HandleNakamaCreateWatchParty)
|
||||
v1Nakama.POST("/watch-party/join", h.HandleNakamaJoinWatchParty)
|
||||
v1Nakama.POST("/watch-party/leave", h.HandleNakamaLeaveWatchParty)
|
||||
|
||||
}
|
||||
|
||||
func (h *Handler) JSON(c echo.Context, code int, i interface{}) error {
|
||||
return c.JSON(code, i)
|
||||
}
|
||||
|
||||
func (h *Handler) RespondWithData(c echo.Context, data interface{}) error {
|
||||
return c.JSON(200, NewDataResponse(data))
|
||||
}
|
||||
|
||||
func (h *Handler) RespondWithError(c echo.Context, err error) error {
|
||||
return c.JSON(500, NewErrorResponse(err))
|
||||
}
|
||||
|
||||
func headMethodMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
// Skip directstream route
|
||||
if strings.Contains(c.Request().URL.Path, "/directstream/stream") {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
if c.Request().Method == http.MethodHead {
|
||||
// Set the method to GET temporarily to reuse the handler
|
||||
c.Request().Method = http.MethodGet
|
||||
|
||||
defer func() {
|
||||
c.Request().Method = http.MethodHead
|
||||
}() // Restore method after
|
||||
|
||||
// Call the next handler and then clear the response body
|
||||
if err := next(c); err != nil {
|
||||
if err.Error() == echo.ErrMethodNotAllowed.Error() {
|
||||
return c.NoContent(http.StatusOK)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user