Ejemplo n.º 1
0
    def output_sync_map_file(self, container_root_path=None):
        """
        Output the sync map file for this task.

        If ``container_root_path`` is specified,
        the output sync map file will be created
        at the path obtained by joining
        the ``container_root_path`` and the relative path
        of the sync map inside the container.

        Otherwise, the sync map file will be created at the path
        ``self.sync_map_file_path_absolute``.

        Return the the path of the sync map file created,
        or ``None`` if an error occurred.

        :param string container_root_path: the path to the root directory
                                           for the output container
        :rtype: string
        """
        if self.sync_map is None:
            self.log_exc(u"The sync_map object has not been set", None, True, TypeError)

        if (container_root_path is not None) and (self.sync_map_file_path is None):
            self.log_exc(u"The (internal) path of the sync map has been set", None, True, TypeError)

        self.log([u"container_root_path is %s", container_root_path])
        self.log([u"self.sync_map_file_path is %s", self.sync_map_file_path])
        self.log([u"self.sync_map_file_path_absolute is %s", self.sync_map_file_path_absolute])

        if (container_root_path is not None) and (self.sync_map_file_path is not None):
            path = os.path.join(container_root_path, self.sync_map_file_path)
        elif self.sync_map_file_path_absolute:
            path = self.sync_map_file_path_absolute
        gf.ensure_parent_directory(path)
        self.log([u"Output sync map to %s", path])

        sync_map_format = self.configuration["o_format"]
        audio_ref = self.configuration["o_smil_audio_ref"]
        page_ref = self.configuration["o_smil_page_ref"]

        self.log([u"sync_map_format is %s", sync_map_format])
        self.log([u"page_ref is %s", page_ref])
        self.log([u"audio_ref is %s", audio_ref])

        self.log(u"Calling sync_map.write...")
        afpa = self.audio_file_path_absolute
        if afpa is not None:
            afpa = os.path.abspath(afpa)
        parameters = {
            "audio_file_path_absolute": afpa,
            gc.PPN_TASK_OS_FILE_SMIL_PAGE_REF : page_ref,
            gc.PPN_TASK_OS_FILE_SMIL_AUDIO_REF : audio_ref
        }
        self.sync_map.write(sync_map_format, path, parameters)
        self.log(u"Calling sync_map.write... done")
        return path
Ejemplo n.º 2
0
    def compress(self, input_path):
        """
        Compress the contents of the given directory.

        :param string input_path: path of the input directory
        :raises: TypeError: if the container path has not been set
        :raises: ValueError: if ``input_path`` is not an existing directory
        :raises: OSError: if an error occurred compressing the given container
                          (e.g., empty file, damaged file, etc.)
        """
        self.log([u"Compressing '%s' into this container", input_path])

        if self.file_path is None:
            self.log_exc(u"The container path has not been set", None, True, TypeError)
        if self.actual_container is None:
            self.log_exc(u"The actual container object has not been set", None, True, TypeError)
        if not gf.directory_exists(input_path):
            self.log_exc(u"The input path is not an existing directory", None, True, ValueError)
        gf.ensure_parent_directory(input_path)
        self.actual_container.compress(input_path)
Ejemplo n.º 3
0
    def compress(self, input_path):
        """
        Compress the contents of the given directory.

        :param string input_path: path of the input directory
        :raises: TypeError: if the container path has not been set
        :raises: ValueError: if ``input_path`` is not an existing directory
        :raises: OSError: if an error occurred compressing the given container
                          (e.g., empty file, damaged file, etc.)
        """
        self.log([u"Compressing '%s' into this container", input_path])

        if self.file_path is None:
            self.log_exc(u"The container path has not been set", None, True, TypeError)
        if self.actual_container is None:
            self.log_exc(u"The actual container object has not been set", None, True, TypeError)
        if not gf.directory_exists(input_path):
            self.log_exc(u"The input path is not an existing directory", None, True, ValueError)
        gf.ensure_parent_directory(input_path)
        self.actual_container.compress(input_path)
Ejemplo n.º 4
0
 def test_ensure_parent_directory(self):
     orig = gf.tmp_directory()
     tmp_path = os.path.join(orig, "foo.bar")
     tmp_parent = orig
     gf.ensure_parent_directory(tmp_path)
     self.assertTrue(gf.directory_exists(tmp_parent))
     tmp_path = os.path.join(orig, "foo/bar.baz")
     tmp_parent = os.path.join(orig, "foo")
     gf.ensure_parent_directory(tmp_path)
     self.assertTrue(gf.directory_exists(tmp_parent))
     tmp_path = os.path.join(orig, "bar")
     gf.ensure_parent_directory(tmp_path, ensure_parent=False)
     self.assertTrue(gf.directory_exists(tmp_path))
     gf.delete_directory(orig)
