Skip to content

Commit

Permalink
Merge pull request #2674 from carpentries/feature/2673
Browse files Browse the repository at this point in the history
[Emails] Extend REST API for events, scheduled emails, and fix too many logs
  • Loading branch information
pbanaszkiewicz committed Jul 15, 2024
2 parents 569f9b0 + c6506f8 commit bd53d31
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
20 changes: 17 additions & 3 deletions amy/api/v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Membership,
Organization,
Person,
TagQuerySet,
TrainingProgress,
TrainingRequirement,
)
Expand Down Expand Up @@ -52,9 +53,6 @@ class Meta:


class EventSerializer(serializers.ModelSerializer):
# start = serializers.DateField()
# end = serializers.DateField()

host = serializers.SlugRelatedField(read_only=True, slug_field="domain")
sponsor = serializers.SlugRelatedField(read_only=True, slug_field="domain")
membership = serializers.SlugRelatedField(read_only=True, slug_field="name")
Expand All @@ -74,6 +72,8 @@ class EventSerializer(serializers.ModelSerializer):

human_readable_date = serializers.CharField(read_only=True)
eligible_for_instructor_recruitment = serializers.BooleanField(read_only=True)
workshop_reports_link = serializers.CharField(read_only=True)
main_tag = serializers.SerializerMethodField()

class Meta:
model = Event
Expand Down Expand Up @@ -107,8 +107,22 @@ class Meta:
"public_status",
"human_readable_date",
"eligible_for_instructor_recruitment",
"workshop_reports_link",
"main_tag",
)

def get_main_tag(self, obj: Event) -> str | None:
try:
# Iterating like that is faster than using qs.filter(name__in=[...]).first()
# because it doesn't introduce new queries.
return next(
tag.name
for tag in obj.tags.all()
if tag.name in TagQuerySet.CARPENTRIES_TAG_NAMES
)
except (IndexError, AttributeError, StopIteration):
return None


class InstructorRecruitmentSignupSerializer(serializers.ModelSerializer):
recruitment = serializers.PrimaryKeyRelatedField(read_only=True)
Expand Down
13 changes: 13 additions & 0 deletions amy/api/v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,19 @@ def succeed(self, request, pk=None):
)
return Response(self.get_serializer(locked_email).data)

@action(detail=True, methods=["post"])
def cancel(self, request, pk=None):
email = self.get_object()
serializer = ScheduledEmailLogDetailsSerializer(data=request.data)

if not serializer.is_valid():
return Response(serializer.errors, status=400)

locked_email = EmailController.cancel_email(
email, serializer.validated_data["details"], request.user
)
return Response(self.get_serializer(locked_email).data)


class TrainingProgressViewSet(viewsets.ReadOnlyModelViewSet):
authentication_classes = (
Expand Down
5 changes: 3 additions & 2 deletions amy/emails/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ def change_state_with_log(

@staticmethod
def cancel_email(
scheduled_email: ScheduledEmail, author: Person | None = None
scheduled_email: ScheduledEmail,
details: str = "Email was cancelled",
author: Person | None = None,
) -> ScheduledEmail:
details = "Email was cancelled"
return EmailController.change_state_with_log(
scheduled_email, ScheduledEmailStatus.CANCELLED, details, author
)
Expand Down
2 changes: 1 addition & 1 deletion amy/emails/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def get_context_data(self, **kwargs):
ScheduledEmailLog.objects.select_related("author")
.filter(scheduled_email=self.object)
.order_by("-created_at")
)
)[0:500]
context["rendered_body"] = markdownify(self.object.body)

context["status_explanation"] = ScheduledEmailStatusExplanation[
Expand Down
2 changes: 1 addition & 1 deletion amy/templates/emails/scheduled_email_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ <h1>
</table>

<table class="table table-striped">
<caption><h2>History</h2> <small>(newest to oldest)</small></caption>
<caption><h2>History</h2> <small>(newest to oldest, last 500 entries)</small></caption>
<thead>
<tr>
<th>Timestamp</th>
Expand Down
12 changes: 9 additions & 3 deletions amy/workshops/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from workshops.signals import person_archived_signal
from workshops.utils.dates import human_daterange
from workshops.utils.emails import find_emails
from workshops.utils.reports import reports_link

# ------------------------------------------------------------

Expand Down Expand Up @@ -1074,12 +1075,14 @@ def archive(self) -> None:


class TagQuerySet(QuerySet):
CARPENTRIES_TAG_NAMES = ["SWC", "DC", "LC"]
MAIN_TAG_NAMES = ["SWC", "DC", "LC", "TTT", "ITT", "WiSE"]

def main_tags(self):
names = ["SWC", "DC", "LC", "TTT", "ITT", "WiSE"]
return self.filter(name__in=names)
return self.filter(name__in=self.MAIN_TAG_NAMES)

def carpentries(self):
return self.filter(name__in=["SWC", "DC", "LC"])
return self.filter(name__in=self.CARPENTRIES_TAG_NAMES)

def strings(self):
return self.values_list("name", flat=True)
Expand Down Expand Up @@ -1593,6 +1596,9 @@ def eligible_for_instructor_recruitment(self) -> bool:
)
)

def workshop_reports_link(self) -> str:
return reports_link(str(self.slug))

def clean(self):
"""Additional model validation."""

Expand Down

0 comments on commit bd53d31

Please sign in to comment.