@ -1,137 +1,57 @@
# coding=utf-8
# coding=utf-8
import os
import os
import platform
import re
import subprocess
import tarfile
import logging
import logging
import requests
import sqlite3
import sqlite3
import json
import json
import requests
import tarfile
from get_args import args
from get_args import args
from config import settings , bazarr_url
from config import settings , bazarr_url
from queueconfig import notifications
from queueconfig import notifications
if not args . no_update :
import git
def check_releases ( ) :
current_working_directory = os . path . dirname ( os . path . dirname ( __file__ ) )
releases = [ ]
url_releases = ' https://api.github.com/repos/morpheus65535/Bazarr/releases '
try :
r = requests . get ( url_releases , timeout = 15 )
r . raise_for_status ( )
except requests . exceptions . HTTPError as errh :
logging . exception ( " Error trying to get releases from Github. Http error. " )
except requests . exceptions . ConnectionError as errc :
logging . exception ( " Error trying to get releases from Github. Connection Error. " )
except requests . exceptions . Timeout as errt :
logging . exception ( " Error trying to get releases from Github. Timeout Error. " )
except requests . exceptions . RequestException as err :
logging . exception ( " Error trying to get releases from Github. " )
else :
for release in r . json ( ) :
releases . append ( [ release [ ' name ' ] , release [ ' body ' ] ] )
with open ( os . path . join ( args . config_dir , ' config ' , ' releases.txt ' ) , ' w ' ) as f :
json . dump ( releases , f )
def run_git ( args ) :
git_locations = [ ' git ' ]
if platform . system ( ) . lower ( ) == ' darwin ' :
git_locations . append ( ' /usr/local/git/bin/git ' )
output = err = None
def gitconfig ( ) :
g = git . Repo . init ( current_working_directory )
for cur_git in git_locations :
config_read = g . config_reader ( )
cmd = cur_git + ' ' + args
config_write = g . config_writer ( )
try :
try :
logging . debug ( ' BAZARR Trying to execute: " ' + cmd + ' " ' )
username = config_read . get_value ( " user " , " name " )
p = subprocess . Popen ( cmd , stdout = subprocess . PIPE , stderr = subprocess . STDOUT , shell = True )
except :
output , err = p . communicate ( )
logging . debug ( ' BAZARR Settings git username ' )
output = output . strip ( )
config_write . set_value ( " user " , " name " , " Bazarr " )
logging . debug ( ' BAZARR Git output: ' + output )
except OSError :
logging . debug ( ' BAZARR Command failed: %s ' , cmd )
continue
if ' not found ' in output or " not recognized as an internal or external command " in output :
logging . debug ( ' BAZARR Unable to find git with command ' + cmd )
output = None
elif ' fatal: ' in output or err :
logging . error ( ' BAZARR Git returned bad info. Are you sure this is a git installation? ' )
output = None
elif output :
break
return output , err
def check_updates ( ) :
commits_behind = 0
current_version , source = get_version ( )
check_releases ( )
if source == ' git ' :
# Get the latest version available from github
logging . debug ( ' BAZARR 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 :
notifications . write (
msg = ' BAZARR Could not get the latest version from GitHub. ' ,
queue = ' check_update ' , type = ' warning ' )
logging . warn (
' BAZARR Could not get the latest version from GitHub. ' )
return
latest_version = version [ ' sha ' ]
logging . debug ( " BAZARR Latest version is %s " , latest_version )
# See how many commits behind we are
if not current_version :
notifications . write ( msg = ' BAZARR You are running an unknown version of Bazarr. Run the updater to identify your version ' ,
queue = ' check_update ' , type = ' warning ' )
logging . warn (
' BAZARR You are running an unknown version of Bazarr. Run the updater to identify your version ' )
return
if latest_version == current_version :
notifications . write ( msg = ' BAZARR is up to date ' , queue = ' check_update ' )
logging . info ( ' BAZARR is up to date ' )
return
logging . debug ( ' 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 :
notifications . write ( msg = ' BAZARR Could not get commits behind from GitHub. ' ,
queue = ' check_update ' , type = ' warning ' )
logging . warn ( ' BAZARR Could not get commits behind from GitHub. ' )
return
try :
try :
commits_behind = int ( commits [ ' behind_by ' ] )
email = config_read . get_value ( " user " , " email " )
logging . debug ( " BAZARR In total, %d commits behind " , commits_behind )
except :
except KeyError :
logging . debug ( ' BAZARR Settings git email ' )
notifications . write ( msg = ' BAZARR Cannot compare versions. Are you running a local development version? ' , queue = ' check_update ' )
config_write . set_value ( " user " , " email " , " bazarr@fake.email " )
logging . info ( ' BAZARR Cannot compare versions. Are you running a local development version? ' )
return
if commits_behind > 0 :
logging . info ( ' BAZARR New version is available. You are %s commits behind ' % commits_behind )
def check_and_apply_update ( ) :
notifications . write ( msg = ' BAZARR New version is available. You are %s commits behind ' % commits_behind ,
check_releases ( )
queue = ' check_update ' )
if not args . release_update :
update ( source , restart = True if settings . general . getboolean ( ' update_restart ' ) else False )
gitconfig ( )
elif commits_behind is 0 :
branch = settings . general . branch
notifications . write ( msg = ' BAZARR is up to date ' , queue = ' check_update ' )
g = git . cmd . Git ( current_working_directory )
logging . info ( ' BAZARR is up to date ' )
g . fetch ( ' origin ' )
result = g . diff ( ' --shortstat ' , ' origin/ ' + branch )
if len ( result ) == 0 :
notifications . write ( msg = ' BAZARR No new version of Bazarr available. ' , queue = ' check_update ' )
logging . info ( ' BAZARR No new version of Bazarr available. ' )
else :
g . reset ( ' --hard ' , ' HEAD ' )
g . checkout ( branch )
g . reset ( ' --hard ' , ' origin/ ' + branch )
g . pull ( )
logging . info ( ' BAZARR Updated to latest version. Restart required. ' + result )
updated ( )
else :
else :
url = ' https://api.github.com/repos/morpheus65535/bazarr/releases '
url = ' https://api.github.com/repos/morpheus65535/bazarr/releases '
releases = request_json ( url , timeout = 20 , whitelist_status_code = 404 , validator = lambda x : type ( x ) == list )
releases = request_json ( url , timeout = 20 , whitelist_status_code = 404 , validator = lambda x : type ( x ) == list )
@ -145,8 +65,8 @@ def check_updates():
release = releases [ 0 ]
release = releases [ 0 ]
latest_release = release [ ' tag_name ' ]
latest_release = release [ ' tag_name ' ]
if ( ' v ' + current_version ) != latest_release and settings . general . branch == ' master ' :
if ( ' v ' + os. environ [ " BAZARR_VERSION " ] ) != latest_release and settings . general . branch == ' master ' :
update ( source , restart = True if settings . general . getboolean ( ' update_restart ' ) else False )
update _from_source( )
elif settings . general . branch != ' master ' :
elif settings . general . branch != ' master ' :
notifications . write ( msg = " BAZARR Can ' t update development branch from source " , queue = ' check_update ' ) # fixme
notifications . write ( msg = " BAZARR Can ' t update development branch from source " , queue = ' check_update ' ) # fixme
logging . info ( " BAZARR Can ' t update development branch from source " ) # fixme
logging . info ( " BAZARR Can ' t update development branch from source " ) # fixme
@ -155,58 +75,18 @@ def check_updates():
logging . info ( ' BAZARR is up to date ' )
logging . info ( ' BAZARR is up to date ' )
def get_version ( ) :
def update_from_source ( ) :
if os . path . isdir ( os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' .git ' ) ) and not args . release_update :
output , err = run_git ( ' rev-parse HEAD ' )
if not output :
logging . error ( ' BAZARR Could not find latest installed version. ' )
cur_commit_hash = None
else :
cur_commit_hash = str ( output )
if not re . match ( ' ^[a-z0-9]+$ ' , cur_commit_hash ) :
logging . error ( ' BAZARR Output does not look like a hash, not using it. ' )
cur_commit_hash = None
return cur_commit_hash , ' git '
else :
return os . environ [ " BAZARR_VERSION " ] , ' source '
def update ( source , restart = True ) :
if source == ' git ' :
output , err = run_git ( ' pull ' + ' origin ' + ' ' + settings . general . branch )
if not output :
notifications . write ( msg = ' Unable to download latest version ' ,
queue = ' check_update ' , type = ' error ' )
logging . error ( ' BAZARR Unable to download latest version ' )
return
for line in output . split ( ' \n ' ) :
if ' Already up-to-date. ' in line :
logging . info ( ' BAZARR No update available, not updating ' )
logging . info ( ' BAZARR Output: ' + str ( output ) )
elif line . endswith ( ( ' Aborting ' , ' Aborting. ' ) ) :
logging . error ( ' BAZARR Unable to update from git: ' + line )
logging . info ( ' BAZARR Output: ' + str ( output ) )
updated ( restart )
else :
tar_download_url = ' https://github.com/morpheus65535/bazarr/tarball/ {} ' . format ( settings . general . branch )
tar_download_url = ' https://github.com/morpheus65535/bazarr/tarball/ {} ' . format ( settings . general . branch )
update_dir = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' update ' )
update_dir = os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' update ' )
logging . info ( ' BAZARR Downloading update from: ' + tar_download_url )
logging . info ( ' BAZARR Downloading update from: ' + tar_download_url )
notifications . write ( msg = ' BAZARR Downloading update from: ' + tar_download_url )
notifications . write ( msg = ' BAZARR Downloading update from: ' + tar_download_url , queue = ' check_update ' )
data = request_content ( tar_download_url )
data = request_content ( tar_download_url )
if not data :
if not data :
logging . error ( " BAZARR Unable to retrieve new version from ' %s ' , can ' t update " , tar_download_url )
logging . error ( " BAZARR Unable to retrieve new version from ' %s ' , can ' t update " , tar_download_url )
notifications . write ( msg = ( " BAZARR Unable to retrieve new version from ' %s ' , can ' t update " , tar_download_url ) ,
notifications . write ( msg = ( " BAZARR Unable to retrieve new version from ' %s ' , can ' t update " , tar_download_url ) ,
type = ' error ' )
type = ' error ' , queue = ' check_update ' )
return
return
download_name = settings . general . branch + ' -github '
download_name = settings . general . branch + ' -github '
@ -218,14 +98,14 @@ def update(source, restart=True):
# Extract the tar to update folder
# Extract the tar to update folder
logging . info ( ' BAZARR Extracting file: ' + tar_download_path )
logging . info ( ' BAZARR Extracting file: ' + tar_download_path )
notifications . write ( msg = ' BAZARR Extracting file: ' + tar_download_path )
notifications . write ( msg = ' BAZARR Extracting file: ' + tar_download_path , queue = ' check_update ' )
tar = tarfile . open ( tar_download_path )
tar = tarfile . open ( tar_download_path )
tar . extractall ( update_dir )
tar . extractall ( update_dir )
tar . close ( )
tar . close ( )
# Delete the tar.gz
# Delete the tar.gz
logging . info ( ' BAZARR Deleting file: ' + tar_download_path )
logging . info ( ' BAZARR Deleting file: ' + tar_download_path )
notifications . write ( msg = ' BAZARR Deleting file: ' + tar_download_path )
notifications . write ( msg = ' BAZARR Deleting file: ' + tar_download_path , queue = ' check_update ' )
os . remove ( tar_download_path )
os . remove ( tar_download_path )
# Find update dir name
# Find update dir name
@ -233,7 +113,7 @@ def update(source, restart=True):
if len ( update_dir_contents ) != 1 :
if len ( update_dir_contents ) != 1 :
logging . error ( " BAZARR Invalid update data, update failed: " + str ( update_dir_contents ) )
logging . error ( " BAZARR Invalid update data, update failed: " + str ( update_dir_contents ) )
notifications . write ( msg = " BAZARR Invalid update data, update failed: " + str ( update_dir_contents ) ,
notifications . write ( msg = " BAZARR Invalid update data, update failed: " + str ( update_dir_contents ) ,
type = ' error ' )
type = ' error ' , queue = ' check_update ' )
return
return
content_dir = os . path . join ( update_dir , update_dir_contents [ 0 ] )
content_dir = os . path . join ( update_dir , update_dir_contents [ 0 ] )
@ -248,23 +128,28 @@ def update(source, restart=True):
if os . path . isfile ( new_path ) :
if os . path . isfile ( new_path ) :
os . remove ( new_path )
os . remove ( new_path )
os . renames ( old_path , new_path )
os . renames ( old_path , new_path )
updated ( restart )
updated ( )
def checkout_git_branch ( ) :
output , err = run_git ( ' fetch origin ' )
output , err = run_git ( ' checkout %s ' % settings . general . branch )
if not output :
def check_releases ( ) :
logging . error ( ' Unable to change git branch. ' )
releases = [ ]
return
url_releases = ' https://api.github.com/repos/morpheus65535/Bazarr/releases '
try :
for line in output . split ( ' \n ' ) :
r = requests . get ( url_releases , timeout = 15 )
if line . endswith ( ( ' Aborting ' , ' Aborting. ' ) ) :
r . raise_for_status ( )
logging . error ( ' Unable to checkout from git: ' + line )
except requests . exceptions . HTTPError as errh :
logging . info ( ' Output: ' + str ( output ) )
logging . exception ( " Error trying to get releases from Github. Http error. " )
except requests . exceptions . ConnectionError as errc :
output , err = run_git ( ' pull %s %s ' % ( ' origin ' , settings . general . branch ) )
logging . exception ( " Error trying to get releases from Github. Connection Error. " )
except requests . exceptions . Timeout as errt :
logging . exception ( " Error trying to get releases from Github. Timeout Error. " )
except requests . exceptions . RequestException as err :
logging . exception ( " Error trying to get releases from Github. " )
else :
for release in r . json ( ) :
releases . append ( [ release [ ' name ' ] , release [ ' body ' ] ] )
with open ( os . path . join ( args . config_dir , ' config ' , ' releases.txt ' ) , ' w ' ) as f :
json . dump ( releases , f )
class FakeLock ( object ) :
class FakeLock ( object ) :
@ -409,8 +294,8 @@ def request_json(url, **kwargs):
logging . error ( " BAZARR Response returned invalid JSON data " )
logging . error ( " BAZARR Response returned invalid JSON data " )
def updated ( restart = Fals e) :
def updated ( restart = Tru e) :
if restart:
if settings. general . getboolean ( ' update_restart ' ) and restart:
try :
try :
requests . get ( bazarr_url + ' restart ' )
requests . get ( bazarr_url + ' restart ' )
except requests . ConnectionError :
except requests . ConnectionError :