MetaTube / engine /review.go
henry99a's picture
Clean commit for Hugging Face Spaces without binary files
ca7217f
package engine
import (
"fmt"
"gorm.io/datatypes"
"gorm.io/gorm/clause"
"github.com/metatube-community/metatube-sdk-go/engine/providerid"
"github.com/metatube-community/metatube-sdk-go/model"
mt "github.com/metatube-community/metatube-sdk-go/provider"
)
func (e *Engine) getMovieReviewsFromDB(provider mt.MovieProvider, id string) (*model.MovieReviewInfo, error) {
info := &model.MovieReviewInfo{}
err := e.db. // Exact match here.
Where("provider = ?", provider.Name()).
Where("id = ? COLLATE NOCASE", id).
First(info).Error
return info, err
}
func (e *Engine) getMovieReviewsWithCallback(provider mt.MovieProvider, id string, lazy bool,
callback func() ([]*model.MovieReviewDetail, error),
) (info *model.MovieReviewInfo, err error) {
defer func() {
// metadata validation check.
if err == nil && (info == nil || !info.IsValid()) {
err = mt.ErrIncompleteMetadata
}
}()
// Query DB first (by id).
if lazy {
if info, err = e.getMovieReviewsFromDB(provider, id); err == nil && info.IsValid() {
return // ignore DB query error.
}
}
// delayed info auto-save.
defer func() {
if err == nil && info.IsValid() {
e.db.Clauses(clause.OnConflict{
UpdateAll: true,
}).Create(info) // ignore error
}
}()
var reviews []*model.MovieReviewDetail
if reviews, err = callback(); err != nil {
return
}
info = &model.MovieReviewInfo{
ID: id,
Provider: provider.Name(),
Reviews: datatypes.NewJSONSlice(reviews),
}
return
}
func (e *Engine) getMovieReviewsByProviderID(provider mt.MovieProvider, id string, lazy bool) (*model.MovieReviewInfo, error) {
if id = provider.NormalizeMovieID(id); id == "" {
return nil, mt.ErrInvalidID
}
reviewer, ok := provider.(mt.MovieReviewer)
if !ok {
return nil, fmt.Errorf("reviews not supported by %s", provider.Name())
}
return e.getMovieReviewsWithCallback(provider, id, lazy, func() ([]*model.MovieReviewDetail, error) {
return reviewer.GetMovieReviewsByID(id)
})
}
func (e *Engine) GetMovieReviewsByProviderID(pid providerid.ProviderID, lazy bool) (*model.MovieReviewInfo, error) {
provider, err := e.GetMovieProviderByName(pid.Provider)
if err != nil {
return nil, err
}
return e.getMovieReviewsByProviderID(provider, pid.ID, lazy)
}
func (e *Engine) getMovieReviewsByProviderURL(provider mt.MovieProvider, rawURL string, lazy bool) (*model.MovieReviewInfo, error) {
id, err := provider.ParseMovieIDFromURL(rawURL)
switch {
case err != nil:
return nil, err
case id == "":
return nil, mt.ErrInvalidURL
}
reviewer, ok := provider.(mt.MovieReviewer)
if !ok {
return nil, fmt.Errorf("reviews not supported by %s", provider.Name())
}
return e.getMovieReviewsWithCallback(provider, id, lazy, func() ([]*model.MovieReviewDetail, error) {
return reviewer.GetMovieReviewsByURL(rawURL)
})
}
func (e *Engine) GetMovieReviewsByProviderURL(rawURL string, lazy bool) (*model.MovieReviewInfo, error) {
provider, err := e.GetMovieProviderByURL(rawURL)
if err != nil {
return nil, err
}
return e.getMovieReviewsByProviderURL(provider, rawURL, lazy)
}