-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
updater.py
124 lines (99 loc) · 3.99 KB
/
updater.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import logging
import os
import shutil
import sys
import glob
import platform
from subprocess import Popen
from urllib.request import urlopen
from urllib.request import urlretrieve
import cgi
import pathlib
# Change working directory to updater.exe's directory.
# The if below determines whether the app is a script file or frozen exe.
if getattr(sys, 'frozen', False):
running_updater_dir = os.path.dirname(sys.executable)
elif __file__:
running_updater_dir = os.path.dirname(__file__)
os.chdir(running_updater_dir)
# Logging configuration: log to file and console.
LOG_FILE_NAME = 'updater.log'
logging.basicConfig(filename=LOG_FILE_NAME, encoding='utf-8', level=logging.DEBUG)
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
def download_archive(url: str):
remotefile = urlopen(url)
content_header = remotefile.info()['Content-Disposition']
value, params = cgi.parse_header(content_header)
filename = params["filename"]
logging.info('Downloading archive from {0}...'.format(url))
urlretrieve(url, filename)
return filename
def backup_config(backend_folder: str):
logging.info('Backing up configuration...')
config_backup_path = os.path.join(backend_folder, "configuration.txt")
config_path = os.path.join('./../', config_backup_path)
if os.path.exists(config_path):
if not os.path.exists(backend_folder):
os.makedirs(backend_folder)
shutil.copyfile(config_path, config_backup_path)
def restore_config(backend_folder: str):
logging.info('Restoring configuration...')
config_backup_path = os.path.join(backend_folder, "configuration.txt")
config_path = os.path.join('./../', config_backup_path)
if os.path.exists(config_backup_path):
shutil.copyfile(config_backup_path, config_path)
def clear_converter_folder():
logging.info('Clearing converter folder...')
paths = glob.glob('../*', recursive=False)
path: str
for path in paths:
if os.path.isdir(path):
# remove directory
if os.path.samefile(path, running_updater_dir):
# Don't remove running updater folder.
continue
shutil.rmtree(path, ignore_errors=True)
else:
# remove file
try:
absolute_path = pathlib.Path(os.path.abspath(path))
absolute_path.unlink()
except FileNotFoundError:
pass
except Exception as e:
logging.warning(f"Failed to remove file: {e}")
def extract_archive(archive_filename: str):
logging.info(f'Extracting archive {archive_filename}...')
target_directory = "../"
shutil.unpack_archive(archive_filename, target_directory)
def open_frontend():
os.chdir('../')
# https://stackoverflow.com/a/13256908/10249243
# set system/version dependent "start_new_session" analogs
kwargs = {}
if platform.system() == 'Windows':
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms684863%28v=vs.85%29.aspx
DETACHED_PROCESS = 0x00000008
kwargs.update(creationflags=DETACHED_PROCESS)
Popen(["ConverterFrontend.exe"], close_fds=True, **kwargs)
else:
kwargs.update(start_new_session=True)
Popen(["./ConverterFrontend"], close_fds=True, **kwargs)
# First argument: URL of converter release .zip to download
# Second argument: name of converter backend folder
if len(sys.argv) != 3:
logging.error('Incorrect number of arguments! Should be 2.')
sys.exit(1)
converterZipURL = sys.argv[1]
converterBackendFolder = sys.argv[2]
if not os.path.isdir(os.path.join('..', converterBackendFolder)):
logging.error('Converter backend folder {0} does not exist!'.format(converterBackendFolder))
sys.exit(2)
archive_filename = download_archive(converterZipURL)
backup_config(converterBackendFolder)
clear_converter_folder()
extract_archive(archive_filename)
restore_config(converterBackendFolder)
logging.info('Update completed successfully!')
open_frontend()
sys.exit(0)