mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 00:43:37 +00:00
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:
parent
91ee2c9ef5
commit
7dc89c084f
10 changed files with 118 additions and 51 deletions
|
@ -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"> </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>
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
||||
|
|
|
@ -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 """
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -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):
|
||||
|
||||
|
|
Loading…
Reference in a new issue