Move asset builder functions

This commit is contained in:
Veronica Berglyd Olsen
2025-01-16 21:32:56 +01:00
parent 3ef790fbe3
commit 0306701e6f
2 changed files with 287 additions and 304 deletions
+8 -304
View File
@@ -31,10 +31,8 @@ import datetime
import shutil
import subprocess
import sys
import zipfile
from pathlib import Path
import utils.assets
import utils.build_appimage
import utils.build_binary
import utils.build_debian
@@ -115,296 +113,6 @@ def cleanBuildDirs(args: argparse.Namespace) -> None:
return
# =============================================================================================== #
# Additional Builds
# =============================================================================================== #
##
# Build PDF Manual (manual)
##
def buildPdfManual(args: argparse.Namespace | None = None) -> None:
"""This function will build the documentation as manual.pdf."""
print("")
print("Building PDF Manual")
print("===================")
print("")
buildFile = ROOT_DIR / "docs" / "build" / "latex" / "manual.pdf"
finalFile = ROOT_DIR / "novelwriter" / "assets" / "manual.pdf"
finalFile.unlink(missing_ok=True)
try:
subprocess.call(["make", "clean"], cwd="docs")
exCode = subprocess.call(["make", "latexpdf"], cwd="docs")
if exCode == 0:
print("")
buildFile.rename(finalFile)
else:
raise Exception(f"Build returned error code {exCode}")
print("PDF manual build: OK")
print("")
except Exception as exc:
print("PDF manual build: FAILED")
print("")
print(str(exc))
print("")
print("Dependencies:")
print(" * pip install sphinx")
print(" * Package latexmk")
print(" * LaTeX build system")
print("")
print(" On Debian/Ubuntu, install: python3-sphinx latexmk texlive texlive-latex-extra")
print("")
sys.exit(1)
if not finalFile.is_file():
print("No output file was found!")
print("")
sys.exit(1)
return
##
# Sample Project ZIP File Builder (sample)
##
def buildSampleZip(args: argparse.Namespace | None = None) -> None:
"""Bundle the sample project into a single zip file to be saved into
the novelwriter/assets folder for further bundling into builds.
"""
print("")
print("Building Sample ZIP File")
print("========================")
print("")
srcSample = ROOT_DIR / "sample"
dstSample = ROOT_DIR / "novelwriter" / "assets" / "sample.zip"
if srcSample.is_dir():
dstSample.unlink(missing_ok=True)
with zipfile.ZipFile(dstSample, "w") as zipObj:
print("Compressing: nwProject.nwx")
zipObj.write(srcSample / "nwProject.nwx", "nwProject.nwx")
for doc in (srcSample / "content").iterdir():
print(f"Compressing: content/{doc.name}")
zipObj.write(doc, f"content/{doc.name}")
else:
print("Error: Could not find sample project source directory.")
sys.exit(1)
print("")
print("Built file: %s" % dstSample)
print("")
return
##
# Import Translations (import-i18n)
##
def importI18nUpdates(args: argparse.Namespace) -> None:
"""Import new translation files from a zip file."""
print("")
print("Import Updated Translations")
print("===========================")
print("")
fileName = Path(args.file).absolute()
if not fileName.is_file():
print("File not found ...")
sys.exit(1)
dstPath = ROOT_DIR / "novelwriter" / "assets" / "i18n"
srcPath = ROOT_DIR / "i18n"
print(f"Loading file: {fileName}")
with zipfile.ZipFile(fileName) as zipObj:
for item in zipObj.namelist():
if item.startswith("nw_") and item.endswith(".ts"):
zipObj.extract(item, srcPath)
print(f"Extracted: {item} > {srcPath / item}")
elif item.startswith("project_") and item.endswith(".json"):
zipObj.extract(item, dstPath)
print(f"Extracted: {item} > {dstPath / item}")
else:
print(f"Skipped: {item}")
print("")
return
##
# Qt Linguist TS Builder (qtlupdate)
##
def updateTranslationSources(args: argparse.Namespace) -> None:
"""Build the lang.ts files for Qt Linguist."""
print("")
print("Building Qt Translation Files")
print("=============================")
try:
# Using the pylupdate tool from PyQt6 as it supports TS file format 2.1.
from PyQt6.lupdate.lupdate import lupdate
except ImportError:
print("ERROR: This command requires lupdate from PyQt6")
print("On Debian/Ubuntu, install: pyqt6-dev-tools")
sys.exit(1)
print("")
print("Scanning Source Tree:")
print("")
sources = list((ROOT_DIR / "novelwriter").glob("**/*.py"))
sources.insert(0, ROOT_DIR / "i18n" / "qtbase.py")
for source in sources:
print(source.relative_to(ROOT_DIR))
print("")
print("TS Files to Update:")
print("")
translations = []
for item in [Path(str(f)).absolute() for f in args.files]:
if not (item.name.startswith("nw_") and item.suffix == ".ts"):
print(f"Skipped: {item}")
continue
if item.is_file():
translations.append(item)
print(f"Added: {item}")
elif item.exists():
continue
else: # Create an empty new language file
langCode = item.name[3:-3]
writeFile(item, (
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<!DOCTYPE TS>\n"
f"<TS version=\"2.0\" language=\"{langCode}\" sourcelanguage=\"en_GB\"/>\n"
))
translations.append(item)
print(f"Created: {item}")
print("")
print("Updating Language Files:")
print("")
lupdate(
sources=[str(f) for f in sources],
translation_files=[str(f) for f in translations],
no_obsolete=True,
no_summary=False,
)
print("")
return
##
# Qt Linguist QM Builder (qtlrelease)
##
def buildTranslationAssets(args: argparse.Namespace | None = None) -> None:
"""Build the lang.qm files for Qt Linguist."""
print("")
print("Building Qt Localisation Files")
print("==============================")
print("")
print("TS Files to Build:")
print("")
srcDir = ROOT_DIR / "i18n"
dstDir = ROOT_DIR / "novelwriter" / "assets" / "i18n"
srcList = []
for item in srcDir.iterdir():
if item.is_file() and item.suffix == ".ts" and item.name != "nw_base.ts":
srcList.append(item)
print(item)
print("")
print("Building Translation Files:")
print("")
try:
subprocess.call(["lrelease", "-verbose", *srcList])
except Exception as exc:
print("Qt Linguist tools seem to be missing")
print("On Debian/Ubuntu, install: qttools5-dev-tools")
print(str(exc))
sys.exit(1)
print("")
print("Moving QM Files to Assets")
print("")
dstRel = dstDir.relative_to(ROOT_DIR)
for item in srcDir.iterdir():
if item.is_file() and item.suffix == ".qm":
item.rename(dstDir / item.name)
print("Moved: %s -> %s" % (item.relative_to(ROOT_DIR), dstRel / item.name))
print("")
return
##
# Clean Assets (clean-assets)
##
def cleanBuiltAssets(args: argparse.Namespace | None = None) -> None:
"""Remove assets built by this script."""
print("")
print("Removing Built Assets")
print("=====================")
print("")
assets = [
ROOT_DIR / "novelwriter" / "assets" / "sample.zip",
ROOT_DIR / "novelwriter" / "assets" / "manual.pdf",
]
assets.extend((ROOT_DIR / "novelwriter" / "assets" / "i18n").glob("*.qm"))
for asset in assets:
if asset.is_file():
asset.unlink()
print(f"Deleted: {asset.relative_to(ROOT_DIR)}")
print("")
return
##
# Build Assets (build-assets)
##
def buildAllAssets(args: argparse.Namespace) -> None:
"""Build all assets."""
cleanBuiltAssets()
buildPdfManual()
buildSampleZip()
buildTranslationAssets()
return
# =============================================================================================== #
# Python Packaging
# =============================================================================================== #
##
# Generate MacOS PList
##
def genMacOSPlist(args: argparse.Namespace) -> None:
"""Set necessary values for .plist file for MacOS build."""
outDir = SETUP_DIR / "macos"
@@ -428,10 +136,6 @@ def genMacOSPlist(args: argparse.Namespace) -> None:
return
# =============================================================================================== #
# Process Command Line
# =============================================================================================== #
if __name__ == "__main__":
"""Parse command line options and run the commands."""
parser = argparse.ArgumentParser(
@@ -478,7 +182,7 @@ if __name__ == "__main__":
"qtlimport", help="Import updated i18n files from a Crowdin zip file."
)
cmdImportTS.add_argument("file", help="Path to zip file from Crowdin")
cmdImportTS.set_defaults(func=importI18nUpdates)
cmdImportTS.set_defaults(func=utils.assets.importI18nUpdates)
# Update i18n Sources
cmdUpdateTS = parsers.add_parser(
@@ -490,37 +194,37 @@ if __name__ == "__main__":
)
)
cmdUpdateTS.add_argument("files", nargs="+")
cmdUpdateTS.set_defaults(func=updateTranslationSources)
cmdUpdateTS.set_defaults(func=utils.assets.updateTranslationSources)
# Build i18n Files
cmdBuildQM = parsers.add_parser(
"qtlrelease", help="Build the language files for internationalisation."
)
cmdBuildQM.set_defaults(func=buildTranslationAssets)
cmdBuildQM.set_defaults(func=utils.assets.buildTranslationAssets)
# Build Manual
cmdBuildManual = parsers.add_parser(
"manual", help="Build the help documentation as a PDF (requires LaTeX)."
)
cmdBuildManual.set_defaults(func=buildPdfManual)
cmdBuildManual.set_defaults(func=utils.assets.buildPdfManual)
# Build Sample
cmdBuildSample = parsers.add_parser(
"sample", help="Build the sample project zip file and add it to assets."
)
cmdBuildSample.set_defaults(func=buildSampleZip)
cmdBuildSample.set_defaults(func=utils.assets.buildSampleZip)
# Clean Assets
cmdCleanAssets = parsers.add_parser(
"clean-assets", help="Delete assets built by manual, sample and qtlrelease."
)
cmdCleanAssets.set_defaults(func=cleanBuiltAssets)
cmdCleanAssets.set_defaults(func=utils.assets.cleanBuiltAssets)
# Build Assets
cmdBuildAssets = parsers.add_parser(
"build-assets", help="Build all assets. Includes manual, sample and qtlrelease."
)
cmdBuildAssets.set_defaults(func=buildAllAssets)
cmdBuildAssets.set_defaults(func=utils.assets.buildAllAssets)
# Python Packaging
# ================