diff --git a/.gitignore b/.gitignore index a98b50f64..3952dd3fe 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ castle/cms/locales/en/LC_MESSAGES/plone.mo pip-selfcheck.json *.pyc .vscode/ -Gruntfile.js log.html node_modules/ report.html @@ -37,7 +36,5 @@ env env2 dump.rdb export/ -/Makefile -/package.json -/watch-run.py -/watchable-grunt.js +npm-debug.log +/Gruntfile.js diff --git a/CHANGES.md b/CHANGES.md index 880b934de..8803f5672 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,8 +4,13 @@ Changelog 3.0.0b127 (unreleased) ---------------------- -- Nothing changed yet. - +- Update control panel icons, providing one for every castle configlet +- Update dexterity types so every one has an icon and a short desription +- Add EmailTemplate dexterity type for repeated emails +- Fix data-tiles that don't exist from rendering and spamming output + (for dexterity type definitions in control panel in /@@dexterity-types/) +- Allow resuming importjson script +- fix missing/ inconsistently localed back to site setup button in controlpanels 3.0.0b126 (2023-08-01) ---------------------- diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..f8a327571 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +.PHONY: less-plone less-plone-logged-in compile-plone compile-plone-logged-in verify-gruntfile-exists +ERROR_MESSAGE = You must run ./bin/plone-compile-resources --site-id before these targets will work + +verify-gruntfile-exists: + test -f Gruntfile.js || ( echo "\n\n$(ERROR_MESSAGE)\n\n"; exit 1 ) + +less-plone: + make verify-gruntfile-exists && grunt less:plone + +less-plone-logged-in: + make verify-gruntfile-exists && grunt less:plone-logged-in + +compile-plone: + make verify-gruntfile-exists && grunt compile-plone + +compile-plone-logged-in: + make verify-gruntfile-exists && grunt compile-plone-logged-in diff --git a/README.rst b/README.rst index 756c30a93..4b8e45722 100644 --- a/README.rst +++ b/README.rst @@ -94,7 +94,12 @@ Development setup on macOS 7. ``bin/buildout`` 8. Run (in separate terminal windows) ``elasticsearch``, ``redis-server``, ``bin/instance fg`` 9. Browse to http://localhost:8080/ -10. Once you have created a site in the development instance, run init-dev script to populate templates, ``bin/instance run castle/cms/_scripts/init-dev.py`` + +Once you have created a site in the development instance: + +10. Run compile-resources script to allow `Makefile targets <./Makefile>`_ to work, ``bin/plone-compile-resources --site-id `` +11. Run init-dev script to populate templates, ``bin/instance run castle/cms/_scripts/init-dev.py`` +12. See the /docs/ folder for further development information Optional Dependencies diff --git a/castle/cms/_scripts/importjson.py b/castle/cms/_scripts/importjson.py index adb12b8a8..654669cb9 100644 --- a/castle/cms/_scripts/importjson.py +++ b/castle/cms/_scripts/importjson.py @@ -46,6 +46,9 @@ '--stop-if-exception', dest='stop_if_exception', default=False) parser.add_argument( '--pdb-if-exception', dest='pdb_if_exception', default=False) +parser.add_argument('--resumable', dest='resumable', default=False, action='store_true') +parser.add_argument( + '--delete-resumable-file', dest='delete_resumable_file', default=False, action='store_true') parser.add_argument('--skip-existing', dest='skip_existing', default=True) parser.add_argument( '--skip-transitioning', dest='skip_transitioning', default=False) @@ -73,6 +76,10 @@ stop_if_exception = args.stop_if_exception pdb_if_exception = args.pdb_if_exception retain_paths = args.retain_paths +resumable = args.resumable +delete_resumable_file = args.delete_resumable_file +successfully_imported_paths = [] +imported_but_not_committed = [] if args.import_paths: import_paths = args.import_paths.split(',') @@ -174,15 +181,23 @@ class CastleImporter(object): ('expiration_date', 'setExpirationDate'), ] + @property + def successfully_imported_paths(self): + return [ + args.export_directory + successfully_imported_path + for successfully_imported_path in successfully_imported_paths + ] + def do_import(self): self.import_folder(args.export_directory, container=site) def import_object(self, filepath, container=None): - fi = open(filepath) - file_read = fi.read() - fi.close() + if resumable and filepath in self.successfully_imported_paths: + print("Skipping {}; Already successfully imported and resuming is enabled".format(filepath)) + return try: - data = mjson.loads(file_read) + with open(filepath, 'r') as import_file: + data = mjson.loads(import_file.read()) except Exception: print("Skipping {}; Unable to read JSON data".format(filepath)) return @@ -275,10 +290,16 @@ def import_object(self, filepath, container=None): try: obj = api.content.create(safe_id=True, **creation_data) print('Created {path}'.format(path=path)) + imported_but_not_committed.append(path) self.imported_count += 1 if self.imported_count % 50 == 0: print('%i processed, committing' % self.imported_count) transaction.commit() + successfully_imported_paths.extend(imported_but_not_committed) + with open('./.successfullyimportedpaths', 'a') as fout: + fout.writelines('\n'.join(imported_but_not_committed) + '\n') + fout.flush() + del imported_but_not_committed[0:] except api.exc.InvalidParameterError: if stop_if_exception: logger.error('Error creating content {}'.format(filepath), exc_info=True) @@ -286,8 +307,7 @@ def import_object(self, filepath, container=None): import pdb pdb.set_trace() raise - logger.error('Error creating content {}' - .format(filepath), exc_info=True) + logger.error('Error creating content {}'.format(filepath), exc_info=True) return # TODO check default folder pages came over as folder with rich text tile # TODO any folder pages without default page should have content listing tile @@ -417,10 +437,20 @@ def create_plain_folder(self, id, container): if __name__ == '__main__': - print('------------------------------') print('Start importing') print('------------------------------') + if resumable: + print('------------------------------') + print('Resuming enabled, checking for ./.successfullyimportedpaths and loading') + # create if it doesn't exist: + with open('.successfullyimportedpaths', 'a+'): + pass + with open('.successfullyimportedpaths', 'r') as fin: + for line in fin.readlines(): + successfully_imported_paths.append(line.replace('\n', '')) + print('{} paths loaded'.format(len(successfully_imported_paths))) + print('------------------------------') if args.overwrite: print('------------------------------') print('Importing with overwrite enabled') @@ -429,3 +459,7 @@ def create_plain_folder(self, id, container): importer.do_import() print('Created {count} Content Items'.format(count=importer.imported_count)) transaction.commit() + print('Import completed') + if delete_resumable_file: + print('Deleting .successfullyimportedpaths') + os.remove('.successfullyimportedpaths') diff --git a/castle/cms/_scripts/templates/Makefile b/castle/cms/_scripts/templates/Makefile deleted file mode 100644 index d279408ee..000000000 --- a/castle/cms/_scripts/templates/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -less-plone: - grunt --gruntfile=watchable-grunt.js less-plone - -less-plone-logged-in: - grunt --gruntfile=watchable-grunt.js less-plone-logged-in - -js-plone: - grunt --gruntfile=watchable-grunt.js js-plone - -js-plone-logged-in: - grunt --gruntfile=watchable-grunt.js js-plone-logged-in - -js-plone-min: - grunt --gruntfile=watchable-grunt.js js-plone-build - -js-plone-logged-in-min: - grunt --gruntfile=watchable-grunt.js js-plone-logged-in-build - -watch-less-plone: - python watch-run.py --command="grunt --gruntfile=watchable-grunt.js less-plone" --dirs /opt/plone/src/castle.cms/castle/cms/static/less - -watch-less-plone-logged-in: - python watch-run.py --command="grunt --gruntfile=watchable-grunt.js less-plone-logged-in" --dirs /opt/plone/src/castle.cms/castle/cms/static/less diff --git a/castle/cms/_scripts/templates/package.json b/castle/cms/_scripts/templates/package.json deleted file mode 100644 index 3292c3eff..000000000 --- a/castle/cms/_scripts/templates/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "webpack-build", - "version": "1.0.0", - "description": "", - "private": true, - "devDependencies": { - "grunt": "~0.4.4", - "grunt-cli": "~0.1.13", - "grunt-contrib-copy": "~0.5.0", - "grunt-contrib-less": "latest", - "grunt-contrib-requirejs": "~0.4.3", - "grunt-contrib-watch": "latest", - "grunt-contrib-uglify": "~2", - "grunt-sed": "~0.1.1", - "less-plugin-inline-urls": "^1.1.0", - "copy-webpack-plugin": "^1.1.1", - "css-loader": "^0.23.1", - "exports-loader": "^0.6.3", - "expose-loader": "^0.7.1", - "extract-text-webpack-plugin": "^1.0.1", - "file-loader": "^0.8.5", - "html-webpack-plugin": "^2.8.1", - "imports-loader": "^0.6.5", - "less": "^2.6.0", - "less-loader": "^2.2.2", - "style-loader": "^0.13.0", - "text-loader": "0.0.1", - "url-loader": "^0.5.7", - "webpack": "^1.12.13", - "webpack-dev-server": "^1.14.1", - "webpack-merge": "^0.7.3", - "write-file-webpack-plugin": "^3.1.7", - "webpack-combine-loaders": "^2.0.3" - }, - "dependencies": { - "backbone": "^1.2.3", - "backbone.paginator": "^1.0.0", - "bootstrap": "^3.3.6", - "brace": "^0.8.0", - "dropzone": "^4.2.0", - "jqtree": "^1.3.0", - "jquery": "^2.2.0", - "jquery-form": "^3.50.0", - "jquery.browser": "^0.1.0", - "jquery.cookie": "^1.4.1", - "moment": "^2.11.2", - "pickadate": "^3.5.6", - "select2": "^3.5.1", - "underscore": "^1.8.3" - } -} diff --git a/castle/cms/browser/content/fc.py b/castle/cms/browser/content/fc.py index 31f276043..0800a2e23 100644 --- a/castle/cms/browser/content/fc.py +++ b/castle/cms/browser/content/fc.py @@ -247,7 +247,7 @@ def get_options(self): return { 'title': 'Recycle bin', 'id': 'recycle', - 'icon': 'trash', + 'icon': 'recycle', 'context': 'default', 'url': self.context.absolute_url() + '/@@fc-trash', 'form': { diff --git a/castle/cms/browser/controlpanel/documentviewer.py b/castle/cms/browser/controlpanel/documentviewer.py new file mode 100644 index 000000000..f772c0e35 --- /dev/null +++ b/castle/cms/browser/controlpanel/documentviewer.py @@ -0,0 +1,12 @@ +from collective.documentviewer.browser.controlpanel import GlobalSettingsForm +from plone.app.z3cform.layout import wrap_form +from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile + + +class CastleDocumentViewerSettingsForm(GlobalSettingsForm): + template = ViewPageTemplateFile('templates/documentviewer.pt') + label = None + description=None + + +GlobalSettingsFormView = wrap_form(CastleDocumentViewerSettingsForm) diff --git a/castle/cms/browser/controlpanel/templates/announcements.pt b/castle/cms/browser/controlpanel/templates/announcements.pt index 16defcc7d..62d4aba35 100644 --- a/castle/cms/browser/controlpanel/templates/announcements.pt +++ b/castle/cms/browser/controlpanel/templates/announcements.pt @@ -14,10 +14,8 @@ Site Setup diff --git a/castle/cms/browser/controlpanel/templates/archives-manage.pt b/castle/cms/browser/controlpanel/templates/archives-manage.pt index eb40ee0f7..a2887a0b7 100644 --- a/castle/cms/browser/controlpanel/templates/archives-manage.pt +++ b/castle/cms/browser/controlpanel/templates/archives-manage.pt @@ -11,12 +11,13 @@ - - Site Setup + + Site Setup +

Archive Management

diff --git a/castle/cms/browser/controlpanel/templates/archives-review.pt b/castle/cms/browser/controlpanel/templates/archives-review.pt index 680eba2e2..3d10c6aef 100644 --- a/castle/cms/browser/controlpanel/templates/archives-review.pt +++ b/castle/cms/browser/controlpanel/templates/archives-review.pt @@ -18,12 +18,13 @@ - - Site Setup + + Site Setup +

Archive Management

diff --git a/castle/cms/browser/controlpanel/templates/audit.pt b/castle/cms/browser/controlpanel/templates/audit.pt index 9981cc711..6ad9b4c00 100644 --- a/castle/cms/browser/controlpanel/templates/audit.pt +++ b/castle/cms/browser/controlpanel/templates/audit.pt @@ -12,15 +12,14 @@ tal:define="connected view/can_connect_to_index; site_path python: '/'.join(context.getPhysicalPath())"> - - Site Setup + + > + Site Setup -

View Title

diff --git a/castle/cms/browser/controlpanel/templates/celery.pt b/castle/cms/browser/controlpanel/templates/celery.pt index 4f17c442a..17842c7ec 100644 --- a/castle/cms/browser/controlpanel/templates/celery.pt +++ b/castle/cms/browser/controlpanel/templates/celery.pt @@ -11,12 +11,13 @@ - - Site Setup + + Site Setup +

Celery Tasks

diff --git a/castle/cms/browser/controlpanel/templates/crawler.pt b/castle/cms/browser/controlpanel/templates/crawler.pt index e1a560d8c..8332e38b6 100644 --- a/castle/cms/browser/controlpanel/templates/crawler.pt +++ b/castle/cms/browser/controlpanel/templates/crawler.pt @@ -10,14 +10,13 @@
- - Site Setup + + Site Setup -

View Title

diff --git a/castle/cms/browser/controlpanel/templates/documentviewer.pt b/castle/cms/browser/controlpanel/templates/documentviewer.pt new file mode 100644 index 000000000..efe2ae9e8 --- /dev/null +++ b/castle/cms/browser/controlpanel/templates/documentviewer.pt @@ -0,0 +1,28 @@ + + + +
+ Portal status message +
+ + + Site Setup + + +

Global Document Viewer Settings

+ + + + + + diff --git a/castle/cms/browser/controlpanel/templates/links.pt b/castle/cms/browser/controlpanel/templates/links.pt index ac321a66a..5df2c0cf7 100644 --- a/castle/cms/browser/controlpanel/templates/links.pt +++ b/castle/cms/browser/controlpanel/templates/links.pt @@ -47,14 +47,13 @@ - - Site Setup + + Site Setup -

View Title

diff --git a/castle/cms/browser/controlpanel/templates/sessions.pt b/castle/cms/browser/controlpanel/templates/sessions.pt index f501fd4cb..f6d7b8e80 100644 --- a/castle/cms/browser/controlpanel/templates/sessions.pt +++ b/castle/cms/browser/controlpanel/templates/sessions.pt @@ -10,14 +10,13 @@ - - Site Setup + + Site Setup -

View Title

diff --git a/castle/cms/browser/controlpanel/templates/social.pt b/castle/cms/browser/controlpanel/templates/social.pt index 8563f4ebe..71980d4d5 100644 --- a/castle/cms/browser/controlpanel/templates/social.pt +++ b/castle/cms/browser/controlpanel/templates/social.pt @@ -10,14 +10,13 @@
- + Site Setup -

View Title

diff --git a/castle/cms/browser/controlpanel/templates/status.pt b/castle/cms/browser/controlpanel/templates/status.pt index d1101af6b..5b765ada5 100644 --- a/castle/cms/browser/controlpanel/templates/status.pt +++ b/castle/cms/browser/controlpanel/templates/status.pt @@ -9,15 +9,13 @@ - + Site Setup - -

CastleCMS Status

Displays the status of components and subprocesses used by CastleCMS diff --git a/castle/cms/browser/controlpanel/templates/subscribers.pt b/castle/cms/browser/controlpanel/templates/subscribers.pt index ba2fa3569..c373b158a 100644 --- a/castle/cms/browser/controlpanel/templates/subscribers.pt +++ b/castle/cms/browser/controlpanel/templates/subscribers.pt @@ -9,12 +9,13 @@ - + Site Setup +

diff --git a/castle/cms/browser/controlpanel/templates/survey.pt b/castle/cms/browser/controlpanel/templates/survey.pt index c0ac45b99..76be2dc84 100644 --- a/castle/cms/browser/controlpanel/templates/survey.pt +++ b/castle/cms/browser/controlpanel/templates/survey.pt @@ -9,12 +9,12 @@
- - Site Setup - › + + Site Setup +

View Title

diff --git a/castle/cms/browser/controlpanel/templates/tags.pt b/castle/cms/browser/controlpanel/templates/tags.pt index cb0fa9a81..2e53b37db 100644 --- a/castle/cms/browser/controlpanel/templates/tags.pt +++ b/castle/cms/browser/controlpanel/templates/tags.pt @@ -9,14 +9,13 @@ - - Site Setup + + Site Setup -

View Title

diff --git a/castle/cms/browser/controlpanel/templates/usergroups_usersoverview.pt b/castle/cms/browser/controlpanel/templates/usergroups_usersoverview.pt index 9ed180fa1..a447b8618 100644 --- a/castle/cms/browser/controlpanel/templates/usergroups_usersoverview.pt +++ b/castle/cms/browser/controlpanel/templates/usergroups_usersoverview.pt @@ -20,11 +20,11 @@
- - Site Setup + + Site Setup

+ + Site Setup + +

Manage aliases

diff --git a/castle/cms/browser/templates/trash.pt b/castle/cms/browser/templates/trash.pt index 2fcfc3fd5..5f9cb6271 100644 --- a/castle/cms/browser/templates/trash.pt +++ b/castle/cms/browser/templates/trash.pt @@ -41,7 +41,7 @@

-
${view/get_trash_log}
+
${view/get_trash_log}
Info diff --git a/castle/cms/browser/templates/types-listing.pt b/castle/cms/browser/templates/types-listing.pt index 1604e3517..afd8b6cbd 100644 --- a/castle/cms/browser/templates/types-listing.pt +++ b/castle/cms/browser/templates/types-listing.pt @@ -15,10 +15,19 @@
+ + Site Setup + + +

Dexterity Content Types

+

-

+ tal:condition="view/description" + tal:content="structure view/description" + >

diff --git a/castle/cms/browser/types.py b/castle/cms/browser/types.py index 598efa356..034050015 100644 --- a/castle/cms/browser/types.py +++ b/castle/cms/browser/types.py @@ -21,5 +21,6 @@ class TypesListing(types.TypesListing): # Create a form wrapper so the form gets layout. TypesListingPage = layout.wrap_form( - TypesListing, __wrapper_class=types.TypesEditFormWrapper, - label=_(u'Dexterity Content Types')) + TypesListing, + __wrapper_class=types.TypesEditFormWrapper, +) diff --git a/castle/cms/constants.py b/castle/cms/constants.py index 6734960cd..6cba1314a 100644 --- a/castle/cms/constants.py +++ b/castle/cms/constants.py @@ -24,8 +24,10 @@ 'pt', 'px', ) -VALID_CSS_FONT_SIZE_PATTERN = compile("^\s*\d+\s*({})\s*$".format( # noqa:W605 - '|'.join(ABSOLUTE_FONT_UNITS) -)) +VALID_CSS_FONT_SIZE_PATTERN = compile( + r"^\s*\d+\s*({})\s*$".format( + '|'.join(ABSOLUTE_FONT_UNITS) + ) +) CLOUDFARE_PURGE_BATCH_SIZE_LIMIT = 30 HYPERTEXT_PROTOCOL_PATTERN = r'^https?:\/\/' diff --git a/castle/cms/fragments/templates/mobilenav.pt b/castle/cms/fragments/templates/mobilenav.pt index 0648b2969..7d46d0dba 100644 --- a/castle/cms/fragments/templates/mobilenav.pt +++ b/castle/cms/fragments/templates/mobilenav.pt @@ -23,7 +23,7 @@ - +