Compare commits

..

No commits in common. "bf54bc5d51a69017c975c39b75e8e78a761521bb" and "4e953c83eac1c9ec1c2fba8c522c58739fd05e0c" have entirely different histories.

9 changed files with 19 additions and 147 deletions

View File

@ -45,14 +45,13 @@ There is a system for customizing texts in Notfellchen. Not every change of a te
Therefore, a solution is used where a number of predefined texts per site are supported. These markdown texts will then be included in the site, if defined. Therefore, a solution is used where a number of predefined texts per site are supported. These markdown texts will then be included in the site, if defined.
| Textcode | Location | | Textcode | Location |
|-------------------------|-----------------------| |---------------------|----------|
| `how_to` | Index | | `how_to` | Index |
| `introduction` | Index | | `introduction` | Index |
| `privacy_statement` | About | | `privacy_statement` | About |
| `terms_of_service` | About | | `terms_of_service` | About |
| `imprint` | About | | `imprint` | About |
| `about_us` | About | | `about_us` | About |
| `external_site_warning` | External Site Warning |
| Any rule | About | | Any rule | About |
# Developer Notes # Developer Notes

View File

@ -1,16 +1,11 @@
import csv from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib import admin from django.contrib import admin
from django.http import HttpResponse
from django.utils.html import format_html from django.utils.html import format_html
from django.urls import reverse
from django.utils.http import urlencode
from .models import User, Language, Text, ReportComment, ReportAdoptionNotice, Log, Timestamp from .models import User, Language, Text, ReportComment, ReportAdoptionNotice, Log, Timestamp
from .models import Animal, Species, RescueOrganization, AdoptionNotice, Location, Rule, Image, ModerationAction, \ from .models import Animal, Species, RescueOrganization, AdoptionNotice, Location, Rule, Image, ModerationAction, \
Comment, Report, Announcement, AdoptionNoticeStatus, User, Subscriptions Comment, Report, Announcement, AdoptionNoticeStatus, User, Subscriptions
from django.utils.translation import gettext_lazy as _
class StatusInline(admin.StackedInline): class StatusInline(admin.StackedInline):
@ -20,44 +15,14 @@ class StatusInline(admin.StackedInline):
@admin.register(AdoptionNotice) @admin.register(AdoptionNotice)
class AdoptionNoticeAdmin(admin.ModelAdmin): class AdoptionNoticeAdmin(admin.ModelAdmin):
search_fields = ("name__icontains", "description__icontains") search_fields = ("name__icontains", "description__icontains")
list_filter = ("owner",)
inlines = [ inlines = [
StatusInline, StatusInline,
] ]
# Re-register UserAdmin # Re-register UserAdmin
@admin.register(User) admin.site.register(User)
class UserAdmin(admin.ModelAdmin):
search_fields = ("usernamname__icontains", "first_name__icontains", "last_name__icontains", "email__icontains")
list_display = ("username", "email", "trust_level", "is_active", "view_adoption_notices")
list_filter = ("is_active", "trust_level",)
actions = ("export_as_csv",)
def view_adoption_notices(self, obj):
count = obj.adoption_notices.count()
url = (
reverse("admin:fellchensammlung_adoptionnotice_changelist")
+ "?"
+ urlencode({"owner__id": f"{obj.id}"})
)
return format_html('<a href="{}">{} Adoption Notices</a>', url, count)
def export_as_csv(self, request, queryset):
meta = self.model._meta
field_names = [field.name for field in meta.fields]
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
writer = csv.writer(response)
writer.writerow(field_names)
for obj in queryset:
row = writer.writerow([getattr(obj, field) for field in field_names])
return response
export_as_csv.short_description = _("Ausgewählte User exportieren")
def _reported_content_link(obj): def _reported_content_link(obj):
reported_content = obj.reported_content reported_content = obj.reported_content
@ -97,9 +62,6 @@ class RescueOrganizationAdmin(admin.ModelAdmin):
class TextAdmin(admin.ModelAdmin): class TextAdmin(admin.ModelAdmin):
search_fields = ("title__icontains", "text_code__icontains",) search_fields = ("title__icontains", "text_code__icontains",)
@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_filter = ("user",)
admin.site.register(Animal) admin.site.register(Animal)
admin.site.register(Species) admin.site.register(Species)

