Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add emaiing mechanism #151

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ src/magnify/static/magnify/
# Settings
local.py

# Npm
node_modules

# Email
src/magnify/apps/core/templates/email/

# Unit test / coverage reports
htmlcov/
.coverage
Expand Down
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ RUN DJANGO_CONFIGURATION=Build python manage.py collectstatic --noinput
# final image
RUN rdfind -makesymlinks true -followsymlinks true -makeresultsfile false ${MAGNIFY_STATIC_ROOT}

# ---- Email builder image ----
FROM node:18 as email-builder
RUN mkdir -p /app/magnify/apps/core/templates/email && \
mkdir -p /app/email
COPY ./src/email /app/email

WORKDIR /app/email

RUN yarn install --frozen-lockfile && \
yarn build-email

# ---- Core application image ----
FROM base as core

Expand Down Expand Up @@ -153,5 +164,8 @@ WORKDIR /app/sandbox
# Copy statics
COPY --from=link-collector ${MAGNIFY_STATIC_ROOT} ${MAGNIFY_STATIC_ROOT}

# Copy generated emails
COPY --from=email-builder /app/magnify/apps/core/templates/email /app/src/magnify/apps/core/templates/email

# The default command runs gunicorn WSGI server in the sandbox
CMD gunicorn -c /usr/local/etc/gunicorn/magnify.py wsgi:application
23 changes: 22 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ COMPOSE = DOCKER_USER=$(DOCKER_USER) DB_HOST=$(DB_HOST) DB_PORT=$(D
COMPOSE_RUN = $(COMPOSE) run --rm
COMPOSE_EXEC = $(COMPOSE) exec
COMPOSE_EXEC_APP = $(COMPOSE_EXEC) app
COMPOSE_EXEC_NODE = $(COMPOSE_EXEC) node
COMPOSE_EXEC_NODE = $(COMPOSE_EXEC) --workdir="/app/src/frontend" node
COMPOSE_RUN_APP = $(COMPOSE_RUN) app
COMPOSE_RUN_CROWDIN = $(COMPOSE_RUN) crowdin crowdin
COMPOSE_RUN_EMAIL = $(COMPOSE_RUN) --workdir="/app/src/email" node
COMPOSE_TEST_RUN = $(COMPOSE) run --rm -e DJANGO_CONFIGURATION=Test
COMPOSE_TEST_RUN_APP = $(COMPOSE_TEST_RUN) app

Expand All @@ -73,6 +74,8 @@ bootstrap: \
data/smedia/.keep \
data/static/.keep \
build \
install-email \
build-email \
run \
migrate \
superuser
Expand Down Expand Up @@ -251,6 +254,24 @@ i18n-generate-front: ## Extract strings to be translated from the code of all fr
@$(COMPOSE_RUN) -e HOME="/tmp" -w /app/src/frontend node yarn extract-translations
.PHONY: i18n-generate-front

# -- Email

build-email: ## Convert mjml files to html and text
@$(COMPOSE_RUN_EMAIL) yarn build-email
.PHONY: build-email

build-email-html-to-plain-text: ## Convert html files to text
@$(COMPOSE_RUN_EMAIL) yarn build-email-html-to-plain-text
.PHONY: build-email-html-to-plain-text

build-mjml-to-html: ## Convert mjml files to html and text
@$(COMPOSE_RUN_EMAIL) yarn build-mjml-to-html
.PHONY: build-mjml-to-html

install-email: ## mail-generator yarn install
@$(COMPOSE_RUN_EMAIL) yarn install
.PHONY: install-email

# -- Misc
clean: ## restore repository state as it was freshly cloned
git clean -idx
Expand Down
9 changes: 7 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ services:
- .:/app
depends_on:
- "${DB_HOST:-postgresql}"
- mailcatcher
stdin_open: true
tty: true

Expand Down Expand Up @@ -68,8 +69,7 @@ services:
- app-production

node:
image: node:16.15
working_dir: /app/src/frontend
image: node:18
user: "${DOCKER_USER:-1000}"
volumes:
- .:/app
Expand Down Expand Up @@ -117,6 +117,11 @@ services:
depends_on:
- redis-primary

mailcatcher:
image: sj26/mailcatcher:latest
ports:
- "1081:1080"

dockerize:
image: jwilder/dockerize
platform: linux/amd64
Expand Down
4 changes: 4 additions & 0 deletions env.d/development/common
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ JITSI_XMPP_DOMAIN="meet.jitsi"
JITSI_SECRET_KEY="ThisIsAnExampleKeyForDevPurposeOnly"
JITSI_APP_ID="app_id"
JITSI_TOKEN_EXPIRATION_SECONDS=300

# Email
EMAIL_HOST="mailcatcher"
EMAIL_FROM="[email protected]"
9 changes: 9 additions & 0 deletions sandbox/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,15 @@ class Base(MagnifyCoreConfigurationMixin, Configuration):
# when their preferred language, whatever it is, is unavailable
LANGUAGES = (("en", _("English")), ("fr", _("French")))

# Email
EMAIL_BACKEND = values.Value("django.core.mail.backends.smtp.EmailBackend")
EMAIL_HOST = values.Value(None)
EMAIL_HOST_USER = values.Value(None)
EMAIL_HOST_PASSWORD = values.Value(None)
EMAIL_PORT = values.PositiveIntegerValue(1025)
EMAIL_USE_TLS = values.BooleanValue(False)
EMAIL_FROM = values.Value(None)

# Logging
LOGGING = {
"version": 1,
Expand Down
8 changes: 7 additions & 1 deletion sandbox/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.views.static import serve

from magnify.apps.core.urls import urlpatterns as core_urlpatterns
from magnify.apps.core.views import SignupEmailDebugView

# For now, we use URLPathVersioning to be consistent with fonzie. Fonzie uses it
# because DRF OpenAPI only supports URLPathVersioning for now.
Expand All @@ -35,7 +36,12 @@
r"media/<path:path>",
serve,
{"document_root": settings.MEDIA_ROOT, "show_indexes": True},
)
),
path(
r"__debug__/email/signup.<str:extension>",
SignupEmailDebugView.as_view(),
name="debug_email_signup",
),
]
+ staticfiles_urlpatterns()
+ urlpatterns
Expand Down
12 changes: 12 additions & 0 deletions src/email/bin/html-to-plain-text
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -eo pipefail
# Run html-to-text to convert all html files to text files
DIR_MAILS="../magnify/apps/core/templates/email"

