[pitivi] Reload factories when loading xptv projects.



commit 1f996c75e0ff112d5a4a7545935f12e1e2e668be
Author: Alessandro Decina <alessandro d gmail com>
Date:   Fri Jun 5 19:10:02 2009 +0200

    Reload factories when loading xptv projects.
---
 pitivi/formatters/base.py     |    1 +
 pitivi/formatters/etree.py    |   96 ++++++++++++++++++++++++++++++++++++++++-
 pitivi/formatters/playlist.py |    4 +-
 tests/test_projectmanager.py  |    8 ++--
 4 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/pitivi/formatters/base.py b/pitivi/formatters/base.py
index 0b3fff6..f49c134 100644
--- a/pitivi/formatters/base.py
+++ b/pitivi/formatters/base.py
@@ -125,6 +125,7 @@ class Formatter(Signallable, Loggable):
         # FIXME : maybe have a convenience method for opening a location
         self._loadProject(location, project)
 
+    def _finishLoadingProject(self, project):
         self.debug("About to get used sources")
         # ask for all sources being used
         uris = []
diff --git a/pitivi/formatters/etree.py b/pitivi/formatters/etree.py
index af93805..da85d60 100644
--- a/pitivi/formatters/etree.py
+++ b/pitivi/formatters/etree.py
@@ -31,9 +31,10 @@ from pitivi.factories.base import SourceFactory
 from pitivi.factories.file import FileSourceFactory
 from pitivi.timeline.track import Track
 from pitivi.timeline.timeline import TimelineObject
-from pitivi.formatters.base import Formatter
+from pitivi.formatters.base import Formatter, FormatterError
 from pitivi.utils import get_filesystem_encoding
 from pitivi.settings import ExportSettings
+from pitivi.stream import match_stream_groups_map
 
 version = "0.1"
 
@@ -226,10 +227,17 @@ class ElementTreeFormatter(Formatter):
         return element
 
     def _loadSources(self):
+        try:
+            return self._sources
+        except AttributeError:
+            pass
+
         sources = self.factoriesnode.find("sources")
         res = []
         for src in sources:
             res.append(self._loadFactory(src))
+
+        self._sources = res
         return res
 
     def _serializeDict(self, element, dict):
@@ -535,7 +543,7 @@ class ElementTreeFormatter(Formatter):
         f.write(tostring(root))
         f.close()
 
-    def _loadProject(self, location, project=None):
+    def _loadProject(self, location, project):
         self.debug("location:%s, project:%r", location, project)
         # open the given location
         self._context.rootelement = parse(location.split('://', 1)[1])
@@ -545,6 +553,90 @@ class ElementTreeFormatter(Formatter):
         if project and self._settingsnode != None:
             project.setSettings(self._loadProjectSettings(self._settingsnode))
 
+        # rediscover the factories
+        closure = {"rediscovered": 0}
+        sources = self._loadSources()
+        uris = [source.uri for source in sources]
+        discoverer = project.sources.discoverer
+        discoverer.connect("discovery-done", self._discovererDiscoveryDoneCb,
+                project, sources, uris, closure)
+        discoverer.connect("discovery-error", self._discovererDiscoveryErrorCb,
+                project, sources, uris, closure)
+
+        # start the rediscovering from the first source
+        source = sources[0]
+        discoverer.addUri(source.uri)
+
+    def _discovererDiscoveryDoneCb(self, discoverer, uri, factory,
+            project, sources, uris, closure):
+        if factory.uri not in uris:
+            # someone else is using discoverer, this signal isn't for us
+            return
+
+        match = None
+        for i, source in enumerate(sources):
+            if source.uri == factory.uri:
+                match = i
+                break
+
+        assert match is not None
+
+        # replace the old source with the new one
+        old_factory = sources[match]
+        sources[match] = factory
+        closure["rediscovered"] += 1
+
+        key = None
+        for k, old_factory1 in self._context.factories.iteritems():
+            if old_factory is old_factory1:
+                key = k
+                break
+
+        assert key is not None
+
+        self._context.factories[key] = factory
+
+        # now replace the streams
+        old_streams = old_factory.getOutputStreams()
+        streams = factory.getOutputStreams()
+        if len(old_streams) != len(streams):
+            self.emit("new-project-failed", uri,
+                    FormatterError("cant find all streams"))
+            return
+
+        stream_map = match_stream_groups_map(old_streams, streams)
+        if len(stream_map) != len(old_streams):
+            self.emit("new-project-failed", uri,
+                    FormatterError("streams don't match"))
+            return
+
+        new_streams = {}
+        for stream_id, old_stream in self._context.streams.iteritems():
+            try:
+                new_stream = stream_map[old_stream]
+            except KeyError:
+                new_stream = old_stream
+
+            new_streams[stream_id] = new_stream
+        self._context.streams = new_streams
+
+        if closure["rediscovered"] == len(sources):
+            self._finishLoadingProject(project)
+            return
+
+        # schedule the next source
+        next = sources[closure["rediscovered"]]
+        discoverer.addUri(next.uri)
+
+    def _discovererDiscoveryErrorCb(self, discoverer, uri, error, detail,
+            project, sources, uris, closure):
+        if factory.uri not in uris:
+            # someone else is using discoverer, this signal isn't for us
+            return
+
+        self.emit("new-project-failed", uri,
+                FormatterError("%s: %s" % (error, detail)))
+
     def newProject(self):
         project = Formatter.newProject(self)
         # add the settings
diff --git a/pitivi/formatters/playlist.py b/pitivi/formatters/playlist.py
index 1ca313c..0f9fde2 100644
--- a/pitivi/formatters/playlist.py
+++ b/pitivi/formatters/playlist.py
@@ -41,7 +41,7 @@ class PlaylistFormatter(LoadOnlyFormatter):
             return 'file://' + ln.strip()
         return 'file://' + os.path.join(self._basedir, ln.strip())
 
-    def _loadProject(self, location, project=None):
+    def _loadProject(self, location, project):
         path = location.split('file://', 1)[1]
         self._basedir = os.path.dirname(path)
         res = []
@@ -54,6 +54,8 @@ class PlaylistFormatter(LoadOnlyFormatter):
                 res.append(val)
         self._uris = res
 
+        self._finishLoadingProject(project)
+
     def _getSources(self):
         return self._uris
 
diff --git a/tests/test_projectmanager.py b/tests/test_projectmanager.py
index 9d0938d..e115442 100644
--- a/tests/test_projectmanager.py
+++ b/tests/test_projectmanager.py
@@ -143,8 +143,8 @@ class TestProjectManager(TestCase):
             def _validateUri(self, uri):
                 pass
 
-            def _loadProject(self, location, project=None):
-                pass
+            def _loadProject(self, location, project):
+                self._finishLoadingProject(project)
 
             def _getSources(self):
                 # this will emit missing-uri
@@ -175,8 +175,8 @@ class TestProjectManager(TestCase):
             def _validateUri(self, uri):
                 pass
 
-            def _loadProject(self, location, project=None):
-                pass
+            def _loadProject(self, location, project):
+                self._finishLoadingProject(project)
 
             def _getSources(self):
                 return []



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