Beispiel #1
0
	def __init__ (self, namespace: str):
		self.Namespace = namespace  # type: str
		self.Path = GetSitePath(namespace)  # type: str

		try:
			self.Module = _GetSiteModule(namespace)  # type: typing.Optional
		except Exception as e:
			if type(e) is not ModuleNotFoundError:
				print("Failed to import site module for '" + self.Namespace + "'\n" + Exceptions.FormatException(e), file = sys.stderr)

			self.Module = None  # type: typing.Optional

		self.Data = _GetSiteData(self.Module)  # type: typing.Dict[str, typing.Any]

		try:
			self.BuildModule = _GetBuildModule(namespace) # type: typing.Optional
		except Exception as e:
			if type(e) is not ModuleNotFoundError:
				print("Failed to import site build module for '" + self.Namespace + "'\n" + Exceptions.FormatException(e), file = sys.stderr)

			self.BuildModule = None  # type: typing.Optional

		self._buildFunction = _GetBuildFunction(self.BuildModule)  # type: typing.Optional[typing.Callable[[], bool]]
		self._buildPublishingFunction = _GetBuildPublishingFunction(self.BuildModule)  # type: typing.Optional[typing.Callable[[], bool]]

		_sites.append(self)
Beispiel #2
0
    def __init__(self, namespace: str):
        self.Namespace = namespace  # type: str
        self.Path = GetModPath(namespace)  # type: str

        self.ReleaseLatest = Distribution.GetReleaseLatest(
            namespace)  # type: typing.Optional[Distribution.ModVersion]
        self.ReleaseVersions = Distribution.GetReleaseVersions(
            namespace
        )  # type: typing.Optional[typing.List[Distribution.ModVersion]]

        self.PreviewLatest = Distribution.GetPreviewLatest(
            namespace)  # type: typing.Optional[Distribution.ModVersion]
        self.PreviewVersions = Distribution.GetPreviewVersions(
            namespace
        )  # type: typing.Optional[typing.List[Distribution.ModVersion]]

        self.Game = "The Sims 4"  # type: str #TODO actually get the game for each mod.
        self.GameShortened = "S4"  # type: str # Used in website page paths

        try:
            self.Module = _GetModModule(namespace)  # type: typing.Optional
        except Exception as e:
            if type(e) is not ModuleNotFoundError:
                print("Failed to import mod module for '" + self.Namespace +
                      "'\n" + Exceptions.FormatException(e),
                      file=sys.stderr)

            self.Module = None  # type: typing.Optional

        self.Data = _GetModData(
            self.Module)  # type: typing.Dict[str, typing.Any]

        try:
            self.BuildModule = _GetBuildModule(
                namespace)  # type: typing.Optional
        except Exception as e:
            if type(e) is not ModuleNotFoundError:
                print("Failed to import mod build module for '" +
                      self.Namespace + "'\n" + Exceptions.FormatException(e),
                      file=sys.stderr)

            self.BuildModule = None  # type: typing.Optional

        self._buildFunction = _GetBuildFunction(
            self.BuildModule
        )  # type: typing.Optional[typing.Callable[[str], bool]]
        self._buildPublishingFunction = _GetBuildPublishingFunction(
            self.BuildModule
        )  # type: typing.Optional[typing.Callable[[], bool]]

        _mods.append(self)
Beispiel #3
0
	def Build (self, value: typing.Tuple[typing.Union[int, str], ...]) -> None:
		if not isinstance(value, tuple):
			raise Exceptions.IncorrectTypeException(value, "Build", (tuple,))

		for buildIdentifierIndex in range(len(value)):  # type: int
			buildIdentifier = value[buildIdentifierIndex]  # type: typing.Union[str, int]

			if not isinstance(buildIdentifier, (str, int)):
				raise Exceptions.IncorrectTypeException(value, "PreRelease[%s]" % buildIdentifierIndex, (str, int))

			if isinstance(buildIdentifier, str):
				if not self.ValidStringIdentifier(buildIdentifier):
					raise ValueError("'PreRelease[%s]' contains a character outside what is allowed (0-9, A-Z, a-z, or -).\nValue: %s" % (buildIdentifierIndex, buildIdentifier))

		self._build = value
