diff --git a/.gitignore b/.gitignore
index a7fa46a4..6365d655 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,3 +69,4 @@ docs/Makefile
/docs/_build
/venv311
/.python-version
+/huey.log
diff --git a/base.cfg b/base.cfg
index a3f14bc3..92ddd9e8 100644
--- a/base.cfg
+++ b/base.cfg
@@ -14,10 +14,12 @@ parts =
i18ndude
omelette
robot
+ huey
plone-helper-scripts
develop = .
+ src/collective.taskqueue2
[instance]
@@ -26,10 +28,13 @@ user = admin:admin
http-address = 8080
environment-vars =
zope_i18n_compile_mo_files true
+ HUEY_CONSUMER True
+ HUEY_LOG_LEVEL WARNING
eggs =
Plone
Pillow
pdbpp
+ huey
Products.EasyNewsletter [test]
[vscode]
@@ -90,6 +95,10 @@ eggs = zest.releaser
recipe = zc.recipe.egg
eggs = i18ndude
+[huey]
+recipe = zc.recipe.egg
+eggs = huey
+
[plone-helper-scripts]
recipe = zc.recipe.egg
@@ -99,6 +108,7 @@ eggs =
interpreter = zopepy
scripts =
zopepy
+ huey_consumer
plone-compile-resources
diff --git a/setup.cfg b/setup.cfg
index b91799fe..9d438cda 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -18,6 +18,7 @@ ignore =
C813,
C101,
E203
+ F401
# E203, E266
exclude = bootstrap.py,docs,*.egg.,omelette
max-line-length = 88
diff --git a/setup.py b/setup.py
index 9930adee..0d59ef92 100644
--- a/setup.py
+++ b/setup.py
@@ -53,6 +53,9 @@
"html2text",
"email-validator>=1.1.2",
"six",
+ "collective.taskqueue2",
+ # "huey",
+ # "gevent",
],
extras_require=dict(
test=[
diff --git a/src/Products/EasyNewsletter/__init__.py b/src/Products/EasyNewsletter/__init__.py
index a2a29932..7ce1baa3 100644
--- a/src/Products/EasyNewsletter/__init__.py
+++ b/src/Products/EasyNewsletter/__init__.py
@@ -2,7 +2,9 @@
# avoid circular import
# from Products.EasyNewsletter import config # noqa
from zope.i18nmessageid import MessageFactory
+import logging
+log = logging.getLogger("Products.EasyNewsletter")
EasyNewsletterMessageFactory = MessageFactory("Products.EasyNewsletter")
_ = EasyNewsletterMessageFactory
diff --git a/src/Products/EasyNewsletter/configure.zcml b/src/Products/EasyNewsletter/configure.zcml
index b3cf9448..40f615ec 100644
--- a/src/Products/EasyNewsletter/configure.zcml
+++ b/src/Products/EasyNewsletter/configure.zcml
@@ -15,6 +15,7 @@
+
diff --git a/src/Products/EasyNewsletter/content/newsletter_issue.py b/src/Products/EasyNewsletter/content/newsletter_issue.py
index 0be2fa4e..c2ff5fa1 100644
--- a/src/Products/EasyNewsletter/content/newsletter_issue.py
+++ b/src/Products/EasyNewsletter/content/newsletter_issue.py
@@ -206,7 +206,8 @@ class NewsletterIssue(Container):
context_property("content_aggregation_sources")
def get_newsletter(self):
- return self.__parent__
+ return self.aq_inner.aq_parent
+ # return self.__parent__
# bbb to support ATCT way, needs to be removed in v5.x:
getNewsletter = get_newsletter
diff --git a/src/Products/EasyNewsletter/issuedatafetcher.py b/src/Products/EasyNewsletter/issuedatafetcher.py
index 105d0aa8..cc1cca79 100644
--- a/src/Products/EasyNewsletter/issuedatafetcher.py
+++ b/src/Products/EasyNewsletter/issuedatafetcher.py
@@ -105,7 +105,9 @@ def _render_output_html(self, preview=False):
with header+body+footer (raw html).
"""
output_tmpl_id = self.issue.output_template
- issue_tmpl = self.issue.restrictedTraverse(str(output_tmpl_id))
+ issue_tmpl = self.issue.restrictedTraverse(str(output_tmpl_id), None)
+ if not issue_tmpl:
+ import pdb; pdb.set_trace() # NOQA: E702
output_html = issue_tmpl.render()
return output_html
diff --git a/src/Products/EasyNewsletter/queue/configure.zcml b/src/Products/EasyNewsletter/queue/configure.zcml
index 530a25e9..0c6a976a 100644
--- a/src/Products/EasyNewsletter/queue/configure.zcml
+++ b/src/Products/EasyNewsletter/queue/configure.zcml
@@ -8,6 +8,9 @@
/>
+
diff --git a/src/Products/EasyNewsletter/queue/huey/__init__.py b/src/Products/EasyNewsletter/queue/huey/__init__.py
new file mode 100644
index 00000000..40a96afc
--- /dev/null
+++ b/src/Products/EasyNewsletter/queue/huey/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/src/Products/EasyNewsletter/queue/huey/configure.zcml b/src/Products/EasyNewsletter/queue/huey/configure.zcml
new file mode 100644
index 00000000..cffc29ea
--- /dev/null
+++ b/src/Products/EasyNewsletter/queue/huey/configure.zcml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/src/Products/EasyNewsletter/queue/huey/handler.py b/src/Products/EasyNewsletter/queue/huey/handler.py
new file mode 100644
index 00000000..2f828830
--- /dev/null
+++ b/src/Products/EasyNewsletter/queue/huey/handler.py
@@ -0,0 +1,11 @@
+from zope.interface import implementer
+from Products.EasyNewsletter.queue.interfaces import IIssueQueue
+from .huey_tasks import send_newsletters
+
+
+@implementer(IIssueQueue)
+class IssueQueue(object):
+ def start(self, context):
+ """Queues issue for sendout through huey-mini task queue"""
+ task_res = send_newsletters(context.UID())
+ return task_res
diff --git a/src/Products/EasyNewsletter/queue/huey/huey_tasks.py b/src/Products/EasyNewsletter/queue/huey/huey_tasks.py
new file mode 100644
index 00000000..b28f5e48
--- /dev/null
+++ b/src/Products/EasyNewsletter/queue/huey/huey_tasks.py
@@ -0,0 +1,25 @@
+import tempfile
+
+from huey import SqliteHuey
+from plone import api
+from Products.EasyNewsletter import log
+
+QUEUE_NAME = "Products.EasyNewsletter.queue"
+# VIEW_NAME = "enl_taskqueue_sendout"
+
+huey_db_name = tempfile.NamedTemporaryFile(suffix=".db", delete=False).name
+huey = SqliteHuey(filename=huey_db_name)
+log.info(f"Huey SQLite DB: {huey_db_name}")
+
+
+@huey.task()
+def send_newsletters(uid):
+ """ resolve the context object by given uid and triggers
+ generation and sending of the newsletter issue.
+ """
+ # from zope.component import getGlobalSiteManager
+ # gsm = getGlobalSiteManager()
+ # import pdb; pdb.set_trace() # NOQA: E702
+ context = api.content.get(UID=uid)
+ send_view = api.content.get_view(name="send-issue", context=context)
+ send_view.send()
diff --git a/src/Products/EasyNewsletter/queue/huey/view.py b/src/Products/EasyNewsletter/queue/huey/view.py
new file mode 100644
index 00000000..7a44b5d2
--- /dev/null
+++ b/src/Products/EasyNewsletter/queue/huey/view.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+from plone import api
+from plone.protect.interfaces import IDisableCSRFProtection
+from Products.Five.browser import BrowserView
+from zope.interface import alsoProvides
+
+from Products.EasyNewsletter import log
+
+
+class ProcessQueue(BrowserView):
+ def __call__(self):
+ alsoProvides(self.request, IDisableCSRFProtection)
+ log.info("generating and sending newsletter issue emails")
+ send_view = api.content.get_view(name="send-issue", context=self.context)
+ send_view.send()
+ log.info("sending done ;)")
diff --git a/src/Products/EasyNewsletter/queue/taskqueue/configure.zcml b/src/Products/EasyNewsletter/queue/taskqueue/configure.zcml
index cbec8cae..e6a7022b 100644
--- a/src/Products/EasyNewsletter/queue/taskqueue/configure.zcml
+++ b/src/Products/EasyNewsletter/queue/taskqueue/configure.zcml
@@ -6,9 +6,9 @@
+
diff --git a/src/Products/EasyNewsletter/queue/taskqueue/handler.py b/src/Products/EasyNewsletter/queue/taskqueue/handler.py
index 7f5fb51d..821bc033 100644
--- a/src/Products/EasyNewsletter/queue/taskqueue/handler.py
+++ b/src/Products/EasyNewsletter/queue/taskqueue/handler.py
@@ -1,18 +1,34 @@
# -*- coding: utf-8 -*-
-from collective.taskqueue import taskqueue
+from plone import api
+from collective.taskqueue2.huey_tasks import schedule_browser_view
from Products.EasyNewsletter.queue.interfaces import IIssueQueue
from zope.interface import implementer
QUEUE_NAME = "Products.EasyNewsletter.queue"
-VIEW_NAME = "enl_taskqueue_sendout"
+ENL_VIEW_NAME = "enl_taskqueue_sendout"
@implementer(IIssueQueue)
class TCIssueQueue(object):
def start(self, context):
"""Queues issue for sendout through collective.taskqueue"""
- jobid = taskqueue.add(
- "/".join(context.getPhysicalPath() + (VIEW_NAME,)), queue=QUEUE_NAME
+ # import pdb; pdb.set_trace() # NOQA: E702
+ result = schedule_browser_view(
+ view_name=ENL_VIEW_NAME,
+ context_path="/".join(context.getPhysicalPath()),
+ site_path="/".join(api.portal.get().getPhysicalPath()),
+ username=api.user.get_current().getId(),
+ params=dict(
+ base=context.REQUEST.base,
+ layers=context.REQUEST.__provides__,
+ cookies=context.REQUEST.cookies,
+ form=dict(),
+ _plonebrowserlayer_=context.REQUEST._plonebrowserlayer_,
+ _plonetheme_=context.REQUEST._plonetheme_,
+ ),
)
- return jobid
+ # jobid = taskqueue.add(
+ # "/".join(context.getPhysicalPath() + (VIEW_NAME,)), queue=QUEUE_NAME
+ # )
+ return result
diff --git a/src/Products/EasyNewsletter/queue/taskqueue/view.py b/src/Products/EasyNewsletter/queue/taskqueue/view.py
index daba1aa4..5b6038c9 100644
--- a/src/Products/EasyNewsletter/queue/taskqueue/view.py
+++ b/src/Products/EasyNewsletter/queue/taskqueue/view.py
@@ -1,10 +1,18 @@
# -*- coding: utf-8 -*-
+from plone import api
from plone.protect.interfaces import IDisableCSRFProtection
from Products.Five.browser import BrowserView
from zope.interface import alsoProvides
+from Products.EasyNewsletter import log
+
class ProcessQueue(BrowserView):
def __call__(self):
alsoProvides(self.request, IDisableCSRFProtection)
- self.context.send()
+ log.info("start sending:\n")
+ import pdb; pdb.set_trace() # NOQA: E702`c`
+ # send_view = api.content.get_view(name="send-issue", context=self.context)
+ send_view = self.context.restrictedTraverse("send-issue")
+ send_view.send()
+ log.info("sending done ;)\n")
diff --git a/src/Products/EasyNewsletter/views/configure.zcml b/src/Products/EasyNewsletter/views/configure.zcml
index 5188ea3b..aefbacfa 100644
--- a/src/Products/EasyNewsletter/views/configure.zcml
+++ b/src/Products/EasyNewsletter/views/configure.zcml
@@ -26,8 +26,9 @@
name="send-issue"
for="Products.EasyNewsletter.content.newsletter_issue.INewsletterIssue"
class=".newsletter_issue_send.NewsletterIssueSend"
- permission="cmf.ModifyPortalContent"
+ permission="zope2.View"
/>
+