if [ ! -d "${DIR_MAILS}" ]; then
mkdir -p "${DIR_MAILS}";
fi

for file in "${DIR_MAILS}"/*.html;
# we don't want unexpected words wrap, we set it to 600 chars
do html-to-text --wordwrap=600 < "$file" > "${file%.html}".txt; done;
9 changes: 9 additions & 0 deletions src/email/bin/mjml-to-html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

# Run mjml command to convert all mjml templates to html files
DIR_MAILS="../magnify/apps/core/templates/email"

if [ ! -d "${DIR_MAILS}" ]; then
mkdir -p "${DIR_MAILS}";
fi
mjml mjml/*.mjml -o "${DIR_MAILS}";
9 changes: 9 additions & 0 deletions src/email/mjml/partial/footer.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<mj-include path="./course_greetings.mjml" />

<mj-section background-color="#000000" padding="15px">
<mj-column vertical-align="top" width="100%">
<mj-text align="center" color="#FFFFFF" font-size="12px" padding="5px 25px">
{% blocktrans %}This email has been sent to {{ user_email }} by {{ site_name }}{% endblocktrans %}
</mj-text>
</mj-column>
</mj-section>
7 changes: 7 additions & 0 deletions src/email/mjml/partial/header.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<mj-head>
<mj-attributes>
<mj-all padding="0px"></mj-all>
<mj-class name="preheader" color="#000000" font-family="Helvetica, Arial, sans-serif" padding="0px"></mj-class>
</mj-attributes>
<mj-style inline="inline">a { text-decoration: none; color: inherit; }</mj-style>
</mj-head>
4 changes: 4 additions & 0 deletions src/email/mjml/partial/hello.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<mj-text align="center" font-size="18px" padding="20px 25px">
{% if user_name %} {% trans "Hello" %} {{user_name}}, {% else %}
{% trans "Hello," %} {% endif %}
</mj-text>
22 changes: 22 additions & 0 deletions src/email/mjml/signup.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<mjml>
<mj-include path="./partial/header.mjml" />
<mj-body background-color="#FFFFFF">
<mj-section background-color="#2a5cab" padding="10px 0">
<mj-column background-color="#008000">
<mj-text>{% load i18n %}</mj-text>
<mj-text align="center" color="#FFFFFF" font-size="15px" padding="8px 8px">
{% trans "Thank you for signing up" %}
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#FFFFFF" padding="0px 50px">
<mj-column width="100%">
<mj-include path="./partial/hello.mjml" />
<mj-text align="center" font-size="18px" padding="10px 50px">
{% trans "Thank you for signing up." %}
</mj-text>
</mj-column>
</mj-section>
<mj-include path="./partial/footer.mjml" />
</mj-body>
</mjml>
21 changes: 21 additions & 0 deletions src/email/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "mjml",
"version": "1.0.0",
"description": "An util to generate html and text templates from mjml templates",
"dependencies": {
"html-to-text": "8.2.1",
"mjml": "4.13.0"
},
"private": true,
"scripts": {
"build-mjml-to-html": "./bin/mjml-to-html",
"build-email-html-to-plain-text": "./bin/html-to-plain-text",
"build-email": "yarn build-mjml-to-html; yarn build-email-html-to-plain-text;"
},
"volta": {
"node": "18.11.0"
},
"repository": "https://github.com/openfun/jitsi-magnify",
"author": "France Université Numérique",
"license": "MIT"
}
Loading