예제 #1
0
    def parse(self):
        """
        Parse the pkl.xml, extracts asset info for storage in memory.
        """
        try:
            self.validate()
        except Exception as e:
            raise PKLError(e)

        # Get hashes from pkl.xml file
        tree = ET.parse(self.path)
        root = tree.getroot()

        # Again, get the namespace so we can search elements
        pkl_ns = get_namespace(root.tag)
        self.id = get_element_text(root, "Id", pkl_ns).split(":")[2]

        asset_list = get_element(root, "AssetList", pkl_ns)

        # Get the data from the pkl file
        for asset in asset_list.getchildren():
            asset_id = get_element_text(asset, "Id", pkl_ns).split(":")[2]

            p = {
                "file_hash": get_element_text(asset, "Hash", pkl_ns),
                "size": get_element_text(asset, "Size", pkl_ns),
                "file_type": get_element_text(asset, "Type", pkl_ns)
            }

            self.assets[asset_id] = PKLData(**p)
예제 #2
0
    def parse(self):
        """
        Parse the pkl.xml, extracts asset info for storage in memory.
        """
        try:
            self.validate()
        except Exception as e:
            raise PKLError(e)

        # Get hashes from pkl.xml file
        tree = ET.parse(self.path)
        root = tree.getroot()

        # Again, get the namespace so we can search elements
        pkl_ns = get_namespace(root.tag)
        self.id = get_element_text(root, "Id", pkl_ns).split(":")[2]

        asset_list = get_element(root, "AssetList", pkl_ns)

        # Get the data from the pkl file
        for asset in asset_list.getchildren():
            asset_id = get_element_text(asset, "Id", pkl_ns).split(":")[2]

            p = {
                "file_hash": get_element_text(asset, "Hash", pkl_ns),
                "size": get_element_text(asset, "Size", pkl_ns),
                "file_type": get_element_text(asset, "Type", pkl_ns)
            }

            self.assets[asset_id] = PKLData(**p)
예제 #3
0
 def __init__(self, element, cpl_ns):
     self.id = get_element_text(element, "Id", cpl_ns).split(":")[2]
     self.edit_rate = tuple([int(x) for x in get_element_text(element, "EditRate", cpl_ns).split()])
     self.intrinsic_duration = long(get_element_text(element, "IntrinsicDuration", cpl_ns))
     e = get_element_text(element, "EntryPoint", cpl_ns)
     self.entry_point = long(e) if e is not None else e
     d = get_element_text(element, "Duration", cpl_ns)
     self.duration = long(d) if d is not None else d
예제 #4
0
    def __init__(self, element, cpl_ns):
        super(Picture, self).__init__(element, cpl_ns)

        self.frame_rate = tuple([
            int(x)
            for x in get_element_text(element, "FrameRate", cpl_ns).split()
        ])
        self.screen_aspect_ratio = tuple([
            float(x) for x in get_element_text(element, "ScreenAspectRatio",
                                               cpl_ns).split()
        ])
예제 #5
0
 def __init__(self, element, cpl_ns):
     self.id = get_element_text(element, "Id", cpl_ns).split(":")[2]
     self.edit_rate = tuple([
         int(x)
         for x in get_element_text(element, "EditRate", cpl_ns).split()
     ])
     self.intrinsic_duration = long(
         get_element_text(element, "IntrinsicDuration", cpl_ns))
     e = get_element_text(element, "EntryPoint", cpl_ns)
     self.entry_point = long(e) if e is not None else e
     d = get_element_text(element, "Duration", cpl_ns)
     self.duration = long(d) if d is not None else d
