From ab2e23539673973b9c671fd1c2de405f8e8945f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Wed, 22 Nov 2023 16:08:12 +0100 Subject: [PATCH 01/16] Add dependency to collective.person --- setup.py | 1 + src/kitconcept/intranet/dependencies.zcml | 1 + 2 files changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 5470e69..f9a8ff9 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,7 @@ "pytest", "pytest-cov", "pytest-plone>=0.2.0", + "collective.person", ], }, entry_points=""" diff --git a/src/kitconcept/intranet/dependencies.zcml b/src/kitconcept/intranet/dependencies.zcml index 6b7699b..1dc6a12 100644 --- a/src/kitconcept/intranet/dependencies.zcml +++ b/src/kitconcept/intranet/dependencies.zcml @@ -5,5 +5,6 @@ + From 6738c326dca5c70fc20de415136c569fbc12cb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Fri, 15 Mar 2024 11:07:56 +0100 Subject: [PATCH 02/16] Add profile for a person type and additional fields - Also include a profile to configure collective.solr --- src/kitconcept/intranet/behaviors/__init__.py | 0 .../behaviors/additional_contact_info.py | 34 +++++++++ .../intranet/behaviors/configure.zcml | 6 ++ src/kitconcept/intranet/profiles.zcml | 34 +++++++++ .../intranet/profiles/default/actions.xml | 45 ++++++++++++ .../profiles/default/browserlayer.xml | 6 ++ .../intranet/profiles/default/catalog.xml | 20 ++++++ .../intranet/profiles/default/metadata.xml | 9 +++ ...olr.interfaces.IKitconceptSolrSettings.xml | 70 +++++++++++++++++++ ...se.interfaces.controlpanel.IMailSchema.xml | 9 +++ ...se.interfaces.controlpanel.ISiteSchema.xml | 9 +++ .../plone.i18n.interfaces.ILanguageSchema.xml | 12 ++++ .../intranet/profiles/default/theme.xml | 5 ++ .../intranet/profiles/default/types.xml | 10 +++ .../profiles/default/types/Person.xml | 12 ++++ .../intranet/profiles/initial/metadata.xml | 4 ++ .../profiles/uninstall/browserlayer.xml | 6 ++ 17 files changed, 291 insertions(+) create mode 100644 src/kitconcept/intranet/behaviors/__init__.py create mode 100644 src/kitconcept/intranet/behaviors/additional_contact_info.py create mode 100644 src/kitconcept/intranet/behaviors/configure.zcml create mode 100644 src/kitconcept/intranet/profiles.zcml create mode 100644 src/kitconcept/intranet/profiles/default/actions.xml create mode 100644 src/kitconcept/intranet/profiles/default/browserlayer.xml create mode 100644 src/kitconcept/intranet/profiles/default/catalog.xml create mode 100644 src/kitconcept/intranet/profiles/default/metadata.xml create mode 100644 src/kitconcept/intranet/profiles/default/registry/kitconcept.solr.interfaces.IKitconceptSolrSettings.xml create mode 100644 src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.IMailSchema.xml create mode 100644 src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.ISiteSchema.xml create mode 100644 src/kitconcept/intranet/profiles/default/registry/plone.i18n.interfaces.ILanguageSchema.xml create mode 100644 src/kitconcept/intranet/profiles/default/theme.xml create mode 100644 src/kitconcept/intranet/profiles/default/types.xml create mode 100644 src/kitconcept/intranet/profiles/default/types/Person.xml create mode 100644 src/kitconcept/intranet/profiles/initial/metadata.xml create mode 100644 src/kitconcept/intranet/profiles/uninstall/browserlayer.xml diff --git a/src/kitconcept/intranet/behaviors/__init__.py b/src/kitconcept/intranet/behaviors/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/behaviors/additional_contact_info.py b/src/kitconcept/intranet/behaviors/additional_contact_info.py new file mode 100644 index 0000000..0aa8e0c --- /dev/null +++ b/src/kitconcept/intranet/behaviors/additional_contact_info.py @@ -0,0 +1,34 @@ +from collective.contact_behaviors import _ +from plone.autoform.directives import read_permission +from plone.autoform.interfaces import IFormFieldProvider +from plone.schema.email import Email +from plone.supermodel import directives +from plone.supermodel import model +from zope import schema +from zope.interface import provider + + +PERMISSION = "kitconcept.intranet.behaviors.additional_contact_info.view" + + +@provider(IFormFieldProvider) +class IAdditionalContactInfo(model.Schema): + directives.fieldset( + "additional_contact_info", + label=_( + "label_additional_contact_info", + default="Additional Contact Information", + ), + fields=("contact_building", "contact_room"), + ) + + read_permission(contact_building=PERMISSION, contact_room=PERMISSION) + + contact_building = schema.TextLine( + title=_("label_contact_building", default="Building"), + required=False, + ) + + contact_room = schema.TextLine( + title=_("label_contact_room", default="Room"), required=False + ) diff --git a/src/kitconcept/intranet/behaviors/configure.zcml b/src/kitconcept/intranet/behaviors/configure.zcml new file mode 100644 index 0000000..e6626aa --- /dev/null +++ b/src/kitconcept/intranet/behaviors/configure.zcml @@ -0,0 +1,6 @@ + + + diff --git a/src/kitconcept/intranet/profiles.zcml b/src/kitconcept/intranet/profiles.zcml new file mode 100644 index 0000000..733c0d7 --- /dev/null +++ b/src/kitconcept/intranet/profiles.zcml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/src/kitconcept/intranet/profiles/default/actions.xml b/src/kitconcept/intranet/profiles/default/actions.xml new file mode 100644 index 0000000..44a0283 --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/actions.xml @@ -0,0 +1,45 @@ + + + + + + False + + + + + True + + + False + + + False + + + False + + + diff --git a/src/kitconcept/intranet/profiles/default/browserlayer.xml b/src/kitconcept/intranet/profiles/default/browserlayer.xml new file mode 100644 index 0000000..93a2269 --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/browserlayer.xml @@ -0,0 +1,6 @@ + + + + diff --git a/src/kitconcept/intranet/profiles/default/catalog.xml b/src/kitconcept/intranet/profiles/default/catalog.xml new file mode 100644 index 0000000..071c8ac --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/catalog.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/src/kitconcept/intranet/profiles/default/metadata.xml b/src/kitconcept/intranet/profiles/default/metadata.xml new file mode 100644 index 0000000..45ab0de --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/metadata.xml @@ -0,0 +1,9 @@ + + + 20231122001 + + profile-plone.volto:default + kitconcept.solr:default + collective.person:default + + diff --git a/src/kitconcept/intranet/profiles/default/registry/kitconcept.solr.interfaces.IKitconceptSolrSettings.xml b/src/kitconcept/intranet/profiles/default/registry/kitconcept.solr.interfaces.IKitconceptSolrSettings.xml new file mode 100644 index 0000000..cf6c565 --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/registry/kitconcept.solr.interfaces.IKitconceptSolrSettings.xml @@ -0,0 +1,70 @@ + + + + + { + "fieldList": [ + "UID", + "Title", + "Description", + "Type", + "effective", + "start", + "created", + "end", + "path_string", + "mime_type", + "location", + "contact_email", + "contact_phone", + "contact_building", + "contact_room", + "image_scales", + "image_field" + ], + "searchTabs": [ + { + "label": "All", + "filter": "Type(*)" + }, + { + "label": "Pages", + "filter": "Type:(Page)" + }, + { + "label": "Events", + "filter": "Type:(Event)" + }, + { + "label": "Images", + "filter": "Type:(Image)" + }, + { + "label": "Files", + "filter": "Type:(File)" + }, + { + "label": "Persons", + "filter": "Type:(Person)", + "layouts": ["list", "grid"], + "facetFields": [ + { + "name": "contact_building", + "label": "Building", + }, + { + "name":"contact_room", + "label": "Room" + } + ] + } + ] + } + + diff --git a/src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.IMailSchema.xml b/src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.IMailSchema.xml new file mode 100644 index 0000000..69001b3 --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.IMailSchema.xml @@ -0,0 +1,9 @@ + + + + kitconcept.intranet.demo + + diff --git a/src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.ISiteSchema.xml b/src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.ISiteSchema.xml new file mode 100644 index 0000000..d8345f1 --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/registry/plone.base.interfaces.controlpanel.ISiteSchema.xml @@ -0,0 +1,9 @@ + + + + kitconcept.intranet.demo + + diff --git a/src/kitconcept/intranet/profiles/default/registry/plone.i18n.interfaces.ILanguageSchema.xml b/src/kitconcept/intranet/profiles/default/registry/plone.i18n.interfaces.ILanguageSchema.xml new file mode 100644 index 0000000..cd2730f --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/registry/plone.i18n.interfaces.ILanguageSchema.xml @@ -0,0 +1,12 @@ + + + + + en + + en + + diff --git a/src/kitconcept/intranet/profiles/default/theme.xml b/src/kitconcept/intranet/profiles/default/theme.xml new file mode 100644 index 0000000..7f916aa --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/theme.xml @@ -0,0 +1,5 @@ + + + barceloneta + true + diff --git a/src/kitconcept/intranet/profiles/default/types.xml b/src/kitconcept/intranet/profiles/default/types.xml new file mode 100644 index 0000000..bed2b0d --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/types.xml @@ -0,0 +1,10 @@ + + + + diff --git a/src/kitconcept/intranet/profiles/default/types/Person.xml b/src/kitconcept/intranet/profiles/default/types/Person.xml new file mode 100644 index 0000000..4842d1f --- /dev/null +++ b/src/kitconcept/intranet/profiles/default/types/Person.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/src/kitconcept/intranet/profiles/initial/metadata.xml b/src/kitconcept/intranet/profiles/initial/metadata.xml new file mode 100644 index 0000000..a0ae0e7 --- /dev/null +++ b/src/kitconcept/intranet/profiles/initial/metadata.xml @@ -0,0 +1,4 @@ + + + 20231122001 + diff --git a/src/kitconcept/intranet/profiles/uninstall/browserlayer.xml b/src/kitconcept/intranet/profiles/uninstall/browserlayer.xml new file mode 100644 index 0000000..ee5fc55 --- /dev/null +++ b/src/kitconcept/intranet/profiles/uninstall/browserlayer.xml @@ -0,0 +1,6 @@ + + + + From f17c8f60ef9ee65b3cab805c58f5e6f48b958644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Fri, 15 Mar 2024 11:16:23 +0100 Subject: [PATCH 03/16] Update configuration --- src/kitconcept/intranet/configure.zcml | 15 +++++++++++++++ src/kitconcept/intranet/dependencies.zcml | 4 +--- src/kitconcept/intranet/permissions.zcml | 12 ++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/kitconcept/intranet/permissions.zcml diff --git a/src/kitconcept/intranet/configure.zcml b/src/kitconcept/intranet/configure.zcml index 8692da1..58364c9 100644 --- a/src/kitconcept/intranet/configure.zcml +++ b/src/kitconcept/intranet/configure.zcml @@ -10,8 +10,23 @@ package="Products.CMFCore" file="permissions.zcml" /> + + + + + + + + + + + + diff --git a/src/kitconcept/intranet/dependencies.zcml b/src/kitconcept/intranet/dependencies.zcml index 1dc6a12..6b1256d 100644 --- a/src/kitconcept/intranet/dependencies.zcml +++ b/src/kitconcept/intranet/dependencies.zcml @@ -3,8 +3,6 @@ - - - + diff --git a/src/kitconcept/intranet/permissions.zcml b/src/kitconcept/intranet/permissions.zcml new file mode 100644 index 0000000..4852e8c --- /dev/null +++ b/src/kitconcept/intranet/permissions.zcml @@ -0,0 +1,12 @@ + + + + + + + + From 91b18b02b16fd3300533a768ce649bda627ff4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Fri, 15 Mar 2024 11:22:23 +0100 Subject: [PATCH 04/16] Add setup handlers (as of cookiecutter) --- .../intranet/setuphandlers/__init__.py | 34 ++++++ .../intranet/setuphandlers/content.py | 107 ++++++++++++++++++ .../intranet/setuphandlers/contents.json | 26 +++++ .../intranet/setuphandlers/home.json | 72 ++++++++++++ .../setuphandlers/images/plone-foundation.png | Bin 0 -> 50737 bytes .../intranet/setuphandlers/users.json | 19 ++++ .../intranet/setuphandlers/users.py | 47 ++++++++ 7 files changed, 305 insertions(+) create mode 100644 src/kitconcept/intranet/setuphandlers/__init__.py create mode 100644 src/kitconcept/intranet/setuphandlers/content.py create mode 100644 src/kitconcept/intranet/setuphandlers/contents.json create mode 100644 src/kitconcept/intranet/setuphandlers/home.json create mode 100644 src/kitconcept/intranet/setuphandlers/images/plone-foundation.png create mode 100644 src/kitconcept/intranet/setuphandlers/users.json create mode 100644 src/kitconcept/intranet/setuphandlers/users.py diff --git a/src/kitconcept/intranet/setuphandlers/__init__.py b/src/kitconcept/intranet/setuphandlers/__init__.py new file mode 100644 index 0000000..2a8e8f0 --- /dev/null +++ b/src/kitconcept/intranet/setuphandlers/__init__.py @@ -0,0 +1,34 @@ +from kitconcept_intranet_demo import logger +from kitconcept_intranet_demo.setuphandlers import content +from kitconcept_intranet_demo.setuphandlers import users +from plone import api +from Products.CMFPlone.interfaces import INonInstallable +from zope.interface import implementer + + +@implementer(INonInstallable) +class HiddenProfiles(object): + def getNonInstallableProfiles(self): + """Hide uninstall profile from site-creation and quickinstaller.""" + return [ + "kitconcept_intranet_demo:uninstall", + ] + + +def populate_portal(context): + """Post install script""" + portal = api.portal.get() + # Delete content + content.delete_content(portal) + logger.info("Deleted default portal content") + user = users.create_default_user() + creators = [user.id] + logger.info("Created default user") + # Create other users + users.create_team_accounts() + logger.info("Created team accounts") + # Create Initial content + content.populate_portal(portal, creators) + logger.info("Created initial content") + # Update cover content + content.update_home(portal, creators) diff --git a/src/kitconcept/intranet/setuphandlers/content.py b/src/kitconcept/intranet/setuphandlers/content.py new file mode 100644 index 0000000..4a39337 --- /dev/null +++ b/src/kitconcept/intranet/setuphandlers/content.py @@ -0,0 +1,107 @@ +from DateTime import DateTime +from dateutil.parser import parse +from plone import api +from plone.app.dexterity.behaviors import constrains +from plone.namedfile.file import NamedBlobImage +from Products.CMFPlone.interfaces.constrains import ISelectableConstrainTypes + +import json +import os + + +TO_DELETE = ("front-page", "news", "events", "Members") + +__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + + +def delete_content(portal): + """Delete default content.""" + o_ids = [o_id for o_id in TO_DELETE if o_id in portal.objectIds()] + for o_id in o_ids: + api.content.delete(obj=portal[o_id]) + + +def _get_image(image: str) -> NamedBlobImage: + filepath = os.path.join(__location__, f"{image}") + with open(filepath, "rb") as f_in: + data = f_in.read() + return NamedBlobImage(data) + + +def date_from_string(value: str) -> DateTime: + return DateTime(parse(value)) + + +def _create_content(portal, item: dict, creators: list): + """Create a content.""" + container = portal.restrictedTraverse(item.get("_parent")) + o_id = item["id"] + + if o_id in container.objectIds(): + return container[o_id] + + item["creators"] = creators + permissions = item.get("_permissions", {}) + allowed_types = item.get("_allowed_types", []) + transitions = item.get("_transitions", []) + attributes = item.get("_attributes", {}) + payload = {k: v for k, v in item.items() if not k.startswith("_")} + payload["container"] = container + image_path = item.get("_image", None) + if image_path: + payload["image"] = _get_image(image_path) + date_keys = [k for k in payload.keys() if k.endswith("_date")] + for key in date_keys: + payload[key] = date_from_string(payload[key]) + + modified = payload.get("modification_date", None) + content = api.content.create(**payload) + # Apply attributes + if attributes: + for key, value in attributes.items(): + setattr(content, key, value) + for transition in transitions: + api.content.transition(obj=content, transition=transition) + # Set permissions + for permission_id, roles in permissions.items(): + content.manage_permission(permission_id, roles=roles) + if allowed_types: + behavior = ISelectableConstrainTypes(content) + behavior.setConstrainTypesMode(constrains.ENABLED) + behavior.setImmediatelyAddableTypes(allowed_types) + if modified: + content.modification_date = modified + content.reindexObject(idxs=["modified"]) + return content + + +def populate_portal(portal, creators): + """Create content structure.""" + with open(os.path.join(__location__, "contents.json"), "r") as f_in: + contents = json.load(f_in) + + # Contents are created by Editors + with api.env.adopt_roles(["Editor", "Manager"]): + for item in contents: + _create_content(portal, item, creators) + + # Update workflow security + wf_tool = api.portal.get_tool("portal_workflow") + wf_tool.updateRoleMappings() + + +def _update_home(portal, item: dict): + """Update front page.""" + for key, value in item.items(): + setattr(portal, key, value) + return portal + + +def update_home(portal, creators): + """Create content structure.""" + with open(os.path.join(__location__, "home.json"), "r") as f_in: + content = json.load(f_in) + + # Contents are created by Editors + with api.env.adopt_roles(["Editor", "Manager"]): + _update_home(portal, content) diff --git a/src/kitconcept/intranet/setuphandlers/contents.json b/src/kitconcept/intranet/setuphandlers/contents.json new file mode 100644 index 0000000..4aa958b --- /dev/null +++ b/src/kitconcept/intranet/setuphandlers/contents.json @@ -0,0 +1,26 @@ +[ + { + "_parent": "", + "type": "Document", + "id": "images", + "title": "Images", + "description": "Image bank.", + "_transitions": [ + "publish" + ], + "_allowed_types": [ + "Image" + ], + "exclude_from_nav": true + }, + { + "_parent": "images", + "type": "Image", + "id": "plone-foundation.png", + "title": "Plone Foundation", + "description": "", + "_image": "images/plone-foundation.png", + "_transitions": [], + "exclude_from_nav": false + } +] diff --git a/src/kitconcept/intranet/setuphandlers/home.json b/src/kitconcept/intranet/setuphandlers/home.json new file mode 100644 index 0000000..613cc1a --- /dev/null +++ b/src/kitconcept/intranet/setuphandlers/home.json @@ -0,0 +1,72 @@ +{ + "blocks": { + "94b9fb26-041d-438c-981a-671a89854cbe": { + "@type": "slate", + "plaintext": "Welcome to kitconcept.intranet", + "value": [ + { + "children": [ + { + "text": "" + }, + { + "children": [ + { + "text": "Welcome to kitconcept.intranet" + } + ], + "type": "b" + } + ], + "type": "p" + } + ] + }, + "1006adfe-d9b1-4e70-9b32-a9158310723d": { + "@type": "slate", + "plaintext": "Plone is an enterprise CMS built with Python.", + "value": [ + { + "children": [ + { + "text": "" + }, + { + "children": [ + { + "text": "Plone" + } + ], + "type": "b" + }, + { + "text": " is an enterprise CMS built with " + }, + { + "children": [ + { + "text": "Python" + } + ], + "data": { + "url": "https://python.org" + }, + "type": "link" + }, + { + "text": "." + } + ], + "type": "p" + } + ] + } + }, + "blocks_layout": { + "items": [ + "94b9fb26-041d-438c-981a-671a89854cbe", + "1006adfe-d9b1-4e70-9b32-a9158310723d" + ] + }, + "title": "kitconcept.intranet.demo" +} diff --git a/src/kitconcept/intranet/setuphandlers/images/plone-foundation.png b/src/kitconcept/intranet/setuphandlers/images/plone-foundation.png new file mode 100644 index 0000000000000000000000000000000000000000..9516c4c6392f24444bec95824f40fcf6bf3a0631 GIT binary patch literal 50737 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 z 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 dict: + """Return users info.""" + with open(os.path.join(__location__, "users.json"), "r") as f_in: + users = json.load(f_in) + return users + + +def create_default_user(): + """Create a default user to organize content.""" + all_users = _users_info() + user_info = all_users["portal"][0] + groups = user_info.pop("groups") + user = api.user.create(**user_info) + for group_name in groups: + api.group.add_user(groupname=group_name, user=user) + return user + + +def create_accounts(accounts: list) -> list: + """Create user accounts.""" + new_users = [] + for user_info in accounts: + username = user_info.get("username", "") + if api.user.get(username=username): + # User already exists, skip it + continue + groups = user_info.pop("groups") + user = api.user.create(**user_info) + for group_name in groups: + api.group.add_user(groupname=group_name, user=user) + new_users.append(user) + return new_users + + +def create_team_accounts(): + """Create team accounts.""" + all_users = _users_info() + return create_accounts(all_users["team"]) From e8898065489e7021d1b5d4b095f064fab4e9fea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Fri, 15 Mar 2024 11:24:28 +0100 Subject: [PATCH 05/16] Add upgrades --- src/kitconcept/intranet/upgrades/__init__.py | 0 .../intranet/upgrades/configure.zcml | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/kitconcept/intranet/upgrades/__init__.py create mode 100644 src/kitconcept/intranet/upgrades/configure.zcml diff --git a/src/kitconcept/intranet/upgrades/__init__.py b/src/kitconcept/intranet/upgrades/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/upgrades/configure.zcml b/src/kitconcept/intranet/upgrades/configure.zcml new file mode 100644 index 0000000..2e301c7 --- /dev/null +++ b/src/kitconcept/intranet/upgrades/configure.zcml @@ -0,0 +1,19 @@ + + + + + From f64b6b8e480f8c8666add23b9cff61b5e3a9f223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Fri, 15 Mar 2024 11:30:01 +0100 Subject: [PATCH 06/16] Add the rest of the scaffold (as of cookiecutter) Why, oh, why?? --- src/kitconcept/intranet/browser/__init__.py | 0 src/kitconcept/intranet/browser/configure.zcml | 15 +++++++++++++++ src/kitconcept/intranet/browser/static/.gitkeep | 0 src/kitconcept/intranet/indexers/__init__.py | 0 src/kitconcept/intranet/indexers/configure.zcml | 10 ++++++++++ src/kitconcept/intranet/serializers/__init__.py | 0 .../intranet/serializers/configure.zcml | 3 +++ src/kitconcept/intranet/services/__init__.py | 0 src/kitconcept/intranet/services/configure.zcml | 3 +++ src/kitconcept/intranet/subscribers/__init__.py | 0 .../intranet/subscribers/configure.zcml | 3 +++ src/kitconcept/intranet/vocabularies/__init__.py | 0 .../intranet/vocabularies/configure.zcml | 10 ++++++++++ 13 files changed, 44 insertions(+) create mode 100644 src/kitconcept/intranet/browser/__init__.py create mode 100644 src/kitconcept/intranet/browser/configure.zcml create mode 100644 src/kitconcept/intranet/browser/static/.gitkeep create mode 100644 src/kitconcept/intranet/indexers/__init__.py create mode 100644 src/kitconcept/intranet/indexers/configure.zcml create mode 100644 src/kitconcept/intranet/serializers/__init__.py create mode 100644 src/kitconcept/intranet/serializers/configure.zcml create mode 100644 src/kitconcept/intranet/services/__init__.py create mode 100644 src/kitconcept/intranet/services/configure.zcml create mode 100644 src/kitconcept/intranet/subscribers/__init__.py create mode 100644 src/kitconcept/intranet/subscribers/configure.zcml create mode 100644 src/kitconcept/intranet/vocabularies/__init__.py create mode 100644 src/kitconcept/intranet/vocabularies/configure.zcml diff --git a/src/kitconcept/intranet/browser/__init__.py b/src/kitconcept/intranet/browser/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/browser/configure.zcml b/src/kitconcept/intranet/browser/configure.zcml new file mode 100644 index 0000000..5d8ff52 --- /dev/null +++ b/src/kitconcept/intranet/browser/configure.zcml @@ -0,0 +1,15 @@ + + + + + + diff --git a/src/kitconcept/intranet/browser/static/.gitkeep b/src/kitconcept/intranet/browser/static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/indexers/__init__.py b/src/kitconcept/intranet/indexers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/indexers/configure.zcml b/src/kitconcept/intranet/indexers/configure.zcml new file mode 100644 index 0000000..94ea6a1 --- /dev/null +++ b/src/kitconcept/intranet/indexers/configure.zcml @@ -0,0 +1,10 @@ + + + + + diff --git a/src/kitconcept/intranet/serializers/__init__.py b/src/kitconcept/intranet/serializers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/serializers/configure.zcml b/src/kitconcept/intranet/serializers/configure.zcml new file mode 100644 index 0000000..fb8b793 --- /dev/null +++ b/src/kitconcept/intranet/serializers/configure.zcml @@ -0,0 +1,3 @@ + + + diff --git a/src/kitconcept/intranet/services/__init__.py b/src/kitconcept/intranet/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/services/configure.zcml b/src/kitconcept/intranet/services/configure.zcml new file mode 100644 index 0000000..fb8b793 --- /dev/null +++ b/src/kitconcept/intranet/services/configure.zcml @@ -0,0 +1,3 @@ + + + diff --git a/src/kitconcept/intranet/subscribers/__init__.py b/src/kitconcept/intranet/subscribers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/subscribers/configure.zcml b/src/kitconcept/intranet/subscribers/configure.zcml new file mode 100644 index 0000000..fb8b793 --- /dev/null +++ b/src/kitconcept/intranet/subscribers/configure.zcml @@ -0,0 +1,3 @@ + + + diff --git a/src/kitconcept/intranet/vocabularies/__init__.py b/src/kitconcept/intranet/vocabularies/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/kitconcept/intranet/vocabularies/configure.zcml b/src/kitconcept/intranet/vocabularies/configure.zcml new file mode 100644 index 0000000..eccbc33 --- /dev/null +++ b/src/kitconcept/intranet/vocabularies/configure.zcml @@ -0,0 +1,10 @@ + + + + + From 7b4ab13d90acab70a2efcb91ca53937b659d8bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Fri, 15 Mar 2024 11:33:34 +0100 Subject: [PATCH 07/16] Update solr configuration --- Makefile | 5 +++++ solr/Dockerfile | 11 +++++++++++ 2 files changed, 16 insertions(+) create mode 100644 solr/Dockerfile diff --git a/Makefile b/Makefile index e307c71..8d8a39e 100644 --- a/Makefile +++ b/Makefile @@ -153,6 +153,11 @@ solr-start: ## Start solr @echo "Start solr" @COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME} docker compose -f ${SOLR_ONLY_COMPOSE} up -d +.PHONY: solr-start-and-rebuild +solr-start-and-rebuild: ## Start solr, force rebuild + @echo "Start solr, force rebuild, erases data" + @COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME} docker compose -f ${SOLR_ONLY_COMPOSE} up -d --build + .PHONY: solr-start-fg solr-start-fg: ## Start solr in foreground @echo "Start solr in foreground" diff --git a/solr/Dockerfile b/solr/Dockerfile new file mode 100644 index 0000000..1b8257f --- /dev/null +++ b/solr/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 +FROM solr:8 + +LABEL maintainer="kitconcept, GmbH " \ + org.label-schema.name="ghcr.io/kitconcept/solr" \ + org.label-schema.description="Solr 8 image with Plone default settings" \ + org.label-schema.vendor="kitconcept, GmbH" + +# Copy default plone configuration for this image +COPY etc /plone-config +COPY bin/solr-update-core /opt/docker-solr/scripts From 4669b530b11ac0ac4722af6c0f84833ef1cf7dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Mon, 25 Mar 2024 13:43:39 +0100 Subject: [PATCH 08/16] Add back plone.distribution, removed accidentally --- src/kitconcept/intranet/dependencies.zcml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kitconcept/intranet/dependencies.zcml b/src/kitconcept/intranet/dependencies.zcml index 6b1256d..1333a8d 100644 --- a/src/kitconcept/intranet/dependencies.zcml +++ b/src/kitconcept/intranet/dependencies.zcml @@ -3,6 +3,7 @@ + From 5bec1d17d7542cb5128b2f2f336ef57e3f6a2af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Mon, 25 Mar 2024 14:20:40 +0100 Subject: [PATCH 09/16] Additional person info behaviour wiring --- src/kitconcept/intranet/behaviors/configure.zcml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/kitconcept/intranet/behaviors/configure.zcml b/src/kitconcept/intranet/behaviors/configure.zcml index e6626aa..6a8e53c 100644 --- a/src/kitconcept/intranet/behaviors/configure.zcml +++ b/src/kitconcept/intranet/behaviors/configure.zcml @@ -1,6 +1,22 @@ + + + + + From c9282a3245fad417d126afe22caeb9a46b252dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Mon, 25 Mar 2024 13:55:02 +0100 Subject: [PATCH 10/16] Clean up unnused scaffold --- src/kitconcept/intranet/browser/__init__.py | 0 src/kitconcept/intranet/browser/configure.zcml | 15 --------------- src/kitconcept/intranet/browser/static/.gitkeep | 0 src/kitconcept/intranet/configure.zcml | 6 ------ src/kitconcept/intranet/indexers/__init__.py | 0 src/kitconcept/intranet/indexers/configure.zcml | 10 ---------- src/kitconcept/intranet/serializers/__init__.py | 0 .../intranet/serializers/configure.zcml | 3 --- src/kitconcept/intranet/services/__init__.py | 0 src/kitconcept/intranet/services/configure.zcml | 3 --- src/kitconcept/intranet/subscribers/__init__.py | 0 .../intranet/subscribers/configure.zcml | 3 --- src/kitconcept/intranet/vocabularies/__init__.py | 0 .../intranet/vocabularies/configure.zcml | 10 ---------- 14 files changed, 50 deletions(-) delete mode 100644 src/kitconcept/intranet/browser/__init__.py delete mode 100644 src/kitconcept/intranet/browser/configure.zcml delete mode 100644 src/kitconcept/intranet/browser/static/.gitkeep delete mode 100644 src/kitconcept/intranet/indexers/__init__.py delete mode 100644 src/kitconcept/intranet/indexers/configure.zcml delete mode 100644 src/kitconcept/intranet/serializers/__init__.py delete mode 100644 src/kitconcept/intranet/serializers/configure.zcml delete mode 100644 src/kitconcept/intranet/services/__init__.py delete mode 100644 src/kitconcept/intranet/services/configure.zcml delete mode 100644 src/kitconcept/intranet/subscribers/__init__.py delete mode 100644 src/kitconcept/intranet/subscribers/configure.zcml delete mode 100644 src/kitconcept/intranet/vocabularies/__init__.py delete mode 100644 src/kitconcept/intranet/vocabularies/configure.zcml diff --git a/src/kitconcept/intranet/browser/__init__.py b/src/kitconcept/intranet/browser/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/kitconcept/intranet/browser/configure.zcml b/src/kitconcept/intranet/browser/configure.zcml deleted file mode 100644 index 5d8ff52..0000000 --- a/src/kitconcept/intranet/browser/configure.zcml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/src/kitconcept/intranet/browser/static/.gitkeep b/src/kitconcept/intranet/browser/static/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/kitconcept/intranet/configure.zcml b/src/kitconcept/intranet/configure.zcml index 58364c9..f7e7ce2 100644 --- a/src/kitconcept/intranet/configure.zcml +++ b/src/kitconcept/intranet/configure.zcml @@ -21,12 +21,6 @@ - - - - - - diff --git a/src/kitconcept/intranet/indexers/__init__.py b/src/kitconcept/intranet/indexers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/kitconcept/intranet/indexers/configure.zcml b/src/kitconcept/intranet/indexers/configure.zcml deleted file mode 100644 index 94ea6a1..0000000 --- a/src/kitconcept/intranet/indexers/configure.zcml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - diff --git a/src/kitconcept/intranet/serializers/__init__.py b/src/kitconcept/intranet/serializers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/kitconcept/intranet/serializers/configure.zcml b/src/kitconcept/intranet/serializers/configure.zcml deleted file mode 100644 index fb8b793..0000000 --- a/src/kitconcept/intranet/serializers/configure.zcml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/kitconcept/intranet/services/__init__.py b/src/kitconcept/intranet/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/kitconcept/intranet/services/configure.zcml b/src/kitconcept/intranet/services/configure.zcml deleted file mode 100644 index fb8b793..0000000 --- a/src/kitconcept/intranet/services/configure.zcml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/kitconcept/intranet/subscribers/__init__.py b/src/kitconcept/intranet/subscribers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/kitconcept/intranet/subscribers/configure.zcml b/src/kitconcept/intranet/subscribers/configure.zcml deleted file mode 100644 index fb8b793..0000000 --- a/src/kitconcept/intranet/subscribers/configure.zcml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/kitconcept/intranet/vocabularies/__init__.py b/src/kitconcept/intranet/vocabularies/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/kitconcept/intranet/vocabularies/configure.zcml b/src/kitconcept/intranet/vocabularies/configure.zcml deleted file mode 100644 index eccbc33..0000000 --- a/src/kitconcept/intranet/vocabularies/configure.zcml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - From f942fd7838b3f188235e8bedb36eda60731b2ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Re=C3=A9?= Date: Mon, 25 Mar 2024 14:41:32 +0100 Subject: [PATCH 11/16] Fix linting --- setup.py | 3 ++- .../intranet/behaviors/additional_contact_info.py | 2 +- src/kitconcept/intranet/dependencies.zcml | 2 +- src/kitconcept/intranet/distributions.zcml | 2 +- src/kitconcept/intranet/permissions.zcml | 2 +- src/kitconcept/intranet/profiles.zcml | 10 +++++----- .../intranet/profiles/default/browserlayer.xml | 4 ++-- .../intranet/profiles/uninstall/browserlayer.xml | 2 +- src/kitconcept/intranet/setuphandlers/__init__.py | 8 ++++---- src/kitconcept/intranet/upgrades/configure.zcml | 2 +- 10 files changed, 19 insertions(+), 18 deletions(-) diff --git a/setup.py b/setup.py index f9a8ff9..bfbfe63 100644 --- a/setup.py +++ b/setup.py @@ -54,6 +54,8 @@ "plone.distribution", # "plone.api", "kitconcept.solr", + "python-dateutil", + "collective.person", ], extras_require={ "test": [ @@ -64,7 +66,6 @@ "pytest", "pytest-cov", "pytest-plone>=0.2.0", - "collective.person", ], }, entry_points=""" diff --git a/src/kitconcept/intranet/behaviors/additional_contact_info.py b/src/kitconcept/intranet/behaviors/additional_contact_info.py index 0aa8e0c..92a4e66 100644 --- a/src/kitconcept/intranet/behaviors/additional_contact_info.py +++ b/src/kitconcept/intranet/behaviors/additional_contact_info.py @@ -1,4 +1,4 @@ -from collective.contact_behaviors import _ +from kitconcept.intranet import _ from plone.autoform.directives import read_permission from plone.autoform.interfaces import IFormFieldProvider from plone.schema.email import Email diff --git a/src/kitconcept/intranet/dependencies.zcml b/src/kitconcept/intranet/dependencies.zcml index 1333a8d..6b7699b 100644 --- a/src/kitconcept/intranet/dependencies.zcml +++ b/src/kitconcept/intranet/dependencies.zcml @@ -4,6 +4,6 @@ - + diff --git a/src/kitconcept/intranet/distributions.zcml b/src/kitconcept/intranet/distributions.zcml index efb1264..94305c6 100644 --- a/src/kitconcept/intranet/distributions.zcml +++ b/src/kitconcept/intranet/distributions.zcml @@ -2,7 +2,7 @@ xmlns="http://namespaces.zope.org/zope" xmlns:i18n="http://namespaces.zope.org/i18n" xmlns:plone="http://namespaces.plone.org/plone" - i18n_domain="plone" + i18n_domain="kitconcept.intranet" > diff --git a/src/kitconcept/intranet/profiles.zcml b/src/kitconcept/intranet/profiles.zcml index 733c0d7..986a706 100644 --- a/src/kitconcept/intranet/profiles.zcml +++ b/src/kitconcept/intranet/profiles.zcml @@ -1,12 +1,12 @@ diff --git a/src/kitconcept/intranet/profiles/default/browserlayer.xml b/src/kitconcept/intranet/profiles/default/browserlayer.xml index 93a2269..88ce498 100644 --- a/src/kitconcept/intranet/profiles/default/browserlayer.xml +++ b/src/kitconcept/intranet/profiles/default/browserlayer.xml @@ -1,6 +1,6 @@ - diff --git a/src/kitconcept/intranet/profiles/uninstall/browserlayer.xml b/src/kitconcept/intranet/profiles/uninstall/browserlayer.xml index ee5fc55..3628ad2 100644 --- a/src/kitconcept/intranet/profiles/uninstall/browserlayer.xml +++ b/src/kitconcept/intranet/profiles/uninstall/browserlayer.xml @@ -1,6 +1,6 @@ - diff --git a/src/kitconcept/intranet/setuphandlers/__init__.py b/src/kitconcept/intranet/setuphandlers/__init__.py index 2a8e8f0..df64863 100644 --- a/src/kitconcept/intranet/setuphandlers/__init__.py +++ b/src/kitconcept/intranet/setuphandlers/__init__.py @@ -1,6 +1,6 @@ -from kitconcept_intranet_demo import logger -from kitconcept_intranet_demo.setuphandlers import content -from kitconcept_intranet_demo.setuphandlers import users +from kitconcept.intranet import logger +from kitconcept.intranet.setuphandlers import content +from kitconcept.intranet.setuphandlers import users from plone import api from Products.CMFPlone.interfaces import INonInstallable from zope.interface import implementer @@ -11,7 +11,7 @@ class HiddenProfiles(object): def getNonInstallableProfiles(self): """Hide uninstall profile from site-creation and quickinstaller.""" return [ - "kitconcept_intranet_demo:uninstall", + "kitconcept.intranet:uninstall", ] diff --git a/src/kitconcept/intranet/upgrades/configure.zcml b/src/kitconcept/intranet/upgrades/configure.zcml index 2e301c7..fc98bb3 100644 --- a/src/kitconcept/intranet/upgrades/configure.zcml +++ b/src/kitconcept/intranet/upgrades/configure.zcml @@ -5,7 +5,7 @@ diff --git a/src/kitconcept/intranet/profiles/default/types/Person.xml b/src/kitconcept/intranet/profiles/default/types/Person.xml index 4842d1f..1e65fc3 100644 --- a/src/kitconcept/intranet/profiles/default/types/Person.xml +++ b/src/kitconcept/intranet/profiles/default/types/Person.xml @@ -1,11 +1,11 @@