Added ability to set a default indexer for trakt notifier used for adding shows from watch list so that SickRage knows what indexer to set the show as.

Indexer mapping now uses indexer api calls to gather its information and then stores it to a new table called indexer_mapping for instant lookups later on.

Fixed trakt related issues for adding new shows and syncing.

Centered items at bottom of pages to just look a little nicer and fit properly.
This commit is contained in:
echel0n 2014-07-23 21:44:11 -07:00
parent b63dffa3a0
commit de5db9be64
20 changed files with 278 additions and 241 deletions

View file

@ -1184,6 +1184,20 @@
<span class="component-desc">Get your key at: <a href="http://trakt.tv/settings/api" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">http://trakt.tv/settings/api</a></span> <span class="component-desc">Get your key at: <a href="http://trakt.tv/settings/api" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">http://trakt.tv/settings/api</a></span>
</label> </label>
</div> </div>
<div class="field-pair">
<label class="nocheck clearfix" for="trakt_default_indexer">
<span class="component-title">Default Indexer:</span>
<span class="component-desc">
<select id="trakt_default_indexer" name="trakt_default_indexer">
#for $indexer in $sickbeard.indexerApi().indexers
<option value="$indexer" #if $indexer == $sickbeard.TRAKT_DEFAULT_INDEXER then "selected=\"selected\"" else ""#>$sickbeard.indexerApi().indexers[$indexer]</option>
#end for
</select>
</span>
</label>
</div
</div>
<div class="field-pair"> <div class="field-pair">
<input type="checkbox" class="enabler" name="trakt_sync" id="trakt_sync" #if $sickbeard.TRAKT_SYNC then "checked=\"checked\"" else ""# /> <input type="checkbox" class="enabler" name="trakt_sync" id="trakt_sync" #if $sickbeard.TRAKT_SYNC then "checked=\"checked\"" else ""# />
<label class="clearfix" for="trakt_sync"> <label class="clearfix" for="trakt_sync">

View file

@ -7,7 +7,7 @@
</div> </div>
<div class="footer clearfix"> <div class="footer clearfix">
<div class="meta" style="float:left;font-size: 12px;"> <div class="meta" style="float:center;font-size: 12px;">
#set $myDB = $db.DBConnection() #set $myDB = $db.DBConnection()
#set $today = str($datetime.date.today().toordinal()) #set $today = str($datetime.date.today().toordinal())
#set status_quality = '(' + ','.join([str(quality) for quality in $Quality.SNATCHED + $Quality.SNATCHED_PROPER]) + ')' #set status_quality = '(' + ','.join([str(quality) for quality in $Quality.SNATCHED + $Quality.SNATCHED_PROPER]) + ')'
@ -40,15 +40,13 @@
#end if #end if
<b>$shows_total</b> Shows (<b>$shows_active</b> Active) <b>|</b> <b><%=ep_downloaded%>#if $ep_snatched > 0 then " (+" + str($ep_snatched) + " snatched)" else ""# / $ep_total</b> Episodes Downloaded <b>|</b> Daily Search: <b><%=str(sickbeard.dailySearchScheduler.timeLeft()).split('.')[0]%></b> <b>|</b> Backlog Search: <b>$sbdatetime.sbdatetime.sbfdate($sickbeard.backlogSearchScheduler.nextRun())</b> <b>$shows_total</b> Shows (<b>$shows_active</b> Active) <b>|</b> <b><%=ep_downloaded%>#if $ep_snatched > 0 then " (+" + str($ep_snatched) + " snatched)" else ""# / $ep_total</b> Episodes Downloaded <b>|</b> Daily Search: <b><%=str(sickbeard.dailySearchScheduler.timeLeft()).split('.')[0]%></b> <b>|</b> Backlog Search: <b>$sbdatetime.sbdatetime.sbfdate($sickbeard.backlogSearchScheduler.nextRun())</b>
<p>
</div> <a href="$sbRoot/manage/manageSearches/forceVersionCheck"><img src="$sbRoot/images/menu/update16.png" alt="" width="16" height="16" />Force Version Check</a>
<a href="$sbRoot/home/restart/?pid=$sbPID" class="confirm"><img src="$sbRoot/images/menu/restart16.png" alt="" width="16" height="16" />Restart</a>
<a href="$sbRoot/home/shutdown/?pid=$sbPID" class="confirm"><img src="$sbRoot/images/menu/shutdown16.png" alt="" width="16" height="16" />Shutdown</a>
<ul style="float:right; font-size: 12px;"> </div>
<li><a href="$sbRoot/manage/manageSearches/forceVersionCheck"><img src="$sbRoot/images/menu/update16.png" alt="" width="16" height="16" />Force Version Check</a></li>
<li><a href="$sbRoot/home/restart/?pid=$sbPID" class="confirm"><img src="$sbRoot/images/menu/restart16.png" alt="" width="16" height="16" />Restart</a></li>
<li><a href="$sbRoot/home/shutdown/?pid=$sbPID" class="confirm"><img src="$sbRoot/images/menu/shutdown16.png" alt="" width="16" height="16" />Shutdown</a></li>
</ul>
</div> </div>
</body> </body>
</html> </html>

View file

@ -534,6 +534,11 @@ class Tvdb:
self.config['url_seriesBanner'] = u"%(base_url)s/api/%(apikey)s/series/%%s/banners.xml" % self.config self.config['url_seriesBanner'] = u"%(base_url)s/api/%(apikey)s/series/%%s/banners.xml" % self.config
self.config['url_artworkPrefix'] = u"%(base_url)s/banners/%%s" % self.config self.config['url_artworkPrefix'] = u"%(base_url)s/banners/%%s" % self.config
self.config['url_updates_all'] = u"%(base_url)s/api/%(apikey)s/updates_all.zip" % self.config
self.config['url_updates_month'] = u"%(base_url)s/api/%(apikey)s/updates_month.zip" % self.config
self.config['url_updates_week'] = u"%(base_url)s/api/%(apikey)s/updates_week.zip" % self.config
self.config['url_updates_day'] = u"%(base_url)s/api/%(apikey)s/updates_day.zip" % self.config
def _getTempDir(self): def _getTempDir(self):
"""Returns the [system temp dir]/tvdb_api-u501 (or """Returns the [system temp dir]/tvdb_api-u501 (or
tvdb_api-myuser) tvdb_api-myuser)

