Пример #1
0
    def setValue(self, value):
        """
		Verändert den Wert der Eigenschaft.
		"""

        if self.__value != value:
            self.__value = value
            Debug.debug("Ändere Eigenschaft {} zu {}".format(self.name, self.__value), level=3)
            self.valueChanged.emit(self.__value)
            self.traitChanged.emit(self)
Пример #2
0
    def setValue(self, value):
        """
		Verändert den Wert der Eigenschaft.
		"""

        if self.__value != value:
            self.__value = value
            Debug.debug("Ändere Eigenschaft {} zu {}".format(
                self.name, self.__value),
                        level=3)
            self.valueChanged.emit(self.__value)
            self.traitChanged.emit(self)
    def read(self):
        """
		Diese Methode startet den Lesevorgang.

		Es wird kontrolliert, ob es sich um eine Zuässige Template-Datei für dieses Programm handelt

		\exception ErrXmlTooOldVersion Die XML-Datei hat die falsche Version.

		\exception ErrXmlOldVersion Die XML-Datei hat die falsche Version.

		\exception ErrXmlParsing Beim Parsen der XML-Datei ist ein Fehler aufgetreten.
		"""

        #dbgStart = Debug.timehook()
        for item in self.__templateFiles:
            Debug.debug("Reading from file \"{}\".".format(item), level=2)
            file_content = None
            with open(item, mode="rb") as fi:
                file_content = fi.read()

            ## Erzeuge eine temporäre Datei, mit der etree umgehen kann und schreibe den Inhalt aus der Qt-Resource in selbige hinein.
            file_like = tempfile.SpooledTemporaryFile()
            ## Dank dieser Einstellung kann ich zlib verwenden um Dateien zu dekomprimieren, welche mittels des gzip-Moduls komprimiert wurden.
            decompressed_object = zlib.decompressobj(16 + zlib.MAX_WBITS)
            file_like.write(decompressed_object.decompress(file_content))
            file_like.seek(0)

            xml_content = etree.parse(file_like)
            file_like.close()

            xml_root_element = xml_content.getroot()

            version_source = xml_root_element.attrib["version"]
            required_source = False
            if "required" in xml_root_element.attrib:
                required_source = xml_root_element.attrib["required"].lower(
                ) == "true"
            #Debug.debug(versionSource)

            try:
                self.checkXmlVersion(xml_root_element.tag,
                                     version_source,
                                     item,
                                     required=required_source)
            except ErrXmlOldVersion as e:
                text_description = self.tr(
                    "{} Loading of template will be continued but errors may occur."
                    .format(str(e)))
                self.exception_raised.emit(text_description, "warning")

            result = self.readSpecies(xml_content)
            self.readTemplate(xml_content, result[0], result[1])
Пример #4
0
	def checkXmlVersion(self, name, version, filename=None, required=False ):
		"""
		Überprüft die Version der XML-Datei. Damit ist die SoulCreator-Version gemeint.

		\param required Für den Betrieb des Programms erfordelriche Dateien sorgen dafür, daß das Programm einen entsprechend ernsten Fehler ausgibt.
		"""

		Debug.debug( "Version of file \"{name_file}\": {name} {version}".format(
			name_file=filename,
			name=name,
			version=version,
		), level=3 )

		if name == Config.PROGRAM_NAME:
			if version == Config.version():
				return
			else:
				# Unterschiede in der Minor-Version sind ignorierbar, Unterschiede in der Major-Version allerdings nicht.
				version_split = version.split(".")
				version_split = [ int(item) for item in version_split ]

				if filename is not None:
					filename = os.path.basename(filename)
				if version_split[0] < Config.PROGRAM_VERSION["major"]:
					raise Error.ErrXmlVersion(
						"XML-file \"{filename}\" was created with {program_name} {file_version} and is incompatible with {program_name} {program_version}.\nLoading of file aborted.".format(
							filename=filename,
							file_version=version,
							program_name=Config.PROGRAM_NAME,
							program_version=Config.version()
						),
						got=version,
						critical=required
					)
				else:
					raise Error.ErrXmlOldVersion(
						"XML-file \"{filename}\" was created with {program_name} {file_version} and may be compatible with {program_name} {program_version}.".format(
							filename=filename,
							file_version=version,
							program_name=Config.PROGRAM_NAME,
							program_version=Config.version()
						),
						got=version,
						critical=required
					)
		else:
			raise Error.ErrXmlVersion(
				got="{} {}".format(name, version),
				expected="{} {}".format(Config.PROGRAM_NAME, Config.version()),
				critical=required
			)
