diff --git a/src/classes/json_data.py b/src/classes/json_data.py index f71655613b..7d1b6bf838 100644 --- a/src/classes/json_data.py +++ b/src/classes/json_data.py @@ -54,12 +54,16 @@ def __init__(self): self._data = {} # Private data store, accessible through the get and set methods self.data_type = "json data" - # Regular expression for project files with possible corruption - self.version_re = re.compile(r'"openshot-qt".*"2.5.0') + # Regular expressions for file version detection of possible corruption + self.version_re_250 = re.compile(r'"openshot-qt".*"2.5.0') + self.version_re_260 = re.compile(r'"openshot-qt".*"2.6.0') # Regular expression matching likely corruption in project files self.damage_re = re.compile(r'/u([0-9a-fA-F]{4})') + # Regular expression matching likely windows drive letter corruption in project files + self.damage_re_windows_drives = re.compile(r'(\n\s*)(\w*):') + # Regular expression used to detect lost slashes, when repairing data self.slash_repair_re = re.compile(r'(["/][.]+)(/u[0-9a-fA-F]{4})') @@ -154,8 +158,27 @@ def read_from_file(self, file_path, path_mode="ignore"): if not contents: raise RuntimeError("Couldn't load {} file, no data.".format(self.data_type)) + # Scan for and correct possible OpenShot 2.6.0 corruption + if self.damage_re_windows_drives.search(contents) and self.version_re_260.search(contents): + # File contains corruptions, backup and repair + self.make_repair_backup(file_path, contents) + + # Repair lost quotes + contents = self.damage_re_windows_drives.sub(r'\1"\2":', contents) + + # We have to de- and re-serialize the data, to complete repairs + temp_data = json.loads(contents) + contents = json.dumps(temp_data, ensure_ascii=False, indent=1) + + # Save the repaired data back to the original file + with open(file_path, "w", encoding="utf-8") as fout: + fout.write(contents) + + msg_log = "Repaired windows drive corruptions in file {}" + log.info(msg_log.format(file_path)) + # Scan for and correct possible OpenShot 2.5.0 corruption - if self.damage_re.search(contents) and self.version_re.search(contents): + if self.damage_re.search(contents) and self.version_re_250.search(contents): # File contains corruptions, backup and repair self.make_repair_backup(file_path, contents) @@ -170,19 +193,13 @@ def read_from_file(self, file_path, path_mode="ignore"): # We have to de- and re-serialize the data, to complete repairs temp_data = json.loads(contents) contents = json.dumps(temp_data, ensure_ascii=False, indent=1) - temp_data = {} # Save the repaired data back to the original file with open(file_path, "w", encoding="utf-8") as fout: fout.write(contents) msg_log = "Repaired {} corruptions in file {}" - msg_local = self._("Repaired {num} corruptions in file {path}") log.info(msg_log.format(subs_count, file_path)) - if hasattr(self.app, "window") and hasattr(self.app.window, "statusBar"): - self.app.window.statusBar.showMessage( - msg_local.format(num=subs_count, path=file_path), 5000 - ) # Process JSON data if path_mode == "absolute": diff --git a/src/classes/project_data.py b/src/classes/project_data.py index 244ea7b8ac..0b7157199b 100644 --- a/src/classes/project_data.py +++ b/src/classes/project_data.py @@ -647,7 +647,7 @@ def read_legacy_project_file(self, file_path): # Increment track counter track_counter += 1 - except Exception: + except Exception as ex: # Error parsing legacy contents msg = "Failed to load legacy project file %(path)s" % {"path": file_path} log.error(msg, exc_info=1)