You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.4 KiB
99 lines
3.4 KiB
# coding=utf-8
|
|
|
|
import os
|
|
import platform
|
|
import logging
|
|
import requests
|
|
import json
|
|
import hashlib
|
|
import stat
|
|
|
|
from whichcraft import which
|
|
from dogpile.cache import make_region
|
|
|
|
region = make_region().configure('dogpile.cache.memory')
|
|
|
|
|
|
class BinaryNotFound(Exception):
|
|
pass
|
|
|
|
|
|
@region.cache_on_arguments()
|
|
def md5(fname):
|
|
hash_md5 = hashlib.md5()
|
|
with open(fname, "rb") as f:
|
|
for chunk in iter(lambda: f.read(4096), b""):
|
|
hash_md5.update(chunk)
|
|
return hash_md5.hexdigest()
|
|
|
|
|
|
@region.cache_on_arguments()
|
|
def get_binaries_from_json():
|
|
try:
|
|
binaries_json_file = os.path.realpath(os.path.join(os.path.dirname(__file__), 'binaries.json'))
|
|
with open(binaries_json_file) as json_file:
|
|
binaries_json = json.load(json_file)
|
|
except OSError:
|
|
logging.exception('BAZARR cannot access binaries.json')
|
|
return []
|
|
else:
|
|
return binaries_json
|
|
|
|
|
|
def get_binary(name):
|
|
installed_exe = which(name)
|
|
|
|
if installed_exe and os.path.isfile(installed_exe):
|
|
logging.debug(f'BAZARR returning this binary: {installed_exe}')
|
|
return installed_exe
|
|
else:
|
|
logging.debug('BAZARR binary not found in path, searching for it...')
|
|
binaries_dir = os.path.realpath(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'bin'))
|
|
system = platform.system()
|
|
machine = platform.machine()
|
|
dir_name = name
|
|
|
|
# deals with exceptions
|
|
if platform.system() == "Windows": # Windows
|
|
machine = "i386"
|
|
name = "%s.exe" % name
|
|
elif platform.system() == "Darwin": # MacOSX
|
|
system = 'MacOSX'
|
|
if name in ['ffprobe', 'ffprobe.exe']:
|
|
dir_name = 'ffmpeg'
|
|
|
|
exe_dir = os.path.abspath(os.path.join(binaries_dir, system, machine, dir_name))
|
|
exe = os.path.abspath(os.path.join(exe_dir, name))
|
|
|
|
binaries_json = get_binaries_from_json()
|
|
binary = next((item for item in binaries_json if item['system'] == system and item['machine'] == machine and
|
|
item['directory'] == dir_name and item['name'] == name), None)
|
|
if not binary:
|
|
logging.debug('BAZARR binary not found in binaries.json')
|
|
raise BinaryNotFound
|
|
else:
|
|
logging.debug(f'BAZARR found this in binaries.json: {binary}')
|
|
|
|
if os.path.isfile(exe) and md5(exe) == binary['checksum']:
|
|
logging.debug(f'BAZARR returning this existing and up-to-date binary: {exe}')
|
|
return exe
|
|
else:
|
|
try:
|
|
logging.debug(f'BAZARR creating directory tree for {exe_dir}')
|
|
os.makedirs(exe_dir, exist_ok=True)
|
|
logging.debug(f'BAZARR downloading {name} from {binary["url"]}')
|
|
r = requests.get(binary['url'])
|
|
logging.debug(f'BAZARR saving {name} to {exe_dir}')
|
|
with open(exe, 'wb') as f:
|
|
f.write(r.content)
|
|
if system != 'Windows':
|
|
logging.debug(f'BAZARR adding execute permission on {exe}')
|
|
st = os.stat(exe)
|
|
os.chmod(exe, st.st_mode | stat.S_IEXEC)
|
|
except Exception:
|
|
logging.exception(f'BAZARR unable to download {name} to {exe_dir}')
|
|
raise BinaryNotFound
|
|
else:
|
|
logging.debug(f'BAZARR returning this new binary: {exe}')
|
|
return exe
|