예제 #6
0
    def __init__(self, element, cpl_ns, assetmap=None):
        """
        Takes a "Reel" element and parses out the information contained inside.

        @todo: Check this against 3D content, in theory it should work but needs tests!
        """

        self.assets = {}
        self.id = get_element_text(element, "Id", cpl_ns).split(":")[2]

        for asset in get_element(element, "AssetList", cpl_ns).getchildren():
            asset_tag = asset.tag.split('}')[1] # Remove the namespace, hack but it works for now!
            if asset_tag in ("MainPicture", "MainStereoscopicPicture"):
                asset_instance = Picture(asset, cpl_ns)
                self.picture = asset_instance
            elif asset_tag == "MainSound":
                asset_instance = Sound(asset, cpl_ns)
                self.sound = asset_instance
            elif asset_tag == "MainSubtitle":
                asset_instance = Subtitle(asset, cpl_ns)
                self.subtitle = asset_instance
            else:
                raise CPLError("Unknown asset type found: {0}".format(asset_tag))

            # Finally set the path to this particular asset.
            if assetmap is not None:
                asset_instance.path = assetmap[asset_instance.id].path

            # Assets can be accessed in two ways now.
            self.assets[asset_instance.id] = asset_instance
예제 #7
0
    def __init__(self, element, cpl_ns, assetmap=None):
        """
        Takes a "Reel" element and parses out the information contained inside.

        @todo: Check this against 3D content, in theory it should work but needs tests!
        """

        self.assets = {}
        self.id = get_element_text(element, "Id", cpl_ns).split(":")[2]

        for asset in get_element(element, "AssetList", cpl_ns).getchildren():
            asset_tag = asset.tag.split('}')[
                1]  # Remove the namespace, hack but it works for now!
            if asset_tag in ("MainPicture", "MainStereoscopicPicture"):
                asset_instance = Picture(asset, cpl_ns)
                self.picture = asset_instance
            elif asset_tag == "MainSound":
                asset_instance = Sound(asset, cpl_ns)
                self.sound = asset_instance
            elif asset_tag == "MainSubtitle":
                asset_instance = Subtitle(asset, cpl_ns)
                self.subtitle = asset_instance
            else:
                raise CPLError(
                    "Unknown asset type found: {0}".format(asset_tag))

            # Finally set the path to this particular asset.
            if assetmap is not None:
                asset_instance.path = assetmap[asset_instance.id].path

            # Assets can be accessed in two ways now.
            self.assets[asset_instance.id] = asset_instance
예제 #8
0
    def parse(self):
        """
        Opens a given CPL asset, parses the XML to extract the playlist info and create a CPL object
        which is added to the DCP's CPL list.
        """
        try:
            tree = ET.parse(self.path)
            root = tree.getroot()
            # ElementTree prepends the namespace to all elements, so we need to extract
            # it so that we can perform sensible searching on elements.
            self.cpl_ns = get_namespace(root.tag)

            self.validate()
        except Exception as e:
            raise CPLError(e)


        self.id = get_element_text(root, "Id", self.cpl_ns).split(":")[2]
        self.content_title_text = get_element_text(root, "ContentTitleText", self.cpl_ns)
        self.annotation_text = get_element_text(root, "AnnotationText", self.cpl_ns)
        self.issue_date = parse_date(get_element_text(root, "IssueDate", self.cpl_ns))
        self.issuer = get_element_text(root, "Issuer", self.cpl_ns)
        self.creator = get_element_text(root, "Creator", self.cpl_ns)
        self.content_kind = get_element_text(root, "ContentKind", self.cpl_ns)

        # Get each of the parts of the CPL, i.e. the Reels :)
        for reel_list_elem in get_element_iterator(root, "ReelList", self.cpl_ns):
            for reel_elem in reel_list_elem.getchildren():
                reel = Reel(reel_elem, self.cpl_ns, assetmap=self.assetmap)

                # Add this in as a convenience for working with assets.
                for asset_id, asset in reel.assets.iteritems():
                    self.assets[asset_id] = asset

                self.reels.append(reel)
