Skip to content

Commit

Permalink
add notification enabling/disabling (#814)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmi4er4 authored Mar 2, 2024
1 parent 360d3f2 commit 328c48b
Show file tree
Hide file tree
Showing 19 changed files with 4,223 additions and 1,087 deletions.
436 changes: 221 additions & 215 deletions apps/admission/locale/ru/LC_MESSAGES/django.po

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions apps/core/migrations/0019_alter_siteconfiguration_managers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.18 on 2024-02-27 15:02

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0018_remove_siteconfiguration_lms_subdomain'),
]

operations = [
migrations.AlterModelManagers(
name='siteconfiguration',
managers=[
],
),
]
28 changes: 28 additions & 0 deletions apps/courses/migrations/0043_auto_20240227_1502.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.2.18 on 2024-02-27 15:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('courses', '0042_new_assigneemode'),
]

operations = [
migrations.AlterField(
model_name='assignment',
name='submission_type',
field=models.CharField(choices=[('online', 'Online Submission'), ('ya.contest', 'Yandex.Contest'), ('external', 'External Service'), ('code_review', 'Code Review Submission'), ('penalty', 'Penalty'), ('other', 'No Submission')], max_length=42, verbose_name='Assignment Format'),
),
migrations.AlterField(
model_name='course',
name='group_mode',
field=models.CharField(choices=[('no_groups', 'No Groups'), ('manual', 'Manual'), ('branch', 'Branches'), ('invite_and_branch', 'Invitations and Branches')], default='branch', help_text='Choose `Branch` to auto generate student groups from course branches.', max_length=100, verbose_name='Student Group Mode'),
),
migrations.AlterField(
model_name='course',
name='materials_visibility',
field=models.CharField(choices=[('public', 'All Users'), ('participants', 'All Students'), ('private', 'Course Participants')], default='private', help_text='Default visibility for class materials.', max_length=12, verbose_name='Materials Visibility'),
),
]
44 changes: 20 additions & 24 deletions apps/htmlpages/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-18 09:16+0100\n"
"POT-Creation-Date: 2024-02-27 18:28+0300\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <[email protected]>\n"
Expand All @@ -13,76 +13,72 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: contrib/flatpages/admin.py:11
#: apps/htmlpages/admin.py:24
msgid "Advanced options"
msgstr ""

#: contrib/flatpages/apps.py:7
#: apps/htmlpages/apps.py:7
msgid "Flat Pages"
msgstr ""

#: contrib/flatpages/forms.py:8 contrib/flatpages/models.py:12
#: apps/htmlpages/forms.py:10 apps/htmlpages/models.py:11
msgid "URL"
msgstr ""

#: contrib/flatpages/forms.py:9
#: apps/htmlpages/forms.py:11
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""

#: contrib/flatpages/forms.py:12
#: apps/htmlpages/forms.py:14
msgid ""
"This value must contain only letters, numbers, dots, underscores, dashes, "
"slashes or tildes."
msgstr ""

#: contrib/flatpages/forms.py:25
#: apps/htmlpages/forms.py:27
msgid "URL is missing a leading slash."
msgstr ""

#: contrib/flatpages/forms.py:32
#: apps/htmlpages/forms.py:34
msgid "URL is missing a trailing slash."
msgstr ""

#: contrib/flatpages/forms.py:49
#: apps/htmlpages/forms.py:51
#, python-format
msgid "Flatpage with url %(url)s already exists for site %(site)s"
msgid "Htmlpage with url %(url)s already exists for site %(site)s"
msgstr ""

#: contrib/flatpages/models.py:13
#: apps/htmlpages/models.py:12
msgid "title"
msgstr ""

#: contrib/flatpages/models.py:14
#: apps/htmlpages/models.py:13
msgid "content"
msgstr ""

#: contrib/flatpages/models.py:15
msgid "enable comments"
msgstr ""

#: contrib/flatpages/models.py:16
#: apps/htmlpages/models.py:14
msgid "template name"
msgstr ""

#: contrib/flatpages/models.py:18
#: apps/htmlpages/models.py:16
msgid ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
"Example: 'htmlpages/contact_page.html'. If this isn't provided, the system "
"will use 'htmlpages/default.html'."
msgstr ""

