[pitivi] tmp. finish save.



commit cacffcff9f85b3a2c36f230c485f2cc742e879fb
Author: Alessandro Decina <alessandro decina collabora co uk>
Date:   Fri Mar 27 16:38:58 2009 +0100

    tmp. finish save.
---
 pitivi/formatters/etree.py |  234 ++++++++++++++++++++++++++++++++++++++++++++
 tests/test_formatter.py    |  233 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 454 insertions(+), 13 deletions(-)

diff --git a/pitivi/formatters/etree.py b/pitivi/formatters/etree.py
new file mode 100644
index 0000000..dccf239
--- /dev/null
+++ b/pitivi/formatters/etree.py
@@ -0,0 +1,234 @@
+# PiTiVi , Non-linear video editor
+#
+#       test_formatter.py
+#
+# Copyright (c) 2009, Edward Hervey <bilboed bilboed com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+from xml.etree.ElementTree import Element, SubElement, tostring
+
+from pitivi.reflect import qual
+from pitivi.factories.base import SourceFactory
+from pitivi.factories.file import FileSourceFactory
+from pitivi.timeline.track import SourceTrackObject
+from pitivi.formatters.base import Formatter
+
+version = "0.1"
+
+def indent(elem, level=0):
+    i = "\n" + level*"  "
+    if len(elem):
+        if not elem.text or not elem.text.strip():
+            elem.text = i + "  "
+        if not elem.tail or not elem.tail.strip():
+            elem.tail = i
+        for elem in elem:
+            indent(elem, level+1)
+        if not elem.tail or not elem.tail.strip():
+            elem.tail = i
+    else:
+        if level and (not elem.tail or not elem.tail.strip()):
+            elem.tail = i
+
+class ElementTreeFormatterContext(object):
+    def __init__(self):
+        self.streams = {}
+        self.factories = {}
+        self.track_objects = {}
+
+class ElementTreeFormatter(Formatter):
+    _element_id = 0
+
+    def _new_element_id(self):
+        element_id = self._element_id
+        self._element_id += 1
+
+        return str(element_id)
+
+    def _saveStream(self, stream, context):
+        element = Element("stream")
+        element.attrib["id"] = self._new_element_id()
+        element.attrib["type"] = qual(stream.__class__)
+        element.attrib["caps"] = str(stream.caps)
+
+        context.streams[stream] = element
+
+        return element
+
+    def _saveStreamRef(self, stream, context):
+        stream_element = context.streams[stream]
+        element = Element("stream-ref")
+        element.attrib["id"] = stream_element.attrib["id"]
+
+        return element
+
+    def _saveSource(self, source, context):
+        element = self._saveObjectFactory(source, context)
+        if isinstance(source, FileSourceFactory):
+            return self._saveFileSourceFactory(element, source, context)
+
+        return element
+
+    def _saveObjectFactory(self, factory, context):
+        element = Element("source")
+        element.attrib["id"] = self._new_element_id()
+        element.attrib["type"] = qual(factory.__class__)
+
+        input_streams_element = SubElement(element, "input-streams")
+        input_streams = factory.getInputStreams()
+        for stream in input_streams:
+            stream_element = self._saveStream(stream, context)
+            input_streams_element.append(stream_element)
+
+        output_streams_element = SubElement(element, "output-streams")
+        output_streams = factory.getOutputStreams()
+        for stream in output_streams:
+            stream_element = self._saveStream(stream, context)
+            output_streams_element.append(stream_element)
+
+        context.factories[factory] = element
+
+        return element
+
+    def _saveFileSourceFactory(self, element, source, context):
+        element.attrib["filename"] = source.filename
+
+        return element
+
+    def _saveFactoryRef(self, factory, context):
+        element = Element("factory-ref")
+        element.attrib["id"] = context.factories[factory].attrib["id"]
+
+        return element
+
+    def _saveFactories(self, factories, context):
+        element = Element("factories")
+        sources = SubElement(element, "sources")
+        for factory in factories:
+            if isinstance(factory, SourceFactory):
+                source_element = self._saveSource(factory, context)
+                sources.append(source_element)
+
+        return element
+
+    def _saveTrackObject(self, track_object, context):
+        element = Element("track-object")
+        element.attrib["id"] = self._new_element_id()
+        element.attrib["type"] = qual(track_object.__class__)
+        for attribute in ("start", "duration",
+                "in_point", "media_duration", "priority"):
+            element.attrib[attribute] = str(getattr(track_object, attribute))
+
+        factory_ref = \
+                self._saveFactoryRef(track_object.factory, context)
+        stream_ref = self._saveStreamRef(track_object.stream, context)
+
+        element.append(factory_ref)
+        element.append(stream_ref)
+
+        context.track_objects[track_object] = element
+
+        return element
+
+    def _saveTrackObjectRef(self, track_object, context):
+        element = Element("track-object-ref")
+        element.attrib["id"] = context.track_objects[track_object].attrib["id"]
+
+        return element
+
+    def _saveTrackObjectRefs(self, track_objects, context):
+        element = Element("track-object-refs")
+
+        for track_object in track_objects:
+            if track_object is track_object.track.default_track_object:
+                continue
+
+            track_object_ref = self._saveTrackObjectRef(track_object, context)
+            element.append(track_object_ref)
+
+        return element
+
+    def _saveTrack(self, track, context):
+        element = Element("track")
+        track_objects = SubElement(element, "track-objects")
+
+        for track_object in track.track_objects:
+            if track_object is track.default_track_object:
+                continue
+
+            track_object_element = self._saveTrackObject(track_object, context)
+            track_objects.append(track_object_element)
+
+        return element
+
+    def _saveTimelineObject(self, timeline_object, context):
+        element = Element("timeline-object")
+        factory_ref = self._saveFactoryRef(timeline_object.factory, context)
+        element.append(factory_ref)
+        track_object_refs = SubElement(element, "track-object-refs")
+        for track_object in timeline_object.track_objects:
+            track_object_ref = self._saveTrackObjectRef(track_object, context)
+            track_object_refs.append(track_object_ref)
+
+        return element
+
+    def _saveTimelineObjects(self, timeline_objects, context):
+        element = Element("timeline-objects")
+        for timeline_object in timeline_objects:
+            timeline_object_element = self._saveTimelineObject(timeline_object)
+            element.append(timeline_object_element)
+
+        return element
+
+    def _saveTracks(self, tracks, context):
+        element = Element("tracks")
+        for track in tracks:
+            track_element = self._saveTrack(track, context)
+            element.append(track_element)
+
+        return element
+
+    def _saveTimeline(self, timeline, context):
+        element = Element("timeline")
+
+        tracks = self._saveTracks(timeline.tracks, context)
+        element.append(tracks)
+
+        timeline_objects = \
+                self._saveTimelineObjects(timeline.timeline_objects, context)
+        element.append(timeline_objects)
+
+        return element
+
+    def _saveMainTag(self, context):
+        element = Element("pitivi")
+        element.attrib["formatter"] = "etree"
+        element.attrib["version"] = version
+
+        return element
+
+    def _saveProject(self, project, context):
+        root = self._saveMainTag(context)
+
+        factories = project.sources.sources.values()
+        factories_element = self._saveFactories(factories, context)
+        root.append(factories_element)
+
+        timeline_element = self._saveTimeline(project.timeline, context)
+        root.append(timeline_element)
+
+        return root
diff --git a/tests/test_formatter.py b/tests/test_formatter.py
index ed8da9f..9642f25 100644
--- a/tests/test_formatter.py
+++ b/tests/test_formatter.py
@@ -24,9 +24,14 @@ from StringIO import StringIO
 import gst
 
 from pitivi.reflect import qual, namedAny
