Skip to content

Commit d497bd8

Browse files
authored
CONDD-1085 User activity report (#2705)
* CONCD-1083 disable activity report for lower envs * CONCD-1084 Only count transcriptions for *different* assets in user activity report * CONCD-1083 use CONCORDIA_ENVIRONMENT setting (instead of looking at the domain * CONCD-1084 refactoring code * CONCD-1084 updated unit test * CONCD-1084 slight code cleanup * CONCD-1083 added an arg to enable testing * CONCD-1045 let's go with 12px, instead of 8
1 parent 42a5ef4 commit d497bd8

File tree

5 files changed

+64
-56
lines changed

5 files changed

+64
-56
lines changed

concordia/models.py

+19-17
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
ONE_MINUTE = datetime.timedelta(minutes=1)
3131
ONE_DAY = datetime.timedelta(days=1)
3232
ONE_DAY_AGO = timezone.now() - ONE_DAY
33-
THRESHOLD = 3
33+
THRESHOLD = 2
3434

3535

3636
def resource_file_upload_path(instance, filename):
@@ -96,20 +96,19 @@ def review_incidents(self, recent_accepts, recent_rejects, threshold=THRESHOLD):
9696
break
9797
return incidents
9898

99-
def transcribe_incidents(self, transcriptions, threshold=THRESHOLD):
100-
recent_transcriptions = transcriptions.filter(user=self).order_by("submitted")
101-
timestamps = recent_transcriptions.values_list("submitted", flat=True)
99+
def transcribe_incidents(self, transcriptions):
100+
transcriptions = transcriptions.filter(user=self).order_by("submitted")
102101
incidents = 0
103-
for i in range(len(timestamps)):
104-
count = 1
105-
for j in range(i + 1, len(timestamps)):
106-
if (timestamps[j] - timestamps[i]).seconds <= 60:
107-
count += 1
108-
if count == threshold:
109-
incidents += 1
110-
break
111-
else:
112-
break
102+
for transcription in transcriptions:
103+
start = transcription.submitted
104+
end = transcription.submitted + datetime.timedelta(minutes=1)
105+
if (
106+
transcriptions.filter(submitted__lte=end, submitted__gt=start)
107+
.exclude(asset=transcription.asset)
108+
.count()
109+
> 0
110+
):
111+
incidents += 1
113112
return incidents
114113

115114

@@ -907,11 +906,14 @@ def review_incidents(self, start=ONE_DAY_AGO):
907906

908907
return user_incident_count
909908

910-
def transcribe_incidents(self, start=ONE_DAY_AGO):
911-
user_incident_count = []
912-
transcriptions = self.get_queryset().filter(
909+
def recent_transcriptions(self, start=ONE_DAY_AGO):
910+
return self.get_queryset().filter(
913911
submitted__gte=start, user__is_superuser=False, user__is_staff=False
914912
)
913+
914+
def transcribe_incidents(self, start=ONE_DAY_AGO):
915+
user_incident_count = []
916+
transcriptions = self.recent_transcriptions(start)
915917
user_ids = (
916918
transcriptions.order_by("user")
917919
.distinct("user")

concordia/static/scss/base.scss

+4
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,10 @@ body .disabled > .page-link {
11981198
}
11991199
}
12001200

1201+
#banner-inner {
1202+
margin-right: 0.75rem;
1203+
}
1204+
12011205
#homepage-contribute-activities {
12021206
img {
12031207
@include media-breakpoint-down(sm) {

concordia/tasks.py

+32-30
Original file line numberDiff line numberDiff line change
@@ -1050,36 +1050,38 @@ def clear_sessions():
10501050

10511051

10521052
@celery_app.task(ignore_result=True)
1053-
def unusual_activity():
1053+
def unusual_activity(ignore_env=False):
10541054
"""
10551055
Locate pages that were improperly transcribed or reviewed.
10561056
"""
1057-
now = timezone.now()
1058-
site = Site.objects.get_current()
1059-
ONE_DAY_AGO = now - datetime.timedelta(days=1)
1060-
context = {
1061-
"title": "Unusual User Activity Report for "
1062-
+ now.strftime("%b %d %Y, %I:%M %p"),
1063-
"domain": "https://" + site.domain,
1064-
"transcriptions": Transcription.objects.transcribe_incidents(ONE_DAY_AGO),
1065-
"reviews": Transcription.objects.review_incidents(ONE_DAY_AGO),
1066-
}
1067-
1068-
text_body_template = loader.get_template("emails/unusual_activity.txt")
1069-
text_body_message = text_body_template.render(context)
1070-
1071-
html_body_template = loader.get_template("emails/unusual_activity.html")
1072-
html_body_message = html_body_template.render(context)
1073-
1074-
to_email = ["[email protected]"]
1075-
if settings.DEFAULT_TO_EMAIL:
1076-
to_email.append(settings.DEFAULT_TO_EMAIL)
1077-
message = EmailMultiAlternatives(
1078-
subject=context["title"],
1079-
body=text_body_message,
1080-
from_email=settings.DEFAULT_FROM_EMAIL,
1081-
to=to_email,
1082-
reply_to=[settings.DEFAULT_FROM_EMAIL],
1083-
)
1084-
message.attach_alternative(html_body_message, "text/html")
1085-
message.send()
1057+
# Don't bother running unless we're in the prod env
1058+
if settings.CONCORDIA_ENVIRONMENT == "production" or ignore_env:
1059+
site = Site.objects.get_current()
1060+
now = timezone.now()
1061+
ONE_DAY_AGO = now - datetime.timedelta(days=1)
1062+
context = {
1063+
"title": "Unusual User Activity Report for "
1064+
+ now.strftime("%b %d %Y, %I:%M %p"),
1065+
"domain": "https://" + site.domain,
1066+
"transcriptions": Transcription.objects.transcribe_incidents(ONE_DAY_AGO),
1067+
"reviews": Transcription.objects.review_incidents(ONE_DAY_AGO),
1068+
}
1069+
1070+
text_body_template = loader.get_template("emails/unusual_activity.txt")
1071+
text_body_message = text_body_template.render(context)
1072+
1073+
html_body_template = loader.get_template("emails/unusual_activity.html")
1074+
html_body_message = html_body_template.render(context)
1075+
1076+
to_email = ["[email protected]"]
1077+
if settings.DEFAULT_TO_EMAIL:
1078+
to_email.append(settings.DEFAULT_TO_EMAIL)
1079+
message = EmailMultiAlternatives(
1080+
subject=context["title"],
1081+
body=text_body_message,
1082+
from_email=settings.DEFAULT_FROM_EMAIL,
1083+
to=to_email,
1084+
reply_to=[settings.DEFAULT_FROM_EMAIL],
1085+
)
1086+
message.attach_alternative(html_body_message, "text/html")
1087+
message.send()

concordia/templates/home.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<div id="homepage-contribute-container" class="container my-4">
1717
<div class="px-default ms-md-3 mb-5">
1818
<div class="alert {{ banner.alert_class }} alert-dismissible w-100 d-flex" id="banner-{{ banner.slug }}" role="alert">
19-
<div class="d-flex flex-1 justify-content-center me-2">
19+
<div id="banner-inner" class="d-flex flex-1 justify-content-center">
2020
<a class="btn {{ banner.btn_class }}" href="{{ banner.link }}"{% if banner.open_in_new_window_tab %} target="_blank"{% endif %}>
2121
{{ banner.text }}
2222
</a>

concordia/tests/test_models.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def test_review_incidents(self):
205205
(
206206
self.transcription1.reviewed_by.id,
207207
self.transcription1.reviewed_by.username,
208-
1,
208+
2,
209209
4,
210210
),
211211
)
@@ -229,7 +229,7 @@ def test_review_incidents(self):
229229
(
230230
self.transcription1.reviewed_by.id,
231231
self.transcription1.reviewed_by.username,
232-
2,
232+
4,
233233
6,
234234
),
235235
)
@@ -247,37 +247,37 @@ def test_transcribe_incidents(self):
247247
self.assertNotIn(self.transcription1.user.id, users)
248248

249249
transcription3 = create_transcription(
250-
asset=self.transcription1.asset,
250+
asset=create_asset(slug="asset-two", item=self.transcription1.asset.item),
251251
user=self.transcription1.user,
252252
submitted=self.transcription1.submitted + timedelta(seconds=58),
253253
)
254254
transcription4 = create_transcription(
255-
asset=self.transcription1.asset,
255+
asset=create_asset(slug="asset-three", item=self.transcription1.asset.item),
256256
user=self.transcription1.user,
257257
submitted=transcription3.submitted + timedelta(minutes=1, seconds=1),
258258
)
259259
create_transcription(
260-
asset=self.transcription1.asset,
260+
asset=transcription4.asset,
261261
user=self.transcription1.user,
262262
submitted=transcription4.submitted + timedelta(seconds=59),
263263
)
264264
users = Transcription.objects.transcribe_incidents()
265265
self.assertEqual(len(users), 1)
266266
self.assertEqual(
267267
users[0],
268-
(self.transcription1.user.id, self.transcription1.user.username, 1, 5),
268+
(self.transcription1.user.id, self.transcription1.user.username, 2, 5),
269269
)
270270

271271
create_transcription(
272-
asset=self.transcription1.asset,
272+
asset=create_asset(slug="asset-five", item=self.transcription1.asset.item),
273273
user=self.transcription1.user,
274274
submitted=self.transcription1.submitted + timedelta(minutes=1, seconds=59),
275275
)
276276
users = Transcription.objects.transcribe_incidents()
277277
self.assertEqual(len(users), 1)
278278
self.assertEqual(
279279
users[0],
280-
(self.transcription1.user.id, self.transcription1.user.username, 2, 6),
280+
(self.transcription1.user.id, self.transcription1.user.username, 3, 6),
281281
)
282282

283283

0 commit comments

Comments
 (0)