View file

@ -377,6 +377,8 @@ class TVRage:
self.config['url_seriesInfo'] = u"%(base_url)s/myfeeds/showinfo.php" % self.config self.config['url_seriesInfo'] = u"%(base_url)s/myfeeds/showinfo.php" % self.config
self.config['params_seriesInfo'] = {"key": self.config['apikey'], "sid": ""} self.config['params_seriesInfo'] = {"key": self.config['apikey'], "sid": ""}
self.config['url_updtes_all'] = u"%(base_url)s/myfeeds/currentshows.php" % self.config
def _getTempDir(self): def _getTempDir(self):
"""Returns the [system temp dir]/tvrage_api-u501 (or """Returns the [system temp dir]/tvrage_api-u501 (or
tvrage_api-myuser) tvrage_api-myuser)

View file

@ -357,6 +357,7 @@ TRAKT_METHOD_ADD = 0
TRAKT_START_PAUSED = False TRAKT_START_PAUSED = False
TRAKT_USE_RECOMMENDED = False TRAKT_USE_RECOMMENDED = False
TRAKT_SYNC = False TRAKT_SYNC = False
TRAKT_DEFAULT_INDEXER = None
USE_PYTIVO = False USE_PYTIVO = False
PYTIVO_NOTIFY_ONSNATCH = False PYTIVO_NOTIFY_ONSNATCH = False
@ -447,7 +448,7 @@ def initialize(consoleLogging=True):
TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_VERIFY_CERT, \ TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_VERIFY_CERT, \
USE_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD, XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, \ USE_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD, XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, \
XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, BACKLOG_FREQUENCY, \ XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, BACKLOG_FREQUENCY, \
USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_API, TRAKT_REMOVE_WATCHLIST, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_USE_RECOMMENDED, TRAKT_SYNC, \ USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_API, TRAKT_REMOVE_WATCHLIST, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_USE_RECOMMENDED, TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, \
USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, \ USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, \
PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, BACKLOG_STARTUP, SKIP_REMOVED_FILES, \ PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, BACKLOG_STARTUP, SKIP_REMOVED_FILES, \
showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, UPDATE_SHOWS_ON_START, SORT_ARTICLE, showList, loadingShowList, \ showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, UPDATE_SHOWS_ON_START, SORT_ARTICLE, showList, loadingShowList, \
@ -799,6 +800,7 @@ def initialize(consoleLogging=True):
TRAKT_START_PAUSED = bool(check_setting_int(CFG, 'Trakt', 'trakt_start_paused', 0)) TRAKT_START_PAUSED = bool(check_setting_int(CFG, 'Trakt', 'trakt_start_paused', 0))
TRAKT_USE_RECOMMENDED = bool(check_setting_int(CFG, 'Trakt', 'trakt_use_recommended', 0)) TRAKT_USE_RECOMMENDED = bool(check_setting_int(CFG, 'Trakt', 'trakt_use_recommended', 0))
TRAKT_SYNC = bool(check_setting_int(CFG, 'Trakt', 'trakt_sync', 0)) TRAKT_SYNC = bool(check_setting_int(CFG, 'Trakt', 'trakt_sync', 0))
TRAKT_DEFAULT_INDEXER = check_setting_int(CFG, 'Trakt', 'trakt_default_indexer', 1)
CheckSection(CFG, 'pyTivo') CheckSection(CFG, 'pyTivo')
USE_PYTIVO = bool(check_setting_int(CFG, 'pyTivo', 'use_pytivo', 0)) USE_PYTIVO = bool(check_setting_int(CFG, 'pyTivo', 'use_pytivo', 0))
@ -1619,6 +1621,7 @@ def save_config():
new_config['Trakt']['trakt_start_paused'] = int(TRAKT_START_PAUSED) new_config['Trakt']['trakt_start_paused'] = int(TRAKT_START_PAUSED)
new_config['Trakt']['trakt_use_recommended'] = int(TRAKT_USE_RECOMMENDED) new_config['Trakt']['trakt_use_recommended'] = int(TRAKT_USE_RECOMMENDED)
new_config['Trakt']['trakt_sync'] = int(TRAKT_SYNC) new_config['Trakt']['trakt_sync'] = int(TRAKT_SYNC)
new_config['Trakt']['trakt_default_indexer'] = int(TRAKT_DEFAULT_INDEXER)
new_config['pyTivo'] = {} new_config['pyTivo'] = {}
new_config['pyTivo']['use_pytivo'] = int(USE_PYTIVO) new_config['pyTivo']['use_pytivo'] = int(USE_PYTIVO)

View file

@ -145,7 +145,6 @@ class TorrentSearchResult(SearchResult):
""" """
resultType = "torrent" resultType = "torrent"
class AllShowsListUI: class AllShowsListUI:
""" """
This class is for indexer api. Instead of prompting with a UI to pick the This class is for indexer api. Instead of prompting with a UI to pick the

View file

@ -27,7 +27,7 @@ from sickbeard import encodingKludge as ek
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
MIN_DB_VERSION = 9 # oldest db version we support migrating from MIN_DB_VERSION = 9 # oldest db version we support migrating from
MAX_DB_VERSION = 38 MAX_DB_VERSION = 39
class MainSanityCheck(db.DBSanityCheck): class MainSanityCheck(db.DBSanityCheck):
def check(self): def check(self):
@ -168,7 +168,7 @@ class InitialSchema(db.SchemaUpgrade):
"CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)", "CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)",
"CREATE TABLE scene_numbering(indexer TEXT, indexer_id INTEGER, season INTEGER, episode INTEGER,scene_season INTEGER, scene_episode INTEGER, PRIMARY KEY(indexer_id, season, episode))", "CREATE TABLE scene_numbering(indexer TEXT, indexer_id INTEGER, season INTEGER, episode INTEGER,scene_season INTEGER, scene_episode INTEGER, PRIMARY KEY(indexer_id, season, episode))",
"CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer TEXT, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC, archive_firstmatch NUMERIC, rls_require_words TEXT, rls_ignore_words TEXT, sports NUMERIC);", "CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer TEXT, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC, archive_firstmatch NUMERIC, rls_require_words TEXT, rls_ignore_words TEXT, sports NUMERIC);",
"CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid NUMERIC, indexerid NUMERIC, indexer TEXT, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC, scene_season NUMERIC, scene_episode NUMERIC);", "CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid/ NUMERIC, indexerid NUMERIC, indexer TEXT, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC, scene_season NUMERIC, scene_episode NUMERIC);",
"CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id)", "CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id)",
"CREATE INDEX idx_showid ON tv_episodes (showid);", "CREATE INDEX idx_showid ON tv_episodes (showid);",
"CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate);", "CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate);",
@ -886,3 +886,18 @@ class AddSceneToTvShows(AddXemRefresh):
self.incDBVersion() self.incDBVersion()
class AddIndexerMapping(AddSceneToTvShows):
def test(self):
return self.checkDBVersion() >= 39
def execute(self):
backupDatabase(39)
if self.hasTable("indexer_mapping"):
self.connection.action("DROP TABLE indexer_mapping")
logger.log(u"Adding table indexer_mapping")
self.connection.action(
"CREATE TABLE indexer_mapping (indexer_id INTEGER, indexer NUMERIC, mindexer_id INTEGER, mindexer NUMERIC, PRIMARY KEY (indexer_id, indexer))")
self.incDBVersion()