View File

@ -1,8 +1,4 @@
from venv import create
import django.conf.global_settings import django.conf.global_settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext from django.utils.translation import gettext
@ -14,7 +10,6 @@ from notfellchen.settings import host
NEWLINE = "\r\n" NEWLINE = "\r\n"
def mail_admins_new_report(report): def mail_admins_new_report(report):
subject = _("Neue Meldung") subject = _("Neue Meldung")
for moderator in User.objects.filter(trust_level__gt=User.TRUST_LEVEL[User.MODERATOR]): for moderator in User.objects.filter(trust_level__gt=User.TRUST_LEVEL[User.MODERATOR]):
@ -36,21 +31,3 @@ def mail_admins_new_report(report):
message = mail.EmailMessage(subject, body_text, settings.DEFAULT_FROM_EMAIL, [moderator.email]) message = mail.EmailMessage(subject, body_text, settings.DEFAULT_FROM_EMAIL, [moderator.email])
print("Sending email to ", moderator.email) print("Sending email to ", moderator.email)
message.send() message.send()
@receiver(post_save, sender=User)
def mail_admins_new_member(sender, instance: User, created: bool, **kwargs):
if not created:
return
subject = _("Neuer User") + f": {instance.username}"
for moderator in User.objects.filter(trust_level__gt=User.TRUST_LEVEL[User.MODERATOR]):
greeting = _("Moin,") + "{NEWLINE}"
new_report_text = _("es hat sich eine neue Person registriert.") + "{NEWLINE}"
user_detail_text = _("Username") + f": {instance.username}{NEWLINE}" + _(
"E-Mail") + f": {instance.email}{NEWLINE}"
user_url = "https://" + host + instance.get_absolute_url()
link_text = f"Um alle Details zu sehen, geh bitte auf: {user_url}"
body_text = greeting + new_report_text + user_detail_text + link_text
message = mail.EmailMessage(subject, body_text, settings.DEFAULT_FROM_EMAIL, [moderator.email])
print("Sending email to ", moderator.email)
message.send()

View File

@ -74,10 +74,6 @@ class User(AbstractUser):
def get_num_unread_notifications(self): 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 adoption_notices(self):
return AdoptionNotice.objects.filter(owner=self)
@property @property
def owner(self): def owner(self):
return self return self

View File

@ -1,15 +1,10 @@
{% extends "fellchensammlung/base_generic.html" %} {% extends "fellchensammlung/base_generic.html" %}
{% load i18n %} {% load i18n %}
{% load custom_tags %}
{% block content %} {% block content %}
<div class="card"> <div class="card">
{% if external_site_warning %}
{{ external_site_warning.content | render_markdown }}
{% else %}
{% blocktranslate %} {% blocktranslate %}
<p>Achtung du verlässt notfellchen.org</p> <p>Achtung du verlässt notfellchen.org</p>
{% endblocktranslate %} {% endblocktranslate %}
{% endif %}
<a href="{{ url }}" class="btn button" >{% translate "Weiter" %}</a> <a href="{{ url }}" class="btn button" >{% translate "Weiter" %}</a>
</div> </div>
{% endblock content %} {% endblock content %}

View File

@ -537,7 +537,6 @@ def external_site_warning(request):
context = {"url": url} context = {"url": url}
language_code = translation.get_language() language_code = translation.get_language()
lang = Language.objects.get(languagecode=language_code) lang = Language.objects.get(languagecode=language_code)
texts = Text.get_texts(["external_site_warning", "good_adoption_practices"], language=lang) Text.get_texts(["external_site_warning", "good_adoption_practices"], language=lang)
context.update(texts)
return render(request, 'fellchensammlung/external_site_warning.html', context=context) return render(request, 'fellchensammlung/external_site_warning.html', context=context)

View File

