diff --git a/SickBeard.py b/SickBeard.py index 74b68050..204fff63 100755 --- a/SickBeard.py +++ b/SickBeard.py @@ -56,14 +56,11 @@ import threading import getopt import sickbeard -from sickbeard import db +from sickbeard import db, logger, network_timezones, failed_history, name_cache, versionChecker from sickbeard.tv import TVShow -from sickbeard import logger, network_timezones, failed_history, name_cache from sickbeard.webserveInit import SRWebServer -from sickbeard.version import SICKBEARD_VERSION from sickbeard.databases.mainDB import MIN_DB_VERSION, MAX_DB_VERSION from sickbeard.event_queue import Events - from lib.configobj import ConfigObj throwaway = datetime.datetime.strptime('20110101', '%Y%m%d') @@ -350,7 +347,7 @@ class SickRage(object): os._exit(1) if self.consoleLogging: - print "Starting up SickRage " + SICKBEARD_VERSION + " from " + sickbeard.CONFIG_FILE + print "Starting up SickRage " + sickbeard.BRANCH + " from " + sickbeard.CONFIG_FILE # Fire up all our threads sickbeard.start() @@ -369,6 +366,7 @@ class SickRage(object): if self.forceUpdate or sickbeard.UPDATE_SHOWS_ON_START: sickbeard.showUpdateScheduler.action.run(force=True) # @UndefinedVariable + # Launch browser if sickbeard.LAUNCH_BROWSER and not (self.noLaunch or self.runAsDaemon): sickbeard.launchBrowser(self.startPort) diff --git a/gui/slick/interfaces/default/config.tmpl b/gui/slick/interfaces/default/config.tmpl index cf85fe61..ee9e1ab4 100644 --- a/gui/slick/interfaces/default/config.tmpl +++ b/gui/slick/interfaces/default/config.tmpl @@ -30,7 +30,7 @@
SR Version: #if $sickbeard.VERSION_NOTIFY - BRANCH: ($sickbeard.version.SICKBEARD_VERSION) / COMMIT: ($sickbeard.CUR_COMMIT_HASH)
+ BRANCH: ($sickbeard.BRANCH) / COMMIT: ($sickbeard.CUR_COMMIT_HASH)
#else You don't have version checking turned on. Please turn on "Check for Update" in Config > General.
#end if diff --git a/gui/slick/interfaces/default/config_general.tmpl b/gui/slick/interfaces/default/config_general.tmpl index 777bdeb2..0f6d81fe 100644 --- a/gui/slick/interfaces/default/config_general.tmpl +++ b/gui/slick/interfaces/default/config_general.tmpl @@ -282,7 +282,7 @@ diff --git a/gui/slick/interfaces/default/inc_top.tmpl b/gui/slick/interfaces/default/inc_top.tmpl index 783416b3..5c9746bd 100644 --- a/gui/slick/interfaces/default/inc_top.tmpl +++ b/gui/slick/interfaces/default/inc_top.tmpl @@ -1,4 +1,3 @@ -#import sickbeard.version #import sickbeard #import urllib @@ -10,7 +9,7 @@ - SickRage - BRANCH:$sickbeard.version.SICKBEARD_VERSION - $title + SickRage - BRANCH:[$sickbeard.BRANCH] - $title diff --git a/setup.py b/setup.py index b6691a05..a3e2eb89 100644 --- a/setup.py +++ b/setup.py @@ -1,12 +1,30 @@ import re -import urllib, ConfigParser -from distutils.core import setup -import py2exe, sys, os, shutil, datetime, zipfile, subprocess, fnmatch +import urllib +import ConfigParser +import sys +import os +import shutil +import zipfile +import subprocess +import fnmatch import googlecode_upload -from lib.pygithub import github + +from distutils.core import setup + +try: + import py2exe +except: + print "The Python module py2exe is required" + sys.exit(1) + +try: + import pygithub.github +except: + print "The Python module pyGitHub is required" + sys.exit(1) # mostly stolen from the SABnzbd package.py file -name = 'SickBeard' +name = 'SickRage' version = '0.1' release = name + '-' + version @@ -14,12 +32,12 @@ release = name + '-' + version Win32ConsoleName = 'SickBeard-console.exe' Win32WindowName = 'SickBeard.exe' -def findLatestBuild(): - regex = "http\://sickbeard\.googlecode\.com/files/SickBeard\-win32\-alpha\-build(\d+)(?:\.\d+)?\.zip" - - svnFile = urllib.urlopen("http://code.google.com/p/sickbeard/downloads/list") - +def findLatestBuild(): + regex = "http\://sickrage\.googlecode\.com/files/SickRage\-win32\-alpha\-build(\d+)(?:\.\d+)?\.zip" + + svnFile = urllib.urlopen("http://code.google.com/p/sickrage/downloads/list") + for curLine in svnFile.readlines(): match = re.search(regex, curLine) if match: @@ -28,39 +46,38 @@ def findLatestBuild(): return None + def recursive_find_data_files(root_dir, allowed_extensions=('*')): - to_return = {} for (dirpath, dirnames, filenames) in os.walk(root_dir): if not filenames: continue - + for cur_filename in filenames: - + matches_pattern = False for cur_pattern in allowed_extensions: - if fnmatch.fnmatch(cur_filename, '*.'+cur_pattern): + if fnmatch.fnmatch(cur_filename, '*.' + cur_pattern): matches_pattern = True if not matches_pattern: continue - + cur_filepath = os.path.join(dirpath, cur_filename) to_return.setdefault(dirpath, []).append(cur_filepath) - + return sorted(to_return.items()) def find_all_libraries(root_dirs): - libs = [] - + for cur_root_dir in root_dirs: for (dirpath, dirnames, filenames) in os.walk(cur_root_dir): if '__init__.py' not in filenames: continue - - libs.append(dirpath.replace(os.sep, '.')) - + + libs.append(dirpath.replace(os.sep, '.')) + return libs @@ -71,7 +88,7 @@ def allFiles(dir): if os.path.isdir(fullFile): files += allFiles(fullFile) else: - files.append(fullFile) + files.append(fullFile) return files @@ -94,19 +111,14 @@ if not 'nopull' in oldArgs: # pull new source from git print 'Updating source from git' p = subprocess.Popen('git pull origin master', shell=True, cwd=compile_dir) - o,e = p.communicate() + o, e = p.communicate() # figure out what build this is going to be latestBuild = findLatestBuild() if 'test' in oldArgs: - currentBuildNumber = str(latestBuild)+'a' + currentBuildNumber = str(latestBuild) + 'a' else: - currentBuildNumber = latestBuild+1 - -# write the version file before we compile -versionFile = open("sickbeard/version.py", "w") -versionFile.write("SICKBEARD_VERSION = \"build "+str(currentBuildNumber)+"\"") -versionFile.close() + currentBuildNumber = latestBuild + 1 # set up the compilation options data_files = recursive_find_data_files('data', ['gif', 'png', 'jpg', 'ico', 'js', 'css', 'tmpl']) @@ -114,25 +126,25 @@ data_files = recursive_find_data_files('data', ['gif', 'png', 'jpg', 'ico', 'js' options = dict( name=name, version=release, - author='Nic Wolfe', - author_email='nic@wolfeden.ca', + author='echel0n', + author_email='sickrage.tv@gmail.com', description=name + ' ' + release, scripts=['SickBeard.py'], packages=find_all_libraries(['sickbeard', 'lib']), ) # set up py2exe to generate the console app -program = [ {'script': 'SickBeard.py' } ] +program = [{'script': 'SickBeard.py'}] options['options'] = {'py2exe': - { - 'bundle_files': 3, - 'packages': ['Cheetah'], - 'excludes': ['Tkconstants', 'Tkinter', 'tcl'], - 'optimize': 2, - 'compressed': 0 - } - } -options['zipfile'] = 'lib/sickbeard.zip' + { + 'bundle_files': 3, + 'packages': ['Cheetah'], + 'excludes': ['Tkconstants', 'Tkinter', 'tcl'], + 'optimize': 2, + 'compressed': 0 + } +} +options['zipfile'] = 'lib/sickrage.zip' options['console'] = program options['data_files'] = data_files @@ -146,7 +158,7 @@ try: os.rename("dist/%s" % Win32WindowName, "dist/%s" % Win32ConsoleName) except: print "Cannot create dist/%s" % Win32ConsoleName - #sys.exit(1) + # sys.exit(1) # we don't need this stuff when we make the 2nd exe del options['console'] @@ -158,8 +170,8 @@ setup(**options) # compile sabToSickbeard.exe using the existing setup.py script auto_process_dir = os.path.join(compile_dir, 'autoProcessTV') -p = subprocess.Popen([ sys.executable, os.path.join(auto_process_dir, 'setup.py') ], cwd=auto_process_dir, shell=True) -o,e = p.communicate() +p = subprocess.Popen([sys.executable, os.path.join(auto_process_dir, 'setup.py')], cwd=auto_process_dir, shell=True) +o, e = p.communicate() # copy autoProcessTV files to the dist dir auto_process_files = ['autoProcessTV/sabToSickBeard.py', @@ -167,9 +179,9 @@ auto_process_files = ['autoProcessTV/sabToSickBeard.py', 'autoProcessTV/autoProcessTV.py', 'autoProcessTV/autoProcessTV.cfg.sample', 'autoProcessTV/sabToSickBeard.exe'] - + os.makedirs('dist/autoProcessTV') - + for curFile in auto_process_files: newFile = os.path.join('dist', curFile) print "Copying file from", curFile, "to", newFile @@ -177,9 +189,9 @@ for curFile in auto_process_files: # compile updater.exe setup( - options = {'py2exe': {'bundle_files': 1}}, - zipfile = None, - console = ['updater.py'], requires=['Cheetah'] + options={'py2exe': {'bundle_files': 1}}, + zipfile=None, + console=['updater.py'], requires=['Cheetah'] ) if 'test' in oldArgs: @@ -188,7 +200,7 @@ else: # start building the CHANGELOG.txt print 'Creating changelog' gh = github.GitHub() - + # read the old changelog and find the last commit from that build lastCommit = "" try: @@ -197,25 +209,25 @@ else: cl.close() except: print "I guess there's no changelog" - + newestCommit = "" changeString = "" # cycle through all the git commits and save their commit messages - for curCommit in gh.commits.forBranch('midgetspy', 'Sick-Beard'): + for curCommit in gh.commits.forBranch('echel0n', 'SickRage'): if curCommit.id == lastCommit: break - + if newestCommit == "": newestCommit = curCommit.id - + changeString += curCommit.message + "\n\n" - + # if we didn't find any changes don't make a changelog file if newestCommit != "": newChangelog = open("CHANGELOG.txt", "w") - newChangelog.write(newestCommit+"\n\n") - newChangelog.write("Changelog for build "+str(currentBuildNumber)+"\n\n") + newChangelog.write(newestCommit + "\n\n") + newChangelog.write("Changelog for build " + str(currentBuildNumber) + "\n\n") newChangelog.write(changeString) newChangelog.close() else: @@ -227,7 +239,7 @@ if os.path.exists("CHANGELOG.txt"): # figure out what we're going to call the zip file print 'Zipping files...' -zipFilename = 'SickBeard-win32-alpha-build'+str(currentBuildNumber) +zipFilename = 'SickRage-win32-alpha-build' + str(currentBuildNumber) if os.path.isfile(zipFilename + '.zip'): zipNum = 2 while os.path.isfile(zipFilename + '.{0:0>2}.zip'.format(str(zipNum))): @@ -245,12 +257,6 @@ z.close() print "Created zip at", zipFilename -# leave version file as it is in source -print "Reverting version file to master" -versionFile = open("sickbeard/version.py", "w") -versionFile.write("SICKBEARD_VERSION = \"master\"") -versionFile.close() - # i store my google code username/pw in a config so i can have this file in public source control config = ConfigParser.ConfigParser() configFilename = os.path.join(compile_dir, "gc.ini") @@ -262,12 +268,15 @@ gc_password = config.get("GC", "password") # upload to google code unless I tell it not to if "noup" not in oldArgs and "test" not in oldArgs: print "Uploading zip to google code" - googlecode_upload.upload(os.path.abspath(zipFilename+".zip"), "sickbeard", gc_username, gc_password, "Win32 alpha build "+str(currentBuildNumber)+" (unstable/development release)", ["Featured","Type-Executable","OpSys-Windows"]) - + googlecode_upload.upload(os.path.abspath(zipFilename + ".zip"), "sickrage", gc_username, gc_password, + "Win32 alpha build " + str(currentBuildNumber) + " (unstable/development release)", + ["Featured", "Type-Executable", "OpSys-Windows"]) + if 'nopush' not in oldArgs and 'test' not in oldArgs: # tag commit as a new build and push changes to github print 'Tagging commit and pushing' - p = subprocess.Popen('git tag -a "build-'+str(currentBuildNumber)+'" -m "Windows build '+zipFilename+'"', shell=True, cwd=compile_dir) - o,e = p.communicate() + p = subprocess.Popen('git tag -a "build-' + str(currentBuildNumber) + '" -m "Windows build ' + zipFilename + '"', + shell=True, cwd=compile_dir) + o, e = p.communicate() p = subprocess.Popen('git push --tags origin windows_binaries', shell=True, cwd=compile_dir) - o,e = p.communicate() + o, e = p.communicate() diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index fcaffc4d..89ac1013 100755 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -102,6 +102,7 @@ VERSION_NOTIFY = False AUTO_UPDATE = False NOTIFY_ON_UPDATE = False CUR_COMMIT_HASH = None +BRANCH = None INIT_LOCK = Lock() started = False @@ -442,7 +443,7 @@ __INITIALIZED__ = False def initialize(consoleLogging=True): with INIT_LOCK: - global ACTUAL_LOG_DIR, LOG_DIR, WEB_PORT, WEB_LOG, ENCRYPTION_VERSION, WEB_ROOT, WEB_USERNAME, WEB_PASSWORD, WEB_HOST, WEB_IPV6, USE_API, API_KEY, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, \ + global BRANCH, ACTUAL_LOG_DIR, LOG_DIR, WEB_PORT, WEB_LOG, ENCRYPTION_VERSION, WEB_ROOT, WEB_USERNAME, WEB_PASSWORD, WEB_HOST, WEB_IPV6, USE_API, API_KEY, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, \ HANDLE_REVERSE_PROXY, USE_NZBS, USE_TORRENTS, NZB_METHOD, NZB_DIR, DOWNLOAD_PROPERS, CHECK_PROPERS_INTERVAL, ALLOW_HIGH_PRIORITY, TORRENT_METHOD, \ SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_HOST, \ NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, NZBGET_USE_HTTPS, backlogSearchScheduler, \ @@ -509,6 +510,9 @@ def initialize(consoleLogging=True): CheckSection(CFG, 'Pushbullet') CheckSection(CFG, 'Subtitles') + # branch + BRANCH = check_setting_str(CFG, 'General', 'branch', '') + ACTUAL_CACHE_DIR = check_setting_str(CFG, 'General', 'cache_dir', 'cache') # fix bad configs due to buggy code if ACTUAL_CACHE_DIR == 'None': @@ -1291,6 +1295,7 @@ def save_config(): # For passwords you must include the word `password` in the item_name and add `helpers.encrypt(ITEM_NAME, ENCRYPTION_VERSION)` in save_config() new_config['General'] = {} + new_config['General']['branch'] = BRANCH new_config['General']['config_version'] = CONFIG_VERSION new_config['General']['encryption_version'] = int(ENCRYPTION_VERSION) new_config['General']['log_dir'] = ACTUAL_LOG_DIR if ACTUAL_LOG_DIR else 'Logs' diff --git a/sickbeard/gh_api.py b/sickbeard/gh_api.py index ac7e4f31..bc5bae51 100644 --- a/sickbeard/gh_api.py +++ b/sickbeard/gh_api.py @@ -15,6 +15,9 @@ # # You should have received a copy of the GNU General Public License # along with SickRage. If not, see . +import os +from subprocess import check_output, PIPE, Popen +from os.path import join, split try: import json @@ -30,7 +33,7 @@ class GitHub(object): needs it for - list of commits. """ - def __init__(self, github_repo_user, github_repo, branch='master'): + def __init__(self, github_repo_user, github_repo, branch): self.github_repo_user = github_repo_user self.github_repo = github_repo @@ -92,4 +95,37 @@ class GitHub(object): access_API = self._access_API( ['repos', self.github_repo_user, self.github_repo, 'branches'], params={'per_page': 100}) - return access_API \ No newline at end of file + return access_API + + def installed_branch(self): + installed_path = os.path.dirname(os.path.normpath(os.path.abspath(__file__))) + return self.hash_dir(installed_path) + + def _lstree(self, files, dirs): + """Make git ls-tree like output.""" + for f, sha1 in files: + yield "100644 blob {}\t{}\0".format(sha1, f) + + for d, sha1 in dirs: + yield "040000 tree {}\t{}\0".format(sha1, d) + + + def _mktree(self, files, dirs): + mkt = Popen(["git", "mktree", "-z"], stdin=PIPE, stdout=PIPE) + return mkt.communicate("".join(self._lstree(files, dirs)))[0].strip() + + def hash_file(self, path): + """Write file at path to Git index, return its SHA1 as a string.""" + return check_output(["git", "hash-object", "-w", "--", path]).strip() + + def hash_dir(self, path): + """Write directory at path to Git index, return its SHA1 as a string.""" + dir_hash = {} + + for root, dirs, files in os.walk(path, topdown=False): + f_hash = ((f, self.hash_file(join(root, f))) for f in files) + d_hash = ((d, dir_hash[join(root, d)]) for d in dirs) + # split+join normalizes paths on Windows (note the imports) + dir_hash[join(*split(root))] = self._mktree(f_hash, d_hash) + + return dir_hash[path] \ No newline at end of file diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index c9a84067..5446af69 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -17,12 +17,14 @@ # along with SickRage. If not, see . from __future__ import with_statement +import getpass import os import re import shutil import socket import stat +import tempfile import time import traceback import urllib @@ -1198,13 +1200,29 @@ def touchFile(fname, atime=None): return False +def _getTempDir(): + """Returns the [system temp dir]/tvdb_api-u501 (or + tvdb_api-myuser) + """ + if hasattr(os, 'getuid'): + uid = "u%d" % (os.getuid()) + else: + # For Windows + try: + uid = getpass.getuser() + except ImportError: + return os.path.join(tempfile.gettempdir(), "sickrage") + + return os.path.join(tempfile.gettempdir(), "sickrage-%s" % (uid)) + 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. """ # request session - session = CacheControl(sess=session, cache=caches.FileCache(os.path.join(sickbeard.CACHE_DIR, 'sessions'))) + cache_dir = sickbeard.CACHE_DIR or _getTempDir() + session = CacheControl(sess=session, cache=caches.FileCache(os.path.join(cache_dir, 'sessions'))) # request session headers req_headers = {'User-Agent': USER_AGENT, 'Accept-Encoding': 'gzip,deflate'} @@ -1258,7 +1276,8 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N def download_file(url, filename, session=None): # create session - session = CacheControl(sess=session, cache=caches.FileCache(os.path.join(sickbeard.CACHE_DIR, 'sessions'))) + cache_dir = sickbeard.CACHE_DIR or _getTempDir() + session = CacheControl(sess=session, cache=caches.FileCache(os.path.join(cache_dir, 'sessions'))) # request session headers session.headers.update({'User-Agent': USER_AGENT, 'Accept-Encoding': 'gzip,deflate'}) diff --git a/sickbeard/version.py b/sickbeard/version.py index 33fe90be..5147319a 100644 --- a/sickbeard/version.py +++ b/sickbeard/version.py @@ -1 +1 @@ -SICKBEARD_VERSION = "master" +SICKBEARD_VERSION = "nightly" diff --git a/sickbeard/versionChecker.py b/sickbeard/versionChecker.py index a276961b..a8fd35df 100644 --- a/sickbeard/versionChecker.py +++ b/sickbeard/versionChecker.py @@ -30,14 +30,14 @@ import gh_api as github import sickbeard from sickbeard import helpers, notifiers -from sickbeard import version, ui +from sickbeard import ui from sickbeard import logger from sickbeard.exceptions import ex from sickbeard import encodingKludge as ek class CheckVersion(): """ - Version check class meant to run as a thread object with the SB scheduler. + Version check class meant to run as a thread object with the sr scheduler. """ def __init__(self): @@ -64,7 +64,7 @@ class CheckVersion(): def find_install_type(self): """ - Determines how this copy of SB was installed. + Determines how this copy of sr was installed. returns: type of installation. Possible values are: 'win': any compiled windows build @@ -73,7 +73,7 @@ class CheckVersion(): """ # check if we're a windows build - if sickbeard.version.SICKBEARD_VERSION.startswith('build '): + if sickbeard.BRANCH.startswith('build '): install_type = 'win' elif os.path.isdir(ek.ek(os.path.join, sickbeard.PROG_DIR, u'.git')): install_type = 'git' @@ -109,15 +109,16 @@ class CheckVersion(): self.updater.set_newest_text() return True - def update(self, branch=None): - if branch and branch != self.updater.branch: - return self.updater.update(branch) - elif self.updater.need_update(): + def update(self): + if self.updater.need_update() or self.updater.branch != sickbeard.BRANCH: return self.updater.update() def list_remote_branches(self): return self.updater.list_remote_branches() + def get_branch(self): + return self.updater.branch + class UpdateManager(): def get_github_repo_user(self): return 'echel0n' @@ -145,7 +146,7 @@ class WindowsUpdateManager(UpdateManager): version = '' try: - version = sickbeard.version.SICKBEARD_VERSION + version = sickbeard.BRANCH return int(version[6:]) except ValueError: logger.log(u"Unknown SickRage Windows binary release: " + version, logger.ERROR) @@ -200,11 +201,7 @@ class WindowsUpdateManager(UpdateManager): sickbeard.NEWEST_VERSION_STRING = newest_text - def update(self, branch=None): - - # set branch version - if branch: - self.branch = branch + def update(self): zip_download_url = self._find_newest_version(True) logger.log(u"new_link: " + repr(zip_download_url), logger.DEBUG) @@ -215,18 +212,18 @@ class WindowsUpdateManager(UpdateManager): try: # prepare the update dir - sb_update_dir = ek.ek(os.path.join, sickbeard.PROG_DIR, u'sb-update') + sr_update_dir = ek.ek(os.path.join, sickbeard.PROG_DIR, u'sr-update') - if os.path.isdir(sb_update_dir): - logger.log(u"Clearing out update folder " + sb_update_dir + " before extracting") - shutil.rmtree(sb_update_dir) + if os.path.isdir(sr_update_dir): + logger.log(u"Clearing out update folder " + sr_update_dir + " before extracting") + shutil.rmtree(sr_update_dir) - logger.log(u"Creating update folder " + sb_update_dir + " before extracting") - os.makedirs(sb_update_dir) + logger.log(u"Creating update folder " + sr_update_dir + " before extracting") + os.makedirs(sr_update_dir) # retrieve file logger.log(u"Downloading update from " + zip_download_url) - zip_download_path = os.path.join(sb_update_dir, u'sb-update.zip') + zip_download_path = os.path.join(sr_update_dir, u'sr-update.zip') urllib.urlretrieve(zip_download_url, zip_download_path) if not ek.ek(os.path.isfile, zip_download_path): @@ -237,10 +234,10 @@ class WindowsUpdateManager(UpdateManager): logger.log(u"Retrieved version from " + zip_download_url + " is corrupt, can't update", logger.ERROR) return False - # extract to sb-update dir - logger.log(u"Unzipping from " + str(zip_download_path) + " to " + sb_update_dir) + # extract to sr-update dir + logger.log(u"Unzipping from " + str(zip_download_path) + " to " + sr_update_dir) update_zip = zipfile.ZipFile(zip_download_path, 'r') - update_zip.extractall(sb_update_dir) + update_zip.extractall(sr_update_dir) update_zip.close() # delete the zip @@ -248,15 +245,15 @@ class WindowsUpdateManager(UpdateManager): os.remove(zip_download_path) # find update dir name - update_dir_contents = [x for x in os.listdir(sb_update_dir) if - os.path.isdir(os.path.join(sb_update_dir, x))] + update_dir_contents = [x for x in os.listdir(sr_update_dir) if + os.path.isdir(os.path.join(sr_update_dir, x))] if len(update_dir_contents) != 1: - logger.log(u"Invalid update data, update failed. Maybe try deleting your sb-update folder?", + logger.log(u"Invalid update data, update failed. Maybe try deleting your sr-update folder?", logger.ERROR) return False - content_dir = os.path.join(sb_update_dir, update_dir_contents[0]) + content_dir = os.path.join(sr_update_dir, update_dir_contents[0]) old_update_path = os.path.join(content_dir, u'updater.exe') new_update_path = os.path.join(sickbeard.PROG_DIR, u'updater.exe') logger.log(u"Copying new update.exe file from " + old_update_path + " to " + new_update_path) @@ -279,7 +276,7 @@ class GitUpdateManager(UpdateManager): self._git_path = self._find_working_git() self.github_repo_user = self.get_github_repo_user() self.github_repo = self.get_github_repo() - self.branch = self._find_git_branch() + self.branch = sickbeard.BRANCH or self._find_installed_branch() self._cur_commit_hash = None self._newest_commit_hash = None @@ -311,7 +308,7 @@ class GitUpdateManager(UpdateManager): alternative_git = [] - # osx people who start SB from launchd have a broken path, so try a hail-mary attempt for them + # osx people who start sr from launchd have a broken path, so try a hail-mary attempt for them if platform.system().lower() == 'darwin': alternative_git.append('/usr/local/git/bin/git') @@ -404,13 +401,12 @@ class GitUpdateManager(UpdateManager): else: return False - def _find_git_branch(self): + def _find_installed_branch(self): branch_info, err, exit_status = self._run_git(self._git_path, 'symbolic-ref -q HEAD') # @UnusedVariable if exit_status == 0 and branch_info: branch = branch_info.strip().replace('refs/heads/', '', 1) if branch: - sickbeard.version.SICKBEARD_VERSION = branch - return sickbeard.version.SICKBEARD_VERSION + return branch def _check_github_for_update(self): """ @@ -506,17 +502,13 @@ class GitUpdateManager(UpdateManager): return False - def update(self, branch=None): + def update(self): """ Calls git pull origin in order to update SickRage. Returns a bool depending on the call's success. """ - # set branch version - if branch: - self.branch = branch - - if self.branch == sickbeard.version.SICKBEARD_VERSION: + if sickbeard.BRANCH == self._find_installed_branch(): 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 @@ -539,30 +531,26 @@ class SourceUpdateManager(UpdateManager): def __init__(self): self.github_repo_user = self.get_github_repo_user() self.github_repo = self.get_github_repo() - self.branch = sickbeard.version.SICKBEARD_VERSION + self.branch = sickbeard.BRANCH or self._find_installed_branch() self._cur_commit_hash = None self._newest_commit_hash = None self._num_commits_behind = 0 def _find_installed_version(self): - - version_file = ek.ek(os.path.join, sickbeard.PROG_DIR, u'version.txt') - - if not os.path.isfile(version_file): - self._cur_commit_hash = None - return - - try: - with open(version_file, 'r') as fp: - self._cur_commit_hash = fp.read().strip(' \n\r') - except EnvironmentError, e: - logger.log(u"Unable to open 'version.txt': " + ex(e), logger.DEBUG) + gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch) + self._cur_commit_hash = gh.installed_branch() if not self._cur_commit_hash: self._cur_commit_hash = None sickbeard.CUR_COMMIT_HASH = str(self._cur_commit_hash) + def _find_installed_branch(self): + gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch) + for branch in gh.branches(): + if branch.commit['sha'] == self._cur_commit_hash: + sickbeard.BRANCH = branch.name + def need_update(self): self._find_installed_version() @@ -647,33 +635,28 @@ class SourceUpdateManager(UpdateManager): sickbeard.NEWEST_VERSION_STRING = newest_text - def update(self, branch=None): + def update(self): """ Downloads the latest source tarball from github and installs it over the existing version. """ - # set branch version - if branch: - 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') try: # prepare the update dir - sb_update_dir = ek.ek(os.path.join, sickbeard.PROG_DIR, u'sb-update') + sr_update_dir = ek.ek(os.path.join, sickbeard.PROG_DIR, u'sr-update') - if os.path.isdir(sb_update_dir): - logger.log(u"Clearing out update folder " + sb_update_dir + " before extracting") - shutil.rmtree(sb_update_dir) + if os.path.isdir(sr_update_dir): + logger.log(u"Clearing out update folder " + sr_update_dir + " before extracting") + shutil.rmtree(sr_update_dir) - logger.log(u"Creating update folder " + sb_update_dir + " before extracting") - os.makedirs(sb_update_dir) + logger.log(u"Creating update folder " + sr_update_dir + " before extracting") + os.makedirs(sr_update_dir) # retrieve file logger.log(u"Downloading update from " + repr(tar_download_url)) - tar_download_path = os.path.join(sb_update_dir, u'sb-update.tar') + tar_download_path = os.path.join(sr_update_dir, u'sr-update.tar') urllib.urlretrieve(tar_download_url, tar_download_path) if not ek.ek(os.path.isfile, tar_download_path): @@ -684,10 +667,10 @@ class SourceUpdateManager(UpdateManager): logger.log(u"Retrieved version from " + tar_download_url + " is corrupt, can't update", logger.ERROR) return False - # extract to sb-update dir + # extract to sr-update dir logger.log(u"Extracting file " + tar_download_path) tar = tarfile.open(tar_download_path) - tar.extractall(sb_update_dir) + tar.extractall(sr_update_dir) tar.close() # delete .tar.gz @@ -695,12 +678,12 @@ class SourceUpdateManager(UpdateManager): os.remove(tar_download_path) # find update dir name - update_dir_contents = [x for x in os.listdir(sb_update_dir) if - os.path.isdir(os.path.join(sb_update_dir, x))] + update_dir_contents = [x for x in os.listdir(sr_update_dir) if + os.path.isdir(os.path.join(sr_update_dir, x))] if len(update_dir_contents) != 1: logger.log(u"Invalid update data, update failed: " + str(update_dir_contents), logger.ERROR) return False - content_dir = os.path.join(sb_update_dir, update_dir_contents[0]) + content_dir = os.path.join(sr_update_dir, update_dir_contents[0]) # walk temp folder and move files to main folder logger.log(u"Moving files from " + content_dir + " to " + sickbeard.PROG_DIR) @@ -726,15 +709,6 @@ class SourceUpdateManager(UpdateManager): if os.path.isfile(new_path): os.remove(new_path) os.renames(old_path, new_path) - - # update version.txt with commit hash - try: - with open(version_path, 'w') as ver_file: - ver_file.write(self._newest_commit_hash) - except EnvironmentError, e: - logger.log(u"Unable to write version file, update not complete: " + ex(e), logger.ERROR) - return False - except Exception, e: logger.log(u"Error while trying to update: " + ex(e), logger.ERROR) logger.log(u"Traceback: " + traceback.format_exc(), logger.DEBUG) @@ -747,4 +721,5 @@ class SourceUpdateManager(UpdateManager): def list_remote_branches(self): gh = github.GitHub(self.github_repo_user, self.github_repo, self.branch) - return gh.branches() \ No newline at end of file + return [x.name for x in gh.branches()] + diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py index 476c5a31..16c07f2f 100644 --- a/sickbeard/webapi.py +++ b/sickbeard/webapi.py @@ -1284,7 +1284,7 @@ class CMD_SickBeard(ApiCall): def run(self): """ display misc sickbeard related information """ - data = {"sb_version": sickbeard.version.SICKBEARD_VERSION, "api_version": Api.version, + data = {"sb_version": sickbeard.BRANCH, "api_version": Api.version, "api_commands": sorted(_functionMaper.keys())} return _responds(RESULT_SUCCESS, data) diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index d3b94a90..5b1cbe8c 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -3449,12 +3449,12 @@ class Home(MainHandler): return _munge(t) - def update(self, pid=None, branch=None): + def update(self, pid=None): if str(pid) != str(sickbeard.PID): redirect("/home/") - updated = sickbeard.versionCheckScheduler.action.update(branch) # @UndefinedVariable + updated = sickbeard.versionCheckScheduler.action.update() # @UndefinedVariable if updated: # do a hard restart sickbeard.events.put(sickbeard.events.SystemEvent.RESTART) @@ -3466,7 +3466,9 @@ class Home(MainHandler): "Update wasn't successful, not restarting. Check your log for more information.") def branchCheckout(self, branch): - return self.update(sickbeard.PID, branch) + sickbeard.BRANCH = branch + ui.notifications.message('Checking out branch: ', branch) + return self.update(sickbeard.PID) def displayShow(self, show=None):