View file

@ -321,6 +321,10 @@ def _processUpgrade(connection, upgradeClass):
result = connection.select("SELECT db_version FROM db_version") result = connection.select("SELECT db_version FROM db_version")
if result: if result:
version = int(result[0]["db_version"]) version = int(result[0]["db_version"])
# close db before attempting restore
connection.close()
if restoreDatabase(version): if restoreDatabase(version):
# initialize the main SB database # initialize the main SB database
upgradeDatabase(DBConnection(), sickbeard.mainDB.InitialSchema) upgradeDatabase(DBConnection(), sickbeard.mainDB.InitialSchema)

View file

@ -62,7 +62,7 @@ from lib import trakt
urllib._urlopener = classes.SickBeardURLopener() urllib._urlopener = classes.SickBeardURLopener()
session = requests.Session() session = requests.Session()
indexerMap = {}
def indentXML(elem, level=0): def indentXML(elem, level=0):
''' '''
@ -85,6 +85,7 @@ def indentXML(elem, level=0):
if level and (not elem.tail or not elem.tail.strip()): if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i elem.tail = i
def remove_extension(name): def remove_extension(name):
""" """
Remove download or media extension from name (if any) Remove download or media extension from name (if any)
@ -97,6 +98,7 @@ def remove_extension(name):
return name return name
def remove_non_release_groups(name): def remove_non_release_groups(name):
""" """
Remove non release groups from name Remove non release groups from name
@ -109,6 +111,7 @@ def remove_non_release_groups(name):
return name return name
def replaceExtension(filename, newExt): def replaceExtension(filename, newExt):
''' '''
>>> replaceExtension('foo.avi', 'mkv') >>> replaceExtension('foo.avi', 'mkv')
@ -291,12 +294,10 @@ def findCertainShow(showList, indexerid):
if indexerid: if indexerid:
results = filter(lambda x: int(x.indexerid) == int(indexerid), showList) results = filter(lambda x: int(x.indexerid) == int(indexerid), showList)
if len(results) == 0: if len(results):
return None return results[0]
elif len(results) > 1: elif len(results) > 1:
raise MultipleShowObjectsException() raise MultipleShowObjectsException()
else:
return results[0]
def makeDir(path): def makeDir(path):
@ -379,9 +380,9 @@ def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
continue continue
if str(name).lower() == str(seriesname).lower and not indexer_id: if str(name).lower() == str(seriesname).lower and not indexer_id:
return (seriesname, int(sickbeard.indexerApi(i).config['id']), int(series_id)) return (seriesname, i, int(series_id))
elif int(indexer_id) == int(series_id): elif int(indexer_id) == int(series_id):
return (seriesname, int(sickbeard.indexerApi(i).config['id']), int(indexer_id)) return (seriesname, i, int(indexer_id))
if indexer: if indexer:
break break
@ -464,7 +465,9 @@ def hardlinkFile(srcFile, destFile):
def symlink(src, dst): def symlink(src, dst):
if os.name == 'nt': if os.name == 'nt':
import ctypes import ctypes
if ctypes.windll.kernel32.CreateSymbolicLinkW(unicode(dst), unicode(src), 1 if os.path.isdir(src) else 0) in [0,1280]: raise ctypes.WinError()
if ctypes.windll.kernel32.CreateSymbolicLinkW(unicode(dst), unicode(src), 1 if os.path.isdir(src) else 0) in [0,
1280]: raise ctypes.WinError()
else: else:
os.symlink(src, dst) os.symlink(src, dst)
@ -718,26 +721,24 @@ def get_absolute_number_from_season_and_episode(show, season, episode):
return None return None
def get_all_episodes_from_absolute_number(show, indexer_id, absolute_numbers): def get_all_episodes_from_absolute_number(show, absolute_numbers, indexer_id=None):
if len(absolute_numbers) == 0: if len(absolute_numbers) == 0:
raise EpisodeNotFoundByAbsoluteNumberException raise EpisodeNotFoundByAbsoluteNumberException
episodes = [] episodes = []
season = None season = None
if not show and not indexer_id:
return (season, episodes)
if not show and indexer_id: if not show and indexer_id:
show = findCertainShow(sickbeard.showList, indexer_id) show = findCertainShow(sickbeard.showList, indexer_id)
for absolute_number in absolute_numbers: if show:
ep = show.getEpisode(None, None, absolute_number=absolute_number) for absolute_number in absolute_numbers:
if ep: ep = show.getEpisode(None, None, absolute_number=absolute_number)
episodes.append(ep.episode) if ep:
else: episodes.append(ep.episode)
raise EpisodeNotFoundByAbsoluteNumberException else:
season = ep.season # this will always take the last found seson so eps that cross the season border are not handeled well raise EpisodeNotFoundByAbsoluteNumberException
season = ep.season # this will always take the last found seson so eps that cross the season border are not handeled well
return (season, episodes) return (season, episodes)
@ -1086,26 +1087,31 @@ def _check_against_names(nameInQuestion, show, season=-1):
return False return False
def get_show(name, indexer_id=0, useIndexer=False): def get_show(name, tryIndexers=False):
if not sickbeard.showList:
return
showObj = None
fromCache = False
try: try:
# check cache for show # check cache for show
showObj = sickbeard.name_cache.retrieveShowFromCache(name, indexer_id=indexer_id) cache = sickbeard.name_cache.retrieveNameFromCache(name)
if showObj: if cache:
return showObj fromCache = True
showObj = findCertainShow(sickbeard.showList, int(cache))
if useIndexer and sickbeard.showList and not showObj: if not showObj and tryIndexers:
(sn, idx, id) = searchIndexerForShowID(full_sanitizeSceneName(name), ui=classes.ShowListUI) showObj = findCertainShow(sickbeard.showList,
if id: searchIndexerForShowID(full_sanitizeSceneName(name), ui=classes.ShowListUI)[2])
showObj = findCertainShow(sickbeard.showList, int(id))
# add show to cache # add show to cache
if showObj: if showObj and not fromCache:
sickbeard.name_cache.addNameToCache(name, showObj.indexerid) sickbeard.name_cache.addNameToCache(name, showObj.indexerid)
except Exception as e:
logger.log(u"Error when attempting to find show: " + name + " in SickRage: " + str(e), logger.DEBUG)
return showObj return showObj
except:
pass
def is_hidden_folder(folder): def is_hidden_folder(folder):
""" """
@ -1216,26 +1222,48 @@ def extractZip(archive, targetDir):
def mapIndexersToShow(showObj): def mapIndexersToShow(showObj):
global indexerMap mapped = {showObj.indexer: showObj.indexerid}
mapped = {'tvdb_id': 0, 'tvrage_id': 0} myDB = db.DBConnection()
if showObj.name in indexerMap: sqlResults = myDB.select(
logger.log(u"Found TVDB<->TVRAGE indexer mapping in cache for show: " + showObj.name, logger.DEBUG) "SELECT * FROM indexer_mapping WHERE indexer_id = ? AND indexer = ?",
return indexerMap[showObj.name] [showObj.indexerid, showObj.indexer])
logger.log(u"Mapping indexers TVDB<->TVRAGE for show: " + showObj.name, logger.DEBUG) # for each mapped entry
results = trakt.TraktCall("search/shows.json/%API%?query=" + sanitizeSceneName(showObj.name), for curResult in sqlResults:
sickbeard.TRAKT_API_KEY) logger.log(u"Found " + sickbeard.indexerApi(showObj.indexer).name + "<->" + sickbeard.indexerApi(
int(curResult['mindexer'])).name + " mapping in cache for show: " + showObj.name, logger.DEBUG)
if results: mapped[int(curResult['mindexer'])] = int(curResult['mindexer_id'])
result = filter(lambda x: int(showObj.indexerid) in [int(x['tvdb_id']), int(x['tvrage_id'])], results) else:
if len(result): sql_l = []
mapped['tvdb_id'] = int(result[0]['tvdb_id']) for indexer in sickbeard.indexerApi().indexers:
mapped['tvrage_id'] = int(result[0]['tvrage_id']) if indexer == showObj.indexer:
mapped[indexer] = showObj.indexerid
continue
logger.log(u"Adding TVDB<->TVRAGE indexer mapping to cache for show: " + showObj.name, logger.DEBUG) lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
indexerMap[showObj.name] = mapped lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
mapped_show = t[showObj.name]
if len(mapped_show) and not len(mapped_show) > 1:
logger.log(u"Mapping " + sickbeard.indexerApi(showObj.indexer).name + "<->" + sickbeard.indexerApi(
indexer).name + " for show " + showObj.name,
logger.DEBUG)
mapped[indexer] = int(mapped_show[0]['id'])
logger.log(u"Adding " + sickbeard.indexerApi(showObj.indexer).name + "<->" + sickbeard.indexerApi(
indexer).name + " mapping to DB for show: " + showObj.name, logger.DEBUG)
sql_l.append([
"INSERT OR IGNORE INTO indexer_mapping (indexer_id, indexer, mindexer_id, mindexer) VALUES (?,?,?,?)",
[showObj.indexerid, showObj.indexer, int(mapped_show[0]['id']), indexer]])
if len(sql_l) > 0:
myDB.mass_action(sql_l)
return mapped return mapped

