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) + 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')