Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple groups and users #59

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions django_datawatch/0005_migrate_new_assigned_fields.py
lociii marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by Django 4.2.9 on 2024-01-15 23:41

from django.db import migrations

from django.core.paginator import Paginator

def migrate_new_assigned_fields(apps, schema_editor):
Result = apps.get_model('django_datawatch', 'Result')
ThroughResultAssignedGroups = Result.assigned_groups.through
ThroughResultAssignedUsers = Result.assigned_users.through

for result in Result.objects.all():
result.assigned_groups = result.assigned_groups.all()
result.assigned_users = result.assigned_users.all()
result.save(update_fields=['assigned_groups', 'assigned_users'])

# Paginate the queryset to avoid memory issues
paginator = Paginator(
Result.objects.only("assigned_to_user", "assigned_to_group"),
5000,
)

for page_number in paginator.page_range:
page = paginator.page(page_number)
group_instances = []
user_instances = []

for result in page.object_list:
if result.assigned_to_group:
group_instances.append(ThroughResultAssignedGroups(
result_id=result.pk,
group_id=result.assigned_to_group.pk,
))
if result.assigned_to_user:
user_instances.append(ThroughResultAssignedUsers(
result_id=result.pk,
user_id=result.assigned_to_user.pk,
))

ThroughResultAssignedGroups.objects.bulk_create(group_instances)
ThroughResultAssignedUsers.objects.bulk_create(user_instances)


class Migration(migrations.Migration):

dependencies = [
('django_datawatch', '0004_result_assigned_groups_result_assigned_users'),
]

operations = [
migrations.RunPython(migrate_new_assigned_fields)
]
14 changes: 11 additions & 3 deletions django_datawatch/admin.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
from django.contrib import admin

from django_datawatch.models import Result, CheckExecution, ResultStatusHistory
from django_datawatch.models import Result, CheckExecution, ResultAssignedGroup, ResultAssignedUser, ResultStatusHistory


class ResultAssignedGroupInline(admin.TabularInline):
model = ResultAssignedGroup
extra = 0

class ResultAssignedUserInline(admin.TabularInline):
model = ResultAssignedUser
extra = 0

@admin.register(Result)
class CheckAdmin(admin.ModelAdmin):
list_display = ('slug', 'identifier', 'status')
readonly_fields = ('created', 'modified')
search_fields = ('slug', 'identifier', 'payload_description')
list_filter = ('status', 'slug', 'assigned_to_group')

list_filter = ('status', 'slug', 'assigned_groups', 'assigned_users')
lociii marked this conversation as resolved.
Show resolved Hide resolved
inlines = [ResultAssignedGroupInline, ResultAssignedUserInline]

@admin.register(CheckExecution)
class CheckExecutionAdmin(admin.ModelAdmin):
Expand Down
35 changes: 22 additions & 13 deletions django_datawatch/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from contextlib import contextmanager

from django import forms
from django.db import transaction
from django.utils import timezone

from django_datawatch.models import Result, CheckExecution, ResultStatusHistory
Expand All @@ -24,7 +25,6 @@ def track_status_history(slug, identifier, new_status):
class DatawatchCheckSkipException(Exception):
pass


class BaseCheckForm(forms.Form):
def save(self, instance):
instance.config = self.cleaned_data
Expand Down Expand Up @@ -60,8 +60,8 @@ class BaseCheck(object):
Any check should inherits from `BaseCheck` and should implements `.generate(self)`
and `.check(self, payload)` methods.