View file

@ -57,4 +57,4 @@ class indexerApi(object):
@property @property
def indexers(self): def indexers(self):
return dict((x['id'], x['name']) for x in indexerConfig.values()) return dict((int(x['id']), x['name']) for x in indexerConfig.values())

View file

@ -55,17 +55,6 @@ def retrieveNameFromCache(name):
if name in nameCache: if name in nameCache:
return int(nameCache[name]) return int(nameCache[name])
def retrieveShowFromCache(name, indexer_id=0):
global nameCache
if not indexer_id:
indexer_id = retrieveNameFromCache(name)
if indexer_id:
return sickbeard.helpers.findCertainShow(sickbeard.showList, int(indexer_id))
def clearCache(): def clearCache():
""" """
Deletes all "unknown" entries from the cache (names with indexer_id of 0). Deletes all "unknown" entries from the cache (names with indexer_id of 0).

View file

@ -35,12 +35,12 @@ class NameParser(object):
SPORTS_REGEX = 1 SPORTS_REGEX = 1
ANIME_REGEX = 2 ANIME_REGEX = 2
def __init__(self, file_name=True, showObj=None, useIndexers=False, convert=False, def __init__(self, file_name=True, showObj=None, tryIndexers=False, convert=False,
naming_pattern=False): naming_pattern=False):
self.file_name = file_name self.file_name = file_name
self.showObj = showObj self.showObj = showObj
self.useIndexers = useIndexers self.tryIndexers = tryIndexers
self.convert = convert self.convert = convert
self.naming_pattern = naming_pattern self.naming_pattern = naming_pattern
@ -132,7 +132,7 @@ class NameParser(object):
# get show object # get show object
if not result.show and not self.naming_pattern: if not result.show and not self.naming_pattern:
result.show = helpers.get_show(result.series_name, useIndexer=self.useIndexers) result.show = helpers.get_show(result.series_name, self.tryIndexers)
elif self.showObj and self.naming_pattern: elif self.showObj and self.naming_pattern:
result.show = self.showObj result.show = self.showObj
@ -245,7 +245,7 @@ class NameParser(object):
for epAbsNo in bestResult.ab_episode_numbers: for epAbsNo in bestResult.ab_episode_numbers:
try: try:
(s, e) = helpers.get_all_episodes_from_absolute_number(bestResult.show, None, [epAbsNo]) (s, e) = helpers.get_all_episodes_from_absolute_number(bestResult.show, [epAbsNo])
except exceptions.EpisodeNotFoundByAbsoluteNumberException: except exceptions.EpisodeNotFoundByAbsoluteNumberException:
pass pass
else: else:
@ -531,7 +531,7 @@ class ParseResult(object):
True, scene_season) True, scene_season)
if ab: if ab:
try: try:
(s, e) = helpers.get_all_episodes_from_absolute_number(self.show, None, [ab]) (s, e) = helpers.get_all_episodes_from_absolute_number(self.show, [ab])
except exceptions.EpisodeNotFoundByAbsoluteNumberException: except exceptions.EpisodeNotFoundByAbsoluteNumberException:
logger.log(str(self.show.indexerid) + ": Indexer object absolute number " + str( logger.log(str(self.show.indexerid) + ": Indexer object absolute number " + str(
ab) + " is incomplete, skipping this episode") ab) + " is incomplete, skipping this episode")

