Beispiel #1
0
def BuildInformation () -> bool:
	if not Information.CanBuildInformation():
		return True

	Information.BuildInformation(Mod.GetCurrentMod().InformationSourceFilePath, Mod.GetCurrentMod().InformationBuildFilePath)

	return True
Beispiel #2
0
def UpdateGamePython() -> bool:
    """
	Send currently built python files to the Sims 4 mod folder.
	:return:
	"""

    try:
        currentPythonFilePath = os.path.join(
            Paths.S4ModsPath,
            Mod.GetCurrentMod().PythonMergeRelativeRoot,
            Mod.GetCurrentMod().PythonBuildArchiveFileName)  # type: str

        if os.path.exists(currentPythonFilePath):
            os.remove(currentPythonFilePath)

        shutil.copy(
            Mod.GetCurrentMod().PythonBuildArchiveFilePath,
            os.path.join(Paths.S4ModsPath,
                         Mod.GetCurrentMod().PythonMergeRelativeRoot))
    except Exception as e:
        print("Failed to send python to the Sims 4 mod folder.\n" + \
           "Mod: '" + Mod.GetCurrentMod().Namespace + "'\n" + \
           Exceptions.FormatException(e), file = sys.stderr)

        return False

    return True
Beispiel #3
0
def UpdateGameFiles() -> bool:
    """
	Send currently built mod files to the Sims 4 mod folder.
	:return:
	"""

    try:
        if os.path.exists(Mod.GetCurrentMod().UninstallFilesFilePath):
            with open(Mod.GetCurrentMod().UninstallFilesFilePath
                      ) as uninstallFilesFile:
                uninstallFiles = uninstallFilesFile.read().splitlines(
                )  # type: typing.List[str]

            for uninstallFile in uninstallFiles:  # type: str
                uninstallFilePath = os.path.join(Paths.S4ModsPath,
                                                 uninstallFile)  # type: str

                if os.path.exists(uninstallFilePath):
                    os.remove(uninstallFilePath)
    except Exception as e:
        print("Failed to uninstall the previous mod version.\n" + \
           "Mod: '" + Mod.GetCurrentMod().Namespace + "'\n" + \
           Exceptions.FormatException(e), file = sys.stderr)

    try:
        dir_util.copy_tree(Paths.BuildPath, Paths.S4ModsPath)
    except Exception as e:
        print("Failed to send mod to the Sims 4 mod folder.\n" + \
           "Mod: '" + Mod.GetCurrentMod().Namespace + "'\n" + \
           Exceptions.FormatException(e), file = sys.stderr)

        return False

    return True
Beispiel #4
0
def BuildMisc() -> bool:
    if not Misc.CanBuildMarkdown():
        return False

    IO.ClearDirectory(Paths.MiscPath)

    changesFilePath = Mod.GetCurrentMod().ChangesFilePath  # type: str

    if os.path.exists(changesFilePath):
        changesBuildFileName = os.path.splitext(
            os.path.split(changesFilePath)[1])[0] + ".html"  # type: str
        changesBuildFilePath = os.path.join(Paths.MiscPath,
                                            Mod.GetCurrentMod().Namespace,
                                            changesBuildFileName)  # type: str

        Misc.BuildMarkdown(changesBuildFilePath, changesFilePath)

    plansFilePath = Mod.GetCurrentMod().PlansFilePath  # type: str

    if os.path.exists(plansFilePath):
        plansBuildFileName = os.path.splitext(
            os.path.split(plansFilePath)[1])[0] + ".html"  # type: str
        plansBuildFilePath = os.path.join(Paths.MiscPath,
                                          Mod.GetCurrentMod().Namespace,
                                          plansBuildFileName)  # type: str

        Misc.BuildMarkdown(plansBuildFilePath, plansFilePath)

    return True
Beispiel #5
0
def BuildPublishing() -> bool:
    print("Building mod publishing '" + Mod.GetCurrentMod().Namespace + "'.")

    for phase in _publishingPhases:  # type: typing.Callable
        try:
            if not phase():
                print("Forced to skip all or part of phase 'Publishing'.\n" + \
                   "Phase: 'Publishing' Mod: '" + Mod.GetCurrentMod().Namespace + "'", file = sys.stderr)
        except Exception as e:
            print("Failed to complete mod build phase.\n" + \
               "Phase: 'Publishing' Mod: '" + Mod.GetCurrentMod().Namespace + "'" + \
               Exceptions.FormatException(e), file = sys.stderr)

            return False

    return True
