[pitivi] preset: Allow renaming and removing any preset



commit 9066b803327c2b4b9bb10f9cb7eb617431c538da
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Thu May 28 10:23:08 2015 +0200

    preset: Allow renaming and removing any preset
    
    Differential Revision: https://phabricator.freedesktop.org/D367
    Reviewed-by: Thibault Saunier <tsaunier gnome org>

 pitivi/preset.py     |   74 +++++++++++++++++++++++--------------------------
 tests/test_preset.py |   42 ++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 39 deletions(-)
---
diff --git a/pitivi/preset.py b/pitivi/preset.py
index 475c215..c3f9c52 100644
--- a/pitivi/preset.py
+++ b/pitivi/preset.py
@@ -28,7 +28,6 @@ from gi.repository import Gtk
 from gettext import gettext as _
 
 from pitivi.settings import xdg_data_home
-from pitivi.utils.misc import isWritable
 from pitivi.configure import get_renderpresets_dir, get_audiopresets_dir, get_videopresets_dir
 from pitivi.utils import system
 from pitivi.utils.loggable import Loggable
@@ -80,13 +79,13 @@ class PresetManager(Loggable):
         self.system = system.getSystem()
 
     def loadAll(self):
-        self._loadFromDir(self.default_path)
+        self._loadFromDir(self.default_path, extra={"readonly": True})
         if os.path.isfile(self.user_path):
             # We used to save presets as a single file instead of a directory
             os.rename(self.user_path, "%s.old" % self.user_path)
         self._loadFromDir(self.user_path)
 
-    def _loadFromDir(self, presets_dir):
+    def _loadFromDir(self, presets_dir, extra={}):
         try:
             files = os.listdir(presets_dir)
         except FileNotFoundError:
@@ -98,12 +97,17 @@ class PresetManager(Loggable):
                 with open(filepath) as section:
                     parser = json.loads(section.read())
                 name = parser["name"]
+                if parser.get("removed"):
+                    self._forgetPreset(name)
+                    continue
                 try:
                     preset = self._deserializePreset(parser)
                 except DeserializeException as e:
                     self.error("Failed to load preset %s: %s", filepath, e)
                     continue
                 preset["filepath"] = filepath
+                for key, value in extra.items():
+                    preset[key] = value
                 self._addPreset(name, preset)
 
     def saveAll(self):
@@ -117,8 +121,7 @@ class PresetManager(Loggable):
         try:
             file_path = self.presets[preset_name]["filepath"]
         except KeyError:
-            file_name = self.system.getUniqueFilename(preset_name + ".json")
-            file_path = os.path.join(self.user_path, file_name)
+            file_path = self._buildFilePath(preset_name)
             self.presets[preset_name]["filepath"] = file_path
         with open(file_path, "w") as fout:
             values = self.presets[preset_name]
@@ -127,6 +130,10 @@ class PresetManager(Loggable):
             serialized = json.dumps(raw, indent=4)
             fout.write(serialized)
 
+    def _buildFilePath(self, preset_name):
+        file_name = self.system.getUniqueFilename(preset_name + ".json")
+        return os.path.join(self.user_path, file_name)
+
     def getUniqueName(self, first=_("Custom"), second=_("Custom %d")):
         name = first
         i = 1
@@ -193,11 +200,14 @@ class PresetManager(Loggable):
         else:
             # We're renaming an unsaved preset, so just pop it from the list
             self.presets.pop(old_name)
-        new_filepath = os.path.join(self.user_path, new_name + ".json")
+        new_filepath = self._createUserPresetPath(new_name)
         self.presets[new_name]["filepath"] = new_filepath
         self.cur_preset = new_name
         self.saveCurrentPreset()
 
+    def _createUserPresetPath(self, preset_name):
+        return os.path.join(self.user_path, preset_name + ".json")
+
     def hasPreset(self, name):
         name = name.lower()
         return any(name == preset.lower() for preset in self.getPresetNames())
@@ -264,21 +274,29 @@ class PresetManager(Loggable):
     def removePreset(self, name=None):
         if name is None:
             name = self.cur_preset
