Created
March 30, 2018 11:15
-
-
Save paulwinex/ee9f5e1df3828a52d3948d9ff7dd221a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os, requests, shutil | |
try: | |
import sh | |
except: | |
pass | |
from fenx.tools.process_output import logger, steps | |
from fenx.tools.utils import sudo, download_file, OS, copytree, move_tree, is_admin | |
requests.packages.urllib3.disable_warnings() | |
from fenx.tools import qt_cmd, utils | |
# PY_VERSION = 20168704 | |
PY2_URL = 'https://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi' #todo: get last version | |
# PY3_URL = 'https://www.python.org/ftp/python/3.6.4/python-3.6.4-amd64.exe' #todo: get last version | |
# PY3_URL = 'https://www.python.org/ftp/python/3.6.4/python-3.6.4-embed-amd64.zip' #todo: get last version | |
PY3_URL = 'https://netix.dl.sourceforge.net/project/winpython/WinPython_3.6/3.6.3.0/WinPython-64bit-3.6.3.0Zero.exe' #todo: get last version | |
PY2_GET_PIP_URL = "https://raw.githubusercontent.com/pypa/get-pip/master/get-pip.py" | |
def install(install_dir, version=2, requirements=None, percentages=None, temp_dir=None, sudopwd=None): | |
# qcmd = qt_cmd.Cmd() | |
if percentages: | |
if requirements: | |
pr1 = percentages[0], percentages[0] + ((percentages[1] - percentages[0]) / 2) | |
pr2 = percentages[1] - ((percentages[1] - percentages[0]) / 2), percentages[1] | |
else: | |
pr1 = percentages | |
pr2 = None | |
else: | |
pr1 = None | |
pr2 = None | |
result = {} | |
py_dir = os.path.normpath(os.path.join(install_dir, 'python')) | |
print( 'Install Python {} to {}'.format(version, py_dir)) | |
if OS.is_windows(): | |
with steps(5, pr1, logger.progress, 1) as st: | |
# ============ WINDOWS | |
st.step() | |
py_exe = os.path.join(py_dir, 'python.exe') | |
if os.path.exists(py_exe): | |
logger.log('Python already installed.') | |
return py_exe | |
py_installer = download_file(PY2_URL if version == 2 else PY3_URL, temp_dir=temp_dir) | |
if not py_installer: | |
logger.error('File not downloaded') | |
return | |
st.step() | |
if not os.path.exists(py_installer): | |
logger.error('File not exists: {}'.format(py_installer)) | |
return | |
if version == 2: | |
# ============ PYTHON 2 | |
py_install_cmd = 'start /wait msiexec /a "{local_py}" /qb TARGETDIR="{install_dir}"'.format( | |
local_py=os.path.normpath(py_installer), | |
install_dir=py_dir | |
) | |
# logger.log('Install Python {} to {}...'.format(version, install_dir)) | |
# os.system(py_install_cmd) | |
# qcmd._call(py_install_cmd) | |
execute_command(py_install_cmd) | |
st.step() | |
if not os.path.exists(py_exe): | |
logger.error('Python installation failed. {} not found'.format(py_exe)) | |
return | |
result['py_exe'] = py_exe | |
logger.log('Python installed: {}'.format(py_exe)) | |
# os.system('{} -V'.format(py_exe)) | |
execute_command('{} -V'.format(py_exe)) | |
# qcmd._call('{} -V'.format(py_exe)) | |
st.step() | |
# INSTALL PIP | |
logger.log('Install PIP') | |
pip_exe = os.path.exists(os.path.join(py_dir, 'Scripts', 'pip.exe')) | |
if not os.path.exists(pip_exe): | |
get_pip_script = download_file(PY2_GET_PIP_URL, temp_dir=temp_dir) | |
if get_pip_script: | |
# os.system(' '.join([py_exe, get_pip_script])) | |
# qcmd._call(' '.join([py_exe, get_pip_script])) | |
execute_command(' '.join([py_exe, get_pip_script])) | |
else: | |
logger.error('get-pip.py not found') | |
return | |
pip_exe = os.path.join(py_dir, 'Scripts', 'pip.exe') | |
if not os.path.exists(pip_exe): | |
logger.error('pip not installed') | |
return | |
st.step() | |
result['pip_exe'] = pip_exe | |
else: | |
# ============ PYTHON 3 | |
# default python | |
# py_install_cmd = 'START /WAIT {local_py} /quiet InstallAllUsers=1 Include_tcltk=0 TargetDir={install_dir} AssociateFiles=0 Include_doc=0'.format( | |
# local_py=os.path.normpath(py_installer), | |
# install_dir=os.path.normpath(install_dir) | |
# ) | |
install_tmp_dir = os.path.join(temp_dir, 'tmp_py3') | |
if not os.path.exists(install_tmp_dir): | |
try: | |
os.makedirs(install_tmp_dir) | |
except: | |
logger.error('Can\'t create temp folder:'.format(install_tmp_dir)) | |
return | |
logger.log('Extracting...') | |
py_install_cmd = 'START /WAIT {local_py} /S /D={install_dir}'.format( | |
# py_install_cmd = 'START /WAIT {local_py} /S /D={install_dir}'.format( | |
local_py=os.path.normpath(py_installer), | |
install_dir=os.path.normpath(install_tmp_dir) | |
) | |
st.step() | |
# logger.log(py_install_cmd) | |
os.system(py_install_cmd) | |
# qcmd._exec(py_install_cmd) | |
tmp_py_dir = ([os.path.join(install_tmp_dir, x) for x in os.listdir(install_tmp_dir) if | |
os.path.exists(os.path.join(install_tmp_dir, x, 'python.exe'))] or [None])[0] | |
if not tmp_py_dir: | |
logger.error('Python installation failed. Python.exe not found: {}'.format(tmp_py_dir)) | |
return | |
st.step() | |
logger.log('Move files...') | |
try: | |
# os.rename(py_dir, install_dir) | |
copytree(tmp_py_dir, py_dir) | |
# print(move_tree(tmp_py_dir, py_dir)) | |
except Exception as e: | |
print(str(e)) | |
logger.error('Python installation failed. Can\'t rename installed dir. "{}" > "{}"'.format(tmp_py_dir, py_dir)) | |
return | |
try: | |
shutil.rmtree(install_tmp_dir) | |
except: | |
logger.log('Can\'t remove temp dir: {}'.format(install_tmp_dir)) | |
st.step() | |
pip_exe = os.path.join(py_dir, 'puthon.exe') + '-mpip' | |
result['pip_exe'] = pip_exe | |
# return result | |
elif OS.is_linux(): | |
if not is_admin(): | |
logger.error('Need sudo permissions for install. ' | |
'You can install python and libs manually and restart installer:' | |
' sudo apt-get install python-dev python-pip libpq-dev python-pyside') | |
raise Exception('Require SUDO privileges') | |
# ============== LINUX | |
with steps(4, pr1, logger.progress, 1) as st: | |
ve_exists = sh.which('virtualenv') | |
# py_exists = sh.which('python') if version == 2 else sh.which('python3.6') | |
py36 = '/usr/bin/python3.6' | |
py_exists = py36 if os.path.exists(py36) else '' | |
st.step() | |
if version == 2: | |
# ================= PYTHON 2 | |
# install python if not exists | |
if not os.path.exists('/usr/bin/python2'): | |
logger.error('System python 2 not installed') | |
return | |
# install lib and pip | |
sudo('apt-get -y install python-dev python-pip libpq-dev python-pyside', sudopwd) | |
st.step() | |
# virtual env | |
if not ve_exists: | |
sudo('pip install virtualenv', sudopwd) | |
# create env | |
logger.log('Create virtual env...') | |
sh.cd(install_dir) | |
sh.virtualenv(os.path.basename(py_dir), '--no-site-packages') | |
st.step() | |
py_exe = os.path.join(install_dir, 'bin', 'python') | |
result['py_exe'] = py_exe | |
pip_exe = os.path.join(install_dir, 'bin', 'pip') | |
result['pip_exe'] = pip_exe | |
# env_exe = os.path.join(install_dir, 'bin', 'activate') | |
# result['env_exe'] = env_exe | |
# sh.source(install_dir) | |
# PySide | |
site_packages = os.path.join(install_dir, 'lib', 'python2.7', 'site-packages') | |
default_pyside = '/usr/lib/python2.7/dist-packages/PySide' | |
if os.path.exists(default_pyside): | |
copytree(default_pyside, os.path.join(site_packages, 'PySide')) | |
else: | |
logger.error('PySide not installed') | |
return | |
st.step() | |
else: | |
# PYTHON 3 | |
lines =[] | |
if not os.path.exists(py_exists): | |
lines +=[ | |
'add-apt-repository -y ppa:jonathonf/python-3.6', | |
'apt-get update', | |
] | |
lines += ['apt-get install -y build-essential libssl-dev libffi-dev python3-dev'] | |
if not sh.which('pip3'): | |
lines += [ | |
'apt-get install -y python3.6 python3-pip', | |
'pip3 install --upgrade pip', | |
] | |
if not os.path.exists('/usr/lib/python3.6/venv'): | |
lines.append('apt-get install -y python3-venv') | |
lines.append('apt-get install -y python3.6-venv') | |
if not lines: | |
print('No commands to execute') | |
for line in lines: | |
print('>>', line) | |
sudo(line, sudopwd) | |
st.step() | |
# v = sh.python3('-V').strip().split(' ')[-1][:3] | |
# sudo('update-alternatives --install /usr/bin/python3 python3 /usr/bin/python{} 3'.format(v), sudopwd) | |
# ''''#update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 3''' | |
# create virtualenv | |
print('Create virtualenv') | |
if not os.path.exists(install_dir): | |
os.makedirs(install_dir) | |
sh.cd(install_dir) | |
print('go to {}'.format(install_dir)) | |
cmd ='{} -m venv {}'.format(py_exists, os.path.basename(py_dir)) | |
print(cmd) | |
sudo(cmd) | |
py_exe = os.path.join(py_dir, 'bin', 'python') | |
result['py_exe'] = py_exe | |
if not os.path.exists(py_exe): | |
logger.error('Python binary not found: {}'.format(py_exe)) | |
return | |
st.step() | |
pip_exe = os.path.join(py_dir, 'bin', 'pip3') | |
# os.system('{} install --upgrade pip'.format(pip_exe)) | |
# qcmd._call('{} install --upgrade pip'.format(pip_exe)) | |
execute_command('{} install --upgrade pip'.format(pip_exe)) | |
result['pip_exe'] = pip_exe | |
st.step() | |
# https://losst.ru/ustanovka-python-3-ubuntu | |
elif OS.is_mac(): | |
# https://wsvincent.com/install-python3-mac/ | |
logger.error('OS X not supported yet') | |
return | |
else: | |
logger.error('OS not supported yet') | |
return | |
# REQUIREMENTS | |
logger.log('Install requirements...') | |
if requirements: | |
# print('='*10, requirements) | |
install_requirements(py_dir, requirements, pr2) | |
return result | |
def install_requirements(python_root, requirements, percentages=None): | |
# qcmd = qt_cmd.Cmd() | |
if OS.is_windows(): | |
pip_exe = os.path.join(python_root, 'python.exe') + ' -mpip' | |
elif OS.is_linux(): | |
pip_exe = os.path.join(python_root, 'bin', 'pip') | |
elif OS.is_mac(): | |
pip_exe = os.path.join(python_root, 'bin', 'pip') | |
else: | |
raise Exception('Unknown OS!!!') | |
for pkg in steps(requirements, percentages, logger.progress, 1): | |
requirements_cmd = ' '.join([pip_exe, 'install', pkg]) | |
print(' '.join([pip_exe, 'install', pkg])) | |
# os.system(requirements_cmd) | |
# print(pkg) | |
# qcmd._call(pip_exe, 'install', pkg) | |
# utils.call(' '.join([pip_exe, 'install', pkg])) | |
execute_command(requirements_cmd) | |
def execute_command(cmd): | |
# os.system(cmd) | |
# qt_cmd.Cmd()._call(cmd) | |
utils.call(cmd) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment