From 7a2dda5f1d2bed7aebc3095979c1be15dde557b6 Mon Sep 17 00:00:00 2001 From: John Tordoff <> Date: Wed, 16 Oct 2024 14:07:45 -0400 Subject: [PATCH] add monthly active stat to users table --- api/institutions/serializers.py | 1 + api/institutions/views.py | 1 + osf/metrics/reporters/institutional_users.py | 29 +++++++++++++++++++ osf/metrics/reports.py | 1 + .../test_institutional_users_reporter.py | 1 + 5 files changed, 33 insertions(+) diff --git a/api/institutions/serializers.py b/api/institutions/serializers.py index 29c7c8b380a..38d652f01e5 100644 --- a/api/institutions/serializers.py +++ b/api/institutions/serializers.py @@ -334,6 +334,7 @@ class Meta: department = ser.CharField(read_only=True, source='department_name') orcid_id = ser.CharField(read_only=True) month_last_login = YearmonthField(read_only=True) + month_activity = YearmonthField(read_only=True) account_creation_date = YearmonthField(read_only=True) public_projects = ser.IntegerField(read_only=True, source='public_project_count') diff --git a/api/institutions/views.py b/api/institutions/views.py index c13cb1f8d74..300fa998adf 100644 --- a/api/institutions/views.py +++ b/api/institutions/views.py @@ -561,6 +561,7 @@ class _NewInstitutionUserMetricsList(InstitutionMixin, ElasticsearchListView): 'user_name', 'department', 'month_last_login', + 'month_activity', 'account_creation_date', 'public_projects', 'private_projects', diff --git a/osf/metrics/reporters/institutional_users.py b/osf/metrics/reporters/institutional_users.py index 98e13003387..04a13144a2c 100644 --- a/osf/metrics/reporters/institutional_users.py +++ b/osf/metrics/reporters/institutional_users.py @@ -52,6 +52,7 @@ def __post_init__(self): if self.user.date_last_login is not None else None ), + month_activity=self._get_last_active(self.user), account_creation_date=YearMonth.from_date(self.user.created), orcid_id=self.user.get_verified_external_id('ORCID', verified_only=True), public_project_count=self._public_project_queryset().count(), @@ -140,3 +141,31 @@ def _storage_byte_count(self): purged__isnull=True, basefilenode__in=self._public_osfstorage_file_queryset(), ).aggregate(storage_bytes=Sum('size', default=0))['storage_bytes'] + + def _get_last_active(self, user): + start_date = self.yearmonth.target_month() + end_date = self.yearmonth.next_month() + + # Fetch NodeLogs for the user within the date range + node_logs = user.logs.filter( + created__gte=start_date, + created__lt=end_date, + ).order_by('-created') + + # Get preprints associated with the user and institution + # Fetch PreprintLogs for the user within the date range + preprint_logs = user.preprint_logs.filter( + created__gte=start_date, + created__lt=end_date, + ).order_by('-created') + + # Get the latest activity date from NodeLogs and PreprintLogs + latest_node_log_date = node_logs.first().created if node_logs.exists() else None + latest_preprint_log_date = preprint_logs.first().created if preprint_logs.exists() else None + + # Determine the most recent activity date + latest_activity_date = max([latest_node_log_date, latest_preprint_log_date]) + if latest_activity_date: + return YearMonth.from_date(latest_activity_date) + else: + return None \ No newline at end of file diff --git a/osf/metrics/reports.py b/osf/metrics/reports.py index 08d14867ae0..0da64d15ac1 100644 --- a/osf/metrics/reports.py +++ b/osf/metrics/reports.py @@ -260,6 +260,7 @@ class InstitutionalUserReport(MonthlyReport): user_name = metrics.Keyword() department_name = metrics.Keyword() month_last_login = YearmonthField() + month_activity = YearmonthField() account_creation_date = YearmonthField() orcid_id = metrics.Keyword() # counts: diff --git a/osf_tests/metrics/reporters/test_institutional_users_reporter.py b/osf_tests/metrics/reporters/test_institutional_users_reporter.py index 8fbb873083f..2912a6a6d61 100644 --- a/osf_tests/metrics/reporters/test_institutional_users_reporter.py +++ b/osf_tests/metrics/reporters/test_institutional_users_reporter.py @@ -52,6 +52,7 @@ def _assert_report_matches_setup(self, report: InstitutionalUserReport, setup: _ self.assertEqual(report.user_name, setup.user.fullname) self.assertEqual(report.department_name, setup.department_name) self.assertEqual(report.month_last_login, YearMonth.from_date(setup.user.date_last_login)) + self.assertEqual(report.month_activity, YearMonth.from_date(setup.user.month_activity)) self.assertEqual(report.account_creation_date, YearMonth.from_date(setup.user.created)) self.assertEqual(report.orcid_id, setup.orcid_id) # counts (NOTE: report.public_file_count and report.storage_byte_count tested separately)