[pitivi] tmp. finish save.
- From: Edward Hervey <edwardrv src gnome org>
- To: svn-commits-list gnome org
- Subject: [pitivi] tmp. finish save.
- Date: Fri, 17 Apr 2009 09:35:40 -0400 (EDT)
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]