#: contrib/flatpages/models.py:22
#: apps/htmlpages/models.py:20
msgid "registration required"
msgstr ""

#: contrib/flatpages/models.py:23
#: apps/htmlpages/models.py:21
msgid "If this is checked, only logged-in users will be able to view the page."
msgstr ""

#: contrib/flatpages/models.py:29
#: apps/htmlpages/models.py:27
msgid "flat page"
msgstr ""

#: contrib/flatpages/models.py:30
#: apps/htmlpages/models.py:28
msgid "flat pages"
msgstr ""
6 changes: 3 additions & 3 deletions apps/htmlpages/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-30 01:19+0000\n"
"POT-Creation-Date: 2024-02-27 18:28+0300\n"
"PO-Revision-Date: 2015-03-18 08:34+0000\n"
"Last-Translator: Jannis Leidel <[email protected]>\n"
"Language-Team: Russian (http://www.transifex.com/projects/p/django/language/"
Expand All @@ -18,8 +18,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"

#: apps/htmlpages/admin.py:24
msgid "Advanced options"
Expand Down
25 changes: 25 additions & 0 deletions apps/learning/migrations/0044_auto_20240227_1502.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 3.2.18 on 2024-02-27 15:02

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('learning', '0043_studentgroupteacherbucket'),
]

operations = [
migrations.RemoveField(
model_name='studentassignment',
name='first_student_comment_at',
),
migrations.RemoveField(
model_name='studentassignment',
name='last_comment_from',
),
migrations.RemoveField(
model_name='studentgroup',
name='meta',
),
]
5 changes: 2 additions & 3 deletions apps/notifications/management/commands/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@ def send_assignment_notifications(site_configurations: Dict[int, SiteConfigurati
'student_assignment__student',
]
notifications = (AssignmentNotification.objects
.filter(is_unread=True,
is_notified=False)
.filter(is_unread=True, is_notified=False, user__is_notification_allowed=True)
.select_related("user", "user__branch")
.prefetch_related(*prefetch))
for notification in notifications:
Expand All @@ -256,7 +255,7 @@ def send_course_news_notifications(site_configurations: Dict[int, SiteConfigurat
'course_offering_news__course__semester',
]
notifications = (CourseNewsNotification.objects
.filter(is_unread=True, is_notified=False)
.filter(is_unread=True, is_notified=False, user__is_notification_allowed=True)
.select_related("user", "course_offering_news")
.prefetch_related(*prefetch))
for notification in notifications:
Expand Down
5 changes: 5 additions & 0 deletions apps/notifications/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ def notify(self, notification):
"as deleted".format(notification.recipient))
Notification.objects.filter(pk=notification.pk).update(deleted=True)
return
if not notification.recipient.is_notification_allowed:
self.logger.warning("user {0} disabled notifications. Mark "
"as deleted".format(notification.recipient))
Notification.objects.filter(pk=notification.pk).update(deleted=True)
return

html_content = linebreaks(self._cached_template.render(context))
# FIXME: Don't strip links
Expand Down
18 changes: 11 additions & 7 deletions apps/notifications/tests/test_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
EnrollmentFactory
)
from notifications.management.commands.notify import resolve_course_participant_branch
from users.tests.factories import CuratorFactory, StudentFactory, TeacherFactory
from users.tests.factories import CuratorFactory, UserFactory, TeacherFactory


@pytest.mark.django_db
Expand All @@ -31,9 +31,7 @@ def test_command_notify(settings, mocker):

out = OutputIO()
mail.outbox = []
student = StudentFactory()
an = AssignmentNotificationFactory(is_about_passed=True,
user=student)
an = AssignmentNotificationFactory(is_about_passed=True)
management.call_command("notify", stdout=out)
if settings.ENABLE_NON_AUTH_NOTIFICATIONS:
assert len(mail.outbox) == 1
Expand All @@ -52,9 +50,7 @@ def test_command_notify(settings, mocker):

out = OutputIO()
mail.outbox = []
student = StudentFactory()
conn = CourseNewsNotificationFactory.create(user=student)
course = conn.course_offering_news.course
conn = CourseNewsNotificationFactory.create()
management.call_command("notify", stdout=out)
if settings.ENABLE_NON_AUTH_NOTIFICATIONS:
assert len(mail.outbox) == 1
Expand All @@ -67,6 +63,14 @@ def test_command_notify(settings, mocker):
assert not conn.is_notified
assert "sending notification for" not in out.getvalue()

