feat: Add instance health check, allow clean locations for rescue orgs
This commit is contained in:
parent
6f68d0cb51
commit
cabb7f7181
@ -1,5 +1,6 @@
|
|||||||
from django.core.management import BaseCommand
|
from django.core.management import BaseCommand
|
||||||
from fellchensammlung.models import AdoptionNotice, Location
|
from fellchensammlung.models import AdoptionNotice, Location
|
||||||
|
from fellchensammlung.tools.geo import clean_locations
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@ -14,19 +15,4 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
adoption_notices_without_location = AdoptionNotice.objects.filter(location__isnull=True)
|
clean_locations(quiet=False)
|
||||||
num_of_all = AdoptionNotice.objects.count()
|
|
||||||
num_without_location = adoption_notices_without_location.count()
|
|
||||||
print(f"From {num_of_all} there are {num_without_location} adoption notices without location "
|
|
||||||
f"({num_without_location/num_of_all*100:.2f}%)")
|
|
||||||
for adoption_notice in adoption_notices_without_location:
|
|
||||||
print(f"Searching {adoption_notice.location_string} in Nominatim")
|
|
||||||
location = Location.get_location_from_string(adoption_notice.location_string)
|
|
||||||
if location:
|
|
||||||
adoption_notice.location = location
|
|
||||||
adoption_notice.save()
|
|
||||||
|
|
||||||
adoption_notices_without_location_new = AdoptionNotice.objects.filter(location__isnull=True)
|
|
||||||
num_without_location_new = adoption_notices_without_location_new.count()
|
|
||||||
num_new = num_without_location - num_without_location_new
|
|
||||||
print(f"Added {num_new} new locations")
|
|
@ -0,0 +1,15 @@
|
|||||||
|
{% extends "fellchensammlung/base_generic.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="card">
|
||||||
|
<h1>{% translate "Instanz-Check" %}</h1>
|
||||||
|
<p>{% translate "Nicht-lokalisierte Vermittlungen" %}: {{ number_not_geocoded_adoption_notices }}/{{ number_of_adoption_notices }}</p>
|
||||||
|
<p>{% translate "Nicht-lokalisierte Tierschutzorganisationen" %}: {{ number_not_geocoded_rescue_orgs }}/{{ number_of_rescue_orgs }}</p>
|
||||||
|
</div>
|
||||||
|
<form class="notification-card-mark-read" method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="hidden" name="action" value="clean_locations">
|
||||||
|
<button class="btn2" type="submit" id="submit"><i class="fa-solid fa-broom"></i> {% translate "Erneut lokalisieren" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
44
src/fellchensammlung/tools/admin.py
Normal file
44
src/fellchensammlung/tools/admin.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
from fellchensammlung.models import AdoptionNotice, Location, RescueOrganization
|
||||||
|
|
||||||
|
def clean_locations(quiet=True):
|
||||||
|
# ADOPTION NOTICES
|
||||||
|
adoption_notices_without_location = AdoptionNotice.objects.filter(location__isnull=True)
|
||||||
|
num_of_all = AdoptionNotice.objects.count()
|
||||||
|
num_without_location = adoption_notices_without_location.count()
|
||||||
|
if not quiet:
|
||||||
|
print(f"From {num_of_all} there are {num_without_location} adoption notices without location "
|
||||||
|
f"({num_without_location/num_of_all*100:.2f}%)")
|
||||||
|
for adoption_notice in adoption_notices_without_location:
|
||||||
|
if not quiet:
|
||||||
|
print(f"Searching {adoption_notice.location_string} in Nominatim")
|
||||||
|
location = Location.get_location_from_string(adoption_notice.location_string)
|
||||||
|
if location:
|
||||||
|
adoption_notice.location = location
|
||||||
|
adoption_notice.save()
|
||||||
|
|
||||||
|
adoption_notices_without_location_new = AdoptionNotice.objects.filter(location__isnull=True)
|
||||||
|
num_without_location_new = adoption_notices_without_location_new.count()
|
||||||
|
num_new = num_without_location - num_without_location_new
|
||||||
|
if not quiet:
|
||||||
|
print(f"Added {num_new} new locations")
|
||||||
|
|
||||||
|
# RESCUE ORGANIZATIONS
|
||||||
|
rescue_orgs_without_location = RescueOrganization.objects.filter(location__isnull=True)
|
||||||
|
num_of_all = RescueOrganization.objects.count()
|
||||||
|
num_without_location = rescue_orgs_without_location.count()
|
||||||
|
if not quiet:
|
||||||
|
print(f"From {num_of_all} there are {num_without_location} adoption notices without location "
|
||||||
|
f"({num_without_location/num_of_all*100:.2f}%)")
|
||||||
|
for rescue_org in rescue_orgs_without_location:
|
||||||
|
if not quiet:
|
||||||
|
print(f"Searching {rescue_org.location_string} in Nominatim")
|
||||||
|
location = Location.get_location_from_string(rescue_org.location_string)
|
||||||
|
if location:
|
||||||
|
rescue_org.location = location
|
||||||
|
rescue_org.save()
|
||||||
|
|
||||||
|
rescue_orgs_without_location_new = RescueOrganization.objects.filter(location__isnull=True)
|
||||||
|
num_without_location_new = rescue_orgs_without_location_new.count()
|
||||||
|
num_new = num_without_location - num_without_location_new
|
||||||
|
if not quiet:
|
||||||
|
print(f"Added {num_new} new locations")
|
@ -1,11 +1,11 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
|
from math import radians, sqrt, sin, cos, atan2
|
||||||
|
|
||||||
from notfellchen import __version__ as nf_version
|
from notfellchen import __version__ as nf_version
|
||||||
from notfellchen import settings
|
from notfellchen import settings
|
||||||
|
|
||||||
from math import radians, sqrt, sin, cos, atan2
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_distance_between_coordinates(position1, position2):
|
def calculate_distance_between_coordinates(position1, position2):
|
||||||
|
@ -59,6 +59,11 @@ urlpatterns = [
|
|||||||
path('accounts/', include('django_registration.backends.activation.urls')),
|
path('accounts/', include('django_registration.backends.activation.urls')),
|
||||||
path('accounts/', include('django.contrib.auth.urls')),
|
path('accounts/', include('django.contrib.auth.urls')),
|
||||||
|
|
||||||
path('change-language', views.change_language, name="change-language")
|
path('change-language', views.change_language, name="change-language"),
|
||||||
|
|
||||||
|
###########
|
||||||
|
## ADMIN ##
|
||||||
|
###########
|
||||||
|
path('instance-health-check', views.instance_health_check, name="instance-health-check")
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -6,20 +6,21 @@ from django.urls import reverse
|
|||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.contrib.auth.decorators import user_passes_test
|
||||||
|
|
||||||
from .mail import mail_admins_new_report
|
from .mail import mail_admins_new_report
|
||||||
from notfellchen import settings
|
from notfellchen import settings
|
||||||
|
|
||||||
from fellchensammlung import logger
|
from fellchensammlung import logger
|
||||||
from .models import AdoptionNotice, Text, Animal, Rule, Image, Report, ModerationAction, \
|
from .models import AdoptionNotice, Text, Animal, Rule, Image, Report, ModerationAction, \
|
||||||
User, Location, AdoptionNoticeStatus, Subscriptions, CommentNotification, BaseNotification
|
User, Location, AdoptionNoticeStatus, Subscriptions, CommentNotification, BaseNotification, RescueOrganization
|
||||||
from .forms import AdoptionNoticeForm, AdoptionNoticeFormWithDateWidget, ImageForm, ReportAdoptionNoticeForm, \
|
from .forms import AdoptionNoticeForm, AdoptionNoticeFormWithDateWidget, ImageForm, ReportAdoptionNoticeForm, \
|
||||||
CommentForm, ReportCommentForm, AnimalForm, \
|
CommentForm, ReportCommentForm, AnimalForm, \
|
||||||
AdoptionNoticeSearchForm, AnimalFormWithDateWidget
|
AdoptionNoticeSearchForm, AnimalFormWithDateWidget
|
||||||
from .models import Language, Announcement
|
from .models import Language, Announcement
|
||||||
from .tools.geo import GeoAPI
|
from .tools.geo import GeoAPI
|
||||||
from .tools.metrics import gather_metrics_data
|
from .tools.metrics import gather_metrics_data
|
||||||
from django.contrib.auth.decorators import user_passes_test
|
from .tools.admin import clean_locations
|
||||||
|
|
||||||
|
|
||||||
def user_is_trust_level_or_above(user, trust_level=User.MODERATOR):
|
def user_is_trust_level_or_above(user, trust_level=User.MODERATOR):
|
||||||
@ -411,3 +412,28 @@ def map(request):
|
|||||||
def metrics(request):
|
def metrics(request):
|
||||||
data = gather_metrics_data()
|
data = gather_metrics_data()
|
||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def instance_health_check(request):
|
||||||
|
"""
|
||||||
|
Allows an administrator to check common problems of an instance
|
||||||
|
"""
|
||||||
|
if request.method == "POST":
|
||||||
|
action = request.POST.get("action")
|
||||||
|
if action == "clean_locations":
|
||||||
|
clean_locations(quiet=False)
|
||||||
|
|
||||||
|
number_of_adoption_notices = AdoptionNotice.objects.all().count()
|
||||||
|
number_not_geocoded_adoption_notices = AdoptionNotice.objects.filter(location__isnull=True).count()
|
||||||
|
|
||||||
|
number_of_rescue_orgs = RescueOrganization.objects.all().count()
|
||||||
|
number_not_geocoded_rescue_orgs = RescueOrganization.objects.filter(location__isnull=True).count()
|
||||||
|
context = {
|
||||||
|
"number_of_adoption_notices": number_of_adoption_notices,
|
||||||
|
"number_not_geocoded_adoption_notices": number_not_geocoded_adoption_notices,
|
||||||
|
"number_of_rescue_orgs": number_of_rescue_orgs,
|
||||||
|
"number_not_geocoded_rescue_orgs": number_not_geocoded_rescue_orgs
|
||||||
|
}
|
||||||
|
return render(request, 'fellchensammlung/instance-health-check.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user