Skip to content

Commit

Permalink
Merge pull request #35 from mxstack/plone-createsite
Browse files Browse the repository at this point in the history
Add plone domain to enable site creation
  • Loading branch information
rnixx authored Jun 6, 2024
2 parents 7775d77 + 1e393ff commit 0cf6fb4
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 7 deletions.
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,11 @@ lines_after_imports = 2

[tool.mypy]
ignore_missing_imports = true
python_version = 3.8
python_version = "3.8"
exclude = "src/mxmake/templates/plone-site.py"

[tool.ruff]
# Exclude a variety of commonly ignored directories.
exclude = [
"src/mxmake/templates/plone-site.py",
]
38 changes: 38 additions & 0 deletions src/mxmake/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,41 @@ class GHActionsTypecheck(GHActionsTemplate):
description: str = "Github action to running static type checks"
target_name = "typecheck.yml"
template_name = "gh-actions-typecheck.yml"


##############################################################################
# plone-site template
##############################################################################


@template("plone-site")
class PloneSitePy(MxIniBoundTemplate):
description: str = "Script to create or purge a Plone site"
target_name = "plone-site.py"
template_name = "plone-site.py"

@property
def target_folder(self) -> Path:
return mxmake_files()

@property
def template_variables(self):
site = {}
vars = {"site": site}
site.setdefault("site_id", "Plone")
site.setdefault("title", "Plone Site")
site.setdefault("setup_content", False)
site.setdefault("default_language", "en")
site.setdefault("portal_timezone", "UTC")
site.setdefault("extension_ids", "")
site.update(**self.settings)
if "distribution" in site:
vars["distribution"] = site.pop("distribution")

# handle extension ids
site["extension_ids"] = [
eid.strip() for eid in site["extension_ids"].split("\n") if eid.strip()
]
if not site["extension_ids"]:
site["extension_ids"] = ["plone.volto:default"]
return vars
63 changes: 63 additions & 0 deletions src/mxmake/templates/plone-site.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from AccessControl.SecurityManagement import newSecurityManager
from plone.distribution.api.site import create
from Products.CMFPlone.factory import _DEFAULT_PROFILE
from Testing.makerequest import makerequest

import os
import transaction


TRUTHY = frozenset(("t", "true", "y", "yes", "on", "1"))


def asbool(value: str|bool|None) -> bool:
"""Return the boolean value ``True`` if the case-lowered value of string
input ``s`` is a :term:`truthy string`. If ``s`` is already one of the
boolean values ``True`` or ``False``, return it.
"""
if value is None:
return False
if isinstance(value, bool):
return value
return value.strip().lower() in TRUTHY


PLONE_SITE_PURGE = asbool(os.getenv("PLONE_SITE_PURGE"))

config = {
{% for key, value in site.items() %}
{% if key == "extension_ids" %}
{% for extension_id in value %}
"extension_ids": [
"{{ extension_id }}",
],
{% endfor %}
{% else %}
"{{ key }}": "{{ value }}",
{% endif %}
{% endfor %}
"profile_id": _DEFAULT_PROFILE,
}
config["setup_content"] = asbool(config["setup_content"])

app = makerequest(globals()["app"])
admin = app.acl_users.getUserById("admin")
newSecurityManager(None, admin.__of__(app.acl_users))

if PLONE_SITE_PURGE:
if config["site_id"] in app.objectIds():
app.manage_delObjects([config["site_id"]])
transaction.commit()
app._p_jar.sync()
else:
print(f"Site with id {config['site_id']} does not exist!")
exit(0)


if config["site_id"] in app.objectIds():
print(f"Site with id {config['site_id']} already exists!")
exit(1)

site = create(app, "{{ distribution }}", config)
transaction.commit()
app._p_jar.sync()
103 changes: 103 additions & 0 deletions src/mxmake/tests/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Template(templates.Template):
"gh-actions-lint": templates.GHActionsLint,
"gh-actions-test": templates.GHActionsTest,
"gh-actions-typecheck": templates.GHActionsTypecheck,
"plone-site": templates.PloneSitePy,
},
)