Optionally, you can implements `.get_assigned_user(self, payload)` (resp. `.get_assigned_group(self, payload)`)
to define to which user (resp. group) the system had to assign the check result.
Optionally, you can implements `.get_assigned_users(self, payload)` (resp. `.get_assigned_groups(self, payload)`)
to define to which user(s) (resp. group(s)) the system had to assign the check result.
"""

config_form = None
Expand Down Expand Up @@ -131,17 +131,26 @@ def get_form_class(self):

def save(self, payload, status, data=None, unacknowledge=False):
# build default data
defaults = dict(status=status, data=data, assigned_to_user=self.get_assigned_user(payload, status),
assigned_to_group=self.get_assigned_group(payload, status),
payload_description=self.get_payload_description(payload))
defaults = dict(status=status, data=data, payload_description=self.get_payload_description(payload))

if unacknowledge:
defaults.update(dict(acknowledged_by=None, acknowledged_at=None, acknowledged_until=None))

with track_status_history(self.slug, self.get_identifier(payload), status):
# save the check
dataset, created = Result.objects.update_or_create(
slug=self.slug, identifier=self.get_identifier(payload),
defaults=defaults)
with transaction.atomic():
with track_status_history(self.slug, self.get_identifier(payload), status):
# save the check
dataset, created = Result.objects.update_or_create(
slug=self.slug, identifier=self.get_identifier(payload),
defaults=defaults)

# set assigned users and groups
if groups := self.get_assigned_groups(payload, status):
assert len(groups) == len(set(g.pk for g in groups)), 'groups must be unique'
lociii marked this conversation as resolved.
Show resolved Hide resolved
dataset.assigned_groups.set(groups)
lociii marked this conversation as resolved.
Show resolved Hide resolved

if users := self.get_assigned_users(payload, status):
assert len(users) == len(set(u.pk for u in users)), 'users must be unique'
lociii marked this conversation as resolved.
Show resolved Hide resolved
dataset.assigned_users.set(users)
lociii marked this conversation as resolved.
Show resolved Hide resolved

return dataset

Expand Down Expand Up @@ -179,10 +188,10 @@ def get_payload_description(self, payload):
def format_result_data(self, result):
return ''

def get_assigned_user(self, payload, result):
def get_assigned_users(self, payload, result):
Kandeel4411 marked this conversation as resolved.
Show resolved Hide resolved
return None

def get_assigned_group(self, payload, result):
def get_assigned_groups(self, payload, result):
Kandeel4411 marked this conversation as resolved.
Show resolved Hide resolved
return None

def get_context_data(self, result):
Expand Down
Binary file modified django_datawatch/locale/de/LC_MESSAGES/django.mo
Binary file not shown.
38 changes: 31 additions & 7 deletions django_datawatch/locale/de/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-09-14 10:02+0000\n"
"POT-Creation-Date: 2024-01-16 01:07+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down Expand Up @@ -72,6 +72,12 @@ msgstr "Ausgeblendet bis"
msgid "Acknowledge reason"
msgstr "Ausblendungsgrund"

msgid "Assigned users"
msgstr "Zugewiesener Benutzer"
lociii marked this conversation as resolved.
Show resolved Hide resolved

msgid "Assigned groups"
msgstr "Zugewiesene Gruppen"

msgid "Result"
msgstr "Ergebnis"

Expand All @@ -84,6 +90,27 @@ msgstr "Zu Status"
msgid "Result status history"
msgstr "Ergebnis-Status-Historie"

msgid "Group"
msgstr "Gruppen"
lociii marked this conversation as resolved.
Show resolved Hide resolved

msgid "Result assigned group"
msgstr "Zugewiesene Gruppe"

msgid "Result assigned groups"
msgstr "Zugewiesene Gruppen"

msgid "Group must be unique across the result"
msgstr "Die Gruppe muss im gesamten Ergebnis eindeutig sein"
lociii marked this conversation as resolved.
Show resolved Hide resolved

msgid "Result assigned user"
msgstr "Zugewiesener Benutzer"

msgid "Result assigned users"
msgstr "Zugewiesener Benutzern"
lociii marked this conversation as resolved.
Show resolved Hide resolved

msgid "User must be unique across the result"
msgstr "Der Benutzer muss im gesamten Ergebnis eindeutig sein"
lociii marked this conversation as resolved.
Show resolved Hide resolved

msgid "Check module slug"
msgstr "Modul-Bezeichner"

Expand Down Expand Up @@ -136,6 +163,9 @@ msgstr "Nicht zugewiesen"
msgid "Config form class"
msgstr "Formular-Klasse für Konfiguration"

msgid "Config"
msgstr "Konfiguration"

msgid "Run every"
msgstr "Periodisches Ausführen"

Expand All @@ -152,12 +182,6 @@ msgstr "Maximale Ausblendezeit"
msgid "%(days)s day(s)"
msgstr "%(days)s Tag(e)"

msgid "Assigned group"
msgstr "Zugewiesene Gruppe"

msgid "Assigned user"
msgstr "Zugewiesener Benutzer"

#, python-format
msgid "Acknowledged until %(date)s by %(user)s"
msgstr "Ausgeblendet bis %(date)s durch %(user)s"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generated by Django 4.2.9 on 2024-01-16 00:05

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('django_datawatch', '0003_resultstatushistory'),
]

operations = [
migrations.CreateModel(
name='ResultAssignedUser',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('result', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='django_datawatch.result', verbose_name='Result')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
options={
'verbose_name': 'Result assigned user',
'verbose_name_plural': 'Result assigned users',
},
),
migrations.CreateModel(
name='ResultAssignedGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.group', verbose_name='Group')),
('result', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='django_datawatch.result', verbose_name='Result')),
],
options={
'verbose_name': 'Result assigned group',
'verbose_name_plural': 'Result assigned groups',
},
),
migrations.AddField(
model_name='result',
name='assigned_groups',
field=models.ManyToManyField(blank=True, related_name='assigned_groups', through='django_datawatch.ResultAssignedGroup', to='auth.group', verbose_name='Assigned groups'),
),
migrations.AddField(
model_name='result',
name='assigned_users',
field=models.ManyToManyField(blank=True, related_name='assigned_results', through='django_datawatch.ResultAssignedUser', to=settings.AUTH_USER_MODEL, verbose_name='Assigned users'),
),
migrations.AddConstraint(
model_name='resultassigneduser',
constraint=models.UniqueConstraint(fields=('result', 'user'), name='unique_result_assigned_user'),
),
migrations.AddConstraint(
model_name='resultassignedgroup',
constraint=models.UniqueConstraint(fields=('result', 'group'), name='unique_result_assigned_group'),
),
]
47 changes: 47 additions & 0 deletions django_datawatch/migrations/0005_migrate_new_assigned_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 4.2.9 on 2024-01-16 00:06

from django.db import migrations

from django.core.paginator import Paginator

def migrate_new_assigned_fields(apps, schema_editor):
Result = apps.get_model('django_datawatch', 'Result')
ResultAssignedGroup = apps.get_model('django_datawatch', 'ResultAssignedGroup')
ResultAssignedUser = apps.get_model('django_datawatch', 'ResultAssignedUser')

# Paginate the queryset to avoid memory issues
paginator = Paginator(
Result.objects.order_by('pk').only('assigned_to_user', 'assigned_to_group'),
5000,
)

for page_number in paginator.page_range:
page = paginator.page(page_number)
group_instances = []
user_instances = []

for result in page.object_list:
if result.assigned_to_group:
group_instances.append(ResultAssignedGroup(
result_id=result.pk,
group_id=result.assigned_to_group.pk,
))
if result.assigned_to_user:
user_instances.append(ResultAssignedUser(
result_id=result.pk,
user_id=result.assigned_to_user.pk,
))

ResultAssignedGroup.objects.bulk_create(group_instances)
ResultAssignedUser.objects.bulk_create(user_instances)


class Migration(migrations.Migration):

dependencies = [
('django_datawatch', '0004_resultassigneduser_resultassignedgroup_and_more'),
]

operations = [
migrations.RunPython(migrate_new_assigned_fields),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 4.2.9 on 2024-01-16 00:07

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('django_datawatch', '0005_migrate_new_assigned_fields'),
]

operations = [
migrations.RemoveField(
model_name='result',
name='assigned_to_group',
),
migrations.RemoveField(
model_name='result',
name='assigned_to_user',
),
]
Loading