Пример #5
0
	def readCharacterIdentity(self, tree):
		"""
		Lese die Identitäten des Charkaters aus.

		\note Derzeit gibt es nur eine. forenames="" surname="" honorname="" nickname="" supername="" gender="Male"
		"""

		identity = tree.find("identities/identity")
		if identity is not None:
			self.__character.identity.forenames = self.getElementAttribute(identity, "forenames").split(" ")
			self.__character.identity.surname = self.getElementAttribute(identity, "surname")
			self.__character.identity.honorname = self.getElementAttribute(identity, "honorname")
			self.__character.identity.nickname = self.getElementAttribute(identity, "nickname")
			self.__character.identity.supername = self.getElementAttribute(identity, "supername")
			self.__character.identity.gender = self.getElementAttribute(identity, "gender")
		else:
			Debug.debug( "No identity of the character found.", level=3 )
	def read(self):
		"""
		Diese Methode startet den Lesevorgang.

		Es wird kontrolliert, ob es sich um eine Zuässige Template-Datei für dieses Programm handelt

		\exception ErrXmlTooOldVersion Die XML-Datei hat die falsche Version.

		\exception ErrXmlOldVersion Die XML-Datei hat die falsche Version.

		\exception ErrXmlParsing Beim Parsen der XML-Datei ist ein Fehler aufgetreten.
		"""

		#dbgStart = Debug.timehook()
		for item in self.__templateFiles:
			Debug.debug( "Reading from file \"{}\".".format(item), level=2 )
			file_content = None
			with open(item, mode="rb") as fi:
				file_content = fi.read()

			## Erzeuge eine temporäre Datei, mit der etree umgehen kann und schreibe den Inhalt aus der Qt-Resource in selbige hinein.
			file_like = tempfile.SpooledTemporaryFile()
			## Dank dieser Einstellung kann ich zlib verwenden um Dateien zu dekomprimieren, welche mittels des gzip-Moduls komprimiert wurden.
			decompressed_object = zlib.decompressobj(16 + zlib.MAX_WBITS)
			file_like.write(decompressed_object.decompress(file_content))
			file_like.seek(0)

			xml_content = etree.parse(file_like)
			file_like.close()

			xml_root_element = xml_content.getroot()

			version_source = xml_root_element.attrib["version"]
			required_source = False
			if "required" in xml_root_element.attrib:
				required_source = xml_root_element.attrib["required"].lower() == "true"
			#Debug.debug(versionSource)

			try:
				self.checkXmlVersion( xml_root_element.tag, version_source, item, required=required_source )
			except ErrXmlOldVersion as e:
				text_description = self.tr( "{} Loading of template will be continued but errors may occur.".format( str( e ) ) )
				self.exception_raised.emit( text_description, "warning" )

			result = self.readSpecies(xml_content)
			self.readTemplate(xml_content, result[0], result[1])
