def __call__(self): if not self.status_id: return self container = PLONESOCIAL.microblog status = container.get(self.status_id) if not self.attachment_id: # do we want to be able to traverse to the status update itself? # Returning only the id for now return self.status_id attachments = IAttachmentStorage(status) attachment = attachments.get(self.attachment_id) if not self.preview_type: self.request.response.setHeader( 'content-type', attachment.getContentType()) self.request.response.setHeader( 'content-disposition', 'inline; ' 'filename="{0}"'.format( self.attachment_id.encode('utf8'))) return attachment if IDocconv is not None: docconv = IDocconv(attachment) if self.preview_type == 'thumb': if docconv.has_thumbs(): return self._prepare_imagedata( attachment, docconv.get_thumbs()[0]) elif self.preview_type == 'preview': if docconv.has_previews(): return self._prepare_imagedata( attachment, docconv.get_previews()[0]) raise NotFound
def test_extract_and_add_attachments(self): file_field = self._create_test_file_field() extract_and_add_attachments(file_field, self.document) attachments = IAttachmentStorage(self.document) self.assertEquals(len(attachments.values()), 1) res = attachments.get(file_field.filename) self.assertEquals(res.id, file_field.filename)
def clean_up_temporary_attachments(workspace, maxage=1): temp_attachments = IAttachmentStorage(workspace) for key in temp_attachments.keys(): keyparts = key.split('-') datestr = keyparts[1] try: date = datetime.strptime(datestr, '%Y%m%d%H%M%S%f') except ValueError: date = datetime.min # No proper datestr, treat as old if datetime.now() - date > timedelta(maxage): temp_attachments.remove(key) log.info('Cleaned up temporary attachment {0} from ' '{1}'.format(key, workspace.Title()))
def test_temporary_attachment(self): token = "{0}-{1}".format( TEST_USER_ID, datetime.utcnow().strftime('%Y%m%d%H%M%S%f')) attachment = self._create_test_temp_attachment(token) temp_attachments = IAttachmentStorage(self.workspace) temp_attachments.add(attachment) file_field = self._create_test_file_field() res = pop_temporary_attachment(self.workspace, file_field, token) self.assertEquals(res.id, attachment.id) self.assertTrue(res.file.size > 0) clean_up_temporary_attachments(self.workspace, maxage=0) self.assertEquals(len(temp_attachments.keys()), 0)
def __call__(self): if not self.status_id: return self container = PLONEINTRANET.microblog status = container.get(self.status_id) if not self.attachment_id: # do we want to be able to traverse to the status update itself? # Returning only the id for now return self.status_id attachments = IAttachmentStorage(status) attachment = attachments.get(self.attachment_id) if not self.preview_type: primary_field = IPrimaryFieldInfo(attachment).value mimetype = primary_field.contentType data = primary_field.data self.request.response.setHeader( 'content-type', mimetype) self.request.response.setHeader( 'content-disposition', 'inline; ' 'filename="{0}"'.format( safe_unicode(self.attachment_id).encode('utf8'))) return data if IDocconv is not None: docconv = IDocconv(attachment) if self.preview_type == 'thumb': if docconv.has_thumbs(): return self._prepare_imagedata( attachment, docconv.get_thumbs()[0]) elif self.preview_type == 'preview': if docconv.has_previews(): return self._prepare_imagedata( attachment, docconv.get_previews()[0]) elif self.preview_type == '@@images': images = api.content.get_view( 'images', attachment.aq_base, self.request, ) return self._prepare_imagedata( attachment, str(images.scale(scale='preview').data.data) ) raise NotFound
def pop_temporary_attachment(workspace, file_field, token): """ Replace a temporary attachment on the workspace with the uploaded data """ temp_attachments = IAttachmentStorage(workspace) temp_id = '{0}-{1}'.format(token, file_field.filename) if temp_id in temp_attachments.keys(): temp_att = aq_base(temp_attachments.get(temp_id)) temp_att.id = file_field.filename temp_att.file = NamedBlobFile( data=file_field.read(), filename=file_field.filename.decode('utf-8'), ) temp_attachments.remove(temp_id) return temp_att return None
def clean_up_temporary_attachments(workspace, maxage=1): """Garbage collect temporary attachments on a workspace -- these are used while creating a statusupdate but already removed when storing the statusupdate. This method removes any remaining temp attachments. maxage is age in days beyond which attachments are removed. """ temp_attachments = IAttachmentStorage(workspace) for key in temp_attachments.keys(): keyparts = key.split('-') datestr = keyparts[1] try: date = datetime.strptime(datestr, '%Y%m%d%H%M%S%f') except ValueError: date = datetime.min # No proper datestr, treat as old if datetime.now() - date > timedelta(maxage): temp_attachments.remove(key) log.info('Cleaned up temporary attachment {0} from ' '{1}'.format(key, workspace.Title()))
def test_extract_and_add_attachments_with_token(self): token = "{0}-{1}".format(TEST_USER_ID, datetime.utcnow().strftime('%Y%m%d%H%M%S%f')) temp_attachment = self._create_test_temp_attachment(token) temp_attachments = IAttachmentStorage(self.workspace) temp_attachments.add(temp_attachment) file_field = self._create_test_file_field() extract_and_add_attachments(file_field, self.document, self.workspace, token) attachments = IAttachmentStorage(self.document) self.assertEquals(len(attachments.values()), 1) self.assertTrue(file_field.filename in attachments.keys()) res = attachments.get(file_field.filename) self.assertEquals(res.id, file_field.filename) self.assertTrue('/'.join(res.getPhysicalPath()).startswith('/'.join( self.workspace.getPhysicalPath())))
def test_attachments(self): su = StatusUpdate("foo bar") attachments = IAttachmentStorage(su) f = ATFile("data.dat") attachments.add(f) self.assertEqual([k for k in attachments.keys()], [f.getId()]) attachments.remove(f.getId()) self.assertEqual(len(attachments.keys()), 0)
def __call__(self): token = self.request.get('attachment-form-token') attachments = self.request.get('form.widgets.attachments') self.attachments = [] if attachments: temp_attachments = IAttachmentStorage(self.context) attachment_objs = utils.extract_attachments(attachments) for obj in attachment_objs: obj.id = '{0}-{1}'.format(token, obj.id) temp_attachments.add(obj) obj = temp_attachments.get(obj.id) if IPreviewFetcher is not None: try: IPreviewFetcher(obj)() except Exception as e: log.warn('Could not get previews for attachment: {0}, ' '{1}: {2}'.format( obj.id, e.__class__.__name__, e)) self.attachments.append(obj) return self.index()
def test_traverse(self): id = self.workspace.invokeFactory( 'slc.underflow.question', 'question', title=u'Question') question = self.workspace._getOb(id) attachments = IAttachmentStorage(question) f = file.ATFile('data1.dat') attachments.add(f) response = self.portal.restrictedTraverse( '%s/++attachments++default/data1.dat' % ('/'.join(question.getPhysicalPath()))) self.assertEqual(f, response) # Test traversal to a non-existing attachment self.assertRaises( NotFound, self.portal.restrictedTraverse, '%s/++attachments++default/non-existing.dat' % ('/'.join(question.getPhysicalPath())))
def test_path(self): id = self.workspace.invokeFactory( 'slc.underflow.question', 'question', title=u'Question') question = self.workspace._getOb(id) attachments = IAttachmentStorage(question) f = file.ATFile('data1.dat') attachments.add(f) attachment_path = attachments.get('data1.dat').getPhysicalPath() self.assertEquals( '/'.join(attachment_path), '%s/++attachments++default/data1.dat' % ('/'.join(question.getPhysicalPath()))) response = self.portal.restrictedTraverse(attachment_path) self.assertEqual( '/'.join(response.getPhysicalPath()), '/'.join(attachment_path))
def __call__(self): token = self.request.get('attachment-form-token') uploaded_attachments = self.request.get('form.widgets.attachments') if not uploaded_attachments: return self.index() normalizer = getUtility(IURLNormalizer) self.attachments = [] attachments = IAttachmentStorage(self.context) attachment_objs = utils.extract_attachments(uploaded_attachments) for obj in attachment_objs: obj.id = normalizer.normalize(u'{0}-{1}'.format(token, obj.id)) attachments.add(obj) obj = attachments.get(obj.id) try: handle_file_creation(obj, None) except Exception as e: log.warn('Could not get previews for attachment: {0}, ' u'{1}: {2}'.format(obj.id, e.__class__.__name__, e)) self.attachments.append(obj) return self.index()
def __call__(self): token = self.request.get("attachment-form-token") uploaded_attachments = self.request.get("form.widgets.attachments") if not uploaded_attachments: return self.index() normalizer = getUtility(IURLNormalizer) self.attachments = [] attachments = IAttachmentStorage(self.context) attachment_objs = utils.extract_attachments(uploaded_attachments) for obj in attachment_objs: obj.id = normalizer.normalize(u"{0}-{1}".format(token, obj.id)) attachments.add(obj) obj = attachments.get(obj.id) try: IPreviewFetcher(obj)() except Exception as e: log.warn( "Could not get previews for attachment: {0}, " u"{1}: {2}".format(obj.id, e.__class__.__name__, e) ) self.attachments.append(obj) return self.index()
def __call__(self): token = self.request.get('attachment-form-token') uploaded_attachments = self.request.get('form.widgets.attachments') if not uploaded_attachments: return self.index() normalizer = getUtility(IURLNormalizer) self.attachments = [] attachments = IAttachmentStorage(self.context) attachment_objs = utils.extract_attachments(uploaded_attachments) for obj in attachment_objs: obj.id = normalizer.normalize(u'{0}-{1}'.format(token, obj.id)) attachments.add(obj) obj = attachments.get(obj.id) try: handle_file_creation(obj, None) except Exception as e: log.warn('Could not get previews for attachment: {0}, ' u'{1}: {2}'.format( obj.id, e.__class__.__name__, e)) self.attachments.append(obj) return self.index()
def test_extract_and_add_attachments_with_token(self): token = "{0}-{1}".format( TEST_USER_ID, datetime.utcnow().strftime('%Y%m%d%H%M%S%f')) temp_attachment = self._create_test_temp_attachment(token) temp_attachments = IAttachmentStorage(self.workspace) temp_attachments.add(temp_attachment) file_field = self._create_test_file_field() extract_and_add_attachments( file_field, self.document, self.workspace, token) attachments = IAttachmentStorage(self.document) self.assertEquals(len(attachments.values()), 1) self.assertTrue(file_field.filename in attachments.keys()) res = attachments.get(file_field.filename) self.assertEquals(res.id, file_field.filename) self.assertTrue( '/'.join(res.getPhysicalPath()).startswith( '/'.join(self.workspace.getPhysicalPath())))
def extract_and_add_attachments(file_upload, obj, workspace=None, token=None): """Create attachments from a file upload field. Extract file data from file_upload, create file/image objects and add them as attachments to obj. If workspace and token are given, reuse previously uploaded temporary attachments if they exist. """ if not file_upload: return if not isinstance(file_upload, list): file_upload = [ file_upload, ] attachment_storage = IAttachmentStorage(obj) attachments = extract_attachments(file_upload, workspace=workspace, token=token) add_attachments(attachments, attachment_storage) if workspace: clean_up_temporary_attachments(workspace)
def pop_temporary_attachment(workspace, file_field, token): """ Replace a temporary attachment on the workspace with the uploaded data """ temp_attachments = IAttachmentStorage(workspace) temp_id = getUtility(IURLNormalizer).normalize(u'{0}-{1}'.format( token, safe_unicode(file_field.filename))) if temp_id in temp_attachments.keys(): temp_att = aq_base(temp_attachments.get(temp_id)) temp_att.id = file_field.filename temp_att.file = NamedBlobFile( data=file_field.read(), filename=file_field.filename.decode('utf-8'), ) temp_attachments.remove(temp_id) return temp_att return None
def get_attachment_ids(self): return IAttachmentStorage(self.context).keys()
def attachments(self): """The attachment storage. Lists filenames via .keys().""" return IAttachmentStorage(self)
def test_remove(self): """ """ question = createObject('Document') alsoProvides(question, IAttachmentStoragable) attachments = IAttachmentStorage(question) self.assertEqual(len(attachments.keys()), 0) self.assertEqual(len(attachments.values()), 0) for fname in ['data1.dat', 'data2.dat']: attachments.add(file.ATFile(fname)) self.assertEqual(len(attachments.keys()), 2) self.assertEqual(len(attachments.values()), 2) self.assertRaises(KeyError, attachments.remove, 'data3.dat') attachments.remove('data1.dat') self.assertEqual(len(attachments.keys()), 1) self.assertTrue('data2.dat' in attachments.keys()) attachments.remove('data2.dat') self.assertEqual(len(attachments.keys()), 0)
def test_add(self): """ """ doc1 = createObject('Document') alsoProvides(doc1, IAttachmentStoragable) attachments = IAttachmentStorage(doc1) self.assertEqual(len(attachments.keys()), 0) self.assertEqual(len(attachments.values()), 0) f = file.ATFile('data.dat') attachments.add(f) self.assertEqual([k for k in attachments.keys()], [f.getId()]) self.assertEqual([v for v in attachments.values()], [f]) # DuplicateIDError is thrown when an object with the same id is # added again. self.assertRaises(DuplicateIDError, attachments.add, f) i = image.ATImage('image.jpg') attachments.add(i) self.assertEqual(len(attachments.keys()), 2) self.assertEqual(len(attachments.values()), 2) self.assertTrue(i.getId()in attachments.keys()) self.assertTrue(i in attachments.values())
def __call__(self): # requires View on self.context attachments = IAttachmentStorage(self.context) # separate rendering out for subclass use return self.render_attachments(attachments)
def __call__(self): container = pi_api.microblog.get_microblog() # requires ViewStatusUpdate on the statusupdate returned statusupdate = container.get(self.status_id) attachments = IAttachmentStorage(statusupdate) return self.render_attachments(attachments)
def test_add(self): """ """ doc1 = createObject('Document') alsoProvides(doc1, IAttachmentStoragable) attachments = IAttachmentStorage(doc1) self.assertEqual(len(attachments.keys()), 0) self.assertEqual(len(attachments.values()), 0) f = file.ATFile('data.dat') attachments.add(f) self.assertEqual([k for k in attachments.keys()], [f.getId()]) self.assertEqual([v for v in attachments.values()], [f]) # DuplicateIDError is thrown when an object with the same id is # added again. self.assertRaises(DuplicateIDError, attachments.add, f) i = image.ATImage('image.jpg') attachments.add(i) self.assertEqual(len(attachments.keys()), 2) self.assertEqual(len(attachments.values()), 2) self.assertTrue(i.getId() in attachments.keys()) self.assertTrue(i in attachments.values())