Skip to content

Commit

Permalink
Feature: support reviews (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
xjasonlyu authored Dec 13, 2023
1 parent 98539ab commit 3533b66
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 32 deletions.
93 changes: 61 additions & 32 deletions Contents/Code/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,30 @@ class MetaTubeAgent(Agent.Movies):
def parse_filename(filename):
return basename(unquote(filename))

@staticmethod
def get_rating_image(rating):
return 'rottentomatoes://image.rating.ripe' \
if float(rating) >= 6.0 \
else 'rottentomatoes://image.rating.rotten'

@staticmethod
def get_audience_rating_image(rating):
return 'rottentomatoes://image.rating.upright' \
if float(rating) >= 6.0 \
else 'rottentomatoes://image.rating.spilled'

@staticmethod
def get_review_image(rating):
return 'rottentomatoes://image.review.fresh' \
if not rating or float(rating) >= 6.0 \
else 'rottentomatoes://image.review.rotten'

@staticmethod
def get_media_attributes(obj, attr, fn=lambda x: x):
if not hasattr(obj, 'all_parts'):
return ()
return [fn(getattr(part, attr)) for part in obj.all_parts() if hasattr(part, attr)]

@staticmethod
def get_actor_image_url(name):

Expand Down Expand Up @@ -219,14 +243,9 @@ def update(self, metadata, media, lang, force=False):
original_title = m.title
release_date = m.release_date.strftime('%Y-%m-%d')

# Inline magic function
def get_media_files(obj):
if hasattr(obj, 'all_parts'):
return [part.file for part in obj.all_parts() if hasattr(part, 'file')]

# Detect Chinese Subtitles
chinese_subtitle_on = False
for filename in get_media_files(media) or ():
for filename in self.get_media_attributes(media, 'file'):
if has_chinese_subtitle(filename):
chinese_subtitle_on = True
m.genres.append(CHINESE_SUBTITLE)
Expand Down Expand Up @@ -293,37 +312,47 @@ def get_media_files(obj):
if m.runtime:
metadata.duration = m.runtime * 60 * 1000 # millisecond

# Rating Score
if Prefs[KEY_ENABLE_RATINGS] and m.score:
rating = m.score * 2.0
metadata.rating = rating
metadata.rating_image = ('rottentomatoes://image.rating.ripe' if rating >= 7.0
else 'rottentomatoes://image.rating.rotten')
else:
metadata.rating = 0.0
metadata.audience_rating = 0.0
metadata.rating_image = None
metadata.audience_rating_image = None

# Reviews
# Clear ratings
metadata.rating = 0.0
metadata.audience_rating = 0.0
metadata.rating_image = None
metadata.audience_rating_image = None
# Clear reviews
metadata.reviews.clear()

# if None:
# r = metadata.reviews.new()
# r.author = review.get('critic')
# r.source = review.get('publication')
# r.image = 'rottentomatoes://image.review.fresh'
# r.link = review.get('link')
# r.text = review.text

def get_media_durations(obj):
if hasattr(obj, 'all_parts'):
return [int(part.duration) for part in obj.all_parts() if hasattr(part, 'duration')]
# Ratings & Reviews
if Prefs[KEY_ENABLE_RATINGS] and m.score:
metadata.rating = m.score * 2.0
metadata.rating_image = self.get_rating_image(metadata.rating)

if Prefs[KEY_ENABLE_REVIEWS]:
try:
reviews = api.get_movie_reviews(m.provider, m.id, homepage=m.homepage)
except Exception as e:
Log.Warn('Get reviews for {id} failed {error}'.format(id=m.id, error=e))
else:
for review in reviews:
r = metadata.reviews.new()
r.author = review.author
r.source = m.provider
r.image = self.get_review_image(review.score * 2)
r.link = m.homepage
r.text = review.comment
_ = review.title # title is never used

# Audience Rating
scores = float(0)
totals = int(0)
for i in reviews:
if i.score > 0:
scores += i.score
totals += 1
metadata.audience_rating = (scores / totals) * 2
metadata.audience_rating_image = self.get_audience_rating_image(metadata.audience_rating)

# Chapters
metadata.chapters.clear()
# only generate chapters for the first video file
durations = get_media_durations(media)
durations = self.get_media_attributes(media, 'duration', fn=int)
if Prefs[KEY_ENABLE_CHAPTERS] and len(durations) > 0 \
and durations[0] > 10 * 60 * 1000:
duration = durations[0]
Expand Down
17 changes: 17 additions & 0 deletions Contents/Code/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ def __init__(self, **data):
self.preview_video_hls_url = data['preview_video_hls_url'] # type: str


class MovieReviewObject(object):
def __init__(self, **data):
self.title = data['title'] # type: str
self.author = data['author'] # type: str
self.comment = data['comment'] # type: str
self.score = float(data['score']) # type: float
self.date = parse_date(data['date']) # type: datetime


class TranslationInfoObject(object):
def __init__(self, **data):
self.translated_text = data['translated_text'] # type: str
Expand All @@ -93,6 +102,7 @@ class APIError(Exception):
class APIClient(object):
ACTOR_INFO_API = '/v1/actors/{0}/{1}'
MOVIE_INFO_API = '/v1/movies/{0}/{1}'
MOVIE_REVIEW_API = '/v1/reviews/{0}/{1}'
ACTOR_SEARCH_API = '/v1/actors/search'
MOVIE_SEARCH_API = '/v1/movies/search'
PRIMARY_IMAGE_API = '/v1/images/primary/{0}/{1}'
Expand Down Expand Up @@ -169,6 +179,13 @@ def get_movie_info(self, provider, id, lazy=None):
lazy=lazy),
require_auth=True))

def get_movie_reviews(self, provider, id, homepage=None):
return [MovieReviewObject(**data) for data in self.get_json(
url=self.prepare_url(
self.MOVIE_REVIEW_API, provider, id,
homepage=homepage),
require_auth=True)]

def get_primary_image_url(self, provider, id,
url=None,
ratio=None,
Expand Down
1 change: 1 addition & 0 deletions Contents/Code/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
KEY_ENABLE_CHAPTERS = 'enable_chapters'
KEY_ENABLE_DIRECTORS = 'enable_directors'
KEY_ENABLE_RATINGS = 'enable_ratings'
KEY_ENABLE_REVIEWS = 'enable_reviews'
KEY_ENABLE_TRAILERS = 'enable_trailers'
KEY_ENABLE_REAL_ACTOR_NAMES = 'enable_real_actor_names'
KEY_ENABLE_BADGES = 'enable_badges'
Expand Down
6 changes: 6 additions & 0 deletions Contents/DefaultPrefs.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
"type": "bool",
"default": "true"
},
{
"id": "enable_reviews",
"label": "Enable reviews",
"type": "bool",
"default": "true"
},
{
"id": "enable_trailers",
"label": "Enable trailers",
Expand Down

0 comments on commit 3533b66

Please sign in to comment.