Commits

Jason R. Coombs committed ad3a076

Added as_stream to zippack so a package can be easily handed off to as a stream (such as in an HTTP response).
Added a test for saving and reloading empty packages. Fixed an issue that emerged where relationships weren't loaded and saved the same way if there were no relationships present. Unified the relationship dump/store mechanism by moving it to the Relationships class.

  • Participants
  • Parent commits 6a30b90

Comments (0)

Files changed (3)

File openpack/basepack.py

 
 	def _load_rels(self, source):
 		"""Load relationships from source XML."""
-		elem = fromstring(source)
-		for rel in elem:
-			mode = rel.get('TargetMode')
-			target = rel.get('Target')
-			rtype = rel.get('Type')
-			id = rel.get('Id')
-			relationship = Relationship(self, target, rtype, id, mode)
-			self.relationships.add(relationship)
+		# don't get confused here - the original source is string data;
+		#  the parameter source below is a Part object
+		self.relationships.load(source=self, data=source)
 
 class Package(DictMixin, Relational):
 	"""A base class for an OPC package.
 	relationships = relationships()
   
 	def dump(self):
-		if not self.children:
-			return ''
 		rels = Element(self.xmlns + 'Relationships', nsmap={None:self.xmlns.strip('{}')})
 		for rel in self:
 			rels.append(Element(
 			))
 		return tostring(rels, encoding=self.encoding)
 
+	def load(self, source, data):
+		"""
+		@param source The source Part for each relationship in this
+		              collection
+		@ptype source Part
+		@param data Relationship XML from a previous dump operation
+		@ptype data string
+		"""
+		elem = fromstring(data)
+		for rel in elem:
+			mode = rel.get('TargetMode')
+			target = rel.get('Target')
+			rtype = rel.get('Type')
+			id = rel.get('Id')
+			relationship = Relationship(source, target, rtype, id, mode)
+			self.add(relationship)
+
 	def __iter__(self):
 		return iter(self.children)
 

File openpack/zippack.py

 import posixpath
 import functools
 from zipfile import ZipFile, ZIP_DEFLATED, ZipInfo
+try: from cStringIO import StringIO
+except ImportError: from StringIO import StringIO
 
 from basepack import Package, Part, Relationship, Relationships
 from util import get_handler
 		self._store(open(target, 'wb'))
 		self.filename = target
 
+	def as_stream(self):
+		"""
+		Return a zipped package as a readable stream
+		"""
+		stream = StringIO()
+		self._store(stream)
+		stream.seek(0)
+		return stream
+
 	def _store(self, stream):
 		zf = _ZipPackageZipFile(stream, mode='w', compression=ZIP_DEFLATED)
 		zf.write_part('[Content_Types].xml', self.content_types.dump())

File test/test_zippack.py

 	Not everybody wants to create a package from a file system object.
 	Make sure the packages can be created from a stream.
 	"""
-	from StringIO import StringIO
 	input_stream = StringIO(zippack_sample)
 	pack = ZipPackage.from_stream(input_stream)
 
+def test_store_empty_package():
+	pack = ZipPackage()
+	data = StringIO()
+	pack._store(data)
+	data.seek(0)
+	pack = ZipPackage.from_stream(data)
+
+def test_as_stream():
+	"Get a package as a readable stream"
+	stream = ZipPackage().as_stream()
+	assert hasattr(stream, 'read')
+
 def test_create_and_open(writable_filename):
 	test_save(writable_filename)
 	pack = ZipPackage.from_file(writable_filename)