예제 #9
0
    def _parse_smpte(self, root):
        """
        Parses a SMPTE KDM

        :params root: the root element of the XML document
        :type root: ElementTree Element
        """
        self._kind = KDM.SMPTE
        smpte_etm_ns = get_namespace(root.tag)
        ap_el = get_element(root, 'AuthenticatedPublic', smpte_etm_ns)
        self.id = strip_urn(get_element_text(ap_el, 'MessageId', smpte_etm_ns))
        self.annotation_text = get_element_text(ap_el, 'AnnotationText',
                                                smpte_etm_ns)
        self.issue_date = get_element_text(ap_el, 'IssueDate', smpte_etm_ns)
        re_el = get_element(ap_el, 'RequiredExtensions', smpte_etm_ns)
        smpte_kdm_ns = 'http://www.smpte-ra.org/schemas/430-1/2006/KDM'
        kdm_re_el = get_element(re_el, 'KDMRequiredExtensions', smpte_kdm_ns)
        self.cpl_id = strip_urn(
            get_element_text(kdm_re_el, 'CompositionPlaylistId', smpte_kdm_ns))
        self.content_title_text = get_element_text(kdm_re_el,
                                                   'ContentTitleText',
                                                   smpte_kdm_ns)
        self.start_date = get_element_text(kdm_re_el,
                                           'ContentKeysNotValidBefore',
                                           smpte_kdm_ns)
        self.end_date = get_element_text(kdm_re_el, 'ContentKeysNotValidAfter',
                                         smpte_kdm_ns)
예제 #10
0
 def _parse(self, catalog_str):
     """
     Parses a KDM bundle catalog XML string
     """
     root = ET.fromstring(catalog_str)
     cat_ns = get_namespace(root.tag)
     self.id = strip_urn(get_element_text(root, 'Id', cat_ns))
     self.annotation_text = get_element_text(root, 'AnnotationText', cat_ns)
     self.creator = get_element_text(root, 'Creator', cat_ns)
     self.cpl_ids = []
     self.kdm_paths = []
     self.start_dates = []
     self.end_dates = []
     for kdm_list_el in get_element_iterator(root, 'KDMFileList', cat_ns):
         for kdm_el in kdm_list_el.getchildren():
             self.cpl_ids.append(
                 strip_urn(get_element_text(kdm_el, 'CPLId', cat_ns)))
             self.kdm_paths.append(
                 get_element_text(kdm_el, 'FilePath', cat_ns))
             self.start_dates.append(
                 get_element_text(kdm_el, 'ContentKeysNotValidBefore',
                                  cat_ns))
             self.end_dates.append(
                 get_element_text(kdm_el, 'ContentKeysNotValidAfter',
                                  cat_ns))
예제 #11
0
    def _parse_interop(self, root):
        """
        Parses a KDM in interop format

        :params root: the root element of the XML document
        :type root: ElementTree Element
        """
        self._kind = KDM.INTEROP
        interop_kdm_ns = get_namespace(root.tag)
        ap_el = get_element(root, 'AuthenticatedPublic', interop_kdm_ns)
        self.id = strip_urn(get_element_text(ap_el, 'MessageId', interop_kdm_ns))
        self.annotation_text = get_element_text(ap_el, 'AnnotationText', interop_kdm_ns)
        self.issue_date = get_element_text(ap_el, 'IssueDate', interop_kdm_ns)
        re_el = get_element(ap_el, 'RequiredExtensions', interop_kdm_ns)
        self.cpl_id = strip_urn(get_element_text(re_el, 'CompositionPlaylistId', interop_kdm_ns))
        self.content_title_text = get_element_text(re_el, 'ContentTitleText', interop_kdm_ns)
        self.start_date = get_element_text(re_el, 'ContentKeysNotValidBefore', interop_kdm_ns)
        self.end_date = get_element_text(re_el, 'ContentKeysNotValidAfter', interop_kdm_ns)