View file

@ -472,7 +472,7 @@ class PostProcessor(object):
name = helpers.remove_non_release_groups(helpers.remove_extension(name)) name = helpers.remove_non_release_groups(helpers.remove_extension(name))
# parse the name to break it into show name, season, and episode # parse the name to break it into show name, season, and episode
np = NameParser(file, useIndexers=True, convert=True) np = NameParser(file, tryIndexers=True, convert=True)
parse_result = np.parse(name) parse_result = np.parse(name)
# show object # show object
@ -493,54 +493,6 @@ class PostProcessor(object):
self._finalize(parse_result) self._finalize(parse_result)
return to_return return to_return
def _analyze_anidb(self, filePath):
# TODO: rewrite this
return (None, None, None, None)
if not helpers.set_up_anidb_connection():
return (None, None, None, None)
ep = self._build_anidb_episode(sickbeard.ADBA_CONNECTION, filePath)
try:
self._log(u"Trying to lookup " + str(filePath) + " on anidb", logger.MESSAGE)
ep.load_data()
except Exception, e:
self._log(u"exception msg: " + str(e))
raise InvalidNameException
else:
self.anidbEpisode = ep
# TODO: clean code. it looks like it's from hell
for name in ep.allNames:
indexer_id = name_cache.retrieveNameFromCache(name)
if not indexer_id:
show = helpers.get_show(name)
if show:
indexer_id = show.indexerid
else:
indexer_id = 0
if indexer_id:
name_cache.addNameToCache(name, indexer_id)
if indexer_id:
try:
show = helpers.findCertainShow(sickbeard.showList, indexer_id)
(season, episodes) = helpers.get_all_episodes_from_absolute_number(show, None, [ep.epno])
except exceptions.EpisodeNotFoundByAbsoluteNumberException:
self._log(str(indexer_id) + ": Indexer object absolute number " + str(
ep.epno) + " is incomplete, skipping this episode")
else:
if len(episodes):
self._log(u"Lookup successful from anidb. ", logger.DEBUG)
return (show, season, episodes, None)
if ep.anidb_file_name:
self._log(u"Lookup successful, using anidb filename " + str(ep.anidb_file_name), logger.DEBUG)
return self._analyze_name(ep.anidb_file_name)
raise InvalidNameException
def _build_anidb_episode(self, connection, filePath): def _build_anidb_episode(self, connection, filePath):
ep = adba.Episode(connection, filePath=filePath, ep = adba.Episode(connection, filePath=filePath,
paramsF=["quality", "anidb_file_name", "crc32"], paramsF=["quality", "anidb_file_name", "crc32"],
@ -583,10 +535,7 @@ class PostProcessor(object):
lambda: self._analyze_name(self.file_path), lambda: self._analyze_name(self.file_path),
# try to analyze the dir + file name together as one name # try to analyze the dir + file name together as one name
lambda: self._analyze_name(self.folder_name + u' ' + self.file_name), lambda: self._analyze_name(self.folder_name + u' ' + self.file_name)
# try to analyze the file path with the help of aniDB
lambda: self._analyze_anidb(self.file_path)
] ]
# attempt every possible method to get our info # attempt every possible method to get our info

View file

@ -27,7 +27,7 @@ from sickbeard import classes
from sickbeard import scene_exceptions from sickbeard import scene_exceptions
from sickbeard import logger from sickbeard import logger
from sickbeard import tvcache from sickbeard import tvcache
from sickbeard.helpers import sanitizeSceneName, mapIndexersToShow from sickbeard.helpers import sanitizeSceneName
from sickbeard.exceptions import ex, AuthException from sickbeard.exceptions import ex, AuthException
from lib import jsonrpclib from lib import jsonrpclib

View file

@ -23,25 +23,26 @@ import datetime
import os import os
import re import re
import itertools import itertools
import Queue
import sickbeard import sickbeard
import requests
from lib import requests
from lib.feedparser import feedparser
from sickbeard import helpers, classes, logger, db from sickbeard import helpers, classes, logger, db
from sickbeard.common import MULTI_EP_RESULT, SEASON_RESULT, cpu_presets from sickbeard.common import MULTI_EP_RESULT, SEASON_RESULT
from sickbeard import tvcache from sickbeard import tvcache
from sickbeard import encodingKludge as ek from sickbeard import encodingKludge as ek
from sickbeard.exceptions import ex from sickbeard.exceptions import ex
from lib.hachoir_parser import createParser
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
from sickbeard.common import Quality from sickbeard.common import Quality
from lib.hachoir_parser import createParser
class GenericProvider: class GenericProvider:
NZB = "nzb" NZB = "nzb"
TORRENT = "torrent" TORRENT = "torrent"
def __init__(self, name): def __init__(self, name):
self.queue = Queue.Queue()
# these need to be set in the subclass # these need to be set in the subclass
self.providerType = None self.providerType = None

View file

