From d3a4d65720e08bd15ddb9a410a26846e82a84e96 Mon Sep 17 00:00:00 2001 From: Philippe Gross Date: Thu, 9 May 2019 08:19:20 +0200 Subject: [PATCH 1/6] Rework SIP Package generation and download. Store SIP package as a blob locally instead of re generating them for each download. This solves time and ressources and makes it possible to provide customer specific scripts and SIP package handling. --- opengever/disposition/browser/configure.zcml | 14 ++++++ opengever/disposition/browser/ech0160.py | 38 ++++++++++++++ opengever/disposition/disposition.py | 43 +++++++++++++++- .../disposition/tests/test_ech0160export.py | 50 +++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) diff --git a/opengever/disposition/browser/configure.zcml b/opengever/disposition/browser/configure.zcml index 9873f2116bc..3ee5cbaa130 100644 --- a/opengever/disposition/browser/configure.zcml +++ b/opengever/disposition/browser/configure.zcml @@ -38,6 +38,20 @@ permission="opengever.disposition.DownloadSIPPackage" /> + + + + Date: Thu, 9 May 2019 10:15:31 +0200 Subject: [PATCH 2/6] Switch SIP download button to the download view. The export view stays still available, but is no longer available trough the UI, can be useful for debugging purposes. --- opengever/disposition/browser/ech0160.py | 10 +++------- opengever/disposition/browser/overview.py | 11 ++++++++++- opengever/disposition/tests/test_ech0160export.py | 2 +- opengever/disposition/tests/test_overview.py | 12 +++++++++++- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/opengever/disposition/browser/ech0160.py b/opengever/disposition/browser/ech0160.py index 50ce4d87df7..26c55a85788 100644 --- a/opengever/disposition/browser/ech0160.py +++ b/opengever/disposition/browser/ech0160.py @@ -2,6 +2,7 @@ from opengever.disposition import _ from opengever.disposition.ech0160.sippackage import SIPPackage from plone import api +from plone.namedfile.utils import set_headers from plone.namedfile.utils import stream_data from Products.Five import BrowserView from pyxb.utils.domutils import BindingDOMSupport @@ -64,11 +65,6 @@ def __call__(self): return self.request.RESPONSE.redirect(self.context.absolute_url()) sip_package = self.context.get_sip_package() - response = self.request.response - response.setHeader( - "Content-Disposition", - 'inline; filename="%s.zip"' % self.context.get_sip_name()) - response.setHeader("Content-type", "application/zip") - response.setHeader("Content-Length", sip_package.getSize()) - + set_headers(sip_package, self.request.response, + u'{}.zip'.format(self.context.get_sip_name())) return stream_data(sip_package) diff --git a/opengever/disposition/browser/overview.py b/opengever/disposition/browser/overview.py index 376a0d33075..596b763255a 100644 --- a/opengever/disposition/browser/overview.py +++ b/opengever/disposition/browser/overview.py @@ -76,7 +76,7 @@ def get_actions(self): {'id': 'sip_download', 'label': _('label_dispositon_package_download', default=u'Download disposition package'), - 'url': '{}/ech0160_export'.format(self.context.absolute_url()), + 'url': '{}/ech0160_download'.format(self.context.absolute_url()), 'visible': self.sip_download_available(), 'class': 'sip_download'}, {'id': 'removal_protocol', @@ -88,6 +88,15 @@ def get_actions(self): ] def sip_download_available(self): + if api.user.has_permission( + 'opengever.disposition: Download SIP Package', + obj=self.context): + + return self.context.has_sip_package() + + return None + + def sip_store_available(self): return api.user.has_permission( 'opengever.disposition: Download SIP Package', obj=self.context) diff --git a/opengever/disposition/tests/test_ech0160export.py b/opengever/disposition/tests/test_ech0160export.py index 5ba99a76588..c915962a771 100644 --- a/opengever/disposition/tests/test_ech0160export.py +++ b/opengever/disposition/tests/test_ech0160export.py @@ -70,5 +70,5 @@ def test_streams_zip_when_sip_package_is_stored(self, browser): self.assertEquals( 'application/zip', browser.headers.get('content-type')) self.assertEquals( - 'inline; filename="SIP_20160611_PLONE_10xy.zip"', + "attachment; filename*=UTF-8''SIP_20160611_PLONE_10xy.zip", browser.headers.get('content-disposition')) diff --git a/opengever/disposition/tests/test_overview.py b/opengever/disposition/tests/test_overview.py index 90ab7e7a488..7a7b93b818d 100644 --- a/opengever/disposition/tests/test_overview.py +++ b/opengever/disposition/tests/test_overview.py @@ -152,11 +152,21 @@ def test_action_availability(self, browser): browser.css('ul.actions li').text) browser.find('disposition-transition-dispose').click() + + # SIP currently not generated + self.assertEquals(['Export appraisal list as excel'], + browser.css('ul.actions li').text) + + # Manually store the sip package + self.disposition.store_sip_package() + browser.open(self.disposition, view='overview') + self.assertEquals(['Export appraisal list as excel', 'Download disposition package'], browser.css('ul.actions li').text) + self.assertEquals( - os.path.join(self.disposition.absolute_url(), 'ech0160_export'), + os.path.join(self.disposition.absolute_url(), 'ech0160_download'), browser.find('Download disposition package').get('href')) self.assertEquals( os.path.join(self.disposition.absolute_url(), 'download_excel'), From 7fff73d2dffcd714a9527f62299e67f5030892de Mon Sep 17 00:00:00 2001 From: Philippe Gross Date: Fri, 10 May 2019 07:25:47 +0200 Subject: [PATCH 3/6] Genarate and store the SIP Package, when disposing a disposition. --- opengever/disposition/handlers.py | 3 +++ opengever/disposition/tests/test_disposition.py | 16 ++++++++++++++++ opengever/disposition/tests/test_overview.py | 8 -------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/opengever/disposition/handlers.py b/opengever/disposition/handlers.py index 96a9cfbc6c8..e360674eedf 100644 --- a/opengever/disposition/handlers.py +++ b/opengever/disposition/handlers.py @@ -21,6 +21,9 @@ def disposition_state_changed(context, event): context.mark_dossiers_as_archived() context.destroy_dossiers() + if event.action == 'disposition-transition-dispose': + context.store_sip_package() + storage = IHistoryStorage(context) storage.add(event.action, api.user.get_current().getId(), diff --git a/opengever/disposition/tests/test_disposition.py b/opengever/disposition/tests/test_disposition.py index 9516197c4a3..0cd1ebfaeae 100644 --- a/opengever/disposition/tests/test_disposition.py +++ b/opengever/disposition/tests/test_disposition.py @@ -224,3 +224,19 @@ def test_reset_date_of_submission_for_dropped_dossiers(self, browser): None, ILifeCycle(self.offered_dossier_to_destroy).date_of_submission) self.assertEquals( date.today(), ILifeCycle(self.expired_dossier).date_of_submission) + + @browsing + def test_sip_package_is_genarated_and_stored_on_dispose(self, browser): + self.login(self.records_manager, browser) + + self.set_workflow_state('disposition-state-appraised', self.disposition) + + browser.open(self.disposition, view='overview') + browser.click_on('disposition-transition-dispose') + + self.assertEquals(['Item state changed.'], info_messages()) + self.assertTrue(self.disposition.has_sip_package()) + + # Download is possible + self.assertIn( + 'Download disposition package', browser.css('ul.actions li').text) diff --git a/opengever/disposition/tests/test_overview.py b/opengever/disposition/tests/test_overview.py index 7a7b93b818d..86f8e662401 100644 --- a/opengever/disposition/tests/test_overview.py +++ b/opengever/disposition/tests/test_overview.py @@ -153,14 +153,6 @@ def test_action_availability(self, browser): browser.find('disposition-transition-dispose').click() - # SIP currently not generated - self.assertEquals(['Export appraisal list as excel'], - browser.css('ul.actions li').text) - - # Manually store the sip package - self.disposition.store_sip_package() - browser.open(self.disposition, view='overview') - self.assertEquals(['Export appraisal list as excel', 'Download disposition package'], browser.css('ul.actions li').text) From 4ca9c5f471623af0fb6c3d5aac589cc39a5657d5 Mon Sep 17 00:00:00 2001 From: Philippe Gross Date: Fri, 10 May 2019 08:12:12 +0200 Subject: [PATCH 4/6] Remove SIP package after closing an disposition. --- opengever/disposition/disposition.py | 3 +++ opengever/disposition/handlers.py | 2 ++ .../disposition/tests/test_disposition.py | 21 +++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/opengever/disposition/disposition.py b/opengever/disposition/disposition.py index c5650348962..1a9c9044d0f 100644 --- a/opengever/disposition/disposition.py +++ b/opengever/disposition/disposition.py @@ -306,6 +306,9 @@ def get_all_archivists(self): def store_sip_package(self): self._sip_package = self.generate_sip_package() + def remove_sip_package(self): + self._sip_package = None + def generate_sip_package(self): package = SIPPackage(self) zip_file = self.create_zipfile(package) diff --git a/opengever/disposition/handlers.py b/opengever/disposition/handlers.py index e360674eedf..a2a9223a54b 100644 --- a/opengever/disposition/handlers.py +++ b/opengever/disposition/handlers.py @@ -16,10 +16,12 @@ def disposition_state_changed(context, event): if event.action == 'disposition-transition-close': context.destroy_dossiers() + context.remove_sip_package() if event.action == 'disposition-transition-appraised-to-closed': context.mark_dossiers_as_archived() context.destroy_dossiers() + context.remove_sip_package() if event.action == 'disposition-transition-dispose': context.store_sip_package() diff --git a/opengever/disposition/tests/test_disposition.py b/opengever/disposition/tests/test_disposition.py index 0cd1ebfaeae..2bcd8dcbf6b 100644 --- a/opengever/disposition/tests/test_disposition.py +++ b/opengever/disposition/tests/test_disposition.py @@ -240,3 +240,24 @@ def test_sip_package_is_genarated_and_stored_on_dispose(self, browser): # Download is possible self.assertIn( 'Download disposition package', browser.css('ul.actions li').text) + + @browsing + def test_sip_package_is_removed_on_close(self, browser): + self.login(self.records_manager, browser) + + self.disposition.store_sip_package() + self.set_workflow_state('disposition-state-appraised', self.disposition) + browser.open(self.disposition, view='overview') + + browser.click_on('disposition-transition-dispose') + self.assertTrue(self.disposition.has_sip_package()) + + with self.login(self.archivist, browser=browser): + browser.open(self.disposition, view='overview') + browser.click_on('disposition-transition-archive') + + browser.open(self.disposition, view='overview') + browser.click_on('disposition-transition-close') + + self.assertEquals(['Item state changed.'], info_messages()) + self.assertFalse(self.disposition.has_sip_package()) From 4843692cecba9e82228249f086afed683b2e1dc2 Mon Sep 17 00:00:00 2001 From: Philippe Gross Date: Fri, 10 May 2019 08:27:31 +0200 Subject: [PATCH 5/6] Update translations. --- opengever/disposition/browser/ech0160.py | 2 +- .../de/LC_MESSAGES/opengever.disposition.po | 12 +++++++++++- .../fr/LC_MESSAGES/opengever.disposition.po | 19 ++++++++++++++----- .../locales/opengever.disposition.pot | 12 +++++++++++- .../disposition/tests/test_ech0160export.py | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/opengever/disposition/browser/ech0160.py b/opengever/disposition/browser/ech0160.py index 26c55a85788..d8733147d87 100644 --- a/opengever/disposition/browser/ech0160.py +++ b/opengever/disposition/browser/ech0160.py @@ -60,7 +60,7 @@ class ECH0160DownloadView(BrowserView): def __call__(self): if not self.context.has_sip_package(): msg = _('msg_no_sip_package_generated', - default=u'No SIP Package generated for this disposition') + default=u'No SIP Package generated for this disposition.') api.portal.show_message(msg, request=self.request, type='error') return self.request.RESPONSE.redirect(self.context.absolute_url()) diff --git a/opengever/disposition/locales/de/LC_MESSAGES/opengever.disposition.po b/opengever/disposition/locales/de/LC_MESSAGES/opengever.disposition.po index 8c21703108b..b672f01583a 100644 --- a/opengever/disposition/locales/de/LC_MESSAGES/opengever.disposition.po +++ b/opengever/disposition/locales/de/LC_MESSAGES/opengever.disposition.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2018-03-19 12:59+0000\n" +"POT-Creation-Date: 2019-07-25 14:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -273,6 +273,16 @@ msgstr "Angebot abgelehnt durch ${user}" msgid "msg_disposition_updated" msgstr "Aktualisiert durch ${user}" +#. Default: "No SIP Package generated for this disposition." +#: ./opengever/disposition/browser/ech0160.py +msgid "msg_no_sip_package_generated" +msgstr "Es wurde noch kein SIP Paket generiert für dieses Angebot." + +#. Default: "SIP Package generated successfully." +#: ./opengever/disposition/browser/ech0160.py +msgid "msg_sip_package_sucessfully_generated" +msgstr "SIP Paket erfolgreich generiert." + #. Default: "Period" #: ./opengever/disposition/browser/templates/overview.pt msgid "period" diff --git a/opengever/disposition/locales/fr/LC_MESSAGES/opengever.disposition.po b/opengever/disposition/locales/fr/LC_MESSAGES/opengever.disposition.po index 2536f78264d..edc76631f52 100644 --- a/opengever/disposition/locales/fr/LC_MESSAGES/opengever.disposition.po +++ b/opengever/disposition/locales/fr/LC_MESSAGES/opengever.disposition.po @@ -1,21 +1,20 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2018-03-19 12:59+0000\n" +"POT-Creation-Date: 2019-07-25 14:32+0000\n" "PO-Revision-Date: 2018-05-22 10:09+0000\n" "Last-Translator: Niklaus Johner \n" -"Language-Team: French \n" -"Language: fr\n" +"Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 2.13.1\n" "Language-Code: en\n" "Language-Name: English\n" "Preferred-Encodings: utf-8 latin1\n" "Domain: DOMAIN\n" +"Language: fr\n" +"X-Generator: Weblate 2.13.1\n" #: ./opengever/disposition/browser/excel_export.py msgid "The report could not been generated." @@ -276,6 +275,16 @@ msgstr "Offre refusée par ${user}" msgid "msg_disposition_updated" msgstr "Actualisé par ${user}" +#. Default: "No SIP Package generated for this disposition." +#: ./opengever/disposition/browser/ech0160.py +msgid "msg_no_sip_package_generated" +msgstr "" + +#. Default: "SIP Package generated successfully." +#: ./opengever/disposition/browser/ech0160.py +msgid "msg_sip_package_sucessfully_generated" +msgstr "" + #. Default: "Period" #: ./opengever/disposition/browser/templates/overview.pt msgid "period" diff --git a/opengever/disposition/locales/opengever.disposition.pot b/opengever/disposition/locales/opengever.disposition.pot index 4f3bd00248e..19d22a2c04f 100644 --- a/opengever/disposition/locales/opengever.disposition.pot +++ b/opengever/disposition/locales/opengever.disposition.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2018-03-19 12:59+0000\n" +"POT-Creation-Date: 2019-07-25 14:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -276,6 +276,16 @@ msgstr "" msgid "msg_disposition_updated" msgstr "" +#. Default: "No SIP Package generated for this disposition." +#: ./opengever/disposition/browser/ech0160.py +msgid "msg_no_sip_package_generated" +msgstr "" + +#. Default: "SIP Package generated successfully." +#: ./opengever/disposition/browser/ech0160.py +msgid "msg_sip_package_sucessfully_generated" +msgstr "" + #. Default: "Period" #: ./opengever/disposition/browser/templates/overview.pt msgid "period" diff --git a/opengever/disposition/tests/test_ech0160export.py b/opengever/disposition/tests/test_ech0160export.py index c915962a771..eb260bc2135 100644 --- a/opengever/disposition/tests/test_ech0160export.py +++ b/opengever/disposition/tests/test_ech0160export.py @@ -53,7 +53,7 @@ def test_shows_status_message_when_no_zip_is_stored(self, browser): self.set_workflow_state('disposition-state-disposed', self.disposition) browser.open(self.disposition, view='ech0160_download') - self.assertEquals([u'No SIP Package generated for this disposition'], + self.assertEquals([u'No SIP Package generated for this disposition.'], error_messages()) @browsing From 1da11eb78bc0fbceb3fdf0577a2b636d21766b35 Mon Sep 17 00:00:00 2001 From: Philippe Gross Date: Fri, 10 May 2019 08:30:52 +0200 Subject: [PATCH 6/6] Update changelog. --- docs/HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/HISTORY.txt b/docs/HISTORY.txt index ea18ab811b6..c6c1920abc4 100644 --- a/docs/HISTORY.txt +++ b/docs/HISTORY.txt @@ -5,6 +5,7 @@ Changelog --------------------- - Bump docxcompose version to 1.0.1 [njohner] +- Improve SIP package generation and download. [phgross] - Fix qa tests. [lgraf] - Disable properties action for teams. [deiferni] - Add source vocabularies for workspace invitations and todo responsibles. [njohner]