Пример #7
0
	def read( self, file_name ):
		"""
		Startet den Lesevorgang.

		\note Diese Funktion kann sowohl normale xml-Dateien als auch mittels gzip komprimierte xml-Dateien laden.
		"""

		Debug.debug( "Loading Character out of {}.".format(file_name) )

		## Mittels lxml kann diese Funktion normale XML-Dateien und offenbar auch mittels gzip komprimierte XML-Dateien laden.
		## Das normale ElementTree-Modul kann das aber nicht.
		xml_content = None
		try:
			xml_content = etree.parse(file_name)
		except etree.ParseError:
			## Möglicherweise eine komprimierte Datei und lxml wurde nicht verwendet?
			xml_content = etree.parse(gzip.GzipFile(file_name))
		xmlRootElement = xml_content.getroot()

		versionSource = xmlRootElement.attrib["version"]

		try:
			self.checkXmlVersion( xmlRootElement.tag, versionSource, file_name )
		except ErrXmlOldVersion as e:
			text_description = self.tr( "{} Loading will be continued but errors may occur.".format( str( e ) ) )
			self.exception_raised.emit( text_description, "warning" )

		## Die Daten müssen zuerst geladen werden, damit schon beim Laden die Unterschiedung zwischen Kindern und Erwachsenen erfolgen kann.
		self.readDates(xml_content)
		self.readCharacterInfo(xml_content)
		self.readCharacterIdentity(xml_content)
		self.readDerangements(xml_content)
		self.readTraits(xml_content)
		self.readItems(xml_content)
		self.readSpeciesSpecials(xml_content)
		self.readPicture(xml_content)
Пример #8
0
def _do_connect(trait, storage, character):
	"""
	Durchsucht alle existierenden Eigenschaften und kontrolliert, ob sie als Voraussetzung für <trait> in Frage kommen.
	"""

	trait_prerequisites = trait.prerequisitesText
	Debug.debug(
		"Voraussetzungen von {trait}: {prerequisite}".format(trait=trait.name, prerequisite=trait_prerequisites),
		level=4,
	)
	stop_loop = False
	for prerequisite_typ in storage.traits.keys():
		## Angabe in den Ressourcen: <typ>.<trait>[.<specialty>]
		typ_resource = "{}.".format(prerequisite_typ)
		## Ist eine Eigenschaft diesen Typs eine Voraussetzung der Eigenschaft?
		if typ_resource in trait_prerequisites:
			#Debug.debug("{trait} hat {typ} als Voraussetzung!".format(trait=trait.name, typ=item))
			for prerequisite_category in storage.categories(prerequisite_typ):
				for prerequisite_trait in character.traits[prerequisite_typ][prerequisite_category].values():
					## Überprüfen ob die Eigenschaft im Anforderungstext des Merits vorkommt.
					trait_resource = "{}.{}".format(prerequisite_typ, prerequisite_trait.identifier)
					if trait_resource in trait_prerequisites:
						# Überprüfen ob diese Eigenschaft tatsächlich in den Voraussetzungen enthalten ist. Bei dieser Überprüfung ist es wichtig, auf den ganuen Namen zu prüfen: "Status" != "Status: Camarilla"
						# Diese Überprüfung wird aber nur durchgeführt, wenn die Chance besteht, daß dieser String identisch ist.
						match_list = re.findall(r"(\w+\.[\w]+[:\s]*[\w]+)(?=[\s]*[><=.]+)", trait_prerequisites, re.UNICODE)
						if trait_resource in match_list:
							stop_loop = _create_connection( trait, prerequisite_trait, trait_prerequisites, trait_resource )
							if stop_loop:
								return
	if not stop_loop:
		## Es kann auch die Supereigenschaft als Voraussetzung vorkommen ...
		if Config.POWERSTAT_IDENTIFIER in trait_prerequisites:
			character.powerstatChanged.connect(trait.checkPrerequisites)
		## ... oder die Moral
		if Config.MORALITY_IDENTIFIER in trait_prerequisites:
			character.moralityChanged.connect(trait.checkPrerequisites)