-from pitivi.formatters.etree import ElementTreeFormatter
+from pitivi.formatters.etree import ElementTreeFormatter, \
+        ElementTreeFormatterContext, version
 from pitivi.stream import VideoStream, AudioStream
 from pitivi.factories.file import FileSourceFactory
+from pitivi.factories.test import VideoTestSourceFactory
+from pitivi.timeline.track import Track, SourceTrackObject
+from pitivi.timeline.timeline import Timeline, TimelineObject
+from pitivi.project import Project
 
 class FakeElementTreeFormatter(ElementTreeFormatter):
     pass
@@ -34,38 +39,240 @@ class FakeElementTreeFormatter(ElementTreeFormatter):
 class TestFormatterSave(TestCase):
     def setUp(self):
         self.formatter = FakeElementTreeFormatter()
+        self.context = ElementTreeFormatterContext()
 
     def testSaveStream(self):
         stream = VideoStream(gst.Caps("video/x-raw-rgb, blah=meh"))
-        element = self.formatter._saveStream(stream)
+        element = self.formatter._saveStream(stream, self.context)
         self.failUnlessEqual(element.tag, "stream")
         self.failUnless("id" in element.attrib)
         self.failUnlessEqual(element.attrib["type"], qual(stream.__class__))
         self.failUnlessEqual(element.attrib["caps"], str(stream.caps))
 
