Skip to content

Commit

Permalink
shared drive notification templating
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeseibel committed May 8, 2024
1 parent 42daf34 commit d4d5a11
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 57 deletions.
20 changes: 20 additions & 0 deletions endorsement/migrations/0029_auto_20240508_1240.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.2.25 on 2024-05-08 19:40

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('endorsement', '0028_auto_20240506_1259'),
]

operations = [
migrations.RemoveField(
model_name='shareddriverecord',
name='acceptance',
),
migrations.DeleteModel(
name='SharedDriveAcceptance',
),
]
26 changes: 26 additions & 0 deletions endorsement/migrations/0030_shareddriveacceptance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 3.2.25 on 2024-05-08 19:42

from django.db import migrations, models
import django.db.models.deletion
import django_prometheus.models


class Migration(migrations.Migration):

dependencies = [
('endorsement', '0029_auto_20240508_1240'),
]

operations = [
migrations.CreateModel(
name='SharedDriveAcceptance',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('action', models.SmallIntegerField(choices=[(0, 'Accept'), (1, 'Revoke')], default=0)),
('datetime_accepted', models.DateTimeField(auto_now_add=True)),
('member', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='endorsement.member')),
('shared_drive_record', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='endorsement.shareddriverecord')),
],
bases=(django_prometheus.models.ExportModelOperationsMixin('shared_drive_acceptance'), models.Model),
),
]
82 changes: 47 additions & 35 deletions endorsement/models/shared_drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,37 +114,6 @@ def json_data(self):

def __str__(self):
return json.dumps(self.json_data())


class SharedDriveAcceptance(
ExportModelOperationsMixin('shared_drive_acceptance'), models.Model):
"""
SharedDriveAcceptance model records each instance of a shared drive
record being accepted or revoked by a shared drive manager.
"""
ACCEPT = 0
REVOKE = 1

ACCEPTANCE_ACTION_CHOICES = (
(ACCEPT, "Accept"),
(REVOKE, "Revoke"))

member = models.ForeignKey(Member, on_delete=models.PROTECT)
action = models.SmallIntegerField(
default=ACCEPT, choices=ACCEPTANCE_ACTION_CHOICES)
datetime_accepted = models.DateTimeField(auto_now_add=True)

def json_data(self):
return {
"member": self.member.json_data(),
"action": self.ACCEPTANCE_ACTION_CHOICES[self.action][1],
"datetime_accepted": datetime_to_str(self.datetime_accepted)
}

def __str__(self):
return json.dumps(self.json_data())


class SharedDriveRecordManager(models.Manager):
def get_member_drives(self, member_netid, drive_id=None):
parms = {
Expand Down Expand Up @@ -183,7 +152,6 @@ class SharedDriveRecord(
datetime_notice_4_emailed = models.DateTimeField(null=True)
datetime_renewed = models.DateTimeField(null=True)
datetime_expired = models.DateTimeField(null=True)
acceptance = models.ManyToManyField(SharedDriveAcceptance, blank=True)
is_deleted = models.BooleanField(null=True)

objects = SharedDriveRecordManager()
Expand All @@ -210,20 +178,31 @@ def itbill_form_url(self):
f"&remote_key={self.subscription.key_remote}"
f"&shared_drive={self.shared_drive.drive_name}")

@property
def acceptor(self):
if not self.datetime_accepted:
return None

return SharedDriveAcceptance.objects.get(
shared_drive_record=self,
datetime_accepted=self.datetime_accepted)

def get_acceptance(self):
return SharedDriveAcceptance.objects.filter(
shared_drive_record=self)

def set_acceptance(self, member_netid, accept=True):
member = Member.objects.get_member(member_netid)
action = SharedDriveAcceptance.ACCEPT if (
accept) else SharedDriveAcceptance.REVOKE

acceptance = SharedDriveAcceptance.objects.create(
member=member, action=action)
self.acceptance.add(acceptance)
shared_drive_record=self, member=member, action=action)

if accept:
self.datetime_accepted = acceptance.datetime_accepted
else:
self.datetime_expired = acceptance.datetime_accepted
self.is_deleted = True

self.save()

Expand Down Expand Up @@ -251,6 +230,7 @@ def json_data(self):
"datetime_notice_4_emailed": datetime_to_str(
self.datetime_notice_4_emailed),
"datetime_accepted": datetime_to_str(self.datetime_accepted),
"acceptance": [a.json_data() for a in self.get_acceptance()],
"datetime_renewed": datetime_to_str(self.datetime_renewed),
"datetime_expired": datetime_to_str(self.datetime_expired),
"datetime_expiration": datetime_to_str(self.expiration_date),
Expand All @@ -259,3 +239,35 @@ def json_data(self):

def __str__(self):
return json.dumps(self.json_data())


class SharedDriveAcceptance(
ExportModelOperationsMixin('shared_drive_acceptance'), models.Model):
"""
SharedDriveAcceptance model records each instance of a shared drive
record being accepted or revoked by a shared drive manager.
"""
ACCEPT = 0
REVOKE = 1

ACCEPTANCE_ACTION_CHOICES = (
(ACCEPT, "Accept"),
(REVOKE, "Revoke"))

shared_drive_record = models.ForeignKey(
SharedDriveRecord, on_delete=models.PROTECT)
member = models.ForeignKey(
Member, on_delete=models.PROTECT)
action = models.SmallIntegerField(
default=ACCEPT, choices=ACCEPTANCE_ACTION_CHOICES)
datetime_accepted = models.DateTimeField(auto_now_add=True)