예제 #12
0
파일: kdm.py 프로젝트: 4lm/smpteparsers
    def _parse_interop(self, root):
        """
        Parses a KDM in interop format

        :params root: the root element of the XML document
        :type root: ElementTree Element
        """
        self._kind = KDM.INTEROP
        interop_kdm_ns = get_namespace(root.tag)
        ap_el = get_element(root, 'AuthenticatedPublic', interop_kdm_ns)
        self.id = strip_urn(get_element_text(ap_el, 'MessageId', interop_kdm_ns))
        self.annotation_text = get_element_text(ap_el, 'AnnotationText', interop_kdm_ns)
        self.issue_date = get_element_text(ap_el, 'IssueDate', interop_kdm_ns)
        re_el = get_element(ap_el, 'RequiredExtensions', interop_kdm_ns)
        self.cpl_id = strip_urn(get_element_text(re_el, 'CompositionPlaylistId', interop_kdm_ns))
        self.content_title_text = get_element_text(re_el, 'ContentTitleText', interop_kdm_ns)
        self.start_date = get_element_text(re_el, 'ContentKeysNotValidBefore', interop_kdm_ns)
        self.end_date = get_element_text(re_el, 'ContentKeysNotValidAfter', interop_kdm_ns)
예제 #13
0
 def _parse(self, catalog_str):
     """
     Parses a KDM bundle catalog XML string
     """
     root = ET.fromstring(catalog_str)
     cat_ns = get_namespace(root.tag)
     self.id = strip_urn(get_element_text(root, 'Id', cat_ns))
     self.annotation_text = get_element_text(root, 'AnnotationText', cat_ns)
     self.creator = get_element_text(root, 'Creator', cat_ns)
     self.cpl_ids = []
     self.kdm_paths = []
     self.start_dates = []
     self.end_dates = []
     for kdm_list_el in get_element_iterator(root, 'KDMFileList', cat_ns):
         for kdm_el in kdm_list_el.getchildren():
             self.cpl_ids.append(strip_urn(get_element_text(kdm_el, 'CPLId', cat_ns)))
             self.kdm_paths.append(get_element_text(kdm_el, 'FilePath', cat_ns))
             self.start_dates.append(get_element_text(kdm_el, 'ContentKeysNotValidBefore', cat_ns))
             self.end_dates.append(get_element_text(kdm_el, 'ContentKeysNotValidAfter', cat_ns))
예제 #14
0
    def _parse(self, root):
        self.id = get_element_text(root, "Id", self.cpl_ns).split(":")[2]
        self.content_title_text = get_element_text(root, "ContentTitleText", self.cpl_ns)
        self.annotation_text = get_element_text(root, "AnnotationText", self.cpl_ns)
        self.issue_date = parse_date(get_element_text(root, "IssueDate", self.cpl_ns))
        self.issuer = get_element_text(root, "Issuer", self.cpl_ns)
        self.creator = get_element_text(root, "Creator", self.cpl_ns)
        self.content_kind = get_element_text(root, "ContentKind", self.cpl_ns)

        # Get each of the parts of the CPL, i.e. the Reels :)
        for reel_list_elem in get_element_iterator(root, "ReelList", self.cpl_ns):
            for reel_elem in reel_list_elem.getchildren():
                reel = Reel(reel_elem, self.cpl_ns, assetmap=self.assetmap)

                # Add this in as a convenience for working with assets.
                for asset_id, asset in reel.assets.items():
                    self.assets[asset_id] = asset

                self.reels.append(reel)
예제 #15
0
    def _parse_smpte(self, root):
        """
        Parses a SMPTE KDM

        :params root: the root element of the XML document
        :type root: ElementTree Element
        """
        self._kind = KDM.SMPTE
        smpte_etm_ns = get_namespace(root.tag)
        ap_el = get_element(root, 'AuthenticatedPublic', smpte_etm_ns)
        self.id = strip_urn(get_element_text(ap_el, 'MessageId', smpte_etm_ns))
        self.annotation_text = get_element_text(ap_el, 'AnnotationText', smpte_etm_ns)
        self.issue_date = get_element_text(ap_el, 'IssueDate', smpte_etm_ns)
        re_el = get_element(ap_el, 'RequiredExtensions', smpte_etm_ns)
        smpte_kdm_ns ='http://www.smpte-ra.org/schemas/430-1/2006/KDM'
        kdm_re_el = get_element(re_el, 'KDMRequiredExtensions', smpte_kdm_ns)
        self.cpl_id = strip_urn(get_element_text(kdm_re_el, 'CompositionPlaylistId', smpte_kdm_ns))
        self.content_title_text = get_element_text(kdm_re_el, 'ContentTitleText', smpte_kdm_ns)
        self.start_date = get_element_text(kdm_re_el, 'ContentKeysNotValidBefore', smpte_kdm_ns)
        self.end_date = get_element_text(kdm_re_el, 'ContentKeysNotValidAfter', smpte_kdm_ns)