Ejemplo n.º 5
0
 def test_ensure_parent_directory(self):
     orig = gf.tmp_directory()
     tmp_path = os.path.join(orig, "foo.bar")
     tmp_parent = orig
     gf.ensure_parent_directory(tmp_path)
     self.assertTrue(gf.directory_exists(tmp_parent))
     tmp_path = os.path.join(orig, "foo/bar.baz")
     tmp_parent = os.path.join(orig, "foo")
     gf.ensure_parent_directory(tmp_path)
     self.assertTrue(gf.directory_exists(tmp_parent))
     tmp_path = os.path.join(orig, "bar")
     gf.ensure_parent_directory(tmp_path, ensure_parent=False)
     self.assertTrue(gf.directory_exists(tmp_path))
     gf.delete_directory(orig)
Ejemplo n.º 6
0
 def test_ensure_parent_directory_no_parent_error(self):
     with self.assertRaises(OSError):
         gf.ensure_parent_directory("/foo/bar/baz", ensure_parent=False)
Ejemplo n.º 7
0
    def output_sync_map_file(self, container_root_path=None):
        """
        Output the sync map file for this task.

        If ``container_root_path`` is specified,
        the output sync map file will be created
        at the path obtained by joining
        the ``container_root_path`` and the relative path
        of the sync map inside the container.

        Otherwise, the sync map file will be created at the path
        ``self.sync_map_file_path_absolute``.

        Return the the path of the sync map file created,
        or ``None`` if an error occurred.

        :param string container_root_path: the path to the root directory
                                           for the output container
        :rtype: string
        """
        if self.sync_map is None:
            self.log_exc(u"The sync_map object has not been set", None, True,
                         TypeError)

        if (container_root_path
                is not None) and (self.sync_map_file_path is None):
            self.log_exc(u"The (internal) path of the sync map has been set",
                         None, True, TypeError)

        self.log([u"container_root_path is %s", container_root_path])
        self.log([u"self.sync_map_file_path is %s", self.sync_map_file_path])
        self.log([
            u"self.sync_map_file_path_absolute is %s",
            self.sync_map_file_path_absolute
        ])

        if (container_root_path is not None) and (self.sync_map_file_path
                                                  is not None):
            path = os.path.join(container_root_path, self.sync_map_file_path)
        elif self.sync_map_file_path_absolute:
            path = self.sync_map_file_path_absolute
        gf.ensure_parent_directory(path)
        self.log([u"Output sync map to %s", path])

        eaf_audio_ref = self.configuration["o_eaf_audio_ref"]
        head_tail_format = self.configuration["o_h_t_format"]
        levels = self.configuration["o_levels"]
        smil_audio_ref = self.configuration["o_smil_audio_ref"]
        smil_page_ref = self.configuration["o_smil_page_ref"]
        sync_map_format = self.configuration["o_format"]

        self.log([u"eaf_audio_ref is %s", eaf_audio_ref])
        self.log([u"head_tail_format is %s", head_tail_format])
        self.log([u"levels is %s", levels])
        self.log([u"smil_audio_ref is %s", smil_audio_ref])
        self.log([u"smil_page_ref is %s", smil_page_ref])
        self.log([u"sync_map_format is %s", sync_map_format])

        self.log(u"Calling sync_map.write...")
        parameters = {
            gc.PPN_TASK_OS_FILE_EAF_AUDIO_REF: eaf_audio_ref,
            gc.PPN_TASK_OS_FILE_HEAD_TAIL_FORMAT: head_tail_format,
            gc.PPN_TASK_OS_FILE_LEVELS: levels,
            gc.PPN_TASK_OS_FILE_SMIL_AUDIO_REF: smil_audio_ref,
            gc.PPN_TASK_OS_FILE_SMIL_PAGE_REF: smil_page_ref,
        }
        self.sync_map.write(sync_map_format, path, parameters)
        self.log(u"Calling sync_map.write... done")
        return path