Beispiel #6
0
def BuildPackageEverything() -> bool:
    if not Package.CanBuildPackage():
        return False

    for package in Mod.GetCurrentMod().Packages:  # type: Mod.Package
        _BuildPackageEverythingInternal(package)

    return True
Beispiel #7
0
def BuildDistribution() -> bool:
    if not Distribution.CanSendToInstaller(
    ) or not Distribution.CanBuildInstaller():
        return False

    IO.ClearDirectory(
        os.path.dirname(Mod.GetCurrentMod().DistributionFilesFilePath))
    IO.ClearDirectory(
        os.path.dirname(Mod.GetCurrentMod().DistributionInstallerFilePath))

    IO.ZipDirectory(Paths.BuildPath,
                    Mod.GetCurrentMod().DistributionFilesFilePath,
                    compress=True)

    IO.ClearDirectory(
        os.path.dirname(Mod.GetCurrentMod().DistributionInstallerFilePath))

    Distribution.SendToNOModInstaller(
        Mod.GetCurrentMod().DistributionFilesFilePath,
        Paths.PublishingAdditionalInstallerPath)
    Distribution.BuildInstaller(
        os.path.dirname(Mod.GetCurrentMod().DistributionInstallerFilePath),
        os.path.splitext(
            os.path.split(
                Mod.GetCurrentMod().DistributionInstallerFilePath)[1])[0])

    return True
Beispiel #8
0
def BuildSTBLEverything() -> bool:
    canBuildSTBL = STBL.CanBuildSTBL()  # type: bool

    if not canBuildSTBL:
        return False

    for package in Mod.GetCurrentMod().Packages:  # type: Mod.Package
        if not os.path.exists(package.STBLPath):
            continue

        for stblXMLFileName in os.listdir(package.STBLPath):  # type: str
            stblXMLFilePath = os.path.join(package.STBLPath,
                                           stblXMLFileName)  # type: str

            if os.path.isfile(stblXMLFilePath) and os.path.splitext(
                    stblXMLFileName)[1].casefold() == ".xml":
                modifiedTime = os.path.getmtime(stblXMLFilePath)  # type: float
                manifestFilePath = os.path.splitext(
                    stblXMLFilePath)[0] + "_Manifest.json"  # type: str

                buildTempDirectory = stblXMLFilePath + "_Temp_Build"  # type: str

                if not os.path.exists(buildTempDirectory):
                    os.makedirs(buildTempDirectory)
                try:
                    STBL.BuildSTBL(buildTempDirectory, stblXMLFilePath)

                    manifest = dict()  # type: typing.Dict[str, typing.Any]

                    manifest[ManifestBuiltModifiedTimeKey] = modifiedTime
                    builtFileNames = list()

                    for builtFileName in os.listdir(buildTempDirectory):
                        builtFilePath = os.path.join(buildTempDirectory,
                                                     builtFileName)

                        if os.path.isfile(builtFilePath):
                            builtFileNames.append(builtFileName)

                    manifest[ManifestBuiltFileNamesKey] = builtFileNames

                    with open(manifestFilePath, "w+") as manifestFile:
                        manifestFile.write(
                            json.JSONEncoder(indent="\t").encode(manifest))

                    dir_util.copy_tree(
                        buildTempDirectory,
                        os.path.join(package.SourceLoosePath, "STBL"))
                finally:
                    shutil.rmtree(buildTempDirectory)

    return True
Beispiel #9
0
def BuildMod(modeName: str) -> bool:
    if not modeName in _modBuildModes:
        modeName = _modBuildDefaultMode

    modePhases = _modBuildModes.get(
        modeName)  # type: typing.List[typing.Callable]

    print("Building mod '" + Mod.GetCurrentMod().Namespace + "' in mode '" +
          modeName + "'.")

    for phase in modePhases:  # type: typing.Callable
        try:
            if not phase():
                print("Forced to skip all or part of phase '" + phase.__name__ + "'.\n" + \
                   "Phase: '" + phase.__name__ + "' Mod: '" + Mod.GetCurrentMod().Namespace + "' Build mode: '" + modeName + "'", file = sys.stderr)
        except Exception as e:
            print("Failed to complete mod build phase.\n" + \
               "Phase: '" + phase.__name__ + "' Mod: '" + Mod.GetCurrentMod().Namespace + "' Build mode: '" + modeName + "' \n" + \
               Exceptions.FormatException(e), file = sys.stderr)

            return False

    return True
