diff --git a/CHANGES.md b/CHANGES.md index aa8abbff..9779ed5d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,14 @@ -### 0.17.4 (2018-09-01 03:00:00 UTC) +### 0.17.5 (2018-09-08 13:20:00 UTC) + +* Fix error updating shows with certain paths +* Fix getting XEM absolute numbers for show +* Fix IMDb info load for redirected ids +* Fix flags on displayShow (under Linux) +* Change refactor scene numbering +* Change update LimeTorrents icon + + +### 0.17.4 (2018-09-01 03:00:00 UTC) * Fix typo diff --git a/gui/slick/images/providers/limetorrents.png b/gui/slick/images/providers/limetorrents.png index 47ea1d55..39f20608 100644 Binary files a/gui/slick/images/providers/limetorrents.png and b/gui/slick/images/providers/limetorrents.png differ diff --git a/gui/slick/interfaces/default/inc_displayShow.tmpl b/gui/slick/interfaces/default/inc_displayShow.tmpl index 1e50ae12..80e383d6 100644 --- a/gui/slick/interfaces/default/inc_displayShow.tmpl +++ b/gui/slick/interfaces/default/inc_displayShow.tmpl @@ -20,7 +20,8 @@ ## #set $eps = $getVar('episodes', None) or [$episode] #for $ep in $eps - #set $ep_str = '%sx%s' % ($ep['season'], $ep['episode']) + #set $ep_key = ($ep['season'], $ep['episode']) + #set $ep_str = '%sx%s' % $ep_key #set $epLoc = $ep['location'] #set never_aired = 0 < int($ep['season']) and 1 == int($ep['airdate']) @@ -50,40 +51,32 @@ #slurp #if $scene - #set $dfltSeas, $dfltEpis = (0, 0) if ($ep['season'], $ep['episode']) not in $xem_numbering else $xem_numbering[($ep['season'], $ep['episode'])] + #set $dfltSeas, $dfltEpis = $xem_numbering.get($ep_key, (0, 0)) #elif $scene_anime - ## todo: $xem_absolute_numbering[$ep['absolute_number']] is tuple key: $xem_absolute_numbering[($ep['season'], $ep['episode'])] - #set $dfltAbsolute = 0 if $ep['absolute_number'] not in $xem_absolute_numbering else $xem_absolute_numbering[$ep['absolute_number']] + #set $dfltAbsolute = $xem_absolute_numbering.get($ep_key, 0) #end if #slurp + ('None opacity40', ('" id="plot_info_%s_%s_%s' % (($show.indexerid,) + $ep_key)))[None is not $ep['description'] and '' != $ep['description']]#"> #set $cls = (' class="tba grey-text"', '')['good' == $Overview.overviewStrings[$ep_cats[$ep_str]]] #if not $ep['name'] or 'TBA' == $ep['name']#TBA#else#$ep['name']#end if# diff --git a/gui/slick/js/displayShow.js b/gui/slick/js/displayShow.js index f7b5f19e..52dde687 100644 --- a/gui/slick/js/displayShow.js +++ b/gui/slick/js/displayShow.js @@ -126,16 +126,17 @@ $(document).ready(function() { }, function(data) { // Set the values we get back - $('#sceneSeasonXEpisode_' + showId + '_' + forSeason + '_' + forEpisode).val( - (null === data.sceneSeason || null === data.sceneEpisode) + var value = ((null === data.sceneSeason || null === data.sceneEpisode) ? '' : data.sceneSeason + 'x' + data.sceneEpisode); + $('#sceneSeasonXEpisode_' + showId + '_' + forSeason + '_' + forEpisode) + .val(value).attr('value', value); if (!data.success) alert(data.errorMessage ? data.errorMessage : 'Update failed.'); } ); } - function setAbsoluteSceneNumbering(forAbsolute, sceneAbsolute) { + function setAbsoluteSceneNumbering(forSeason, forEpisode, sceneAbsolute) { var showId = $('#showID').val(), indexer = $('#indexer').val(); if ('' === sceneAbsolute) @@ -145,13 +146,15 @@ $(document).ready(function() { { 'show': showId, 'indexer': indexer, - 'forAbsolute': forAbsolute, + 'forSeason': forSeason, + 'forEpisode': forEpisode, 'sceneAbsolute': sceneAbsolute }, function(data) { // Set the values we get back - $('#sceneAbsolute_' + showId + '_' + forAbsolute).val( - (null === data.sceneAbsolute) ? '' : data.sceneAbsolute); + var value = (null === data.sceneAbsolute ? '' : data.sceneAbsolute); + $('#sceneAbsolute_' + showId + '_' + forSeason + '_' + forEpisode) + .val(value).attr('value', value); if (!data.success) alert(data.errorMessage ? data.errorMessage : 'Update failed.'); } @@ -250,13 +253,14 @@ $(document).ready(function() { $(obj).find('.sceneAbsolute').change(function() { // Strip non-numeric characters - $(this).val($(this).val().replace(/[^0-9xX]*/g, '')); + $(this).val($(this).val().replace(/[^0-9]*/g, '')); - var forAbsolute = $(this).attr('data-for-absolute'), - m = $(this).val().match(/^(\d{1,3})$/i), + var forSeason = $(this).attr('data-for-season'), + forEpisode = $(this).attr('data-for-episode'), + m = $(this).val().match(/^(\d{1,4})$/i), sceneAbsolute = m && m[1] || null; - setAbsoluteSceneNumbering(forAbsolute, sceneAbsolute); + setAbsoluteSceneNumbering(forSeason, forEpisode, sceneAbsolute); }); }); } diff --git a/sickbeard/scene_numbering.py b/sickbeard/scene_numbering.py index 2cb0e1e9..448a9d66 100644 --- a/sickbeard/scene_numbering.py +++ b/sickbeard/scene_numbering.py @@ -30,6 +30,7 @@ import sickbeard from sickbeard import logger from sickbeard import db from sickbeard.exceptions import ex +from sickbeard.helpers import tryInt from sickbeard.scene_exceptions import xem_ids_list @@ -37,10 +38,11 @@ def get_scene_numbering(indexer_id, indexer, season, episode, fallback_to_xem=Tr """ Returns a tuple, (season, episode), with the scene numbering (if there is one), otherwise returns the xem numbering (if fallback_to_xem is set), otherwise - returns the TVDB and TVRAGE numbering. + returns the TVDB numbering. (so the return values will always be set) @param indexer_id: int + @param indexer: int @param season: int @param episode: int @param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering @@ -69,14 +71,16 @@ def find_scene_numbering(indexer_id, indexer, season, episode): Same as get_scene_numbering(), but returns None if scene numbering is not set """ if None is indexer_id or None is season or None is episode: - return season, episode + return indexer_id = int(indexer_id) indexer = int(indexer) my_db = db.DBConnection() rows = my_db.select( - 'SELECT scene_season, scene_episode FROM scene_numbering WHERE indexer = ? and indexer_id = ? and season = ? and episode = ? and (scene_season or scene_episode) != 0', + 'SELECT scene_season, scene_episode' + ' FROM scene_numbering' + ' WHERE indexer = ? AND indexer_id = ? AND season = ? AND episode = ? AND (scene_season OR scene_episode) != 0', [indexer, indexer_id, season, episode]) if rows: @@ -87,25 +91,29 @@ def get_scene_absolute_numbering(indexer_id, indexer, absolute_number, season, e """ Returns a tuple, (season, episode), with the scene numbering (if there is one), otherwise returns the xem numbering (if fallback_to_xem is set), otherwise - returns the TVDB and TVRAGE numbering. + returns the TVDB numbering. (so the return values will always be set) @param indexer_id: int + @param indexer: int @param absolute_number: int + @param season: int + @param episode: int @param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering @return: (int, int) a tuple with (season, episode) """ - if None is indexer_id or None is absolute_number: + has_sxe = None is not season and None is not episode + if None is indexer_id or (None is absolute_number and not has_sxe): return absolute_number indexer_id = int(indexer_id) indexer = int(indexer) show_obj = sickbeard.helpers.findCertainShow(sickbeard.showList, indexer_id) - if show_obj and not show_obj.is_scene: + if show_obj and not show_obj.is_scene and not has_sxe: return absolute_number - result = find_scene_absolute_numbering(indexer_id, indexer, absolute_number) + result = find_scene_absolute_numbering(indexer_id, indexer, absolute_number, season, episode) if result: return result else: @@ -116,56 +124,63 @@ def get_scene_absolute_numbering(indexer_id, indexer, absolute_number, season, e return absolute_number -def find_scene_absolute_numbering(indexer_id, indexer, absolute_number): +def find_scene_absolute_numbering(indexer_id, indexer, absolute_number, season=None, episode=None): """ Same as get_scene_numbering(), but returns None if scene numbering is not set """ - if None is indexer_id or None is absolute_number: - return absolute_number + has_sxe = None is not season and None is not episode + if None is indexer_id or (None is absolute_number and not has_sxe): + return indexer_id = int(indexer_id) indexer = int(indexer) my_db = db.DBConnection() + sql_vars, cond = (([absolute_number], 'and absolute_number = ?'), + ([season, episode], 'and season = ? AND episode = ?'))[has_sxe] rows = my_db.select( - 'SELECT scene_absolute_number FROM scene_numbering WHERE indexer = ? and indexer_id = ? and absolute_number = ? and scene_absolute_number != 0', - [indexer, indexer_id, absolute_number]) + 'SELECT scene_absolute_number' + ' FROM scene_numbering' + ' WHERE indexer = ? AND indexer_id = ? %s AND scene_absolute_number != 0' % cond, + [indexer, indexer_id] + sql_vars) if rows: return int(rows[0]['scene_absolute_number']) -def get_indexer_numbering(indexer_id, indexer, sceneSeason, sceneEpisode, fallback_to_xem=True): +def get_indexer_numbering(indexer_id, indexer, scene_season, scene_episode, fallback_to_xem=True): """ - Returns a tuple, (season, episode) with the TVDB and TVRAGE numbering for (sceneSeason, sceneEpisode) + Returns a tuple, (season, episode) with the TVDB numbering for (sceneSeason, sceneEpisode) (this works like the reverse of get_scene_numbering) """ - if None is indexer_id or None is sceneSeason or None is sceneEpisode: - return sceneSeason, sceneEpisode + if None is indexer_id or None is scene_season or None is scene_episode: + return scene_season, scene_episode indexer_id = int(indexer_id) indexer = int(indexer) my_db = db.DBConnection() rows = my_db.select( - 'SELECT season, episode FROM scene_numbering WHERE indexer = ? and indexer_id = ? and scene_season = ? and scene_episode = ?', - [indexer, indexer_id, sceneSeason, sceneEpisode]) + 'SELECT season, episode' + ' FROM scene_numbering' + ' WHERE indexer = ? AND indexer_id = ? AND scene_season = ? AND scene_episode = ?', + [indexer, indexer_id, scene_season, scene_episode]) if rows: return int(rows[0]['season']), int(rows[0]['episode']) else: if fallback_to_xem: - return get_indexer_numbering_for_xem(indexer_id, indexer, sceneSeason, sceneEpisode) - return sceneSeason, sceneEpisode + return get_indexer_numbering_for_xem(indexer_id, indexer, scene_season, scene_episode) + return scene_season, scene_episode -def get_indexer_absolute_numbering(indexer_id, indexer, sceneAbsoluteNumber, fallback_to_xem=True, scene_season=None): +def get_indexer_absolute_numbering(indexer_id, indexer, scene_absolute_number, fallback_to_xem=True, scene_season=None): """ - Returns a tuple, (season, episode, absolute_number) with the TVDB and TVRAGE numbering for (sceneAbsoluteNumber) + Returns a tuple, (season, episode, absolute_number) with the TVDB numbering for (sceneAbsoluteNumber) (this works like the reverse of get_absolute_numbering) """ - if None is indexer_id or None is sceneAbsoluteNumber: - return sceneAbsoluteNumber + if None is indexer_id or None is scene_absolute_number: + return scene_absolute_number indexer_id = int(indexer_id) indexer = int(indexer) @@ -173,23 +188,27 @@ def get_indexer_absolute_numbering(indexer_id, indexer, sceneAbsoluteNumber, fal my_db = db.DBConnection() if None is scene_season: rows = my_db.select( - 'SELECT absolute_number FROM scene_numbering WHERE indexer = ? and indexer_id = ? and scene_absolute_number = ?', - [indexer, indexer_id, sceneAbsoluteNumber]) + 'SELECT absolute_number' + ' FROM scene_numbering' + ' WHERE indexer = ? AND indexer_id = ? AND scene_absolute_number = ?', + [indexer, indexer_id, scene_absolute_number]) else: rows = my_db.select( - 'SELECT absolute_number FROM scene_numbering WHERE indexer = ? and indexer_id = ? and scene_absolute_number = ? and scene_season = ?', - [indexer, indexer_id, sceneAbsoluteNumber, scene_season]) + 'SELECT absolute_number' + ' FROM scene_numbering' + ' WHERE indexer = ? AND indexer_id = ? AND scene_absolute_number = ? AND scene_season = ?', + [indexer, indexer_id, scene_absolute_number, scene_season]) if rows: return int(rows[0]['absolute_number']) else: if fallback_to_xem: - return get_indexer_absolute_numbering_for_xem(indexer_id, indexer, sceneAbsoluteNumber, scene_season) - return sceneAbsoluteNumber + return get_indexer_absolute_numbering_for_xem(indexer_id, indexer, scene_absolute_number, scene_season) + return scene_absolute_number -def set_scene_numbering(indexer_id, indexer, season=None, episode=None, absolute_number=None, sceneSeason=None, - sceneEpisode=None, sceneAbsolute=None): +def set_scene_numbering(indexer_id, indexer, season=None, episode=None, absolute_number=None, scene_season=None, + scene_episode=None, scene_absolute=None, anime=False): """ Set scene numbering for a season/episode. To clear the scene numbering, leave both sceneSeason and sceneEpisode as None. @@ -207,17 +226,49 @@ def set_scene_numbering(indexer_id, indexer, season=None, episode=None, absolute 'INSERT OR IGNORE INTO scene_numbering (indexer, indexer_id, season, episode) VALUES (?,?,?,?)', [indexer, indexer_id, season, episode]) + # sxe replaced abs_num as key, migrate data with only abs + _, _, ep_absolute_number = _get_sea(indexer, indexer_id, season, episode) + rows = my_db.select( + 'SELECT scene_season, scene_episode, scene_absolute_number' + ' FROM scene_numbering' + ' WHERE indexer = ? AND indexer_id = ? AND season IS NULL AND episode IS NULL AND absolute_number = ?', + [indexer, indexer_id, ep_absolute_number]) + + if not len(rows): + update, values = (('scene_absolute_number = ?', [scene_absolute]), + ('scene_season = ?, scene_episode = ?', [scene_season, scene_episode]))[not anime] + else: + for row in rows: + scene_season = scene_season or row['scene_season'] + scene_episode = scene_episode or row['scene_episode'] + scene_absolute = scene_absolute or row['scene_absolute_number'] + + update, values = ('scene_season = ?, scene_episode = ?, scene_absolute_number = ?', + [scene_season, scene_episode, scene_absolute]) my_db.action( - 'UPDATE scene_numbering SET scene_season = ?, scene_episode = ? WHERE indexer = ? and indexer_id = ? and season = ? and episode = ?', - [sceneSeason, sceneEpisode, indexer, indexer_id, season, episode]) + 'UPDATE scene_numbering' + ' SET %s' % update + + ' WHERE indexer = ? AND indexer_id = ? AND season = ? AND episode = ?', + values + [indexer, indexer_id, season, episode]) + + my_db.action( + 'DELETE' + ' FROM scene_numbering' + ' WHERE indexer = ? AND indexer_id = ? AND' + ' ((absolute_number = ? OR (season = ? AND episode = ?))' + ' AND scene_season IS NULL AND scene_episode IS NULL AND scene_absolute_number IS NULL)', + [indexer, indexer_id, ep_absolute_number, season, episode]) + elif absolute_number: my_db.action( 'INSERT OR IGNORE INTO scene_numbering (indexer, indexer_id, absolute_number) VALUES (?,?,?)', [indexer, indexer_id, absolute_number]) my_db.action( - 'UPDATE scene_numbering SET scene_absolute_number = ? WHERE indexer = ? and indexer_id = ? and absolute_number = ?', - [sceneAbsolute, indexer, indexer_id, absolute_number]) + 'UPDATE scene_numbering' + ' SET scene_absolute_number = ?' + ' WHERE indexer = ? AND indexer_id = ? AND absolute_number = ?', + [scene_absolute, indexer, indexer_id, absolute_number]) def find_xem_numbering(indexer_id, indexer, season, episode): @@ -226,6 +277,7 @@ def find_xem_numbering(indexer_id, indexer, season, episode): Refreshes/Loads as needed. @param indexer_id: int + @param indexer: int @param season: int @param episode: int @return: (int, int) a tuple of scene_season, scene_episode, or None if there is no special mapping. @@ -240,7 +292,9 @@ def find_xem_numbering(indexer_id, indexer, season, episode): my_db = db.DBConnection() rows = my_db.select( - 'SELECT scene_season, scene_episode FROM tv_episodes WHERE indexer = ? and showid = ? and season = ? and episode = ? and (scene_season or scene_episode) != 0', + 'SELECT scene_season, scene_episode' + ' FROM tv_episodes' + ' WHERE indexer = ? AND showid = ? AND season = ? AND episode = ? AND (scene_season OR scene_episode) != 0', [indexer, indexer_id, season, episode]) if rows: @@ -253,7 +307,10 @@ def find_xem_absolute_numbering(indexer_id, indexer, absolute_number, season, ep Refreshes/Loads as needed. @param indexer_id: int + @param indexer: int @param absolute_number: int + @param season: int + @param episode: int @return: int """ if None is indexer_id or None is absolute_number: @@ -266,24 +323,27 @@ def find_xem_absolute_numbering(indexer_id, indexer, absolute_number, season, ep my_db = db.DBConnection() rows = my_db.select( - 'SELECT scene_absolute_number FROM tv_episodes WHERE indexer = ? and showid = ? and season = ? and episode = ? and scene_absolute_number != 0', + 'SELECT scene_absolute_number' + ' FROM tv_episodes' + ' WHERE indexer = ? AND showid = ? AND season = ? AND episode = ? AND scene_absolute_number != 0', [indexer, indexer_id, season, episode]) if rows: return int(rows[0]['scene_absolute_number']) -def get_indexer_numbering_for_xem(indexer_id, indexer, sceneSeason, sceneEpisode): +def get_indexer_numbering_for_xem(indexer_id, indexer, scene_season, scene_episode): """ Reverse of find_xem_numbering: lookup a tvdb season and episode using scene numbering @param indexer_id: int - @param sceneSeason: int - @param sceneEpisode: int + @param indexer: int + @param scene_season: int + @param scene_episode: int @return: (int, int) a tuple of (season, episode) """ - if None is indexer_id or None is sceneSeason or None is sceneEpisode: - return sceneSeason, sceneEpisode + if None is indexer_id or None is scene_season or None is scene_episode: + return scene_season, scene_episode indexer_id = int(indexer_id) indexer = int(indexer) @@ -292,25 +352,29 @@ def get_indexer_numbering_for_xem(indexer_id, indexer, sceneSeason, sceneEpisode my_db = db.DBConnection() rows = my_db.select( - 'SELECT season, episode FROM tv_episodes WHERE indexer = ? and showid = ? and scene_season = ? and scene_episode = ?', - [indexer, indexer_id, sceneSeason, sceneEpisode]) + 'SELECT season, episode' + ' FROM tv_episodes' + ' WHERE indexer = ? AND showid = ? AND scene_season = ? AND scene_episode = ?', + [indexer, indexer_id, scene_season, scene_episode]) if rows: return int(rows[0]['season']), int(rows[0]['episode']) - return sceneSeason, sceneEpisode + return scene_season, scene_episode -def get_indexer_absolute_numbering_for_xem(indexer_id, indexer, sceneAbsoluteNumber, scene_season=None): +def get_indexer_absolute_numbering_for_xem(indexer_id, indexer, scene_absolute_number, scene_season=None): """ Reverse of find_xem_numbering: lookup a tvdb season and episode using scene numbering @param indexer_id: int - @param sceneAbsoluteNumber: int + @param indexer: int + @param scene_absolute_number: int + @param scene_season: int/None @return: int """ - if None is indexer_id or None is sceneAbsoluteNumber: - return sceneAbsoluteNumber + if None is indexer_id or None is scene_absolute_number: + return scene_absolute_number indexer_id = int(indexer_id) indexer = int(indexer) @@ -320,141 +384,137 @@ def get_indexer_absolute_numbering_for_xem(indexer_id, indexer, sceneAbsoluteNum my_db = db.DBConnection() if None is scene_season: rows = my_db.select( - 'SELECT absolute_number FROM tv_episodes WHERE indexer = ? and showid = ? and scene_absolute_number = ?', - [indexer, indexer_id, sceneAbsoluteNumber]) + 'SELECT absolute_number' + ' FROM tv_episodes' + ' WHERE indexer = ? AND showid = ? AND scene_absolute_number = ?', + [indexer, indexer_id, scene_absolute_number]) else: rows = my_db.select( - 'SELECT absolute_number FROM tv_episodes WHERE indexer = ? and showid = ? and scene_absolute_number = ? and scene_season = ?', - [indexer, indexer_id, sceneAbsoluteNumber, scene_season]) + 'SELECT absolute_number' + ' FROM tv_episodes' + ' WHERE indexer = ? AND showid = ? AND scene_absolute_number = ? AND scene_season = ?', + [indexer, indexer_id, scene_absolute_number, scene_season]) if rows: return int(rows[0]['absolute_number']) - return sceneAbsoluteNumber + return scene_absolute_number def get_scene_numbering_for_show(indexer_id, indexer): """ - Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings + Returns a dict of (season, episode) : (scene_season, scene_episode) mappings for an entire show. Both the keys and values of the dict are tuples. - Will be empty if there are no scene numbers set + Will be empty if no scene numbers are set """ - if None is indexer_id: - return {} - - indexer_id = int(indexer_id) - indexer = int(indexer) - - my_db = db.DBConnection() - rows = my_db.select( - 'SELECT season, episode, scene_season, scene_episode FROM scene_numbering WHERE indexer = ? and indexer_id = ? and (scene_season or scene_episode) != 0 ORDER BY season, episode', - [indexer, indexer_id]) - - result = {} - for row in rows: - season = int(row['season']) - episode = int(row['episode']) - scene_season = int(row['scene_season']) - scene_episode = int(row['scene_episode']) - - result[(season, episode)] = (scene_season, scene_episode) - - return result + return _get_numbering_for_show('scene_numbering', indexer, indexer_id) def get_xem_numbering_for_show(indexer_id, indexer): """ - Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings + Returns a dict of (season, episode) : (scene_season, scene_episode) mappings for an entire show. Both the keys and values of the dict are tuples. - Will be empty if there are no scene numbers set in xem + Will be empty if no scene numbers are set in xem """ - if None is indexer_id: - return {} + return _get_numbering_for_show('tv_episodes', indexer, indexer_id) - indexer_id = int(indexer_id) - indexer = int(indexer) - xem_refresh(indexer_id, indexer) - - my_db = db.DBConnection() - rows = my_db.select( - 'SELECT season, episode, scene_season, scene_episode FROM tv_episodes WHERE indexer = ? and showid = ? and (scene_season or scene_episode) != 0 ORDER BY season, episode', - [indexer, indexer_id]) +def _get_numbering_for_show(tbl, indexer, indexer_id): result = {} - for row in rows: - season = int(row['season']) - episode = int(row['episode']) - scene_season = int(row['scene_season']) - scene_episode = int(row['scene_episode']) - result[(season, episode)] = (scene_season, scene_episode) + if None is not indexer_id: + if 'tv_episodes' == tbl: + xem_refresh(indexer_id, indexer) + + my_db = db.DBConnection() + # noinspection SqlResolve + rows = my_db.select( + 'SELECT season, episode, scene_season, scene_episode' + ' FROM %s' % tbl + + ' WHERE indexer = ? AND %s = ?' % ('indexer_id', 'showid')['tv_episodes' == tbl] + + ' AND (scene_season OR scene_episode) != 0' + ' ORDER BY season, episode', + [int(indexer), int(indexer_id)]) + + for row in rows: + season, episode = tryInt(row['season'], None), tryInt(row['episode'], None) + if None is not season and None is not episode: + scene_season, scene_episode = tryInt(row['scene_season'], None), tryInt(row['scene_episode'], None) + if None is not scene_season and None is not scene_episode: + result[(season, episode)] = (scene_season, scene_episode) return result def get_scene_absolute_numbering_for_show(indexer_id, indexer): """ - Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings - for an entire show. Both the keys and values of the dict are tuples. - Will be empty if there are no scene numbers set + Returns a dict of (season, episode) : scene_absolute_number mappings for an entire show. + Will be empty if no scene numbers are set """ - if None is indexer_id: - return {} - - indexer_id = int(indexer_id) - indexer = int(indexer) - - my_db = db.DBConnection() - rows = my_db.select( - 'SELECT absolute_number, scene_absolute_number FROM scene_numbering WHERE indexer = ? and indexer_id = ? and scene_absolute_number != 0 ORDER BY absolute_number', - [indexer, indexer_id]) - - result = {} - for row in rows: - absolute_number = int(row['absolute_number']) - scene_absolute_number = int(row['scene_absolute_number']) - - result[absolute_number] = scene_absolute_number - - return result + return _get_absolute_numbering_for_show('scene_numbering', indexer, indexer_id) def get_xem_absolute_numbering_for_show(indexer_id, indexer): """ - Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings - for an entire show. Both the keys and values of the dict are tuples. - Will be empty if there are no scene numbers set in xem + Returns a dict of (season, episode) : scene_absolute_number mappings for an entire show. + Will be empty if no scene numbers are set in xem """ - if None is indexer_id: - return {} + return _get_absolute_numbering_for_show('tv_episodes', indexer, indexer_id) - indexer_id = int(indexer_id) - indexer = int(indexer) - xem_refresh(indexer_id, indexer) +def _get_absolute_numbering_for_show(tbl, indexer, indexer_id): result = {} - my_db = db.DBConnection() - rows = my_db.select( - 'SELECT season, episode, scene_absolute_number FROM tv_episodes WHERE indexer = ? and showid = ? and scene_absolute_number != 0 ORDER BY season, episode', - [indexer, indexer_id]) - for row in rows: - season = int(row['season']) - episode = int(row['episode']) - scene_absolute_number = int(row['scene_absolute_number']) + if None is not indexer_id: + if 'tv_episodes' == tbl: + xem_refresh(indexer_id, indexer) - result[(season, episode)] = scene_absolute_number + my_db = db.DBConnection() + # noinspection SqlResolve + rows = my_db.select( + 'SELECT season, episode, absolute_number, scene_absolute_number' + ' FROM %s' % tbl + + ' WHERE indexer = ? AND %s = ?' % ('indexer_id', 'showid')['tv_episodes' == tbl] + + ' AND scene_absolute_number != 0' + ' ORDER BY season, episode', + [int(indexer), int(indexer_id)]) + + for row in rows: + season, episode, abs_num = map(lambda x: tryInt(row[x], None), ('season', 'episode', 'absolute_number')) + if None is season and None is episode and None is not abs_num: + season, episode, _ = _get_sea(indexer, indexer_id, absolute_number=abs_num) + + if None is not season and None is not episode: + scene_absolute_number = tryInt(row['scene_absolute_number'], None) + if None is not scene_absolute_number: + result[(season, episode)] = scene_absolute_number return result +def _get_sea(indexer, indexer_id, season=None, episode=None, absolute_number=None): + show_obj = sickbeard.helpers.find_show_by_id(sickbeard.showList, {indexer: indexer_id}, + no_mapped_ids=True) + if show_obj: + ep_obj = None + if None is not absolute_number: + ep_obj = show_obj.getEpisode(absolute_number=absolute_number) + elif None is not season and None is not episode: + ep_obj = show_obj.getEpisode(season, episode) + if None is not ep_obj: + season, episode, absolute_number = ep_obj.season, ep_obj.episode, ep_obj.absolute_number + return season, episode, absolute_number + + def xem_refresh(indexer_id, indexer, force=False): """ Refresh data from xem for a tv show @param indexer_id: int + @param indexer: int + @param force: bool """ if None is indexer_id: return @@ -472,8 +532,11 @@ def xem_refresh(indexer_id, indexer, force=False): max_refresh_age_secs = 86400 # 1 day my_db = db.DBConnection() - rows = my_db.select('SELECT last_refreshed FROM xem_refresh WHERE indexer = ? and indexer_id = ?', - [indexer, indexer_id]) + rows = my_db.select( + 'SELECT last_refreshed' + ' FROM xem_refresh' + ' WHERE indexer = ? AND indexer_id = ?', + [indexer, indexer_id]) if rows: last_refresh = int(rows[0]['last_refreshed']) refresh = int(time.mktime(datetime.datetime.today().timetuple())) > last_refresh + max_refresh_age_secs @@ -493,32 +556,24 @@ def xem_refresh(indexer_id, indexer, force=False): try: parsed_json = sickbeard.helpers.getURL(url, json=True, timeout=90) if not parsed_json or '' == parsed_json: - logger.log(u'No XEM data for show %s on %s' % (indexer_id, sickbeard.indexerApi(indexer).name), logger.MESSAGE) + logger.log(u'No XEM data for show %s on %s' % ( + indexer_id, sickbeard.indexerApi(indexer).name), logger.MESSAGE) return if 'success' in parsed_json['result']: cl = [] for entry in parsed_json['data']: - if 'scene' in entry: - cl.append([ - 'UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?', - [entry['scene']['season'], - entry['scene']['episode'], - entry['scene']['absolute'], - indexer_id, - entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'], - entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode'] - ]]) - if 'scene_2' in entry: # for doubles - cl.append([ - 'UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?', - [entry['scene_2']['season'], - entry['scene_2']['episode'], - entry['scene_2']['absolute'], - indexer_id, - entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'], - entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode'] - ]]) + # use scene2 for doubles + scene = 'scene%s' % ('', '_2')['scene_2' in entry] + cl.append([ + 'UPDATE tv_episodes' + ' SET scene_season = ?, scene_episode = ?, scene_absolute_number = ?' + ' WHERE showid = ? AND season = ? AND episode = ?', + [entry[scene]['season'], entry[scene]['episode'], entry[scene]['absolute'], + indexer_id, + entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'], + entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode'] + ]]) if 0 < len(cl): my_db = db.DBConnection() @@ -534,60 +589,18 @@ def xem_refresh(indexer_id, indexer, force=False): def fix_xem_numbering(indexer_id, indexer): - """ - Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings - for an entire show. Both the keys and values of the dict are tuples. - Will be empty if there are no scene numbers set in xem - """ + if None is indexer_id: return {} indexer_id = int(indexer_id) indexer = int(indexer) - # query = [{ - # "name": self.show.name, - # "seasons": [{ - # "episodes": [{ - # "episode_number": None, - # "name": None - # }], - # "season_number": None, - # }], - # "/tv/tv_program/number_of_seasons": [], - # "/tv/tv_program/number_of_episodes": [], - # "/tv/tv_program/thetvdb_id": [], - # "/tv/tv_program/tvrage_id": [], - # "type": "/tv/tv_program", - # }] - # - # - # url = 'https://www.googleapis.com/freebase/v1/mqlread' - # api_key = "AIzaSyCCHNp4dhVHxJYzbLiCE4y4a1rgTnX4fDE" - # params = { - # 'query': json.dumps(query), - # 'key': api_key - # } - # - # - # def get_from_api(url, params=None): - # """Build request and return results - # """ - # import xmltodict - # - # response = requests.get(url, params=params) - # if response.status_code == 200: - # try: - # return response.json() - # except ValueError: - # return xmltodict.parse(response.text)['Data'] - # - # # Get query results - # tmp = get_from_api(url, params=params)['result'] - my_db = db.DBConnection() rows = my_db.select( - 'SELECT season, episode, absolute_number, scene_season, scene_episode, scene_absolute_number FROM tv_episodes WHERE indexer = ? and showid = ?', + 'SELECT season, episode, absolute_number, scene_season, scene_episode, scene_absolute_number' + ' FROM tv_episodes' + ' WHERE indexer = ? AND showid = ?', [indexer, indexer_id]) last_absolute_number = None @@ -654,7 +667,9 @@ def fix_xem_numbering(indexer_id, indexer): if update_absolute_number: cl.append([ - 'UPDATE tv_episodes SET absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?', + 'UPDATE tv_episodes' + ' SET absolute_number = ?' + ' WHERE showid = ? AND season = ? AND episode = ?', [absolute_number, indexer_id, season, @@ -664,7 +679,9 @@ def fix_xem_numbering(indexer_id, indexer): if update_scene_season: cl.append([ - 'UPDATE tv_episodes SET scene_season = ? WHERE showid = ? AND season = ? AND episode = ?', + 'UPDATE tv_episodes' + ' SET scene_season = ?' + ' WHERE showid = ? AND season = ? AND episode = ?', [scene_season, indexer_id, season, @@ -674,7 +691,9 @@ def fix_xem_numbering(indexer_id, indexer): if update_scene_episode: cl.append([ - 'UPDATE tv_episodes SET scene_episode = ? WHERE showid = ? AND season = ? AND episode = ?', + 'UPDATE tv_episodes' + ' SET scene_episode = ?' + ' WHERE showid = ? AND season = ? AND episode = ?', [scene_episode, indexer_id, season, @@ -684,7 +703,9 @@ def fix_xem_numbering(indexer_id, indexer): if update_scene_absolute_number: cl.append([ - 'UPDATE tv_episodes SET scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?', + 'UPDATE tv_episodes' + ' SET scene_absolute_number = ?' + ' WHERE showid = ? AND season = ? AND episode = ?', [scene_absolute_number, indexer_id, season, @@ -697,37 +718,34 @@ def fix_xem_numbering(indexer_id, indexer): my_db.mass_action(cl) -def set_scene_numbering_helper(indexerid, indexer, forSeason=None, forEpisode=None, forAbsolute=None, - sceneSeason=None, sceneEpisode=None, sceneAbsolute=None): +def set_scene_numbering_helper(indexerid, indexer, for_season=None, for_episode=None, for_absolute=None, + scene_season=None, scene_episode=None, scene_absolute=None): # sanitize: indexerid = None if indexerid in [None, 'null', ''] else int(indexerid) indexer = None if indexer in [None, 'null', ''] else int(indexer) show_obj = sickbeard.helpers.find_show_by_id(sickbeard.showList, {indexer: indexerid}, no_mapped_ids=True) - if not show_obj: - result = {'success': False} - return result + return {'success': False} + for_season = None if for_season in [None, 'null', ''] else int(for_season) + for_episode = None if for_episode in [None, 'null', ''] else int(for_episode) + ep_args = {'show': indexerid, 'season': for_season, 'episode': for_episode} + scene_args = {'indexer': indexer, 'indexer_id': indexerid, 'season': for_season, 'episode': for_episode} if not show_obj.is_anime: - for_season = None if forSeason in [None, 'null', ''] else int(forSeason) - for_episode = None if forEpisode in [None, 'null', ''] else int(forEpisode) - scene_season = None if sceneSeason in [None, 'null', ''] else int(sceneSeason) - scene_episode = None if sceneEpisode in [None, 'null', ''] else int(sceneEpisode) + scene_season = None if scene_season in [None, 'null', ''] else int(scene_season) + scene_episode = None if scene_episode in [None, 'null', ''] else int(scene_episode) action_log = u'Set episode scene numbering to %sx%s for episode %sx%s of "%s"' \ % (scene_season, scene_episode, for_season, for_episode, show_obj.name) - ep_args = {'show': indexerid, 'season': for_season, 'episode': for_episode} - scene_args = {'indexer_id': indexerid, 'indexer': indexer, 'season': for_season, 'episode': for_episode, - 'sceneSeason': scene_season, 'sceneEpisode': scene_episode} + scene_args.update({'scene_season': scene_season, 'scene_episode': scene_episode}) result = {'forSeason': for_season, 'forEpisode': for_episode, 'sceneSeason': None, 'sceneEpisode': None} else: - for_absolute = None if forAbsolute in [None, 'null', ''] else int(forAbsolute) - scene_absolute = None if sceneAbsolute in [None, 'null', ''] else int(sceneAbsolute) - action_log = u'Set absolute scene numbering to %s for episode %s of "%s"' \ - % (scene_absolute, for_absolute, show_obj.name) - ep_args = {'show': indexerid, 'absolute': for_absolute} - scene_args = {'indexer_id': indexerid, 'indexer': indexer, 'absolute_number': for_absolute, - 'sceneAbsolute': scene_absolute} + for_absolute = None if for_absolute in [None, 'null', ''] else int(for_absolute) + scene_absolute = None if scene_absolute in [None, 'null', ''] else int(scene_absolute) + action_log = u'Set absolute scene numbering to %s for episode %sx%s of "%s"' \ + % (scene_absolute, for_season, for_episode, show_obj.name) + ep_args.update({'absolute': for_absolute}) + scene_args.update({'absolute_number': for_absolute, 'scene_absolute': scene_absolute, 'anime': True}) result = {'forAbsolute': for_absolute, 'sceneAbsolute': None} if ep_args.get('absolute'): @@ -735,18 +753,15 @@ def set_scene_numbering_helper(indexerid, indexer, forSeason=None, forEpisode=No elif None is not ep_args['season'] and None is not ep_args['episode']: ep_obj = show_obj.getEpisode(int(ep_args['season']), int(ep_args['episode'])) else: - ep_obj = 'Invalid paramaters' + ep_obj = 'Invalid parameters' - if ep_obj is None: - ep_obj = "Episode couldn't be retrieved" - - result['success'] = not isinstance(ep_obj, str) + result['success'] = None is not ep_obj and not isinstance(ep_obj, str) if result['success']: logger.log(action_log, logger.DEBUG) set_scene_numbering(**scene_args) show_obj.flushEpisodes() else: - result['errorMessage'] = ep_obj + result['errorMessage'] = "Episode couldn't be retrieved, invalid parameters" if not show_obj.is_anime: scene_numbering = get_scene_numbering(indexerid, indexer, for_season, for_episode) @@ -757,4 +772,4 @@ def set_scene_numbering_helper(indexerid, indexer, forSeason=None, forEpisode=No if scene_numbering: result['sceneAbsolute'] = scene_numbering - return result \ No newline at end of file + return result diff --git a/sickbeard/tv.py b/sickbeard/tv.py index d6e6c95c..72b496d1 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -992,7 +992,7 @@ class TVShow(object): if not self.tag: self.tag = 'Show List' - logger.log('Loaded.. {: <9} {: <8} {}'.format( + logger.log(u'Loaded.. {: <9} {: <8} {}'.format( sickbeard.indexerApi(self.indexer).config.get('name') + ',', str(self.indexerid) + ',', self.name)) # Get IMDb_info from database diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 0a5bf4d9..901095d6 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -2342,16 +2342,18 @@ class Home(MainHandler): showObj.rls_require_words = rls_require_words.strip() # if we change location clear the db of episodes, change it, write to db, and rescan - if os.path.normpath(showObj._location) != os.path.normpath(location): - logger.log(os.path.normpath(showObj._location) + ' != ' + os.path.normpath(location), logger.DEBUG) - if not ek.ek(os.path.isdir, location) and not sickbeard.CREATE_MISSING_SHOW_DIRS: - errors.append('New location %s does not exist' % location) + old_path = ek.ek(os.path.normpath, showObj._location) + new_path = ek.ek(os.path.normpath, location) + if old_path != new_path: + logger.log(u'%s != %s' % (old_path, new_path), logger.DEBUG) + if not ek.ek(os.path.isdir, new_path) and not sickbeard.CREATE_MISSING_SHOW_DIRS: + errors.append(u'New location %s does not exist' % new_path) # don't bother if we're going to update anyway elif not do_update: # change it try: - showObj.location = location + showObj.location = new_path try: sickbeard.showQueueScheduler.action.refreshShow(showObj) # @UndefinedVariable except exceptions.CantRefreshException as e: @@ -2361,7 +2363,8 @@ class Home(MainHandler): # rescan the episodes in the new folder except exceptions.NoNFOException: errors.append( - "The folder at %s doesn't contain a tvshow.nfo - copy your files to that folder before you change the directory in SickGear." % location) + u"The folder at %s doesn't contain a tvshow.nfo - " + u"copy your files to that folder before you change the directory in SickGear." % new_path) # save it to the DB showObj.saveToDB()