def _open_zip(cls, transform_id, stream_reader): try: return zipfile.ZipFile(stream_reader) except (AttributeError, blobstore.Error), e: # Having no blob raises AttributeError. raise x5_exceptions.X5BundleError( 'Error opening blob for bundle key %s: %s', transform_id, e)
def transform(self): """Apply the workflow to convert the bundle to a DFP creative.""" if not self.assets: raise x5_exceptions.X5BundleError('No assets in bundle.') for snippet in self.snippets.values(): for converter in x5_converters.X5_CONVERTERS: if not converter.match(snippet): continue try: converter(self).convert(snippet) except x5_exceptions.X5ConverterError, e: logger.exception('Conversion error') raise x5_exceptions.X5BundleError( 'Error converting %s: %s', self.transform_id, e) else: snippet.x5type = converter.X5_TYPE break
class X5Bundle(object): """HTML5 zipped creative bundle.""" @classmethod def _open_zip(cls, transform_id, stream_reader): try: return zipfile.ZipFile(stream_reader) except (AttributeError, blobstore.Error), e: # Having no blob raises AttributeError. raise x5_exceptions.X5BundleError( 'Error opening blob for bundle key %s: %s', transform_id, e) except (zipfile.BadZipfile, zipfile.LargeZipFile), e: raise x5_exceptions.X5BundleError( 'Error opening zip from bundle key %s: %s' % (transform_id, e))
def zip_factory(cls, transform_id, stream_reader): """Returns an X5 bundle instance from a zipped bundle.""" zipped_bundle = cls._open_zip(transform_id, stream_reader) bundle = cls(transform_id) for info in zipped_bundle.infolist(): if info.filename.endswith('/'): continue if '__MACOSX/' in info.filename: continue basename = os.path.basename(info.filename) if basename.startswith('.') or basename in ('Thumbs.db', ): continue if info.filename.endswith('.DS_Store'): continue try: with zipped_bundle.open(info) as fileobj: bundle.add_member(info.filename, info.file_size, fileobj) except zipfile.BadZipfile, e: raise x5_exceptions.X5BundleError( 'Error reading zip entry %s for bundle key %s: %s', info.filename, transform_id, e)
def get_creative_part(self, transform_id, stream_reader, snippet_name): """Get snippet and assets in the format expected by the DFP API.""" if isinstance(snippet_name, unicode): snippet_name = snippet_name.encode('utf-8', errors='ignore') try: snippet = self.snippets[snippet_name] except KeyError: raise x5_exceptions.X5BundleError( 'Invalid snippet name or bundle not populated') zipped_bundle = self._open_zip(transform_id, stream_reader) # TODO(ludomagno): inject the assets table in the snippet creative_part = { 'customCreativeAssets': [], 'htmlSnippet': snippet.as_snippet() } for asset_name in set(snippet.assets): # Don't skip assets that are over quota as they are referenced in macros. asset = self.assets[asset_name] with zipped_bundle.open(asset_name) as fileobj: creative_part['customCreativeAssets'].append( asset.as_creative_asset(transform_id, fileobj)) return creative_part
if '__MACOSX/' in info.filename: continue basename = os.path.basename(info.filename) if basename.startswith('.') or basename in ('Thumbs.db', ): continue if info.filename.endswith('.DS_Store'): continue try: with zipped_bundle.open(info) as fileobj: bundle.add_member(info.filename, info.file_size, fileobj) except zipfile.BadZipfile, e: raise x5_exceptions.X5BundleError( 'Error reading zip entry %s for bundle key %s: %s', info.filename, transform_id, e) if not bundle.snippets: raise x5_exceptions.X5BundleError('No snippets found.') return bundle def __init__(self, transform_id): self.transform_id = transform_id self.snippets = {} self.assets = {} self._macro_names = {} def get_creative_part(self, transform_id, stream_reader, snippet_name): """Get snippet and assets in the format expected by the DFP API.""" if isinstance(snippet_name, unicode): snippet_name = snippet_name.encode('utf-8', errors='ignore') try: snippet = self.snippets[snippet_name] except KeyError: