From bee761e0c4962518a0c4531ed36bd8fff47dca6b Mon Sep 17 00:00:00 2001 From: j Date: Thu, 23 Jan 2025 14:03:55 +0530 Subject: [PATCH] subscribe to digest --- app/listmonk/utils.py | 8 +++-- app/listmonk/views.py | 54 +++++++++++++++++++++++++++++-- app/static/css/site.scss | 5 ++- app/templates/base.html | 3 ++ app/templates/register.html | 2 +- app/templates/subscribe.html | 21 ++++++++++++ app/templates/subscribe_form.html | 6 ++++ app/urls.py | 2 ++ 8 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 app/templates/subscribe.html create mode 100644 app/templates/subscribe_form.html 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 @@
{{ overlay.content | safe }} +
+ {% include "subscribe_form.html" %} +
{% if now %}
diff --git a/app/templates/register.html b/app/templates/register.html index dfbc644..d682fd4 100644 --- a/app/templates/register.html +++ b/app/templates/register.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {% block head %} -Login - {{ settings.SITENAME }} +Register - {{ settings.SITENAME }} {% endblock %} {% block content %}
diff --git a/app/templates/subscribe.html b/app/templates/subscribe.html new file mode 100644 index 0000000..79aa205 --- /dev/null +++ b/app/templates/subscribe.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% block head %} +Subscribe - {{ settings.SITENAME }} +{% endblock %} +{% block content %} + +{% endblock %} + + diff --git a/app/templates/subscribe_form.html b/app/templates/subscribe_form.html new file mode 100644 index 0000000..b7812f8 --- /dev/null +++ b/app/templates/subscribe_form.html @@ -0,0 +1,6 @@ +
+ {% csrf_token %} + + +
{{ error }}
+
diff --git a/app/urls.py b/app/urls.py index e58e187..2c8f6e6 100644 --- a/app/urls.py +++ b/app/urls.py @@ -20,6 +20,7 @@ from django.urls import path, re_path from .item import views as item_views from .user import views as user_views from .page import views as page_views +from .listmonk import views as email_views from . import views urlpatterns = [ @@ -31,6 +32,7 @@ urlpatterns = [ path('login/', user_views.login, name='login'), path('logout/', user_views.logout, name='logout'), path('register/', user_views.register, name='register'), + path('subscribe/', email_views.subscribe, name='subscribe'), path('comment/publish/', item_views.publish_comment, name='publish-comment'), path('comment/', item_views.comment, name='comment'), path('_--/', item_views.archive, name='archive'),