diff --git a/pyproject.toml b/pyproject.toml
index a671cb5..499bd04 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,7 +42,7 @@ dependencies = [
"pyramid_tm",
"waitress",
"WebHelpers2",
- "WuttJamaican[db]>=0.12.1",
+ "WuttJamaican[db,email]>=0.12.1",
"zope.sqlalchemy>=1.5",
]
diff --git a/src/wuttaweb/app.py b/src/wuttaweb/app.py
index 88318b4..c263b60 100644
--- a/src/wuttaweb/app.py
+++ b/src/wuttaweb/app.py
@@ -37,9 +37,10 @@ from wuttaweb.auth import WuttaSecurityPolicy
class WebAppProvider(AppProvider):
"""
- The :term:`app provider` for WuttaWeb. This adds some methods
- specific to web apps.
+ The :term:`app provider` for WuttaWeb. This adds some methods to
+ the :term:`app handler`, which are specific to web apps.
"""
+ email_templates = 'wuttaweb:email/templates'
def get_web_handler(self, **kwargs):
"""
diff --git a/src/wuttaweb/templates/temporary/feedback.html.mako b/src/wuttaweb/email/templates/feedback.html.mako
similarity index 100%
rename from src/wuttaweb/templates/temporary/feedback.html.mako
rename to src/wuttaweb/email/templates/feedback.html.mako
diff --git a/src/wuttaweb/templates/temporary/feedback.txt.mako b/src/wuttaweb/email/templates/feedback.txt.mako
similarity index 78%
rename from src/wuttaweb/templates/temporary/feedback.txt.mako
rename to src/wuttaweb/email/templates/feedback.txt.mako
index b0d396a..a73a55e 100644
--- a/src/wuttaweb/templates/temporary/feedback.txt.mako
+++ b/src/wuttaweb/email/templates/feedback.txt.mako
@@ -5,9 +5,9 @@
**User Name**
% if user:
- ${user}
+${user}
% else:
- ${user_name}
+${user_name}
% endif
**Referring URL**
diff --git a/src/wuttaweb/templates/appinfo/configure.mako b/src/wuttaweb/templates/appinfo/configure.mako
index d2de2cf..03f1551 100644
--- a/src/wuttaweb/templates/appinfo/configure.mako
+++ b/src/wuttaweb/templates/appinfo/configure.mako
@@ -73,6 +73,54 @@
+
Email
+
+
+
+
+ Enable email sending
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Web Libraries
@@ -219,6 +267,19 @@
this.editWebLibraryShowDialog = false
}
+ ThisPage.methods.validateEmailSettings = function() {
+ if (this.simpleSettings['${config.appname}.mail.send_emails']) {
+ if (!this.simpleSettings['${config.appname}.email.default.sender']) {
+ return "Default Sender is required to send email."
+ }
+ if (!this.simpleSettings['${config.appname}.email.default.to']) {
+ return "Default Recipient(s) are required to send email."
+ }
+ }
+ }
+
+ ThisPageData.validators.push(ThisPage.methods.validateEmailSettings)
+
%def>
diff --git a/src/wuttaweb/templates/appinfo/index.mako b/src/wuttaweb/templates/appinfo/index.mako
index 279a41e..383157f 100644
--- a/src/wuttaweb/templates/appinfo/index.mako
+++ b/src/wuttaweb/templates/appinfo/index.mako
@@ -20,7 +20,10 @@
${app.get_node_title()}
- ${config.production()}
+ ${"Yes" if config.production() else "No"}
+
+
+ ${"Yes" if app.get_email_handler().sending_is_enabled() else "No"}
diff --git a/src/wuttaweb/templates/configure.mako b/src/wuttaweb/templates/configure.mako
index f0363e0..20878a3 100644
--- a/src/wuttaweb/templates/configure.mako
+++ b/src/wuttaweb/templates/configure.mako
@@ -167,7 +167,11 @@
for (let validator of this.validators) {
let msg = validator.call(this)
if (msg) {
- alert(msg)
+ this.$buefy.toast.open({
+ message: msg,
+ type: 'is-warning',
+ duration: 4000, // 4 seconds
+ })
return
}
}
diff --git a/src/wuttaweb/views/common.py b/src/wuttaweb/views/common.py
index a68e298..309ecc3 100644
--- a/src/wuttaweb/views/common.py
+++ b/src/wuttaweb/views/common.py
@@ -132,31 +132,9 @@ class CommonView(View):
return schema
- def feedback_send(self, context): # pragma: no cover
+ def feedback_send(self, context):
""" """
-
- # TODO: this is definitely a stopgap bit of logic, until we
- # have a more robust way to handle email via wuttjamaican etc.
-
- from pyramid_mailer.mailer import Mailer
- from pyramid_mailer.message import Message
-
- From = self.config.require(f'{self.config.appname}.email.default.sender')
- To = self.config.require(f'{self.config.appname}.email.feedback.to')
- Subject = self.config.get(f'{self.config.appname}.email.feedback.subject',
- default="User Feedback")
-
- text_body = render('/temporary/feedback.txt.mako', context, request=self.request)
- html_body = render('/temporary/feedback.html.mako', context, request=self.request)
-
- msg = Message(subject=Subject,
- sender=From,
- recipients=[To],
- body=text_body,
- html=html_body)
-
- mailer = Mailer()
- mailer.send_immediately(msg)
+ self.app.send_email('feedback', context)
def setup(self, session=None):
"""
diff --git a/src/wuttaweb/views/settings.py b/src/wuttaweb/views/settings.py
index 43b4687..90a00cb 100644
--- a/src/wuttaweb/views/settings.py
+++ b/src/wuttaweb/views/settings.py
@@ -124,16 +124,25 @@ class AppInfoView(MasterView):
simple_settings = [
# basics
- {'name': f'{self.app.appname}.app_title'},
- {'name': f'{self.app.appname}.node_type'},
- {'name': f'{self.app.appname}.node_title'},
- {'name': f'{self.app.appname}.production',
+ {'name': f'{self.config.appname}.app_title'},
+ {'name': f'{self.config.appname}.node_type'},
+ {'name': f'{self.config.appname}.node_title'},
+ {'name': f'{self.config.appname}.production',
'type': bool},
# user/auth
{'name': 'wuttaweb.home_redirect_to_login',
'type': bool, 'default': False},
+ # email
+ {'name': f'{self.config.appname}.mail.send_emails',
+ 'type': bool, 'default': False},
+ {'name': f'{self.config.appname}.email.default.sender'},
+ {'name': f'{self.config.appname}.email.default.subject'},
+ {'name': f'{self.config.appname}.email.default.to'},
+ {'name': f'{self.config.appname}.email.feedback.subject'},
+ {'name': f'{self.config.appname}.email.feedback.to'},
+
]
def getval(key):
diff --git a/tests/views/test_common.py b/tests/views/test_common.py
index 9fe0074..0da2822 100644
--- a/tests/views/test_common.py
+++ b/tests/views/test_common.py
@@ -117,6 +117,16 @@ class TestCommonView(WebTestCase):
self.assertEqual(list(context), ['error'])
self.assertIn('RuntimeError', context['error'])
+ def test_feedback_send(self):
+ view = self.make_view()
+ with patch.object(self.app, 'send_email') as send_email:
+ view.feedback_send({'user_name': "Barney",
+ 'message': "hello world"})
+ send_email.assert_called_once_with('feedback', {
+ 'user_name': "Barney",
+ 'message': "hello world"
+ })
+
def test_setup(self):
self.pyramid_config.add_route('home', '/')
self.pyramid_config.add_route('login', '/login')