mirror of
https://gitlab.com/foxixus/neomovies-api.git
synced 2025-10-28 01:48:51 +05:00
fix: correct player routes and IDs, add API documentation
- Vidsrc: uses IMDb ID for both movies and TV shows
- Vidlink: uses IMDb ID for movies, TMDB ID for TV shows
- Updated routes: /players/vidsrc/{media_type}/{imdb_id}
- Updated routes: /players/vidlink/movie/{imdb_id}
- New route: /players/vidlink/tv/{tmdb_id}
- Added comprehensive OpenAPI documentation for new players
This commit is contained in:
@@ -97,8 +97,9 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|||||||
api.HandleFunc("/players/alloha/{imdb_id}", playersHandler.GetAllohaPlayer).Methods("GET")
|
api.HandleFunc("/players/alloha/{imdb_id}", playersHandler.GetAllohaPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/lumex/{imdb_id}", playersHandler.GetLumexPlayer).Methods("GET")
|
api.HandleFunc("/players/lumex/{imdb_id}", playersHandler.GetLumexPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/vibix/{imdb_id}", playersHandler.GetVibixPlayer).Methods("GET")
|
api.HandleFunc("/players/vibix/{imdb_id}", playersHandler.GetVibixPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/vidsrc/{media_type}/{id}", playersHandler.GetVidsrcPlayer).Methods("GET")
|
api.HandleFunc("/players/vidsrc/{media_type}/{imdb_id}", playersHandler.GetVidsrcPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/vidlink/{media_type}/{id}", playersHandler.GetVidlinkPlayer).Methods("GET")
|
api.HandleFunc("/players/vidlink/movie/{imdb_id}", playersHandler.GetVidlinkMoviePlayer).Methods("GET")
|
||||||
|
api.HandleFunc("/players/vidlink/tv/{tmdb_id}", playersHandler.GetVidlinkTVPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/rgshows/{tmdb_id}", playersHandler.GetRgShowsPlayer).Methods("GET")
|
api.HandleFunc("/players/rgshows/{tmdb_id}", playersHandler.GetRgShowsPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/rgshows/{tmdb_id}/{season}/{episode}", playersHandler.GetRgShowsTVPlayer).Methods("GET")
|
api.HandleFunc("/players/rgshows/{tmdb_id}/{season}/{episode}", playersHandler.GetRgShowsTVPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/iframevideo/{kinopoisk_id}/{imdb_id}", playersHandler.GetIframeVideoPlayer).Methods("GET")
|
api.HandleFunc("/players/iframevideo/{kinopoisk_id}/{imdb_id}", playersHandler.GetIframeVideoPlayer).Methods("GET")
|
||||||
|
|||||||
5
main.go
5
main.go
@@ -78,8 +78,9 @@ func main() {
|
|||||||
api.HandleFunc("/players/alloha/{imdb_id}", playersHandler.GetAllohaPlayer).Methods("GET")
|
api.HandleFunc("/players/alloha/{imdb_id}", playersHandler.GetAllohaPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/lumex/{imdb_id}", playersHandler.GetLumexPlayer).Methods("GET")
|
api.HandleFunc("/players/lumex/{imdb_id}", playersHandler.GetLumexPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/vibix/{imdb_id}", playersHandler.GetVibixPlayer).Methods("GET")
|
api.HandleFunc("/players/vibix/{imdb_id}", playersHandler.GetVibixPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/vidsrc/{media_type}/{id}", playersHandler.GetVidsrcPlayer).Methods("GET")
|
api.HandleFunc("/players/vidsrc/{media_type}/{imdb_id}", playersHandler.GetVidsrcPlayer).Methods("GET")
|
||||||
api.HandleFunc("/players/vidlink/{media_type}/{id}", playersHandler.GetVidlinkPlayer).Methods("GET")
|
api.HandleFunc("/players/vidlink/movie/{imdb_id}", playersHandler.GetVidlinkMoviePlayer).Methods("GET")
|
||||||
|
api.HandleFunc("/players/vidlink/tv/{tmdb_id}", playersHandler.GetVidlinkTVPlayer).Methods("GET")
|
||||||
|
|
||||||
api.HandleFunc("/torrents/search/{imdbId}", torrentsHandler.SearchTorrents).Methods("GET")
|
api.HandleFunc("/torrents/search/{imdbId}", torrentsHandler.SearchTorrents).Methods("GET")
|
||||||
api.HandleFunc("/torrents/movies", torrentsHandler.SearchMovies).Methods("GET")
|
api.HandleFunc("/torrents/movies", torrentsHandler.SearchMovies).Methods("GET")
|
||||||
|
|||||||
@@ -374,6 +374,116 @@ func getOpenAPISpecWithURL(baseURL string) *OpenAPISpec {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"/api/v1/players/vidsrc/{media_type}/{imdb_id}": map[string]interface{}{
|
||||||
|
"get": map[string]interface{}{
|
||||||
|
"summary": "Vidsrc плеер (английский)",
|
||||||
|
"description": "Возвращает HTML-страницу с iframe Vidsrc.to. Использует IMDb ID для фильмов и сериалов. Пример URL для фильма: https://vidsrc.to/embed/movie/tt1234567, для сериала: https://vidsrc.to/embed/tv/tt6385540/1/1",
|
||||||
|
"tags": []string{"Players"},
|
||||||
|
"parameters": []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"name": "media_type",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": map[string]interface{}{"type": "string", "enum": []string{"movie", "tv"}},
|
||||||
|
"description": "Тип контента: movie (фильм) или tv (сериал)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "imdb_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": map[string]string{"type": "string"},
|
||||||
|
"description": "IMDb ID, например tt6385540 (с префиксом tt)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "season",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": map[string]string{"type": "integer"},
|
||||||
|
"description": "Номер сезона (обязательно для TV)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "episode",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": map[string]string{"type": "integer"},
|
||||||
|
"description": "Номер серии (обязательно для TV)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"responses": map[string]interface{}{
|
||||||
|
"200": map[string]interface{}{
|
||||||
|
"description": "HTML со встроенным Vidsrc плеером",
|
||||||
|
"content": map[string]interface{}{
|
||||||
|
"text/html": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"400": map[string]interface{}{"description": "Отсутствуют обязательные параметры"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/api/v1/players/vidlink/movie/{imdb_id}": map[string]interface{}{
|
||||||
|
"get": map[string]interface{}{
|
||||||
|
"summary": "Vidlink плеер для фильмов (английский)",
|
||||||
|
"description": "Возвращает HTML-страницу с iframe Vidlink.pro для фильмов. Использует IMDb ID. Пример URL: https://vidlink.pro/movie/tt1234567",
|
||||||
|
"tags": []string{"Players"},
|
||||||
|
"parameters": []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"name": "imdb_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": map[string]string{"type": "string"},
|
||||||
|
"description": "IMDb ID фильма, например tt1234567 (с префиксом tt)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"responses": map[string]interface{}{
|
||||||
|
"200": map[string]interface{}{
|
||||||
|
"description": "HTML со встроенным Vidlink плеером",
|
||||||
|
"content": map[string]interface{}{
|
||||||
|
"text/html": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"400": map[string]interface{}{"description": "IMDb ID не указан"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/api/v1/players/vidlink/tv/{tmdb_id}": map[string]interface{}{
|
||||||
|
"get": map[string]interface{}{
|
||||||
|
"summary": "Vidlink плеер для сериалов (английский)",
|
||||||
|
"description": "Возвращает HTML-страницу с iframe Vidlink.pro для сериалов. Использует TMDB ID (без префикса tt). Пример URL: https://vidlink.pro/tv/94997/1/1",
|
||||||
|
"tags": []string{"Players"},
|
||||||
|
"parameters": []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"name": "tmdb_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": map[string]string{"type": "integer"},
|
||||||
|
"description": "TMDB ID сериала, например 94997 (числовой идентификатор без префикса)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "season",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": map[string]string{"type": "integer"},
|
||||||
|
"description": "Номер сезона (обязательно)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "episode",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": map[string]string{"type": "integer"},
|
||||||
|
"description": "Номер серии (обязательно)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"responses": map[string]interface{}{
|
||||||
|
"200": map[string]interface{}{
|
||||||
|
"description": "HTML со встроенным Vidlink плеером",
|
||||||
|
"content": map[string]interface{}{
|
||||||
|
"text/html": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"400": map[string]interface{}{"description": "Отсутствуют обязательные параметры (tmdb_id, season, episode)"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
"/api/v1/torrents/search/{imdbId}": map[string]interface{}{
|
"/api/v1/torrents/search/{imdbId}": map[string]interface{}{
|
||||||
|
|||||||
@@ -436,22 +436,22 @@ func (h *PlayersHandler) GetStreamAPI(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Printf("Successfully served stream API for provider: %s, tmdb_id: %s", provider, tmdbID)
|
log.Printf("Successfully served stream API for provider: %s, tmdb_id: %s", provider, tmdbID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVidsrcPlayer handles Vidsrc.to player
|
// GetVidsrcPlayer handles Vidsrc.to player (uses IMDb ID for both movies and TV shows)
|
||||||
func (h *PlayersHandler) GetVidsrcPlayer(w http.ResponseWriter, r *http.Request) {
|
func (h *PlayersHandler) GetVidsrcPlayer(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("GetVidsrcPlayer called: %s %s", r.Method, r.URL.Path)
|
log.Printf("GetVidsrcPlayer called: %s %s", r.Method, r.URL.Path)
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
id := vars["id"]
|
imdbId := vars["imdb_id"]
|
||||||
mediaType := vars["media_type"] // "movie" or "tv"
|
mediaType := vars["media_type"] // "movie" or "tv"
|
||||||
|
|
||||||
if id == "" || mediaType == "" {
|
if imdbId == "" || mediaType == "" {
|
||||||
http.Error(w, "id and media_type are required", http.StatusBadRequest)
|
http.Error(w, "imdb_id and media_type are required", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var playerURL string
|
var playerURL string
|
||||||
if mediaType == "movie" {
|
if mediaType == "movie" {
|
||||||
playerURL = fmt.Sprintf("https://vidsrc.to/embed/movie/%s", id)
|
playerURL = fmt.Sprintf("https://vidsrc.to/embed/movie/%s", imdbId)
|
||||||
} else if mediaType == "tv" {
|
} else if mediaType == "tv" {
|
||||||
season := r.URL.Query().Get("season")
|
season := r.URL.Query().Get("season")
|
||||||
episode := r.URL.Query().Get("episode")
|
episode := r.URL.Query().Get("episode")
|
||||||
@@ -459,7 +459,7 @@ func (h *PlayersHandler) GetVidsrcPlayer(w http.ResponseWriter, r *http.Request)
|
|||||||
http.Error(w, "season and episode are required for TV shows", http.StatusBadRequest)
|
http.Error(w, "season and episode are required for TV shows", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
playerURL = fmt.Sprintf("https://vidsrc.to/embed/tv/%s/%s/%s", id, season, episode)
|
playerURL = fmt.Sprintf("https://vidsrc.to/embed/tv/%s/%s/%s", imdbId, season, episode)
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "Invalid media_type. Use 'movie' or 'tv'", http.StatusBadRequest)
|
http.Error(w, "Invalid media_type. Use 'movie' or 'tv'", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
@@ -473,39 +473,24 @@ func (h *PlayersHandler) GetVidsrcPlayer(w http.ResponseWriter, r *http.Request)
|
|||||||
w.Header().Set("Content-Type", "text/html")
|
w.Header().Set("Content-Type", "text/html")
|
||||||
w.Write([]byte(htmlDoc))
|
w.Write([]byte(htmlDoc))
|
||||||
|
|
||||||
log.Printf("Successfully served Vidsrc player for %s: %s", mediaType, id)
|
log.Printf("Successfully served Vidsrc player for %s: %s", mediaType, imdbId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVidlinkPlayer handles vidlink.pro player
|
// GetVidlinkMoviePlayer handles vidlink.pro player for movies (uses IMDb ID)
|
||||||
func (h *PlayersHandler) GetVidlinkPlayer(w http.ResponseWriter, r *http.Request) {
|
func (h *PlayersHandler) GetVidlinkMoviePlayer(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("GetVidlinkPlayer called: %s %s", r.Method, r.URL.Path)
|
log.Printf("GetVidlinkMoviePlayer called: %s %s", r.Method, r.URL.Path)
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
id := vars["id"]
|
imdbId := vars["imdb_id"]
|
||||||
mediaType := vars["media_type"] // "movie" or "tv"
|
|
||||||
|
|
||||||
if id == "" || mediaType == "" {
|
if imdbId == "" {
|
||||||
http.Error(w, "id and media_type are required", http.StatusBadRequest)
|
http.Error(w, "imdb_id is required", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var playerURL string
|
playerURL := fmt.Sprintf("https://vidlink.pro/movie/%s", imdbId)
|
||||||
if mediaType == "movie" {
|
|
||||||
playerURL = fmt.Sprintf("https://vidlink.pro/movie/%s", id)
|
|
||||||
} else if mediaType == "tv" {
|
|
||||||
season := r.URL.Query().Get("season")
|
|
||||||
episode := r.URL.Query().Get("episode")
|
|
||||||
if season == "" || episode == "" {
|
|
||||||
http.Error(w, "season and episode are required for TV shows", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
playerURL = fmt.Sprintf("https://vidlink.pro/tv/%s/%s/%s", id, season, episode)
|
|
||||||
} else {
|
|
||||||
http.Error(w, "Invalid media_type. Use 'movie' or 'tv'", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Generated Vidlink URL: %s", playerURL)
|
log.Printf("Generated Vidlink Movie URL: %s", playerURL)
|
||||||
|
|
||||||
iframe := fmt.Sprintf(`<iframe src="%s" allowfullscreen loading="lazy" style="border:none;width:100%%;height:100%%;"></iframe>`, playerURL)
|
iframe := fmt.Sprintf(`<iframe src="%s" allowfullscreen loading="lazy" style="border:none;width:100%%;height:100%%;"></iframe>`, playerURL)
|
||||||
htmlDoc := fmt.Sprintf(`<!DOCTYPE html><html><head><meta charset='utf-8'/><title>Vidlink Player</title><style>html,body{margin:0;height:100%%;}</style></head><body>%s</body></html>`, iframe)
|
htmlDoc := fmt.Sprintf(`<!DOCTYPE html><html><head><meta charset='utf-8'/><title>Vidlink Player</title><style>html,body{margin:0;height:100%%;}</style></head><body>%s</body></html>`, iframe)
|
||||||
@@ -513,5 +498,37 @@ func (h *PlayersHandler) GetVidlinkPlayer(w http.ResponseWriter, r *http.Request
|
|||||||
w.Header().Set("Content-Type", "text/html")
|
w.Header().Set("Content-Type", "text/html")
|
||||||
w.Write([]byte(htmlDoc))
|
w.Write([]byte(htmlDoc))
|
||||||
|
|
||||||
log.Printf("Successfully served Vidlink player for %s: %s", mediaType, id)
|
log.Printf("Successfully served Vidlink movie player: %s", imdbId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVidlinkTVPlayer handles vidlink.pro player for TV shows (uses TMDB ID)
|
||||||
|
func (h *PlayersHandler) GetVidlinkTVPlayer(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf("GetVidlinkTVPlayer called: %s %s", r.Method, r.URL.Path)
|
||||||
|
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
tmdbId := vars["tmdb_id"]
|
||||||
|
|
||||||
|
if tmdbId == "" {
|
||||||
|
http.Error(w, "tmdb_id is required", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
season := r.URL.Query().Get("season")
|
||||||
|
episode := r.URL.Query().Get("episode")
|
||||||
|
if season == "" || episode == "" {
|
||||||
|
http.Error(w, "season and episode are required for TV shows", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
playerURL := fmt.Sprintf("https://vidlink.pro/tv/%s/%s/%s", tmdbId, season, episode)
|
||||||
|
|
||||||
|
log.Printf("Generated Vidlink TV URL: %s", playerURL)
|
||||||
|
|
||||||
|
iframe := fmt.Sprintf(`<iframe src="%s" allowfullscreen loading="lazy" style="border:none;width:100%%;height:100%%;"></iframe>`, playerURL)
|
||||||
|
htmlDoc := fmt.Sprintf(`<!DOCTYPE html><html><head><meta charset='utf-8'/><title>Vidlink Player</title><style>html,body{margin:0;height:100%%;}</style></head><body>%s</body></html>`, iframe)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "text/html")
|
||||||
|
w.Write([]byte(htmlDoc))
|
||||||
|
|
||||||
|
log.Printf("Successfully served Vidlink TV player: %s S%sE%s", tmdbId, season, episode)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user