diff --git a/gui/slick/css/dark.css b/gui/slick/css/dark.css index fefc3fe3a74e8c43b7a6c1a35c4b1a388f0318e5..e608042ae82ebc4e602b5aead6f9328041c66ae9 100644 --- a/gui/slick/css/dark.css +++ b/gui/slick/css/dark.css @@ -1305,7 +1305,7 @@ td.col-subtitles { th.col-status, td.col-status { - width: 200px; + width: 210px; text-align: center; } diff --git a/gui/slick/css/light.css b/gui/slick/css/light.css index 9518a99faa6424f707ac0915f3172b983f6b011a..c75cbdd08c8bf6d7b1cf0c715fd81116adb7aaa0 100644 --- a/gui/slick/css/light.css +++ b/gui/slick/css/light.css @@ -1280,7 +1280,7 @@ td.col-subtitles { th.col-status, td.col-status { - width: 200px; + width: 210px; text-align: center; } diff --git a/gui/slick/css/style.css b/gui/slick/css/style.css index 0e0cfafcf1c52d83bd8f6a51c229a517df963850..e51f082d56ae033cfea21a59ff1aabe43f5a27f1 100644 --- a/gui/slick/css/style.css +++ b/gui/slick/css/style.css @@ -1309,7 +1309,7 @@ td.col-subtitles { th.col-status, td.col-status { - width: 200px; + width: 210px; text-align: center; } diff --git a/gui/slick/interfaces/default/history.tmpl b/gui/slick/interfaces/default/history.tmpl index 9a1fc75c131bcc5ccaed6abed7d4ef71ce848551..0babb59b8ee3b761ac8982838ea8353a78ab4fe9 100644 --- a/gui/slick/interfaces/default/history.tmpl +++ b/gui/slick/interfaces/default/history.tmpl @@ -12,6 +12,7 @@ #set global $sbPath=".." #set global $topmenu="history"# #set $layout = $sickbeard.HISTORY_LAYOUT +#set $history_limit = $sickbeard.HISTORY_LIMIT #include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_top.tmpl") @@ -87,11 +88,11 @@ <h1 class="title">$title</h1> #end if <div class="h2footer pull-right"><b>Limit:</b> - <select name="limit" id="limit" class="form-control form-control-inline input-sm"> - <option value="100" #if $limit == "100" then "selected=\"selected\"" else ""#>100</option> - <option value="250" #if $limit == "250" then "selected=\"selected\"" else ""#>250</option> - <option value="500" #if $limit == "500" then "selected=\"selected\"" else ""#>500</option> - <option value="0" #if $limit == "0" then "selected=\"selected\"" else ""#>All</option> + <select name="history_limit" id="history_limit" class="form-control form-control-inline input-sm" onchange="location = this.options[this.selectedIndex].value;"> + <option value="$sbRoot/setHistoryLimit/?history_limit=100" #if $history_limit == "100" then "selected=\"selected\"" else ""#>100</option> + <option value="$sbRoot/setHistoryLimit/?history_limit=250" #if $history_limit == "250" then "selected=\"selected\"" else ""#>250</option> + <option value="$sbRoot/setHistoryLimit/?history_limit=500" #if $history_limit == "500" then "selected=\"selected\"" else ""#>500</option> + <option value="$sbRoot/setHistoryLimit/?history_limit=0" #if $history_limit == "0" then "selected=\"selected\"" else ""#>All</option> </select> diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index e81ec3161a90f36e560842a8edbc92ae8c765fb0..44ad391965872e250262de64dbc239198d6ee837 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -487,6 +487,7 @@ EMAIL_LIST = None GUI_NAME = None HOME_LAYOUT = None HISTORY_LAYOUT = None +HISTORY_LIMIT = 0 DISPLAY_SHOW_SPECIALS = False COMING_EPS_LAYOUT = None COMING_EPS_DISPLAY_PAUSED = False @@ -583,7 +584,7 @@ def initialize(consoleLogging=True): USE_LISTVIEW, METADATA_KODI, METADATA_KODI_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, metadata_provider_dict, \ NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, SYNC_FILES, POSTPONE_IF_SYNC_FILES, dailySearchScheduler, NFO_RENAME, \ GUI_NAME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, COMING_EPS_LAYOUT, COMING_EPS_SORT, COMING_EPS_DISPLAY_PAUSED, COMING_EPS_MISSED_RANGE, DISPLAY_FILESIZE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, FILTER_ROW, \ - POSTER_SORTBY, POSTER_SORTDIR, \ + POSTER_SORTBY, POSTER_SORTDIR, HISTORY_LIMIT, \ METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, REQUIRE_WORDS, CALENDAR_UNPROTECTED, NO_RESTART, CREATE_MISSING_SHOW_DIRS, \ ADD_SHOWS_WO_DIR, USE_SUBTITLES, SUBTITLES_LANGUAGES, SUBTITLES_DIR, SUBTITLES_SERVICES_LIST, SUBTITLES_SERVICES_ENABLED, SUBTITLES_HISTORY, SUBTITLES_FINDER_FREQUENCY, SUBTITLES_MULTI, EMBEDDED_SUBTITLES_ALL, SUBTITLES_EXTRA_SCRIPTS, subtitlesFinderScheduler, \ USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, TMDB_API_KEY, DEBUG, DEFAULT_PAGE, PROXY_SETTING, PROXY_INDEXERS, \ @@ -1143,6 +1144,7 @@ def initialize(consoleLogging=True): HOME_LAYOUT = check_setting_str(CFG, 'GUI', 'home_layout', 'poster') HISTORY_LAYOUT = check_setting_str(CFG, 'GUI', 'history_layout', 'detailed') + HISTORY_LIMIT = check_setting_str(CFG, 'GUI', 'history_limit', '100') DISPLAY_SHOW_SPECIALS = bool(check_setting_int(CFG, 'GUI', 'display_show_specials', 1)) COMING_EPS_LAYOUT = check_setting_str(CFG, 'GUI', 'coming_eps_layout', 'banner') COMING_EPS_DISPLAY_PAUSED = bool(check_setting_int(CFG, 'GUI', 'coming_eps_display_paused', 0)) @@ -2077,6 +2079,7 @@ def save_config(): new_config['GUI']['theme_name'] = THEME_NAME new_config['GUI']['home_layout'] = HOME_LAYOUT new_config['GUI']['history_layout'] = HISTORY_LAYOUT + new_config['GUI']['history_limit'] = HISTORY_LIMIT new_config['GUI']['display_show_specials'] = int(DISPLAY_SHOW_SPECIALS) new_config['GUI']['coming_eps_layout'] = COMING_EPS_LAYOUT new_config['GUI']['coming_eps_display_paused'] = int(COMING_EPS_DISPLAY_PAUSED) diff --git a/sickbeard/dailysearcher.py b/sickbeard/dailysearcher.py index 2b30b9488299f949ace1f31a91bbd3fce15484f1..5d5d3d27b39a8a5968345b7fba24a1b2dad66f21 100644 --- a/sickbeard/dailysearcher.py +++ b/sickbeard/dailysearcher.py @@ -70,7 +70,7 @@ class DailySearcher(): show = helpers.findCertainShow(sickbeard.showList, int(sqlEp["showid"])) # for when there is orphaned series in the database but not loaded into our showlist - if not show: + if not show or show.paused: continue except exceptions.MultipleShowObjectsException: @@ -91,9 +91,7 @@ class DailySearcher(): UpdateWantedList = 0 ep = show.getEpisode(int(sqlEp["season"]), int(sqlEp["episode"])) with ep.lock: - if ep.show.paused: - ep.status = ep.show.default_ep_status - elif ep.season == 0: + if ep.season == 0: logger.log(u"New episode " + ep.prettyName() + " airs today, setting status to SKIPPED because is a special season") ep.status = common.SKIPPED elif sickbeard.TRAKT_USE_ROLLING_DOWNLOAD and sickbeard.USE_TRAKT: diff --git a/sickbeard/db.py b/sickbeard/db.py index a5f8701f7c2ee99e2667ed77d9a6ed0b3f6fe843..2df18e5d493637821602901c2ef207ed70017663 100644 --- a/sickbeard/db.py +++ b/sickbeard/db.py @@ -57,7 +57,13 @@ class DBConnection(object): db_locks[self.filename] = threading.Lock() self.connection = sqlite3.connect(dbFilename(self.filename, self.suffix), 20, check_same_thread=False) - self.connection.text_factory = self._unicode_text_factory + + # Lets test without this for awhile. If non-unicode data is getting to the DB, fix it at the source. + # There are too many places we convert when we don't need to, + # sqlite, browsers, python, everything understands unicode + + #self.connection.text_factory = self._unicode_text_factory + db_cons[self.filename] = self.connection else: self.connection = db_cons[self.filename] diff --git a/sickbeard/logger.py b/sickbeard/logger.py index 0172c6856c079bfd1d70e8b03bfe8f5adadc4ddf..1bf3416ef6e8e199fff97bd9342ba6a7763f44a3 100644 --- a/sickbeard/logger.py +++ b/sickbeard/logger.py @@ -183,11 +183,6 @@ class Logger(object): # parse and submit errors to issue tracker for curError in sorted(classes.ErrorViewer.errors, key=lambda error: error.time, reverse=True)[:500]: - #Skip SSL Error, we pointed them to a URL. - if re.search('http://git.io/vJrkM', curError.message): - classes.ErrorViewer.errors.remove(curError) - continue - try: title_Error = str(curError.title) if not len(title_Error) or title_Error == 'None': diff --git a/sickbeard/providers/kat.py b/sickbeard/providers/kat.py index 3d50c81552efa0fe773d5045886e8f5ebf44ba9d..4e6d2f93b6f93b79f3db3b2a9b30a9adef47cbf3 100644 --- a/sickbeard/providers/kat.py +++ b/sickbeard/providers/kat.py @@ -165,20 +165,17 @@ class KATProvider(generic.TorrentProvider): search_string = {'Season': []} for show_name in set(allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' if ep_obj.show.air_by_date or ep_obj.show.sports: - ep_string = show_name + ' ' + str(ep_obj.airdate).split('-')[0] - search_string['Season'].append(ep_string) - ep_string = show_name + ' Season ' + str(ep_obj.airdate).split('-')[0] + ep_string += str(ep_obj.airdate).split('-')[0] search_string['Season'].append(ep_string) elif ep_obj.show.anime: - ep_string = show_name + ' ' + "%02d" % ep_obj.scene_absolute_number + ep_string += "%02d" % ep_obj.scene_absolute_number search_string['Season'].append(ep_string) else: - ep_string = show_name + ' S%02d' % int(ep_obj.scene_season) + ' -S%02d' % int( - ep_obj.scene_season) + 'E' + ' category:tv' #1) showName SXX -SXXE + ep_string = '%s S%02d -S%02dE category:tv' % (sanitizeSceneName(show_name), ep_obj.scene_season, ep_obj.scene_season) #1) showName SXX -SXXE search_string['Season'].append(ep_string) - ep_string = show_name + ' "Season ' + str( - ep_obj.scene_season) + '" -Ep*' + ' category:tv' # 2) showName "Season X" + ep_string = '%s "Season %d" -Ep* category:tv' % (sanitizeSceneName(show_name), ep_obj.scene_season) # 2) showName "Season X" search_string['Season'].append(ep_string) return [search_string] @@ -186,40 +183,30 @@ class KATProvider(generic.TorrentProvider): def _get_episode_search_strings(self, ep_obj, add_string=''): search_string = {'Episode': []} - if self.show.air_by_date: - for show_name in set(allPossibleShowNames(self.show)): - ep_string = sanitizeSceneName(show_name) + ' ' + \ - str(ep_obj.airdate).replace('-', ' ') - search_string['Episode'].append(ep_string) - elif self.show.sports: - for show_name in set(allPossibleShowNames(self.show)): - ep_string = sanitizeSceneName(show_name) + ' ' + \ - str(ep_obj.airdate).replace('-', '|') + '|' + \ - ep_obj.airdate.strftime('%b') - search_string['Episode'].append(ep_string) - elif self.show.anime: - for show_name in set(allPossibleShowNames(self.show)): - ep_string = sanitizeSceneName(show_name) + ' ' + \ - "%02i" % int(ep_obj.scene_absolute_number) - search_string['Episode'].append(ep_string) - else: - for show_name in set(allPossibleShowNames(self.show)): - ep_string = sanitizeSceneName(show_name) + ' ' + \ - sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season, - 'episodenumber': ep_obj.scene_episode} + '|' + \ - sickbeard.config.naming_ep_type[0] % {'seasonnumber': ep_obj.scene_season, - 'episodenumber': ep_obj.scene_episode} + ' %s category:tv' % add_string - search_string['Episode'].append(re.sub('\s+', ' ', ep_string)) + for show_name in set(allPossibleShowNames(self.show)): + ep_string = sanitizeSceneName(show_name) + ' ' + if self.show.air_by_date: + ep_string += str(ep_obj.airdate).replace('-', ' ') + elif self.show.sports: + ep_string += str(ep_obj.airdate).replace('-', ' ') + '|' + ep_obj.airdate.strftime('%b') + elif self.show.anime: + ep_string += "%02d" % ep_obj.scene_absolute_number + else: + ep_string += sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season, + 'episodenumber': ep_obj.scene_episode} + '|' + \ + sickbeard.config.naming_ep_type[0] % {'seasonnumber': ep_obj.scene_season, + 'episodenumber': ep_obj.scene_episode} + ' category:tv' + if add_string: + ep_string += ' ' + add_string + + search_string['Episode'].append(re.sub('\s+', ' ', ep_string)) return [search_string] def _get_size(self, item): title, url, id, seeders, leechers, size, pubdate = item - if not size: - return -1 - - return size + return size or -1 def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0, epObj=None): diff --git a/sickbeard/search.py b/sickbeard/search.py index 90993728a045ada8a5477e1ad7d7f7f3cc62f048..2c48f4fd7889dba664f6e40df1bc490705ea856f 100644 --- a/sickbeard/search.py +++ b/sickbeard/search.py @@ -397,6 +397,10 @@ def searchForNeededEpisodes(): # pick a single result for each episode, respecting existing results for curEp in curFoundResults: + if not curEp.show or curEp.show.paused: + logger.log(u"Skipping %s because the show is paused " % curEp.prettyName(), logger.DEBUG) + continue + bestResult = pickBestResult(curFoundResults[curEp], curEp.show) # if all results were rejected move on to the next episode diff --git a/sickbeard/search_queue.py b/sickbeard/search_queue.py index b99984e46bedad4a1f206613c874874627a3da7d..5f735e679bff2b312216c087d52651fb96b43e80 100644 --- a/sickbeard/search_queue.py +++ b/sickbeard/search_queue.py @@ -216,22 +216,23 @@ class BacklogQueueItem(generic_queue.QueueItem): def run(self): generic_queue.QueueItem.run(self) - try: - logger.log("Beginning backlog search for: [" + self.show.name + "]") - searchResult = search.searchProviders(self.show, self.segment, False) - - if searchResult: - for result in searchResult: - # just use the first result for now - logger.log(u"Downloading " + result.name + " from " + result.provider.name) - search.snatchEpisode(result) - - # give the CPU a break - time.sleep(common.cpu_presets[sickbeard.CPU_PRESET]) - else: - logger.log(u"No needed episodes found during backlog search for: [" + self.show.name + "]") - except Exception: - logger.log(traceback.format_exc(), logger.DEBUG) + if not self.show.paused: + try: + logger.log("Beginning backlog search for: [" + self.show.name + "]") + searchResult = search.searchProviders(self.show, self.segment, False) + + if searchResult: + for result in searchResult: + # just use the first result for now + logger.log(u"Downloading " + result.name + " from " + result.provider.name) + search.snatchEpisode(result) + + # give the CPU a break + time.sleep(common.cpu_presets[sickbeard.CPU_PRESET]) + else: + logger.log(u"No needed episodes found during backlog search for: [" + self.show.name + "]") + except Exception: + logger.log(traceback.format_exc(), logger.DEBUG) self.finish() diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index ffa29e2d5a36b9177b853dd01c189e7b8fbdc548..b6d1d11bcfd9f9e2fe27cce515b8e23adddd1786 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -458,6 +458,15 @@ class WebRoot(WebHandler): return self.redirect("/history/") + def setHistoryLimit(self, history_limit): + + if not int(history_limit): + history_limit = 100 + + sickbeard.HISTORY_LIMIT = history_limit + + return self.redirect("/history/") + def toggleDisplayShowSpecials(self, show): sickbeard.DISPLAY_SHOW_SPECIALS = not sickbeard.DISPLAY_SHOW_SPECIALS @@ -2197,7 +2206,7 @@ class HomeNews(Home): t.title = "News" t.header = "News" t.topmenu = "news" - t.data = markdown2.markdown(news) + t.data = markdown2.markdown(news if news else "The was a problem connecting to github, please refresh and try again") return t.respond() @@ -2218,7 +2227,7 @@ class HomeChangeLog(Home): t.title = "Changelog" t.header = "Changelog" t.topmenu = "changes" - t.data = markdown2.markdown(changes) + t.data = markdown2.markdown(changes if changes else "The was a problem connecting to github, please refresh and try again") return t.respond()