[pitivi] previewers: Stop symlinking cache files for proxies



commit 65ed685672428fd5d0cd5572eee90b89d6a79aad
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Tue Sep 3 22:52:30 2019 +0200

    previewers: Stop symlinking cache files for proxies
    
    Instead of symlinking the cache files for proxies to the cache files for
    the original assets, we simply use the cache for the original asset.
    
    This simplifies the logic and avoids opening the same sqlite file
    multiple times.

 pitivi/timeline/previewers.py | 70 ++++++++++++++-----------------------------
 pitivi/utils/proxy.py         | 14 ++++++---
 2 files changed, 33 insertions(+), 51 deletions(-)
---
diff --git a/pitivi/timeline/previewers.py b/pitivi/timeline/previewers.py
index 6170380e..ec9a7fe0 100644
--- a/pitivi/timeline/previewers.py
+++ b/pitivi/timeline/previewers.py
@@ -42,6 +42,7 @@ from pitivi.utils.misc import quantize
 from pitivi.utils.misc import quote_uri
 from pitivi.utils.pipeline import MAX_BRINGING_TO_PAUSED_DURATION
 from pitivi.utils.proxy import get_proxy_target
+from pitivi.utils.proxy import ProxyManager
 from pitivi.utils.system import CPUUsageTracker
 from pitivi.utils.timeline import Zoomable
 from pitivi.utils.ui import EXPANDED_SIZE
@@ -90,7 +91,7 @@ class PreviewerBin(Gst.Bin, Loggable):
         srcpad, = [pad for pad in self.internal_bin.iterate_src_pads()]
         self.add_pad(Gst.GhostPad.new(None, srcpad))
 
-    def finalize(self, proxy=None):
+    def finalize(self):
         """Finalizes the previewer, saving data to the disk if needed."""
 
 
@@ -137,11 +138,9 @@ class TeedThumbnailBin(PreviewerBin):
 
         return Gst.Bin.do_post_message(self, message)
 
-    def finalize(self, proxy=None):
+    def finalize(self):
         """Finalizes the previewer, saving data to file if needed."""
         self.thumb_cache.commit()
-        if proxy:
-            self.thumb_cache.copy(proxy.get_id())
 
     def do_get_property(self, prop):
         if prop.name == 'uri':
@@ -252,7 +251,7 @@ class WaveformPreviewer(PreviewerBin):
 
         return Gst.Bin.do_post_message(self, message)
 
-    def finalize(self, proxy=None):
+    def finalize(self):
         """Finalizes the previewer, saving data to file if needed."""
         if not self.passthrough and self.peaks:
             # Let's go mono.
@@ -266,15 +265,6 @@ class WaveformPreviewer(PreviewerBin):
 
             self.samples = samples
 
-        if proxy and not proxy.get_error():
-            proxy_wavefile = get_wavefile_location_for_uri(proxy.get_id())
-            self.debug("symlinking %s and %s", self.wavefile, proxy_wavefile)
-            try:
-                os.remove(proxy_wavefile)
-            except FileNotFoundError:
-                pass
-            os.symlink(self.wavefile, proxy_wavefile)
-
 
 Gst.Element.register(None, "waveformbin", Gst.Rank.NONE,
                      WaveformPreviewer)
@@ -817,8 +807,6 @@ class VideoPreviewer(Gtk.Layout, AssetPreviewer, Zoomable):
         self.ges_elem = ges_elem
         self.thumbs = {}
 
-        self._ensure_proxy_thumbnails_cache()
-
         # Connect signals and fire things up
         self.ges_elem.connect("notify::in-point", self._inpoint_changed_cb)
         self.ges_elem.connect("notify::duration", self._duration_changed_cb)
@@ -870,12 +858,6 @@ class VideoPreviewer(Gtk.Layout, AssetPreviewer, Zoomable):
         if queue:
             self.become_controlled()
 
-    def _ensure_proxy_thumbnails_cache(self):
-        """Ensures that both the target asset and the proxy assets have caches."""
-        uri = quote_uri(self.ges_elem.props.uri)
-        if self.uri != uri:
-            self.thumb_cache.copy(uri)
-
     def _set_pixbuf(self, pixbuf, position):
         """Sets the pixbuf for the thumbnail at the expected position."""
         try:
@@ -926,10 +908,10 @@ class ThumbnailCache(Loggable):
 
     def __init__(self, uri):
         Loggable.__init__(self)