예제 #16
0
    def parse(self):
        """
        Opens a given CPL asset, parses the XML to extract the playlist info and create a CPL object
        which is added to the DCP's CPL list.
        """
        try:
            tree = ET.parse(self.path)
            root = tree.getroot()
            # ElementTree prepends the namespace to all elements, so we need to extract
            # it so that we can perform sensible searching on elements.
            self.cpl_ns = get_namespace(root.tag)

            self.validate()
        except Exception as e:
            raise CPLError(e)

        self.id = get_element_text(root, "Id", self.cpl_ns).split(":")[2]
        self.content_title_text = get_element_text(root, "ContentTitleText",
                                                   self.cpl_ns)
        self.annotation_text = get_element_text(root, "AnnotationText",
                                                self.cpl_ns)
        self.issue_date = parse_date(
            get_element_text(root, "IssueDate", self.cpl_ns))
        self.issuer = get_element_text(root, "Issuer", self.cpl_ns)
        self.creator = get_element_text(root, "Creator", self.cpl_ns)
        self.content_kind = get_element_text(root, "ContentKind", self.cpl_ns)

        # Get each of the parts of the CPL, i.e. the Reels :)
        for reel_list_elem in get_element_iterator(root, "ReelList",
                                                   self.cpl_ns):
            for reel_elem in reel_list_elem.getchildren():
                reel = Reel(reel_elem, self.cpl_ns, assetmap=self.assetmap)

                # Add this in as a convenience for working with assets.
                for asset_id, asset in reel.assets.iteritems():
                    self.assets[asset_id] = asset

                self.reels.append(reel)
예제 #17
0
    def _parse(self, root):
        self.id = get_element_text(root, "Id", self.cpl_ns).split(":")[2]
        self.content_title_text = get_element_text(root, "ContentTitleText",
                                                   self.cpl_ns)
        self.annotation_text = get_element_text(root, "AnnotationText",
                                                self.cpl_ns)
        self.issue_date = parse_date(
            get_element_text(root, "IssueDate", self.cpl_ns))
        self.issuer = get_element_text(root, "Issuer", self.cpl_ns)
        self.creator = get_element_text(root, "Creator", self.cpl_ns)
        self.content_kind = get_element_text(root, "ContentKind", self.cpl_ns)

        # Get each of the parts of the CPL, i.e. the Reels :)
        for reel_list_elem in get_element_iterator(root, "ReelList",
                                                   self.cpl_ns):
            for reel_elem in reel_list_elem.getchildren():
                reel = Reel(reel_elem, self.cpl_ns, assetmap=self.assetmap)

                # Add this in as a convenience for working with assets.
                for asset_id, asset in reel.assets.items():
                    self.assets[asset_id] = asset

                self.reels.append(reel)
