Example #1
0
    def check_link_ov_asset(self, asset, essence):
        """ VF package shall reference assets present in OV.

            Reference : N/A
        """
        if not self.ov_dcp:
            return

        ov_dcp_dict = self.ov_dcp.parse()

        if not asset.get('Path'):
            uuid = asset['Id']
            path_ov = ov_dcp_dict['asset_list'].get(uuid)

            if not path_ov:
                raise CheckException(
                    "Asset missing ({}) from OV : {}".format(essence, uuid))

            asset_path = os.path.join(self.ov_dcp.path, path_ov)
            if not os.path.exists(asset_path):
                raise CheckException(
                    "Asset missing ({}) from OV (MXF not found) : {}"
                    "".format(essence, path_ov))

            # Probe asset for later checks
            asset['AbsolutePath'] = asset_path
            cpl_probe_asset(asset, essence, asset_path)
Example #2
0
    def check_link_ov_coherence(self):
        """ Relink OV/VF sanity checks. """
        if self.ov_path and self.dcp.package_type != 'VF':
            raise CheckException("Package checked must be a VF")

        from clairmeta.dcp import DCP
        self.ov_dcp = DCP(self.ov_path)
        self.ov_dcp.parse()
        if self.ov_dcp.package_type != 'OV':
            raise CheckException("Package referenced must be a OV")
Example #3
0
    def check_dcp_multiple_am_or_vol(self):
        """ Only one AssetMap and VolIndex shall be present. """
        restricted_lists = {
            'VolIndex': self.dcp._list_vol,
            'Assetmap': self.dcp._list_am,
        }

        for k, v in six.iteritems(restricted_lists):
            if len(v) == 0:
                raise CheckException("Missing {} file".format(k))
            if len(v) > 1:
                raise CheckException("Multiple {} files found".format(k))
Example #4
0
    def __init__(
        self, dcp, profile=get_default_profile(), ov_path=None,
        hash_callback=None
    ):
        """ DCPChecker constructor.

            Args:
                dcp (clairmeta.DCP): DCP object.
                profile (dict): Checker profile.
                ov_path (str, optional): Absolute path of OriginalVersion DCP.

        """
        super(DCPChecker, self).__init__(dcp, profile)
        self.ov_path = ov_path
        self.ov_dcp = None

        self.hash_callback = hash_callback
        if not self.hash_callback:
            pass
        elif isinstance(self.hash_callback, ConsoleProgress):
            self.hash_callback._total_size = self.dcp.size
        elif inspect.isclass(self.hash_callback):
            raise CheckException(
                "Invalid callback, please provide a function"
                " or instance of ConsoleProgress (or derivate).")

        self.check_modules = {}
        self.load_modules()
Example #5
0
 def check_dcp_hidden_files(self):
     """ Hidden files detection. """
     hidden_files = [
         os.path.relpath(f, self.dcp.path) for f in self.dcp._list_files
         if os.path.basename(f).startswith('.')
     ]
     if hidden_files:
         raise CheckException(
             "Hidden files detected : {}".format(hidden_files))
Example #6
0
    def check_link_ov_asset(self, asset, essence):
        """ VF package shall reference assets present in OV. """
        ov_dcp_dict = self.ov_dcp.parse()

        if 'Path' not in asset:
            uuid = asset['Id']
            path_ov = ov_dcp_dict['asset_list'].get(uuid)

            if not path_ov:
                raise CheckException("Missing asset from OV : {}".format(uuid))

            asset_path = os.path.join(self.ov_dcp.path, path_ov)
            if not os.path.exists(asset_path):
                raise CheckException(
                    "Missing asset from OV (MXF not found) : {}"
                    "".format(path_ov))

            # Probe asset for later checks
            asset['Path'] = asset_path
            cpl_probe_asset(asset, essence, asset_path)
Example #7
0
    def check_dcp_empty_dir(self):
        """ Empty directory detection. """
        list_empty_dir = []
        for dirpath, dirnames, filenames in os.walk(self.dcp.path):
            for d in dirnames:
                fullpath = os.path.join(dirpath, d)
                if not os.listdir(fullpath):
                    list_empty_dir.append(
                        os.path.relpath(fullpath, self.dcp.path))

        if list_empty_dir:
            raise CheckException(
                "Empty directories detected : {}".format(list_empty_dir))
Example #8
0
    def check_dcp_foreign_files(self):
        """ Foreign files detection (not listed in AssetMap). """
        list_asset_path = [
            os.path.join(self.dcp.path, a)
            for a in self.dcp._list_asset.values()
        ]
        list_asset_path += self.dcp._list_vol_path
        list_asset_path += self.dcp._list_am_path

        self.dcp.foreign_files = [
            os.path.relpath(a, self.dcp.path) for a in self.dcp._list_files
            if a not in list_asset_path
        ]
        if self.dcp.foreign_files:
            raise CheckException("Foreign files detected : {}".format(
                self.dcp.foreign_files))
Example #9
0
    def check_dcp_signed(self):
        """ DCP with encrypted content must be digitally signed. """
        if self.dcp.schema != "SMPTE":
            return

        for cpl in self.dcp._list_cpl:
            cpl_node = cpl['Info']['CompositionPlaylist']
            docs = [
                pkl['Info']['PackingList'] for pkl in self.dcp._list_pkl
                if pkl['Info']['PackingList']['Id'] == cpl_node.get('PKLId')
            ]
            docs.append(cpl_node)

            for doc in docs:
                signed = all_keys_in_dict(doc, ['Signer', 'Signature'])
                if not signed and cpl_node['Encrypted'] is True:
                    raise CheckException("Encrypted DCP must be signed")
Example #10
0
    def check_dcp_signed(self):
        """ DCP with encrypted content must be digitally signed.

            Reference :
                DCI Spec 1.3 5.4.3.7.
                DCI Spec 1.3 5.5.2.3.
        """
        for cpl in self.dcp._list_cpl:
            cpl_node = cpl['Info']['CompositionPlaylist']
            xmls = [
                pkl['Info']['PackingList'] for pkl in self.dcp._list_pkl
                if pkl['Info']['PackingList']['Id'] == cpl_node.get('PKLId')]
            xmls.append(cpl_node)

            for xml in xmls:
                signed = all_keys_in_dict(xml, ['Signer', 'Signature'])
                if not signed and cpl_node['Encrypted'] is True:
                    raise CheckException("Encrypted DCP must be signed")