2024-05-30 07:26:04 +00:00
|
|
|
import logging
|
|
|
|
|
2024-06-06 21:16:57 +00:00
|
|
|
from django.http import HttpResponseRedirect, JsonResponse
|
2024-03-19 17:18:55 +00:00
|
|
|
from django.shortcuts import render, redirect
|
|
|
|
from django.urls import reverse
|
2024-04-12 21:37:03 +00:00
|
|
|
from django.contrib.auth.decorators import login_required
|
2024-04-14 13:45:57 +00:00
|
|
|
from django.utils import translation
|
2024-05-30 12:37:15 +00:00
|
|
|
from django.core.exceptions import PermissionDenied
|
|
|
|
|
2024-03-25 09:49:56 +00:00
|
|
|
from .mail import mail_admins_new_report
|
2024-04-12 21:37:03 +00:00
|
|
|
from notfellchen import settings
|
2024-03-17 10:26:32 +00:00
|
|
|
|
2024-05-30 07:26:04 +00:00
|
|
|
from fellchensammlung import logger
|
2024-06-08 10:31:22 +00:00
|
|
|
from .models import AdoptionNotice, Text, Animal, Rule, Image, Report, ModerationAction, \
|
|
|
|
User, Location, AdoptionNoticeStatus
|
|
|
|
from .forms import AdoptionNoticeForm, AdoptionNoticeFormWithDateWidget, ImageForm, ReportAdoptionNoticeForm, \
|
|
|
|
CommentForm, ReportCommentForm, AnimalForm, \
|
|
|
|
AdoptionNoticeSearchForm, AnimalFormWithDateWidget
|
2024-05-31 07:58:03 +00:00
|
|
|
from .models import Language, Announcement
|
2024-05-31 08:58:57 +00:00
|
|
|
from .tools.geo import GeoAPI
|
2024-06-06 21:16:57 +00:00
|
|
|
from .tools.metrics import gather_metrics_data
|
2024-03-17 10:26:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
def index(request):
|
2024-03-18 13:53:31 +00:00
|
|
|
"""View function for home page of site."""
|
2024-03-18 13:21:42 +00:00
|
|
|
latest_adoption_list = AdoptionNotice.objects.order_by("-created_at")[:5]
|
2024-05-31 14:00:52 +00:00
|
|
|
active_adoptions = [adoption for adoption in latest_adoption_list if adoption.is_active]
|
2024-05-31 07:58:03 +00:00
|
|
|
language_code = translation.get_language()
|
|
|
|
lang = Language.objects.get(languagecode=language_code)
|
|
|
|
active_announcements = Announcement.get_active_announcements(lang)
|
2024-05-31 14:00:52 +00:00
|
|
|
context = {"adoption_notices": active_adoptions, "announcements": active_announcements}
|
2024-03-18 13:53:31 +00:00
|
|
|
|
|
|
|
return render(request, 'fellchensammlung/index.html', context=context)
|
2024-03-18 07:26:21 +00:00
|
|
|
|
|
|
|
|
2024-04-12 21:37:03 +00:00
|
|
|
def change_language(request):
|
|
|
|
if request.method == 'POST':
|
|
|
|
language_code = request.POST.get('language')
|
|
|
|
if language_code:
|
|
|
|
if language_code != settings.LANGUAGE_CODE and language_code in list(zip(*settings.LANGUAGES))[0]:
|
|
|
|
redirect_path = f'/{language_code}/'
|
|
|
|
elif language_code == settings.LANGUAGE_CODE:
|
|
|
|
redirect_path = '/'
|
|
|
|
else:
|
|
|
|
response = HttpResponseRedirect('/')
|
|
|
|
return response
|
|
|
|
translation.activate(language_code)
|
|
|
|
response = HttpResponseRedirect(redirect_path)
|
|
|
|
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language_code)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2024-03-18 07:26:21 +00:00
|
|
|
def adoption_notice_detail(request, adoption_notice_id):
|
2024-03-20 09:35:40 +00:00
|
|
|
adoption_notice = AdoptionNotice.objects.get(id=adoption_notice_id)
|
2024-05-30 12:37:15 +00:00
|
|
|
if request.method == 'POST':
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
comment_form = CommentForm(request.POST)
|
|
|
|
|
|
|
|
if comment_form.is_valid():
|
|
|
|
comment_instance = comment_form.save(commit=False)
|
|
|
|
comment_instance.adoption_notice_id = adoption_notice_id
|
|
|
|
comment_instance.user = request.user.member
|
|
|
|
comment_instance.save()
|
|
|
|
else:
|
|
|
|
raise PermissionDenied
|
|
|
|
else:
|
|
|
|
comment_form = CommentForm(instance=adoption_notice)
|
2024-05-30 12:39:28 +00:00
|
|
|
context = {"adoption_notice": adoption_notice, "comment_form": comment_form, "user": request.user}
|
2024-03-25 10:04:01 +00:00
|
|
|
return render(request, 'fellchensammlung/details/detail_adoption_notice.html', context=context)
|
2024-03-18 07:26:21 +00:00
|
|
|
|
2024-05-30 09:47:18 +00:00
|
|
|
|
2024-05-31 14:42:32 +00:00
|
|
|
@login_required()
|
2024-05-30 07:54:54 +00:00
|
|
|
def adoption_notice_edit(request, adoption_notice_id):
|
2024-05-30 07:57:20 +00:00
|
|
|
"""
|
|
|
|
Form to update adoption notices
|
|
|
|
"""
|
|
|
|
adoption_notice = AdoptionNotice.objects.get(pk=adoption_notice_id)
|
|
|
|
if request.method == 'POST':
|
2024-05-30 14:38:55 +00:00
|
|
|
form = AdoptionNoticeForm(request.POST, instance=adoption_notice)
|
2024-05-30 07:57:20 +00:00
|
|
|
|
|
|
|
if form.is_valid():
|
|
|
|
adoption_notice_instance = form.save()
|
|
|
|
return redirect(reverse("adoption-notice-detail", args=[adoption_notice_instance.pk], ))
|
|
|
|
else:
|
|
|
|
form = AdoptionNoticeForm(instance=adoption_notice)
|
2024-05-30 07:54:54 +00:00
|
|
|
return render(request, 'fellchensammlung/forms/form-adoption-notice.html', context={"form": form})
|
2024-03-18 07:26:21 +00:00
|
|
|
|
2024-05-30 09:47:18 +00:00
|
|
|
|
2024-03-18 07:26:21 +00:00
|
|
|
def animal_detail(request, animal_id):
|
2024-03-19 05:15:38 +00:00
|
|
|
animal = Animal.objects.get(id=animal_id)
|
|
|
|
context = {"animal": animal}
|
2024-03-25 10:04:01 +00:00
|
|
|
return render(request, 'fellchensammlung/details/detail_animal.html', context=context)
|
2024-03-18 15:36:45 +00:00
|
|
|
|
2024-03-19 17:18:55 +00:00
|
|
|
|
2024-03-18 15:36:45 +00:00
|
|
|
def search(request):
|
2024-05-31 11:40:06 +00:00
|
|
|
if request.method == 'POST':
|
2024-05-31 11:48:24 +00:00
|
|
|
search_form = AdoptionNoticeSearchForm(request.POST)
|
2024-05-31 11:40:06 +00:00
|
|
|
max_distance = int(request.POST.get('max_distance'))
|
|
|
|
if max_distance == "":
|
|
|
|
max_distance = None
|
|
|
|
geo_api = GeoAPI()
|
|
|
|
search_position = geo_api.get_coordinates_from_query(request.POST['postcode'])
|
|
|
|
|
|
|
|
latest_adoption_list = AdoptionNotice.objects.order_by("-created_at")
|
2024-05-31 14:00:52 +00:00
|
|
|
active_adoptions = [adoption for adoption in latest_adoption_list if adoption.is_active]
|
|
|
|
adoption_notices_in_distance = [a for a in active_adoptions if a.in_distance(search_position, max_distance)]
|
2024-05-31 11:48:24 +00:00
|
|
|
context = {"adoption_notices": adoption_notices_in_distance, "search_form": search_form}
|
2024-05-31 11:40:06 +00:00
|
|
|
else:
|
|
|
|
latest_adoption_list = AdoptionNotice.objects.order_by("-created_at")
|
2024-05-31 14:00:52 +00:00
|
|
|
active_adoptions = [adoption for adoption in latest_adoption_list if adoption.is_active]
|
2024-05-31 11:48:24 +00:00
|
|
|
search_form = AdoptionNoticeSearchForm()
|
2024-05-31 14:00:52 +00:00
|
|
|
context = {"adoption_notices": active_adoptions, "search_form": search_form}
|
2024-05-31 11:48:24 +00:00
|
|
|
return render(request, 'fellchensammlung/search.html', context=context)
|
2024-03-19 17:18:55 +00:00
|
|
|
|
|
|
|
|
2024-04-12 21:37:03 +00:00
|
|
|
@login_required
|
2024-05-31 08:58:57 +00:00
|
|
|
def add_adoption_notice(request):
|
2024-03-19 17:18:55 +00:00
|
|
|
if request.method == 'POST':
|
2024-06-08 10:32:57 +00:00
|
|
|
form = AdoptionNoticeFormWithDateWidget(request.POST, request.FILES, in_adoption_notice_creation_flow=True)
|
2024-03-19 17:18:55 +00:00
|
|
|
|
|
|
|
if form.is_valid():
|
2024-06-08 09:43:55 +00:00
|
|
|
instance = form.save(commit=False)
|
|
|
|
instance.created_by = request.user
|
2024-05-31 08:58:57 +00:00
|
|
|
"""Search the location given in the location string and add it to the adoption notice"""
|
2024-05-31 11:40:06 +00:00
|
|
|
location = Location.get_location_from_string(instance.location_string)
|
2024-05-31 08:58:57 +00:00
|
|
|
instance.location = location
|
|
|
|
instance.save()
|
|
|
|
|
2024-06-08 10:32:57 +00:00
|
|
|
# Set correct status
|
|
|
|
if request.user.trust_level >= User.TRUST_LEVEL[User.COORDINATOR]:
|
|
|
|
status = AdoptionNoticeStatus.objects.create(major_status=AdoptionNoticeStatus.ACTIVE,
|
|
|
|
minor_status=AdoptionNoticeStatus.MINOR_STATUS_CHOICES[AdoptionNoticeStatus.ACTIVE]["searching"],
|
|
|
|
adoption_notice=instance)
|
|
|
|
status.save()
|
|
|
|
else:
|
|
|
|
status = AdoptionNoticeStatus.objects.create(major_status=AdoptionNoticeStatus.AWAITING_ACTION,
|
|
|
|
minor_status=AdoptionNoticeStatus.MINOR_STATUS_CHOICES[AdoptionNoticeStatus.AWAITING_ACTION][
|
|
|
|
"waiting_for_review"],
|
|
|
|
adoption_notice=instance)
|
|
|
|
status.save()
|
|
|
|
|
2024-05-31 07:58:55 +00:00
|
|
|
return redirect(reverse("adoption-notice-add-animal", args=[instance.pk]))
|
2024-03-19 17:18:55 +00:00
|
|
|
else:
|
2024-06-08 10:31:22 +00:00
|
|
|
form = AdoptionNoticeFormWithDateWidget(in_adoption_notice_creation_flow=True)
|
2024-03-25 10:04:01 +00:00
|
|
|
return render(request, 'fellchensammlung/forms/form_add_adoption.html', {'form': form})
|
2024-03-19 17:18:55 +00:00
|
|
|
|
2024-05-31 08:56:41 +00:00
|
|
|
|
2024-05-30 13:49:32 +00:00
|
|
|
@login_required
|
|
|
|
def adoption_notice_add_animal(request, adoption_notice_id):
|
|
|
|
if request.method == 'POST':
|
2024-06-08 10:31:22 +00:00
|
|
|
form = AnimalFormWithDateWidget(request.POST, request.FILES)
|
2024-05-30 13:49:32 +00:00
|
|
|
|
|
|
|
if form.is_valid():
|
|
|
|
instance = form.save(commit=False)
|
|
|
|
instance.adoption_notice_id = adoption_notice_id
|
|
|
|
instance.save()
|
|
|
|
form.save_m2m()
|
2024-05-31 08:56:41 +00:00
|
|
|
if "save-and-add-another-animal" in request.POST:
|
2024-06-08 10:31:22 +00:00
|
|
|
form = AnimalFormWithDateWidget(in_adoption_notice_creation_flow=True)
|
2024-05-31 08:56:41 +00:00
|
|
|
return render(request, 'fellchensammlung/forms/form_add_animal_to_adoption.html', {'form': form})
|
2024-05-30 13:49:32 +00:00
|
|
|
else:
|
2024-05-31 08:56:41 +00:00
|
|
|
return redirect(reverse("adoption-notice-detail", args=[adoption_notice_id]))
|
2024-05-30 13:49:32 +00:00
|
|
|
else:
|
2024-06-08 10:31:22 +00:00
|
|
|
form = AnimalFormWithDateWidget(in_adoption_notice_creation_flow=True)
|
2024-05-30 13:49:32 +00:00
|
|
|
return render(request, 'fellchensammlung/forms/form_add_animal_to_adoption.html', {'form': form})
|
2024-03-19 17:18:55 +00:00
|
|
|
|
2024-05-31 08:56:41 +00:00
|
|
|
|
2024-05-31 08:56:43 +00:00
|
|
|
@login_required
|
|
|
|
def add_photo_to_animal(request, animal_id):
|
|
|
|
animal = Animal.objects.get(id=animal_id)
|
|
|
|
if request.method == 'POST':
|
|
|
|
form = ImageForm(request.POST, request.FILES)
|
|
|
|
|
|
|
|
if form.is_valid():
|
|
|
|
instance = form.save()
|
|
|
|
animal.photos.add(instance)
|
|
|
|
if "save-and-add-another" in request.POST:
|
|
|
|
form = ImageForm(in_flow=True)
|
|
|
|
return render(request, 'fellchensammlung/forms/form-image.html', {'form': form})
|
|
|
|
else:
|
|
|
|
return redirect(reverse("animal-detail", args=[animal_id]))
|
|
|
|
else:
|
|
|
|
form = ImageForm(in_flow=True)
|
|
|
|
return render(request, 'fellchensammlung/forms/form-image.html', {'form': form})
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def add_photo_to_adoption_notice(request, adoption_notice_id):
|
|
|
|
adoption_notice = AdoptionNotice.objects.get(id=adoption_notice_id)
|
|
|
|
if request.method == 'POST':
|
|
|
|
form = ImageForm(request.POST, request.FILES)
|
|
|
|
|
|
|
|
if form.is_valid():
|
|
|
|
instance = form.save()
|
|
|
|
adoption_notice.photos.add(instance)
|
|
|
|
if "save-and-add-another" in request.POST:
|
|
|
|
form = ImageForm(in_flow=True)
|
|
|
|
return render(request, 'fellchensammlung/forms/form-image.html', {'form': form})
|
|
|
|
else:
|
|
|
|
return redirect(reverse("adoption-notice-detail", args=[adoption_notice_id]))
|
|
|
|
else:
|
|
|
|
form = ImageForm(in_flow=True)
|
|
|
|
return render(request, 'fellchensammlung/forms/form-image.html', {'form': form})
|
|
|
|
|
|
|
|
|
2024-05-10 11:54:16 +00:00
|
|
|
@login_required
|
2024-05-30 07:54:54 +00:00
|
|
|
def animal_edit(request, animal_id):
|
2024-05-10 11:54:16 +00:00
|
|
|
"""
|
|
|
|
View implements the following methods
|
|
|
|
* Updating an Animal
|
|
|
|
"""
|
2024-05-30 14:57:47 +00:00
|
|
|
animal = Animal.objects.get(pk=animal_id)
|
2024-05-10 11:54:16 +00:00
|
|
|
if request.method == 'POST':
|
2024-05-30 14:57:47 +00:00
|
|
|
form = AnimalForm(request.POST, instance=animal)
|
2024-05-10 11:54:16 +00:00
|
|
|
|
2024-05-30 14:57:47 +00:00
|
|
|
if form.is_valid():
|
|
|
|
animal = form.save()
|
|
|
|
return redirect(reverse("animal-detail", args=[animal.pk], ))
|
2024-03-19 17:18:55 +00:00
|
|
|
else:
|
2024-05-30 14:57:47 +00:00
|
|
|
form = AnimalForm(instance=animal)
|
|
|
|
return render(request, 'fellchensammlung/forms/form-adoption-notice.html', context={"form": form})
|
2024-03-19 17:18:55 +00:00
|
|
|
|
2024-03-18 15:36:45 +00:00
|
|
|
|
2024-03-18 15:41:22 +00:00
|
|
|
def about(request):
|
2024-03-20 10:02:24 +00:00
|
|
|
rules = Rule.objects.all()
|
2024-04-14 12:39:49 +00:00
|
|
|
|
2024-04-14 13:45:57 +00:00
|
|
|
language_code = translation.get_language()
|
2024-04-14 13:39:54 +00:00
|
|
|
lang = Language.objects.get(languagecode=language_code)
|
2024-04-14 12:39:49 +00:00
|
|
|
|
|
|
|
legal = {}
|
|
|
|
for text_code in ["terms_of_service", "privacy_statement", "imprint"]:
|
|
|
|
try:
|
2024-05-01 08:09:36 +00:00
|
|
|
legal[text_code] = Text.objects.get(text_code=text_code, language=lang, )
|
2024-04-14 12:39:49 +00:00
|
|
|
except Text.DoesNotExist:
|
|
|
|
legal[text_code] = None
|
|
|
|
|
2024-05-01 08:09:36 +00:00
|
|
|
context = {"rules": rules, }
|
2024-04-14 12:39:49 +00:00
|
|
|
context.update(legal)
|
2024-03-18 15:41:22 +00:00
|
|
|
return render(
|
|
|
|
request,
|
|
|
|
"fellchensammlung/about.html",
|
|
|
|
context=context
|
|
|
|
)
|
2024-03-22 11:45:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
def report_adoption(request, adoption_notice_id):
|
|
|
|
"""
|
|
|
|
Form to report adoption notices
|
|
|
|
"""
|
|
|
|
if request.method == 'POST':
|
2024-05-30 13:46:51 +00:00
|
|
|
form = ReportAdoptionNoticeForm(request.POST)
|
2024-03-22 11:45:50 +00:00
|
|
|
|
|
|
|
if form.is_valid():
|
|
|
|
report_instance = form.save(commit=False)
|
|
|
|
report_instance.adoption_notice_id = adoption_notice_id
|
|
|
|
report_instance.status = Report.WAITING
|
|
|
|
report_instance.save()
|
2024-05-30 13:46:51 +00:00
|
|
|
form.save_m2m()
|
2024-03-25 09:49:56 +00:00
|
|
|
mail_admins_new_report(report_instance)
|
2024-03-22 11:45:50 +00:00
|
|
|
return redirect(reverse("report-detail-success", args=[report_instance.pk], ))
|
|
|
|
else:
|
2024-05-30 13:46:51 +00:00
|
|
|
form = ReportAdoptionNoticeForm()
|
|
|
|
return render(request, 'fellchensammlung/forms/form-report.html', {'form': form})
|
|
|
|
|
|
|
|
|
|
|
|
def report_comment(request, comment_id):
|
|
|
|
"""
|
|
|
|
Form to report comments
|
|
|
|
"""
|
|
|
|
if request.method == 'POST':
|
|
|
|
form = ReportCommentForm(request.POST)
|
|
|
|
|
|
|
|
if form.is_valid():
|
|
|
|
report_instance = form.save(commit=False)
|
|
|
|
report_instance.reported_comment_id = comment_id
|
|
|
|
report_instance.status = Report.WAITING
|
|
|
|
report_instance.save()
|
|
|
|
form.save_m2m()
|
|
|
|
mail_admins_new_report(report_instance)
|
|
|
|
return redirect(reverse("report-detail-success", args=[report_instance.pk], ))
|
|
|
|
else:
|
|
|
|
form = ReportCommentForm()
|
2024-03-25 10:04:01 +00:00
|
|
|
return render(request, 'fellchensammlung/forms/form-report.html', {'form': form})
|
2024-03-22 11:45:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
def report_detail(request, report_id, form_complete=False):
|
|
|
|
"""
|
|
|
|
Detailed view of a report, including moderation actions
|
|
|
|
"""
|
|
|
|
report = Report.objects.get(pk=report_id)
|
|
|
|
moderation_actions = ModerationAction.objects.filter(report_id=report_id)
|
|
|
|
|
|
|
|
context = {"report": report, "moderation_actions": moderation_actions, "form_complete": form_complete}
|
|
|
|
|
2024-03-25 10:04:01 +00:00
|
|
|
return render(request, 'fellchensammlung/details/detail-report.html', context)
|
2024-03-22 11:45:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
def report_detail_success(request, report_id):
|
|
|
|
"""
|
|
|
|
Calls the report detail view with form_complete set to true, so success message shows
|
|
|
|
"""
|
|
|
|
return report_detail(request, report_id, form_complete=True)
|
2024-03-23 21:20:31 +00:00
|
|
|
|
|
|
|
|
2024-06-08 07:31:23 +00:00
|
|
|
def user_detail(request, user_id):
|
2024-04-07 07:06:18 +00:00
|
|
|
member = Member.objects.get(id=user_id)
|
2024-03-23 21:20:31 +00:00
|
|
|
context = {"member": member}
|
2024-04-07 07:03:20 +00:00
|
|
|
return render(request, 'fellchensammlung/details/detail-member.html', context=context)
|
|
|
|
|
|
|
|
|
|
|
|
def modqueue(request):
|
|
|
|
open_reports = Report.objects.filter(status=Report.WAITING)
|
|
|
|
context = {"reports": open_reports}
|
|
|
|
return render(request, 'fellchensammlung/modqueue.html', context=context)
|
2024-06-06 21:16:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
def metrics(request):
|
|
|
|
data = gather_metrics_data()
|
|
|
|
return JsonResponse(data)
|