diff --git a/app/listmonk/utils.py b/app/listmonk/utils.py index 401debc..9d71547 100644 --- a/app/listmonk/utils.py +++ b/app/listmonk/utils.py @@ -57,12 +57,16 @@ def email2name(email): name = " ".join([part.capitalize() for part in name.split(" ")]) return name +def is_subscribed(email): + url = settings.LISTMONK_API + 'subscribers' + auth = (settings.LISTMONK_USER, settings.LISTMONK_PASSWORD) + exists = url + '?' + "list_id=&query=email='%s'&page=1&order_by=id&order=desc" % email + return bool(len(requests.get(exists, auth=auth).json()['data']['results'])) def add_email(email): url = settings.LISTMONK_API + 'subscribers' auth = (settings.LISTMONK_USER, settings.LISTMONK_PASSWORD) - exists = url + '?' + "list_id=&query=email='%s'&page=1&order_by=id&order=desc" % email - if not len(requests.get(exists, auth=auth).json()['data']['results']): + if not is_subscribed(email): data = { "email": email, "name": email2name(email), diff --git a/app/listmonk/views.py b/app/listmonk/views.py index 1fee8a9..767e84a 100644 --- a/app/listmonk/views.py +++ b/app/listmonk/views.py @@ -1,13 +1,26 @@ +import json + +from brake.decorators import ratelimit + from django.conf import settings +from django.contrib.auth import get_user_model from django.db.models.functions import ExtractWeek, ExtractYear -from django.shortcuts import render +from django.shortcuts import redirect, render from django.template.loader import render_to_string from django.utils import timezone from django.utils.timezone import datetime, timedelta - +from django.core.validators import validate_email +import django.contrib.auth from ..item import models from ..item.views import get_weeks, format_week, get_monday, get_byline +from ..item.utils import render_to_json +from ..utils import default_context + +from . import utils + + +User = get_user_model() def week(year, month, day): @@ -32,3 +45,40 @@ def week(year, month, day): context['week_link'] = settings.URL + '/_' + monday context['items'] = archive_week return render_to_string("weekly_email.html", context) + + +@ratelimit(method="POST", block=True, rate="5/m") +def subscribe(request): + context = default_context(request) + response = {} + request_type = 'json' + if request.method == "POST": + if "email" in request.POST: + data = request.POST + request_type = 'html' + else: + data = json.loads(request.body) + if not response: + try: + validate_email(data["email"]) + except ValidationError as e: + response['error'] = 'please enter a valid email address.' + else: + try: + if utils.is_subscribed(data["email"]): + pass + elif not utils.add_email(data["email"]): + response['error'] = 'failed to add email to weekly digest.' + except: + response['error'] = 'failed to add your email, please try again later.' + + if request_type == 'html': + if 'error' in response: + context['error'] = response['error'] + return render(request, 'subscribe.html', context) + else: + context["subscribed"] = True + return render(request, 'subscribe.html', context) + return render_to_json(response) + else: + return render(request, 'subscribe.html', context) diff --git a/app/static/css/site.scss b/app/static/css/site.scss index 86bde26..c40fecc 100644 --- a/app/static/css/site.scss +++ b/app/static/css/site.scss @@ -250,7 +250,7 @@ nav.overlay { } -.login, .register { +.login, .register, .subscribe, .digest{ margin-top: 16px; margin-left: 24px; textarea, @@ -276,6 +276,9 @@ nav.overlay { border: solid 1px lightgreen; cursor: pointer; } + .error { + color: red; + } } .content { diff --git a/app/templates/base.html b/app/templates/base.html index 5798d81..9d4dcaa 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -39,6 +39,9 @@