@ -98,9 +98,9 @@ class NewznabProvider(generic.NZBProvider):
cur_params['season'] = str(ep_obj.scene_season) cur_params['season'] = str(ep_obj.scene_season)
# search # search
indexers = helpers.mapIndexersToShow(ep_obj.show) mindexers = helpers.mapIndexersToShow(ep_obj.show)
if indexers['tvrage_id']: if 2 in mindexers:
cur_params['rid'] = indexers['tvrage_id'] cur_params['rid'] = mindexers[2]
to_return.append(cur_params) to_return.append(cur_params)
else: else:
# add new query strings for exceptions # add new query strings for exceptions
@ -131,9 +131,9 @@ class NewznabProvider(generic.NZBProvider):
params['ep'] = ep_obj.scene_episode params['ep'] = ep_obj.scene_episode
# search # search
indexers = helpers.mapIndexersToShow(ep_obj.show) mindexers = helpers.mapIndexersToShow(ep_obj.show)
if indexers['tvrage_id']: if 2 in mindexers:
params['rid'] = indexers['tvrage_id'] params['rid'] = mindexers[2]
to_return.append(params) to_return.append(params)
else: else:
# add new query strings for exceptions # add new query strings for exceptions

View file

@ -54,15 +54,19 @@ class TraktChecker():
except Exception: except Exception:
logger.log(traceback.format_exc(), logger.DEBUG) logger.log(traceback.format_exc(), logger.DEBUG)
def findShow(self, indexerid): def findShow(self, indexer, indexerid):
library = TraktCall("user/library/shows/all.json/%API%/" + sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_API, library = TraktCall("user/library/shows/all.json/%API%/" + sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_API,
sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD) sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD)
results = filter(lambda x: int(x['tvdb_id']) == int(indexerid), library) if not library:
if len(results) == 0: logger.log(u"Could not connect to trakt service, aborting library check", logger.ERROR)
return None return
else:
return results[0] for show in library:
if int(indexer) == 1 and int(show['tvdb_id']) == int(indexerid):
return show
elif int(indexer) == 2 and int(show['tvrage_id']) == int(indexerid):
return show
def syncLibrary(self): def syncLibrary(self):
logger.log(u"Syncing library to trakt.tv show library", logger.DEBUG) logger.log(u"Syncing library to trakt.tv show library", logger.DEBUG)
@ -71,20 +75,23 @@ class TraktChecker():
self.addShowToTraktLibrary(myShow) self.addShowToTraktLibrary(myShow)
def removeShowFromTraktLibrary(self, show_obj): def removeShowFromTraktLibrary(self, show_obj):
if not self.findShow(show_obj.indexerid): if self.findShow(show_obj.indexer, show_obj.indexerid):
return # URL parameters
data = {}
if show_obj.indexer == 1:
data['tvdb_id'] = show_obj.indexerid
data['title'] = show_obj.name
data['year'] = show_obj.startyear
# URL parameters elif show_obj.indexer == 2:
data = { data['tvrage_id'] = show_obj.indexerid
'tvdb_id': show_obj.indexerid, data['title'] = show_obj.name
'title': show_obj.name, data['year'] = show_obj.startyear
'year': show_obj.startyear,
}
if data is not None: if data is not None:
logger.log(u"Removing " + show_obj.name + " from trakt.tv library", logger.DEBUG) logger.log(u"Removing " + show_obj.name + " from trakt.tv library", logger.DEBUG)
TraktCall("show/unlibrary/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD, TraktCall("show/unlibrary/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD,
data) data)
def addShowToTraktLibrary(self, show_obj): def addShowToTraktLibrary(self, show_obj):
""" """
@ -93,20 +100,23 @@ class TraktChecker():
show_obj: The TVShow object to add to trakt show_obj: The TVShow object to add to trakt
""" """
if self.findShow(show_obj.indexerid): if not self.findShow(show_obj.indexer, show_obj.indexerid):
return # URL parameters
data = {}
if show_obj.indexer == 1:
data['tvdb_id'] = show_obj.indexerid
data['title'] = show_obj.name
data['year'] = show_obj.startyear
# URL parameters elif show_obj.indexer == 2:
data = { data['tvrage_id'] = show_obj.indexerid
'tvdb_id': show_obj.indexerid, data['title'] = show_obj.name
'title': show_obj.name, data['year'] = show_obj.startyear
'year': show_obj.startyear,
}
if data is not None: if data is not None:
logger.log(u"Adding " + show_obj.name + " to trakt.tv library", logger.DEBUG) logger.log(u"Adding " + show_obj.name + " to trakt.tv library", logger.DEBUG)
TraktCall("show/library/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD, TraktCall("show/library/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD,
data) data)
def updateShows(self): def updateShows(self):
logger.log(u"Starting trakt show watchlist check", logger.DEBUG) logger.log(u"Starting trakt show watchlist check", logger.DEBUG)
@ -117,19 +127,25 @@ class TraktChecker():
return return
for show in watchlist: for show in watchlist:
if int(sickbeard.TRAKT_METHOD_ADD) != 2: indexer = int(sickbeard.TRAKT_DEFAULT_INDEXER)
self.addDefaultShow(show["tvdb_id"], show["title"], SKIPPED) if indexer == 2:
indexer_id = int(show["tvrage_id"])
else: else:
self.addDefaultShow(show["tvdb_id"], show["title"], WANTED) indexer_id = int(show["tvdb_id"])
if int(sickbeard.TRAKT_METHOD_ADD) != 2:
self.addDefaultShow(indexer, indexer_id, show["title"], SKIPPED)
else:
self.addDefaultShow(indexer, indexer_id, show["title"], WANTED)
if int(sickbeard.TRAKT_METHOD_ADD) == 1: if int(sickbeard.TRAKT_METHOD_ADD) == 1:
newShow = helpers.findCertainShow(sickbeard.showList, int(show["tvdb_id"])) newShow = helpers.findCertainShow(sickbeard.showList, indexer_id)
if newShow is not None: if newShow is not None:
self.setEpisodeToWanted(newShow, 1, 1) self.setEpisodeToWanted(newShow, 1, 1)
self.startBacklog(newShow) self.startBacklog(newShow)
else: else:
self.todoWanted.append((int(show["tvdb_id"]), 1, 1)) self.todoWanted.append((indexer_id, 1, 1))
self.todoWanted.append((int(show["tvdb_id"]), -1, -1)) # used to pause new shows if the settings say to self.todoWanted.append((indexer_id, -1, -1)) # used to pause new shows if the settings say to
def updateEpisodes(self): def updateEpisodes(self):
""" """
@ -143,69 +159,79 @@ class TraktChecker():
return return
for show in watchlist: for show in watchlist:
self.addDefaultShow(int(show["tvdb_id"]), show["title"], SKIPPED) indexer = int(sickbeard.TRAKT_DEFAULT_INDEXER)
newShow = helpers.findCertainShow(sickbeard.showList, int(show["tvdb_id"])) if indexer == 2:
for episode in show["episodes"]: indexer_id = int(show["tvrage_id"])
if newShow is not None: else:
self.setEpisodeToWanted(newShow, episode["season"], episode["number"]) indexer_id = int(show["tvdb_id"])
else:
self.todoWanted.append((int(show["tvdb_id"]), episode["season"], episode["number"]))
self.startBacklog(newShow)
def addDefaultShow(self, indexerid, name, status): self.addDefaultShow(indexer, indexer_id, show["title"], SKIPPED)
newShow = helpers.findCertainShow(sickbeard.showList, indexer_id)
if newShow and int(newShow['indexer']) == indexer:
for episode in show["episodes"]:
if newShow is not None:
self.setEpisodeToWanted(newShow, episode["season"], episode["number"])
else:
self.todoWanted.append((indexer_id, episode["season"], episode["number"]))
self.startBacklog(newShow)
def addDefaultShow(self, indexer, indexer_id, name, status):
""" """
Adds a new show with the default settings Adds a new show with the default settings
""" """
if helpers.findCertainShow(sickbeard.showList, int(indexerid)): if not helpers.findCertainShow(sickbeard.showList, int(indexer_id)):
return logger.log(u"Adding show " + str(indexer_id))
root_dirs = sickbeard.ROOT_DIRS.split('|')
logger.log(u"Adding show " + str(indexerid)) try:
root_dirs = sickbeard.ROOT_DIRS.split('|') location = root_dirs[int(root_dirs[0]) + 1]
except:
location = None
try: if location:
location = root_dirs[int(root_dirs[0]) + 1] showPath = ek.ek(os.path.join, location, helpers.sanitizeFileName(name))
except: dir_exists = helpers.makeDir(showPath)
location = None if not dir_exists:
logger.log(u"Unable to create the folder " + showPath + ", can't add the show", logger.ERROR)
return
else:
helpers.chmodAsParent(showPath)
if location: sickbeard.showQueueScheduler.action.addShow(int(indexer), int(indexer_id), showPath, status,
showPath = ek.ek(os.path.join, location, helpers.sanitizeFileName(name)) int(sickbeard.QUALITY_DEFAULT),
dir_exists = helpers.makeDir(showPath) int(sickbeard.FLATTEN_FOLDERS_DEFAULT))
if not dir_exists:
logger.log(u"Unable to create the folder " + showPath + ", can't add the show", logger.ERROR)
return
else: else:
helpers.chmodAsParent(showPath) logger.log(u"There was an error creating the show, no root directory setting found", logger.ERROR)
return
sickbeard.showQueueScheduler.action.addShow(1, int(indexerid), showPath, status,
int(sickbeard.QUALITY_DEFAULT),
int(sickbeard.FLATTEN_FOLDERS_DEFAULT))
else:
logger.log(u"There was an error creating the show, no root directory setting found", logger.ERROR)
return
def setEpisodeToWanted(self, show, s, e): def setEpisodeToWanted(self, show, s, e):
""" """
Sets an episode to wanted, only is it is currently skipped Sets an episode to wanted, only is it is currently skipped
""" """
epObj = show.getEpisode(int(s), int(e)) epObj = show.getEpisode(int(s), int(e))
if epObj == None: if epObj:
return
with epObj.lock:
if epObj.status != SKIPPED:
return
logger.log(u"Setting episode s" + str(s) + "e" + str(e) + " of show " + show.name + " to wanted")
# figure out what segment the episode is in and remember it so we can backlog it
if epObj.show.air_by_date or epObj.show.sports:
ep_segment = str(epObj.airdate)[:7]
else:
ep_segment = epObj.season
epObj.status = WANTED ep_segment = {}
epObj.saveToDB()
backlog = (show, ep_segment) with epObj.lock:
if self.todoBacklog.count(backlog) == 0: if epObj.status != SKIPPED:
self.todoBacklog.append(backlog) return
logger.log(u"Setting episode s" + str(s) + "e" + str(e) + " of show " + show.name + " to wanted")
# figure out what segment the episode is in and remember it so we can backlog it
if epObj.season in ep_segment:
ep_segment[epObj.season].append(epObj)
else:
ep_segment[epObj.season] = [epObj]
epObj.status = WANTED
epObj.saveToDB()
backlog = (show, ep_segment)
if self.todoBacklog.count(backlog) == 0:
self.todoBacklog.append(backlog)
def manageNewShow(self, show): def manageNewShow(self, show):
@ -223,8 +249,8 @@ class TraktChecker():
for segment in segments: for segment in segments:
cur_backlog_queue_item = search_queue.BacklogQueueItem(show, segment[1]) cur_backlog_queue_item = search_queue.BacklogQueueItem(show, segment[1])
sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item) sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item)
logger.log(u"Starting backlog for " + show.name + " season " + str(
segment[1]) + " because some eps were set to wanted")
self.todoBacklog.remove(segment)
for season in segment[1]:
logger.log(u"Starting backlog for " + show.name + " season " + str(
season) + " because some eps were set to wanted")
self.todoBacklog.remove(segment)

