mirror of
https://github.com/sbondCo/Watcharr.git
synced 2026-08-07 07:14:44 +00:00
385 lines
9.1 KiB
Go
385 lines
9.1 KiB
Go
package discover
|
|
|
|
import (
|
|
"errors"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"github.com/sbondCo/Watcharr/config"
|
|
"github.com/sbondCo/Watcharr/domain"
|
|
"github.com/sbondCo/Watcharr/media/tmdb"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type Service struct {
|
|
db *gorm.DB
|
|
cfg *config.ServerConfig
|
|
tmdb *tmdb.TMDB
|
|
}
|
|
|
|
func NewService(
|
|
db *gorm.DB,
|
|
cfg *config.ServerConfig,
|
|
tmdb *tmdb.TMDB,
|
|
) *Service {
|
|
return &Service{
|
|
db,
|
|
cfg,
|
|
tmdb,
|
|
}
|
|
}
|
|
|
|
// `Limit` is not supported.
|
|
func (s *Service) Discover(
|
|
// User request
|
|
r domain.DiscoverRequest,
|
|
// Extra data
|
|
meta domain.DiscoverRequestMeta,
|
|
) (domain.DiscoverResponse, error) {
|
|
resp := domain.DiscoverResponse{}
|
|
|
|
switch r.Type {
|
|
case domain.SearchTypeMulti:
|
|
return s.DiscoverMulti(r, meta)
|
|
case domain.SearchTypeShow:
|
|
return s.DiscoverTv(r, meta)
|
|
case domain.SearchTypePerson:
|
|
return s.DiscoverPeople(r, meta)
|
|
case domain.SearchTypeMovie:
|
|
return s.DiscoverMovie(r, meta)
|
|
case domain.SearchTypeGame:
|
|
return s.DiscoverGame(r, meta)
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
// Discover Multi. Just for tmdb.
|
|
func (s *Service) DiscoverMulti(
|
|
r domain.DiscoverRequest,
|
|
meta domain.DiscoverRequestMeta,
|
|
) (domain.DiscoverResponse, error) {
|
|
resp := domain.DiscoverResponse{}
|
|
var err error
|
|
switch r.Filter {
|
|
case domain.DiscoverFilterTrending:
|
|
err = s.discoverMultiTrending(tmdb.TrendingTypeAll, meta, &resp)
|
|
case domain.DiscoverFilterInTheatres:
|
|
err = s.discoverMovieInTheatres(meta, &resp)
|
|
default:
|
|
slog.Error("DiscoverMulti: Unsupported filter.")
|
|
return resp, errors.New("unsupported filter")
|
|
}
|
|
return resp, err
|
|
}
|
|
|
|
// Discover movies.
|
|
func (s *Service) DiscoverMovie(
|
|
r domain.DiscoverRequest,
|
|
meta domain.DiscoverRequestMeta,
|
|
) (domain.DiscoverResponse, error) {
|
|
resp := domain.DiscoverResponse{}
|
|
var err error
|
|
switch r.Filter {
|
|
case domain.DiscoverFilterTrending:
|
|
err = s.discoverMultiTrending(tmdb.TrendingTypeMovie, meta, &resp)
|
|
case domain.DiscoverFilterInTheatres:
|
|
err = s.discoverMovieInTheatres(meta, &resp)
|
|
case domain.DiscoverFilterUpcoming:
|
|
err = s.discoverMovieUpcoming(meta, &resp)
|
|
case domain.DiscoverFilterPopular:
|
|
err = s.discoverMoviePopular(meta, &resp)
|
|
default:
|
|
slog.Error("DiscoverMovie: Unsupported filter.")
|
|
return resp, errors.New("unsupported filter")
|
|
}
|
|
return resp, err
|
|
}
|
|
|
|
// Discover shows.
|
|
func (s *Service) DiscoverTv(
|
|
r domain.DiscoverRequest,
|
|
meta domain.DiscoverRequestMeta,
|
|
) (domain.DiscoverResponse, error) {
|
|
resp := domain.DiscoverResponse{}
|
|
var err error
|
|
switch r.Filter {
|
|
case domain.DiscoverFilterTrending:
|
|
err = s.discoverMultiTrending(tmdb.TrendingTypeShow, meta, &resp)
|
|
case domain.DiscoverFilterUpcoming:
|
|
err = s.discoverTvUpcoming(meta, &resp)
|
|
case domain.DiscoverFilterPopular:
|
|
err = s.discoverTvPopular(meta, &resp)
|
|
default:
|
|
slog.Error("DiscoverMovie: Unsupported filter.")
|
|
return resp, errors.New("unsupported filter")
|
|
}
|
|
return resp, err
|
|
}
|
|
|
|
// Discover people.
|
|
func (s *Service) DiscoverPeople(
|
|
r domain.DiscoverRequest,
|
|
meta domain.DiscoverRequestMeta,
|
|
) (domain.DiscoverResponse, error) {
|
|
resp := domain.DiscoverResponse{}
|
|
var err error
|
|
switch r.Filter {
|
|
case domain.DiscoverFilterTrending:
|
|
err = s.discoverMultiTrending(tmdb.TrendingTypePerson, meta, &resp)
|
|
case domain.DiscoverFilterPopular:
|
|
err = s.discoverPeoplePopular(meta, &resp)
|
|
default:
|
|
slog.Error("DiscoverMulti: Unsupported filter.")
|
|
return resp, errors.New("unsupported filter")
|
|
}
|
|
return resp, err
|
|
}
|
|
|
|
// Discover games.
|
|
func (s *Service) DiscoverGame(
|
|
r domain.DiscoverRequest,
|
|
meta domain.DiscoverRequestMeta,
|
|
) (domain.DiscoverResponse, error) {
|
|
resp := domain.DiscoverResponse{}
|
|
var err error
|
|
switch r.Filter {
|
|
case domain.DiscoverFilterTrending:
|
|
err = s.discoverGameTrending(&resp)
|
|
case domain.DiscoverFilterUpcoming:
|
|
err = s.discoverGameUpcoming(&resp)
|
|
default:
|
|
slog.Error("DiscoverGame: Unsupported filter.")
|
|
return resp, errors.New("unsupported filter")
|
|
}
|
|
return resp, err
|
|
}
|
|
|
|
// Discover anything that is trending on TMDB (including combined).
|
|
func (s *Service) discoverMultiTrending(
|
|
t tmdb.TrendingType,
|
|
meta domain.DiscoverRequestMeta,
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
tmdbRes, err := s.tmdb.Trending(t, meta.PageParams.Page, meta.Region)
|
|
if err != nil {
|
|
slog.Error("discoverMulti: Failed to search tmdb!", "error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range tmdbRes.Results {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = tmdbRes.Page
|
|
resp.TotalPages = tmdbRes.TotalPages
|
|
resp.TotalResults = int64(tmdbRes.TotalResults)
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverMovieInTheatres(
|
|
meta domain.DiscoverRequestMeta,
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
tmdbRes, err := s.tmdb.DiscoverMovies(
|
|
tmdb.DiscoverOptions{
|
|
ReleaseDateMin: time.Now().AddDate(0, 0, -40),
|
|
ReleaseDateMax: time.Now().AddDate(0, 0, 2),
|
|
WithReleaseType: "2|3",
|
|
},
|
|
meta.PageParams.Page,
|
|
meta.Region,
|
|
)
|
|
if err != nil {
|
|
slog.Error("discoverMovieInTheatres: Failed to search tmdb!",
|
|
"error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range tmdbRes.Results {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = tmdbRes.Page
|
|
resp.TotalPages = tmdbRes.TotalPages
|
|
resp.TotalResults = int64(tmdbRes.TotalResults)
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverMovieUpcoming(
|
|
meta domain.DiscoverRequestMeta,
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
tmdbRes, err := s.tmdb.DiscoverMovies(
|
|
tmdb.DiscoverOptions{
|
|
ReleaseDateMin: time.Now(),
|
|
ReleaseDateMax: time.Now().AddDate(0, 1, 0),
|
|
WithReleaseType: "2|3",
|
|
},
|
|
meta.PageParams.Page,
|
|
meta.Region,
|
|
)
|
|
if err != nil {
|
|
slog.Error("discoverMovieUpcoming: Failed to search tmdb!",
|
|
"error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range tmdbRes.Results {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = tmdbRes.Page
|
|
resp.TotalPages = tmdbRes.TotalPages
|
|
resp.TotalResults = int64(tmdbRes.TotalResults)
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverMoviePopular(
|
|
meta domain.DiscoverRequestMeta,
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
tmdbRes, err := s.tmdb.DiscoverMovies(
|
|
tmdb.DiscoverOptions{},
|
|
meta.PageParams.Page,
|
|
meta.Region,
|
|
)
|
|
if err != nil {
|
|
slog.Error("discoverMoviePopular: Failed to search tmdb!",
|
|
"error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range tmdbRes.Results {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = tmdbRes.Page
|
|
resp.TotalPages = tmdbRes.TotalPages
|
|
resp.TotalResults = int64(tmdbRes.TotalResults)
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverTvUpcoming(
|
|
meta domain.DiscoverRequestMeta,
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
tmdbRes, err := s.tmdb.DiscoverShows(
|
|
tmdb.DiscoverOptions{
|
|
ReleaseDateMin: time.Now(),
|
|
ReleaseDateMax: time.Now().AddDate(0, 1, 0),
|
|
WithReleaseType: "2|3",
|
|
},
|
|
meta.PageParams.Page,
|
|
meta.Region,
|
|
)
|
|
if err != nil {
|
|
slog.Error("discoverTvUpcoming: Failed to search tmdb!",
|
|
"error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range tmdbRes.Results {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = tmdbRes.Page
|
|
resp.TotalPages = tmdbRes.TotalPages
|
|
resp.TotalResults = int64(tmdbRes.TotalResults)
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverTvPopular(
|
|
meta domain.DiscoverRequestMeta,
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
tmdbRes, err := s.tmdb.DiscoverShows(
|
|
tmdb.DiscoverOptions{},
|
|
meta.PageParams.Page,
|
|
meta.Region,
|
|
)
|
|
if err != nil {
|
|
slog.Error("discoverTvPopular: Failed to search tmdb!",
|
|
"error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range tmdbRes.Results {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = tmdbRes.Page
|
|
resp.TotalPages = tmdbRes.TotalPages
|
|
resp.TotalResults = int64(tmdbRes.TotalResults)
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverPeoplePopular(
|
|
meta domain.DiscoverRequestMeta,
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
tmdbRes, err := s.tmdb.PopularPeople(
|
|
meta.PageParams.Page,
|
|
)
|
|
if err != nil {
|
|
slog.Error("discoverPeoplePopular: Failed to search tmdb!",
|
|
"error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range tmdbRes.Results {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = tmdbRes.Page
|
|
resp.TotalPages = tmdbRes.TotalPages
|
|
resp.TotalResults = int64(tmdbRes.TotalResults)
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverGameTrending(
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
igdbRes, err := s.cfg.TWITCH.Trending()
|
|
if err != nil {
|
|
slog.Error("discoverGameTrending: Failed to search igdb!", "error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range igdbRes {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = 1
|
|
resp.TotalPages = 1
|
|
resp.TotalResults = int64(len(igdbRes))
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) discoverGameUpcoming(
|
|
resp *domain.DiscoverResponse,
|
|
) error {
|
|
igdbRes, err := s.cfg.TWITCH.Upcoming()
|
|
if err != nil {
|
|
slog.Error("discoverGameUpcoming: Failed to search igdb!", "error", err)
|
|
return errors.New("content request failed")
|
|
}
|
|
for _, v := range igdbRes {
|
|
resp.Results = append(
|
|
resp.Results,
|
|
v.AsMedia(),
|
|
)
|
|
}
|
|
resp.Page = 1
|
|
resp.TotalPages = 1
|
|
resp.TotalResults = int64(len(igdbRes))
|
|
return nil
|
|
}
|