From 02259d11b45654de683d8aa3e659efba6cf0ade4 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Sun, 11 Dec 2022 17:54:32 -0500 Subject: [PATCH 01/18] feat: add SurveyReportUpload and add send report method --- lms/envs/production.py | 2 +- lms/envs/test.py | 1 + openedx/features/survey_report/api.py | 47 ++++++++++++++++++- .../management/commands/generate_report.py | 25 +++++++--- openedx/features/survey_report/models.py | 29 ++++++++++++ 5 files changed, 96 insertions(+), 8 deletions(-) diff --git a/lms/envs/production.py b/lms/envs/production.py index 9352be3bb045..924f0171ea0b 100644 --- a/lms/envs/production.py +++ b/lms/envs/production.py @@ -1083,6 +1083,6 @@ def get_env_setting(setting): ############## Settings for survey report ############## SURVEY_REPORT_EXTRA_DATA = ENV_TOKENS.get('SURVEY_REPORT_EXTRA_DATA', {}) - +SURVEY_REPORT_ENDPOINT = ENV_TOKENS.get('SURVEY_REPORT_ENDPOINT', "") AVAILABLE_DISCUSSION_TOURS = ENV_TOKENS.get('AVAILABLE_DISCUSSION_TOURS', []) diff --git a/lms/envs/test.py b/lms/envs/test.py index 634c2bb627d4..b4036aee73ee 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -674,3 +674,4 @@ ############## Settings for survey report ############## SURVEY_REPORT_EXTRA_DATA = {} +SURVEY_REPORT_ENDPOINT = "https://example.com/survey_report" diff --git a/openedx/features/survey_report/api.py b/openedx/features/survey_report/api.py index 7cd8633b2f70..71d0b0e26187 100644 --- a/openedx/features/survey_report/api.py +++ b/openedx/features/survey_report/api.py @@ -1,10 +1,12 @@ """ Contains the logic to manage survey report model. """ +import requests from django.conf import settings +from django.forms.models import model_to_dict -from openedx.features.survey_report.models import SurveyReport +from openedx.features.survey_report.models import SurveyReport, SurveyReportUpload from openedx.features.survey_report.queries import ( get_course_enrollments, get_recently_active_users, @@ -49,6 +51,49 @@ def generate_report() -> None: except (Exception, ) as update_report_error: update_report(survey_report.id, {"state": SURVEY_REPORT_ERROR}) raise Exception(update_report_error) from update_report_error + return survey_report.id + + +def send_report(report_id: int) -> None: + """ + Send a report to Openedx endpoint and save the response in the SurveyReportUpload model. + + endpoint: The value of the setting SURVEY_REPORT_ENDPOINT + + content_type: JSON + + payload: + - courses_offered: Total number of active unique courses. + - learner: Recently active users with login in some weeks. + - registered_learners: Total number of users ever registered in the platform. + - enrollments: Total number of active enrollments in the platform. + - generated_certificates: Total number of generated certificates. + - extra_data: Extra information that will be saved in the report, E.g: site_name, openedx-release. + - created_at: Date when the report was generated, this date will send with format '%m-%d-%Y %H:%M:%S' + """ + report = SurveyReport.objects.get(id=report_id) + + fields = [ + "courses_offered", + "learners", + "registered_learners", + "generated_certificates", + "enrollments", + ] + + data = model_to_dict(report, fields=fields) + data["extra_data"] = report.extra_data + data["created_at"] = report.created_at.strftime("%m-%d-%Y %H:%M:%S") + + request = requests.post(settings.SURVEY_REPORT_ENDPOINT, json=data) + + request.raise_for_status() + + SurveyReportUpload.objects.create( + report = report, + status = request.status_code, + request_details = request.content + ) def update_report(survey_report_id: int, data: dict) -> None: diff --git a/openedx/features/survey_report/management/commands/generate_report.py b/openedx/features/survey_report/management/commands/generate_report.py index 5c8978e4c23b..7fcf6ea7852e 100644 --- a/openedx/features/survey_report/management/commands/generate_report.py +++ b/openedx/features/survey_report/management/commands/generate_report.py @@ -4,7 +4,7 @@ from django.core.management.base import BaseCommand, CommandError -from openedx.features.survey_report.api import generate_report +from openedx.features.survey_report.api import generate_report, send_report class Command(BaseCommand): @@ -22,12 +22,25 @@ class Command(BaseCommand): learners ever registered, and generated certificates. """ - def handle(self, *_args, **_options): + def add_arguments(self, parser): + parser.add_argument( + '--no-send', + action='store_true', + help='Not send the report after generated.' + ) + + def handle(self, *_args, **options): try: - generate_report() + report = generate_report() + self.stdout.write(self.style.SUCCESS('Survey report has been generated successfully.')) except Exception as error: raise CommandError(f'An error has occurred while survey report was generating. {error}') from error - self.stdout.write( - self.style.SUCCESS('Survey report has been generated successfully.') - ) + if not options['no_send']: + try: + send_report(report_id=report) + self.stdout.write(self.style.SUCCESS('Survey report has been sent successfully.')) + except Exception as send_error: + raise CommandError( + f'An error has occurred while survey report was sending. {send_error}' + ) from send_error diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index ebcf4195c820..d9487a2b2ef2 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -4,6 +4,7 @@ from django.db import models from jsonfield import JSONField +from requests.models import Response SURVEY_REPORT_PROCESSING = 'processing' SURVEY_REPORT_GENERATED = 'generated' @@ -58,3 +59,31 @@ class SurveyReport(models.Model): class Meta: ordering = ["-created_at"] get_latest_by = 'created_at' + + +class SurveyReportUpload(models.Model): + """ + This models stores information about send request of a survey report. + + .. no_pii: + + fields: + - sent_at: Date when the report was sent. + - report: The report that was sent. + - status: Request status code. + - request_details: Information about the send request. + """ + sent_at = models.DateTimeField(auto_now=True, help_text="Date when the report was sent.") + report = models.ForeignKey(SurveyReport, on_delete=models.CASCADE, help_text="The report that was sent.") + status = models.IntegerField(help_text="Request status code.") + request_details = models.CharField( + max_length=255, + null=True, + blank=True, + help_text="Information about the send request." + ) + + def is_uploaded(self) -> bool: + response = Response() + response.status_code = self.status + return response.ok From 50703ad1d7d05fafae3d874207397710f37cdb62 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 07:37:18 -0500 Subject: [PATCH 02/18] docs: Update openedx/features/survey_report/management/commands/generate_report.py Co-authored-by: Maria Grimaldi --- .../survey_report/management/commands/generate_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/features/survey_report/management/commands/generate_report.py b/openedx/features/survey_report/management/commands/generate_report.py index 7fcf6ea7852e..78a718ced200 100644 --- a/openedx/features/survey_report/management/commands/generate_report.py +++ b/openedx/features/survey_report/management/commands/generate_report.py @@ -26,7 +26,7 @@ def add_arguments(self, parser): parser.add_argument( '--no-send', action='store_true', - help='Not send the report after generated.' + help='Do not send the report after generated.' ) def handle(self, *_args, **options): From a266eb15983d7c02804f69a88b7e8c7d4ba54ab5 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 07:37:51 -0500 Subject: [PATCH 03/18] docs: Update openedx/features/survey_report/models.py Co-authored-by: Maria Grimaldi --- openedx/features/survey_report/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index d9487a2b2ef2..91824b4235a6 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -63,7 +63,7 @@ class Meta: class SurveyReportUpload(models.Model): """ - This models stores information about send request of a survey report. + This model stores the result of the POST request made to an external service after generating a survey report. .. no_pii: From 2774888f5db5bbe70bdb8f11d7700bac43eeb59f Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 07:43:00 -0500 Subject: [PATCH 04/18] refactor: Update openedx/features/survey_report/models.py Co-authored-by: Maria Grimaldi --- openedx/features/survey_report/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index 91824b4235a6..1d7a5a704b84 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -75,7 +75,7 @@ class SurveyReportUpload(models.Model): """ sent_at = models.DateTimeField(auto_now=True, help_text="Date when the report was sent.") report = models.ForeignKey(SurveyReport, on_delete=models.CASCADE, help_text="The report that was sent.") - status = models.IntegerField(help_text="Request status code.") + status_code = models.IntegerField(help_text="Request status code.") request_details = models.CharField( max_length=255, null=True, From 7ff5df24f2bdeed3f2c11d92cca733bf37bdae1d Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 08:24:27 -0500 Subject: [PATCH 05/18] style: Update openedx/features/survey_report/api.py Co-authored-by: Maria Grimaldi --- openedx/features/survey_report/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openedx/features/survey_report/api.py b/openedx/features/survey_report/api.py index 71d0b0e26187..78b02be6d4a9 100644 --- a/openedx/features/survey_report/api.py +++ b/openedx/features/survey_report/api.py @@ -90,9 +90,9 @@ def send_report(report_id: int) -> None: request.raise_for_status() SurveyReportUpload.objects.create( - report = report, - status = request.status_code, - request_details = request.content + report=report, + status=request.status_code, + request_details=request.content ) From 1bf781aea8b15710f603963a993bff137ff1efc9 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 10:59:27 -0500 Subject: [PATCH 06/18] feat: add migratio file and update status field name --- .../migrations/0003_surveyreportupload.py | 24 +++++++++++++++++++ openedx/features/survey_report/models.py | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 openedx/features/survey_report/migrations/0003_surveyreportupload.py diff --git a/openedx/features/survey_report/migrations/0003_surveyreportupload.py b/openedx/features/survey_report/migrations/0003_surveyreportupload.py new file mode 100644 index 000000000000..d77b101c3c7e --- /dev/null +++ b/openedx/features/survey_report/migrations/0003_surveyreportupload.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.16 on 2022-12-19 15:57 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('survey_report', '0002_auto_20221130_1533'), + ] + + operations = [ + migrations.CreateModel( + name='SurveyReportUpload', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sent_at', models.DateTimeField(auto_now=True, help_text='Date when the report was sent.')), + ('status_code', models.IntegerField(help_text='Request status code.')), + ('request_details', models.CharField(blank=True, help_text='Information about the send request.', max_length=255, null=True)), + ('report', models.ForeignKey(help_text='The report that was sent.', on_delete=django.db.models.deletion.CASCADE, to='survey_report.surveyreport')), + ], + ), + ] diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index 1d7a5a704b84..164f67366551 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -85,5 +85,5 @@ class SurveyReportUpload(models.Model): def is_uploaded(self) -> bool: response = Response() - response.status_code = self.status + response.status_code = self.status_code return response.ok From 29d65d01f4d10bcb6d67c5df8733a2f35beda54a Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 19:14:39 -0500 Subject: [PATCH 07/18] refactor: rename send report method --- openedx/features/survey_report/api.py | 2 +- .../survey_report/management/commands/generate_report.py | 4 ++-- ...urveyreportupload.py => 0003_create_surveyreportupload.py} | 4 ++-- openedx/features/survey_report/models.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename openedx/features/survey_report/migrations/{0003_surveyreportupload.py => 0003_create_surveyreportupload.py} (89%) diff --git a/openedx/features/survey_report/api.py b/openedx/features/survey_report/api.py index 78b02be6d4a9..40624a916389 100644 --- a/openedx/features/survey_report/api.py +++ b/openedx/features/survey_report/api.py @@ -54,7 +54,7 @@ def generate_report() -> None: return survey_report.id -def send_report(report_id: int) -> None: +def send_report_to_external_api(report_id: int) -> None: """ Send a report to Openedx endpoint and save the response in the SurveyReportUpload model. diff --git a/openedx/features/survey_report/management/commands/generate_report.py b/openedx/features/survey_report/management/commands/generate_report.py index 78a718ced200..1904ac9f1b5e 100644 --- a/openedx/features/survey_report/management/commands/generate_report.py +++ b/openedx/features/survey_report/management/commands/generate_report.py @@ -4,7 +4,7 @@ from django.core.management.base import BaseCommand, CommandError -from openedx.features.survey_report.api import generate_report, send_report +from openedx.features.survey_report.api import generate_report, send_report_to_external_api class Command(BaseCommand): @@ -38,7 +38,7 @@ def handle(self, *_args, **options): if not options['no_send']: try: - send_report(report_id=report) + send_report_to_external_api(report_id=report) self.stdout.write(self.style.SUCCESS('Survey report has been sent successfully.')) except Exception as send_error: raise CommandError( diff --git a/openedx/features/survey_report/migrations/0003_surveyreportupload.py b/openedx/features/survey_report/migrations/0003_create_surveyreportupload.py similarity index 89% rename from openedx/features/survey_report/migrations/0003_surveyreportupload.py rename to openedx/features/survey_report/migrations/0003_create_surveyreportupload.py index d77b101c3c7e..9c6165883e59 100644 --- a/openedx/features/survey_report/migrations/0003_surveyreportupload.py +++ b/openedx/features/survey_report/migrations/0003_create_surveyreportupload.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.16 on 2022-12-19 15:57 +# Generated by Django 3.2.16 on 2022-12-20 00:13 from django.db import migrations, models import django.db.models.deletion @@ -15,7 +15,7 @@ class Migration(migrations.Migration): name='SurveyReportUpload', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sent_at', models.DateTimeField(auto_now=True, help_text='Date when the report was sent.')), + ('sent_at', models.DateTimeField(auto_now=True, help_text='Date when the report was sent to external api.')), ('status_code', models.IntegerField(help_text='Request status code.')), ('request_details', models.CharField(blank=True, help_text='Information about the send request.', max_length=255, null=True)), ('report', models.ForeignKey(help_text='The report that was sent.', on_delete=django.db.models.deletion.CASCADE, to='survey_report.surveyreport')), diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index 164f67366551..97b369e076ec 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -73,7 +73,7 @@ class SurveyReportUpload(models.Model): - status: Request status code. - request_details: Information about the send request. """ - sent_at = models.DateTimeField(auto_now=True, help_text="Date when the report was sent.") + sent_at = models.DateTimeField(auto_now=True, help_text="Date when the report was sent to external api.") report = models.ForeignKey(SurveyReport, on_delete=models.CASCADE, help_text="The report that was sent.") status_code = models.IntegerField(help_text="Request status code.") request_details = models.CharField( From 55f31dd5d3707ef3f2c6960ce63c99020030e037 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 19:26:20 -0500 Subject: [PATCH 08/18] test: fix test errors --- .../management/commands/tests/test_generate_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/features/survey_report/management/commands/tests/test_generate_report.py b/openedx/features/survey_report/management/commands/tests/test_generate_report.py index a2156fb0199f..99aafcea07f8 100644 --- a/openedx/features/survey_report/management/commands/tests/test_generate_report.py +++ b/openedx/features/survey_report/management/commands/tests/test_generate_report.py @@ -31,7 +31,7 @@ def test_generate_report(self, mock_get_report_data): } mock_get_report_data.return_value = report_test_data out = StringIO() - call_command('generate_report', stdout=out) + call_command('generate_report --no-send', stdout=out) survey_report = SurveyReport.objects.last() From 7fbfb02461b0e82e1eadf7b900a3f38a8f7586f8 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 19 Dec 2022 20:56:01 -0500 Subject: [PATCH 09/18] test: add command options --- .../management/commands/tests/test_generate_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/features/survey_report/management/commands/tests/test_generate_report.py b/openedx/features/survey_report/management/commands/tests/test_generate_report.py index 99aafcea07f8..74204981d520 100644 --- a/openedx/features/survey_report/management/commands/tests/test_generate_report.py +++ b/openedx/features/survey_report/management/commands/tests/test_generate_report.py @@ -31,7 +31,7 @@ def test_generate_report(self, mock_get_report_data): } mock_get_report_data.return_value = report_test_data out = StringIO() - call_command('generate_report --no-send', stdout=out) + call_command('generate_report', no_send=True, stdout=out) survey_report = SurveyReport.objects.last() From 2b5ac9acd8db0f710d5694dcec23dfd731f4ae15 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Tue, 3 Jan 2023 08:23:38 -0500 Subject: [PATCH 10/18] refactor: simple conditional instead of ok method --- openedx/features/survey_report/models.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index 97b369e076ec..d71ab37362d2 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -84,6 +84,4 @@ class SurveyReportUpload(models.Model): ) def is_uploaded(self) -> bool: - response = Response() - response.status_code = self.status_code - return response.ok + return 200 <= self.status_code < 300 From e83bebfa9bf5b593bb0fe80b05869af4381fdad1 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Fri, 6 Jan 2023 08:43:42 -0500 Subject: [PATCH 11/18] fix: remove useless imports --- openedx/features/survey_report/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index d71ab37362d2..b94c289cbacf 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -4,7 +4,6 @@ from django.db import models from jsonfield import JSONField -from requests.models import Response SURVEY_REPORT_PROCESSING = 'processing' SURVEY_REPORT_GENERATED = 'generated' From 220aec587ee15766addbf06bea054ca4abffd3f3 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Tue, 17 Jan 2023 07:36:10 -0500 Subject: [PATCH 12/18] fix: use status code instead of status --- openedx/features/survey_report/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/features/survey_report/api.py b/openedx/features/survey_report/api.py index 40624a916389..63db3b9baa95 100644 --- a/openedx/features/survey_report/api.py +++ b/openedx/features/survey_report/api.py @@ -91,7 +91,7 @@ def send_report_to_external_api(report_id: int) -> None: SurveyReportUpload.objects.create( report=report, - status=request.status_code, + status_code=request.status_code, request_details=request.content ) From 96827ec09f1e8ab75fa929c287241547b9c28900 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Tue, 17 Jan 2023 07:52:48 -0500 Subject: [PATCH 13/18] feat: add zapier endpoint --- lms/envs/production.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/envs/production.py b/lms/envs/production.py index 924f0171ea0b..a7a448e5e906 100644 --- a/lms/envs/production.py +++ b/lms/envs/production.py @@ -1083,6 +1083,6 @@ def get_env_setting(setting): ############## Settings for survey report ############## SURVEY_REPORT_EXTRA_DATA = ENV_TOKENS.get('SURVEY_REPORT_EXTRA_DATA', {}) -SURVEY_REPORT_ENDPOINT = ENV_TOKENS.get('SURVEY_REPORT_ENDPOINT', "") +SURVEY_REPORT_ENDPOINT = ENV_TOKENS.get('SURVEY_REPORT_ENDPOINT', "https://hooks.zapier.com/hooks/catch/2208510/bjzht2h/") AVAILABLE_DISCUSSION_TOURS = ENV_TOKENS.get('AVAILABLE_DISCUSSION_TOURS', []) From 8d3a27b3c2bbdedd55a56a28c2cd9300f6778a67 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Tue, 17 Jan 2023 10:48:09 -0500 Subject: [PATCH 14/18] style: solve pylint issues --- lms/envs/production.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lms/envs/production.py b/lms/envs/production.py index a7a448e5e906..0f05fb4d5dee 100644 --- a/lms/envs/production.py +++ b/lms/envs/production.py @@ -1083,6 +1083,7 @@ def get_env_setting(setting): ############## Settings for survey report ############## SURVEY_REPORT_EXTRA_DATA = ENV_TOKENS.get('SURVEY_REPORT_EXTRA_DATA', {}) -SURVEY_REPORT_ENDPOINT = ENV_TOKENS.get('SURVEY_REPORT_ENDPOINT', "https://hooks.zapier.com/hooks/catch/2208510/bjzht2h/") +SURVEY_REPORT_ENDPOINT = ENV_TOKENS.get('SURVEY_REPORT_ENDPOINT', + 'https://hooks.zapier.com/hooks/catch/2208510/bjzht2h/') AVAILABLE_DISCUSSION_TOURS = ENV_TOKENS.get('AVAILABLE_DISCUSSION_TOURS', []) From 22875845bfc65ceeb2d54898f6b959aa0503a6dd Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 23 Jan 2023 11:49:12 -0500 Subject: [PATCH 15/18] feat: add id field to send report data --- lms/envs/production.py | 1 + lms/envs/test.py | 1 + openedx/features/survey_report/api.py | 9 +++++++++ 3 files changed, 11 insertions(+) diff --git a/lms/envs/production.py b/lms/envs/production.py index 0f05fb4d5dee..bde9f8823429 100644 --- a/lms/envs/production.py +++ b/lms/envs/production.py @@ -1085,5 +1085,6 @@ def get_env_setting(setting): SURVEY_REPORT_EXTRA_DATA = ENV_TOKENS.get('SURVEY_REPORT_EXTRA_DATA', {}) SURVEY_REPORT_ENDPOINT = ENV_TOKENS.get('SURVEY_REPORT_ENDPOINT', 'https://hooks.zapier.com/hooks/catch/2208510/bjzht2h/') +ANONYMOUS_SURVEY_REPORT = False AVAILABLE_DISCUSSION_TOURS = ENV_TOKENS.get('AVAILABLE_DISCUSSION_TOURS', []) diff --git a/lms/envs/test.py b/lms/envs/test.py index b4036aee73ee..b1fb5f8b249d 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -675,3 +675,4 @@ ############## Settings for survey report ############## SURVEY_REPORT_EXTRA_DATA = {} SURVEY_REPORT_ENDPOINT = "https://example.com/survey_report" +ANONYMOUS_SURVEY_REPORT = False diff --git a/openedx/features/survey_report/api.py b/openedx/features/survey_report/api.py index 63db3b9baa95..f3b40d80084f 100644 --- a/openedx/features/survey_report/api.py +++ b/openedx/features/survey_report/api.py @@ -2,6 +2,7 @@ Contains the logic to manage survey report model. """ import requests +import hashlib from django.conf import settings from django.forms.models import model_to_dict @@ -54,6 +55,13 @@ def generate_report() -> None: return survey_report.id +def get_id() -> str: + """ Generate id for the survey report.""" + if not settings.ANONYMOUS_SURVEY_REPORT: + return settings.LMS_BASE + return hashlib.sha256(settings.LMS_BASE.encode('utf-8')).hexdigest() + + def send_report_to_external_api(report_id: int) -> None: """ Send a report to Openedx endpoint and save the response in the SurveyReportUpload model. @@ -82,6 +90,7 @@ def send_report_to_external_api(report_id: int) -> None: ] data = model_to_dict(report, fields=fields) + data["id"] = get_id() data["extra_data"] = report.extra_data data["created_at"] = report.created_at.strftime("%m-%d-%Y %H:%M:%S") From 5a460de2e35dcf0a34d5cc68379c55accf7fef48 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 1 Feb 2023 11:16:38 -0400 Subject: [PATCH 16/18] refactor: regenerate migration with correct history --- ...reate_surveyreportupload.py => 0004_surveyreportupload.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename openedx/features/survey_report/migrations/{0003_create_surveyreportupload.py => 0004_surveyreportupload.py} (87%) diff --git a/openedx/features/survey_report/migrations/0003_create_surveyreportupload.py b/openedx/features/survey_report/migrations/0004_surveyreportupload.py similarity index 87% rename from openedx/features/survey_report/migrations/0003_create_surveyreportupload.py rename to openedx/features/survey_report/migrations/0004_surveyreportupload.py index 9c6165883e59..cc77eaef71bb 100644 --- a/openedx/features/survey_report/migrations/0003_create_surveyreportupload.py +++ b/openedx/features/survey_report/migrations/0004_surveyreportupload.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.16 on 2022-12-20 00:13 +# Generated by Django 3.2.16 on 2023-02-01 15:16 from django.db import migrations, models import django.db.models.deletion @@ -7,7 +7,7 @@ class Migration(migrations.Migration): dependencies = [ - ('survey_report', '0002_auto_20221130_1533'), + ('survey_report', '0003_add_state_field_and_add_default_values_to_fields'), ] operations = [ From c7ecb2342b8441b47999b13c35ad4113c73b7930 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Fri, 10 Feb 2023 10:49:16 -0500 Subject: [PATCH 17/18] feat: add anonymous site id model --- openedx/features/survey_report/api.py | 12 +++++++---- .../0005_surveyreportanonymoussiteid.py | 20 +++++++++++++++++++ openedx/features/survey_report/models.py | 12 +++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 openedx/features/survey_report/migrations/0005_surveyreportanonymoussiteid.py diff --git a/openedx/features/survey_report/api.py b/openedx/features/survey_report/api.py index f3b40d80084f..bce26b19b0b8 100644 --- a/openedx/features/survey_report/api.py +++ b/openedx/features/survey_report/api.py @@ -2,12 +2,17 @@ Contains the logic to manage survey report model. """ import requests -import hashlib from django.conf import settings from django.forms.models import model_to_dict -from openedx.features.survey_report.models import SurveyReport, SurveyReportUpload +from openedx.features.survey_report.models import ( + SurveyReport, + SurveyReportUpload, + SurveyReportAnonymousSiteID, + SURVEY_REPORT_ERROR, + SURVEY_REPORT_GENERATED +) from openedx.features.survey_report.queries import ( get_course_enrollments, get_recently_active_users, @@ -15,7 +20,6 @@ get_registered_learners, get_unique_courses_offered ) -from .models import SURVEY_REPORT_ERROR, SURVEY_REPORT_GENERATED MAX_WEEKS_SINCE_LAST_LOGIN: int = 4 @@ -59,7 +63,7 @@ def get_id() -> str: """ Generate id for the survey report.""" if not settings.ANONYMOUS_SURVEY_REPORT: return settings.LMS_BASE - return hashlib.sha256(settings.LMS_BASE.encode('utf-8')).hexdigest() + return str(SurveyReportAnonymousSiteID.objects.get_or_create()[0].id) def send_report_to_external_api(report_id: int) -> None: diff --git a/openedx/features/survey_report/migrations/0005_surveyreportanonymoussiteid.py b/openedx/features/survey_report/migrations/0005_surveyreportanonymoussiteid.py new file mode 100644 index 000000000000..ccf7d059a2d2 --- /dev/null +++ b/openedx/features/survey_report/migrations/0005_surveyreportanonymoussiteid.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.16 on 2023-02-10 15:45 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('survey_report', '0004_surveyreportupload'), + ] + + operations = [ + migrations.CreateModel( + name='SurveyReportAnonymousSiteID', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ], + ), + ] diff --git a/openedx/features/survey_report/models.py b/openedx/features/survey_report/models.py index b94c289cbacf..a753da620b33 100644 --- a/openedx/features/survey_report/models.py +++ b/openedx/features/survey_report/models.py @@ -2,6 +2,8 @@ Survey Report models. """ +import uuid + from django.db import models from jsonfield import JSONField @@ -84,3 +86,13 @@ class SurveyReportUpload(models.Model): def is_uploaded(self) -> bool: return 200 <= self.status_code < 300 + + +class SurveyReportAnonymousSiteID(models.Model): + """ + This model is just to save the identification which will be send to the external API when + the settings ANONYMOUS_SURVEY_REPORT is defined. + + .. no_pii: + """ + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) From 85ce81392d5afcfd511f1507cff0a44aaeb47453 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Mon, 20 Feb 2023 06:39:18 -0500 Subject: [PATCH 18/18] feat: update zapier url --- lms/envs/production.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/envs/production.py b/lms/envs/production.py index bde9f8823429..c76ca3e8591a 100644 --- a/lms/envs/production.py +++ b/lms/envs/production.py @@ -1084,7 +1084,7 @@ def get_env_setting(setting): ############## Settings for survey report ############## SURVEY_REPORT_EXTRA_DATA = ENV_TOKENS.get('SURVEY_REPORT_EXTRA_DATA', {}) SURVEY_REPORT_ENDPOINT = ENV_TOKENS.get('SURVEY_REPORT_ENDPOINT', - 'https://hooks.zapier.com/hooks/catch/2208510/bjzht2h/') + 'https://hooks.zapier.com/hooks/catch/11595998/3ouwv7m/') ANONYMOUS_SURVEY_REPORT = False AVAILABLE_DISCUSSION_TOURS = ENV_TOKENS.get('AVAILABLE_DISCUSSION_TOURS', [])