Beispiel #4
0
	def ValidStringIdentifier (cls, identifier: str) -> bool:
		"""
		Get whether or not a pre-release or build string identifier is valid. An identifier is invalid if it contains a character outside what is permitted
		(0-9, A-Z, a-z, or -).
		"""

		if not isinstance(identifier, str):
			raise Exceptions.IncorrectTypeException(identifier, "identifier", (str,))

		if re.match(cls.StringIdentifierPattern, identifier) is None:
			return False

		return True
Beispiel #5
0
	def IsValid (cls, versionString: str) -> bool:
		"""
		Get whether or not the input version string is valid.
		:param versionString: A string containing a valid or invalid version number.
		:type versionString: str
		"""

		if not isinstance(versionString, str):
			raise Exceptions.IncorrectTypeException(versionString, "versionString", (str,))

		match = cls.ParsePattern.match(versionString)

		return bool(match)
Beispiel #6
0
	def __init__ (self, versionString: typing.Optional[str] = None, translate: bool = False):
		"""
		A version system based on semantic versioning specification. https://semver.org/
		:param versionString: A string containing a valid version. Invalid inputs will produce exceptions. Letting this be none will cause the version object to
		default to '0.0.0'.
		:type versionString: typing.Optional[str]
		:param translate: Whether or not we should try to translate a version number if we cannot parse it initially.
		:type translate: bool
		"""

		if not isinstance(versionString, str) and versionString is not None:
			raise Exceptions.IncorrectTypeException(versionString, "versionString", (str, None))

		self.Major = 0
		self.Minor = 0
		self.Patch = 0
		self.PreRelease = ()
		self.Build = ()

		if versionString is not None:
			self.Apply(*self.Parse(versionString, translate = translate))
Beispiel #7
0
	def Patch (self, value: int) -> None:
		if not isinstance(value, int):
			raise Exceptions.IncorrectTypeException(value, "Patch", (int,))

		self._patch = value
Beispiel #8
0
	def Minor (self, value: int) -> None:
		if not isinstance(value, int):
			raise Exceptions.IncorrectTypeException(value, "Minor", (int,))

		self._minor = value
Beispiel #9
0
	def Translate (cls, versionString: str) -> str:
		"""
		Try to translate a version string of another type to one that is inline with the semantic versioning specification.
		An exception will be raised if we could not translate if to a valid format.
		"""

		if not isinstance(versionString, str):
			raise Exceptions.IncorrectTypeException(versionString, "versionString", (str,))

		preReleaseStartIndex = versionString.find("-")  # type: typing.Optional[int]
		preReleaseStartIndex = None if preReleaseStartIndex == -1 else preReleaseStartIndex

		buildStartIndex = versionString.find("+")  # type: typing.Optional[int]
		buildStartIndex = None if buildStartIndex == -1 else buildStartIndex

		if buildStartIndex is not None and preReleaseStartIndex is not None:
			if buildStartIndex <= preReleaseStartIndex:  # Pre-release identifiers cannot come after the build meta data. The hyphen we found is just part of the build meta data.
				preReleaseStartIndex = None

		if preReleaseStartIndex is not None:
			mainPart = versionString[0:preReleaseStartIndex]  # type: str
		elif buildStartIndex is not None:
			mainPart = versionString[0:buildStartIndex]  # type: str
		else:
			mainPart = versionString

		if not mainPart:
			raise ValueError("Could not find at least a major version number in '%s'." % versionString)

		preReleasePart = versionString[preReleaseStartIndex + 1:buildStartIndex] if preReleaseStartIndex is not None else ""  # type: str
		buildPart = versionString[buildStartIndex + 1:None] if buildStartIndex is not None else ""  # type: str

		mainPartIdentifiers = mainPart.split(".")  # type: typing.List[str]

		if len(mainPartIdentifiers) > 3:
			# Too many identifiers in the main part, these will be booted to the front of the build meta data. All semantic version numbers can only have major, minor, and patch numbers in their main sections.

			mainPartExtraIdentifiers = mainPartIdentifiers[3:]

			if buildPart:
				buildPart = ".".join(mainPartExtraIdentifiers) + "." + buildPart
			else:
				buildPart = ".".join(mainPartExtraIdentifiers)

			mainPartIdentifiers = mainPartIdentifiers[:3]
			assert len(mainPartIdentifiers) == 3

		elif len(mainPartIdentifiers) < 3:
			# Too few identifiers in the main part, we need to add at least one. All semantic version numbers must have major, minor, and patch numbers.

			mainPartMissingIdentifiers = 3 - len(mainPartIdentifiers)  # type: int

			for _ in range(mainPartMissingIdentifiers):
				mainPartIdentifiers.append("0")

			assert len(mainPartIdentifiers) == 3

		mainPart = ".".join(mainPartIdentifiers)

		buildPart = buildPart.replace("+", ".")  # Replace extra plus signs in the build meta data part. More than one plus sign in a version string will cause errors.

		translatedVersionString = ""

		if mainPart:
			translatedVersionString += mainPart

		if preReleasePart:
			translatedVersionString += "-" + preReleasePart

		if buildPart:
			translatedVersionString += "+" + buildPart

		if not cls.IsValid(translatedVersionString):
			raise ValueError("Could not translate '%s' to a valid version number." % versionString)

		return translatedVersionString