Expand Down Expand Up @@ -820,3 +821,105 @@ def test_MxIni(self, tempdir):
""",
f.read(),
)

@testing.template_directory()
def test_PloneSite_all_defaults(self, tempdir):
mxini = tempdir / "mx.ini"
with mxini.open("w") as fd:
fd.write(
"[settings]\n"
"\n"
"[mxmake-plone-site]\n"
"distribution = mxmake.test:default\n"
)
with mxini.open("w") as fd:
fd.write("[settings]\n")
configuration = mxdev.Configuration(mxini, hooks=[hook.Hook()])
factory = templates.template.lookup("plone-site")
template = factory(configuration, templates.get_template_environment())

self.assertEqual(template.description, "Script to create or purge a Plone site")
self.assertEqual(template.target_folder, utils.mxmake_files())
self.assertEqual(template.target_name, "plone-site.py")
self.assertEqual(template.template_name, "plone-site.py")
self.assertEqual(
template.template_variables,
{
"site": {
"default_language": "en",
"extension_ids": ["plone.volto:default"],
"portal_timezone": "UTC",
"setup_content": False,
"site_id": "Plone",
"title": "Plone Site",
}
},
)

template.write()
with (tempdir / "plone-site.py").open() as f:
self.checkOutput(
'''
from AccessControl.SecurityManagement import newSecurityManager
from plone.distribution.api.site import create
from Products.CMFPlone.factory import _DEFAULT_PROFILE
from Testing.makerequest import makerequest
import os
import transaction
TRUTHY = frozenset(("t", "true", "y", "yes", "on", "1"))
def asbool(value: str|bool|None) -> bool:
"""Return the boolean value ``True`` if the case-lowered value of string
input ``s`` is a :term:`truthy string`. If ``s`` is already one of the
boolean values ``True`` or ``False``, return it.
"""
if value is None:
return False
if isinstance(value, bool):
return value
return value.strip().lower() in TRUTHY
PLONE_SITE_PURGE = asbool(os.getenv("PLONE_SITE_PURGE"))
config = {
"site_id": "Plone",
"title": "Plone Site",
"setup_content": "False",
"default_language": "en",
"portal_timezone": "UTC",
"extension_ids": [
"plone.volto:default",
],
"profile_id": _DEFAULT_PROFILE,
}
config["setup_content"] = asbool(config["setup_content"])
app = makerequest(globals()["app"])
admin = app.acl_users.getUserById("admin")
newSecurityManager(None, admin.__of__(app.acl_users))
if PLONE_SITE_PURGE:
if config["site_id"] in app.objectIds():
app.manage_delObjects([config["site_id"]])
transaction.commit()
app._p_jar.sync()
else:
print(f"Site with id {config['site_id']} does not exist!")
exit(0)
if config["site_id"] in app.objectIds():
print(f"Site with id {config['site_id']} already exists!")
exit(1)
site = create(app, "", config)
transaction.commit()
app._p_jar.sync()
''',
f.read(),
)
1 change: 0 additions & 1 deletion src/mxmake/topics/applications/cookiecutter.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#:
#:[target.cookiecutter-clean]
#:description = Uninstall cookiecutter.
#:

##############################################################################
# cookiecutter
Expand Down
29 changes: 29 additions & 0 deletions src/mxmake/topics/applications/plone.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#:[plone]
#:title = plone
#:description = Plone application related
#:depends = applications.zope
#:
#:[target.plone-site-create]
#:description = Creates a Plone site using the script provided in `PLONE_SITE_SCRIPT` configuration.
#:
#:[target.plone-site-purge]
#:description = Removes the Plone instance from the database, but the database itself is kept.
#:
#:[setting.PLONE_SITE_SCRIPT]
#:description = Path to the script to create or purge a Plone site
#:default = .mxmake/files/plone-site.py

##############################################################################
# plone
##############################################################################

.PHONY: plone-site-create
plone-site-create: $(ZOPE_RUN_TARGET)
@echo "Creating Plone Site"
@zconsole run $(ZOPE_INSTANCE_FOLDER)/etc/zope.conf $(PLONE_SITE_SCRIPT)

.PHONY: plone-site-purge
plone-site-purge: $(ZOPE_RUN_TARGET)
@echo "Purging Plone Site"
@export PLONE_SITE_PURGE=True
@zconsole run $(ZOPE_INSTANCE_FOLDER)/etc/zope.conf $(PLONE_SITE_SCRIPT)
9 changes: 4 additions & 5 deletions src/mxmake/topics/applications/zope.mk
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@
#:
#:[target.zope-purge]
#:description = Removes the whole Zope instance folder including database.
#:


##############################################################################
# zope
##############################################################################

ZOPE_INSTANCE_FOLDER:=$(ZOPE_BASE_FOLDER)/instance
ZOPE_INSTANCE_TARGET:=$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini $(ZOPE_INSTANCE_FOLDER)/etc/zope.conf $(ZOPE_INSTANCE_FOLDER)/etc/site.zcml
ZOPE_RUN_TARGET:=$(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET)

ifeq (,$(ZOPE_TEMPLATE_CHECKOUT))
ZOPE_COOKIECUTTER_TEMPLATE_OPTIONS=
Expand All @@ -72,17 +71,17 @@ $(ZOPE_INSTANCE_TARGET): $(COOKIECUTTER_TARGET) $(ZOPE_CONFIGURATION_FILE)
zope-instance: $(ZOPE_INSTANCE_TARGET) $(SOURCES)

.PHONY: zope-start
zope-start: $(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET)
zope-start: $(ZOPE_RUN_TARGET)
@echo "Start Zope/Plone with configuration in $(ZOPE_INSTANCE_FOLDER)"
@runwsgi -v "$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini"

.PHONY: zope-debug
zope-debug: $(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET)
zope-debug: $(ZOPE_RUN_TARGET)
@echo "Start Zope/Plone with configuration in $(ZOPE_INSTANCE_FOLDER)"
@zconsole debug "$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini"

.PHONY: zope-runscript
zope-runscript: $(ZOPE_INSTANCE_TARGET) $(PACKAGES_TARGET)
zope-runscript: $(ZOPE_RUN_TARGET)
@echo "Run Zope/Plone Console Script $(ZOPE_SCRIPTNAME) in $(ZOPE_INSTANCE_FOLDER)"
@zconsole run "$(ZOPE_INSTANCE_FOLDER)/etc/zope.ini" $(ZOPE_SCRIPTNAME)

Expand Down
1 change: 1 addition & 0 deletions src/mxmake/topics/core/packages.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#:description = Allow prerelease and development versions.
#: By default, the package installer only finds stable versions.
#:default = false

##############################################################################
# packages
##############################################################################
Expand Down

0 comments on commit 0cf6fb4

Please sign in to comment.