Example #1
0
    def convert_paths_to_relative(self, file_path, previous_path, data):
        """ Convert all paths relative to this filepath """
        try:
            # Get project folder
            path_context["new_project_folder"] = os.path.dirname(file_path)
            path_context["new_project_assets"] = get_assets_path(
                file_path, create_paths=False)
            path_context["existing_project_folder"] = os.path.dirname(
                file_path)
            path_context["existing_project_assets"] = get_assets_path(
                file_path, create_paths=False)
            if previous_path and file_path != previous_path:
                path_context["existing_project_folder"] = os.path.dirname(
                    previous_path)
                path_context["existing_project_assets"] = get_assets_path(
                    previous_path, create_paths=False)

            # Optimized regex replacement
            data = re.sub(path_regex, self.replace_string_to_relative, data)

        except Exception as ex:
            log.error(
                "Error while converting absolute paths to relative paths: %s" %
                str(ex))

        return data
Example #2
0
    def convert_paths_to_absolute(self, file_path, data):
        """ Convert all paths to absolute using regex """
        try:
            # Get project folder
            path_context["new_project_folder"] = os.path.dirname(file_path)
            path_context["existing_project_folder"] = os.path.dirname(
                file_path)
            path_context["new_project_assets"] = get_assets_path(
                file_path, create_paths=False)
            path_context["existing_project_assets"] = get_assets_path(
                file_path, create_paths=False)

            # Optimized regex replacement
            data = re.sub(path_regex, self.replace_string_to_absolute, data)

        except Exception:
            log.error(
                "Error while converting relative paths to absolute paths",
                exc_info=1)

        return data
Example #3
0
    def save(self, file_path, move_temp_files=True, make_paths_relative=True):
        """ Save project file to disk """
        import openshot

        log.info("Saving project file: {}".format(file_path))

        # Move all temp files (i.e. Blender animations) to the project folder
        if move_temp_files:
            self.move_temp_paths_to_project_folder(
                file_path, previous_path=self.current_filepath)

        # Append version info
        self._data["version"] = {
            "openshot-qt": info.VERSION,
            "libopenshot": openshot.OPENSHOT_VERSION_FULL
        }

        # Try to save project settings file, will raise error on failure
        self.write_to_file(file_path,
                           self._data,
                           path_mode="relative",
                           previous_path=self.current_filepath)

        # On success, save current filepath
        self.current_filepath = file_path

        # Update info paths to assets folders
        if move_temp_files:
            info.THUMBNAIL_PATH = os.path.join(
                get_assets_path(self.current_filepath), "thumbnail")
            info.TITLE_PATH = os.path.join(
                get_assets_path(self.current_filepath), "title")
            info.BLENDER_PATH = os.path.join(
                get_assets_path(self.current_filepath), "blender")

        # Add to recent files setting
        self.add_to_recent_files(file_path)

        # Track unsaved changes
        self.has_unsaved_changes = False