Beispiel #10
0
def GetEntries() -> typing.List[typing.Tuple[str, int]]:
    entries = list()  # type: typing.List[typing.Tuple[str, int]]

    for package in Mod.GetCurrentMod().Packages:  # type: Mod.Package
        if not os.path.exists(package.STBLPath):
            continue

        if os.path.exists(package.STBLPath):
            for stblXMLFileName in os.listdir(package.STBLPath):  # type: str
                stblXMLFilePath = os.path.join(package.STBLPath,
                                               stblXMLFileName)  # type: str

                if os.path.isfile(stblXMLFilePath) and os.path.splitext(
                        stblXMLFileName)[1].casefold() == ".xml":
                    try:
                        stblXMLFile = ElementTree.parse(
                            stblXMLFilePath)  # type: ElementTree.ElementTree
                        entriesElements = stblXMLFile.findall(
                            "Entries/STBLXMLEntry"
                        )  # type: typing.Optional[typing.List[ElementTree.Element]]

                        if entriesElements is None:
                            continue

                        for entryElement in entriesElements:  # type: ElementTree.Element
                            entryIdentifierElement = entryElement.find(
                                "Identifier")  # type: ElementTree.Element
                            entryKeyElement = entryElement.find(
                                "Key")  # type: ElementTree.Element

                            if entryIdentifierElement is None or entryKeyElement is None:
                                continue

                            entryIdentifier = entryIdentifierElement.text  # type: str
                            entryKeyText = entryKeyElement.text  # type: str
                            entryKey = int(entryKeyText)  # type: int

                            entries.append((entryIdentifier, entryKey))
                    except Exception as e:
                        print("Failed to read potential stbl xml file at '" +
                              stblXMLFilePath + "'\n" + str(e),
                              file=sys.stderr)
                        continue

    return entries
Beispiel #11
0
def BuildPython() -> bool:
    if not Python.CanBuildPython():
        return False

    IO.ClearDirectory(Paths.PythonBuildArchivePath)
    IO.ClearDirectory(Paths.PythonBuildLoosePath)

    Python.BuildPython(Paths.PythonBuildLoosePath,
                       Mod.GetCurrentMod().PythonBuildArchiveFilePath,
                       Mod.GetCurrentMod().PythonSourceRootPath,
                       Mod.GetCurrentMod().PythonSourceTargetPath,
                       Mod.GetCurrentMod().PythonSourceExcludedFiles)

    if not os.path.exists(Mod.GetCurrentMod().PythonMergeRoot):
        os.makedirs(Mod.GetCurrentMod().PythonMergeRoot)

    shutil.copy(Mod.GetCurrentMod().PythonBuildArchiveFilePath,
                Mod.GetCurrentMod().PythonMergeRoot)

    return True