Ejemplo n.º 8
0
    def write(self, sync_map_format, output_file_path, parameters=None):
        """
        Write the current sync map to file in the requested format.

        Return ``True`` if the call succeeded,
        ``False`` if an error occurred.

        :param sync_map_format: the format of the sync map
        :type  sync_map_format: :class:`~aeneas.syncmap.SyncMapFormat`
        :param string output_file_path: the path to the output file to write
        :param dict parameters: additional parameters (e.g., for ``SMIL`` output)
        :raises: ValueError: if ``sync_map_format`` is ``None`` or it is not an allowed value
        :raises: TypeError: if a required parameter is missing
        :raises: OSError: if ``output_file_path`` cannot be written
        """
        def select_levels(syncmap, levels):
            """
            Select the given levels of the fragments tree,
            modifying the given syncmap (always pass a copy of it!).
            """
            self.log([u"Levels: '%s'", levels])
            if levels is None:
                return
            try:
                levels = [int(l) for l in levels if int(l) > 0]
                syncmap.fragments_tree.keep_levels(levels)
                self.log([u"Selected levels: %s", levels])
            except ValueError:
                self.log_warn(u"Cannot convert levels to list of int, returning unchanged")

        def set_head_tail_format(syncmap, head_tail_format=None):
            """
            Set the appropriate head/tail nodes of the fragments tree,
            modifying the given syncmap (always pass a copy of it!).
            """
            self.log([u"Head/tail format: '%s'", str(head_tail_format)])
            tree = syncmap.fragments_tree
            head = tree.get_child(0)
            first = tree.get_child(1)
            last = tree.get_child(-2)
            tail = tree.get_child(-1)
            # mark HEAD as REGULAR if needed
            if head_tail_format == SyncMapHeadTailFormat.ADD:
                head.value.fragment_type = SyncMapFragment.REGULAR
                self.log(u"Marked HEAD as REGULAR")
            # stretch first and last fragment timings if needed
            if head_tail_format == SyncMapHeadTailFormat.STRETCH:
                self.log([u"Stretched first.begin: %.3f => %.3f (head)", first.value.begin, head.value.begin])
                self.log([u"Stretched last.end:    %.3f => %.3f (tail)", last.value.end, tail.value.end])
                first.value.begin = head.value.begin
                last.value.end = tail.value.end
            # mark TAIL as REGULAR if needed
            if head_tail_format == SyncMapHeadTailFormat.ADD:
                tail.value.fragment_type = SyncMapFragment.REGULAR
                self.log(u"Marked TAIL as REGULAR")
            # remove all fragments that are not REGULAR
            for node in list(tree.dfs):
                if (node.value is not None) and (node.value.fragment_type != SyncMapFragment.REGULAR):
                    node.remove()

        if sync_map_format is None:
            self.log_exc(u"Sync map format is None", None, True, ValueError)
        if sync_map_format not in SyncMapFormat.CODE_TO_CLASS:
            self.log_exc(u"Sync map format '%s' is not allowed" % (sync_map_format), None, True, ValueError)
        if not gf.file_can_be_written(output_file_path):
            self.log_exc(u"Cannot write sync map file '%s'. Wrong permissions?" % (output_file_path), None, True, OSError)

        self.log([u"Output format:     '%s'", sync_map_format])
        self.log([u"Output path:       '%s'", output_file_path])
        self.log([u"Output parameters: '%s'", parameters])

        # select levels and head/tail format
        pruned_syncmap = self.clone()
        try:
            select_levels(pruned_syncmap, parameters[gc.PPN_TASK_OS_FILE_LEVELS])
        except:
            self.log_warn([u"No %s parameter specified", gc.PPN_TASK_OS_FILE_LEVELS])
        try:
            set_head_tail_format(pruned_syncmap, parameters[gc.PPN_TASK_OS_FILE_HEAD_TAIL_FORMAT])
        except:
            self.log_warn([u"No %s parameter specified", gc.PPN_TASK_OS_FILE_HEAD_TAIL_FORMAT])

        # create writer
        # the constructor will check for required parameters, if any
        # if some are missing, it will raise a SyncMapMissingParameterError
        writer = (SyncMapFormat.CODE_TO_CLASS[sync_map_format])(
            variant=sync_map_format,
            parameters=parameters,
            rconf=self.rconf,
            logger=self.logger
        )

        # create dir hierarchy, if needed
        gf.ensure_parent_directory(output_file_path)

        # open file for writing
        self.log(u"Writing output file...")
        with io.open(output_file_path, "w", encoding="utf-8") as output_file:
            output_file.write(writer.format(syncmap=pruned_syncmap))
        self.log(u"Writing output file... done")
