Added ability to switch branches from general settings/advanced, will perform a forced checkout of whatever branch you choose and restart automatically.

Git updates are now forced to overwrite locale changes to avoid needing to manually stash uncommited changes before being able to proceed with a update.

Fixed indexer mapping when unable to locate show on indexer that we are trying to map to.
This commit is contained in:
echel0n 2014-07-27 10:58:19 -07:00
parent 91ee2c9ef5
commit 7dc89c084f
10 changed files with 118 additions and 51 deletions

View file

@ -276,6 +276,23 @@
<fieldset class="component-group-list" style="width:670px">
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Git Branch:</span>
<span class="component-desc">
<select id="git_branch" name="git_branch">
#for $cur_branch in $sickbeard.versionCheckScheduler.action.list_remote_branches():
<option value="$cur_branch" #if $cur_branch == $sickbeard.version.SICKBEARD_VERSION then "selected=\"selected\"" else ""#>$cur_branch.capitalize()</option>
#end for
</select>
</span>
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">Select the branch you wish to use, changing this will require a restart.</span>
</label>
</div>
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">CPU Throttling:</span>

View file

@ -694,8 +694,7 @@ class Tvdb:
log().debug("Searching for show %s" % series)
self.config['params_getSeries']['seriesname'] = series
seriesEt = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries'])
return [seriesEt[item] for item in seriesEt][0]
return [seriesEt[item] for item in seriesEt][0] if seriesEt else []
def _getSeries(self, series):
"""This searches TheTVDB.com for the series name,
@ -715,7 +714,6 @@ class Tvdb:
log().debug("Using custom UI %s" % (repr(self.config['custom_ui'])))
CustomUI = self.config['custom_ui']
ui = CustomUI(config=self.config)
else:
if not self.config['interactive']:
log().debug('Auto-selecting first search result using BaseUI')

View file

@ -556,8 +556,7 @@ class TVRage:
log().debug("Searching for show %s" % series)
self.config['params_getSeries']['show'] = series
seriesEt = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries'])
return [seriesEt[item] for item in seriesEt][0]
return [seriesEt[item] for item in seriesEt][0] if seriesEt else []
def _getSeries(self, series):
"""This searches tvrage.com for the series name,

View file

@ -24,7 +24,6 @@ import socket
import os
import re
from urllib2 import getproxies
from threading import Lock
# apparently py2exe won't build these unless they're imported somewhere

View file

@ -199,15 +199,15 @@ class ShowListUI:
self.log = log
def selectSeries(self, allSeries):
if sickbeard.showList:
idList = [x.indexerid for x in sickbeard.showList]
try:
# try to pick a show that's in my show list
for curShow in allSeries:
if int(curShow['id']) in idList:
if filter(lambda x: int(x.indexerid) == int(curShow['id']), sickbeard.showList):
return curShow
except:
pass
# if nothing matches then return everything
# if nothing matches then return first result
return allSeries[0]

View file

@ -27,6 +27,7 @@ from sickbeard import helpers
from sickbeard import logger
from sickbeard import naming
from sickbeard import db
from sickbeard import version
naming_ep_type = ("%(seasonnumber)dx%(episodenumber)02d",
"s%(seasonnumber)02de%(episodenumber)02d",
@ -190,6 +191,10 @@ def change_VERSION_NOTIFY(version_notify):
if oldSetting == False and version_notify == True:
sickbeard.versionCheckScheduler.action.run() # @UndefinedVariable
def change_VERSION(version):
if sickbeard.version.SICKBEARD_VERSION != version:
sickbeard.versionCheckScheduler.action.run() # @UndefinedVariable
def CheckSection(CFG, sec):
""" Check if INI section exists, if not create it """

View file

@ -87,3 +87,14 @@ class GitHub(object):
['repos', self.github_repo_user, self.github_repo, 'compare', base + '...' + head],
params={'per_page': per_page})
return access_API
def branches(self):
access_API = self._access_API(
['repos', self.github_repo_user, self.github_repo, 'branches'])
return access_API
def checkout(self, branch):
access_API = self._access_API(
['repos', self.github_repo_user, self.github_repo, 'branches'])
return access_API

