diff --git a/src/fellchensammlung/admin.py b/src/fellchensammlung/admin.py index 5c71ec2..a8c7ac3 100644 --- a/src/fellchensammlung/admin.py +++ b/src/fellchensammlung/admin.py @@ -2,7 +2,7 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib import admin from django.utils.html import format_html -from .models import User, Language, Text, ReportComment, ReportAdoptionNotice +from .models import User, Language, Text, ReportComment, ReportAdoptionNotice, Log from .models import Animal, Species, RescueOrganization, AdoptionNotice, Location, Rule, Image, ModerationAction, \ Comment, Report, Announcement, AdoptionNoticeStatus, User, Subscriptions @@ -62,3 +62,4 @@ admin.site.register(Text) admin.site.register(Announcement) admin.site.register(AdoptionNoticeStatus) admin.site.register(Subscriptions) +admin.site.register(Log) diff --git a/src/fellchensammlung/migrations/0009_log.py b/src/fellchensammlung/migrations/0009_log.py new file mode 100644 index 0000000..4ec7077 --- /dev/null +++ b/src/fellchensammlung/migrations/0009_log.py @@ -0,0 +1,25 @@ +# Generated by Django 5.1.1 on 2024-10-10 21:00 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('fellchensammlung', '0008_alter_adoptionnoticestatus_minor_status_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Log', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('action', models.CharField(max_length=255, verbose_name='Aktion')), + ('text', models.CharField(max_length=1000, verbose_name='Log text')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Nutzer*in')), + ], + ), + ] diff --git a/src/fellchensammlung/models.py b/src/fellchensammlung/models.py index d508630..aaaa330 100644 --- a/src/fellchensammlung/models.py +++ b/src/fellchensammlung/models.py @@ -72,7 +72,7 @@ class User(AbstractUser): return self.get_absolute_url() def get_num_unread_notifications(self): - return BaseNotification.objects.filter(user=self,read=False).count() + return BaseNotification.objects.filter(user=self, read=False).count() @property def owner(self): @@ -141,6 +141,7 @@ class Location(models.Model): instance.location = location instance.save() + class RescueOrganization(models.Model): def __str__(self): return f"{self.name}" @@ -161,7 +162,10 @@ class RescueOrganization(models.Model): name = models.CharField(max_length=200) trusted = models.BooleanField(default=False, verbose_name=_('Vertrauenswürdig')) - allows_using_materials = models.CharField(max_length=200,default=ALLOW_USE_MATERIALS_CHOICE[USE_MATERIALS_NOT_ASKED], choices=ALLOW_USE_MATERIALS_CHOICE, verbose_name=_('Erlaubt Nutzung von Inhalten')) + allows_using_materials = models.CharField(max_length=200, + default=ALLOW_USE_MATERIALS_CHOICE[USE_MATERIALS_NOT_ASKED], + choices=ALLOW_USE_MATERIALS_CHOICE, + verbose_name=_('Erlaubt Nutzung von Inhalten')) location_string = models.CharField(max_length=200, verbose_name=_("Ort der Organisation")) location = models.ForeignKey(Location, on_delete=models.PROTECT, blank=True, null=True) instagram = models.URLField(null=True, blank=True, verbose_name=_('Instagram Profil')) @@ -282,11 +286,11 @@ class AdoptionNotice(models.Model): if not hasattr(self, 'adoptionnoticestatus'): return False return self.adoptionnoticestatus.is_active - + def set_checked(self): self.last_checked = datetime.now() self.save() - + def set_closed(self): self.last_checked = datetime.now() self.adoptionnoticestatus.set_closed() @@ -540,7 +544,6 @@ class Text(models.Model): return expandable_dict - class Announcement(Text): """ Class to store announcements that should be displayed for all users @@ -639,4 +642,17 @@ class Subscriptions(models.Model): created_at = models.DateTimeField(auto_now_add=True) def __str__(self): - return f"{self.owner} - { self.adoption_notice }" + return f"{self.owner} - {self.adoption_notice}" + + +class Log(models.Model): + """ + Basic class that allows logging random entries for later inspection + """ + user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_("Nutzer*in")) + action = models.CharField(max_length=255, verbose_name=_("Aktion")) + text = models.CharField(max_length=1000, verbose_name=_("Log text")) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"[{self.action}] - {self.user} - {self.created_at.strftime('%H:%M:%S %d-%m-%Y ')}" \ No newline at end of file diff --git a/src/fellchensammlung/views.py b/src/fellchensammlung/views.py index 87a3b68..3c6d1a8 100644 --- a/src/fellchensammlung/views.py +++ b/src/fellchensammlung/views.py @@ -14,7 +14,7 @@ from notfellchen import settings from fellchensammlung import logger from .models import AdoptionNotice, Text, Animal, Rule, Image, Report, ModerationAction, \ User, Location, AdoptionNoticeStatus, Subscriptions, CommentNotification, BaseNotification, RescueOrganization, \ - Species + Species, Log from .forms import AdoptionNoticeForm, AdoptionNoticeFormWithDateWidget, ImageForm, ReportAdoptionNoticeForm, \ CommentForm, ReportCommentForm, AnimalForm, \ AdoptionNoticeSearchForm, AnimalFormWithDateWidget, AdoptionNoticeFormWithDateWidgetAutoAnimal @@ -93,6 +93,10 @@ def adoption_notice_detail(request, adoption_notice_id): comment_instance.user = request.user comment_instance.save() + """Log""" + Log.objects.create(user=request.user, action="comment", + text=f"{request.user} hat Kommentar {comment_instance.pk} zur Vermittlung {adoption_notice_id} hinzugefügt") + # Auto-subscribe user to adoption notice subscription, created = Subscriptions.objects.get_or_create(adoption_notice=adoption_notice, owner=request.user) @@ -140,6 +144,9 @@ def adoption_notice_edit(request, adoption_notice_id): location = Location.get_location_from_string(adoption_notice_instance.location_string) adoption_notice_instance.location = location adoption_notice_instance.save() + + """Log""" + Log.objects.create(user=request.user, action="adoption_notice_edit", text=f"{request.user} hat Vermittlung {adoption_notice.pk} geändert") return redirect(reverse("adoption-notice-detail", args=[adoption_notice_instance.pk], )) else: form = AdoptionNoticeForm(instance=adoption_notice) @@ -216,6 +223,10 @@ def add_adoption_notice(request): Animal.objects.create(owner=request.user, name=f"{species} {i + 1}", adoption_notice=instance, species=species, sex=sex, date_of_birth=date_of_birth) + + """Log""" + Log.objects.create(user=request.user, action="add_adoption_notice", + text=f"{request.user} hat Vermittlung {instance.pk} hinzugefügt") return redirect(reverse("adoption-notice-detail", args=[instance.pk])) else: form = AdoptionNoticeFormWithDateWidgetAutoAnimal(in_adoption_notice_creation_flow=True) @@ -260,6 +271,11 @@ def add_photo_to_animal(request, animal_id): instance.save() animal.photos.add(instance) + + """Log""" + Log.objects.create(user=request.user, action="add_photo_to_animal", + text=f"{request.user} hat Foto {instance.pk} zum Tier {animal.pk} hinzugefügt") + if "save-and-add-another" in request.POST: form = ImageForm(in_flow=True) return render(request, 'fellchensammlung/forms/form-image.html', {'form': form}) @@ -283,6 +299,9 @@ def add_photo_to_adoption_notice(request, adoption_notice_id): instance.owner = request.user instance.save() adoption_notice.photos.add(instance) + """Log""" + Log.objects.create(user=request.user, action="add_photo_to_animal", + text=f"{request.user} hat Foto {instance.pk} zur Vermittlung {adoption_notice.pk} hinzugefügt") if "save-and-add-another" in request.POST: form = ImageForm(in_flow=True) return render(request, 'fellchensammlung/forms/form-image.html', {'form': form}) @@ -309,6 +328,10 @@ def animal_edit(request, animal_id): if form.is_valid(): animal = form.save() + + """Log""" + Log.objects.create(user=request.user, action="add_photo_to_animal", + text=f"{request.user} hat Tier {animal.pk} zum Tier geändert") return redirect(reverse("animal-detail", args=[animal.pk], )) else: form = AnimalForm(instance=animal) @@ -429,6 +452,7 @@ def modqueue(request): @login_required def updatequeue(request): + #TODO: Make sure update can only be done for instances with permission if request.method == "POST": print(request.POST.get("adoption_notice_id")) adoption_notice = AdoptionNotice.objects.get(id=request.POST.get("adoption_notice_id"))