Beispiel #12
0
def BuildPackageChanges() -> bool:
    if not Package.CanBuildPackage():
        return False

    for package in Mod.GetCurrentMod().Packages:  # type: Mod.Package
        baseFileExists = os.path.exists(
            package.SourceBaseFilePath)  # type: bool
        loosePathExists = os.path.exists(package.SourceLoosePath)  # type: bool

        packageManifest = None  # type: typing.Optional[typing.Dict[str, typing.Union[float, typing.Dict[str, float]]]]

        if not os.path.exists(package.BuildFilePath):
            _BuildPackageEverythingInternal(package)
            return True

        if os.path.exists(package.BuildManifestFilePath):
            with open(package.BuildManifestFilePath) as packageManifestFile:
                packageManifest = decoder.JSONDecoder().decode(
                    packageManifestFile.read())

        if packageManifest is not None and not isinstance(
                packageManifest, dict):
            packageManifest = None

        if packageManifest is not None and (not "Loose" in packageManifest
                                            or not "Base" in packageManifest):
            packageManifest = None

        if packageManifest is None:
            _BuildPackageEverythingInternal(package)
            return True
        else:
            filesChanged = False  # type: bool

            if baseFileExists:
                baseCurrentChangeTime = os.path.getmtime(
                    package.SourceBaseFilePath)  # type: float

                if packageManifest["Base"] != os.path.getmtime(
                        package.SourceBaseFilePath):
                    packageManifest["Base"] = baseCurrentChangeTime
                    filesChanged = True

            if loosePathExists:
                packageManifestLooseDictionary = packageManifest[
                    "Loose"]  # type: dict

                for entryFileName in list(
                        packageManifestLooseDictionary.keys()):  # type: str
                    entryChangeTime = packageManifestLooseDictionary[
                        entryFileName]  # type: float

                    entryFilePath = os.path.join(package.SourceLoosePath,
                                                 entryFileName)  # type: str

                    if not os.path.exists(entryFilePath):
                        packageManifestLooseDictionary.pop(entryFileName)
                        filesChanged = True
                        continue

                    entryCurrentChangeTime = os.path.getmtime(
                        entryFilePath)  # type: float

                    if entryCurrentChangeTime != entryChangeTime:
                        packageManifest["Loose"][
                            entryFileName] = entryCurrentChangeTime
                        filesChanged = True

                for sourceDirectoryRoot, sourceDirectoryNames, sourceFileNames in os.walk(
                        package.SourceLoosePath
                ):  # type: str, typing.List[str], typing.List[str]
                    for sourceFileName in sourceFileNames:  # type: str
                        sourceFilePath = os.path.join(
                            sourceDirectoryRoot, sourceFileName)  # type: str
                        relativeSourceFilePath = os.path.relpath(
                            sourceFilePath,
                            package.SourceLoosePath)  # type: str
                        sourceFileDuplicate = False  # type: bool

                        for entryFileName in packageManifest["Loose"].keys(
                        ):  # type: str
                            if entryFileName.lower(
                            ) == relativeSourceFilePath.lower():
                                sourceFileDuplicate = True
                                break

                        if not sourceFileDuplicate:
                            packageManifest["Loose"][
                                relativeSourceFilePath] = os.path.getmtime(
                                    sourceFilePath)
                            filesChanged = True

            if filesChanged:
                addingFilePaths = list()  # type: typing.List[str]

                if loosePathExists:
                    for sourceDirectoryRoot, sourceDirectoryNames, sourceFileNames in os.walk(
                            package.SourceLoosePath
                    ):  # type: str, typing.List[str], typing.List[str]
                        for sourceFileName in sourceFileNames:  # type: str
                            # noinspection SpellCheckingInspection
                            if os.path.splitext(sourceFileName)[1].lower(
                            ) == ".sourceinfo":
                                continue

                            sourceFilePath = os.path.join(
                                sourceDirectoryRoot,
                                sourceFileName)  # type: str

                            if os.path.isfile(sourceFilePath):
                                addingFilePaths.append(sourceFilePath)

                if baseFileExists:
                    Package.BuildPackage(
                        package.BuildFilePath,
                        baseFilePath=package.SourceBaseFilePath,
                        addingFilePaths=addingFilePaths)
                else:
                    Package.BuildPackage(package.BuildFilePath,
                                         addingFilePaths=addingFilePaths)

                with open(package.BuildManifestFilePath,
                          "w+") as packageManifestFile:
                    packageManifestFile.write(
                        encoder.JSONEncoder(
                            indent="\t").encode(packageManifest))

    return True
Beispiel #13
0
def _BuildManifest() -> None:
    Merging.BuildManifest(
        os.path.join(Mod.GetCurrentMod().Namespace,
                     Mod.GetCurrentMod().Namespace + "-Uninstall-Files.txt"),
        Paths.BuildPath)
Beispiel #14
0
def _MergePackage() -> None:
    for package in Mod.GetCurrentMod().Packages:  # type: Mod.Package
        if os.path.exists(package.BuildFilePath):
            shutil.copy(package.BuildFilePath, package.MergeRoot)
Beispiel #15
0
def _MergePython() -> None:
    if os.path.exists(Mod.GetCurrentMod().PythonBuildArchiveFilePath):
        shutil.copy(Mod.GetCurrentMod().PythonBuildArchiveFilePath,
                    Mod.GetCurrentMod().PythonMergeRoot)
