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
def tryInt(s):
def tryInt(s, default=0):
try: return int(s)
except: return 0
except: return default
def tryFloat(s):
try:

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

@ -1,11 +1,14 @@
import pprint
import re
from couchpotato import get_session, Env
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.media._base.searcher.main import SearchSetupError
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__)
@ -14,6 +17,15 @@ class ShowSearcher(Plugin):
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):
super(ShowSearcher, self).__init__()
@ -21,10 +33,12 @@ class ShowSearcher(Plugin):
addEvent('searcher.correct_release', self.correctRelease)
addEvent('searcher.get_search_title', self.getSearchTitle)
self.caper = Caper()
def _lookupMedia(self, media):
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
season = None
@ -45,6 +59,8 @@ class ShowSearcher(Plugin):
return show, season, episode
def single(self, media, search_protocols = None):
pprint.pprint(media)
if media['type'] == 'show':
# TODO handle show searches (scan all seasons)
return
@ -70,7 +86,7 @@ class ShowSearcher(Plugin):
found_releases = []
too_early_to_search = []
default_title = getTitle(media['library'])
default_title = self.getSearchTitle(media['library'])
if not default_title:
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)
@ -126,14 +142,118 @@ class ShowSearcher(Plugin):
if not fireEvent('searcher.correct_words', release['name'], media, single = True):
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
if fireEvent('searcher.contains_other_quality', release, preferred_quality = preferred_quality, single = True):
log.info2('Wrong: %s, looking for %s', (release['name'], quality['label']))
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
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):
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': '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': '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']

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)
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):
freeleech = '' if not self.conf('freeleech') else '&free=on'
base_url = self.buildUrl(title, media, quality)
if not base_url: return
pages = 1
current_page = 1
while current_page <= pages and not self.shuttingDown():
url = self.buildUrl(title, media, quality)
if not url: return
url = url % (freeleech, current_page)
data = self.getHTMLData(url, opener = self.login_opener)
data = self.getHTMLData(
base_url % (freeleech, current_page),
opener = self.login_opener
)
if data:
html = BeautifulSoup(data)
@ -135,12 +136,12 @@ class Show(ShowProvider, Base):
cat_ids = [
('season', [
([65], ['hdtv', '480p', '720p', '1080p']),
([65], ['hdtv_sd', 'hdtv_720p', 'webdl_720p', 'webdl_1080p']),
]),
('episode', [
([5], ['720p', '1080p']),
([78], ['480p']),
([4, 79], ['hdtv'])
([5], ['hdtv_720p', 'webdl_720p', 'webdl_1080p']),
([78], ['hdtv_sd']),
([4, 79], ['hdtv_sd'])
])
]

Loading…
Cancel
Save