1. YouGov, plc.
  2. Untitled project
  3. openpack

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
  • Branches default

Comments (0)

Files changed (3)

File openpack/basepack.py

View file
 
 	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

View file
 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

View file
 	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)