moving the deployment functions into a class to avoid juggling dirs as arguments
parent
a15c9bc220
commit
d6bcdb9ecc
461
gui/deploy.py
461
gui/deploy.py
|
@ -17,26 +17,6 @@ from distutils.dir_util import copy_tree
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from widgets import create_logger
|
from widgets import create_logger
|
||||||
|
|
||||||
def find_install_dir():
|
|
||||||
library_folders = Path("C:\Program Files (x86)\Steam\steamapps\libraryfolders.vdf")
|
|
||||||
game_id = "602960"
|
|
||||||
data = vdf.load(open(library_folders))
|
|
||||||
install_path = ""
|
|
||||||
for (id, folder) in data["libraryfolders"].items():
|
|
||||||
if game_id in folder["apps"]:
|
|
||||||
install_path = Path(folder["path"]) / Path("steamapps\common\Barotrauma")
|
|
||||||
|
|
||||||
return install_path.as_posix()
|
|
||||||
|
|
||||||
|
|
||||||
def download_via_requests(url_source, file_name):
|
|
||||||
|
|
||||||
response = requests.get(url_source, stream=True, verify=certifi.where())
|
|
||||||
|
|
||||||
with open(file_name, 'wb') as out_file:
|
|
||||||
shutil.copyfileobj(response.raw, out_file)
|
|
||||||
del response
|
|
||||||
|
|
||||||
|
|
||||||
def rmfulldir(dirpath):
|
def rmfulldir(dirpath):
|
||||||
try:
|
try:
|
||||||
|
@ -45,48 +25,12 @@ def rmfulldir(dirpath):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def update(utils_dir: str):
|
def download_via_requests(url_source, file_name):
|
||||||
logging.info(f"checking for updates via git pull.")
|
response = requests.get(url_source, stream=True, verify=certifi.where())
|
||||||
pull = [f"{utils_dir}/git/bin/git.exe", "pull"]
|
|
||||||
subprocess.call(pull)
|
|
||||||
|
|
||||||
|
with open(file_name, 'wb') as out_file:
|
||||||
def download_and_extract(url_source, out_archive, utils_dir="./utils", subdir=""):
|
shutil.copyfileobj(response.raw, out_file)
|
||||||
logger = create_logger()
|
del response
|
||||||
logger.info(f"Downloading {url_source}, this may take a while.")
|
|
||||||
|
|
||||||
download_via_requests(url_source, out_archive)
|
|
||||||
time.sleep(0.7)
|
|
||||||
logger.info("Download complete.")
|
|
||||||
|
|
||||||
logger.info(f"Extracting {out_archive}")
|
|
||||||
extract = [f"{utils_dir}/7z/7za.exe", "x", out_archive, "-o" f"{utils_dir}{subdir}"]
|
|
||||||
subprocess.call(extract)
|
|
||||||
|
|
||||||
time.sleep(0.7)
|
|
||||||
logger.info("Removing " + out_archive)
|
|
||||||
os.remove(out_archive)
|
|
||||||
|
|
||||||
|
|
||||||
def download_ffmpeg(utils_dir: str, clean=False):
|
|
||||||
|
|
||||||
if clean:
|
|
||||||
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 = f"{utils_dir}/ffmpeg-release-full.7z.exe"
|
|
||||||
|
|
||||||
download_and_extract(url_ffmpeg_source, out_ffmpeg_archive, utils_dir)
|
|
||||||
|
|
||||||
def download_git(utils_dir: str, clean=False):
|
|
||||||
if clean:
|
|
||||||
rmfulldir(f"{utils_dir}/git")
|
|
||||||
|
|
||||||
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_and_extract(url_git_source, out_git_archive, utils_dir, subdir="/git")
|
|
||||||
|
|
||||||
|
|
||||||
def get_ffmpeg_version():
|
def get_ffmpeg_version():
|
||||||
|
@ -99,194 +43,257 @@ def get_ffmpeg_version():
|
||||||
return ffmpeg_version
|
return ffmpeg_version
|
||||||
|
|
||||||
|
|
||||||
def fetch_and_cut_song(utils_dir: str, build_dir: str, tape, ffmpeg_version):
|
class Deployer:
|
||||||
python_executable = f"{utils_dir}/python-3.9.7-embed-amd64/python.exe"
|
def __init__(self):
|
||||||
script = "./fetch_song.py"
|
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
|
||||||
|
self.logger = logging.getLogger()
|
||||||
|
|
||||||
if type(tape["source"]) == str:
|
self.utils_dir = "./utils"
|
||||||
shutil.copy(tape["source"], f"{build_dir}/music/{tape['identifier']}.ogg")
|
self.build_dir = "./build"
|
||||||
else:
|
self.music_dir = "./build/music"
|
||||||
fetch = [python_executable, script, tape["source"]["url"], "-x", "--audio-format", "vorbis",
|
self.source_dir = "./source"
|
||||||
"--audio-quality", "0", "-o", f"{build_dir}/tmp_music/{tape['identifier']}.ogg"]
|
self.install_dir = self.find_install_dir()
|
||||||
|
|
||||||
# this is done in a separate python script because subprocess.call makes sure that the
|
def find_install_dir(self):
|
||||||
# download process is finished before trying to cut the song
|
self.logger.info("Trying to find Barotraumma install folder")
|
||||||
|
library_folders = Path("C:\Program Files (x86)\Steam\steamapps\libraryfolders.vdf")
|
||||||
|
game_id = "602960"
|
||||||
|
data = vdf.load(open(library_folders))
|
||||||
|
install_path = ""
|
||||||
|
for (id, folder) in data["libraryfolders"].items():
|
||||||
|
if game_id in folder["apps"]:
|
||||||
|
install_path = Path(folder["path"]) / Path("steamapps\common\Barotrauma")
|
||||||
|
|
||||||
subprocess.call(fetch)
|
self.logger.info(f"Barotrauma is installed in {install_path.as_posix()}")
|
||||||
|
|
||||||
time.sleep(0.1)
|
return install_path.as_posix()
|
||||||
|
|
||||||
cut = [f"{utils_dir}/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe",
|
def download_ffmpeg(self, clean=False):
|
||||||
"-y", "-ss", f"{tape['source']['start']}",
|
if clean:
|
||||||
"-i", f"{build_dir}/tmp_music/{tape['identifier']}.ogg", "-acodec", "libvorbis",
|
rmfulldir(f"{self.utils_dir}/ffmpeg-" + get_ffmpeg_version() + "-full_build")
|
||||||
"-ac", "1", "-af", f"volume={tape['source']['volume']}dB",
|
|
||||||
f"{build_dir}/music/{tape['identifier']}.ogg"]
|
|
||||||
|
|
||||||
if tape["source"]["end"] != -1:
|
url_ffmpeg_source = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z"
|
||||||
cut = cut[:-7] + ["-to", f"{tape['source']['end']}"] + cut[-7:]
|
out_ffmpeg_archive = f"{self.utils_dir}/ffmpeg-release-full.7z.exe"
|
||||||
|
|
||||||
|
self.download_and_extract(url_ffmpeg_source, out_ffmpeg_archive)
|
||||||
|
|
||||||
|
def download_git(self, clean=False):
|
||||||
|
if clean:
|
||||||
|
rmfulldir(f"{self.utils_dir}/git")
|
||||||
|
|
||||||
|
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"{self.utils_dir}/PortableGit-2.46.2-64-bit.7z.exe"
|
||||||
|
|
||||||
|
self.download_and_extract(url_git_source, out_git_archive, subdir="/git")
|
||||||
|
|
||||||
|
def download_and_extract(self, url_source, out_archive, subdir=""):
|
||||||
|
self.logger.info(f"Downloading {url_source}, this may take a while.")
|
||||||
|
|
||||||
|
download_via_requests(url_source, out_archive)
|
||||||
|
time.sleep(0.7)
|
||||||
|
self.logger.info("Download complete.")
|
||||||
|
|
||||||
|
self.logger.info(f"Extracting {out_archive}")
|
||||||
|
extract = [f"{self.utils_dir}/7z/7za.exe", "x", out_archive, "-o" f"{self.utils_dir}{subdir}"]
|
||||||
|
subprocess.call(extract)
|
||||||
|
|
||||||
|
time.sleep(0.7)
|
||||||
|
self.logger.info("Removing " + out_archive)
|
||||||
|
os.remove(out_archive)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.logger.info(f"checking for updates via git pull.")
|
||||||
|
pull = [f"{self.utils_dir}/git/bin/git.exe", "pull"]
|
||||||
|
subprocess.call(pull)
|
||||||
|
|
||||||
|
def fetch_and_cut_song(self, tape, ffmpeg_version):
|
||||||
|
python_executable = f"{self.utils_dir}/python-3.9.7-embed-amd64/python.exe"
|
||||||
|
script = "./fetch_song.py"
|
||||||
|
|
||||||
|
if type(tape["source"]) == str:
|
||||||
|
shutil.copy(tape["source"], f"{self.music_dir}/{tape['identifier']}.ogg")
|
||||||
|
else:
|
||||||
|
fetch = [python_executable, script, tape["source"]["url"], "-x", "--audio-format", "vorbis",
|
||||||
|
"--audio-quality", "0", "-o", f"{self.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
|
||||||
|
|
||||||
|
subprocess.call(fetch)
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
cut = [f"{self.utils_dir}/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe",
|
||||||
|
"-y", "-ss", f"{tape['source']['start']}",
|
||||||
|
"-i", f"{self.build_dir}/tmp_music/{tape['identifier']}.ogg", "-acodec", "libvorbis",
|
||||||
|
"-ac", "1", "-af", f"volume={tape['source']['volume']}dB",
|
||||||
|
f"{self.music_dir}/{tape['identifier']}.ogg"]
|
||||||
|
|
||||||
|
if tape["source"]["end"] != -1:
|
||||||
|
cut = cut[:-7] + ["-to", f"{tape['source']['end']}"] + cut[-7:]
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.call(cut)
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("ffmpeg not in utils directory. Run python install_dependencies.py "
|
||||||
|
"or download the latest release version manually.")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
walkman = [f"{self.utils_dir}/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe",
|
||||||
|
"-i", f"{self.music_dir}/{tape['identifier']}.ogg",
|
||||||
|
"-af", f"highpass=f=300,lowpass=f=12000",
|
||||||
|
f"{self.music_dir}/{tape['identifier']}-walkman.ogg"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.call(cut)
|
subprocess.call(walkman)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print("ffmpeg not in utils directory. Run python install_dependencies.py "
|
self.logger.error("ffmpeg not in utils directory. Run python install_dependencies.py "
|
||||||
"or download the latest release version manually.")
|
"or download the latest release version manually.")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
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_dir}/music/{tape['identifier']}-walkman.ogg"]
|
|
||||||
|
|
||||||
try:
|
def assemble_png_images(self, tapes, outfile: str, resize=None):
|
||||||
subprocess.call(walkman)
|
img_names = [f"{self.source_dir}/images/{tape['identifier']}.png" for tape in tapes]
|
||||||
except FileNotFoundError:
|
|
||||||
print("ffmpeg not in utils directory. Run python install_dependencies.py "
|
images = [Image.open(x) for x in img_names]
|
||||||
"or download the latest release version manually.")
|
|
||||||
sys.exit()
|
if resize is not None:
|
||||||
|
for i, (im, tape) in enumerate(zip(images, tapes)):
|
||||||
|
im.thumbnail((128, 82), Image.ANTIALIAS)
|
||||||
|
if resize == (64, 41) and tape["icon_resize"] == "blur":
|
||||||
|
im.thumbnail(resize, Image.ANTIALIAS)
|
||||||
|
else:
|
||||||
|
im.thumbnail(resize, Image.NEAREST)
|
||||||
|
images[i] = im
|
||||||
|
|
||||||
|
widths, heights = zip(*(i.size for i in images))
|
||||||
|
|
||||||
|
columns = int((len(images)) ** 0.5)
|
||||||
|
rows = int(math.ceil(len(images) / columns))
|
||||||
|
|
||||||
|
total_width = max(widths) * columns
|
||||||
|
max_height = max(heights) * rows
|
||||||
|
|
||||||
|
new_im = Image.new('RGBA', (total_width, max_height))
|
||||||
|
|
||||||
|
for i, im in enumerate(images):
|
||||||
|
x_offset = max(widths) * (i % columns)
|
||||||
|
y_offset = max(heights) * math.floor(i / columns)
|
||||||
|
new_im.paste(im, (x_offset, y_offset))
|
||||||
|
|
||||||
|
new_im.save(f"{self.build_dir}/{outfile}.png")
|
||||||
|
|
||||||
|
|
||||||
def assemble_png_images(tapes, outfile: str, resize=None):
|
def prepare_music(self, data):
|
||||||
|
try:
|
||||||
|
os.mkdir(f'{self.music_dir}')
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
|
||||||
img_names = [f"./source/images/{tape['identifier']}.png" for tape in tapes]
|
ffmpeg_version = get_ffmpeg_version()
|
||||||
|
|
||||||
images = [Image.open(x) for x in img_names]
|
self.logger.info("downloading and cutting the songs")
|
||||||
|
for i, tape in enumerate(data):
|
||||||
if resize is not None:
|
if not (os.path.exists(f"{self.music_dir}/{tape['identifier']}.ogg") or os.path.exists(
|
||||||
for i, (im, tape) in enumerate(zip(images, tapes)):
|
f"{self.music_dir}/{tape['identifier']}-walkman.ogg")):
|
||||||
im.thumbnail((128, 82), Image.ANTIALIAS)
|
self.logger.info(f"{i + 1}/{len(data)} Downloading: {tape['name']}")
|
||||||
if resize == (64, 41) and tape["icon_resize"] == "blur":
|
self.fetch_and_cut_song(tape, ffmpeg_version)
|
||||||
im.thumbnail(resize, Image.ANTIALIAS)
|
|
||||||
else:
|
else:
|
||||||
im.thumbnail(resize, Image.NEAREST)
|
self.logger.info(f"{i + 1}/{len(data)} Already exists: {tape['name']}")
|
||||||
images[i] = im
|
|
||||||
|
|
||||||
widths, heights = zip(*(i.size for i in images))
|
self.logger.info(f"removing temporary music folder")
|
||||||
|
rmfulldir(f"{self.build_dir}/tmp_music/")
|
||||||
|
|
||||||
columns = int((len(images))**0.5)
|
self.logger.info(f"copying the sound effects to build")
|
||||||
rows = int(math.ceil(len(images) / columns))
|
copy_tree(f"{self.source_dir}/sound_effects", f"{self.build_dir}/sound_effects")
|
||||||
|
|
||||||
total_width = max(widths) * columns
|
|
||||||
max_height = max(heights) * rows
|
|
||||||
|
|
||||||
new_im = Image.new('RGBA', (total_width, max_height))
|
|
||||||
|
|
||||||
for i, im in enumerate(images):
|
|
||||||
x_offset = max(widths) * (i % columns)
|
|
||||||
y_offset = max(heights) * math.floor(i / columns)
|
|
||||||
new_im.paste(im, (x_offset, y_offset))
|
|
||||||
|
|
||||||
new_im.save(f"./build/{outfile}.png")
|
|
||||||
|
|
||||||
|
|
||||||
def prepare_music(data, music_dir: str, build_dir: str):
|
def prepare_images(self, data):
|
||||||
try:
|
logging.info(f"assembling covers and icons into png files")
|
||||||
os.mkdir(f'{music_dir}')
|
self.assemble_png_images(data, "covers")
|
||||||
except FileExistsError:
|
self.assemble_png_images(data, "icons", resize=(64, 41))
|
||||||
pass
|
self.assemble_png_images(data, "sprites", resize=(33, 21))
|
||||||
|
|
||||||
ffmpeg_version = get_ffmpeg_version()
|
logging.info(f"copying other images")
|
||||||
|
shutil.copy(f"{self.source_dir}/images/players_icons.png", f"{self.build_dir}/players_icons.png")
|
||||||
|
shutil.copy(f"{self.source_dir}/images/players_sprites.png", f"{self.build_dir}/players_sprites.png")
|
||||||
|
shutil.copy(f"{self.source_dir}/images/PreviewImage.png", f"{self.build_dir}/PreviewImage.png")
|
||||||
|
|
||||||
logging.info("downloading and cutting the songs")
|
|
||||||
for i, tape in enumerate(data):
|
def build_xml_code(self, data, config):
|
||||||
if not (os.path.exists(f"./build/music/{tape['identifier']}.ogg") or os.path.exists(f"./build/music/{tape['identifier']}-walkman.ogg")):
|
self.logger.info(f"calculate the value that lets you use the songs n-times")
|
||||||
logging.info(f"{i + 1}/{len(data)} Downloading: {tape['name']}")
|
song_lengths = [OggVorbis(f"{self.music_dir}/{tape['identifier']}.ogg").info.length
|
||||||
fetch_and_cut_song(tape, ffmpeg_version)
|
for tape in data]
|
||||||
|
|
||||||
|
use_lengths = [song_length * n for song_length, n in
|
||||||
|
zip(song_lengths, [tape["no_of_uses"] for tape in data])]
|
||||||
|
|
||||||
|
condition_delta = [f"{1 / use_length:0.5f}" for use_length in use_lengths]
|
||||||
|
affliction_delta = [100 / song_length for song_length in song_lengths]
|
||||||
|
|
||||||
|
columns = int((len(data)) ** 0.5)
|
||||||
|
positions = [{"column": i % columns, "row": math.floor(i / columns)} for i in range(len(data))]
|
||||||
|
|
||||||
|
self.logger.info(f"creating jinja environment")
|
||||||
|
# create jinja2 environment
|
||||||
|
j2env = j2.Environment(loader=j2.FileSystemLoader(Path(".")))
|
||||||
|
j2env.globals.update(zip=zip)
|
||||||
|
|
||||||
|
# load the template file
|
||||||
|
template0 = j2env.get_template(f"{self.source_dir}/filelist_template.xml")
|
||||||
|
template1 = j2env.get_template(f"{self.source_dir}/sunken_tapes_template.xml")
|
||||||
|
template2 = j2env.get_template(f"{self.source_dir}/sunken_tapes_style_template.xml")
|
||||||
|
|
||||||
|
self.logger.info(f"rendering the xml files")
|
||||||
|
with open(f"{self.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"{self.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,
|
||||||
|
affliction_delta=affliction_delta,
|
||||||
|
song_lengths=song_lengths,
|
||||||
|
positions=positions))
|
||||||
|
|
||||||
|
with open(f"{self.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(self, local_mod_name: str, config):
|
||||||
|
try:
|
||||||
|
os.mkdir(self.build_dir)
|
||||||
|
except FileExistsError:
|
||||||
|
self.logger.info(f"removing old XML files in ./build/:")
|
||||||
|
for f in Path(self.build_dir).glob("*.xml"):
|
||||||
|
self.logger.info(f" {f}")
|
||||||
|
os.remove(f)
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.logger.info("Reading tapes.yaml")
|
||||||
|
data_file = Path("./source/tapes.yaml")
|
||||||
|
|
||||||
|
# load yaml file
|
||||||
|
with data_file.open(encoding='utf-8') as fr:
|
||||||
|
data = yaml.load(fr, Loader=yaml.SafeLoader)
|
||||||
|
|
||||||
|
self.prepare_music(data)
|
||||||
|
self.prepare_images(data)
|
||||||
|
self.build_xml_code(data, config)
|
||||||
|
|
||||||
|
mod_directory = f"{self.install_dir}/LocalMods/{local_mod_name}/"
|
||||||
|
|
||||||
|
self.logger.info(f"removing the old installed mod directory {mod_directory}")
|
||||||
|
rmfulldir(mod_directory)
|
||||||
|
|
||||||
|
self.logger.info(f"copying the new build")
|
||||||
|
if Path(f"{self.install_dir}").is_dir():
|
||||||
|
copy_tree(self.build_dir, mod_directory)
|
||||||
else:
|
else:
|
||||||
logging.info(f"{i + 1}/{len(data)} Already exists: {tape['name']}")
|
raise FileNotFoundError(
|
||||||
|
f"{self.install_dir} does not exist. Set up the correct Barotrauma installation directory")
|
||||||
|
|
||||||
logging.info(f"removing temporary music folder")
|
self.logger.info(f"Done!")
|
||||||
rmfulldir(f"{build_dir}/tmp_music/")
|
|
||||||
|
|
||||||
logging.info(f"copying the sound effects to build")
|
|
||||||
copy_tree("./source/sound_effects", f"{build_dir}/sound_effects")
|
|
||||||
|
|
||||||
|
|
||||||
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", 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, 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]
|
|
||||||
|
|
||||||
use_lengths = [song_length * n for song_length, n in
|
|
||||||
zip(song_lengths, [tape["no_of_uses"] for tape in data])]
|
|
||||||
|
|
||||||
condition_delta = [f"{1 / use_length:0.5f}" for use_length in use_lengths]
|
|
||||||
affliction_delta = [100 / song_length for song_length in song_lengths]
|
|
||||||
|
|
||||||
columns = int((len(data))**0.5)
|
|
||||||
positions = [{"column": i % columns, "row": math.floor(i / columns)} for i in range(len(data))]
|
|
||||||
|
|
||||||
logging.info(f"creating jinja environment")
|
|
||||||
# create jinja2 environment
|
|
||||||
j2env = j2.Environment(loader=j2.FileSystemLoader(Path(".")))
|
|
||||||
j2env.globals.update(zip=zip)
|
|
||||||
|
|
||||||
# load the template file
|
|
||||||
template0 = j2env.get_template("./source/filelist_template.xml")
|
|
||||||
template1 = j2env.get_template("./source/sunken_tapes_template.xml")
|
|
||||||
|
|
||||||
template2 = j2env.get_template("./source/sunken_tapes_style_template.xml")
|
|
||||||
|
|
||||||
logging.info(f"rendering the xml files")
|
|
||||||
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_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,
|
|
||||||
affliction_delta=affliction_delta,
|
|
||||||
song_lengths=song_lengths,
|
|
||||||
positions=positions))
|
|
||||||
|
|
||||||
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(build_dir: str, install_dir: str, local_mod_name: str, config):
|
|
||||||
try:
|
|
||||||
os.mkdir(build_dir)
|
|
||||||
except FileExistsError:
|
|
||||||
logging.info(f"removing old XML files in ./build/:")
|
|
||||||
for f in Path(build_dir).glob("*.xml"):
|
|
||||||
logging.info(f" {f}")
|
|
||||||
os.remove(f)
|
|
||||||
pass
|
|
||||||
|
|
||||||
logging.info("Reading tapes.yaml")
|
|
||||||
data_file = Path("./source/tapes.yaml")
|
|
||||||
|
|
||||||
# load yaml file
|
|
||||||
with data_file.open(encoding='utf-8') as fr:
|
|
||||||
data = yaml.load(fr, Loader=yaml.SafeLoader)
|
|
||||||
|
|
||||||
prepare_music(data)
|
|
||||||
prepare_images(data, build_dir)
|
|
||||||
build_xml_code(data, build_dir, config)
|
|
||||||
|
|
||||||
mod_directory = f"{install_dir}/LocalMods/{local_mod_name}/"
|
|
||||||
|
|
||||||
logging.info(f"removing the old installed mod directory {mod_directory}")
|
|
||||||
rmfulldir(mod_directory)
|
|
||||||
|
|
||||||
logging.info(f"copying the new build")
|
|
||||||
if Path(f"{install_dir}").is_dir():
|
|
||||||
copy_tree(build_dir, mod_directory)
|
|
||||||
else:
|
|
||||||
raise FileNotFoundError(
|
|
||||||
f"{install_dir} does not exist. Set up the correct Barotrauma installation directory")
|
|
||||||
|
|
||||||
logging.info(f"Done!")
|
|
||||||
|
|
|
@ -4,9 +4,10 @@ import getpass
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from gui.deploy import Deployer
|
||||||
from tape_editor_widgets import *
|
from tape_editor_widgets import *
|
||||||
from widgets import LabelWebLink
|
from widgets import LabelWebLink
|
||||||
from deploy import download_ffmpeg, get_ffmpeg_version, download_git, find_install_dir
|
from deploy import Deployer, get_ffmpeg_version
|
||||||
|
|
||||||
from PIL import ImageGrab
|
from PIL import ImageGrab
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ class OptionsWidget(QWidget):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
self.deployer = Deployer()
|
||||||
|
|
||||||
options = [("Buffs", "Some songs affect the characters with strengthen\nand haste afflictions."),
|
options = [("Buffs", "Some songs affect the characters with strengthen\nand haste afflictions."),
|
||||||
("De-buffs", "Some songs affect the characters with psychosis \naffliction."),
|
("De-buffs", "Some songs affect the characters with psychosis \naffliction."),
|
||||||
|
@ -92,7 +94,7 @@ class OptionsWidget(QWidget):
|
||||||
# Update widget
|
# Update widget
|
||||||
self.update_widget = UpdateWidget(self)
|
self.update_widget = UpdateWidget(self)
|
||||||
# Install widget
|
# Install widget
|
||||||
self.install_widget = InstallWidget(self)
|
self.install_widget = InstallWidget(self, self.deployer)
|
||||||
# Console widget
|
# Console widget
|
||||||
self.console_widget = ConsoleWidget(self)
|
self.console_widget = ConsoleWidget(self)
|
||||||
|
|
||||||
|
@ -421,7 +423,7 @@ class UpdateWidget(QGroupBox):
|
||||||
self.does_git_exist()
|
self.does_git_exist()
|
||||||
|
|
||||||
def download_git_action(self):
|
def download_git_action(self):
|
||||||
download_git(self.git_dir.directory)
|
self.parent.deployer.download_git()
|
||||||
|
|
||||||
def does_git_exist(self):
|
def does_git_exist(self):
|
||||||
executable_path = Path("git/bin/git.exe")
|
executable_path = Path("git/bin/git.exe")
|
||||||
|
@ -447,10 +449,11 @@ class ConsoleWidget(QGroupBox):
|
||||||
|
|
||||||
|
|
||||||
class InstallWidget(QGroupBox):
|
class InstallWidget(QGroupBox):
|
||||||
def __init__(self, parent: QWidget):
|
def __init__(self, parent: QWidget, deployer: Deployer):
|
||||||
super().__init__("Install steps")
|
super().__init__("Install steps")
|
||||||
|
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
self.deployer = deployer
|
||||||
self.grid = QGridLayout(self)
|
self.grid = QGridLayout(self)
|
||||||
|
|
||||||
hr_html_string = "<hr style=\"background-color:gray;\">"
|
hr_html_string = "<hr style=\"background-color:gray;\">"
|
||||||
|
@ -461,7 +464,7 @@ class InstallWidget(QGroupBox):
|
||||||
self.ffmpeg_label_link = LabelWebLink("https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z")
|
self.ffmpeg_label_link = LabelWebLink("https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z")
|
||||||
self.ffmpeg_pushbutton = QPushButton("Download")
|
self.ffmpeg_pushbutton = QPushButton("Download")
|
||||||
self.ffmpeg_pushbutton.clicked.connect(self.download_ffmpeg_action)
|
self.ffmpeg_pushbutton.clicked.connect(self.download_ffmpeg_action)
|
||||||
self.ffmpeg_dir = DirWidget("./utils")
|
self.ffmpeg_dir = DirWidget(self.deployer.utils_dir)
|
||||||
self.grid.addWidget(self.ffmpeg_checkbox, 0, 0)
|
self.grid.addWidget(self.ffmpeg_checkbox, 0, 0)
|
||||||
self.grid.addWidget(self.ffmpeg_label, 0, 1)
|
self.grid.addWidget(self.ffmpeg_label, 0, 1)
|
||||||
self.grid.addWidget(self.ffmpeg_pushbutton, 0, 2)
|
self.grid.addWidget(self.ffmpeg_pushbutton, 0, 2)
|
||||||
|
@ -472,7 +475,7 @@ class InstallWidget(QGroupBox):
|
||||||
self.songs_download_checkbox = QCheckBox()
|
self.songs_download_checkbox = QCheckBox()
|
||||||
self.songs_download_checkbox.setDisabled(True)
|
self.songs_download_checkbox.setDisabled(True)
|
||||||
self.songs_download_label = QLabel("Download songs and process them")
|
self.songs_download_label = QLabel("Download songs and process them")
|
||||||
self.songs_download_dir = DirWidget("./build/music")
|
self.songs_download_dir = DirWidget(self.deployer.music_dir)
|
||||||
self.songs_download_pushbutton = QPushButton("Download")
|
self.songs_download_pushbutton = QPushButton("Download")
|
||||||
self.songs_download_pushbutton.clicked.connect(self.are_songs_ready)
|
self.songs_download_pushbutton.clicked.connect(self.are_songs_ready)
|
||||||
self.grid.addWidget(self.songs_download_checkbox, 20, 0)
|
self.grid.addWidget(self.songs_download_checkbox, 20, 0)
|
||||||
|
@ -484,7 +487,7 @@ class InstallWidget(QGroupBox):
|
||||||
self.compile_checkbox = QCheckBox()
|
self.compile_checkbox = QCheckBox()
|
||||||
self.compile_checkbox.setDisabled(True)
|
self.compile_checkbox.setDisabled(True)
|
||||||
self.compile_label = QLabel("Compile mod according to the settings")
|
self.compile_label = QLabel("Compile mod according to the settings")
|
||||||
self.compile_dir = DirWidget("./build")
|
self.compile_dir = DirWidget(self.deployer.build_dir)
|
||||||
self.compile_pushbutton = QPushButton("Compile")
|
self.compile_pushbutton = QPushButton("Compile")
|
||||||
self.grid.addWidget(self.compile_checkbox, 30, 0)
|
self.grid.addWidget(self.compile_checkbox, 30, 0)
|
||||||
self.grid.addWidget(self.compile_label, 30, 1)
|
self.grid.addWidget(self.compile_label, 30, 1)
|
||||||
|
@ -495,7 +498,7 @@ class InstallWidget(QGroupBox):
|
||||||
self.install_checkbox = QCheckBox()
|
self.install_checkbox = QCheckBox()
|
||||||
self.install_checkbox.setDisabled(True)
|
self.install_checkbox.setDisabled(True)
|
||||||
self.install_label = QLabel("Copy the files to the install directory")
|
self.install_label = QLabel("Copy the files to the install directory")
|
||||||
self.install_dir = DirWidget(find_install_dir())
|
self.install_dir = DirWidget(self.deployer.install_dir)
|
||||||
self.install_pushbutton = QPushButton("Install")
|
self.install_pushbutton = QPushButton("Install")
|
||||||
self.grid.addWidget(self.install_checkbox, 40, 0)
|
self.grid.addWidget(self.install_checkbox, 40, 0)
|
||||||
self.grid.addWidget(self.install_label, 40, 1)
|
self.grid.addWidget(self.install_label, 40, 1)
|
||||||
|
@ -576,5 +579,4 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
|
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue