Skip to content

Commit

Permalink
Merge pull request #2655 from carpentries/feature/2649-new-email-ask-…
Browse files Browse the repository at this point in the history
…for-website

[Emails] New email Ask For Website
  • Loading branch information
pbanaszkiewicz committed Jun 9, 2024
2 parents 9f2302a + f84631a commit 0a5f031
Show file tree
Hide file tree
Showing 33 changed files with 1,592 additions and 5,272 deletions.
5 changes: 3 additions & 2 deletions amy/autoemails/management/commands/repeated_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,6 @@ class Command(BaseCommand):
"""

def handle(self, *args, **kwargs):
clear_scheduled_jobs() # This is necessary to prevent dupes
register_scheduled_jobs()
print("Management command disabled because the old email system is disabled.")
# clear_scheduled_jobs() # This is necessary to prevent dupes
# register_scheduled_jobs()
44 changes: 1 addition & 43 deletions amy/autoemails/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@
from rq_scheduler.utils import to_unix

from autoemails.tests.base import FakeRedisTestCaseMixin, dummy_fail_job, dummy_job
from autoemails.utils import (
check_status,
safe_next_or_default_url,
scheduled_execution_time,
)
from autoemails.utils import check_status, scheduled_execution_time


class TestScheduledExecutionTime(FakeRedisTestCaseMixin, TestCase):
Expand Down Expand Up @@ -169,41 +165,3 @@ def test_status_deferred_job(self):
# test
rv = check_status(job, self.scheduler)
self.assertEqual(rv, "deferred")


class TestSafeNextOrDefaultURL(TestCase):
def test_default_url_if_next_empty(self):
# Arrange
next_url = None
default_url = "/dashboard/"
# Act
url = safe_next_or_default_url(next_url, default_url)
# Assert
self.assertEqual(url, default_url)

def test_default_url_if_next_not_provided(self):
# Arrange
next_url = ""
default_url = "/dashboard/"
# Act
url = safe_next_or_default_url(next_url, default_url)
# Assert
self.assertEqual(url, default_url)

def test_default_url_if_next_not_safe(self):
# Arrange
next_url = "https://google.com"
default_url = "/dashboard/"
# Act
url = safe_next_or_default_url(next_url, default_url)
# Assert
self.assertEqual(url, default_url)

def test_next_url_if_next_safe(self):
# Arrange
next_url = "/admin/"
default_url = "/dashboard/"
# Act
url = safe_next_or_default_url(next_url, default_url)
# Assert
self.assertEqual(url, next_url)
12 changes: 1 addition & 11 deletions amy/autoemails/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from datetime import UTC
from typing import Optional, Union
from typing import Union

from django.conf import settings
from django.utils.http import url_has_allowed_host_and_scheme
from rq.exceptions import NoSuchJobError
from rq.job import Job
from rq_scheduler.utils import from_unix
Expand Down Expand Up @@ -59,11 +57,3 @@ def check_status(job: Union[str, Job], scheduler):
return job.get_status() or "scheduled"
else:
return job.get_status() or "cancelled"


def safe_next_or_default_url(next_url: Optional[str], default: str) -> str:
if next_url is not None and url_has_allowed_host_and_scheme(
next_url, settings.ALLOWED_HOSTS
):
return next_url
return default
3 changes: 2 additions & 1 deletion amy/autoemails/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@

from workshops.models import WorkshopRequest
from workshops.utils.access import admin_required
from workshops.utils.urls import safe_next_or_default_url

from .actions import GenericAction
from .forms import GenericEmailScheduleForm
from .models import EmailTemplate, Trigger
from .utils import check_status, safe_next_or_default_url, scheduled_execution_time
from .utils import check_status, scheduled_execution_time

logger = logging.getLogger("amy")
scheduler = django_rq.get_scheduler("default")
Expand Down
53 changes: 31 additions & 22 deletions amy/consents/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Any, Iterable
from typing import Any
from urllib.parse import unquote

from django.contrib import admin, messages
Expand All @@ -8,9 +8,7 @@
from django.http.response import HttpResponseRedirect
import django_rq

from autoemails.actions import NewConsentRequiredAction
from consents.models import Consent, Term, TermOption
from consents.util import send_consent_email

logger = logging.getLogger("amy")
scheduler = django_rq.get_scheduler("default")
Expand Down Expand Up @@ -127,27 +125,38 @@ class TermAdmin(ArchiveActionMixin, admin.ModelAdmin):
readonly_fields = ("rq_jobs", "archived_at")

def email_users_missing_consent(self, request, queryset):
if not self.check_terms_for_consent_email(request, queryset):
return
for term in queryset:
send_consent_email(request, term)
messages.error(
request,
"Error: action disabled because old email system is disabled.",
)
return
# if not self.check_terms_for_consent_email(request, queryset):
# return
# for term in queryset:
# send_consent_email(request, term)

def email_users_to_reconsent(self, request, queryset):
if not self.check_terms_for_consent_email(request, queryset):
return
Consent.archive_all_for_term(queryset)
for term in queryset:
send_consent_email(request, term)

def check_terms_for_consent_email(self, request, terms: Iterable[Term]) -> bool:
for term in terms:
if not NewConsentRequiredAction.check(term):
messages.error(
request,
f"Error: Selected term {term.slug} is not valid for emailing users",
)
return False
return True
messages.error(
request,
"Error: action disabled because old email system is disabled.",
)
return
# if not self.check_terms_for_consent_email(request, queryset):
# return
# Consent.archive_all_for_term(queryset)
# for term in queryset:
# send_consent_email(request, term)

# def check_terms_for_consent_email(self, request, terms: Iterable[Term]) -> bool:
# for term in terms:
# if not NewConsentRequiredAction.check(term):
# messages.error(
# request,
# f"Error: Selected term {term.slug} is not valid for emailing "
# "users",
# )
# return False
# return True

def warning_message(self, obj: Any) -> str:
message = super().warning_message(obj)
Expand Down
2 changes: 1 addition & 1 deletion amy/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from django_comments.models import Comment
from flags.sources import get_flags

from autoemails.utils import safe_next_or_default_url
from communityroles.models import CommunityRole
from consents.forms import TermBySlugsForm
from consents.models import Consent, Term, TermEnum
Expand Down Expand Up @@ -65,6 +64,7 @@
TrainingRequirement,
)
from workshops.utils.access import admin_required, login_required
from workshops.utils.urls import safe_next_or_default_url

# Terms shown on the instructor dashboard and can be updated by the user.
TERM_SLUGS = [TermEnum.MAY_CONTACT, TermEnum.PUBLIC_PROFILE, TermEnum.MAY_PUBLISH_NAME]
Expand Down
5 changes: 5 additions & 0 deletions amy/emails/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
from emails.actions.admin_signs_instructor_up_for_workshop import (
admin_signs_instructor_up_for_workshop_receiver,
)
from emails.actions.ask_for_website import (
ask_for_website_cancel_receiver,
ask_for_website_receiver,
ask_for_website_update_receiver,
)
from emails.actions.host_instructors_introduction import (
host_instructors_introduction_cancel_receiver,
host_instructors_introduction_receiver,
Expand Down
Loading

0 comments on commit 0a5f031

Please sign in to comment.