Browse Source

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

pull/2284/head
Dean Gardiner 12 years ago
parent
commit
dd5ae3c4ee
  1. 4
      couchpotato/core/helpers/variable.py
  2. 138
      couchpotato/core/media/show/searcher/main.py
  3. 10
      couchpotato/core/plugins/quality/main.py
  4. 23
      couchpotato/core/providers/torrent/iptorrents/main.py

4
couchpotato/core/helpers/variable.py

@ -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:

138
couchpotato/core/media/show/searcher/main.py

@ -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)
show, season, episode = self._lookupMedia(media)
if show is None or season is None:
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
# 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
# Contains lower quality string def correctQuality(self, chain, quality_identifier):
if fireEvent('searcher.contains_other_quality', release, preferred_quality = preferred_quality, single = True): if quality_identifier not in self.quality_map:
log.info2('Wrong: %s, looking for %s', (release['name'], quality['label'])) log.info2('Wrong: unknown preferred quality %s for TV searching', quality_identifier)
return False return False
pprint.pprint(release) 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)

10
couchpotato/core/plugins/quality/main.py

@ -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']

23
couchpotato/core/providers/torrent/iptorrents/main.py

@ -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'])
]) ])
] ]

Loading…
Cancel
Save