def set_archival_file(self, document, data, filename=u'test.pdf', conversion_state=STATE_CONVERTED): archival_file = NamedBlobFile(data=data, filename=u'test.pdf') IDocumentMetadata(document).archival_file_state = conversion_state IDocumentMetadata(document).archival_file = archival_file
def test_archival_file_management_view_listing(self, browser): self.login(self.manager, browser) subdossier = create( Builder('dossier').within( self.expired_dossier).titled(u"Subdossier")) subdocument = create( Builder('document').within(subdossier).with_dummy_content().titled( u"subdocument")) document = create( Builder('document').within( self.expired_dossier).with_dummy_content().titled( u"Another document")) ArchivalFileConverter(subdocument).store_file('TEST DATA') IDocumentMetadata(self.expired_document ).archival_file_state = STATE_FAILED_TEMPORARILY # make sure that document with no archival file is handled by the view self.assertIsNone(IDocumentMetadata(document).archival_file) browser.open(self.expired_dossier, view="archival_file_management") table = browser.css('table').first expected = [[ 'Path', 'Filetype', 'Has archival PDF', 'Archival file state' ], [ self.expired_document.absolute_url_path(), '.doc', 'True', "STATE_FAILED_TEMPORARILY" ], [document.absolute_url_path(), '.doc', 'False', ''], [ subdocument.absolute_url_path(), '.doc', 'True', "STATE_CONVERTED" ]] self.assertEqual(expected, table.lists())
def initialize_required_metadata(self, mail): mail_metadata = IDocumentMetadata(mail) date_time = datetime.fromtimestamp( utils.get_date_header(mail.msg, 'Date')) mail_metadata.document_date = date_time.date() # Receipt date should be None for migrated mails mail_metadata.receipt_date = None mail_metadata.document_author = get_author_by_email(mail)
def setUp(self): super(TestDocumentOverviewMissingFields, self).setUp() omitted_values = [] if OMITTED_KEY in IDocumentMetadata.getTaggedValueTags(): omitted_values.extend( IDocumentMetadata.getTaggedValue(OMITTED_KEY)) self.orig_omitted_values = list(omitted_values) omitted_values.append((Interface, 'document_type', 'true')) IDocumentMetadata.setTaggedValue(OMITTED_KEY, omitted_values) self.document = create(Builder('document'))
def test_earliest_possible_is_latest_of_dossiers_end_dates_and_document_dates(self): self.login(self.dossier_responsible) IDocumentMetadata(self.document).document_date = date(2020, 1, 1) self.document.reindexObject(idxs=['document_date']) IDossier(self.subdossier).end = date(2020, 2, 2) self.subdossier.reindexObject(idxs=['end']) self.assertEquals(date(2020, 2, 2), self.dossier.earliest_possible_end_date()) IDocumentMetadata(self.document).document_date = date(2020, 3, 3) self.document.reindexObject(idxs=['document_date']) self.assertEquals(date(2020, 3, 3), self.dossier.earliest_possible_end_date())
def test_save_pdf_under_form_copies_metadata_to_created_document(self, browser): self.login(self.regular_user, browser) # Fill metadata of document metadata_dict = {"description": "Document description", u'keywords': ("test", "document"), u'foreign_reference': "1234", u'document_date': datetime(2018, 1, 1), u'receipt_date': datetime(2018, 1, 2), u'delivery_date': datetime(2018, 1, 3), u'document_type': 'contract', u'document_author': 'test_user_1_', u'preserved_as_paper': True, u'digitally_available': True, u'thumbnail': "thumbnail", u'preview': "preview", u"archival_file": "archival_file", u"archival_file_state": STATE_CONVERTED, } # fields that should not be copied over fields_to_skip = set(("file", "archival_file", "archival_file_state", "thumbnail", "preview", "digitally_available")) for field, value in metadata_dict.items(): setattr(IDocumentMetadata(self.document), field, value) browser.open(self.document, view='save_pdf_under') browser.forms.get('form').find_field("Destination").fill(self.empty_dossier) with self.observe_children(self.empty_dossier) as children: browser.click_on("Save") self.assertEqual(len(children["added"]), 1) created_document = children["added"].pop() for field, value in metadata_dict.items(): if field in fields_to_skip: self.assertNotEqual( value, getattr(IDocumentMetadata(created_document), field), "{} should not be copied to destination document".format(field) ) else: self.assertEqual( value, getattr(IDocumentMetadata(created_document), field), "{} should be copied to destination document".format(field) )
def get_templates(context): """We only want to document templates that are directly contained in a templatefolder, and not those contained in dossiertemplate """ results = api.content.find(portal_type="opengever.dossier.templatefolder") template_folders = [brain.getObject() for brain in results] if not template_folders: # this may happen when the user does not have permissions to # view templates and/or during ++widget++ traversal return SimpleVocabulary([]) templates = [] for template_folder in template_folders: templates.extend( api.content.find(context=template_folder, depth=1, portal_type="opengever.document.document", sort_on='sortable_title', sort_order='ascending')) templates.sort(key=lambda template: template.Title.lower()) intids = getUtility(IIntIds) terms = [] for brain in templates: template = brain.getObject() if IDocumentMetadata(template).digitally_available: terms.append( SimpleVocabulary.createTerm(template, str(intids.getId(template)), template.title)) return SimpleVocabulary(terms)
def test_document_type_indexer(self): document = create(Builder("document")) self.assertEqual(index_data_for(document)['document_type'], None) IDocumentMetadata(document).document_type = "question" document.reindexObject() self.assertEqual(index_data_for(document)['document_type'], "question")
def binding(self): dokument = arelda.dokumentGeverSIP(id=u'_{}'.format(self.obj.UID())) dokument.titel = self.obj.Title().decode('utf8') md = IDocumentMetadata(self.obj) if md.document_author: dokument.autor.append(md.document_author) if self.obj.digitally_available: dokument.erscheinungsform = u'digital' else: dokument.erscheinungsform = u'nicht digital' dokument.dokumenttyp = voc_term_title( IDocumentMetadata['document_type'], md.document_type) dokument.registrierdatum = arelda.historischerZeitpunkt( self.obj.created().asdatetime().date()) dokument.entstehungszeitraum = arelda.historischerZeitraum() dokument.entstehungszeitraum.von = arelda.historischerZeitpunkt( self.obj.created().asdatetime().date()) dokument.entstehungszeitraum.bis = arelda.historischerZeitpunkt( self.obj.modified().asdatetime().date()) set_classification_attributes(dokument, self.obj) for file_ref in self.file_refs: dokument.dateiRef.append(file_ref) return dokument
def store_file(self, data, mimetype='application/pdf'): if isinstance(mimetype, unicode): mimetype = mimetype.encode('utf-8') IDocumentMetadata(self.document).archival_file = NamedBlobFile( data=data, contentType=mimetype, filename=self.get_file_name()) self.set_state(STATE_CONVERTED)
def fix_contenttype_encoding(self, document): if not IDocumentMetadata(document).archival_file: return content_type = document.archival_file.contentType if isinstance(content_type, unicode): document.archival_file.contentType = content_type.encode('utf-8')
def test_earliest_possible_can_handle_datetime_objs(self): self.login(self.dossier_responsible) IDocumentMetadata(self.document).document_date = datetime(2020, 1, 1, 10, 10) self.document.reindexObject(idxs=['document_date']) IDossier(self.subdossier).end = date(2020, 2, 2) self.subdossier.reindexObject(idxs=['end']) self.assertEquals(date(2020, 2, 2), self.dossier.earliest_possible_end_date())
def test_user_CAN_change_the_archival_file(self, browser): browser.login().visit(self.document, view='edit_archival_file') browser.fill({ 'Archival File': ('FILE DATA', 'archival_file.pdf') }).submit() archival_file = IDocumentMetadata(self.document).archival_file self.assertTrue(isinstance(archival_file, NamedBlobFile)) self.assertEquals('application/pdf', archival_file.contentType) self.assertEquals('FILE DATA', archival_file.data)
def get_keywords(self): linked_keywords = [{ 'url': u'{}/@@search?Subject={}'.format( api.portal.get().absolute_url(), quote_plus(safe_unicode(keyword).encode('utf-8'))), 'title': keyword, } for keyword in IDocumentMetadata(self.context).keywords] return linked_keywords
def test_trigger_conversion_skip_files_in_manually_state(self): document = create( Builder('document').titled( u'\xdcberpr\xfcfung XY').with_dummy_content().having( archival_file_state=STATE_MANUALLY_PROVIDED)) ArchivalFileConverter(self.document).trigger_conversion() self.assertEquals(STATE_MANUALLY_PROVIDED, IDocumentMetadata(document).archival_file_state)
def test_set_to_manually_when_archival_file_is_added_in_edit_form( self, browser): document = create(Builder('document').within(self.dossier)) browser.login().open(document, view='edit') browser.fill({'Archival File': ('FILE DATA', 'archival_file.pdf')}) browser.click_on('Save') self.assertEquals(STATE_MANUALLY_PROVIDED, IDocumentMetadata(document).archival_file_state)
def test_enddate_may_be_latest_dossier_end_date(self, browser): """When a dossiers end date is greater than the document's date, use the dossier end date. """ self.login(self.dossier_responsible, browser) IDossier(self.dossier).end = date(2021, 2, 2) self.dossier.reindexObject(idxs=['end']) IDocumentMetadata(self.subdocument).document_date = date(2021, 2, 1) self.subdocument.reindexObject(idxs=['document_date']) browser.open(self.dossier, view='transition-archive') self.assertEqual(date(2021, 2, 2), self._get_form_date(browser, 'dossier_enddate'))
def test_is_not_updated_when_archival_file_is_not_changed(self, browser): document = create( Builder('document').within( self.dossier).attach_archival_file_containing('DATA').having( archival_file_state=STATE_CONVERTED)) browser.login().open(document, view='edit') browser.fill({'Title': u'New document title'}) browser.click_on('Save') self.assertEquals(STATE_CONVERTED, IDocumentMetadata(document).archival_file_state)
def test_set_to_manually_when_archival_file_is_updated_in_archival_file_form( self, browser): document = create( Builder('document').within( self.dossier).attach_archival_file_containing('DATA').having( archival_file_state=STATE_CONVERTED)) browser.login().open(document, view='edit_archival_file') browser.fill({'Archival File': ('NEW FILE DATA', 'ddd.pdf')}) browser.click_on('Save') self.assertEquals(STATE_MANUALLY_PROVIDED, IDocumentMetadata(document).archival_file_state)
def test_removes_state_when_archival_file_is_removed_in_archival_file_form( self, browser): document = create( Builder('document').within( self.dossier).attach_archival_file_containing('DATA').having( archival_file_state=STATE_CONVERTED)) browser.login().open(document, view='edit_archival_file') remove_radio_button = browser.css( '#form-widgets-archival_file-remove').first remove_radio_button.checked = 'checked' browser.find('Save').click() self.assertIsNone(IDocumentMetadata(document).archival_file_state)
def get_archival_file_class(self): mtr = getToolByName(self, 'mimetypes_registry', None) archival_file = IDocumentMetadata(self.context).archival_file normalize = getUtility(IIDNormalizer).normalize try: icon = mtr.lookup(archival_file.contentType)[0].icon_path filetype = icon[:icon.rfind('.')].replace('icon_', '') return 'icon-%s' % normalize(filetype) except MimeTypeException: pass return 'contenttype-opengever-document-document'
def test_sets_failed_permanently_state_when_conversion_was_skipped(self): with freeze(datetime(2016, 4, 25, 10, 24)): body = { "status": "skipped", "error": "File is password protected.", "token": download_token_for(self.document) } self.request.set('BODY', json.dumps(body)) view = StoreArchivalFile(self.document, self.request) view() self.assertEquals(STATE_FAILED_PERMANENTLY, IDocumentMetadata(self.document).archival_file_state)
def metadata(obj): metadata = [] reference_number = IReferenceNumber(obj) metadata.append(reference_number.get_number()) doc_metadata = IDocumentMetadata(obj) if doc_metadata.description: metadata.append(doc_metadata.description.encode('utf8')) if doc_metadata.keywords: metadata.extend([k.encode('utf8') for k in doc_metadata.keywords]) if doc_metadata.foreign_reference: metadata.append(doc_metadata.foreign_reference.encode('utf8')) return ' '.join(metadata)
def test_sets_failed_temporary_state_when_conversion_has_not_succeeded_or_skipped( self): with freeze(datetime(2016, 4, 25, 10, 24)): body = { "status": "failed", "error": "Some parts of the document could not be processed", "token": download_token_for(self.document) } self.request.set('BODY', json.dumps(body)) view = StoreArchivalFile(self.document, self.request) view() self.assertEquals(STATE_FAILED_TEMPORARILY, IDocumentMetadata(self.document).archival_file_state)
def test_regular_user_can_add_new_keywords_in_document(self, browser): self.login(self.regular_user, browser) browser.open(self.subsubdocument, view='@@edit') keywords = browser.find_field_by_text(u'Keywords') new = browser.css('#' + keywords.attrib['id'] + '_new').first new.text = u'NewItem1\nNew Item 2\nN\xf6i 3' browser.find_button_by_label('Save').click() self.assertItemsEqual(('New Item 2', 'NewItem1', u'N\xf6i 3'), IDocumentMetadata(self.subsubdocument).keywords) browser.open(self.subsubdocument, view='edit') keywords = browser.find_field_by_text(u'Keywords') self.assertItemsEqual(('New Item 2', 'NewItem1', 'N=C3=B6i 3'), tuple(keywords.value))
def test_updates_archival_file_when_conversion_succeeded(self): with freeze(datetime(2016, 4, 25, 10, 24)): body = { 'status': "success", 'data': "data:application/pdf;base64,VGVzdCBTdHJpbmc=", 'token': download_token_for(self.document) } self.request.set('BODY', json.dumps(body)) view = StoreArchivalFile(self.document, self.request) view() archival_file = IDocumentMetadata(self.document).archival_file self.assertEquals('Ueberpruefung XY.pdf', archival_file.filename) self.assertTrue(isinstance(archival_file, NamedBlobFile)) self.assertEquals('application/pdf', archival_file.contentType) self.assertEquals('Test String', archival_file.data)
def test_regular_user_can_add_new_keywords_in_sablon(self, browser): self.grant('Reader', 'Contributor', 'Editor') browser.login().visit(self.sablon_template, view='@@edit') keywords = browser.find_field_by_text(u'Keywords') new = browser.css('#' + keywords.attrib['id'] + '_new').first new.text = u'NewItem1\nNew Item 2\nN\xf6i 3' browser.find_button_by_label('Save').click() self.assertItemsEqual(('New Item 2', 'NewItem1', u'N\xf6i 3'), IDocumentMetadata(self.sablon_template).keywords) browser.visit(self.sablon_template, view='edit') keywords = browser.find_field_by_text(u'Keywords') self.assertItemsEqual(('New Item 2', 'NewItem1', 'N=C3=B6i 3'), tuple(keywords.value))
def __call__(self): searchable = [] # append some other attributes to the searchableText index # reference_number refNumb = getAdapter(self.context, IReferenceNumber) searchable.append(refNumb.get_number()) # sequence_number seqNumb = getUtility(ISequenceNumber) searchable.append(str(seqNumb.get_number(self.context))) # keywords keywords = IDocumentMetadata(self.context).keywords if keywords: searchable.extend(safe_utf8(keyword) for keyword in keywords) return ' '.join(searchable)
def get_documents(self): catalog = api.portal.get_tool('portal_catalog') docs = catalog.unrestrictedSearchResults( path=self.context.absolute_url_path(), portal_type='opengever.document.document', sort_on="path") for doc in docs: obj = doc.getObject() metadata = IDocumentMetadata(obj) doc_info = {} doc_info["path"] = obj.absolute_url_path() doc_info["url"] = obj.absolute_url() doc_info["filetype"] = doc.file_extension doc_info["has_archival_file"] = bool(metadata.archival_file) doc_info["archival_file_state"] = ARCHIVAL_FILE_STATE_MAPPING.get( metadata.archival_file_state) yield doc_info
def binding(self): d = ech0147t0.documentType() d.uuid = self.obj.UID() d.titles = ech0039.titlesType() d.titles.append( ech0039.titleType(self.obj.Title().decode('utf8'), lang=u'DE')) d.status = u'undefined' d.files = ech0147t0.filesType() f = ech0147t0.fileType() f.pathFileName = self.path f.mimeType = self.obj.file.contentType f.hashCodeAlgorithm, f.hashCode = file_checksum(self.blobpath) d.files.append(f) c_obj = IClassification(self.obj) d.classification = ech0039.classificationType( CLASSIFICATION_MAPPING[c_obj.classification]) d.hasPrivacyProtection = PRIVACY_LAYER_MAPPING[c_obj.privacy_layer] d.openToThePublic = PUBLIC_TRIAL_MAPPING[c_obj.public_trial] md = IDocumentMetadata(self.obj) d.documentKind = md.document_type d.openingDate = md.document_date d.ourRecordReference = md.foreign_reference d.owner = md.document_author if md.keywords: d.keywords = ech0039.keywordsType() for keyword in md.keywords: d.keywords.append(ech0039.keywordType(keyword, lang=u'DE')) # Optional, currently not supported properties d.signer = None d.comments = None d.isLeadingDocument = None d.sortOrder = None d.applicationCustom = None return d
def get_templates(context): template_folder = get_template_folder() if template_folder is None: # this may happen when the user does not have permissions to # view templates and/or during ++widget++ traversal return SimpleVocabulary([]) templates = api.content.find(context=template_folder, depth=-1, portal_type="opengever.document.document", sort_on='sortable_title', sort_order='ascending') intids = getUtility(IIntIds) terms = [] for brain in templates: template = brain.getObject() if IDocumentMetadata(template).digitally_available: terms.append( SimpleVocabulary.createTerm(template, str(intids.getId(template)), template.title)) return SimpleVocabulary(terms)
def ensure_utf_8_keywords(self): for obj in self.objects(self.query, 'Ensure keywords are utf-8'): doc = IDocumentMetadata(obj) doc.keywords = tuple( safe_unicode(keyword).encode('utf-8') for keyword in doc.keywords)
def tearDown(self): IDocumentMetadata.setTaggedValue(OMITTED_KEY, self.orig_omitted_values)
def make_document_keywords_unicode(self): query = {'object_provides': [IDocumentMetadata.__identifier__]} for obj in self.objects(query, 'Ensure document keywords are unicode'): doc = IDocumentMetadata(obj) doc.keywords = tuple( safe_unicode(keyword) for keyword in doc.keywords)