diff --git a/gui/deploy.py b/gui/deploy.py index 7d8e90e..afbf17a 100644 --- a/gui/deploy.py +++ b/gui/deploy.py @@ -32,13 +32,13 @@ def rmfulldir(dirpath): pass -def update(): +def update(utils_dir: str): logging.info(f"checking for updates via git pull.") - pull = ["utils/git/bin/git.exe", "pull"] + pull = [f"{utils_dir}/git/bin/git.exe", "pull"] subprocess.call(pull) -def download_and_extract(url_source, out_archive): +def download_and_extract(url_source, out_archive, utils_dir="./utils", subdir=""): logging.info(f"Downloading {url_source}, this may take a while.") download_via_requests(url_source, out_archive) @@ -46,7 +46,7 @@ def download_and_extract(url_source, out_archive): logging.info("Download complete.") logging.info(f"Extracting {out_archive}") - extract = ["utils/7z/7za.exe", "x", out_archive, "-o" "./utils/"] + extract = [f"{utils_dir}/7z/7za.exe", "x", out_archive, "-o" f"{utils_dir}{subdir}"] subprocess.call(extract) time.sleep(0.7) @@ -54,35 +54,24 @@ def download_and_extract(url_source, out_archive): os.remove(out_archive) -def download_ffmpeg(clean=False): +def download_ffmpeg(utils_dir: str, clean=False): if clean: - rmfulldir("./utils/ffmpeg-" + get_ffmpeg_version() + "-full_build") + rmfulldir(f"{utils_dir}/ffmpeg-" + get_ffmpeg_version() + "-full_build") url_ffmpeg_source = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z" - out_ffmpeg_archive = "./utils/ffmpeg-release-full.7z.exe" + out_ffmpeg_archive = f"{utils_dir}/ffmpeg-release-full.7z.exe" - download_and_extract(url_ffmpeg_source, out_ffmpeg_archive) + download_and_extract(url_ffmpeg_source, out_ffmpeg_archive, utils_dir) - -def download_git(clean=False): +def download_git(utils_dir: str, clean=False): if clean: - rmfulldir("./utils/PortableGit-2.33.0.2-64-bit") + rmfulldir(f"{utils_dir}/git") - url_git_source = "https://github.com/git-for-windows/git/releases/download/" + \ - "v2.33.0.windows.2/PortableGit-2.33.0.2-64-bit.7z.exe" - out_git_archive = "./utils/PortableGit-2.33.0.2-64-bit.7z" + url_git_source = ("https://github.com/git-for-windows/git/releases/download/" + "v2.46.2.windows.1/PortableGit-2.46.2-64-bit.7z.exe") + out_git_archive = f"{utils_dir}/PortableGit-2.46.2-64-bit.7z.exe" - download_via_requests(url_git_source, out_git_archive) - time.sleep(0.7) - logging.info("Download complete.") - - logging.info(f"Extracting {out_git_archive}") - extract = [out_git_archive, "-o" "./utils/git", "-y"] - subprocess.call(extract) - - time.sleep(0.7) - logging.info("Removing " + out_git_archive) - os.remove(out_git_archive) + download_and_extract(url_git_source, out_git_archive, utils_dir, subdir="/git") def get_ffmpeg_version(): @@ -95,15 +84,15 @@ def get_ffmpeg_version(): return ffmpeg_version -def fetch_and_cut_song(tape, ffmpeg_version): - python_executable = "./utils/python-3.9.7-embed-amd64/python.exe" +def fetch_and_cut_song(utils_dir: str, build_dir: str, tape, ffmpeg_version): + python_executable = f"{utils_dir}/python-3.9.7-embed-amd64/python.exe" script = "./fetch_song.py" if type(tape["source"]) == str: - shutil.copy(tape["source"], f"./build/music/{tape['identifier']}.ogg") + shutil.copy(tape["source"], f"{build_dir}/music/{tape['identifier']}.ogg") else: fetch = [python_executable, script, tape["source"]["url"], "-x", "--audio-format", "vorbis", - "--audio-quality", "0", "-o", f"./build/tmp_music/{tape['identifier']}.ogg"] + "--audio-quality", "0", "-o", f"{build_dir}/tmp_music/{tape['identifier']}.ogg"] # this is done in a separate python script because subprocess.call makes sure that the # download process is finished before trying to cut the song @@ -112,11 +101,11 @@ def fetch_and_cut_song(tape, ffmpeg_version): time.sleep(0.1) - cut = ["./utils/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe", + cut = [f"{utils_dir}/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe", "-y", "-ss", f"{tape['source']['start']}", - "-i", f"./build/tmp_music/{tape['identifier']}.ogg", "-acodec", "libvorbis", + "-i", f"{build_dir}/tmp_music/{tape['identifier']}.ogg", "-acodec", "libvorbis", "-ac", "1", "-af", f"volume={tape['source']['volume']}dB", - f"./build/music/{tape['identifier']}.ogg"] + f"{build_dir}/music/{tape['identifier']}.ogg"] if tape["source"]["end"] != -1: cut = cut[:-7] + ["-to", f"{tape['source']['end']}"] + cut[-7:] @@ -128,10 +117,10 @@ def fetch_and_cut_song(tape, ffmpeg_version): "or download the latest release version manually.") sys.exit() - walkman = ["./utils/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe", - "-i", f"./build/music/{tape['identifier']}.ogg", + walkman = [f"{utils_dir}/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe", + "-i", f"{build_dir}/music/{tape['identifier']}.ogg", "-af", f"highpass=f=300,lowpass=f=12000", - f"./build/music/{tape['identifier']}-walkman.ogg"] + f"{build_dir}/music/{tape['identifier']}-walkman.ogg"] try: subprocess.call(walkman) @@ -174,15 +163,13 @@ def assemble_png_images(tapes, outfile: str, resize=None): new_im.save(f"./build/{outfile}.png") -def prepare_music(data): +def prepare_music(data, music_dir: str, build_dir: str): try: - os.mkdir('./build/music/') + os.mkdir(f'{music_dir}') except FileExistsError: pass - logging.info("reading ffmpeg version") ffmpeg_version = get_ffmpeg_version() - logging.info(f"ffmpeg version is {ffmpeg_version}") logging.info("downloading and cutting the songs") for i, tape in enumerate(data): @@ -193,25 +180,25 @@ def prepare_music(data): logging.info(f"{i + 1}/{len(data)} Already exists: {tape['name']}") logging.info(f"removing temporary music folder") - rmfulldir('./build/tmp_music/') + rmfulldir(f"{build_dir}/tmp_music/") logging.info(f"copying the sound effects to build") - copy_tree("./source/sound_effects", "./build/sound_effects") + copy_tree("./source/sound_effects", f"{build_dir}/sound_effects") -def prepare_images(data, config): +def prepare_images(data, build_dir:str): logging.info(f"assembling covers and icons into png files") assemble_png_images(data, "covers") assemble_png_images(data, "icons", resize=(64, 41)) assemble_png_images(data, "sprites", resize=(33, 21)) logging.info(f"copying other images") - shutil.copy("./source/images/players_icons.png", "./build/players_icons.png") - shutil.copy("./source/images/players_sprites.png", "./build/players_sprites.png") - shutil.copy("./source/images/PreviewImage.png", "./build/PreviewImage.png") + shutil.copy("./source/images/players_icons.png", f"{build_dir}/players_icons.png") + shutil.copy("./source/images/players_sprites.png", f"{build_dir}/players_sprites.png") + shutil.copy("./source/images/PreviewImage.png", f"{build_dir}/PreviewImage.png") -def build_xml_code(data, config): +def build_xml_code(data, build_dir:str, config): logging.info(f"calculate the value that lets you use the songs n-times") song_lengths = [OggVorbis(f"./build/music/{tape['identifier']}.ogg").info.length for tape in data] @@ -237,11 +224,11 @@ def build_xml_code(data, config): template2 = j2env.get_template("./source/sunken_tapes_style_template.xml") logging.info(f"rendering the xml files") - with open("./build/filelist.xml", "w+", encoding="utf8") as output_file: + with open(f"{build_dir}/filelist.xml", "w+", encoding="utf8") as output_file: # render the template output_file.write(template0.render(config=config, tapes=data)) - with open(f"./build/{config['slug']}.xml", "w+", encoding="utf8") as output_file: + with open(f"{build_dir}/{config['slug']}.xml", "w+", encoding="utf8") as output_file: # render the template output_file.write(template1.render(tapes=data, config=config, condition_delta=condition_delta, @@ -249,17 +236,17 @@ def build_xml_code(data, config): song_lengths=song_lengths, positions=positions)) - with open(f"./build/{config['slug']}_style.xml", "w+", encoding="utf8") as output_file: + with open(f"{build_dir}/{config['slug']}_style.xml", "w+", encoding="utf8") as output_file: # render the template output_file.write(template2.render(tapes=data, config=config, positions=positions)) -def deploy(config): +def deploy(build_dir: str, install_dir: str, local_mod_name: str, config): try: - os.mkdir('./build') + os.mkdir(build_dir) except FileExistsError: logging.info(f"removing old XML files in ./build/:") - for f in Path('./build/').glob("*.xml"): + for f in Path(build_dir).glob("*.xml"): logging.info(f" {f}") os.remove(f) pass @@ -272,19 +259,19 @@ def deploy(config): data = yaml.load(fr, Loader=yaml.SafeLoader) prepare_music(data) - prepare_images(data, config) - build_xml_code(data, config) + prepare_images(data, build_dir) + build_xml_code(data, build_dir, config) - mod_directory = f"/LocalMods/{config['name']}/" + mod_directory = f"{install_dir}/LocalMods/{local_mod_name}/" - logging.info(f"removing the old installed mod directory {config['installdir'] + mod_directory}") - rmfulldir(config["installdir"] + mod_directory) + logging.info(f"removing the old installed mod directory {mod_directory}") + rmfulldir(mod_directory) logging.info(f"copying the new build") - if Path(config["installdir"]).is_dir(): - copy_tree("./build/", config["installdir"] + mod_directory) + if Path(f"{install_dir}").is_dir(): + copy_tree(build_dir, mod_directory) else: raise FileNotFoundError( - f"{config['installdir']} does not exist. Set up the correct Barotrauma installation directory") + f"{install_dir} does not exist. Set up the correct Barotrauma installation directory") logging.info(f"Done!") diff --git a/gui/installer.py b/gui/installer.py index 5aadeed..6a1e7eb 100644 --- a/gui/installer.py +++ b/gui/installer.py @@ -5,7 +5,7 @@ import logging import time from tape_editor_widgets import * -from deploy import download_ffmpeg, get_ffmpeg_version +from deploy import download_ffmpeg, get_ffmpeg_version, download_git from PIL import ImageGrab @@ -49,6 +49,7 @@ class OptionsWidget(QWidget): self.detect_pushbutton = QPushButton("Detect screen resolution") self.detect_pushbutton.clicked.connect(self.update_screen_res) + self.update_screen_res() self.resolution_hbox = QVBoxLayout() self.resolution_hbox.addWidget(self.width_spinbox) @@ -89,14 +90,17 @@ class OptionsWidget(QWidget): self.options_gbox = QGroupBox("Other options") self.options_gbox.setLayout(self.options_hbox) + # Update widget + self.update_widget = UpdateWidget() # Install widget - self.install = InstallWidget() + self.install_widget = InstallWidget() layout = QVBoxLayout() layout.addWidget(self.name_gbox) layout.addWidget(self.tape_covers_gbox) layout.addWidget(self.options_gbox) - layout.addWidget(self.install) + layout.addWidget(self.update_widget) + layout.addWidget(self.install_widget) layout.addStretch() self.setLayout(layout) @@ -109,6 +113,18 @@ class OptionsWidget(QWidget): self.width_spinbox.setValue(img.size[0]) self.height_spinbox.setValue(img.size[1]) + @property + def options(self): + return {"name": self.name_line_edit.text(), + "tape_covers": self.tape_covers_gbox.isChecked(), + "resoultion_x": self.width_spinbox.value(), + "resolution_y": self.height_spinbox.value(), + "buffs": self.cbox_buffs.isChecked(), + "debuffs": self.cbox_debuffs.isChecked(), + "walkmans": self.cbox_walkmans.isChecked(), + "durability": self.cbox_durability.isChecked(), + "repair": self.cbox_repair.isChecked()} + # TODO: implement random local mod name @@ -343,31 +359,32 @@ class ValidationWidget(QWidget): scrollbar.setValue(tape_number * step) -class InstallWidget(QWidget): +class UpdateWidget(QWidget): def __init__(self): super().__init__() - self.install_grid = QGridLayout() hr_html_string = "
" + download_link = ("https://github.com/git-for-windows/git/releases/download/" + "v2.46.2.windows.1/PortableGit-2.46.2-64-bit.7z.exe") - self.ffmpeg_checkbox = QCheckBox() - self.ffmpeg_checkbox.setDisabled(True) - self.ffmpeg_label = QLabel("Download and unpack ffmpeg") - self.ffmpeg_label_link = QLabel("" - "gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z") - self.ffmpeg_label_link.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction) - self.ffmpeg_label_link.setTextInteractionFlags(Qt.TextInteractionFlag.LinksAccessibleByMouse) - self.ffmpeg_label_link.setOpenExternalLinks(True) - self.ffmpeg_dir = DirWidget("./utils") - self.ffmpeg_pushbutton = QPushButton("Download") - self.ffmpeg_pushbutton.clicked.connect(self.download_ffmpeg_action) - self.ffmpeg_info_label = QLabel('ffmpeg downloaded. You can now deploy Sunken Tapes.') - self.install_grid.addWidget(self.ffmpeg_checkbox, 0, 0) - self.install_grid.addWidget(self.ffmpeg_label, 0, 1) - self.install_grid.addWidget(self.ffmpeg_label_link, 1, 1) - self.install_grid.addWidget(self.ffmpeg_dir, 2, 1) - self.install_grid.addWidget(self.ffmpeg_pushbutton, 0, 2) - self.install_grid.addWidget(QLabel(hr_html_string), 4, 0, 1, 3) + self.grid = QGridLayout() + + self.git_checkbox = QCheckBox() + self.git_checkbox.setDisabled(True) + self.git_label = QLabel("Download and unpack git") + self.git_label_link = QLabel(f"" + f"{download_link.replace('https://', '').replace('download/', 'download/
')}
") + self.git_label_link.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction) + self.git_label_link.setTextInteractionFlags(Qt.TextInteractionFlag.LinksAccessibleByMouse) + self.git_label_link.setOpenExternalLinks(True) + self.git_pushbutton = QPushButton("Download") + self.git_pushbutton.clicked.connect(self.download_git_action) + self.git_dir = DirWidget("./utils") + self.grid.addWidget(self.git_checkbox, 0, 0) + self.grid.addWidget(self.git_label, 0, 1) + self.grid.addWidget(self.git_pushbutton, 0, 2) + self.grid.addWidget(self.git_label_link, 1, 1) + self.grid.addWidget(self.git_dir, 2, 1) self.git_update_checkbox = QCheckBox() self.git_update_checkbox.setDisabled(True) @@ -378,65 +395,113 @@ class InstallWidget(QWidget): self.git_update_label_link.setTextInteractionFlags(Qt.TextInteractionFlag.LinksAccessibleByMouse) self.git_update_label_link.setOpenExternalLinks(True) self.git_update_pushbutton = QPushButton("Update") - self.install_grid.addWidget(self.git_update_checkbox, 10, 0) - self.install_grid.addWidget(self.git_update_label, 10, 1) - self.install_grid.addWidget(self.git_update_label_link, 11, 1) - self.install_grid.addWidget(self.git_update_pushbutton, 10, 2) - self.install_grid.addWidget(QLabel(hr_html_string), 12, 0, 1, 3) + self.grid.addWidget(self.git_update_checkbox, 10, 0) + self.grid.addWidget(self.git_update_label, 10, 1) + self.grid.addWidget(self.git_update_label_link, 11, 1) + self.grid.addWidget(self.git_update_pushbutton, 10, 2) + self.grid.addWidget(QLabel(hr_html_string), 12, 0, 1, 3) + + self.gbox = QGroupBox("Update") + self.gbox.setLayout(self.grid) + + layout = QHBoxLayout() + layout.addWidget(self.gbox) + layout.setContentsMargins(0, 0, 0, 0) + self.setLayout(layout) + + self.does_git_exist() + + def download_git_action(self): + download_git(self.git_dir.directory) + + def does_git_exist(self): + executable_path = Path("git/bin/git.exe") + if (self.git_dir.directory / executable_path).exists(): + exists = True + else: + exists = False + + self.git_pushbutton.setEnabled(not exists) + self.git_checkbox.setChecked(exists) + return exists + + +class InstallWidget(QWidget): + def __init__(self): + super().__init__() + self.grid = QGridLayout() + + hr_html_string = "
" + download_link = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z" + + self.ffmpeg_checkbox = QCheckBox() + self.ffmpeg_checkbox.setDisabled(True) + self.ffmpeg_label = QLabel("Download and unpack ffmpeg") + self.ffmpeg_label_link = QLabel(f"" + f"{download_link.replace('https://', '')}") + self.ffmpeg_label_link.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction) + self.ffmpeg_label_link.setTextInteractionFlags(Qt.TextInteractionFlag.LinksAccessibleByMouse) + self.ffmpeg_label_link.setOpenExternalLinks(True) + self.ffmpeg_pushbutton = QPushButton("Download") + self.ffmpeg_pushbutton.clicked.connect(self.download_ffmpeg_action) + self.ffmpeg_dir = DirWidget("./utils") + self.grid.addWidget(self.ffmpeg_checkbox, 0, 0) + self.grid.addWidget(self.ffmpeg_label, 0, 1) + self.grid.addWidget(self.ffmpeg_pushbutton, 0, 2) + self.grid.addWidget(self.ffmpeg_label_link, 1, 1) + self.grid.addWidget(self.ffmpeg_dir, 2, 1) + self.grid.addWidget(QLabel(hr_html_string), 9, 0, 1, 3) self.songs_download_checkbox = QCheckBox() self.songs_download_checkbox.setDisabled(True) self.songs_download_label = QLabel("Download songs and process them") self.songs_download_dir = DirWidget("./build/music") self.songs_download_pushbutton = QPushButton("Download") - self.install_grid.addWidget(self.songs_download_checkbox, 20, 0) - self.install_grid.addWidget(self.songs_download_label, 20, 1) - self.install_grid.addWidget(self.songs_download_pushbutton, 20, 2) - self.install_grid.addWidget(self.songs_download_dir, 21, 1) - self.install_grid.addWidget(QLabel(hr_html_string), 22, 0, 1, 3) + self.grid.addWidget(self.songs_download_checkbox, 20, 0) + self.grid.addWidget(self.songs_download_label, 20, 1) + self.grid.addWidget(self.songs_download_pushbutton, 20, 2) + self.grid.addWidget(self.songs_download_dir, 21, 1) + self.grid.addWidget(QLabel(hr_html_string), 22, 0, 1, 3) self.compile_checkbox = QCheckBox() self.compile_checkbox.setDisabled(True) self.compile_label = QLabel("Compile mod according to the settings") self.compile_dir = DirWidget("./build") self.compile_pushbutton = QPushButton("Compile") - self.install_grid.addWidget(self.compile_checkbox, 30, 0) - self.install_grid.addWidget(self.compile_label, 30, 1) - self.install_grid.addWidget(self.compile_pushbutton, 30, 2) - self.install_grid.addWidget(self.compile_dir, 31, 1) - self.install_grid.addWidget(QLabel(hr_html_string), 32, 0, 1, 3) + self.grid.addWidget(self.compile_checkbox, 30, 0) + self.grid.addWidget(self.compile_label, 30, 1) + self.grid.addWidget(self.compile_pushbutton, 30, 2) + self.grid.addWidget(self.compile_dir, 31, 1) + self.grid.addWidget(QLabel(hr_html_string), 32, 0, 1, 3) self.install_checkbox = QCheckBox() self.install_checkbox.setDisabled(True) self.install_label = QLabel("Copy the files to the install directory") self.install_dir = DirWidget() self.install_pushbutton = QPushButton("Install") - self.install_grid.addWidget(self.install_checkbox, 40, 0) - self.install_grid.addWidget(self.install_label, 40, 1) - self.install_grid.addWidget(self.install_pushbutton, 40, 2) - self.install_grid.addWidget(self.install_dir, 41, 1) - self.install_grid.addWidget(QLabel(hr_html_string), 42, 0, 1, 3) + self.grid.addWidget(self.install_checkbox, 40, 0) + self.grid.addWidget(self.install_label, 40, 1) + self.grid.addWidget(self.install_pushbutton, 40, 2) + self.grid.addWidget(self.install_dir, 41, 1) + self.grid.addWidget(QLabel(hr_html_string), 42, 0, 1, 3) - self.install_grid.setRowStretch(50, 20) + self.grid.setRowStretch(50, 20) - self.install_gbox = QGroupBox("Install steps") - self.install_gbox.setLayout(self.install_grid) + self.gbox = QGroupBox("Install steps") + self.gbox.setLayout(self.grid) layout = QHBoxLayout() - layout.addWidget(self.install_gbox) + layout.addWidget(self.gbox) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) - self.does_ffmpeg_exists() + self.does_ffmpeg_exist() - def does_ffmpeg_exists(self): - if Path("./utils/ffmpeg-" + get_ffmpeg_version() + "-full_build/bin/ffmpeg.exe").exists(): - self.install_grid.addWidget(self.ffmpeg_info_label, 3, 0, 1, 3) - self.ffmpeg_info_label.show() + def does_ffmpeg_exist(self): + executable_path = Path("ffmpeg-" + get_ffmpeg_version() + "-full_build/bin/ffmpeg.exe") + if (self.ffmpeg_dir.directory / executable_path).exists(): exists = True else: - self.install_grid.removeWidget(self.ffmpeg_info_label) - self.ffmpeg_info_label.hide() exists = False self.ffmpeg_pushbutton.setEnabled(not exists) @@ -445,8 +510,8 @@ class InstallWidget(QWidget): return exists def download_ffmpeg_action(self): - download_ffmpeg() - self.does_ffmpeg_exists() + download_ffmpeg(self.ffmpeg_dir.directory) + self.does_ffmpeg_exist() class MainWidget(QWidget):