View file

@ -428,7 +428,7 @@ class TVShow(object):
try: try:
parse_result = None parse_result = None
np = NameParser(False, showObj=self, useIndexers=True) np = NameParser(False, showObj=self, tryIndexers=True)
parse_result = np.parse(ep_file_name) parse_result = np.parse(ep_file_name)
except (InvalidNameException, InvalidShowException): except (InvalidNameException, InvalidShowException):
pass pass
@ -612,7 +612,7 @@ class TVShow(object):
logger.log(str(self.indexerid) + u": Creating episode object from " + file, logger.DEBUG) logger.log(str(self.indexerid) + u": Creating episode object from " + file, logger.DEBUG)
try: try:
myParser = NameParser(True, showObj=self, useIndexers=True) myParser = NameParser(True, showObj=self, tryIndexers=True)
parse_result = myParser.parse(file) parse_result = myParser.parse(file)
except InvalidNameException: except InvalidNameException:
logger.log(u"Unable to parse the filename " + file + " into a valid episode", logger.DEBUG) logger.log(u"Unable to parse the filename " + file + " into a valid episode", logger.DEBUG)

View file

@ -975,14 +975,14 @@ class CMD_EpisodeSetStatus(ApiCall):
sql_l = [] sql_l = []
for epObj in ep_list: for epObj in ep_list:
if self.status == WANTED:
# figure out what episodes are wanted so we can backlog them
if epObj.season in ep_segment:
ep_segment[epObj.season].append(epObj)
else:
ep_segment[epObj.season] = [epObj]
with epObj.lock: with epObj.lock:
if self.status == WANTED:
# figure out what episodes are wanted so we can backlog them
if epObj.season in ep_segment:
ep_segment[epObj.season].append(epObj)
else:
ep_segment[epObj.season] = [epObj]
# don't let them mess up UNAIRED episodes # don't let them mess up UNAIRED episodes
if epObj.status == UNAIRED: if epObj.status == UNAIRED:
if self.e != None: # setting the status of a unaired is only considert a failure if we directly wanted this episode, but is ignored on a season request if self.e != None: # setting the status of a unaired is only considert a failure if we directly wanted this episode, but is ignored on a season request
@ -1723,6 +1723,8 @@ class CMD_Show(ApiCall):
if not showObj: if not showObj:
return _responds(RESULT_FAILURE, msg="Show not found") return _responds(RESULT_FAILURE, msg="Show not found")
mindexers = helpers.mapIndexersToShow(showObj)
showDict = {} showDict = {}
showDict["season_list"] = CMD_ShowSeasonList(self.handler, (), {"indexerid": self.indexerid}).run()["data"] showDict["season_list"] = CMD_ShowSeasonList(self.handler, (), {"indexerid": self.indexerid}).run()["data"]
showDict["cache"] = CMD_ShowCache(self.handler, (), {"indexerid": self.indexerid}).run()["data"] showDict["cache"] = CMD_ShowCache(self.handler, (), {"indexerid": self.indexerid}).run()["data"]
@ -1753,7 +1755,7 @@ class CMD_Show(ApiCall):
showDict["anime"] = showObj.anime showDict["anime"] = showObj.anime
#clean up tvdb horrible airs field #clean up tvdb horrible airs field
showDict["airs"] = str(showObj.airs).replace('am', ' AM').replace('pm', ' PM').replace(' ', ' ') showDict["airs"] = str(showObj.airs).replace('am', ' AM').replace('pm', ' PM').replace(' ', ' ')
showDict["tvrage_id"] = helpers.mapIndexersToShow(showObj)['tvrage_id'] showDict["tvrage_id"] = mindexers[2] if 2 in mindexers else 0
showDict["tvrage_name"] = showObj.name showDict["tvrage_name"] = showObj.name
showDict["network"] = showObj.network showDict["network"] = showObj.network
if not showDict["network"]: if not showDict["network"]:
@ -2522,6 +2524,7 @@ class CMD_Shows(ApiCall):
if self.paused != None and bool(self.paused) != bool(curShow.paused): if self.paused != None and bool(self.paused) != bool(curShow.paused):
continue continue
mindexers = helpers.mapIndexersToShow(curShow)
showDict = { showDict = {
"paused": curShow.paused, "paused": curShow.paused,
"quality": _get_quality_string(curShow.quality), "quality": _get_quality_string(curShow.quality),
@ -2530,8 +2533,8 @@ class CMD_Shows(ApiCall):
"sports": curShow.sports, "sports": curShow.sports,
"anime": curShow.anime, "anime": curShow.anime,
"indexerid": curShow.indexerid, "indexerid": curShow.indexerid,
"tvdbid": helpers.mapIndexersToShow(curShow)['tvdb_id'], "tvdbid": mindexers[1] if 1 in mindexers else 0,
"tvrage_id": helpers.mapIndexersToShow(curShow)['tvrage_id'], "tvrage_id": mindexers[2] if 2 in mindexers else 0,
"tvrage_name": curShow.name, "tvrage_name": curShow.name,
"network": curShow.network, "network": curShow.network,
"show_name": curShow.name, "show_name": curShow.name,

View file

@ -2213,7 +2213,7 @@ class ConfigNotifications(MainHandler):
use_nmjv2=None, nmjv2_host=None, nmjv2_dbloc=None, nmjv2_database=None, use_nmjv2=None, nmjv2_host=None, nmjv2_dbloc=None, nmjv2_database=None,
use_trakt=None, trakt_username=None, trakt_password=None, trakt_api=None, use_trakt=None, trakt_username=None, trakt_password=None, trakt_api=None,
trakt_remove_watchlist=None, trakt_use_watchlist=None, trakt_method_add=None, trakt_remove_watchlist=None, trakt_use_watchlist=None, trakt_method_add=None,
trakt_start_paused=None, trakt_use_recommended=None, trakt_sync=None, trakt_start_paused=None, trakt_use_recommended=None, trakt_sync=None, trakt_default_indexer=None,
use_synologynotifier=None, synologynotifier_notify_onsnatch=None, use_synologynotifier=None, synologynotifier_notify_onsnatch=None,
synologynotifier_notify_ondownload=None, synologynotifier_notify_onsubtitledownload=None, synologynotifier_notify_ondownload=None, synologynotifier_notify_onsubtitledownload=None,
use_pytivo=None, pytivo_notify_onsnatch=None, pytivo_notify_ondownload=None, use_pytivo=None, pytivo_notify_onsnatch=None, pytivo_notify_ondownload=None,
@ -2326,6 +2326,7 @@ class ConfigNotifications(MainHandler):
sickbeard.TRAKT_START_PAUSED = config.checkbox_to_value(trakt_start_paused) sickbeard.TRAKT_START_PAUSED = config.checkbox_to_value(trakt_start_paused)
sickbeard.TRAKT_USE_RECOMMENDED = config.checkbox_to_value(trakt_use_recommended) sickbeard.TRAKT_USE_RECOMMENDED = config.checkbox_to_value(trakt_use_recommended)
sickbeard.TRAKT_SYNC = config.checkbox_to_value(trakt_sync) sickbeard.TRAKT_SYNC = config.checkbox_to_value(trakt_sync)
sickbeard.TRAKT_DEFAULT_INDEXER = int(trakt_default_indexer)
if sickbeard.USE_TRAKT: if sickbeard.USE_TRAKT:
sickbeard.traktCheckerScheduler.silent = False sickbeard.traktCheckerScheduler.silent = False