+    def testSaveStreamRef(self):
+        # save a stream so that a mapping is created in the context
+        stream = VideoStream(gst.Caps("video/x-raw-rgb, blah=meh"))
+        element = self.formatter._saveStream(stream, self.context)
+        element_ref = self.formatter._saveStreamRef(stream, self.context)
+        self.failUnlessEqual(element_ref.tag, "stream-ref")
+        self.failUnlessEqual(element_ref.attrib["id"], element.attrib["id"])
+
     def testSaveSource(self):
         video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
         audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
-        source = FileSourceFactory("file.ogg")
-        source.addOutputStream(video_stream)
-        source.addOutputStream(audio_stream)
-
-        element = self.formatter._saveSource(source)
+        source1 = FileSourceFactory("file1.ogg")
+        source1.addOutputStream(video_stream)
+        source1.addOutputStream(audio_stream)
+        element = self.formatter._saveSource(source1, self.context)
         self.failUnlessEqual(element.tag, "source")
-        self.failUnlessEqual(element.attrib["type"], qual(source.__class__))
-        self.failUnlessEqual(element.attrib["filename"], "file.ogg")
+        self.failUnlessEqual(element.attrib["type"], qual(source1.__class__))
+        self.failUnlessEqual(element.attrib["filename"], "file1.ogg")
 
         streams = element.find("output-streams")
         self.failUnlessEqual(len(streams), 2)
 
     def testSaveFactories(self):
-        raise NotImplementedError()
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+
+        source1 = FileSourceFactory("file1.ogg")
+        source1.addOutputStream(video_stream)
+        source1.addOutputStream(audio_stream)
+
+        source2 = FileSourceFactory("file2.ogg")
+        source2.addOutputStream(video_stream)
+        source2.addOutputStream(audio_stream)
+
+        factories = [source1, source2]
+        element = self.formatter._saveFactories(factories, self.context)
+        self.failUnlessEqual(element.tag, "factories")
+
+        sources = element.find("sources")
+        self.failUnlessEqual(len(sources), 2)
+        # source tags are tested in testSaveSource
+
+    def testSaveFactoryRef(self):
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+        source1 = FileSourceFactory("file1.ogg")
+        source1.addOutputStream(video_stream)
+        source1.addOutputStream(audio_stream)
+        element = self.formatter._saveSource(source1, self.context)
+
+        element_ref = self.formatter._saveFactoryRef(source1, self.context)
+        self.failUnlessEqual(element_ref.tag, "factory-ref")
+        self.failUnlessEqual(element_ref.attrib["id"], element.attrib["id"])
 
     def testSaveTrackObject(self):
-        raise NotImplementedError()
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+        source1 = FileSourceFactory("file1.ogg")
+
+        # these two calls are needed to populate the context for the -ref
+        # elements
+        self.formatter._saveSource(source1, self.context)
+        self.formatter._saveStream(video_stream, self.context)
+
+        track_object = SourceTrackObject(source1, video_stream,
+                start=10 * gst.SECOND, duration=20 * gst.SECOND,
+                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
+                priority=10)
+
+        element = self.formatter._saveTrackObject(track_object, self.context)
+        self.failUnlessEqual(element.tag, "track-object")
+        self.failUnlessEqual(element.attrib["type"],
+                qual(track_object.__class__))
+        self.failUnlessEqual(element.attrib["start"], str(10 * gst.SECOND))
+        self.failUnlessEqual(element.attrib["duration"], str(20 * gst.SECOND))
+        self.failUnlessEqual(element.attrib["in_point"], str(5 * gst.SECOND))
+        self.failUnlessEqual(element.attrib["media_duration"],
+                str(15 * gst.SECOND))
+        self.failUnlessEqual(element.attrib["priority"], str(10))
+
+        self.failIfEqual(element.find("factory-ref"), None)
+        self.failIfEqual(element.find("stream-ref"), None)
+
+    def testSaveTrackObjectRef(self):
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+        source1 = FileSourceFactory("file1.ogg")
+
+        # these two calls are needed to populate the context for the -ref
+        # elements
+        self.formatter._saveSource(source1, self.context)
+        self.formatter._saveStream(video_stream, self.context)
+
+        track_object = SourceTrackObject(source1, video_stream,
+                start=10 * gst.SECOND, duration=20 * gst.SECOND,
+                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
+                priority=10)
+
+        element = self.formatter._saveTrackObject(track_object, self.context)
+        element_ref = self.formatter._saveTrackObjectRef(track_object,
+                self.context)
+        self.failUnlessEqual(element_ref.tag, "track-object-ref")
+        self.failUnlessEqual(element.attrib["id"], element.attrib["id"])
 
     def testSaveTrack(self):
