@ -11,14 +11,9 @@ import json
from get_args import args
from get_args import args
from config import settings
from config import settings
bazarr_version = ' 7.2.0 '
LATEST_VERSION = None
# from main import bazarr_version
INSTALL_TYPE = None
UPDATE_AVAILABLE = None
COMMITS_BEHIND = None
LATEST_RELEASE = None
PREV_RELEASE = bazarr_version
class FakeLock ( object ) :
class FakeLock ( object ) :
@ -63,243 +58,249 @@ def check_releases():
json . dump ( releases , f )
json . dump ( releases , f )
def runGit ( args ) :
class Updater ( object ) :
git_locations = [ ' git ' ]
def __init__ ( self ) :
self . bazarr_version = ' 7.2.0 '
if platform . system ( ) . lower ( ) == ' darwin ' :
git_locations . append ( ' /usr/local/git/bin/git ' )
output = err = None
for cur_git in git_locations :
cmd = cur_git + ' ' + args
try :
self . LATEST_VERSION = ' '
logging . debug ( ' Trying to execute: " ' + cmd + ' " ' )
self . INSTALL_TYPE = ' '
p = subprocess . Popen ( cmd , stdout = subprocess . PIPE , stderr = subprocess . STDOUT , shell = True )
self . UPDATE_AVAILABLE = ' '
output , err = p . communicate ( )
self . COMMITS_BEHIND = ' '
output = output . strip ( )
self . LATEST_RELEASE = ' '
self . CURRENT_VERSION = ' '
logging . debug ( ' Git output: ' + output )
self . PREV_RELEASE = self . bazarr_version
except OSError :
self . CURRENT_VERSION , self . GIT_REMOTE , self . GIT_BRANCH = self . getVersion ( )
logging . debug ( ' Command failed: %s ' , cmd )
continue
if ' not found ' in output or " not recognized as an internal or external command " in output :
logging . debug ( ' Unable to find git with command ' + cmd )
output = None
elif ' fatal: ' in output or err :
logging . error ( ' Git returned bad info. Are you sure this is a git installation? ' )
output = None
elif output :
break
return ( output , err )
def runGit ( self , args ) :
git_locations = [ ' git ' ]
def getVersion ( ) :
if os . path . isdir ( os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' .git ' ) ) :
INSTALL_TYPE = ' git '
output , err = runGit ( ' rev-parse HEAD ' )
if not output :
logging . error ( ' Could not find latest installed version. ' )
cur_commit_hash = None
cur_commit_hash = str ( output )
if platform . system ( ) . lower ( ) == ' darwin ' :
git_locations . append ( ' /usr/local/git/bin/git ' )
if not re . match ( ' ^[a-z0-9]+$ ' , cur_commit_hash ) :
output = err = None
logging . error ( ' Output does not look like a hash, not using it. ' )
cur_commit_hash = None
if settings . general . branch :
for cur_git in git_locations :
branch_name = settings . general . branch
cmd = cur_git + ' ' + args
else :
remote_branch , err = runGit ( ' rev-parse --abbrev-ref --symbolic-full-name @ {u} ' )
remote_branch = remote_branch . rsplit ( ' / ' , 1 ) if remote_branch else [ ]
if len ( remote_branch ) == 2 :
remote_name , branch_name = remote_branch
else :
remote_name = branch_name = None
if not remote_name and settings . general . branch :
try :
logging . error ( ' Could not retrieve remote name from git. Defaulting to origin. ' )
logging . debug ( ' Trying to execute: " ' + cmd + ' " ' )
branch_name = settings . general . branch
p = subprocess . Popen ( cmd , stdout = subprocess . PIPE , stderr = subprocess . STDOUT , shell = True )
output , err = p . communicate ( )
output = output . strip ( )
logging . debug ( ' Git output: ' + output )
except OSError :
logging . debug ( ' Command failed: %s ' , cmd )
continue
if not branch_name :
if ' not found ' in output or " not recognized as an internal or external command " in output :
logging . error ( ' Could not retrieve branch name from git. Defaulting to master. ' )
logging . debug ( ' Unable to find git with command ' + cmd )
branch_name = ' master '
output = None
elif ' fatal: ' in output or err :
logging . error ( ' Git returned bad info. Are you sure this is a git installation? ' )
output = None
elif output :
break
return cur_commit_hash , ' origin ' , branch_name
return ( output , err )
else :
def getVersion ( self ) :
INSTALL_TYPE = ' source '
if os . path . isdir ( os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' .git ' ) ) and not args . release_update :
self . INSTALL_TYPE = ' git '
output , err = self . runGit ( ' rev-parse HEAD ' )
if not output :
logging . error ( ' Could not find latest installed version. ' )
cur_commit_hash = None
cur_commit_hash = str ( output )
if not re . match ( ' ^[a-z0-9]+$ ' , cur_commit_hash ) :
logging . error ( ' Output does not look like a hash, not using it. ' )
cur_commit_hash = None
if settings . general . branch :
branch_name = settings . general . branch
else :
remote_branch , err = self . runGit ( ' rev-parse --abbrev-ref --symbolic-full-name @ {u} ' )
remote_branch = remote_branch . rsplit ( ' / ' , 1 ) if remote_branch else [ ]
if len ( remote_branch ) == 2 :
remote_name , branch_name = remote_branch
else :
remote_name = branch_name = None
if not remote_name and settings . general . branch :
logging . error ( ' Could not retrieve remote name from git. Defaulting to origin. ' )
branch_name = settings . general . branch
if not branch_name :
logging . error ( ' Could not retrieve branch name from git. Defaulting to master. ' )
branch_name = ' master '
return cur_commit_hash , ' origin ' , branch_name
if CURRENT_VERSION :
return CURRENT_VERSION , ' origin ' , settings . general . branch
else :
else :
return None , ' origin ' , settings . general . branch
self . INSTALL_TYPE = ' source '
if self . CURRENT_VERSION :
CURRENT_VERSION , GIT_REMOTE , GIT_BRANCH = getVersion ( )
return self . CURRENT_VERSION , ' origin ' , settings . general . branch
else :
return None , ' origin ' , settings . general . branch
def check_updates ( ) :
check_github ( )
if not CURRENT_VERSION :
UPDATE_AVAILABLE = None
elif COMMITS_BEHIND > 0 and settings . general . branch in ( ' master ' ) and \
( ' V ' + bazarr_version ) != LATEST_RELEASE :
UPDATE_AVAILABLE = ' release '
elif COMMITS_BEHIND > 0 and CURRENT_VERSION != LATEST_VERSION :
UPDATE_AVAILABLE = ' commit '
else :
UPDATE_AVAILABLE = False
def check_github ( ) :
COMMITS_BEHIND = 0
# Get the latest version available from github
logging . info ( ' Retrieving latest version information from GitHub ' )
url = ' https://api.github.com/repos/morpheus65535/bazarr/commits/ %s ' % settings . general . branch
version = request_json ( url , timeout = 20 , validator = lambda x : type ( x ) == dict )
if version is None :
logging . warn ( ' Could not get the latest version from GitHub. Are you running a local development version? ' )
return CURRENT_VERSION
LATEST_VERSION = version [ ' sha ' ]
logging . debug ( " Latest version is %s " , LATEST_VERSION )
# See how many commits behind we are
if not CURRENT_VERSION :
logging . info ( ' You are running an unknown version of Bazarr. Run the updater to identify your version ' )
return LATEST_VERSION
if LATEST_VERSION == CURRENT_VERSION :
logging . info ( ' Bazarr is up to date ' )
return LATEST_VERSION
logging . info ( ' Comparing currently installed version with latest GitHub version ' )
url = ' https://api.github.com/repos/morpheus65535/bazarr/compare/ %s ... %s ' % ( LATEST_VERSION ,
CURRENT_VERSION )
commits = request_json ( url , timeout = 20 , whitelist_status_code = 404 , validator = lambda x : type ( x ) == dict )
if commits is None :
logging . warn ( ' Could not get commits behind from GitHub. ' )
return LATEST_VERSION
try :
COMMITS_BEHIND = int ( commits [ ' behind_by ' ] )
logging . debug ( " In total, %d commits behind " , COMMITS_BEHIND )
except KeyError :
logging . info ( ' Cannot compare versions. Are you running a local development version? ' )
COMMITS_BEHIND = 0
if COMMITS_BEHIND > 0 :
def check_updates ( self ) :
logging . info ( ' New version is available. You are %s commits behind ' % COMMITS_BEHIND )
self . check_github ( )
if not self . CURRENT_VERSION :
url = ' https://api.github.com/repos/morpheus65535/bazarr/releases '
self . UPDATE_AVAILABLE = None
releases = request_json ( url , timeout = 20 , whitelist_status_code = 404 , validator = lambda x : type ( x ) == list )
elif self . COMMITS_BEHIND > 0 and settings . general . branch in ( ' master ' ) and \
( ' v ' + self . bazarr_version ) != self . LATEST_RELEASE :
if releases is None :
self . UPDATE_AVAILABLE = ' release '
logging . warn ( ' Could not get releases from GitHub. ' )
elif self . COMMITS_BEHIND > 0 and self . CURRENT_VERSION != self . LATEST_VERSION :
return LATEST_VERSION
self . UPDATE_AVAILABLE = ' commit '
if settings . general . branch == ' master ' :
release = next ( ( r for r in releases if not r [ ' prerelease ' ] ) , releases [ 0 ] )
else :
else :
release = releases [ 0 ]
self . UPDATE_AVAILABLE = False
LATEST_RELEASE = release [ ' tag_name ' ]
print self . UPDATE_AVAILABLE
elif COMMITS_BEHIND == 0 :
def check_github ( self ) :
logging . info ( ' Bazarr is up to date ' )
self . COMMITS_BEHIND = 0
return LATEST_VERSION
def update ( ) :
if INSTALL_TYPE == ' git ' :
output , err = runGit ( ' pull ' + ' origin ' + ' ' + settings . general . branch )
if not output :
logging . error ( ' Unable to download latest version ' )
return
for line in output . split ( ' \n ' ) :
# Get the latest version available from github
logging . info ( ' Retrieving latest version information from GitHub ' )
if ' Already up-to-date. ' in line :
url = ' https://api.github.com/repos/morpheus65535/bazarr/commits/ %s ' % settings . general . branch
logging . info ( ' No update available, not updating ' )
version = request_json ( url , timeout = 20 , validator = lambda x : type ( x ) == dict )
logging . info ( ' Output: ' + str ( output ) )
elif line . endswith ( ( ' Aborting ' , ' Aborting. ' ) ) :
logging . error ( ' Unable to update from git: ' + line )
logging . info ( ' Output: ' + str ( output ) )
else :
tar_download_url = ' https://github.com/morpheus65535/bazarr/tarball/ {} ' . format ( settings . general . branch )
update_dir = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' update ' )
logging . info ( ' Downloading update from: ' + tar_download_url )
if version is None :
data = request_content ( tar_download_url )
logging . warn ( ' Could not get the latest version from GitHub. Are you running a local development version? ' )
return self . CURRENT_VERSION
if not data :
self . LATEST_VERSION = version [ ' sha ' ]
logging . error ( " Unable to retrieve new version from ' %s ' , can ' t update " , tar_download_url )
logging . debug ( " Latest version is %s " , self . LATEST_VERSION )
return
download_name = settings . general . branch + ' -github '
# See how many commits behind we are
tar_download_path = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , download_name )
if not self . CURRENT_VERSION :
logging . info ( ' You are running an unknown version of Bazarr. Run the updater to identify your version ' )
return self . LATEST_VERSION
# Save tar to disk
if self . LATEST_VERSION == self . CURRENT_VERSION :
with open ( tar_download_path , ' wb ' ) as f :
logging . info ( ' Bazarr is up to date ' )
f . write ( data )
return self . LATEST_VERSION
# Extract the tar to update folder
logging . info ( ' Comparing currently installed version with latest GitHub version ' )
logging . info ( ' Extracting file: ' + tar_download_path )
url = ' https://api.github.com/repos/morpheus65535/bazarr/compare/ %s ... %s ' % ( self . LATEST_VERSION ,
tar = tarfile . open ( tar_download_path )
self . CURRENT_VERSION )
tar . extractall ( update_dir )
commits = request_json ( url , timeout = 20 , whitelist_status_code = 404 , validator = lambda x : type ( x ) == dict )
tar . close ( )
# Delete the tar.gz
if commits is None :
logging . info ( ' Deleting file: ' + tar_download_path )
logging . warn ( ' Could not get commits behind from GitHub. ' )
os . remove ( tar_download_path )
return self . LATEST_VERSION
# Find update dir name
try :
update_dir_contents = [ x for x in os . listdir ( update_dir ) if os . path . isdir ( os . path . join ( update_dir , x ) ) ]
self . COMMITS_BEHIND = int ( commits [ ' behind_by ' ] )
if len ( update_dir_contents ) != 1 :
logging . debug ( " In total, %d commits behind " , self . COMMITS_BEHIND )
logging . error ( " Invalid update data, update failed: " + str ( update_dir_contents ) )
except KeyError :
return
logging . info ( ' Cannot compare versions. Are you running a local development version? ' )
content_dir = os . path . join ( update_dir , update_dir_contents [ 0 ] )
self . COMMITS_BEHIND = 0
# walk temp folder and move files to main folder
if self . COMMITS_BEHIND > 0 :
for dirname , dirnames , filenames in os . walk ( content_dir ) :
logging . info ( ' New version is available. You are %s commits behind ' % self . COMMITS_BEHIND )
dirname = dirname [ len ( content_dir ) + 1 : ]
for curfile in filenames :
url = ' https://api.github.com/repos/morpheus65535/bazarr/releases '
old_path = os . path . join ( content_dir , dirname , curfile )
releases = request_json ( url , timeout = 20 , whitelist_status_code = 404 , validator = lambda x : type ( x ) == list )
new_path = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , dirname , curfile )
if releases is None :
if os . path . isfile ( new_path ) :
logging . warn ( ' Could not get releases from GitHub. ' )
os . remove ( new_path )
return self . LATEST_VERSION
os . renames ( old_path , new_path )
if settings . general . branch == ' master ' :
release = next ( ( r for r in releases if not r [ ' prerelease ' ] ) , releases [ 0 ] )
def checkout_git_branch ( ) :
else :
if INSTALL_TYPE == ' git ' :
release = releases [ 0 ]
output , err = runGit ( ' fetch origin ' )
self . LATEST_RELEASE = release [ ' tag_name ' ]
output , err = runGit ( ' checkout %s ' % settings . general . branch )
if not output :
elif self . COMMITS_BEHIND == 0 :
logging . error ( ' Unable to change git branch. ' )
logging . info ( ' Bazarr is up to date ' )
return
for line in output . split ( ' \n ' ) :
return self . LATEST_VERSION
if line . endswith ( ( ' Aborting ' , ' Aborting. ' ) ) :
logging . error ( ' Unable to checkout from git: ' + line )
def update ( self ) :
logging . info ( ' Output: ' + str ( output ) )
if self . INSTALL_TYPE == ' git ' and not args . release_update :
output , err = self . runGit ( ' pull ' + ' origin ' + ' ' + settings . general . branch )
if not output :
logging . error ( ' Unable to download latest version ' )
return
for line in output . split ( ' \n ' ) :
if ' Already up-to-date. ' in line :
logging . info ( ' No update available, not updating ' )
logging . info ( ' Output: ' + str ( output ) )
elif line . endswith ( ( ' Aborting ' , ' Aborting. ' ) ) :
logging . error ( ' Unable to update from git: ' + line )
logging . info ( ' Output: ' + str ( output ) )
output , err = runGit ( ' pull origin %s ' % settings . general . branch )
else :
tar_download_url = ' https://github.com/morpheus65535/bazarr/tarball/ {} ' . format ( settings . general . branch )
update_dir = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' update ' )
logging . info ( ' Downloading update from: ' + tar_download_url )
data = request_content ( tar_download_url )
if not data :
logging . error ( " Unable to retrieve new version from ' %s ' , can ' t update " , tar_download_url )
return
download_name = settings . general . branch + ' -github '
tar_download_path = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , download_name )
# Save tar to disk
with open ( tar_download_path , ' wb ' ) as f :
f . write ( data )
# Extract the tar to update folder
logging . info ( ' Extracting file: ' + tar_download_path )
tar = tarfile . open ( tar_download_path )
tar . extractall ( update_dir )
tar . close ( )
# Delete the tar.gz
logging . info ( ' Deleting file: ' + tar_download_path )
os . remove ( tar_download_path )
# Find update dir name
update_dir_contents = [ x for x in os . listdir ( update_dir ) if os . path . isdir ( os . path . join ( update_dir , x ) ) ]
if len ( update_dir_contents ) != 1 :
logging . error ( " Invalid update data, update failed: " + str ( update_dir_contents ) )
return
content_dir = os . path . join ( update_dir , update_dir_contents [ 0 ] )
# walk temp folder and move files to main folder
for dirname , dirnames , filenames in os . walk ( content_dir ) :
dirname = dirname [ len ( content_dir ) + 1 : ]
for curfile in filenames :
old_path = os . path . join ( content_dir , dirname , curfile )
new_path = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , dirname , curfile )
if os . path . isfile ( new_path ) :
os . remove ( new_path )
os . renames ( old_path , new_path )
def checkout_git_branch ( self ) :
if self . INSTALL_TYPE == ' git ' and not args . release_update :
output , err = self . runGit ( ' fetch origin ' )
output , err = self . runGit ( ' checkout %s ' % settings . general . branch )
if not output :
logging . error ( ' Unable to change git branch. ' )
return
for line in output . split ( ' \n ' ) :
if line . endswith ( ( ' Aborting ' , ' Aborting. ' ) ) :
logging . error ( ' Unable to checkout from git: ' + line )
logging . info ( ' Output: ' + str ( output ) )
output , err = self . runGit ( ' pull origin %s ' % settings . general . branch )
def request_content ( url , * * kwargs ) :
def request_content ( url , * * kwargs ) :