def test_reverting(self): """Test that reverting to a version creates a new NamedBlobFile instance instead of using a reference. This avoids the version being reverted to being overwritte later. """ pr = getToolByName(self.portal, 'portal_repository') doc1 = createContentInContainer( self.portal, 'opengever.document.document', title=u'Some Doc', document_author=u'Hugo Boss', document_date=datetime.date(2011, 1, 1), file=NamedBlobFile('bla bla 0', filename=u'test.txt')) manager = self.get_manager(doc1) manager.checkout() doc1.file = NamedBlobFile('bla bla 1', filename=u'test.txt') manager.checkin(comment="Created Version 1") manager.checkout() doc1.file = NamedBlobFile('bla bla 2', filename=u'test.txt') manager.checkin(comment="Created Version 2") manager.checkout() doc1.file = NamedBlobFile('bla bla 3', filename=u'test.txt') manager.checkin(comment="Created Version 3") manager.revert_to_version(2) version2 = pr.retrieve(doc1, 2) self.assertTrue(doc1.file._blob != version2.object.file._blob) self.assertTrue(doc1.file != version2.object.file)
def testCloneNamedFileBlobsInSchema(self): file_fti = DexterityFTI('BlobFile', model_source=""" <model xmlns="http://namespaces.plone.org/supermodel/schema"> <schema> <field name="file" type="plone.namedfile.field.NamedBlobFile"> <title>File</title> <required>True</required> </field> </schema> </model> """) self.portal.portal_types._setObject('BlobFile', file_fti) file1 = createContentInContainer(self.portal, 'BlobFile') file1.file = NamedBlobFile('dummy test data', filename=u'test.txt') modifier = CloneNamedFileBlobs('modifier', 'Modifier') attrs_dict = modifier.getReferencedAttributes(file1) self.assertTrue( 'plone.dexterity.schema.generated.plone_0_BlobFile.file' in attrs_dict) blob = attrs_dict.values()[0] self.assertTrue(IBlob.providedBy(blob)) file2 = createContentInContainer(self.portal, 'BlobFile') file2.file = NamedBlobFile('dummy test data', filename=u'test.txt') modifier.reattachReferencedAttributes(file2, attrs_dict) self.assertTrue(file2.file._blob is blob)
def test_bulk_checkout(self): doc1 = createContentInContainer( self.portal, 'opengever.document.document', title=u'Document1', document_author=u'Hugo Boss', document_date=datetime.date(2011, 1, 1), file=NamedBlobFile('bla bla', filename=u'test.txt')) doc2 = createContentInContainer( self.portal, 'opengever.document.document', title=u'Document2', document_author=u'Hugo Boss', document_date=datetime.date(2011, 1, 1), file=NamedBlobFile('bla bla', filename=u'test.txt')) self.portal.REQUEST['paths'] = [ obj2brain(doc1).getPath(), obj2brain(doc2).getPath(), ] view = self.portal.restrictedTraverse('@@checkout_documents').render() self.assertEquals('http://nohost/plone#documents', view) self.assertEquals(TEST_USER_ID, self.get_manager(doc1).checked_out()) self.assertEquals(TEST_USER_ID, self.get_manager(doc2).checked_out())
def test_RestrictedNamedBlobFile(self): path = "%s/batchimport/toprocess/outgoing-mail/Accusé de réception.odt" % imiodmsmail.__path__[ 0] odtfile = file(path, 'rb') odtblob = NamedBlobFile(data=odtfile.read(), filename=u'file.odt') odtfile.close() path = "%s/configure.zcml" % imiodmsmail.__path__[0] otherfile = file(path, 'rb') otherblob = NamedBlobFile(data=otherfile.read(), filename=u'file.txt') otherfile.close() registry = getUtility(IRegistry) # check content type self.assertEqual(get_contenttype(odtblob), 'application/vnd.oasis.opendocument.text') self.assertEqual(get_contenttype(otherblob), 'text/plain') field = RestrictedNamedBlobFile() # with om context and good file field.context = get_object(oid='reponse1', ptype='dmsoutgoingmail')['1'] field._validate(odtblob) # with bad file self.assertRaises(Invalid, field._validate, otherblob) # bad file, validation deactivated registry[ 'imio.dms.mail.browser.settings.IImioDmsMailConfig.omail_odt_mainfile'] = False field._validate(otherblob)
def test_custom_content_type(self): test_file = NamedBlobFile("some text", filename=u"sometext.txt") test_file.contentType = 'foo/bar' test_doc = create(Builder("document").attach(test_file)) self.download(test_doc) self.assertResponseHeader('content-type', 'foo/bar')
def test_custom_content_type(self): test_file = NamedBlobFile("some text", filename=u"sometext.txt") test_file.contentType = "foo/bar" test_doc = create(Builder("document").attach(test_file)) self.download(test_doc) self.assertResponseHeader("content-type", "foo/bar")
def upload(self, files, title='', description=''): loaded = [] namechooser = INameChooser(self.context) if not isinstance(files, list): files = [files] for item in files: if item.filename: content_type = item.headers.get('Content-Type') filename = safe_unicode(item.filename) data = item.read() id_name = '' title = title and title[0] or filename # Get a unique id here id_name = namechooser.chooseName(title, self.context) # Portal types allowed : File and Image # Since Plone 4.x both types use Blob if content_type in IMAGE_MIMETYPES: portal_type = 'ArquivoBiblioteca' wrapped_data = NamedBlobFile(data=data, filename=filename) else: portal_type = 'ArquivoBiblioteca' wrapped_data = NamedBlobFile(data=data, filename=filename) # Create content self.context.invokeFactory(portal_type, id=id_name, title=title, description=description[0]) newfile = self.context[id_name] if not newfile.Title(): newfile.setTitle(title) import transaction transaction.commit() if IBoaPratica.providedBy(self.context): newfile.setUid_pratica(self.context) # Set data if portal_type == 'ArquivoBiblioteca': if IATFile.providedBy(newfile): newfile.setFile(data, filename=filename) else: newfile.file = wrapped_data elif portal_type == 'ArquivoBiblioteca': if IATImage.providedBy(newfile): newfile.setImage(data, filename=filename) else: newfile.image = wrapped_data # Finalize content creation, reindex it newfile.reindexObject() notify(ObjectModifiedEvent(newfile)) loaded.append(newfile) if loaded: return loaded return False
def setup_content_data(self): audio = self.audio path = os.path.dirname(__file__) mp3_audio = open(os.path.join(path, 'files', 'file.mp3')).read() audio.invokeFactory('MPEG Audio File', 'file.mp3') audio['file.mp3'].file = NamedBlobFile(mp3_audio, 'audio/mp3', u'file.mp3') ogg_audio = open(os.path.join(path, 'files', 'file.ogg')).read() audio.invokeFactory('OGG Audio File', 'file.ogg') audio['file.ogg'].file = NamedBlobFile(ogg_audio, 'audio/ogg', u'file.ogg')
def testCopyBlobs(self): from zope.copy import copy file = NamedBlobFile() file.data = u'hello, world' image = NamedBlobImage() image.data = 'some image bytes' transaction.commit() file_copy = copy(file) self.assertEqual(file_copy.data, file.data) image_copy = copy(image) self.assertEqual(image_copy.data, image.data)
def test_filesize(self): # original value in patrimoine : 30000000 file = NamedFile() file.data = "0" * 30000000 self.patrimoine.fichier_pdf = NamedBlobFile(data=file.data, filename=u"bigfile.pdf") self.assertTrue(fileSize(self.patrimoine.fichier_pdf)) file = NamedFile() file.data = "0" * 30000001 self.patrimoine.fichier_pdf = NamedBlobFile(data=file.data, filename=u"bigfile.pdf") with self.assertRaises(InvalidFileSizeError): self.assertRaises(InvalidFileSizeError, fileSize(self.patrimoine.fichier_pdf))
def updateMIDI(context, normalizedTitle, pt): """ :param context: an object with a ``midi`` field :type context: usualy a ABC object :param normalizedTitle: used for the blob filename :type normalizedTitle: string :param pt: tool :type pt: portal_tranform tool :returns: nothing, update the ``midi`` field of the object """ try: midiData = pt.convertTo( 'audio/x-midi', context.abc, context=context, annotate=True, ) midiFilename = normalizedTitle + u'.mid' midiContentType = u'audio/mid' context.midi = NamedBlobFile() context.midi.data = midiData.getData() context.midi.contentType = midiContentType context.midi.filename = midiFilename except Exception: msg = u'Failed to create MIDI' logger.info(msg) annotateObject(context, msg=msg, key='ABC_ERRORS')
def test_file_limit(self): _file = plone.api.content.create(id='file1', type='File', title='My file', container=self.portal) _file.file = NamedBlobFile() _file.file.data = 'hello, world' _file.file.__dict__['size'] = 1e10 # fake it plone.api.content.delete(_file) self.assertEqual(len(self.can.objectIds()), 0)
def test_files_in_contact_view(self): contact = api.content.create( container=self.entity, type="imio.directory.Contact", title="contact", ) view = getMultiAdapter((contact, self.request), name="view") view.update() self.assertNotIn("contact-files", view.render()) file_obj = api.content.create( container=contact, type="File", title="file", ) file_obj.file = NamedBlobFile(data="file data", filename="file.txt") view = queryMultiAdapter((contact, self.request), name="view") view.update() self.assertIn("++resource++mimetype.icons/txt.png", view.render()) self.assertIn("1 KB", view.render()) self.assertEqual(view.get_thumb_scale_list(), "thumb") api.portal.set_registry_record("plone.thumb_scale_listing", "preview") annotations = IAnnotations(self.request) del annotations["plone.memoize"] view = queryMultiAdapter((contact, self.request), name="view") self.assertEqual(view.get_thumb_scale_list(), "preview") api.portal.set_registry_record("plone.no_thumbs_lists", True) annotations = IAnnotations(self.request) del annotations["plone.memoize"] view = queryMultiAdapter((contact, self.request), name="view") self.assertIsNone(view.get_thumb_scale_list()) view.update() self.assertIn("contact-files", view.render())
def test_does_not_accept_emails(self): mail = NamedBlobFile('bla bla', filename=u'test.eml') validator = UploadValidator(*self.validator_arguments()) with self.assertRaises(Invalid) as cm: self.assertFalse(validator.validate(mail)) self.assertEquals('error_mail_upload', str(cm.exception))
def _deserialize(cls, data): realdata = data['data'] if len(realdata) < 10: # arbitrary print("short data found in NamedBlobFileSerializer _deserialize") return NamedBlobFile(base64.b64decode(data['data']), filename=data['filename'], contentType=data['content_type'].encode('utf-8'))
def test_updates_checksum_and_queue_storing_after_docproperty_update( self, browser): api.portal.set_registry_record('create_doc_properties', interface=ITemplateFolderProperties, value=True) dossier = create(Builder('dossier')) document = create( Builder('document').within(dossier).checked_out().with_asset_file( 'with_gever_properties.docx')) # update document.file = NamedBlobFile( data=assets.load(u'with_gever_properties_update.docx'), filename=u'with_gever_properties.docx') checksum_before = IBumblebeeDocument(document).update_checksum() browser.login().open(document) browser.click_on('without comment') self.assertNotEqual( checksum_before, IBumblebeeDocument(document).get_checksum(), 'Document checksum not updated after docproperties update.') self.assertNotEqual( checksum_before, obj2brain(document).bumblebee_checksum, 'Document checksum not updated after docproperties update.')
def test_get_file(self): # pragma: no cover self.portal.invokeFactory("File", id="file1") self.portal.file1.title = "File" self.portal.file1.description = "A file" pdf_file = os.path.join(os.path.dirname(__file__), "file.pdf") with open(pdf_file, "rb") as f: pdf_data = f.read() self.portal.file1.file = NamedBlobFile(data=pdf_data, contentType="application/pdf", filename="file.pdf") intids = getUtility(IIntIds) file_id = intids.getId(self.portal.file1) self.portal.file1.file = RelationValue(file_id) transaction.commit() response = self.api_session.get(self.portal.file1.absolute_url()) self.assertEqual(response.status_code, 200) self.assertEqual( response.headers.get("Content-Type"), "application/json", "When sending a GET request with Content-Type: application/json " + "the server should respond with sending back application/json.", ) self.assertEqual(response.json()["@id"], self.portal.file1.absolute_url())
def migrate_schema_fields(self): old_file = self.old.getField('file').get(self.old) filename = safe_unicode(old_file.filename) namedblobfile = NamedBlobFile(contentType=old_file.content_type, data=old_file.data, filename=filename) self.new.file = namedblobfile
def test_do_not_show_link_to_update_outdated_document_on_submitted_proposal_view( self, browser): proposal, submitted_proposal = create( Builder('proposal').within(self.dossier).having( title='Mach doch', committee=self.committee.load_model()).relate_to( self.document).with_submitted()) repository = api.portal.get_tool('portal_repository') self.document.file = NamedBlobFile(data='New', filename=u'test.txt') repository.save(self.document) transaction.commit() browser.login().visit(proposal, view='tabbedview_view-overview') self.assertEqual(['Update document in proposal'], browser.css('a.proposal-outdated').text, "The outdated link should be visible on a proposal") browser.login().visit(submitted_proposal, view='tabbedview_view-overview') self.assertEqual( ['Mach doch', 'A Document'], browser.css('.document_link').text, "Attachment and proposal document should be available in the " "submittedproposal listing") self.assertEqual( [], browser.css('a.proposal-outdated'), "The outdated link should not be visible on a submitted proposal")
def test_dexterity_file_get(self): self.portal.invokeFactory("File", id="file") self.portal.file.title = "My File" self.portal.file.description = u"This is a file" pdf_file = os.path.join(os.path.dirname(__file__), u"file.pdf") fd = open(pdf_file, "rb") self.portal.file.file = NamedBlobFile( data=fd.read(), contentType="application/pdf", filename=u"file.pdf" ) fd.close() intids = getUtility(IIntIds) file_id = intids.getId(self.portal.file) self.portal.file.file = RelationValue(file_id) import transaction transaction.commit() response = requests.get( self.portal.file.absolute_url(), headers={"Accept": "application/json"}, auth=(SITE_OWNER_NAME, SITE_OWNER_PASSWORD), ) self.assertEqual(200, response.status_code) self.assertEqual(u"file", response.json().get("id")) self.assertEqual(u"GET", response.json().get("method"))
def __call__(self, validate_all=False, data=None, create=False): if data is None: data = json_body(self.request) context = super(DeserializeMailFromJson, self).__call__(validate_all=validate_all, data=data, create=create) if context.message and context.message.filename.lower().endswith( '.msg'): self.context.original_message = context.message transform = Msg2MimeTransform() eml = transform.transform(context.message.data) file_ = NamedBlobFile(data=eml, filename=context.message.filename[:-3] + 'eml', contentType='message/rfc822') context.message = file_ if create and 'message' in data: if not data.get('title'): context._update_title_from_message_subject() initalize_title(context, None) initialize_metadata(context, None) return context
def update(self): try: from plone.protect.interfaces import IDisableCSRFProtection alsoProvides(self.request, IDisableCSRFProtection) except: pass if self.request.environ['REQUEST_METHOD'] == 'POST': portal = api.portal.get() folder_name = self.request.get("folder") local_file = self.request.get("local_file") f = open(local_file, 'r') content = f.read() f.close() for folder_name_part in folder_name.split('/'): if portal.get(folder_name_part) is None: makeFolder(portal, folder_name_part) portal = portal.get(folder_name_part) file = NamedBlobFile(data=content, filename=u'{}'.format(local_file), contentType='application/xls') createContentInContainer(portal, 'AppFile', id='{}'.format(local_file.split('/')[-1]), title='{}'.format( local_file.split('/')[-1]), file=file, checkConstraints=False)
def _create_file(self, item, files, title, description, rights): namechooser = INameChooser(self.context) content_type = item.headers.get('Content-Type') filename = safe_unicode(item.filename) data = item.read() id_name = '' title = title and title[0] or filename id_name = namechooser.chooseName(title, self.context) if content_type in IMAGE_MIMETYPES: portal_type = 'Image' wrapped_data = NamedBlobImage(data=data, filename=filename) else: portal_type = 'File' wrapped_data = NamedBlobFile(data=data, filename=filename) self.context.invokeFactory(portal_type, id=id_name, title=title, description=description[0], rights=rights[0]) newfile = self.context[id_name] if portal_type == 'File': if IATFile.providedBy(newfile): newfile.setFile(data, filename=filename) else: newfile.file = wrapped_data elif portal_type == 'Image': if IATImage.providedBy(newfile): newfile.setImage(data, filename=filename) else: newfile.image = wrapped_data newfile.reindexObject() notify(ObjectModifiedEvent(newfile)) return newfile
def afterSetUp(self): super(TestSyndicationFeedAdapter, self).afterSetUp() self.feed = IFeed(self.folder) self.feeddatadoc = DexterityItem(self.doc1, self.feed) from plone.namedfile.file import NamedBlobFile self.file.file = NamedBlobFile(data='lorem', filename=u'string.txt') self.feeddatafile = DexterityItem(self.file, self.feed)
def test_preview(self): """Verify async preview generation""" if not ASYNC_ENABLED: print("Skipping preview test") return if not self.redis_running(): self.fail("requires redis") return ff = open(os.path.join(os.path.dirname(__file__), TEST_FILENAME), 'r') self.filedata = ff.read() ff.close() # Temporarily enable Async self.testfile = api.content.create( type='File', id='test-file', title=u"Test File", file=NamedBlobFile(data=self.filedata, filename=TEST_FILENAME), container=self.portal) context = getattr(self.portal, 'test-file') self.assertFalse(pi_api.previews.has_previews(context)) generator = tasks.GeneratePreview(context, self.request) result = generator() self.waitfor(result, timeout=15.0) # we need to commit in order to see the other transaction # now go and check that the preview has been generated transaction.commit() self.assertTrue(pi_api.previews.has_previews(context))
def test_get_file(self): # pragma: no cover self.portal.invokeFactory('File', id='file1') self.portal.file1.title = 'File' self.portal.file1.description = u'A file' pdf_file = os.path.join( os.path.dirname(__file__), u'file.pdf' ) self.portal.file1.file = NamedBlobFile( data=open(pdf_file, 'r').read(), contentType='application/pdf', filename=u'file.pdf' ) intids = getUtility(IIntIds) file_id = intids.getId(self.portal.file1) self.portal.file1.file = RelationValue(file_id) transaction.commit() response = self.api_session.get(self.portal.file1.absolute_url()) self.assertEqual(response.status_code, 200) self.assertEqual( response.headers.get('Content-Type'), 'application/json', 'When sending a GET request with Content-Type: application/json ' + 'the server should respond with sending back application/json.' ) self.assertEqual( response.json()['@id'], self.portal.file1.absolute_url() )
def test_contains_also_original_message(self, browser): self.login(self.regular_user, browser) IOGMail(self.mail_eml).original_message = NamedBlobFile( data='__DATA__', filename=u'testmail.msg') browser.open(self.mail_eml.absolute_url(), method='GET', headers={ 'Accept': 'application/json', 'Content-Type': 'application/json' }) self.assertEqual(200, browser.status_code) expected_message = { u'content-type': u'application/vnd.ms-outlook', u'download': u'http://nohost/plone/ordnungssystem/fuhrung/vertrage-und-vereinbarungen/dossier-1/document-29' u'/@@download/original_message', u'filename': u'testmail.msg', u'size': 8, } self.assertEqual(expected_message, browser.json.get('original_message'))
def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) # disable diazo theming self.portal.portal_registry[ 'plone.app.theming.interfaces.IThemeSettings.enabled'] = False # disable auto-CSRF from plone.protect import auto auto.CSRF_DISABLED = True _createObjectByType('Folder', self.portal, 'folder') _createObjectByType('Document', self.portal, 'document') _createObjectByType('File', self.portal, 'file') self.portal.file.file = NamedBlobFile('foo', 'text/plain', u'foo.txt') transaction.commit() self.putils = getToolByName(self.portal, "plone_utils") self.browser = Browser(self.layer['app']) self.browser.addHeader( 'Authorization', 'Basic %s:%s' % ( TEST_USER_NAME, TEST_USER_PASSWORD, ))
def revert_to_version(self, version_id, create_version=True): """Reverts the adapted document to a specific version. We only revert the file field, since we do not wan't to version the metadata on the document. If `create_version` is set to `True`, a new version is created after reverting. """ version = self.repository.retrieve(self.context, version_id) old_obj = version.object if old_obj.file: # Create a new NamedBlobFile instance instead of using # a reference in order to avoid the version being reverted # to being overwritten later old_file_copy = NamedBlobFile(old_obj.file.data, filename=old_obj.file.filename, contentType=old_obj.file.contentType) self.context.file = old_file_copy else: self.context.file = None if create_version: # let's create a version comment = _(u'Reverted file to version ${version_id}', mapping=dict(version_id=version_id)) self.repository.save(obj=self.context, comment=comment) # event notify( ObjectRevertedToVersion(self.context, version_id, create_version))
def update_file_content(self, info): type_, location = self.get_type_and_location(info) obj = uuidToObject(info['existing_id']) success = False msg = None if obj: if self.sm.checkPermission(ModifyPortalContent, obj): try: if info['field_name'].startswith('tmp_'): self.add_tmp_upload(obj, info) else: fi = open(info['tmp_file'], 'r') filename = ploneutils.safe_unicode(info['name']) if 'Image' in type_: blob = NamedBlobImage(data=fi, filename=filename) else: blob = NamedBlobFile(data=fi, filename=filename) setattr(obj, info['field_name'], blob) success = True except Exception: # could not update content logger.warning('Error updating content', exc_info=True) msg = 'Unknown error' else: msg = 'Invalid permissions' else: success = False msg = 'Object not found' return obj, success, msg
def get_blob(self): ''' Returns a blob with a previewable pdf ''' return NamedBlobFile(data=resource_string( 'ploneintranet.attachments.tests', 'plone.pdf').decode('latin1', 'utf8'), filename=u'plone.pdf')