Add email backend
This commit is contained in:
parent
2ec9d2a630
commit
ebd1104efb
37
.editorconfig
Normal file
37
.editorconfig
Normal file
@ -0,0 +1,37 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.py]
|
||||
indent_size = 4
|
||||
continuation_indent_size = 8
|
||||
combine_as_imports = true
|
||||
max_line_length = 88
|
||||
multi_line_output = 4
|
||||
quote_type = single
|
||||
|
||||
[*.js]
|
||||
indent_size = 4
|
||||
|
||||
[*.jsx]
|
||||
indent_size = 4
|
||||
|
||||
[*.scss]
|
||||
indent_size = 4
|
||||
|
||||
[*.ts]
|
||||
indent_size = 4
|
||||
|
||||
[*.tsx]
|
||||
indent_size = 4
|
||||
|
||||
[*.yml]
|
||||
indent_size = 4
|
||||
|
||||
[*.html]
|
||||
indent_size = 4
|
||||
2
Pipfile
2
Pipfile
@ -14,6 +14,8 @@ django-localflavor = "*"
|
||||
django-extensions = "*"
|
||||
markdown = "*"
|
||||
pillow = "*"
|
||||
django-anymail = {extras = ["mailgun"], version = "*"}
|
||||
django-templated-email = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
||||
71
Pipfile.lock
generated
71
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "d96bc4c80d45b75316ad378ebf86a010b0fbbfe651b086caad0d70a037d515b2"
|
||||
"sha256": "9590e03874968b489838ba3255c583c160e54a777547932a761d550b42ce46df"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -47,6 +47,22 @@
|
||||
"index": "pypi",
|
||||
"version": "==5.2.7"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d",
|
||||
"sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2022.6.15"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5",
|
||||
"sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
@ -60,7 +76,7 @@
|
||||
"sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667",
|
||||
"sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'",
|
||||
"markers": "python_version < '4' and python_full_version >= '3.6.2'",
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"click-plugins": {
|
||||
@ -85,6 +101,17 @@
|
||||
"index": "pypi",
|
||||
"version": "==4.0.6"
|
||||
},
|
||||
"django-anymail": {
|
||||
"extras": [
|
||||
"mailgun"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:49d83d7c16316ca86a624097496881d59b7d71b16bf1c5211cffa5b19ef98d0c",
|
||||
"sha256:783342d49dd07d68778b81dd12a94c86e1d217463a68a85450a0513fabe31345"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==8.6"
|
||||
},
|
||||
"django-appconf": {
|
||||
"hashes": [
|
||||
"sha256:ae9f864ee1958c815a965ed63b3fba4874eec13de10236ba063a788f9a17389d",
|
||||
@ -133,6 +160,30 @@
|
||||
"index": "pypi",
|
||||
"version": "==3.1"
|
||||
},
|
||||
"django-render-block": {
|
||||
"hashes": [
|
||||
"sha256:a01bfdb839e2f6b3f88a99021597484392bbd15d084f9a796e3e5658bae800f4",
|
||||
"sha256:fbdd8be56cefcfd794756a2e62117cc031f9c5de3ef4bb53e9a3f877a359a1a7"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.9.1"
|
||||
},
|
||||
"django-templated-email": {
|
||||
"hashes": [
|
||||
"sha256:49d61840ec551e640adaf341146e94d6f9058ae01df964480850bf988046e5eb",
|
||||
"sha256:bf1b68ffe6c8794c0c50e2ce20e3a166c6d511b3879abbd3cf059a3fc2fe2e60"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.0.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
|
||||
"sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.3"
|
||||
},
|
||||
"kombu": {
|
||||
"hashes": [
|
||||
"sha256:37cee3ee725f94ea8bb173eaab7c1760203ea53bbebae226328600f9d2799610",
|
||||
@ -268,6 +319,14 @@
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983",
|
||||
"sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"
|
||||
],
|
||||
"markers": "python_version >= '3.7' and python_version < '4'",
|
||||
"version": "==2.28.1"
|
||||
},
|
||||
"rjsmin": {
|
||||
"hashes": [
|
||||
"sha256:05efa485dfddb6418e3b86d8862463aa15641a61f6ae05e7e6de8f116ee77c69",
|
||||
@ -309,6 +368,14 @@
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==0.4.2"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec",
|
||||
"sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'",
|
||||
"version": "==1.26.10"
|
||||
},
|
||||
"vine": {
|
||||
"hashes": [
|
||||
"sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30",
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
from django import forms
|
||||
from django.core.mail import send_mail
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from templated_email import send_templated_mail
|
||||
|
||||
from .models import Post, Comment
|
||||
|
||||
NOTIFICATION_EMAIL_TEMPLATE = 'notification.html'
|
||||
|
||||
|
||||
class CommentCreateForm(forms.ModelForm):
|
||||
class Meta:
|
||||
@ -22,20 +26,27 @@ class CommentCreateForm(forms.ModelForm):
|
||||
})
|
||||
}
|
||||
|
||||
def send_notification(self):
|
||||
# subject = self.cleaned_data['content_object']
|
||||
def send_notification(self, request):
|
||||
author = self.instance.author
|
||||
message = self.cleaned_data.get('content')
|
||||
post = Post.objects.get(pk=self.cleaned_data['object_id'])
|
||||
url = get_current_site(request).domain + post.get_absolute_url()
|
||||
recipients = list(post.recipients.all().values_list('email', flat=True))
|
||||
if author in recipients:
|
||||
recipients.remove(author.email)
|
||||
|
||||
send_mail(
|
||||
post.title,
|
||||
message,
|
||||
author.email,
|
||||
recipients
|
||||
context = {
|
||||
'subject': post.title,
|
||||
'author': author,
|
||||
'message': message,
|
||||
'url': url
|
||||
}
|
||||
|
||||
send_templated_mail(
|
||||
template_name=NOTIFICATION_EMAIL_TEMPLATE,
|
||||
from_email=author.email,
|
||||
recipient_list=recipients,
|
||||
context=context
|
||||
)
|
||||
|
||||
|
||||
|
||||
20
src/core/migrations/0007_alter_post_recipients.py
Normal file
20
src/core/migrations/0007_alter_post_recipients.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.0.6 on 2022-07-21 00:19
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('core', '0006_alter_post_recipients'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='post',
|
||||
name='recipients',
|
||||
field=models.ManyToManyField(blank=True, related_name='subscriptions', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -130,7 +130,6 @@ class Post(models.Model):
|
||||
recipients = models.ManyToManyField(
|
||||
User,
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name='subscriptions'
|
||||
)
|
||||
tags = GenericRelation(Tag)
|
||||
|
||||
@ -45,7 +45,9 @@
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% empty %}
|
||||
<p>No posts</p>
|
||||
<tr>
|
||||
<td colspan="3">No posts</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tbody>
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<li colspan="3">No topics yet</li>
|
||||
<td colspan="3">No topics yet</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@ -34,7 +34,7 @@ class CommentCreateView(LoginRequiredMixin, CreateView):
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.author = self.request.user
|
||||
form.send_notification()
|
||||
form.send_notification(self.request)
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
|
||||
@ -1,19 +1,32 @@
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
DATABASE_CONFIG={
|
||||
'port' : os.environ.get('DATABASE_PORT', ''),
|
||||
'host' : os.environ.get('DATABASE_HOST', ''),
|
||||
'password' : os.environ.get('DATABASE_PASSWORD', ''),
|
||||
'user' : os.environ.get('DATABASE_USER', ''),
|
||||
'name' : os.environ.get('DATABASE_NAME', ''),
|
||||
'engine' : os.environ.get('DATABASE_ENGINE', ''),
|
||||
DEBUG = os.environ.get('DEBUG', 'True') == 'True'
|
||||
|
||||
DATABASE_CONFIG = {
|
||||
'port': os.environ.get('DATABASE_PORT', ''),
|
||||
'host': os.environ.get('DATABASE_HOST', ''),
|
||||
'password': os.environ.get('DATABASE_PASSWORD', ''),
|
||||
'user': os.environ.get('DATABASE_USER', ''),
|
||||
'name': os.environ.get('DATABASE_NAME', ''),
|
||||
'engine': os.environ.get('DATABASE_ENGINE', ''),
|
||||
}
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY', '')
|
||||
CACHE_CONFIG={
|
||||
'location' : os.environ.get('CACHE_LOCATION', ''),
|
||||
'backend' : os.environ.get('CACHE_BACKEND', ''),
|
||||
|
||||
ANYMAIL_CONFIG = {
|
||||
'MAILGUN_API_KEY': os.environ.get('MAILGUN_API_KEY', ''),
|
||||
'MAILGUN_SENDER_DOMAIN': os.environ.get('MAILGUN_SENDER_DOMAIN', '')
|
||||
}
|
||||
|
||||
DEFAULT_FROM_EMAIL = os.environ.get(
|
||||
'DEFAULT_FROM_EMAIL', 'notifications@forum.windmillapps.org'
|
||||
)
|
||||
SERVER_EMAIL = os.environ.get('SERVER_EMAIL', 'server@forum.windmillapps.org')
|
||||
ADMIN_EMAIL = os.environ.get('ADMIN_EMAIL', 'debug@nathanjchapman.com')
|
||||
|
||||
CACHE_CONFIG = {
|
||||
'location': os.environ.get('CACHE_LOCATION', ''),
|
||||
'backend': os.environ.get('CACHE_BACKEND', ''),
|
||||
}
|
||||
|
||||
@ -8,9 +8,17 @@ from .config import *
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
# Add Your Required Allow Host
|
||||
ALLOWED_HOSTS = []
|
||||
if not DEBUG:
|
||||
ALLOWED_HOSTS = [
|
||||
'forum.windmillapps.org',
|
||||
]
|
||||
else:
|
||||
ALLOWED_HOSTS = ['192.168.68.106', '127.0.0.1', 'localhost']
|
||||
|
||||
DEBUG = True
|
||||
INTERNAL_IPS = [
|
||||
'127.0.0.1',
|
||||
'localhost',
|
||||
]
|
||||
|
||||
|
||||
# Application definition
|
||||
@ -22,10 +30,12 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.sites',
|
||||
|
||||
# 3rd party
|
||||
'django_filters',
|
||||
'compressor',
|
||||
'anymail',
|
||||
|
||||
# Local
|
||||
'accounts.apps.AccountsConfig',
|
||||
@ -42,6 +52,7 @@ MIDDLEWARE = [
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'forum.middleware.TimezoneMiddleware',
|
||||
'django.contrib.sites.middleware.CurrentSiteMiddleware',
|
||||
|
||||
]
|
||||
|
||||
@ -140,3 +151,17 @@ STATICFILES_FINDERS = (
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
AUTH_USER_MODEL = 'accounts.User'
|
||||
LOGIN_REDIRECT_URL = reverse_lazy('core:topic-list')
|
||||
|
||||
# Email
|
||||
ANYMAIL = ANYMAIL_CONFIG
|
||||
EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend'
|
||||
ADMINS = (
|
||||
('Nathan Chapman', ADMIN_EMAIL),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
TEMPLATED_EMAIL_BACKEND = 'templated_email.backends.vanilla_django.TemplateBackend'
|
||||
|
||||
# Site ID
|
||||
SITE_ID = 1
|
||||
|
||||
12
src/templates/templated_email/notification.html.email
Normal file
12
src/templates/templated_email/notification.html.email
Normal file
@ -0,0 +1,12 @@
|
||||
{% load helpers %}
|
||||
|
||||
{% block subject %}The Forum: {{ subject }}{% endblock %}
|
||||
{% block html %}
|
||||
<h3>{{ author }} posted:</h3>
|
||||
|
||||
{{ message|markdown|safe|truncatechars_html:64 }}
|
||||
|
||||
<p>
|
||||
<a href="{{ url }}">View or reply</a>
|
||||
</p>
|
||||
{% endblock %}
|
||||
Loading…
x
Reference in New Issue
Block a user