@ -1,25 +0,0 @@
from django.test import TestCase
from fellchensammlung.forms import AdoptionNoticeFormWithDateWidgetAutoAnimal
from fellchensammlung.models import Species
from model_bakery import baker
class TestAdoptionNoticeFormWithDateWidgetAutoAnimal(TestCase):
@classmethod
def setUpTestData(cls):
rat = baker.make(Species, name="Farbratte")
def test_forms(self):
form_data = {"name": "TestAdoption3",
"species": Species.objects.first(),
"num_animals": "2",
"date_of_birth": "2024-11-04",
"sex": "M",
"group_only": "on",
"searching_since": "2024-11-10",
"location_string": "Mannheim",
"description": "Blaaaa",
"further_information": "https://notfellchen.org",
"save-and-add-another-animal": "Speichern"}
form = AdoptionNoticeFormWithDateWidgetAutoAnimal(data=form_data)
self.assertTrue(form.is_valid())

View File

@ -4,15 +4,7 @@ from django.utils import timezone
from django.test import TestCase from django.test import TestCase
from model_bakery import baker from model_bakery import baker
from fellchensammlung.models import Announcement, Language, User from fellchensammlung.models import Announcement, Language
class UserTest(TestCase):
def test_creating_user(self):
test_user_1 = User.objects.create(username="Testuser1", password="SUPERSECRET", email="test@example.org")
self.assertTrue(test_user_1.trust_level == 1)
self.assertTrue(test_user_1.trust_level == User.TRUST_LEVEL[User.MEMBER])
class AnnouncementTest(TestCase): class AnnouncementTest(TestCase):
@ -77,3 +69,4 @@ class AnnouncementTest(TestCase):
self.assertTrue(self.announcement2 not in active_announcements) self.assertTrue(self.announcement2 not in active_announcements)
self.assertTrue(self.announcement4 not in active_announcements) self.assertTrue(self.announcement4 not in active_announcements)
self.assertTrue(self.announcement5 in active_announcements) self.assertTrue(self.announcement5 in active_announcements)

View File

@ -20,8 +20,7 @@ class AnimalAndAdoptionTest(TestCase):
first_name="Max", first_name="Max",
last_name="Müller", last_name="Müller",
password='12345') password='12345')
test_user0.trust_level = User.TRUST_LEVEL[User.ADMIN] test_user1.save()
test_user0.save()
adoption1 = baker.make(AdoptionNotice, name="TestAdoption1") adoption1 = baker.make(AdoptionNotice, name="TestAdoption1")
rat = baker.make(Species, name="Farbratte") rat = baker.make(Species, name="Farbratte")
@ -51,28 +50,6 @@ class AnimalAndAdoptionTest(TestCase):
self.assertContains(response, "TestAdoption1") self.assertContains(response, "TestAdoption1")
self.assertContains(response, "Rat1") self.assertContains(response, "Rat1")
def test_creating_AN_as_admin(self):
self.client.login(username='testuser0', password='12345')
form_data = {"name": "TestAdoption4",
"species": Species.objects.first().pk,
"num_animals": "2",
"date_of_birth": "2024-11-04",
"sex": "M",
"group_only": "on",
"searching_since": "2024-11-10",
"location_string": "Mannheim",
"description": "Blaaaa",
"further_information": "https://notfellchen.org",
"save-and-add-another-animal": "Speichern"}
response = self.client.post(reverse('add-adoption'), data=form_data)
print(response.content)
self.assertTrue(response.status_code < 400)
self.assertTrue(AdoptionNotice.objects.get(name="TestAdoption4").is_active)
class SearchTest(TestCase): class SearchTest(TestCase):
@classmethod @classmethod
@ -192,4 +169,3 @@ class UpdateQueueTest(TestCase):
self.assertNotContains(response, "TestAdoption3") self.assertNotContains(response, "TestAdoption3")
self.assertFalse(self.adoption3.is_active) self.assertFalse(self.adoption3.is_active)
self.assertEqual(self.adoption3.adoptionnoticestatus.major_status, AdoptionNoticeStatus.CLOSED) self.assertEqual(self.adoption3.adoptionnoticestatus.major_status, AdoptionNoticeStatus.CLOSED)