-        try:
-            # Deletes json file if exists
-            os.remove(self.presets[name]["filepath"])
-        except KeyError:
-            # Trying to remove a preset that has not actually been saved
-            return
-        except Exception:
-            raise
+        preset = self.presets[name]
+        filepath = preset.get("filepath")
+        if filepath:
+            if "readonly" in preset:
+                self._markRemoved(name)
+            else:
+                os.remove(filepath)
+        if self.cur_preset == name:
+            self.cur_preset = None
+        self._forgetPreset(name)
+
+    def _forgetPreset(self, name):
         self.presets.pop(name)
         for i, row in enumerate(self.ordered):
             if row[0] == name:
                 del self.ordered[i]
                 break
-        if self.cur_preset == name:
-            self.cur_preset = None
+
+    def _markRemoved(self, name):
+        data = json.dumps({"name": name, "removed": True}, indent=4)
+        filepath = self._createUserPresetPath(name)
+        with open(filepath, "w") as fout:
+            fout.write(data)
 
     def prependPreset(self, name, values):
         self.presets[name] = values
@@ -291,18 +309,7 @@ class PresetManager(Loggable):
             return False
         if "volatile" in self.presets[self.cur_preset]:
             return False
-        try:
-            full_path = self.presets[self.cur_preset]["filepath"]
-        except KeyError:
-            # This is a newly created preset that has not yet been saved
-            return True
-        (dir, name) = os.path.split(full_path)
-        if dir == self.default_path or not isWritable(full_path):
-            # default_path is the system-wide directory where the default
-            # presets are installed; they are not expected to be editable.
-            return False
-        else:
-            return self._isCurrentPresetChanged()
+        return self._isCurrentPresetChanged()
 
     def isRemoveButtonSensitive(self):
         """Whether the Remove button should be enabled"""
@@ -310,17 +317,6 @@ class PresetManager(Loggable):
             return False
         if "volatile" in self.presets[self.cur_preset]:
             return False
-        try:
-            full_path = self.presets[self.cur_preset]["filepath"]
-            (dir, name) = os.path.split(full_path)
-        except KeyError:
-            # This is a newly created preset that has not yet been saved
-            # We cannot remove it since it does not exist
-            return False
-        if dir == self.default_path or not isWritable(full_path):
-            # default_path is the system-wide directory where the default
-            # presets are installed; they are not expected to be editable.
-            return False
         return True
 
     def _projectToPreset(self, project):
diff --git a/tests/test_preset.py b/tests/test_preset.py
index 3a6dd69..89ae476 100644
--- a/tests/test_preset.py
+++ b/tests/test_preset.py
@@ -177,3 +177,45 @@ class TestAudioPresetsIO(TestCase):
             other_manager), len(other_manager.presets))
         other_values = other_manager.presets[preset_name]
         self.assertEqual(values, other_values)
+
+    def testRemovingSystemPresets(self):
+        self.manager.loadAll()
+        system_presets = list(self.manager.presets.keys())
+        for preset_name in system_presets:
+            self.manager.removePreset(preset_name)
+
+        # Check that the files have not been deleted or changed.
+        other_manager = AudioPresetManager()
+        other_manager.user_path = "/pitivi/non/existing/directory"
+        other_manager.loadAll()
+        for preset_name in system_presets:
+            self.assertTrue(other_manager.hasPreset(preset_name))
+
+        # Check that overwrite files have been created and
+        # they mark the system presets as deleted.
+        other_manager = self.createOtherManager()
+        other_manager.loadAll()
+        for preset_name in system_presets:
+            self.assertFalse(other_manager.hasPreset(preset_name))
+
+    def testRenamingSystemPresets(self):
+        self.manager.loadAll()
+        system_presets = list(self.manager.presets.keys())
+        new_name_template = "%s new"
+        for preset_name in system_presets:
+            new_name = new_name_template % preset_name
+            self.manager.renamePreset(preset_name, new_name)
+
+        # Check that the files have not been deleted or changed.
+        other_manager = AudioPresetManager()
+        other_manager.user_path = "/pitivi/non/existing/directory"
+        other_manager.loadAll()
+        for preset_name in system_presets:
+            self.assertTrue(other_manager.hasPreset(preset_name), preset_name)
+
+        other_manager = self.createOtherManager()
+        other_manager.loadAll()
+        for preset_name in system_presets:
+            self.assertFalse(other_manager.hasPreset(preset_name), preset_name)
+            new_name = new_name_template % preset_name
+            self.assertTrue(other_manager.hasPreset(new_name), new_name)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]