예제 #18
0
    def parse(self):
        """
        Parse the ASSETMAP. Extract the id, path, volume index, offset and
        length for each asset, and the validate the paths of the downloaded
        files against the paths from the ASSETMAP file.
        """
        try:
            self.validate()
        except Exception as e:
            raise AssetmapError(e)

        tree = ET.parse(self.path)
        root = tree.getroot()
        # ElementTree prepends the namespace to all elements, so we need to extract
        # it so that we can perform sensible searching on elements.
        assetmap_ns = get_namespace(root.tag)

        self.id = get_element_text(root, "Id", assetmap_ns).split(":")[2]
        self.annotation_text = get_element_text(root, "AnnotationText", assetmap_ns)
        self.volume_count = int(get_element_text(root, "VolumeCount", assetmap_ns))
        self.issue_date = parse_date(get_element_text(root, "IssueDate", assetmap_ns))
        self.issuer = get_element_text(root, "Issuer", assetmap_ns)
        self.creator = get_element_text(root, "Creator", assetmap_ns)

        asset_list = get_element(root, "AssetList", assetmap_ns)
        # Get the data from the ASSETMAP file
        for asset in asset_list.getchildren():
            asset_id = get_element_text(asset, "Id", assetmap_ns).split(":")[2]
            for chunklist in get_element_iterator(asset, "ChunkList", assetmap_ns):
                """
                The code below assumes that there will only ever be one chunk in a chunklist. Chunking is 
                used to split files up into smaller parts, usually in order to provide compatability with older
                filesystems, which is not applicable for our uses.
                """
                for chunk in chunklist.getchildren():
                    v = get_element_text(chunk, "VolumeIndex", assetmap_ns)
                    o = get_element_text(chunk, "Offset", assetmap_ns) 
                    l = get_element_text(chunk, "Length", assetmap_ns)
                    
                    a = {
                        "path": get_element_text(chunk, "Path", assetmap_ns),
                        "volume_index": int(v) if v is not None else v,
                        "offset": int(o) if o is not None else o,
                        "length": int(l) if l is not None else l
                    }

                    self.assets[asset_id] = AssetData(**a)
예제 #19
0
    def __init__(self, element, cpl_ns):
        super(Picture, self).__init__(element, cpl_ns)

        self.frame_rate = tuple([int(x) for x in get_element_text(element, "FrameRate", cpl_ns).split()])
        self.screen_aspect_ratio = tuple([int(x) for x in get_element_text(element, "ScreenAspectRatio", cpl_ns).split()])
예제 #20
0
    def parse(self):
        """
        Parse the ASSETMAP. Extract the id, path, volume index, offset and
        length for each asset, and the validate the paths of the downloaded
        files against the paths from the ASSETMAP file.
        """
        try:
            self.validate()
        except Exception as e:
            raise AssetmapError(e)

        tree = ET.parse(self.path)
        root = tree.getroot()
        # ElementTree prepends the namespace to all elements, so we need to extract
        # it so that we can perform sensible searching on elements.
        assetmap_ns = get_namespace(root.tag)

        self.id = get_element_text(root, "Id", assetmap_ns).split(":")[2]
        self.annotation_text = get_element_text(root, "AnnotationText",
                                                assetmap_ns)
        self.volume_count = int(
            get_element_text(root, "VolumeCount", assetmap_ns))
        self.issue_date = parse_date(
            get_element_text(root, "IssueDate", assetmap_ns))
        self.issuer = get_element_text(root, "Issuer", assetmap_ns)
        self.creator = get_element_text(root, "Creator", assetmap_ns)

        asset_list = get_element(root, "AssetList", assetmap_ns)
        # Get the data from the ASSETMAP file
        for asset in asset_list.getchildren():
            asset_id = get_element_text(asset, "Id", assetmap_ns).split(":")[2]
            for chunklist in get_element_iterator(asset, "ChunkList",
                                                  assetmap_ns):
                """
                The code below assumes that there will only ever be one chunk in a chunklist. Chunking is 
                used to split files up into smaller parts, usually in order to provide compatability with older
                filesystems, which is not applicable for our uses.
                """
                for chunk in chunklist.getchildren():
                    v = get_element_text(chunk, "VolumeIndex", assetmap_ns)
                    o = get_element_text(chunk, "Offset", assetmap_ns)
                    l = get_element_text(chunk, "Length", assetmap_ns)

                    a = {
                        "path": get_element_text(chunk, "Path", assetmap_ns),
                        "volume_index": int(v) if v is not None else v,
                        "offset": int(o) if o is not None else o,
                        "length": int(l) if l is not None else l
                    }

                    self.assets[asset_id] = AssetData(**a)