Beispiel #16
0
def BuildSTBLChanges() -> bool:
    canBuildSTBL = STBL.CanBuildSTBL()  # type: bool

    if not canBuildSTBL:
        return False

    for package in Mod.GetCurrentMod().Packages:  # type: Mod.Package
        if not os.path.exists(package.STBLPath):
            continue

        for stblXMLFileName in os.listdir(package.STBLPath):  # type: str
            stblXMLFilePath = os.path.join(package.STBLPath,
                                           stblXMLFileName)  # type: str

            if os.path.isfile(stblXMLFilePath) and os.path.splitext(
                    stblXMLFileName)[1].casefold() == ".xml":
                manifestFilePath = os.path.splitext(
                    stblXMLFilePath)[0] + "_Manifest.json"  # type: str

                modifiedTime = os.path.getmtime(stblXMLFilePath)  # type: float
                builtModifiedTime = None  # type: typing.Optional[int]
                builtFileNames = list()  # type: typing.List[str]

                try:
                    if os.path.exists(manifestFilePath):
                        with open(manifestFilePath) as manifestFile:
                            manifest = json.JSONDecoder().decode(
                                manifestFile.read()
                            )  # type: typing.Dict[str, typing.Any]

                        if not isinstance(manifest, dict):
                            raise Exceptions.IncorrectTypeException(
                                manifest, "Root", (dict, ))

                        if ManifestBuiltModifiedTimeKey in manifest:
                            builtModifiedTime = manifest[
                                ManifestBuiltModifiedTimeKey]

                        if not isinstance(builtModifiedTime,
                                          float) and not isinstance(
                                              builtModifiedTime, int):
                            incorrectValue = builtModifiedTime  # type: typing.Any
                            builtModifiedTime = None
                            raise Exceptions.IncorrectTypeException(
                                incorrectValue,
                                "Root[%s]" % ManifestBuiltModifiedTimeKey,
                                (dict, ))

                        if ManifestBuiltFileNamesKey in manifest:
                            builtFileNames = manifest[
                                ManifestBuiltFileNamesKey]

                        if not isinstance(builtFileNames, list):
                            incorrectValue = builtFileNames  # type: typing.Any
                            builtFileNames = list()
                            raise Exceptions.IncorrectTypeException(
                                incorrectValue,
                                "Root[%s]" % ManifestBuiltFileNamesKey,
                                (dict, ))

                        for builtFileNameIndex in range(
                                len(builtFileNames)):  # type: int
                            builtFileName = builtFileNames[
                                builtFileNameIndex]  # type: str

                            if not isinstance(builtFileName, str):
                                builtFileNames = list()
                                raise Exceptions.IncorrectTypeException(
                                    builtFileName, "Root[%s][%s]" %
                                    (ManifestBuiltFileNamesKey,
                                     builtFileNameIndex), (dict, ))

                except Exception as e:
                    print("Failed to read STBL manifest file at '" +
                          manifestFilePath + "'\n" + str(e),
                          file=sys.stderr)

                missingBuiltFile = False  # type: bool

                for builtFileName in builtFileNames:
                    builtFilePath = os.path.join(
                        os.path.join(package.SourceLoosePath, "STBL"),
                        builtFileName)  # type: str

                    if not os.path.exists(builtFilePath):
                        missingBuiltFile = True
                        break

                if missingBuiltFile or modifiedTime != builtModifiedTime:
                    buildTempDirectory = stblXMLFilePath + "_Temp_Build"  # type: str

                    if not os.path.exists(buildTempDirectory):
                        os.makedirs(buildTempDirectory)

                    try:
                        STBL.BuildSTBL(buildTempDirectory, stblXMLFilePath)

                        manifest = dict()  # type: typing.Dict[str, typing.Any]

                        manifest[ManifestBuiltModifiedTimeKey] = modifiedTime
                        builtFileNames = list()

                        for builtFileName in os.listdir(buildTempDirectory):
                            builtFilePath = os.path.join(
                                buildTempDirectory, builtFileName)

                            if os.path.isfile(builtFilePath):
                                builtFileNames.append(builtFileName)

                        manifest[ManifestBuiltFileNamesKey] = builtFileNames

                        with open(manifestFilePath, "w+") as manifestFile:
                            manifestFile.write(
                                json.JSONEncoder(indent="\t").encode(manifest))

                        dir_util.copy_tree(
                            buildTempDirectory,
                            os.path.join(package.SourceLoosePath, "STBL"))
                    finally:
                        shutil.rmtree(buildTempDirectory)

    return True