Adding an imported product

Currently products can be imported only from files, thus any imported product should derive from ImportedFileProduct:

from runmacs.processor.product import ImportedFileProduct

class NewImportedProduct(ImportedFileProduct):
    pass

Every product should specify its productType, additionally, every imported file product must implement a fromFilename classmethod, which is supposed to return a new instance of the new imported product, if the filename belongs to a file which actually can be represented using this product. It the file can not be represented by this product, the classmethod should raise a ValueError. Most likely, the product needs to store some information about the data location in the instance as well:

class NewImportedProduct(ImportedFileProduct):
    productType = "my_new_product"
    @classmethod
    def fromFilename(cls, filename, place, accessor):
        if not filename.endswith(".mydata"):
            raise ValueError("invalid file")
        instance = cls()
        instance._accessor = accessor
        instance.place = place
        instance.filename = filename
        return instance

Additionally, every imported product must implement _hash(self), which is supposed to return a unique hash value computed from the contents of the file. The Product baseclass provides a defaulthash method to help implementing this:

class NewImportedProduct(ImportedFileProduct):
    ...
    def _hash(self):
        contents = self._accessor.files.getFileData(self.place, self.filename)
        return self.defaulthash(contents).hexdigest()