Ejemplo n.º 9
0
    def write(self, sync_map_format, output_file_path, parameters=None):
        """
        Write the current sync map to file in the requested format.

        Return ``True`` if the call succeeded,
        ``False`` if an error occurred.

        :param sync_map_format: the format of the sync map
        :type  sync_map_format: :class:`~aeneas.syncmap.SyncMapFormat`
        :param string output_file_path: the path to the output file to write
        :param dict parameters: additional parameters (e.g., for ``SMIL`` output)
        :raises: ValueError: if ``sync_map_format`` is ``None`` or it is not an allowed value
        :raises: TypeError: if a required parameter is missing
        :raises: OSError: if ``output_file_path`` cannot be written
        """
        def select_levels(syncmap, levels):
            """
            Select the given levels of the fragments tree,
            modifying the given syncmap (always pass a copy of it!).
            """
            self.log([u"Levels: '%s'", levels])
            if levels is None:
                return
            try:
                levels = [int(l) for l in levels if int(l) > 0]
                syncmap.fragments_tree.keep_levels(levels)
                self.log([u"Selected levels: %s", levels])
            except ValueError:
                self.log_warn(
                    u"Cannot convert levels to list of int, returning unchanged"
                )

        def set_head_tail_format(syncmap, head_tail_format=None):
            """
            Set the appropriate head/tail nodes of the fragments tree,
            modifying the given syncmap (always pass a copy of it!).
            """
            self.log([u"Head/tail format: '%s'", str(head_tail_format)])
            tree = syncmap.fragments_tree
            head = tree.get_child(0)
            first = tree.get_child(1)
            last = tree.get_child(-2)
            tail = tree.get_child(-1)
            # mark HEAD as REGULAR if needed
            if head_tail_format == SyncMapHeadTailFormat.ADD:
                head.value.fragment_type = SyncMapFragment.REGULAR
                self.log(u"Marked HEAD as REGULAR")
            # stretch first and last fragment timings if needed
            if head_tail_format == SyncMapHeadTailFormat.STRETCH:
                self.log([
                    u"Stretched first.begin: %.3f => %.3f (head)",
                    first.value.begin, head.value.begin
                ])
                self.log([
                    u"Stretched last.end:    %.3f => %.3f (tail)",
                    last.value.end, tail.value.end
                ])
                first.value.begin = head.value.begin
                last.value.end = tail.value.end
            # mark TAIL as REGULAR if needed
            if head_tail_format == SyncMapHeadTailFormat.ADD:
                tail.value.fragment_type = SyncMapFragment.REGULAR
                self.log(u"Marked TAIL as REGULAR")
            # remove all fragments that are not REGULAR
            for node in list(tree.dfs):
                if (node.value is not None) and (node.value.fragment_type !=
                                                 SyncMapFragment.REGULAR):
                    node.remove()

        if sync_map_format is None:
            self.log_exc(u"Sync map format is None", None, True, ValueError)
        if sync_map_format not in SyncMapFormat.CODE_TO_CLASS:
            self.log_exc(
                u"Sync map format '%s' is not allowed" % (sync_map_format),
                None, True, ValueError)
        if not gf.file_can_be_written(output_file_path):
            self.log_exc(
                u"Cannot write sync map file '%s'. Wrong permissions?" %
                (output_file_path), None, True, OSError)

        self.log([u"Output format:     '%s'", sync_map_format])
        self.log([u"Output path:       '%s'", output_file_path])
        self.log([u"Output parameters: '%s'", parameters])

        # select levels and head/tail format
        pruned_syncmap = self.clone()
        try:
            select_levels(pruned_syncmap,
                          parameters[gc.PPN_TASK_OS_FILE_LEVELS])
        except:
            self.log_warn(
                [u"No %s parameter specified", gc.PPN_TASK_OS_FILE_LEVELS])
        try:
            set_head_tail_format(
                pruned_syncmap,
                parameters[gc.PPN_TASK_OS_FILE_HEAD_TAIL_FORMAT])
        except:
            self.log_warn([
                u"No %s parameter specified",
                gc.PPN_TASK_OS_FILE_HEAD_TAIL_FORMAT
            ])

        # create writer
        # the constructor will check for required parameters, if any
        # if some are missing, it will raise a SyncMapMissingParameterError
        writer = (SyncMapFormat.CODE_TO_CLASS[sync_map_format])(
            variant=sync_map_format,
            parameters=parameters,
            rconf=self.rconf,
            logger=self.logger)

        # create dir hierarchy, if needed
        gf.ensure_parent_directory(output_file_path)

        # open file for writing
        self.log(u"Writing output file...")
        with io.open(output_file_path, "w", encoding="utf-8") as output_file:
            output_file.write(writer.format(syncmap=pruned_syncmap))
        self.log(u"Writing output file... done")
Ejemplo n.º 10
0
 def test_ensure_parent_directory_no_parent_error(self):
     with self.assertRaises(OSError):
         gf.ensure_parent_directory("/foo/bar/baz", ensure_parent=False)