Skip to content

Commit

Permalink
Project data: Tweak autosave
Browse files Browse the repository at this point in the history
- project.save(make_paths_relative=False, move_temp_files=False) both
  replaced with backup_only=True, which does the same plus adds
  additional protections against unwanted actions
- Backup-only save files will now retain absolute paths, as was
  apparently intended (make_paths_relative=False was being ignored)
  • Loading branch information
ferdnyc committed Dec 9, 2021
1 parent f13df1e commit 15392cd
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 60 deletions.
6 changes: 2 additions & 4 deletions src/classes/json_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,7 @@ def read_from_file(self, file_path, path_mode="ignore"):
msg = "Couldn't load {} file".format(self.data_type)
log.error(msg, exc_info=1)
raise Exception(msg) from ex
msg = ()
log.warning(msg)
raise Exception(msg)
raise Exception("Unknown error (should be unreachable)")

def write_to_file(self, file_path, data, path_mode="ignore", previous_path=None):
""" Save JSON settings to a file """
Expand All @@ -229,7 +227,7 @@ def write_to_file(self, file_path, data, path_mode="ignore", previous_path=None)
except Exception as ex:
msg = "Couldn't save {} file:\n{}\n{}".format(self.data_type, file_path, ex)
log.error(msg)
raise Exception(msg)
raise ex

def replace_string_to_absolute(self, match):
"""Replace matched string for converting paths to relative paths"""
Expand Down
28 changes: 15 additions & 13 deletions src/classes/project_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,37 +781,39 @@ def is_keyframe_valid(self, keyframe, default_value):
points[0].get("co", {}).get("Y", default_value) != default_value,
])

def save(self, file_path, move_temp_files=True, make_paths_relative=True):
def save(self, file_path, backup_only=False):
""" Save project file to disk """
import openshot

log.info("Saving project file: %s", 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)
if not backup_only:
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)
self.write_to_file(
file_path,
self._data,
path_mode="ignore" if backup_only else "relative",
previous_path=self.current_filepath if not backup_only else None)

# On success, save current filepath
self.current_filepath = file_path
if not backup_only:
# On success, save current filepath
self.current_filepath = file_path

# Update info paths to assets folders
if move_temp_files:
# Update info paths to assets folders
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
self.add_to_recent_files(file_path)
self.has_unsaved_changes = False

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. """
Expand Down
84 changes: 41 additions & 43 deletions src/windows/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,55 +599,53 @@ def auto_save_project(self):

# Get current filepath (if any)
file_path = app.project.current_filepath
if app.project.needs_save():
log.info("auto_save_project")
if not app.project.needs_save():
return

if file_path:
# A Real project file exists
# Append .osp if needed
if ".osp" not in file_path:
if file_path:
# A Real project file exists
# Append .osp if needed
if ".osp" not in file_path:
file_path = "%s.osp" % file_path
folder_path, file_name = os.path.split(file_path)
file_name, file_ext = os.path.splitext(file_name)

# Make copy of unsaved project file in 'recovery' folder
recover_path_with_timestamp = os.path.join(
info.RECOVERY_PATH, "%d-%s.osp" % (int(time.time()), file_name))
if os.path.exists(file_path):
shutil.copy(file_path, recover_path_with_timestamp)
else:
log.warning("Existing project *.osp file not found during recovery process: %s" % file_path)

# Find any recovery file older than X auto-saves
old_backup_files = []
backup_file_count = 0
for backup_filename in reversed(sorted(os.listdir(info.RECOVERY_PATH))):
if ".osp" in backup_filename:
backup_file_count += 1
if backup_file_count > s.get("recovery-limit"):
old_backup_files.append(os.path.join(info.RECOVERY_PATH, backup_filename))
folder_path, file_name = os.path.split(file_path)
file_name, file_ext = os.path.splitext(file_name)

# Delete recovery files which are 'too old'
for backup_filepath in old_backup_files:
os.unlink(backup_filepath)

# Save project
log.info("Auto save project file: %s", file_path)
self.save_project(file_path)
# Make copy of unsaved project file in 'recovery' folder
recover_path_with_timestamp = os.path.join(
info.RECOVERY_PATH, "%d-%s.osp" % (int(time.time()), file_name))
if os.path.exists(file_path):
shutil.copy(file_path, recover_path_with_timestamp)
else:
log.warning(
"Existing project *.osp file not found during recovery process: %s",
file_path)

# Find any recovery file older than X auto-saves
old_backup_files = []
backup_file_count = 0
for backup_filename in reversed(sorted(os.listdir(info.RECOVERY_PATH))):
if ".osp" in backup_filename:
backup_file_count += 1
if backup_file_count > s.get("recovery-limit"):
old_backup_files.append(os.path.join(info.RECOVERY_PATH, backup_filename))

# Delete recovery files which are 'too old'
for backup_filepath in old_backup_files:
os.unlink(backup_filepath)

# Remove backup.osp (if any)
if os.path.exists(info.BACKUP_FILE):
# Delete backup.osp since we just saved the actual project
os.unlink(info.BACKUP_FILE)
# Save project
log.info("Auto save project file: %s", file_path)
self.save_project(file_path)

else:
# No saved project found
log.info("Creating backup of project file: %s", info.BACKUP_FILE)
app.project.save(info.BACKUP_FILE, move_temp_files=False, make_paths_relative=False)
# Remove backup.osp (if any)
if os.path.exists(info.BACKUP_FILE):
# Delete backup.osp since we just saved the actual project
os.unlink(info.BACKUP_FILE)

# Clear the file_path (which is set by saving the project)
app.project.current_filepath = None
app.project.has_unsaved_changes = True
else:
# No saved project found
log.info("Creating backup of project file: %s", info.BACKUP_FILE)
app.project.save(info.BACKUP_FILE, backup_only=True)

def actionSaveAs_trigger(self):
app = get_app()
Expand Down

0 comments on commit 15392cd

Please sign in to comment.