def handle_upload(self, id, attached_file): if not attached_file: return if id in self.objectIds(): self.manage_delObjects([id, ]) attached_file.seek(0) data = attached_file.read() sfile = StringIO(data) sfile.filename = attached_file.filename[-1] content_type = mimetypes.guess_type(attached_file.filename)[0] if content_type is None: content_type = getattr(attached_file, 'headers', {}).get( 'content-type', 'application/octet-stream') sfile.headers = {'content-type': content_type} if id in self.objectIds(): self.manage_delObjects([id, ]) bf = make_blobfile(sfile, title=attached_file.filename, removed=False, timestamp=datetime.utcnow(), contributor='') bf.content_type = content_type bf.filename = id attached_file.seek(0) bf.size = len(attached_file.read()) setattr(self, id, bf)
def test_send_data(self): data = 'some test data' f = StringIO(data) f.filename = 'my.txt' f.headers = {'content-type': 'text/plain'} bf = make_blobfile(f, somerandomkw='thevalue') ok_headers = {'Content-Length': 14, 'Content-Type': 'text/plain', 'Content-Disposition': ("attachment;filename*=" "UTF-8''my.txt")} response = MockResponse() ret = bf.send_data(response) self.assertEqual(response.headers, ok_headers) self.assertEqual(ret, 'some test data') ok_headers['Content-Disposition'] = "attachment" ret = bf.send_data(response, set_filename=False) self.assertEqual(response.headers, ok_headers) self.assertEqual(ret, 'some test data') self.assertEqual(response.headers.get('X-Sendfile'), None) request = MockRequest() request.set_header('X-NaayaEnableSendfile', 'on') ret = bf.send_data(response, REQUEST=request) self.assertEqual(ret, "[body should be replaced by front-end server]") self.assertEqual(response.headers.get('X-Sendfile'), bf._current_filename())
def save_file(self, schema_raw_data, object_attribute, form_field): _uploaded_file = schema_raw_data.pop(form_field, None) if _uploaded_file is not None and _uploaded_file.filename: setattr(self, object_attribute, make_blobfile(_uploaded_file, removed=False, timestamp=datetime.utcnow()))
def saveProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG if self.hasVersion(): obj = self.version if self.checkout_user != self.REQUEST.AUTHENTICATED_USER.getUserName(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG else: obj = self if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate(schema_raw_data.pop('releasedate', ''), obj.releasedate) _subtitle = schema_raw_data.pop('subtitle', '') _subtitle_file = schema_raw_data.pop('subtitle_file', None) _startup_image = schema_raw_data.pop('startup_image', '') _delete_startup_image = schema_raw_data.pop('delete_startup_image', '') _source = schema_raw_data.pop('source', None) _file = schema_raw_data.pop('file', '') form_errors = self.process_submitted_form(schema_raw_data, _lang, _override_releasedate=_releasedate) # TODO: check if video file is good video file if form_errors: if REQUEST is not None: self._prepare_error_response(REQUEST, form_errors, schema_raw_data) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) return else: raise ValueError(form_errors.popitem()[1]) # pick a random error if _subtitle_file: _subtitle = force_to_unicode(_subtitle_file.read()) self._setLocalPropValue('subtitle', _lang, _subtitle) if _delete_startup_image: self.startup_image = None if _startup_image: self.startup_image = make_blobfile(_startup_image) if _source: self.saveUpload(file=_file, lang=_lang) self._p_changed = 1 self.recatalogNyObject(self) #log date contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) notify(NyContentObjectEditEvent(self, contributor)) if REQUEST: self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES, date=self.utGetTodayDate()) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang))
def _update(self, portal): brains = portal.portal_catalog(meta_type=['Naaya Survey Answer']) for brain in brains: try: obj = brain.getObject() except: self.log.warning( "Couldn't get obj based on catalog information %s", brain.getURL()) continue for upload in obj.objectValues('ExtFile'): if upload is None: continue if 'blob' in getattr(upload, 'meta_type', "").lower(): continue if upload.is_broken(): self.log.warning( "\t BROKEN EXTFILE: Couldn't migrate extfile for " "%s because of broken file", obj.absolute_url() ) continue if upload.get_size(): data = upload.index_html() sfile = StringIO(data) self.log.debug('\t VERSION FILENAME: %s', '/'.join(upload.filename)) sfile.filename = upload.filename[-1] sfile.headers = { 'content-type': upload.content_type} bf = make_blobfile(sfile, title=upload.title, removed=False, timestamp=datetime.utcnow(), contributor='') bf.filename = upload.id bf.content_type = upload.content_type bf.size = len(data) upload._delete('/'.join(upload.filename)) setattr(obj, upload.id, bf) self.log.info("Migrated %s bytes to bfile: %s" % (len(data), obj.absolute_url())) obj._p_changed = True self.log.info('Migration done') return True
def saveProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG if self.hasVersion(): obj = self.version if self.checkout_user != self.REQUEST.AUTHENTICATED_USER.getUserName( ): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG else: obj = self if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate( schema_raw_data.pop('releasedate', ''), obj.releasedate) #Process uploaded file _uploaded_file = schema_raw_data.pop('organisation_picture', None) if _uploaded_file is not None and _uploaded_file.filename: self.picture = make_blobfile(_uploaded_file, removed=False, timestamp=datetime.utcnow()) form_errors = self.process_submitted_form( schema_raw_data, _lang, _override_releasedate=_releasedate) if not form_errors: if self.discussion: self.open_for_comments() else: self.close_for_comments() self._p_changed = 1 self.recatalogNyObject(self) #log date contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) notify(NyContentObjectEditEvent(self, contributor)) if REQUEST: self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES, date=self.utGetTodayDate()) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) else: if REQUEST is not None: self._prepare_error_response(REQUEST, form_errors, schema_raw_data) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) else: raise ValueError( form_errors.popitem()[1]) # pick a random error
def test_factory_ie6_filename(self): data = 'some test data' f = StringIO(data) f.filename = r'C:\\Documents and Settings\\uzer\\Desktop\\data.txt' f.headers = {'content-type': 'text/plain'} bf = make_blobfile(f, somerandomkw='thevalue') self.assertEqual(bf.open().read(), data) self.assertEqual(bf.content_type, 'text/plain') self.assertEqual(bf.filename, 'data.txt') self.assertEqual(bf.somerandomkw, 'thevalue')
def test_factory(self): data = 'some test data' f = StringIO(data) f.filename = 'my.txt' f.headers = {'content-type': 'text/plain'} bf = make_blobfile(f, somerandomkw='thevalue') self.assertEqual(bf.open().read(), data) self.assertEqual(bf.content_type, 'text/plain') self.assertEqual(bf.filename, 'my.txt') self.assertEqual(bf.somerandomkw, 'thevalue')
def saveProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG if self.hasVersion(): obj = self.version if self.checkout_user != self.REQUEST.AUTHENTICATED_USER.getUserName(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG else: obj = self if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate(schema_raw_data.pop('releasedate', ''), obj.releasedate) #Process uploaded file _uploaded_file = schema_raw_data.pop('organisation_picture', None) if _uploaded_file is not None and _uploaded_file.filename: self.picture = make_blobfile(_uploaded_file, removed=False, timestamp=datetime.utcnow()) form_errors = self.process_submitted_form(schema_raw_data, _lang, _override_releasedate=_releasedate) if not form_errors: if self.discussion: self.open_for_comments() else: self.close_for_comments() self._p_changed = 1 self.recatalogNyObject(self) #log date contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) notify(NyContentObjectEditEvent(self, contributor)) if REQUEST: self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES, date=self.utGetTodayDate()) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) else: if REQUEST is not None: self._prepare_error_response(REQUEST, form_errors, schema_raw_data) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) else: raise ValueError(form_errors.popitem()[1]) # pick a random error
def _save_file(self, the_file, language, contributor): """ """ bf = make_blobfile(the_file, removed=False, timestamp=datetime.utcnow(), contributor=contributor) _versions = self._versions.pop(language, None) if _versions == None: toAdd = [bf] newD = {language: toAdd} self._versions.update(newD) else: _versions.append(bf) newD = {language: _versions} self._versions.update(newD)
def _save_file(self, the_file, language, contributor): """ """ bf = make_blobfile(the_file, removed=False, timestamp=datetime.utcnow(), contributor=contributor) _versions = self._versions.pop(language, None) if _versions == None: toAdd = [bf] newD = {language:toAdd} self._versions.update(newD) else: _versions.append(bf) newD = {language:_versions} self._versions.update(newD)
def versions(self, value): """ Import versions """ for version in value: bf = make_blobfile(version, removed=False, timestamp=datetime.utcnow(), contributor='') vstorage = getattr(self.context, '_versions', None) if vstorage is None: self.context._versions = PersistentList() self.context._versions.append(bf) fname = bf.get_filename() with open(fname) as f: version.seek(0) if not len(f.read()) == len(version.read()): raise ValueError("Different size of files")
def _update(self, portal): brains = portal.portal_catalog(meta_type=['Naaya Publication']) for brain in brains: fobj = brain.getObject() self.log.info("Migrating object %s", fobj.absolute_url()) if not hasattr(fobj, '_ext_file'): continue if fobj._ext_file.is_broken(): self.log.warning( "\t BROKEN EXTFILE: Couldn't migrate extfile for " "%s because of broken file", fobj.absolute_url() ) continue if fobj._ext_file.get_size(): data = fobj._ext_file.index_html() out = StringIO() out.filename = fobj._ext_file.id out.write(data) out.seek(0) fobj._bfile = make_blobfile( out, filename=fobj._ext_file.id, content_type=fobj._ext_file.content_type) fobj._p_changed = True self.log.info("Migrated %s bytes to bfile: %s" % (len(data), fobj.absolute_url())) fobj._ext_file._delete('/'.join(fobj._ext_file.filename)) del fobj._ext_file self.log.info("Removed _ext_file for %s" % fobj.absolute_url()) self.log.info('Migrated to bfile: %s' % fobj.absolute_url()) self.log.info('Migration done') return True
def _update(self, portal): brains = portal.portal_catalog(meta_type=['Naaya Publication']) for brain in brains: fobj = brain.getObject() self.log.info("Migrating object %s", fobj.absolute_url()) if not hasattr(fobj, '_ext_file'): continue if fobj._ext_file.is_broken(): self.log.warning( "\t BROKEN EXTFILE: Couldn't migrate extfile for " "%s because of broken file", fobj.absolute_url()) continue if fobj._ext_file.get_size(): data = fobj._ext_file.index_html() out = StringIO() out.filename = fobj._ext_file.id out.write(data) out.seek(0) fobj._bfile = make_blobfile( out, filename=fobj._ext_file.id, content_type=fobj._ext_file.content_type) fobj._p_changed = True self.log.info("Migrated %s bytes to bfile: %s" % (len(data), fobj.absolute_url())) fobj._ext_file._delete('/'.join(fobj._ext_file.filename)) del fobj._ext_file self.log.info("Removed _ext_file for %s" % fobj.absolute_url()) self.log.info('Migrated to bfile: %s' % fobj.absolute_url()) self.log.info('Migration done') return True
def versions(self, value): """ Import versions Required arguments: value -- Iterator over NyExFile versions """ for version in value: bf = make_blobfile(version, removed=False, timestamp=datetime.utcnow(), contributor='') vstorage = getattr(self.context, '_versions', None) if vstorage is None: self.context._versions = PersistentList() self.context._versions.append(bf) # self.context._save_file(version, # contributor='') self.context._versions[-1].timestamp = \ version.releasedate.asdatetime()
def manage_addFile(self, id, file="", **kwargs): # if self.is_ext: # return manage_addExtFile(self, id=id, file=file) if self.is_blobfile: if isinstance(file, basestring): if not bool(id): raise ValueError, "Please specify id of file passed as string" f = StringIO() f.write(file) f.seek(0) f.filename = id file = f if not bool(id): # TODO: make sure of proper id id = file.filename blobfile = make_blobfile(file) self._setObject(id, blobfile, set_owner=0) blobfile.id = id return blobfile.getId() else: return NyContainer.manage_addFile(self, id, file)
def addNyOrganisation(self, id='', REQUEST=None, contributor=None, **kwargs): """ Create an Organisation type of object. """ #process parameters if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate( schema_raw_data.pop('releasedate', '')) schema_raw_data.setdefault('details', '') schema_raw_data.setdefault('resourceurl', '') schema_raw_data.setdefault('source', '') schema_raw_data.setdefault('topitem', '') _organisation_word = schema_raw_data.get('organisation_word', '') id = make_id(self, id=id, title=schema_raw_data.get('title', ''), prefix='organisation') if contributor is None: contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() ob = _create_NyOrganisation_object(self, id, contributor) form_errors = ob.process_submitted_form(schema_raw_data, _lang, _override_releasedate=_releasedate) #check Captcha/reCaptcha if not self.checkPermissionSkipCaptcha(): captcha_validator = self.validateCaptcha(_organisation_word, REQUEST) if captcha_validator: form_errors['captcha'] = captcha_validator if form_errors: if REQUEST is None: raise ValueError(form_errors.popitem()[1]) # pick a random error else: import transaction transaction.abort( ) # because we already called _crete_NyZzz_object ob._prepare_error_response(REQUEST, form_errors, schema_raw_data) return REQUEST.RESPONSE.redirect('%s/organisation_add_html' % self.absolute_url()) return if self.glCheckPermissionPublishObjects(): approved, approved_by = 1, self.REQUEST.AUTHENTICATED_USER.getUserName( ) else: approved, approved_by = 0, None ob.approveThis(approved, approved_by) ob.submitThis() #Process uploaded file ob.picture = None _uploaded_file = schema_raw_data.pop('organisation_picture', None) if _uploaded_file is not None and _uploaded_file.filename: ob.picture = make_blobfile(_uploaded_file, removed=False, timestamp=datetime.utcnow()) if ob.discussion: ob.open_for_comments() self.recatalogNyObject(ob) notify(NyContentObjectAddEvent(ob, contributor, schema_raw_data)) #log post date auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) #redirect if case if REQUEST is not None: l_referer = REQUEST['HTTP_REFERER'].split('/')[-1] if l_referer == 'organisation_manage_add' or l_referer.find( 'organisation_manage_add') != -1: return self.manage_main(self, REQUEST, update_menu=1) elif l_referer == 'organisation_add_html': self.setSession('referer', self.absolute_url()) return ob.object_submitted_message(REQUEST) REQUEST.RESPONSE.redirect('%s/messages_html' % self.absolute_url()) return ob.getId()
def addNyOrganisation(self, id='', REQUEST=None, contributor=None, **kwargs): """ Create an Organisation type of object. """ #process parameters if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate(schema_raw_data.pop('releasedate', '')) schema_raw_data.setdefault('details', '') schema_raw_data.setdefault('resourceurl', '') schema_raw_data.setdefault('source', '') schema_raw_data.setdefault('topitem', '') _organisation_word = schema_raw_data.get('organisation_word', '') id = make_id(self, id=id, title=schema_raw_data.get('title', ''), prefix='organisation') if contributor is None: contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() ob = _create_NyOrganisation_object(self, id, contributor) form_errors = ob.process_submitted_form(schema_raw_data, _lang, _override_releasedate=_releasedate) #check Captcha/reCaptcha if not self.checkPermissionSkipCaptcha(): captcha_validator = self.validateCaptcha(_organisation_word, REQUEST) if captcha_validator: form_errors['captcha'] = captcha_validator if form_errors: if REQUEST is None: raise ValueError(form_errors.popitem()[1]) # pick a random error else: import transaction; transaction.abort() # because we already called _crete_NyZzz_object ob._prepare_error_response(REQUEST, form_errors, schema_raw_data) return REQUEST.RESPONSE.redirect('%s/organisation_add_html' % self.absolute_url()) return if self.glCheckPermissionPublishObjects(): approved, approved_by = 1, self.REQUEST.AUTHENTICATED_USER.getUserName() else: approved, approved_by = 0, None ob.approveThis(approved, approved_by) ob.submitThis() #Process uploaded file ob.picture = None _uploaded_file = schema_raw_data.pop('organisation_picture', None) if _uploaded_file is not None and _uploaded_file.filename: ob.picture = make_blobfile(_uploaded_file, removed=False, timestamp=datetime.utcnow()) if ob.discussion: ob.open_for_comments() self.recatalogNyObject(ob) notify(NyContentObjectAddEvent(ob, contributor, schema_raw_data)) #log post date auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) #redirect if case if REQUEST is not None: l_referer = REQUEST['HTTP_REFERER'].split('/')[-1] if l_referer == 'organisation_manage_add' or l_referer.find('organisation_manage_add') != -1: return self.manage_main(self, REQUEST, update_menu=1) elif l_referer == 'organisation_add_html': self.setSession('referer', self.absolute_url()) return ob.object_submitted_message(REQUEST) REQUEST.RESPONSE.redirect('%s/messages_html' % self.absolute_url()) return ob.getId()
def test_guess_mimetype(self): f = StringIO('some test image') f.filename = 'photo.jpg' bf = make_blobfile(f) self.assertEqual(bf.content_type, 'image/jpeg')
def parseFormData(self, data): if data is None or not getattr(data, 'filename', ''): return None return make_blobfile(data)
def _update(self, portal): brains = portal.portal_catalog(meta_type=['Naaya Survey Answer']) for brain in brains: try: obj = brain.getObject() except: self.log.warning( "Couldn't get obj based on catalog information %s", brain.getURL()) continue if not hasattr(obj, 'w_assessment-upload'): continue upload = getattr(obj, 'w_assessment-upload', None) if upload is None: continue if 'blob' in getattr(upload, 'meta_type', "").lower(): continue if upload.is_broken(): self.log.warning( "\t BROKEN EXTFILE: Couldn't migrate extfile for " "%s because of broken file", obj.absolute_url()) continue if upload.get_size(): data = upload.index_html() sfile = StringIO(data) self.log.debug('\t VERSION FILENAME: %s', '/'.join(upload.filename)) sfile.filename = upload.filename[-1] sfile.headers = {'content-type': upload.content_type} bf = make_blobfile(sfile, title=upload.title, removed=False, timestamp=datetime.utcnow(), contributor='') bf.filename = upload.id bf.content_type = upload.content_type bf.size = len(data) upload._delete('/'.join(upload.filename)) setattr(obj, 'w_assessment-upload', bf) self.log.info("Migrated %s bytes to bfile: %s" % (len(data), obj.absolute_url())) obj._p_changed = True brains = portal.portal_catalog(meta_type=['Naaya Mega Survey']) for brain in brains: obj = brain.getObject() self.log.info("Migrating object %s", obj.absolute_url()) for attach in obj.objectValues('Naaya Survey Attachment'): self.log.info("Migrating survey attachment %s", attach.absolute_url()) for fobj in attach.objectValues(): if not hasattr(fobj, '_ext_file'): continue if fobj._ext_file.is_broken(): self.log.warning( "\t BROKEN EXTFILE: Couldn't migrate extfile for " "%s because of broken file", fobj.absolute_url()) continue if fobj._ext_file.get_size(): data = fobj._ext_file.index_html() blob = fobj._bfile.open_write() blob.write(data) blob.seek(0) blob.close() fobj._bfile.filename = fobj._ext_file.id fobj._bfile.content_type = fobj._ext_file.content_type fobj._bfile.size = len(data) fobj._p_changed = True fobj._bfile._p_changed = True self.log.info("Migrated %s bytes to bfile: %s" % (len(data), fobj.absolute_url())) fobj._ext_file._delete('/'.join( fobj._ext_file.filename)) del fobj._ext_file self.log.info("Removed _ext_file for %s" % fobj.absolute_url()) self.log.info('Migrated to bfile: %s' % fobj.absolute_url()) self.log.info('Migration done') return True
def _update(self, portal): brains = portal.portal_catalog(meta_type=['Naaya Survey Answer']) for brain in brains: try: obj = brain.getObject() except: self.log.warning("Couldn't get obj based on catalog information %s", brain.getURL()) continue if not hasattr(obj, 'w_assessment-upload'): continue upload = getattr(obj, 'w_assessment-upload', None) if upload is None: continue if 'blob' in getattr(upload, 'meta_type', "").lower(): continue if upload.is_broken(): self.log.warning( "\t BROKEN EXTFILE: Couldn't migrate extfile for " "%s because of broken file", obj.absolute_url() ) continue if upload.get_size(): data = upload.index_html() sfile = StringIO(data) self.log.debug('\t VERSION FILENAME: %s', '/'.join(upload.filename)) sfile.filename = upload.filename[-1] sfile.headers = {'content-type': upload.content_type} bf = make_blobfile(sfile, title=upload.title, removed=False, timestamp=datetime.utcnow(), contributor='') bf.filename = upload.id bf.content_type = upload.content_type bf.size = len(data) upload._delete('/'.join(upload.filename)) setattr(obj, 'w_assessment-upload', bf) self.log.info("Migrated %s bytes to bfile: %s" % (len(data), obj.absolute_url())) obj._p_changed = True brains = portal.portal_catalog(meta_type=['Naaya Mega Survey']) for brain in brains: obj = brain.getObject() self.log.info("Migrating object %s", obj.absolute_url()) for attach in obj.objectValues('Naaya Survey Attachment'): self.log.info("Migrating survey attachment %s", attach.absolute_url()) for fobj in attach.objectValues(): if not hasattr(fobj, '_ext_file'): continue if fobj._ext_file.is_broken(): self.log.warning( "\t BROKEN EXTFILE: Couldn't migrate extfile for " "%s because of broken file", fobj.absolute_url() ) continue if fobj._ext_file.get_size(): data = fobj._ext_file.index_html() blob = fobj._bfile.open_write() blob.write(data) blob.seek(0) blob.close() fobj._bfile.filename = fobj._ext_file.id fobj._bfile.content_type = fobj._ext_file.content_type fobj._bfile.size = len(data) fobj._p_changed = True fobj._bfile._p_changed = True self.log.info("Migrated %s bytes to bfile: %s" % (len(data), fobj.absolute_url())) fobj._ext_file._delete('/'.join(fobj._ext_file.filename)) del fobj._ext_file self.log.info("Removed _ext_file for %s" % fobj.absolute_url()) self.log.info('Migrated to bfile: %s' % fobj.absolute_url()) self.log.info('Migration done') return True