mirror of
https://github.com/SickGear/SickGear.git
synced 2024-11-22 04:45:05 +00:00
Merge branch 'main' into dev
This commit is contained in:
commit
6bda4d7c8f
4 changed files with 79 additions and 63 deletions
|
@ -19,6 +19,12 @@
|
||||||
* Add search of grouped options in shows drop down at view-show
|
* Add search of grouped options in shows drop down at view-show
|
||||||
|
|
||||||
|
|
||||||
|
### 3.29.10 (2023-09-19 12:55:00 UTC)
|
||||||
|
|
||||||
|
* Fix Metacritic cards
|
||||||
|
* Fix Linux CI tests
|
||||||
|
|
||||||
|
|
||||||
### 3.29.9 (2023-09-17 23:25:00 UTC)
|
### 3.29.9 (2023-09-17 23:25:00 UTC)
|
||||||
|
|
||||||
* Fix Emby notifier library update
|
* Fix Emby notifier library update
|
||||||
|
|
|
@ -418,12 +418,12 @@ $(document).ready(function(){
|
||||||
#elif 'Metacritic' == $browse_type
|
#elif 'Metacritic' == $browse_type
|
||||||
<optgroup label="Metacritic">
|
<optgroup label="Metacritic">
|
||||||
<option value="mc_newseries"#echo ('', selected)['newseries' == $mode]#>New seasons</option>
|
<option value="mc_newseries"#echo ('', selected)['newseries' == $mode]#>New seasons</option>
|
||||||
<option value="mc_90days"#echo ('', selected)['90days' == $mode]#>Last 90 days</option>
|
<option value="mc_explore"#echo ('', selected)['explore' == $mode]#>Explore</option>
|
||||||
<option value="mc_year"#echo ('', selected)['year' == $mode]#>By year</option>
|
<option value="mc_popular"#echo ('', selected)['popular' == $mode]#>Popular</option>
|
||||||
<option value="mc_discussed"#echo ('', selected)['discussed' == $mode]#>Most discussed</option>
|
<option value="mc_metascore"#echo ('', selected)['metascore' == $mode]#>By metascore</option>
|
||||||
<option value="mc_shared"#echo ('', selected)['shared' == $mode]#>Most shared</option>
|
<option value="mc_userscore"#echo ('', selected)['userscore' == $mode]#>By userscore</option>
|
||||||
#if $kwargs and $kwargs.get('more') and 'newseries' in $mode
|
#if $kwargs and $kwargs.get('more')
|
||||||
<option value="mc_newseries?more=1"#echo ('', selected + ' disabled')[mode.endswith('more')]#>... list more</option>
|
<option value="mc_#echo $mode#?more=1"#echo ('', selected + ' disabled')[mode.endswith('more')]#>... list more</option>
|
||||||
#end if
|
#end if
|
||||||
</optgroup>
|
</optgroup>
|
||||||
#elif 'TMDB' == $browse_type
|
#elif 'TMDB' == $browse_type
|
||||||
|
|
|
@ -5002,23 +5002,23 @@ class AddShows(Home):
|
||||||
|
|
||||||
def mc_newseries(self, **kwargs):
|
def mc_newseries(self, **kwargs):
|
||||||
return self.browse_mc(
|
return self.browse_mc(
|
||||||
'release-date/new-series/date?', 'New Series at Metacritic', mode='newseries', **kwargs)
|
'/all/all/all-time/new/', 'New Series at Metacritic', mode='newseries', **kwargs)
|
||||||
|
|
||||||
def mc_90days(self, **kwargs):
|
def mc_explore(self, **kwargs):
|
||||||
return self.browse_mc(
|
return self.browse_mc(
|
||||||
'score/metascore/90day/filtered?sort=desc&', 'Last 90 days at Metacritic', mode='90days', **kwargs)
|
'/', 'Explore at Metacritic', mode='explore', **kwargs)
|
||||||
|
|
||||||
def mc_year(self, **kwargs):
|
def mc_popular(self, **kwargs):
|
||||||
return self.browse_mc(
|
return self.browse_mc(
|
||||||
'score/metascore/year/filtered?sort=desc&', 'By year at Metacritic', mode='year', **kwargs)
|
'/all/all/all-time/popular/', 'Popular at Metacritic', mode='popular', **kwargs)
|
||||||
|
|
||||||
def mc_discussed(self, **kwargs):
|
def mc_metascore(self, **kwargs):
|
||||||
return self.browse_mc(
|
return self.browse_mc(
|
||||||
'score/metascore/discussed/filtered?sort=desc&', 'Most discussed at Metacritic', mode='discussed', **kwargs)
|
'/all/all/all-time/metascore/', 'By metascore at Metacritic', mode='metascore', **kwargs)
|
||||||
|
|
||||||
def mc_shared(self, **kwargs):
|
def mc_userscore(self, **kwargs):
|
||||||
return self.browse_mc(
|
return self.browse_mc(
|
||||||
'score/metascore/shared/filtered?sort=desc&', 'Most shared at Metacritic', mode='shared', **kwargs)
|
'/all/all/all-time/userscore/', 'By userscore at Metacritic', mode='userscore', **kwargs)
|
||||||
|
|
||||||
def browse_mc(self, url_path, browse_title, **kwargs):
|
def browse_mc(self, url_path, browse_title, **kwargs):
|
||||||
|
|
||||||
|
@ -5026,77 +5026,87 @@ class AddShows(Home):
|
||||||
|
|
||||||
footnote = None
|
footnote = None
|
||||||
|
|
||||||
page = 'more' in kwargs and '&page=1' or ''
|
page = 'more' in kwargs and '&page=2' or ''
|
||||||
if page:
|
if page:
|
||||||
kwargs['mode'] += '-more'
|
kwargs['mode'] += '-more'
|
||||||
|
|
||||||
filtered = []
|
filtered = []
|
||||||
|
|
||||||
import browser_ua
|
import browser_ua
|
||||||
url = 'https://www.metacritic.com/browse/tv/%sview=detailed%s' % (url_path, page)
|
this_year = datetime.datetime.today().strftime('%Y')
|
||||||
|
url = f'https://www.metacritic.com/browse/tv{url_path}' \
|
||||||
|
f'?releaseYearMin={this_year}&releaseYearMax={this_year}{page}'
|
||||||
html = helpers.get_url(url, headers={'User-Agent': browser_ua.get_ua()})
|
html = helpers.get_url(url, headers={'User-Agent': browser_ua.get_ua()})
|
||||||
if html:
|
if html:
|
||||||
try:
|
try:
|
||||||
if re.findall('(<a[^>]+rel="next"[^>]+)', html)[0]:
|
if re.findall('(c-navigationPagination_item--next)', html)[0]:
|
||||||
kwargs.update(dict(more=1))
|
kwargs.update(dict(more=1))
|
||||||
except (BaseException, Exception):
|
except (BaseException, Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with BS4Parser(html, parse_only=dict(table={'class': (lambda at: at and 'clamp-list' in at)})) as tbl:
|
with BS4Parser(html, parse_only=dict(div={'class': (lambda at: at and 'c-productListings' in at)})) as soup:
|
||||||
# with BS4Parser(html, features=['html5lib', 'permissive']) as soup:
|
items = [] if not soup else soup.select('.c-finderProductCard_container')
|
||||||
items = [] if not tbl else tbl.find_all('tr')
|
|
||||||
oldest, newest, oldest_dt, newest_dt = None, None, 9999999, 0
|
oldest, newest, oldest_dt, newest_dt = None, None, 9999999, 0
|
||||||
for cur_row in items:
|
rc_title = re.compile(r'(?i)(?::\s*season\s*\d+|\s*\((?:19|20)\d{2}\))?$')
|
||||||
|
rc_id = re.compile(r'(?i)[^A-Z0-9]')
|
||||||
|
rc_img = re.compile(r'(.*?)(/resize/[^?]+)?(/catalog/provider.*?\.(?:jpg|png)).*')
|
||||||
|
rc_season = re.compile(r'(\d+)(?:[.]\d*?)?$')
|
||||||
|
for idx, cur_row in enumerate(items):
|
||||||
try:
|
try:
|
||||||
ids = dict(custom=cur_row.select('input[type="checkbox"]')[0].attrs['id'], name='mc')
|
title = rc_title.sub(
|
||||||
info = cur_row.find('a', href=re.compile('^/tv'))
|
'', cur_row.find('div', class_='c-finderProductCard_title').get('data-title').strip())
|
||||||
url_path = info['href'].strip()
|
|
||||||
|
|
||||||
images = {}
|
# 2023-09-23 deprecated id at site, using title as id
|
||||||
img_uri = None
|
# ids = dict(custom=cur_row.select('input[type="checkbox"]')[0].attrs['id'], name='mc')
|
||||||
img = info.find('img')
|
ids = dict(custom=rc_id.sub('', title), name='mc')
|
||||||
if img and isinstance(img.attrs, dict):
|
|
||||||
title = img.attrs.get('alt')
|
url_path = cur_row['href'].strip()
|
||||||
img_src = img.attrs.get('src').split('-')
|
if not url_path.startswith('/tv/'):
|
||||||
img_uri = img_src.pop(0)
|
continue
|
||||||
|
|
||||||
|
images = None
|
||||||
|
img_src = (cur_row.find('img') or {}).get('src', '').strip()
|
||||||
if img_src:
|
if img_src:
|
||||||
img_uri += '.' + img_src[0].split('.')[-1]
|
img_uri = rc_img.sub(r'\1\3', img_src)
|
||||||
images = dict(poster=dict(thumb='imagecache?path=browse/thumb/metac&source=%s' % img_uri))
|
images = dict(poster=dict(thumb=f'imagecache?path=browse/thumb/metac&source={img_uri}'))
|
||||||
sickgear.CACHE_IMAGE_URL_LIST.add_url(img_uri)
|
sickgear.CACHE_IMAGE_URL_LIST.add_url(img_uri)
|
||||||
if not title:
|
|
||||||
title = cur_row.find('h3').get_text()
|
|
||||||
title = re.sub(r'(?i)(?::\s*season\s*\d+|\s*\((?:19|20)\d{2}\))?$', '', title.strip())
|
|
||||||
|
|
||||||
ord_premiered = 0
|
ord_premiered = 0
|
||||||
str_premiered = ''
|
str_premiered = ''
|
||||||
started_past = False
|
started_past = False
|
||||||
date_tags = list(filter(lambda t: t.find('span'),
|
|
||||||
cur_row.find_all('div', class_='clamp-details')))
|
dated = None
|
||||||
if date_tags:
|
rating = None
|
||||||
|
rating_user = None # 2023-09-23 deprecated at site
|
||||||
|
meta_tags = cur_row.find_all('div', class_='c-finderProductCard_meta')
|
||||||
|
for tag in meta_tags:
|
||||||
|
meta_tag = tag.find('span', class_='u-text-uppercase')
|
||||||
|
if not dated and meta_tag:
|
||||||
|
dated = meta_tag
|
||||||
|
try: # a bad date caused a sanitise exception here
|
||||||
ord_premiered, str_premiered, started_past, oldest_dt, newest_dt, oldest, newest, \
|
ord_premiered, str_premiered, started_past, oldest_dt, newest_dt, oldest, newest, \
|
||||||
_, _, _, _ \
|
_, _, _, _ = self.sanitise_dates(dated.get_text().strip(), oldest_dt, newest_dt,
|
||||||
= self.sanitise_dates(date_tags[0].get_text().strip(), oldest_dt, newest_dt,
|
|
||||||
oldest, newest)
|
oldest, newest)
|
||||||
|
|
||||||
overview = cur_row.find('div', class_='summary').get_text().strip()
|
|
||||||
|
|
||||||
rating = cur_row.find('div', class_='clamp-metascore')
|
|
||||||
if rating:
|
|
||||||
rating = rating.find('div', class_='metascore_w')
|
|
||||||
if rating:
|
|
||||||
rating = rating.get_text().strip()
|
|
||||||
rating_user = cur_row.find('div', class_='clamp-userscore')
|
|
||||||
if rating_user:
|
|
||||||
rating_user = rating_user.find('div', class_='metascore_w')
|
|
||||||
if rating_user:
|
|
||||||
rating_user = rating_user.get_text().strip()
|
|
||||||
|
|
||||||
season = -1
|
|
||||||
try:
|
|
||||||
season = re.findall(r'(\d+)(?:[.]\d*?)?$', url_path)[0]
|
|
||||||
except (BaseException, Exception):
|
except (BaseException, Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
meta_tag = tag.find('div', class_='c-siteReviewScore')
|
||||||
|
if not rating and meta_tag:
|
||||||
|
rating = meta_tag
|
||||||
|
rating = rating.get_text().strip()
|
||||||
|
|
||||||
|
if dated and rating:
|
||||||
|
break
|
||||||
|
|
||||||
|
overview = cur_row.find('div', class_='c-finderProductCard_description')
|
||||||
|
if overview:
|
||||||
|
overview = helpers.xhtml_escape(overview.get_text().strip()[:250:])
|
||||||
|
|
||||||
|
try:
|
||||||
|
season = rc_season.findall(url_path)[0]
|
||||||
|
except(BaseException, Exception):
|
||||||
|
season = -1
|
||||||
|
|
||||||
filtered.append(dict(
|
filtered.append(dict(
|
||||||
ord_premiered=ord_premiered,
|
ord_premiered=ord_premiered,
|
||||||
str_premiered=str_premiered,
|
str_premiered=str_premiered,
|
||||||
|
@ -5104,12 +5114,12 @@ class AddShows(Home):
|
||||||
episode_season=int(season),
|
episode_season=int(season),
|
||||||
genres='',
|
genres='',
|
||||||
ids=ids,
|
ids=ids,
|
||||||
images='' if not img_uri else images,
|
images=images or '',
|
||||||
overview='No overview yet' if not overview else helpers.xhtml_escape(overview[:250:]),
|
overview=overview or 'No overview yet',
|
||||||
rating=0 if not rating else rating or 'TBD',
|
rating=0 if not rating else rating or 'TBD',
|
||||||
rating_user='tbd' if not rating_user else int(helpers.try_float(rating_user) * 10) or 'tbd',
|
rating_user='tbd' if not rating_user else int(helpers.try_float(rating_user) * 10) or 'tbd',
|
||||||
title=title,
|
title=title,
|
||||||
url_src_db='https://www.metacritic.com/%s/' % url_path.strip('/'),
|
url_src_db=f'https://www.metacritic.com/{url_path.strip("/")}/',
|
||||||
votes=None))
|
votes=None))
|
||||||
|
|
||||||
except (AttributeError, IndexError, KeyError, TypeError):
|
except (AttributeError, IndexError, KeyError, TypeError):
|
||||||
|
@ -5121,7 +5131,7 @@ class AddShows(Home):
|
||||||
|
|
||||||
mode = kwargs.get('mode', '')
|
mode = kwargs.get('mode', '')
|
||||||
if mode:
|
if mode:
|
||||||
func = 'mc_%s' % mode
|
func = f'mc_{mode}'
|
||||||
if callable(getattr(self, func, None)):
|
if callable(getattr(self, func, None)):
|
||||||
sickgear.MC_MRU = func
|
sickgear.MC_MRU = func
|
||||||
sickgear.save_config()
|
sickgear.save_config()
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
import datetime
|
import datetime
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import test_lib as test # must be before import sickgear
|
||||||
import sickgear
|
import sickgear
|
||||||
import test_lib as test
|
|
||||||
from sickgear import db
|
from sickgear import db
|
||||||
from sickgear.common import Quality, UNAIRED, SKIPPED, WANTED, WantedQualities, statusStrings
|
from sickgear.common import Quality, UNAIRED, SKIPPED, WANTED, WantedQualities, statusStrings
|
||||||
from sickgear.show_queue import QueueItemAdd
|
from sickgear.show_queue import QueueItemAdd
|
||||||
|
|
Loading…
Reference in a new issue