Beispiel #10
0
	def Parse (cls, versionString: str, translate: bool = False) -> typing.Tuple[int, int, int, typing.Tuple[typing.Union[int, str], ...], typing.Tuple[typing.Union[int, str], ...]]:
		"""
		Parse a version string to get its major, minor, patch, pre-release and build metadata values placed in a tuple in that order.
		:param versionString: A string containing a valid version. Invalid inputs will produce exceptions.
		:type: str
		:param translate: Whether or not we should try to translate a version number if we cannot parse it initially.
		:type translate: bool
		"""

		if not isinstance(versionString, str):
			raise Exceptions.IncorrectTypeException(versionString, "versionString", (str,))

		match = cls.ParsePattern.match(versionString)  # type: typing.Optional[typing.Match]

		if translate:
			try:
				translatedVersionString = cls.Translate(versionString)
			except Exception as e:
				raise ValueError("Could not parse or translate the version string '%s'." % versionString) from e

			match = cls.ParsePattern.match(translatedVersionString)  # type: typing.Optional[typing.Match]

			if not match:
				raise ValueError("Could not parse or translate the version string '%s'." % versionString)
		else:
			if not match:
				raise ValueError("Could not parse the version string '%s'." % versionString)

		(majorString, minorString, patchString, preReleaseString, buildString) = match.groups()  # type: str

		major = int(majorString)  # type: int
		minor = int(minorString)  # type: int
		patch = int(patchString)  # type: int

		if preReleaseString:
			preReleaseIdentifiers = preReleaseString.split(".")  # type: typing.List[str]
			preRelease = ()  # type: typing.Tuple[typing.Union[int, str], ...]

			for preReleaseIdentifier in preReleaseIdentifiers:  # type: str
				try:
					preRelease += (int(preReleaseIdentifier),)
					continue
				except:
					pass

				preRelease += (preReleaseIdentifier,)
		else:
			preRelease = ()  # type: typing.Tuple[typing.Union[int, str], ...]

		if buildString:
			buildIdentifiers = buildString.split(".")  # type: typing.List[str]
			build = ()  # type: typing.Tuple[typing.Union[int, str], ...]

			for buildIdentifier in buildIdentifiers:  # type: str
				try:
					build += (int(buildIdentifier),)
					continue
				except:
					pass

				build += (buildIdentifier,)
		else:
			build = ()  # type: typing.Tuple[typing.Union[int, str], ...]

		return major, minor, patch, preRelease, build