This commit is contained in:
Alexis Delhaie
2020-08-09 19:00:43 +02:00
commit 801a85da08
12 changed files with 338 additions and 0 deletions

138
.gitignore vendored Normal file
View File

@@ -0,0 +1,138 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/../../../../../../:\Users\robof\PycharmProjects\pythonProject\.idea/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (pythonProject)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pythonProject.iml" filepath="$PROJECT_DIR$/.idea/pythonProject.iml" />
</modules>
</component>
</project>

10
.idea/pythonProject.iml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

9
README.md Normal file
View File

@@ -0,0 +1,9 @@
# Installer bootstrap
This bootstrap is for Chronos installer ([Github](https://github.com/alexlegarnd/chronos-installer)) but it can be used to bootstrap other software
This installer is developed in Python 3 and packaged to an EXE with PyInstaller
## Build
Just run this command:
./build.bat

BIN
app.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

16
build.bat Normal file
View File

@@ -0,0 +1,16 @@
@echo off
call clean.bat
pip install -r requirements.txt
IF EXIST "build" (
RMDIR /S /Q build
)
IF EXIST "dist" (
RMDIR /S /Q dist
)
IF EXIST "__pycache__" (
RMDIR /S /Q __pycache__
)
IF EXIST "main.spec" (
ERASE main.spec
)
pyinstaller --onefile --uac-admin --icon=app.ico main.py

13
clean.bat Normal file
View File

@@ -0,0 +1,13 @@
@echo off
IF EXIST "build" (
RMDIR /S /Q build
)
IF EXIST "dist" (
RMDIR /S /Q dist
)
IF EXIST "__pycache__" (
RMDIR /S /Q __pycache__
)
IF EXIST "main.spec" (
ERASE main.spec
)

123
main.py Normal file
View File

@@ -0,0 +1,123 @@
import requests
import os
import subprocess
from rich.progress import Progress
from rich import print
import ctypes
import sys
import shutil
REPO_URL = "https://alexisdelhaie.ovh/dlcenter/chronos-repo/installer/"
VERSION_FILE = "version"
COMPANY_NAME = "alexlegarnd"
SOFTWARE_NAME = "chronos-installer"
CACHE_FOLDER = "cache"
INSTALL_FOLDER = "{}\\{}\\{}".format(os.getenv('APPDATA'), COMPANY_NAME, SOFTWARE_NAME)
CACHE_FOLDER_PATH = "{}\\{}".format(INSTALL_FOLDER, CACHE_FOLDER)
INSTALLED_VERSION_PATH = "{}\\{}".format(INSTALL_FOLDER, VERSION_FILE)
EXECUTABLE = "Install.exe"
EXECUTABLE_PATH = "{}\\{}".format(INSTALL_FOLDER, EXECUTABLE)
FILES = ["libeay32.dll", "ssleay32.dll", "7z.dll", EXECUTABLE]
def get_installed_version():
print('[bold green]INFO[/] Checking installed version')
if os.path.exists(INSTALLED_VERSION_PATH):
file = open(INSTALLED_VERSION_PATH, "r")
version = file.read()
file.close()
print('[bold green]INFO[/] {} found'.format(version))
return version
print('[bold green]INFO[/] no version installed')
return "0.0.0"
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def get_version_from_repo():
print('[bold green]INFO[/] Getting version on repo')
url = "{}{}".format(REPO_URL, VERSION_FILE)
r = requests.get(url, allow_redirects=True)
return r.text
def download_file_from_repo(filename):
url = "{}{}".format(REPO_URL, filename)
with open("{}\\{}".format(INSTALL_FOLDER, filename), 'wb') as f:
response = requests.get(url, stream=True)
total_length = response.headers.get('content-length')
if total_length is None: # no content length header
f.write(response.content)
else:
with Progress() as progress:
task = progress.add_task("Fetching {}".format(filename), total=int(total_length))
for data in response.iter_content(chunk_size=4096):
f.write(data)
progress.update(task, advance=len(data))
def create_install_folder():
company_directory = "{}\\{}".format(os.getenv('APPDATA'), COMPANY_NAME)
if not os.path.exists(company_directory):
os.mkdir(company_directory)
print('[bold green]INFO[/] Creating {} folder'.format(company_directory))
if not os.path.exists(INSTALL_FOLDER):
os.mkdir(INSTALL_FOLDER)
print('[bold green]INFO[/] Creating {} folder'.format(INSTALL_FOLDER))
def clean_folder(path):
if os.path.exists(path):
for filename in os.listdir(path):
if filename != CACHE_FOLDER:
file_path = os.path.join(path, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print('[bold red]ERROR[/] Failed to delete {}. Reason: {}'.format(file_path, e))
def clean():
if '--clean' in sys.argv:
clean_folder(INSTALL_FOLDER)
clean_folder(CACHE_FOLDER_PATH)
if '--clean-cache' in sys.argv:
clean_folder(CACHE_FOLDER_PATH)
if '--clean-installer' in sys.argv:
clean_folder(INSTALL_FOLDER)
def main():
if not is_admin():
print('[bold red]ERROR[/] This app need to be launched eleveted')
sys.exit(0)
version = get_version_from_repo()
create_install_folder()
clean()
if get_installed_version() != version:
clean_folder(INSTALL_FOLDER)
for file in FILES:
download_file_from_repo(file)
if os.path.exists(INSTALLED_VERSION_PATH):
os.remove(INSTALLED_VERSION_PATH)
file = open(INSTALLED_VERSION_PATH, "w")
file.write(version)
file.close()
if os.path.exists(EXECUTABLE_PATH):
print('[bold green]INFO[/] Starting installer')
subprocess.Popen([EXECUTABLE_PATH], cwd=INSTALL_FOLDER)
else:
print('[bold red]ERROR[/] Executable not found')
input('-- Press enter key to quit --')
main()

3
requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
requests
rich
pyinstaller