-        raise NotImplementedError()
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+        source1 = VideoTestSourceFactory()
+
+        # these two calls are needed to populate the context for the -ref
+        # elements
+        self.formatter._saveSource(source1, self.context)
+        self.formatter._saveStream(video_stream, self.context)
+
+        track_object = SourceTrackObject(source1, video_stream,
+                start=10 * gst.SECOND, duration=20 * gst.SECOND,
+                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
+                priority=10)
+
+        track = Track(video_stream)
+        track.addTrackObject(track_object)
+
+        element = self.formatter._saveTrack(track, self.context)
+        self.failUnlessEqual(element.tag, "track")
+        track_objects_element = element.find("track-objects")
+        self.failUnlessEqual(len(track_objects_element), 1)
+
+    def testSaveTimelineObject(self):
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+        source1 = FileSourceFactory("file1.ogg")
+
+        # these two calls are needed to populate the context for the -ref
+        # elements
+        self.formatter._saveSource(source1, self.context)
+        self.formatter._saveStream(video_stream, self.context)
+
+        track_object = SourceTrackObject(source1, video_stream,
+                start=10 * gst.SECOND, duration=20 * gst.SECOND,
+                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
+                priority=10)
+
+        self.formatter._saveTrackObject(track_object, self.context)
+
+        timeline_object = TimelineObject(source1)
+        timeline_object.addTrackObject(track_object)
+
+        element = self.formatter._saveTimelineObject(timeline_object, self.context)
+        self.failUnlessEqual(element.tag, "timeline-object")
+        self.failIfEqual(element.find("factory-ref"), None)
+        track_object_refs = element.find("track-object-refs")
+        self.failUnlessEqual(len(track_object_refs), 1)
 
     def testSaveTimeline(self):
-        raise NotImplementedError()
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+        source1 = VideoTestSourceFactory()
+
+        self.formatter._saveSource(source1, self.context)
+        self.formatter._saveStream(video_stream, self.context)
+
+        track_object = SourceTrackObject(source1, video_stream,
+                start=10 * gst.SECOND, duration=20 * gst.SECOND,
+                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
+                priority=10)
+
+        self.formatter._saveTrackObject(track_object, self.context)
+
+        track = Track(video_stream)
+        track.addTrackObject(track_object)
+
+        timeline_object = TimelineObject(source1)
+        timeline_object.addTrackObject(track_object)
+
+        self.formatter._saveTimelineObject(timeline_object, self.context)
+
+        timeline = Timeline()
+        timeline.addTrack(track)
+
+        element = self.formatter._saveTimeline(timeline, self.context)
+        self.failUnlessEqual(element.tag, "timeline")
+        tracks = element.find("tracks")
+        self.failUnlessEqual(len(tracks), 1)
+
+    def testSaveMainTag(self):
+        element = self.formatter._saveMainTag(self.context)
+        self.failUnlessEqual(element.tag, "pitivi")
+        self.failUnlessEqual(element.attrib["formatter"], "etree")
+        self.failUnlessEqual(element.attrib["version"], version)
+
+    def testSaveProject(self):
+        video_stream = VideoStream(gst.Caps("video/x-raw-yuv"))
+        audio_stream = AudioStream(gst.Caps("audio/x-raw-int"))
+        source1 = VideoTestSourceFactory()
+
+        self.formatter._saveSource(source1, self.context)
+        self.formatter._saveStream(video_stream, self.context)
+
+        track_object = SourceTrackObject(source1, video_stream,
+                start=10 * gst.SECOND, duration=20 * gst.SECOND,
+                in_point=5 * gst.SECOND, media_duration=15 * gst.SECOND,
+                priority=10)
+
+        self.formatter._saveTrackObject(track_object, self.context)
+
+        track = Track(video_stream)
+        track.addTrackObject(track_object)
+
+        timeline_object = TimelineObject(source1)
+        timeline_object.addTrackObject(track_object)
+
+        self.formatter._saveTimelineObject(timeline_object, self.context)
+
+        timeline = Timeline()
+        timeline.addTrack(track)
+
+        self.formatter._saveTimeline(timeline, self.context)
+
+        project = Project()
+        project.timeline = timeline
+        project.sources.addFactory("meh", source1)
+
+        element = self.formatter._saveProject(project, self.context)
+
+        self.failUnlessEqual(element.tag, "pitivi")
+        self.failIfEqual(element.find("factories"), None)
+        self.failIfEqual(element.find("timeline"), None)



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