View file

@ -65,6 +65,7 @@ from itertools import izip, cycle
urllib._urlopener = classes.SickBeardURLopener()
def indentXML(elem, level=0):
'''
Does our pretty printing, makes Matt very happy
@ -192,12 +193,14 @@ def sanitizeFileName(name):
return name
def _remove_file_failed(file):
try:
ek.ek(os.remove, file)
except:
pass
def findCertainShow(showList, indexerid):
if not showList:
return None
@ -522,6 +525,7 @@ def delete_empty_folders(check_empty_dir, keep_dir=None):
else:
break
def fileBitFilter(mode):
for bit in [stat.S_IXUSR, stat.S_IXGRP, stat.S_IXOTH, stat.S_ISUID, stat.S_ISGID]:
if mode & bit:
@ -529,6 +533,7 @@ def fileBitFilter(mode):
return mode
def chmodAsParent(childPath):
if os.name == 'nt' or os.name == 'ce':
return
@ -567,6 +572,7 @@ def chmodAsParent(childPath):
except OSError:
logger.log(u"Failed to set permission for %s to %o" % (childPath, childMode), logger.ERROR)
def fixSetGroupID(childPath):
if os.name == 'nt' or os.name == 'ce':
return
@ -622,14 +628,17 @@ def get_absolute_number_from_season_and_episode(show, season, episode):
if len(sqlResults) == 1:
absolute_number = int(sqlResults[0]["absolute_number"])
logger.log(
"Found absolute_number:" + str(absolute_number) + " by " + str(season) + "x" + str(episode), logger.DEBUG)
"Found absolute_number:" + str(absolute_number) + " by " + str(season) + "x" + str(episode),
logger.DEBUG)
else:
logger.log(
"No entries for absolute number in show: " + show.name + " found using " + str(season) + "x" + str(episode),
"No entries for absolute number in show: " + show.name + " found using " + str(season) + "x" + str(
episode),
logger.DEBUG)
return absolute_number
def get_all_episodes_from_absolute_number(show, absolute_numbers, indexer_id=None):
episodes = []
season = None
@ -712,11 +721,13 @@ def create_https_certificates(ssl_cert, ssl_key):
return True
if __name__ == '__main__':
import doctest
doctest.testmod()
def parse_json(data):
"""
Parse json data into a python object
@ -1016,6 +1027,7 @@ def get_show(name, tryIndexers=False):
return showObj
def is_hidden_folder(folder):
"""
Returns True if folder is hidden.
@ -1128,16 +1140,13 @@ def mapIndexersToShow(showObj):
mapped = {showObj.indexer: showObj.indexerid}
myDB = db.DBConnection()
sqlResults = myDB.select(
"SELECT * FROM indexer_mapping WHERE indexer_id = ? AND indexer = ?",
[showObj.indexerid, showObj.indexer])
# for each mapped entry
for curResult in sqlResults:
logger.log(u"Found " + sickbeard.indexerApi(showObj.indexer).name + "<->" + sickbeard.indexerApi(
int(curResult['mindexer'])).name + " mapping in cache for show: " + showObj.name, logger.DEBUG)
logger.log(u"Found indexer mapping in cache for show: " + showObj.name, logger.DEBUG)
mapped[int(curResult['mindexer'])] = int(curResult['mindexer_id'])
else:
sql_l = []
@ -1150,22 +1159,27 @@ def mapIndexersToShow(showObj):
lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
mapped_show = t[showObj.name]
try:
mapped_show = t[showObj.name]
except sickbeard.indexer_shownotfound:
logger.log(u"Unable to map " + sickbeard.indexerApi(showObj.indexer).name + "->" + sickbeard.indexerApi(
indexer).name + " for show: " + showObj.name + ", skipping it", logger.ERROR)
mapped_show = None
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)
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)
logger.log(u"Adding indexer 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 = db.DBConnection()
myDB.mass_action(sql_l)
return mapped
@ -1183,6 +1197,7 @@ def touchFile(fname, atime=None):
return False
def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=None, json=False):
"""
Returns a byte-string retrieved from the url provider.
@ -1231,10 +1246,7 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
logger.log(u"Unknown exception while loading URL " + url + ": " + traceback.format_exc(), logger.WARNING)
return
if not resp:
logger.log(u"No data returned from " + url, logger.DEBUG)
return
elif not resp.ok:
if not resp.ok:
logger.log(u"Requested url " + url + " returned status code is " + str(
resp.status_code) + ': ' + clients.http_error_code[resp.status_code], logger.WARNING)
return
@ -1244,8 +1256,8 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
return resp.content
def download_file(url, filename, session=None):
def download_file(url, filename, session=None):
# create session
session = CacheControl(sess=session, cache=caches.FileCache(os.path.join(sickbeard.CACHE_DIR, 'sessions')))
@ -1309,6 +1321,7 @@ def download_file(url, filename, session=None):
return True
def clearCache(force=False):
update_datetime = datetime.datetime.now()

View file

@ -27,7 +27,6 @@ import tarfile
import stat
import traceback
import gh_api as github
import threading
import sickbeard
from sickbeard import helpers, notifiers
@ -53,11 +52,8 @@ class CheckVersion():
else:
self.updater = None
def __del__(self):
pass
def run(self, force=False):
if self.check_for_new_version():
if self.check_for_new_version(force):
if sickbeard.AUTO_UPDATE:
logger.log(u"New update found for SickRage, starting auto-updater ...")
ui.notifications.message('New update found for SickRage, starting auto-updater')
@ -113,10 +109,15 @@ class CheckVersion():
self.updater.set_newest_text()
return True
def update(self):
if self.updater.need_update():
def update(self, branch=None):
if branch and branch != self.updater.branch:
return self.updater.update(branch)
elif self.updater.need_update():
return self.updater.update()
def list_remote_branches(self):
return self.updater.list_remote_branches()
class UpdateManager():
def get_github_repo_user(self):
return 'echel0n'
@ -127,7 +128,6 @@ class UpdateManager():
def get_update_url(self):
return sickbeard.WEB_ROOT + "/home/update/?pid=" + str(sickbeard.PID)
class WindowsUpdateManager(UpdateManager):
def __init__(self):
self.github_repo_user = self.get_github_repo_user()
@ -200,7 +200,10 @@ class WindowsUpdateManager(UpdateManager):
sickbeard.NEWEST_VERSION_STRING = newest_text
def update(self):
def update(self, branch='windows_binaries'):
# set branch version
self.branch = branch
zip_download_url = self._find_newest_version(True)
logger.log(u"new_link: " + repr(zip_download_url), logger.DEBUG)
@ -267,6 +270,8 @@ class WindowsUpdateManager(UpdateManager):
return True
def list_remote_branches(self):
return ['windows_binaries']
class GitUpdateManager(UpdateManager):
def __init__(self):
@ -500,13 +505,19 @@ class GitUpdateManager(UpdateManager):
return False
def update(self):
def update(self, branch=sickbeard.version.SICKBEARD_VERSION):
"""
Calls git pull origin <branch> in order to update SickRage. Returns a bool depending
on the call's success.
"""
output, err, exit_status = self._run_git(self._git_path, 'pull origin ' + self.branch) # @UnusedVariable
# set branch version
self.branch = branch
if self.branch == sickbeard.version.SICKBEARD_VERSION:
output, err, exit_status = self._run_git(self._git_path, 'pull -f origin ' + self.branch) # @UnusedVariable
else:
output, err, exit_status = self._run_git(self._git_path, 'checkout -f ' + self.branch) # @UnusedVariable
if exit_status == 0:
# Notify update successful
@ -516,6 +527,11 @@ class GitUpdateManager(UpdateManager):
return False
def list_remote_branches(self):
branches, err, exit_status = self._run_git(self._git_path, 'branch -r') # @UnusedVariable
if exit_status == 0 and branches:
return branches.strip().replace('origin/', '').split()
return []
class SourceUpdateManager(UpdateManager):
def __init__(self):
@ -629,10 +645,14 @@ class SourceUpdateManager(UpdateManager):
sickbeard.NEWEST_VERSION_STRING = newest_text
def update(self):
def update(self, branch=sickbeard.version.SICKBEARD_VERSION):
"""
Downloads the latest source tarball from github and installs it over the existing version.
"""
# set branch version
self.branch = branch
base_url = 'http://github.com/' + self.github_repo_user + '/' + self.github_repo
tar_download_url = base_url + '/tarball/' + self.branch
version_path = ek.ek(os.path.join, sickbeard.PROG_DIR, u'version.txt')
@ -721,3 +741,7 @@ class SourceUpdateManager(UpdateManager):
notifiers.notify_git_update(sickbeard.NEWEST_VERSION_STRING)
return True
def list_remote_branches(self):
gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch)
return gh.branches()

View file

@ -47,6 +47,7 @@ from sickbeard import naming
from sickbeard import scene_exceptions
from sickbeard import subtitles
from sickbeard import network_timezones
from sickbeard import version
from sickbeard.providers import newznab, rsstorrent
from sickbeard.common import Quality, Overview, statusStrings, qualityPresetStrings, cpu_presets, SKIPPED
@ -604,6 +605,13 @@ class ManageSearches(MainHandler):
return _munge(t)
def forceVersionCheck(self, *args, **kwargs):
# force a check to see if there is a new version
if sickbeard.versionCheckScheduler.action.check_for_new_version(force=True):
logger.log(u"Forcing version check")
redirect("/home/")
def forceBacklog(self, *args, **kwargs):
# force it to run the next time it looks
result = sickbeard.backlogSearchScheduler.forceRun()
@ -613,7 +621,6 @@ class ManageSearches(MainHandler):
redirect("/manage/manageSearches/")
def forceSearch(self, *args, **kwargs):
# force it to run the next time it looks
@ -1429,7 +1436,7 @@ class ConfigGeneral(MainHandler):
handle_reverse_proxy=None, sort_article=None, auto_update=None, notify_on_update=None,
proxy_setting=None, anon_redirect=None, git_path=None, calendar_unprotected=None,
fuzzy_dating=None, trim_zero=None, date_preset=None, date_preset_na=None, time_preset=None,
indexer_timeout=None, play_videos=None):
indexer_timeout=None, play_videos=None, git_branch=None):
results = []
@ -1496,8 +1503,11 @@ class ConfigGeneral(MainHandler):
sickbeard.HANDLE_REVERSE_PROXY = config.checkbox_to_value(handle_reverse_proxy)
sickbeard.save_config()
sickbeard.versionCheckScheduler.action.checkout_branch(git_branch)
if len(results) > 0:
for x in results:
logger.log(x, logger.ERROR)
@ -2535,15 +2545,6 @@ class HomePostProcess(MainHandler):
t.submenu = HomeMenu()
return _munge(t)
def forceVersionCheck(self, *args, **kwargs):
# force a check to see if there is a new version
if sickbeard.versionCheckScheduler.action.check_for_new_version(force=True):
logger.log(u"Forcing version check")
redirect("/home/")
def processEpisode(self, dir=None, nzbName=None, jobName=None, quiet=None, process_method=None, force=None,
is_priority=None, failed="0", type="auto", *args, **kwargs):