out = OutputIO()
mail.outbox = []
user = UserFactory(is_notification_allowed=False)
an = AssignmentNotificationFactory(is_about_passed=True, user=user)
management.call_command("notify", stdout=out)
assert not mail.outbox
assert not AssignmentNotification.objects.get(pk=an.pk).is_notified
assert "sending notification for" not in out.getvalue()

@pytest.mark.django_db
def test_command_notification_cleanup(client, settings):
Expand Down
8 changes: 4 additions & 4 deletions apps/projects/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-30 01:19+0000\n"
"POT-Creation-Date: 2024-02-27 18:28+0300\n"
"PO-Revision-Date: 2022-02-21 15:24+0000\n"
"Last-Translator: Сергей Жеревчук <[email protected]>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
"%100>=11 && n%100<=14)? 2 : 3);\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
"(n%100>=11 && n%100<=14)? 2 : 3);\n"
"X-Translated-Using: django-rosetta 0.9.8\n"

#: apps/projects/admin.py:107 apps/projects/filters.py:36
Expand Down
8 changes: 4 additions & 4 deletions apps/surveys/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-30 01:19+0000\n"
"POT-Creation-Date: 2024-02-27 18:28+0300\n"
"PO-Revision-Date: 2019-10-31 16:30+0000\n"
"Last-Translator: b' <[email protected]>'\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
"%100>=11 && n%100<=14)? 2 : 3);\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
"(n%100>=11 && n%100<=14)? 2 : 3);\n"
"X-Translated-Using: django-rosetta 0.9.3\n"

#: apps/surveys/admin.py:66 apps/surveys/models.py:255
Expand Down
5 changes: 3 additions & 2 deletions apps/users/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Meta:
model = User
fields = ('birth_date', 'phone', 'workplace', 'bio', 'time_zone',
'telegram_username', 'yandex_login', 'github_login', 'stepic_id', 'codeforces_login',
'private_contacts')
'private_contacts', 'is_notification_allowed')
widgets = {
'bio': UbereditorWidget,
'private_contacts': UbereditorWidget,
Expand All @@ -84,7 +84,8 @@ class Meta:
'github_login': "github.com/<b>GITHUB-ID</b>",
'stepic_id': _("stepik.org/users/<b>USER_ID</b>"),
'codeforces_login': _("codeforces.com/profile/<b>HANDLE</b>"),
'workplace': _("Specify one or more jobs (comma-separated)")
'workplace': _("Specify one or more jobs (comma-separated)"),
'is_notification_allowed': _("Не касается уведомлений аутентификации")
}


Expand Down
18 changes: 18 additions & 0 deletions apps/users/migrations/0040_user_is_notification_allowed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.18 on 2024-02-27 15:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('users', '0039_yandexuserdata'),
]

operations = [
migrations.AddField(
model_name='user',
name='is_notification_allowed',
field=models.BooleanField(default=True, help_text='Designates that this user enabled email notifications ', verbose_name='notification permission status'),
),
]
8 changes: 8 additions & 0 deletions apps/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,14 @@ class User(TimezoneAwareMixin, LearningPermissionsMixin, StudentProfileAbstract,
'explicitly assigning them.'
),
)

is_notification_allowed = models.BooleanField(
_('notification permission status'),
default=True,
help_text=_(
'Designates that this user enabled email notifications '
),
)
gender = models.CharField(_("Gender"), max_length=1,
choices=GenderTypes.choices)
phone = models.CharField(
Expand Down
1 change: 1 addition & 0 deletions apps/users/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Meta:
last_name = factory.Sequence(lambda n: "Petrov%03d" % n)
branch = None
time_zone = factory.LazyAttribute(lambda user: user.branch.time_zone if user.branch is not None else settings.DEFAULT_TIMEZONE)
is_notification_allowed = True

@factory.post_generation
def groups(self, create, extracted, **kwargs):
Expand Down
Loading

0 comments on commit 328c48b

Please sign in to comment.