def json_data(self):
return {
"member": self.member.json_data(),
"action": self.ACCEPTANCE_ACTION_CHOICES[self.action][1],
"datetime_accepted": datetime_to_str(self.datetime_accepted)
}

def __str__(self):
return json.dumps(self.json_data())
3 changes: 2 additions & 1 deletion endorsement/notifications/shared_drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ def _email_template(template_name):
return "email/shared_drive/{}".format(template_name)


def _create_expire_notice_message(notice_level, lifetime, drive):
def _create_notification_expiration_notice(notice_level, lifetime, drive):
context = {
'drive': drive,
'acceptor': drive.acceptor,
'lifetime': lifetime,
'notice_time': expiration_warning(notice_level)
}
Expand Down
8 changes: 5 additions & 3 deletions endorsement/templates/email/shared_drive/notice_warning.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
Hello,
<p>
You are receiving this email because you are identified as a Manager of the
Google Shared Drive "{{drive.shared_drive.drive_name}}".
You are receiving this email because you are identified as
{%if drive.shared_drive.members.all.count > 0 %}one of {{ drive.shared_drive.members.all.count }}{% else %}the{% endif %} UW manager{{drive.shared_drive.members.all.count|pluralize}} of the Google Shared Drive named
"{{drive.shared_drive.drive_name}}".
</p>
<p>
To maintain service, Google Shared Drive use must be actively
acknowledged every {{lifetime}} days. The drive "{{drive.shared_drive.drive_name}}"
is within {{notice_time}} days of its required renewal.
was last acknowledged by the netid {{acceptor.member.netid}} on {{acceptor.datetime_accepted|date:"M j, Y"}},
and is now within {{notice_time}} days of its required renewal.
</p>
<p>
To log in to the Provisioning Request Tool (PRT) and renew the expiring shared drive visit:
Expand Down
10 changes: 5 additions & 5 deletions endorsement/templates/email/shared_drive/notice_warning.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Hello,

You are receiving this email because you are identified as a Manager of the
Google Shared Drive "{{drive.shared_drive.drive_name}}".
You are receiving this email because you are identified as {%if drive.shared_drive.members.all.count > 0 %}one of {{ drive.shared_drive.members.all.count }}{% else %}the{% endif %} UW manager{{drive.shared_drive.members.all.count|pluralize}}
of the Google Shared Drive named "{{drive.shared_drive.drive_name}}".

To maintain service, Google Shared Drive use must be actively
acknowledged every {{lifetime}} days. The drive "{{drive.shared_drive.drive_name}}"
is within {{notice_time}} days of its required renewal.
To maintain service, Google Shared Drive use must be actively acknowledged
every {{lifetime}} days. The drive "{{drive.shared_drive.drive_name}}" was last acknowledged by
the netid {{acceptor.member.netid}} on {{acceptor.datetime_accepted|date:"M j, Y"}}, and is now within {{notice_time}} days of its required renewal.

To log in to the Provisioning Request Tool (PRT) and renew the expiring shared drive visit:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Hello,
<p>
You are receiving this email because you are identified as a Manager of the
Google Shared Drive "{{drive.shared_drive.drive_name}}".
You are receiving this email because you are identified as
{%if drive.shared_drive.members.all.count > 0 %}one of {{ drive.shared_drive.members.all.count }}{% else %}the{% endif %} UW manager{{drive.shared_drive.members.all.count|pluralize}} of the Google Shared Drive named
"{{drive.shared_drive.drive_name}}".
</p>
<p>
To maintain service, Google Shared Drive use must be actively acknowledged
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Hello,

You are receiving this email because you are identified as a Manager of the
Google Shared Drive "{{drive.shared_drive.drive_name}}".
You are receiving this email because you are identified as {%if drive.shared_drive.members.all.count > 0 %}one of {{ drive.shared_drive.members.all.count }}{% else %}the{% endif %} UW manager{{drive.shared_drive.members.all.count|pluralize}}
of the Google Shared Drive named "{{drive.shared_drive.drive_name}}".

To maintain service, Google Shared Drive use must be actively acknowledged
every {{lifetime}} days. The drive "{{drive.shared_drive.drive_name}}"
Expand Down
13 changes: 4 additions & 9 deletions endorsement/views/api/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from endorsement.notifications.access import (
_create_accessor_message)
from endorsement.notifications.shared_drive import (
_create_expire_notice_message)
_create_notification_expiration_notice)
from endorsement.dao.accessors import get_accessor_email
from datetime import datetime, timedelta
import re
Expand Down Expand Up @@ -176,16 +176,11 @@ def _shared_drive_notification(self, request):
if m:
warning_level = int(m.group(1))

shared_drive = SharedDrive(
drive_id='1234567890abcdef1234567890abcdef',
drive_name='My shared drive',
drive_quota=SharedDriveQuota.objects.get(quota_limit=200),
drive_usage=200)

record = SharedDriveRecord(shared_drive=shared_drive)
record = SharedDriveRecord.objects.filter(
is_deleted__isnull=True).first()

if warning_level:
subject, text, html = _create_expire_notice_message(
subject, text, html = _create_notification_expiration_notice(
warning_level, 365, record)
else:
return self.error_response(400, "Unknown notification.")
Expand Down

0 comments on commit d4d5a11

Please sign in to comment.