Working TV correctRelease function with quality, identifier and show title checking.

This commit is contained in:
Dean Gardiner
2013-09-30 22:03:21 +13:00
parent ab51707607
commit dd5ae3c4ee
4 changed files with 152 additions and 23 deletions
+2 -2
View File
@@ -146,9 +146,9 @@ def getImdb(txt, check_inside = False, multiple = False):
return False return False
def tryInt(s): def tryInt(s, default=0):
try: return int(s) try: return int(s)
except: return 0 except: return default
def tryFloat(s): def tryFloat(s):
try: try:
+129 -9
View File
@@ -1,11 +1,14 @@
import pprint import pprint
import re
from couchpotato import get_session, Env from couchpotato import get_session, Env
from couchpotato.core.event import addEvent, fireEvent from couchpotato.core.event import addEvent, fireEvent
from couchpotato.core.helpers.variable import getTitle from couchpotato.core.helpers.encoding import simplifyString
from couchpotato.core.helpers.variable import getTitle, tryInt, possibleTitles
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.media._base.searcher.main import SearchSetupError from couchpotato.core.media._base.searcher.main import SearchSetupError
from couchpotato.core.plugins.base import Plugin from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Media from couchpotato.core.settings.model import Media, Library
from caper import Caper
log = CPLog(__name__) log = CPLog(__name__)
@@ -14,6 +17,15 @@ class ShowSearcher(Plugin):
in_progress = False in_progress = False
# TODO come back to this later, think this could be handled better
quality_map = {
'webdl_1080p': {'resolution': ['1080p'], 'source': ['webdl']},
'webdl_720p': {'resolution': ['720p'], 'source': ['webdl']},
'hdtv_720p': {'resolution': ['720p'], 'source': ['hdtv']},
'hdtv_sd': {'resolution': ['480p', None], 'source': ['hdtv']},
}
def __init__(self): def __init__(self):
super(ShowSearcher, self).__init__() super(ShowSearcher, self).__init__()
@@ -21,10 +33,12 @@ class ShowSearcher(Plugin):
addEvent('searcher.correct_release', self.correctRelease) addEvent('searcher.correct_release', self.correctRelease)
addEvent('searcher.get_search_title', self.getSearchTitle) addEvent('searcher.get_search_title', self.getSearchTitle)
self.caper = Caper()
def _lookupMedia(self, media): def _lookupMedia(self, media):
db = get_session() db = get_session()
media_library = db.query(Media).filter_by(id = media['id']).first().library media_library = db.query(Library).filter_by(id = media['library_id']).first()
show = None show = None
season = None season = None
@@ -45,6 +59,8 @@ class ShowSearcher(Plugin):
return show, season, episode return show, season, episode
def single(self, media, search_protocols = None): def single(self, media, search_protocols = None):
pprint.pprint(media)
if media['type'] == 'show': if media['type'] == 'show':
# TODO handle show searches (scan all seasons) # TODO handle show searches (scan all seasons)
return return
@@ -70,7 +86,7 @@ class ShowSearcher(Plugin):
found_releases = [] found_releases = []
too_early_to_search = [] too_early_to_search = []
default_title = getTitle(media['library']) default_title = self.getSearchTitle(media['library'])
if not default_title: if not default_title:
log.error('No proper info found for episode, removing it from library to cause it from having more issues.') log.error('No proper info found for episode, removing it from library to cause it from having more issues.')
#fireEvent('episode.delete', episode['id'], single = True) #fireEvent('episode.delete', episode['id'], single = True)
@@ -126,14 +142,118 @@ class ShowSearcher(Plugin):
if not fireEvent('searcher.correct_words', release['name'], media, single = True): if not fireEvent('searcher.correct_words', release['name'], media, single = True):
return False return False
preferred_quality = fireEvent('quality.single', identifier = quality['identifier'], single = True) #pprint.pprint(release)
# Contains lower quality string show, season, episode = self._lookupMedia(media)
if fireEvent('searcher.contains_other_quality', release, preferred_quality = preferred_quality, single = True): if show is None or season is None:
log.info2('Wrong: %s, looking for %s', (release['name'], quality['label'])) log.error('Unable to find show or season library in database, missing required data for searching')
return
release_info = self.caper.parse(release['name'])
if len(release_info.chains) < 1:
log.info2('Wrong: %s, unable to parse release name (no chains)', release['name'])
return False return False
pprint.pprint(release) # TODO look at all chains
chain = release_info.chains[0]
if not self.correctQuality(chain, quality['identifier']):
log.info('Wrong: %s, quality does not match', release['name'])
return False
if not self.correctIdentifier(chain, media):
log.info('Wrong: %s, identifier does not match', release['name'])
return False
#print chain.weight
#pprint.pprint(chain.info)
if 'show_name' not in chain.info or not len(chain.info['show_name']):
log.info('Wrong: %s, missing show name in parsed result', release['name'])
return False
chain_words = [x.lower() for x in chain.info['show_name']]
chain_title = ' '.join(chain_words)
library_title = None
# Check show titles match
for raw_title in show.titles:
for valid_words in [x.split(' ') for x in possibleTitles(raw_title.title)]:
if not library_title:
library_title = ' '.join(valid_words)
if valid_words == chain_words:
return True
log.info("Wrong: title '%s', undetermined show naming. Looking for '%s (%s)'", (chain_title, library_title, media['library']['year']))
return False
def correctQuality(self, chain, quality_identifier):
if quality_identifier not in self.quality_map:
log.info2('Wrong: unknown preferred quality %s for TV searching', quality_identifier)
return False
if 'video' not in chain.info:
log.info2('Wrong: no video tags found')
return False
video_tags = self.quality_map[quality_identifier]
if not self.chainMatches(chain, 'video', video_tags):
log.info2('Wrong: %s tags not in chain', video_tags)
return False
return True
def correctIdentifier(self, chain, media):
required_id = self.getIdentifier(media['library'], 'season_number', 'episode_number')
if 'identifier' not in chain.info:
return False
# TODO could be handled better?
if len(chain.info['identifier']) != 1:
return False
identifier = chain.info['identifier'][0]
# TODO air by date episodes
release_id = self.getIdentifier(identifier, 'season', 'episode')
if required_id != release_id:
log.info2('Wrong: required identifier %s does not match release identifier %s', (str(required_id), str(release_id)))
return False
return True
def getIdentifier(self, d, episode_key, season_key):
return (
tryInt(d.get(season_key), None) if season_key in d else None,
tryInt(d.get(episode_key), None) if episode_key in d else None
)
def chainMatches(self, chain, group, tags):
found_tags = []
for match in chain.info[group]:
for ck, cv in match.items():
if ck in tags and self.cleanMatchValue(cv) in tags[ck]:
found_tags.append(ck)
if set(tags.keys()) == set(found_tags):
return True
return set([key for key, value in tags.items() if value]) == set(found_tags)
def cleanMatchValue(self, value):
value = value.lower()
value = value.strip()
for ch in [' ', '-', '.']:
value = value.replace(ch, '')
return value
def getSearchTitle(self, media): def getSearchTitle(self, media):
show, season, episode = self._lookupMedia(media) show, season, episode = self._lookupMedia(media)
+9 -1
View File
@@ -26,7 +26,15 @@ class QualityPlugin(Plugin):
{'identifier': 'r5', 'size': (600, 1000), 'label': 'R5', 'alternative': ['r6'], 'allow': ['dvdr'], 'ext':['avi', 'mpg', 'mpeg']}, {'identifier': 'r5', 'size': (600, 1000), 'label': 'R5', 'alternative': ['r6'], 'allow': ['dvdr'], 'ext':['avi', 'mpg', 'mpeg']},
{'identifier': 'tc', 'size': (600, 1000), 'label': 'TeleCine', 'alternative': ['telecine'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']}, {'identifier': 'tc', 'size': (600, 1000), 'label': 'TeleCine', 'alternative': ['telecine'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']},
{'identifier': 'ts', 'size': (600, 1000), 'label': 'TeleSync', 'alternative': ['telesync', 'hdts'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']}, {'identifier': 'ts', 'size': (600, 1000), 'label': 'TeleSync', 'alternative': ['telesync', 'hdts'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']},
{'identifier': 'cam', 'size': (600, 1000), 'label': 'Cam', 'alternative': ['camrip', 'hdcam'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']} {'identifier': 'cam', 'size': (600, 1000), 'label': 'Cam', 'alternative': ['camrip', 'hdcam'], 'allow': [], 'ext':['avi', 'mpg', 'mpeg']},
# TODO come back to this later, think this could be handled better
# WEB-DL
{'identifier': 'webdl_1080p', 'hd': True, 'size': (800, 5000), 'label': 'WEB-DL - 1080p', 'width': 1920, 'height': 1080, 'alternative': [], 'allow': [], 'ext':['mkv']},
{'identifier': 'webdl_720p', 'hd': True, 'size': (800, 5000), 'label': 'WEB-DL - 720p', 'width': 1280, 'height': 720, 'alternative': [], 'allow': [], 'ext':['mkv']},
# HDTV
{'identifier': 'hdtv_720p', 'hd': True, 'size': (800, 5000), 'label': 'HDTV - 720p', 'width': 1280, 'height': 720, 'alternative': [], 'allow': [], 'ext':['mkv']},
{'identifier': 'hdtv_sd', 'hd': False, 'size': (100, 1000), 'label': 'HDTV - SD', 'width': 720, 'alternative': [], 'allow': [], 'ext':['mkv', 'mp4', 'avi']},
] ]
pre_releases = ['cam', 'ts', 'tc', 'r5', 'scr'] pre_releases = ['cam', 'ts', 'tc', 'r5', 'scr']
@@ -36,21 +36,22 @@ class Base(TorrentProvider):
log.warning('Unable to find category for quality %s', quality_identifier) log.warning('Unable to find category for quality %s', quality_identifier)
return return
return self.urls['search'] % (cat_id, tryUrlencode(query)) return self.urls['search'] % (cat_id, tryUrlencode(query).replace('%', '%%'))
def _searchOnTitle(self, title, media, quality, results): def _searchOnTitle(self, title, media, quality, results):
freeleech = '' if not self.conf('freeleech') else '&free=on' freeleech = '' if not self.conf('freeleech') else '&free=on'
base_url = self.buildUrl(title, media, quality)
if not base_url: return
pages = 1 pages = 1
current_page = 1 current_page = 1
while current_page <= pages and not self.shuttingDown(): while current_page <= pages and not self.shuttingDown():
url = self.buildUrl(title, media, quality) data = self.getHTMLData(
if not url: return base_url % (freeleech, current_page),
opener = self.login_opener
url = url % (freeleech, current_page) )
data = self.getHTMLData(url, opener = self.login_opener)
if data: if data:
html = BeautifulSoup(data) html = BeautifulSoup(data)
@@ -135,12 +136,12 @@ class Show(ShowProvider, Base):
cat_ids = [ cat_ids = [
('season', [ ('season', [
([65], ['hdtv', '480p', '720p', '1080p']), ([65], ['hdtv_sd', 'hdtv_720p', 'webdl_720p', 'webdl_1080p']),
]), ]),
('episode', [ ('episode', [
([5], ['720p', '1080p']), ([5], ['hdtv_720p', 'webdl_720p', 'webdl_1080p']),
([78], ['480p']), ([78], ['hdtv_sd']),
([4, 79], ['hdtv']) ([4, 79], ['hdtv_sd'])
]) ])
] ]