Example #4
0
    def move_temp_paths_to_project_folder(self, file_path, previous_path=None):
        """ Move all temp files (such as Thumbnails, Titles, and Blender animations) to the project asset folder. """
        try:
            # Get or generate asset folder name, max 30 chars of filename + "_assets"
            asset_path = get_assets_path(file_path)
            target_thumb_path = os.path.join(asset_path, "thumbnail")
            target_title_path = os.path.join(asset_path, "title")
            target_blender_path = os.path.join(asset_path, "blender")

            # Update paths (if a previous path exists)
            #   /Project1/ to /Project2/ for example
            if previous_path:
                previous_asset_path = get_assets_path(previous_path)
                info.THUMBNAIL_PATH = os.path.join(previous_asset_path,
                                                   "thumbnail")
                info.TITLE_PATH = os.path.join(previous_asset_path, "title")
                info.BLENDER_PATH = os.path.join(previous_asset_path,
                                                 "blender")

            # Track assets we copy/update
            copied = []
            reader_paths = {}

            # Copy all thumbnail files (if not found in target asset folder)
            for thumb_path in os.listdir(info.THUMBNAIL_PATH):
                working_thumb_path = os.path.join(info.THUMBNAIL_PATH,
                                                  thumb_path)
                target_thumb_filepath = os.path.join(target_thumb_path,
                                                     thumb_path)
                if not os.path.exists(target_thumb_filepath):
                    shutil.copy2(working_thumb_path, target_thumb_filepath)

            # Copy all title files (if not found in target asset folder)
            for title_path in os.listdir(info.TITLE_PATH):
                working_title_path = os.path.join(info.TITLE_PATH, title_path)
                target_title_filepath = os.path.join(target_title_path,
                                                     title_path)
                if not os.path.exists(target_title_filepath):
                    shutil.copy2(working_title_path, target_title_filepath)

            # Copy all blender folders (if not found in target asset folder)
            for blender_path in os.listdir(info.BLENDER_PATH):
                working_blender_path = os.path.join(info.BLENDER_PATH,
                                                    blender_path)
                target_blender_filepath = os.path.join(target_blender_path,
                                                       blender_path)
                if os.path.isdir(working_blender_path) and not os.path.exists(
                        target_blender_filepath):
                    shutil.copytree(working_blender_path,
                                    target_blender_filepath)

            # Copy any necessary assets for File records
            for file in self._data["files"]:
                path = file["path"]

                # For now, store thumbnail path for backwards compatibility
                file["image"] = os.path.join(target_thumb_path,
                                             "{}.png".format(file["id"]))

                # Assets which need to be copied
                new_asset_path = None
                if info.BLENDER_PATH in path:
                    # Copy directory of blender files
                    log.info("Copying {}".format(path))
                    old_dir, asset_name = os.path.split(path)
                    if os.path.isdir(old_dir) and old_dir not in copied:
                        # Copy dir into new folder
                        old_dir_name = os.path.basename(old_dir)
                        copied.append(old_dir)
                        log.info("Copied dir {} to {}.".format(
                            old_dir_name, target_blender_path))
                    new_asset_path = os.path.join(target_blender_path,
                                                  old_dir_name, asset_name)

                if info.TITLE_PATH in path:
                    # Copy title files into assets folder
                    log.info("Copying {}".format(path))
                    old_dir, asset_name = os.path.split(path)
                    if asset_name not in copied:
                        # Copy title into assets title folder
                        copied.append(asset_name)
                        log.info("Copied title {} to {}.".format(
                            asset_name, target_title_path))
                    new_asset_path = os.path.join(target_title_path,
                                                  asset_name)

                # Update path in File object to new location
                if new_asset_path:
                    file["path"] = new_asset_path
                    file_id = file["id"]
                    reader_paths[file_id] = new_asset_path
                    log.info("Set file {} path to {}".format(
                        file_id, new_asset_path))

            # Copy all Clip thumbnails and update reader paths
            for clip in self._data["clips"]:
                file_id = clip["file_id"]

                # For now, store thumbnail path for backwards compatibility
                clip["image"] = os.path.join(target_thumb_path,
                                             "{}.png".format(file_id))

                log.info("Checking clip {} path for file {}".format(
                    clip["id"], file_id))
                # Update paths to files stored in our working space or old path structure
                # (should have already been copied during previous File stage)
                if file_id and file_id in reader_paths:
                    clip["reader"]["path"] = reader_paths[file_id]
                    log.info("Updated clip {} path for file {}".format(
                        clip["id"], file_id))

        except Exception:
            log.error(
                "Error while moving temp paths to project assets folder %s",
                asset_path,
                exc_info=1)
Example #5
0
    def load(self, file_path, clear_thumbnails=True):
        """ Load project from file """

        self.new()

        if file_path:
            log.info("Loading project file: {}".format(file_path))

            # Default project data
            default_project = self._data

            try:
                # Attempt to load v2.X project file
                project_data = self.read_from_file(file_path,
                                                   path_mode="absolute")

                # Fix history (if broken)
                if not project_data.get("history"):
                    project_data["history"] = {"undo": [], "redo": []}

            except Exception:
                try:
                    # Attempt to load legacy project file (v1.X version)
                    project_data = self.read_legacy_project_file(file_path)

                except Exception:
                    # Project file not recognized as v1.X or v2.X, bubble up error
                    raise

            # Merge default and project settings, excluding settings not in default.
            self._data = self.merge_settings(default_project, project_data)

            # On success, save current filepath
            self.current_filepath = file_path

            # Update info paths to assets folders
            if clear_thumbnails:
                info.THUMBNAIL_PATH = os.path.join(
                    get_assets_path(self.current_filepath), "thumbnail")
                info.TITLE_PATH = os.path.join(
                    get_assets_path(self.current_filepath), "title")
                info.BLENDER_PATH = os.path.join(
                    get_assets_path(self.current_filepath), "blender")

            # Clear needs save flag
            self.has_unsaved_changes = False

            # Check if paths are all valid
            self.check_if_paths_are_valid()

            # Clear old thumbnails
            openshot_thumbnails = os.path.join(info.USER_PATH, "thumbnails")
            if os.path.exists(openshot_thumbnails) and clear_thumbnails:
                # Clear thumbnails
                shutil.rmtree(openshot_thumbnails, True)
                os.mkdir(openshot_thumbnails)

            # Add to recent files setting
            self.add_to_recent_files(file_path)

            # Upgrade any data structures
            self.upgrade_project_data_structures()

        # Get app, and distribute all project data through update manager
        from classes.app import get_app
        get_app().updates.load(self._data)