Note
This module is based on wz’s NifTester module, although nothing of wz’s original code is left in this module.
A toaster, implemented by subclasses of the abstract Toaster class, walks over all files in a folder, and applies one or more transformations on each file. Such transformations are called spells, and are implemented by subclasses of the abstract Spell class.
A spell can also run independently of a toaster and be applied on a branch directly. The recommended way of doing this is via the Spell.recurse() method.
For format specific spells, refer to the corresponding module.
Some spells are applicable on every file format, and those are documented here.
Bases: pyffi.spells.Spell
A spell for applying a patch on files.
There is no need to read the whole file, so we apply the patch already at inspection stage, and stop the spell process by returning False.
| Returns: | False |
|---|---|
| Return type: | bool |
To create new spells, derive your custom spells from the Spell class, and include them in the Toaster.SPELLS attribute of your toaster.
Bases: object
Spell base class. A spell takes a data file and then does something useful with it. The main entry point for spells is recurse(), so if you are writing new spells, start with reading the documentation with recurse().
Initialize the spell data.
| Parameters: |
|---|
Helper function which calls _branchinspect() and branchinspect() on the branch, if both successful then branchentry() on the branch, and if this is succesful it calls recurse() on the branch’s children, and once all children are done, it calls branchexit().
Note that _branchinspect() and branchinspect() are not called upon first entry of this function, that is, when called with data as branch argument. Use datainspect() to stop recursion into this branch.
Do not override this function.
| Parameter: | branch (GlobalNode) – The branch to start the recursion from, or None to recurse the whole tree. |
|---|
This is called after pyffi.object_models.FileFormat.Data.inspect() has been called, and before pyffi.object_models.FileFormat.Data.read() is called.
| Returns: | True if the file must be processed, False otherwise. |
|---|---|
| Return type: | bool |
This is called after pyffi.object_models.FileFormat.Data.inspect() has been called, and before pyffi.object_models.FileFormat.Data.read() is called. Override this function for customization.
| Returns: | True if the file must be processed, False otherwise. |
|---|---|
| Return type: | bool |
Check if spell should be cast on this branch or not, based on exclude and include options passed on the command line. You should not need to override this function: if you need additional checks on whether a branch must be parsed or not, override the branchinspect() method.
| Parameter: | branch (GlobalNode) – The branch to check. |
|---|---|
| Returns: | True if the branch must be processed, False otherwise. |
| Return type: | bool |
Like _branchinspect(), but for customization: can be overridden to perform an extra inspection (the default implementation always returns True).
| Parameter: | branch (GlobalNode) – The branch to check. |
|---|---|
| Returns: | True if the branch must be processed, False otherwise. |
| Return type: | bool |
Called before all blocks are recursed. The default implementation simply returns True. You can access the data via data, and unlike in the datainspect() method, the full file has been processed at this stage.
Typically, you will override this function to perform a global operation on the file data.
| Returns: | True if the children must be processed, False otherwise. |
|---|---|
| Return type: | bool |
Called after all blocks have been processed, if dataentry() returned True.
Typically, you will override this function to perform a final spell operation, such as writing back the file in a special way, or making a summary log.
Cast the spell on the given branch. First called with branch equal to data‘s children, then the grandchildren, and so on. The default implementation simply returns True.
Typically, you will override this function to perform an operation on a particular block type and/or to stop recursion at particular block types.
| Parameter: | branch (GlobalNode) – The branch to cast the spell on. |
|---|---|
| Returns: | True if the children must be processed, False otherwise. |
| Return type: | bool |
Cast a spell on the given branch, after all its children, grandchildren, have been processed, if branchentry() returned True on the given branch.
Typically, you will override this function to perform a particular operation on a block type, but you rely on the fact that the children must have been processed first.
| Parameter: | branch (GlobalNode) – The branch to cast the spell on. |
|---|
Called just before the toaster starts processing all files. If it returns False, then the spell is not used. The default implementation simply returns True.
For example, if the spell only acts on a particular block type, but that block type is excluded, then you can use this function to flag that this spell can be skipped. You can also use this function to initialize statistics data to be aggregated from files, to initialize a log file, and so.
| Parameter: | toaster (Toaster) – The toaster this spell is called from. |
|---|---|
| Returns: | True if the spell applies, False otherwise. |
| Return type: | bool |
It is also possible to create composite spells, that is, spells that simply execute other spells. The following functions and classes can be used for this purpose.
Bases: pyffi.spells.Spell
Base class for grouping spells. This implements all the spell grouping functions that fall outside of the actual recursing (__init__(), toastentry(), _datainspect(), datainspect(), and toastexit()).
Bases: pyffi.spells.SpellGroupBase
Base class for running spells in parallel (that is, with only a single recursion in the tree).
To create a new toaster script, derive your toaster from the Toaster class, and set the Toaster.FILEFORMAT attribute of your toaster to the file format class of the files it can toast.
Bases: object
Toaster base class. Toasters run spells on large quantities of files. They load each file and pass the data structure to any number of spells.
The file format class (a subclass of FileFormat).
alias of FileFormat
Helper function which checks whether a given branch type should have spells cast on it or not, based in exclude and include options.
>>> from pyffi.formats.nif import NifFormat
>>> class MyToaster(Toaster):
... FILEFORMAT = NifFormat
>>> toaster = MyToaster() # no include or exclude: all admissible
>>> toaster.isadmissiblebranchtype(NifFormat.NiProperty)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiNode)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiAVObject)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiLODNode)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiMaterialProperty)
True
>>> toaster = MyToaster(options={"exclude": ["NiProperty", "NiNode"]})
>>> toaster.isadmissiblebranchtype(NifFormat.NiProperty)
False
>>> toaster.isadmissiblebranchtype(NifFormat.NiNode)
False
>>> toaster.isadmissiblebranchtype(NifFormat.NiAVObject)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiLODNode)
False
>>> toaster.isadmissiblebranchtype(NifFormat.NiMaterialProperty)
False
>>> toaster = MyToaster(options={"include": ["NiProperty", "NiNode"]})
>>> toaster.isadmissiblebranchtype(NifFormat.NiProperty)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiNode)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiAVObject)
False
>>> toaster.isadmissiblebranchtype(NifFormat.NiLODNode) # NiNodes are!
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiMaterialProperty) # NiProperties are!
True
>>> toaster = MyToaster(options={"include": ["NiProperty", "NiNode"], "exclude": ["NiMaterialProperty", "NiLODNode"]})
>>> toaster.isadmissiblebranchtype(NifFormat.NiProperty)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiNode)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiAVObject)
False
>>> toaster.isadmissiblebranchtype(NifFormat.NiLODNode)
False
>>> toaster.isadmissiblebranchtype(NifFormat.NiSwitchNode)
True
>>> toaster.isadmissiblebranchtype(NifFormat.NiMaterialProperty)
False
>>> toaster.isadmissiblebranchtype(NifFormat.NiAlphaProperty)
True
Write log message with logger.info(), taking into account indent.
| Parameter: | message (str) – The message to write. |
|---|
Walk over all files in a directory tree and cast spells on every file.
| Parameter: | top (str) – The directory or file to toast. |
|---|