Пример #9
0
def checkPrerequisites(trait, storage, character):
	if not isinstance(trait, BasicTrait):
		Debug.debug("Error!")
	else:
		if trait.hasPrerequisites and trait.prerequisiteTraits:
			## Angabe in den Ressourcen: <typ>.<trait>[.<specialty>] >|<|== ? and|or ...
			## Diese werden aufgeteilt in [[ <typ>, <trait>, <specialty> ] >|<|== ? and|or ... ]
			traitPrerequisites = trait.prerequisitesText
			#Debug.debug("{trait} hat Voraussetzungen? {truth}".format(trait=trait.name, truth=trait.hasPrerequisites))
			for item in trait.prerequisiteTraits:
				# Überprüfen, ob die Eigenschaft im Anforderungstext des Merits vorkommt.
				literalReference = "ptr{}".format(id(item))
				if literalReference in traitPrerequisites:
					## Spezialisierungen
					literalReferencePlusSpecial = "{}.".format(literalReference)
					if literalReferencePlusSpecial in traitPrerequisites:
						idx = traitPrerequisites.index(literalReferencePlusSpecial)
						#traitWithSpecial = re.search(r"\w+\.{1}(\w+)", traitPrerequisites[idx:])
						#special = traitWithSpecial.group(1)
						specialties = re.findall(r"\w+\.{1}(\w+)", traitPrerequisites[idx:])
						for special in specialties:
							if special in item.specialties:
								traitPrerequisites = traitPrerequisites.replace(".{}".format(special), "")
							else:
								traitPrerequisites = traitPrerequisites.replace("{}.{}".format(literalReference, special), "0")
					traitPrerequisites = traitPrerequisites.replace(literalReference, str(item.value))
			# Es kann auch die Supereigenschaft als Voraussetzung vorkommen ...
			if Config.POWERSTAT_IDENTIFIER in traitPrerequisites:
				traitPrerequisites = traitPrerequisites.replace(Config.POWERSTAT_IDENTIFIER, str(character.powerstat))
			# ... oder die Moral
			if Config.MORALITY_IDENTIFIER in traitPrerequisites:
				traitPrerequisites = traitPrerequisites.replace(Config.MORALITY_IDENTIFIER, str(character.morality))

			# Die Voraussetzungen sollten jetzt nurnoch aus Zahlen und logischen Operatoren bestehen.
			## eval() is dangerous
			## Aber ast.literal_eval() erlaubt nicht das Auswerten von "a < b" etc.
			## Es werden ausschließlich Zahlen, Klammern "(" und ")" und die Zeichen "<" "<=" ">" ">=" "==" und "!=" sowie den logischen Verknüpfungen "and" und "or" erlaubt.
			#traitPrerequisites = "1 < 2 and 2 < 3"
			if re.match( r"^(\(*\d+\s*[<>=!]+\s*\d+\)*\s*(and|or)?\s*)+$", traitPrerequisites ):
				try:
					result = eval(traitPrerequisites)
					#Debug.debug("Eigenschaft {} ({} = {})".format(trait.name, traitPrerequisites, result))
				except (NameError, SyntaxError):
					Debug.debug("Error bei {}: {}".format(trait.name, traitPrerequisites))
					result = False
			else:
				raise ValueError("Only digits, spaces and the symbols \"<\", \">\", \"=\", \"!\", \"(\" and \")\" are allowed at this point.")

			Debug.debug( "Eigenschaft \"{}\" wird verfügbar? {}!".format(trait.name, result), level=4 )
			trait.setAvailable(result)
	def writeFile(self, tree, file_name):
		"""
		Schreibt den Elementbaum in eine Datei.

		Die Charaktere können als komprimierte Datei gespeichert werden, wenn dies in den Einstellungen so festgelegt wird.
		"""

		_character_data = None
		if lxmlLoadad:
			Debug.debug( "Using the advanced lxml-module to write the XML-tree." )
			_character_data = etree.tostring(tree, pretty_print=True, encoding="UTF-8", xml_declaration=True)
		else:
			Debug.debug( "Using the basic xml.etree.ElementTree-module to write the XML-tree." )
			_character_data = etree.tostring(tree, encoding="unicode")

		## In die Datei schreiben.
		if Config.compress_saves:
			Debug.debug( "Writing character into {} (compressed).".format(file_name) )
			with gzip.open(file_name, "w") as file_object:
				file_object.write(bytes(_character_data, "UTF-8"))
		else:
			Debug.debug( "Writing character into {} (uncompressed).".format(file_name) )
			with open(file_name, "w") as file_object:
				file_object.write(_character_data)