-        self._filehash = hash_file(Gst.uri_get_location(uri))
-        thumbs_cache_dir = get_dir(os.path.join(xdg_cache_home(), "thumbs"))
-        self._dbfile = os.path.join(thumbs_cache_dir, self._filehash)
-        self._db = sqlite3.connect(self._dbfile)
+        self.uri = uri
+        self.dbfile = self.dbfile_name(uri)
+        self.log("Caching thumbs for %s in %s", uri, self.dbfile)
+        self._db = sqlite3.connect(self.dbfile)
         self._cur = self._db.cursor()
         self._cur.execute("CREATE TABLE IF NOT EXISTS Thumbs "
                           "(Time INTEGER NOT NULL PRIMARY KEY, "
@@ -945,6 +927,13 @@ class ThumbnailCache(Loggable):
         self._cur.execute("SELECT Time FROM Thumbs")
         return {row[0] for row in self._cur.fetchall()}
 
+    @staticmethod
+    def dbfile_name(uri):
+        """Returns the cache file path for the specified URI."""
+        filename = hash_file(Gst.uri_get_location(uri))
+        thumbs_cache_dir = get_dir(os.path.join(xdg_cache_home(), "thumbs"))
+        return os.path.join(thumbs_cache_dir, filename)
+
     @classmethod
     def get(cls, obj):
         """Gets a ThumbnailCache for the specified object.
@@ -963,26 +952,13 @@ class ThumbnailCache(Loggable):
         else:
             raise ValueError("Unhandled type: %s" % type(obj))
 
+        if ProxyManager.is_proxy_asset(uri):
+            uri = ProxyManager.getTargetUri(uri)
+
         if uri not in cls.caches_by_uri:
             cls.caches_by_uri[uri] = ThumbnailCache(uri)
         return cls.caches_by_uri[uri]
 
-    def copy(self, uri):
-        """Copies `self` to the specified `uri`.
-
-        Args:
-            uri (str): The place where to copy/save the ThumbnailCache
-        """
-        filehash = hash_file(Gst.uri_get_location(uri))
-        thumbs_cache_dir = get_dir(os.path.join(xdg_cache_home(), "thumbs"))
-        dbfile = os.path.join(thumbs_cache_dir, filehash)
-
-        try:
-            os.remove(dbfile)
-        except FileNotFoundError:
-            pass
-        os.symlink(self._dbfile, dbfile)
-
     @property
     def image_size(self):
         """Gets the image size.
@@ -1065,11 +1041,13 @@ class ThumbnailCache(Loggable):
     def commit(self):
         """Saves the cache on disk (in the database)."""
         self._db.commit()
-        self.log("Saved thumbnail cache file: %s", self._filehash)
+        self.log("Saved thumbnail cache file")
 
 
 def get_wavefile_location_for_uri(uri):
     """Computes the URI where the wave.npy file should be stored."""
+    if ProxyManager.is_proxy_asset(uri):
+        uri = ProxyManager.getTargetUri(uri)
     filename = hash_file(Gst.uri_get_location(uri)) + ".wave.npy"
     cache_dir = get_dir(os.path.join(xdg_cache_home(), "waves"))
 
@@ -1110,7 +1088,6 @@ class AudioPreviewer(Gtk.Layout, Previewer, Zoomable, Loggable):
 
     def _startLevelsDiscovery(self):
         filename = get_wavefile_location_for_uri(self._uri)
-
         if os.path.exists(filename):
             with open(filename, "rb") as samples:
                 self.samples = self._scale_samples(numpy.load(samples))
@@ -1136,7 +1113,7 @@ class AudioPreviewer(Gtk.Layout, Previewer, Zoomable, Loggable):
 
     def _launchPipeline(self):
         self.debug(
-            'Now generating waveforms for: %s', path_from_uri(self._uri))
+            "Now generating waveforms for: %s", path_from_uri(self._uri))
         self.pipeline = Gst.parse_launch("uridecodebin name=decode uri=" +
                                          self._uri + " ! waveformbin name=wave"
                                          " ! fakesink qos=false name=faked")
@@ -1159,8 +1136,7 @@ class AudioPreviewer(Gtk.Layout, Previewer, Zoomable, Loggable):
         bus.connect("message", self._busMessageCb)
 
     def _prepareSamples(self):
-        proxy = self.ges_elem.get_parent().get_asset().get_proxy_target()
-        self._wavebin.finalize(proxy=proxy)
+        self._wavebin.finalize()
         self.samples = self._scale_samples(self._wavebin.samples)
 
     def _busMessageCb(self, bus, message):
diff --git a/pitivi/utils/proxy.py b/pitivi/utils/proxy.py
index e46e5794..f823380e 100644
--- a/pitivi/utils/proxy.py
+++ b/pitivi/utils/proxy.py
@@ -230,8 +230,14 @@ class ProxyManager(GObject.Object, Loggable):
         self.emit("error-preparing-asset", None, proxy, proxy.get_error())
         return False
 
-    def getTargetUri(self, proxy_asset):
-        return ".".join(proxy_asset.props.id.split(".")[:-3])
+    @classmethod
+    def getTargetUri(cls, obj):
+        if isinstance(obj, GES.Asset):
+            uri = obj.props.id
+        else:
+            uri = obj
+
+        return ".".join(uri.split(".")[:-3])
 
     def getProxyUri(self, asset):
         """Returns the URI of a possible proxy file.
@@ -317,8 +323,8 @@ class ProxyManager(GObject.Object, Loggable):
             if not self.__assetsMatch(asset, proxy):
                 return self.__createTranscoder(asset)
         else:
-            transcoder.props.pipeline.props.video_filter.finalize(proxy)
-            transcoder.props.pipeline.props.audio_filter.finalize(proxy)
+            transcoder.props.pipeline.props.video_filter.finalize()
+            transcoder.props.pipeline.props.audio_filter.finalize()
 
             del transcoder
 


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