def reply(self): userid = self.request.form.get('userid') if not userid: return self.error(message='Missing userid.') file_ = self.request.form.get('file') if not file_: return self.error(message='Missing file.') # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) try: adopt_user = api.env.adopt_user(username=userid) except api.exc.UserNotFoundError: return self.error(status=404, message='Unknown user.') with adopt_user: destination = self.destination() if destination: # XXX - Duck typing as error handling # We've encountered an error while discovering a destination if isinstance(destination, dict): return destination filename = file_.filename.decode('utf8') command = CreateDocumentCommand(destination, filename, file_) with elevated_privileges(): command.execute() self.request.response.setStatus(201) return super(ScanIn, self).reply()
def reply(self): userid = self.request.form.get('userid') if not userid: return self.error(message='Missing userid.') file_ = self.request.form.get('file') if not file_: return self.error(message='Missing file.') # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) try: adopt_user = api.env.adopt_user(username=userid) except api.exc.UserNotFoundError: return self.error(message='Unknown user.') with adopt_user: destination = self.destination() if destination is None: return self.error(message='Destination does not exist.') filename = file_.filename.decode('utf8') command = CreateDocumentCommand(destination, filename, file_) command.execute() self.request.response.setStatus(201) return super(ScanIn, self).reply()
def create_destination_document(self): # get all the metadata that will be set on the created file. # We blacklist some fields that should not be copied fields_to_skip = set(("file", "archival_file", "archival_file_state", "thumbnail", "preview", "digitally_available", "changeNote", "changed", "relatedItems",)) metadata = {} for schema in iterSchemataForType(self.context.portal_type): for name, schema_field in getFieldsInOrder(schema): if name in fields_to_skip: continue field_instance = schema_field.bind(self.context) metadata[name] = field_instance.get(self.context) command = CreateDocumentCommand(self.destination, None, None, **metadata) destination_document = command.execute() # We make it in shadow state until its file is set by the callback view destination_document.as_shadow_document() # Add marker interface. This should be useful in the future for # cleanup jobs, retries if the PDF was not delivered and so on. alsoProvides(destination_document, IDocumentSavedAsPDFMarker) # Add annotations needed for the SavePDFDocumentUnder view. annotations = IAnnotations(destination_document) annotations[PDF_SAVE_SOURCE_UUID_KEY] = IUUID(self.context) annotations[PDF_SAVE_SOURCE_VERSION_KEY] = self.version_id # The missing_value attribute of a z3c-form field is used # as soon as an object has no default_value i.e. after creating # an object trough the command-line. # # Because the relatedItems field needs a list as a missing_value, # we will fall into the "mutable keyword argument"-python gotcha. # The relatedItems will be shared between the object-instances. # # Unfortunately the z3c-form field does not provide a # missing_value-factory (like the defaultFactory) which would be # necessary to fix this issue properly. # # As a workaround we make sure that the new document's relatedItems # is different object from the source document's. IRelatedDocuments(destination_document).relatedItems = list( IRelatedDocuments(destination_document).relatedItems) IRelatedDocuments(destination_document).relatedItems.append( RelationValue(getUtility(IIntIds).getId(self.context))) msg = _(u'Document ${document} was successfully created in ${destination}', mapping={"document": destination_document.title, "destination": self.destination.title}) api.portal.show_message(msg, self.request, type='info') return destination_document
def test_create_document_from_command(self): self.login(self.regular_user) command = CreateDocumentCommand( self.dossier, 'testm\xc3\xa4il.txt', 'buh!', title='\xc3\x9cnicode') document = command.execute() self.assertIsInstance(document.title, unicode) self.assertEqual(u'\xdcnicode', document.title) self.assertEqual('buh!', document.file.data) self.assertEqual('text/plain', document.file.contentType)
def create_tasks_listing_pdf(self): """Creates a pdf representation of the dossier tasks, and add it to the dossier as a normal document. If the dossiers has an end date use that date as the document date. This prevents the dossier from entering an invalid state with a document date outside the dossiers start-end range. """ if not self.get_property('tasks_pdf_enabled'): return view = self.context.unrestrictedTraverse('pdf-dossier-tasks') today = api.portal.get_localized_time(datetime=datetime.today(), long_format=True) filename = u'Tasks {}.pdf'.format(today) title = _(u'title_dossier_tasks', default=u'Task list of dossier ${title}, ${timestamp}', mapping={ 'title': self.context.title, 'timestamp': today }) kwargs = { 'preserved_as_paper': False, } dossier = IDossier(self.context) if dossier and dossier.end: kwargs['document_date'] = dossier.end results = api.content.find(object_provides=IDossierTasksPDFMarker, depth=1, context=self.context) with elevated_privileges(): if len(results) > 0: document = results[0].getObject() document.title = translate(title, context=self.context.REQUEST) comment = _( u'Updated with a newer generated version from dossier ${title}.', mapping=dict(title=self.context.title)) document.update_file(view.get_data(), create_version=True, comment=comment) return document = CreateDocumentCommand( self.context, filename, view.get_data(), title=translate(title, context=self.context.REQUEST), content_type='application/pdf', interfaces=[IDossierTasksPDFMarker], **kwargs).execute() document.reindexObject(idxs=['object_provides'])
def test_create_document_from_command(self): self.login(self.regular_user) command = CreateDocumentCommand(self.dossier, 'testm\xc3\xa4il.txt', 'buh!', title='\xc3\x9cnicode') document = command.execute() self.assertIsInstance(document.title, unicode) self.assertEqual(u'\xdcnicode', document.title) self.assertEqual('buh!', document.file.data) self.assertEqual('text/plain', document.file.contentType)
def create_tasks_listing_pdf(self): """Creates a pdf representation of the dossier tasks, and add it to the dossier as a normal document. If the dossiers has an end date use that date as the document date. This prevents the dossier from entering an invalid state with a document date outside the dossiers start-end range. """ if not self.get_property('tasks_pdf_enabled'): return view = self.context.unrestrictedTraverse('pdf-dossier-tasks') today = api.portal.get_localized_time( datetime=datetime.today(), long_format=True) filename = u'Tasks {}.pdf'.format(today) title = _(u'title_dossier_tasks', default=u'Task list of dossier ${title}, ${timestamp}', mapping={'title': self.context.title, 'timestamp': today}) kwargs = { 'preserved_as_paper': False, } dossier = IDossier(self.context) if dossier and dossier.end: kwargs['document_date'] = dossier.end results = api.content.find(object_provides=IDossierTasksPDFMarker, depth=1, context=self.context) with elevated_privileges(): if len(results) > 0: document = results[0].getObject() document.title = translate(title, context=self.context.REQUEST) comment = _(u'Updated with a newer generated version from dossier ${title}.', mapping=dict(title=self.context.title)) document.update_file(view.get_data(), create_version=True, comment=comment) return document = CreateDocumentCommand( self.context, filename, view.get_data(), title=translate(title, context=self.context.REQUEST), content_type='application/pdf', interfaces=[IDossierTasksPDFMarker], **kwargs).execute() document.reindexObject(idxs=['object_provides'])
def schedule_ad_hoc(self, title): committee = self.committee.resolve_committee() ad_hoc_template = committee.get_ad_hoc_template() if not ad_hoc_template: raise MissingAdHocTemplate meeting_dossier = self.get_dossier() if not api.user.get_current().checkPermission( 'opengever.document: Add document', meeting_dossier): raise MissingMeetingDossierPermissions document_title = _(u'title_ad_hoc_document', default=u'Ad hoc agenda item ${title}', mapping={u'title': title}) ad_hoc_document = CreateDocumentCommand( context=meeting_dossier, filename=ad_hoc_template.file.filename, data=ad_hoc_template.file.data, content_type=ad_hoc_template.file.contentType, title=translate(document_title, context=getRequest())).execute() agenda_item = AgendaItem(title=title, document=ad_hoc_document, is_paragraph=False) self.agenda_items.append(agenda_item) self.reorder_agenda_items() return agenda_item
def create_proposal_document(self, source_blob=None, **kwargs): """Creates a proposal document within this proposal or submitted proposal. Only one proposal document can be created. """ if not is_word_meeting_implementation_enabled(): raise WordMeetingImplementationDisabledError() if self.get_proposal_document(): raise ValueError('There is already a proposal document.') if source_blob: kwargs.setdefault('filename', source_blob.filename) kwargs.setdefault('data', source_blob.open().read()) kwargs.setdefault('content_type', source_blob.contentType) kwargs['context'] = self kwargs.setdefault('preserved_as_paper', False) title = _(u'proposal_document_title', default=u'Proposal document ${title}', mapping={'title': safe_unicode(self.Title())}) title = translate(title, context=self.REQUEST).strip() kwargs.setdefault('title', title) with elevated_privileges(): obj = CreateDocumentCommand(**kwargs).execute() self._proposal_document_uuid = IUUID(obj) return obj
def __call__(self, filename, title, description, content_type, data, portal_type): """Quickupload description inputs are hidden in gever therefore we skip the description. """ if self.is_email_upload(filename): command = CreateEmailCommand( self.context, filename, data, message_source=MESSAGE_SOURCE_DRAG_DROP_UPLOAD) else: command = CreateDocumentCommand(self.context, filename, data) try: obj = command.execute() except ForbiddenByQuota as exc: # this is an error, we must not commit transaction.abort() return { 'error': translate(exc.message, context=self.context.REQUEST), 'success': None } result = {'success': obj} return result
def generate_excerpt(self, title): """Generate an excerpt from the agenda items document. Can either be an excerpt from the proposals document or an excerpt from the ad-hoc agenda items document. In both cases the excerpt is stored in the meeting dossier. """ assert self.can_generate_excerpt() meeting_dossier = self.meeting.get_dossier() source_document = self.resolve_document() if not source_document: raise ValueError('The agenda item has no document.') if not api.user.get_current().checkPermission( 'opengever.document: Add document', meeting_dossier): raise MissingMeetingDossierPermissions excerpt_document = CreateDocumentCommand( context=meeting_dossier, filename=source_document.file.filename, data=source_document.file.data, content_type=source_document.file.contentType, title=title).execute() if self.has_proposal: submitted_proposal = self.proposal.resolve_submitted_proposal() submitted_proposal.append_excerpt(excerpt_document) else: self.excerpts.append(Excerpt( excerpt_oguid=Oguid.for_object(excerpt_document))) return excerpt_document
def create_journal_pdf(self): """Creates a pdf representation of the dossier journal, and add it to the dossier as a normal document. """ if not self.get_property('journal_pdf_enabled'): return view = self.context.unrestrictedTraverse('pdf-dossier-journal') today = api.portal.get_localized_time(datetime=datetime.today(), long_format=True) filename = u'Journal {}.pdf'.format(today) title = _(u'title_dossier_journal', default=u'Journal of dossier ${title}, ${timestamp}', mapping={ 'title': self.context.title, 'timestamp': today }) with elevated_privileges(): CreateDocumentCommand(self.context, filename, view.get_data(), title=translate( title, context=self.context.REQUEST), content_type='application/pdf', preserved_as_paper=False).execute()
def extract_attachment_into_parent(self, position): """Extract one specified attachment into the mails parent dossier or inbox. Also add a reference from all attached documents (*not* mails) to self. Position must be an integer attachment positions. The position can be obtained from the attachment description returned by `get_attachments`. """ parent = self.get_extraction_parent() if parent is None: raise RuntimeError("Could not find a parent dossier or inbox for " "{}".format(self.absolute_url())) data, content_type, filename = self._get_attachment_data(position) title = os.path.splitext(filename)[0] if content_type == 'message/rfc822': doc = CreateEmailCommand(parent, filename, data, title=title, content_type=content_type, digitally_available=True).execute() else: doc = CreateDocumentCommand(parent, filename, data, title=title, content_type=content_type, digitally_available=True).execute() # add a reference from the attachment to the mail intids = getUtility(IIntIds) iid = intids.getId(self) IRelatedDocuments(doc).relatedItems = [RelationValue(iid)] doc.reindexObject() return doc
def schedule_ad_hoc(self, title, template_id=None, description=None): committee = self.committee.resolve_committee() if template_id is None: ad_hoc_template = committee.get_ad_hoc_template() else: from opengever.meeting.vocabulary import ProposalTemplatesForCommitteeVocabulary vocabulary_factory = ProposalTemplatesForCommitteeVocabulary() vocabulary = vocabulary_factory(committee) templates = [ term.value for term in vocabulary if term.value.getId() == template_id ] assert 1 == len(templates) ad_hoc_template = templates[0] if not ad_hoc_template: raise MissingAdHocTemplate meeting_dossier = self.get_dossier() if not api.user.get_current().checkPermission( 'opengever.document: Add document', meeting_dossier): raise MissingMeetingDossierPermissions ad_hoc_document = CreateDocumentCommand( context=meeting_dossier, filename=ad_hoc_template.file.filename, data=ad_hoc_template.file.data, content_type=ad_hoc_template.file.contentType, title=title).execute() agenda_item = AgendaItem(title=title, description=description, document=ad_hoc_document, is_paragraph=False) self.agenda_items.append(agenda_item) self.reorder_agenda_items() return agenda_item
def create_proposal_document(self, source_blob=None, **kwargs): """Creates a proposal document within this proposal or submitted proposal. Only one proposal document can be created. """ if self.get_proposal_document(): raise ValueError('There is already a proposal document.') if source_blob: kwargs.setdefault('filename', source_blob.filename) kwargs.setdefault('data', source_blob.open().read()) kwargs.setdefault('content_type', source_blob.contentType) kwargs['context'] = self kwargs.setdefault('preserved_as_paper', False) kwargs.setdefault('title', safe_unicode(self.Title())) with elevated_privileges(): obj = CreateDocumentCommand(**kwargs).execute() self._proposal_document_uuid = IUUID(obj) return obj
def create_journal_pdf(self): """Creates a pdf representation of the dossier journal, and add it to the dossier as a normal document. If the dossiers has an end date use that date as the document date. This prevents the dossier from entering an invalid state with a document date outside the dossiers start-end range. """ if not self.get_property('journal_pdf_enabled'): return view = self.context.unrestrictedTraverse('pdf-dossier-journal') today = api.portal.get_localized_time(datetime=datetime.today(), long_format=True) filename = u'Journal {}.pdf'.format(today) title = _(u'title_dossier_journal', default=u'Journal of dossier ${title}, ${timestamp}', mapping={ 'title': self.context.title, 'timestamp': today }) kwargs = { 'preserved_as_paper': False, } dossier = IDossier(self.context) if dossier and dossier.end: kwargs['document_date'] = dossier.end with elevated_privileges(): CreateDocumentCommand(self.context, filename, view.get_data(), title=translate( title, context=self.context.REQUEST), content_type='application/pdf', **kwargs).execute()
def create_destination_document(self): # get all the metadata that will be set on the created file. # We blacklist some fields that should not be copied fields_to_skip = set(( "file", "archival_file", "archival_file_state", "thumbnail", "preview", "digitally_available", "changeNote", "changed", "relatedItems", )) metadata = {} for schema in iterSchemataForType(self.context.portal_type): for name, schema_field in getFieldsInOrder(schema): if name in fields_to_skip: continue field_instance = schema_field.bind(self.context) metadata[name] = field_instance.get(self.context) command = CreateDocumentCommand(self.destination, None, None, **metadata) destination_document = command.execute() # We make it in shadow state until its file is set by the callback view destination_document.as_shadow_document() # Add marker interface. This should be useful in the future for # cleanup jobs, retries if the PDF was not delivered and so on. alsoProvides(destination_document, IDocumentSavedAsPDFMarker) # Add annotations needed for the SavePDFDocumentUnder view. annotations = IAnnotations(destination_document) annotations[PDF_SAVE_SOURCE_UUID_KEY] = IUUID(self.context) annotations[PDF_SAVE_SOURCE_VERSION_KEY] = self.version_id # The missing_value attribute of a z3c-form field is used # as soon as an object has no default_value i.e. after creating # an object trough the command-line. # # Because the relatedItems field needs a list as a missing_value, # we will fall into the "mutable keyword argument"-python gotcha. # The relatedItems will be shared between the object-instances. # # Unfortunately the z3c-form field does not provide a # missing_value-factory (like the defaultFactory) which would be # necessary to fix this issue properly. # # As a workaround we make sure that the new document's relatedItems # is different object from the source document's. IRelatedDocuments(destination_document).relatedItems = list( IRelatedDocuments(destination_document).relatedItems) IRelatedDocuments(destination_document).relatedItems.append( RelationValue(getUtility(IIntIds).getId(self.context))) msg = _( u'Document ${document} was successfully created in ${destination}', mapping={ "document": destination_document.title, "destination": self.destination.title }) api.portal.show_message(msg, self.request, type='info') return destination_document