You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

197 lines
5.9 KiB

from django.contrib import admin
from django.core.paginator import Paginator
from django.db import connection
from django.db.models import Count
from django.utils.safestring import mark_safe
from hc.api.models import Channel, Check, Flip, Notification, Ping
from hc.lib.date import format_duration
@admin.register(Check)
class ChecksAdmin(admin.ModelAdmin):
class Media:
css = {
'all': ('css/admin/checks.css',)
}
search_fields = ["name", "user__email", "code"]
list_display = ("id", "name_tags", "created", "code", "timeout_schedule",
"status", "email", "last_start", "last_ping", "n_pings")
list_select_related = ("user", )
list_filter = ("status", "kind", "last_ping",
"last_start")
actions = ["send_alert"]
def email(self, obj):
return obj.user.email if obj.user else None
def name_tags(self, obj):
if not obj.tags:
return obj.name
return "%s [%s]" % (obj.name, obj.tags)
def timeout_schedule(self, obj):
if obj.kind == "simple":
return format_duration(obj.timeout)
elif obj.kind == "cron":
return obj.schedule
else:
return "Unknown"
timeout_schedule.short_description = "Schedule"
def send_alert(self, request, qs):
for check in qs:
check.send_alert()
self.message_user(request, "%d alert(s) sent" % qs.count())
send_alert.short_description = "Send Alert"
class SchemeListFilter(admin.SimpleListFilter):
title = "Scheme"
parameter_name = 'scheme'
def lookups(self, request, model_admin):
return (
('http', "HTTP"),
('https', "HTTPS"),
('email', "Email"),
)
def queryset(self, request, queryset):
if self.value():
queryset = queryset.filter(scheme=self.value())
return queryset
class MethodListFilter(admin.SimpleListFilter):
title = "Method"
parameter_name = 'method'
methods = ["HEAD", "GET", "POST", "PUT", "DELETE"]
def lookups(self, request, model_admin):
return zip(self.methods, self.methods)
def queryset(self, request, queryset):
if self.value():
queryset = queryset.filter(method=self.value())
return queryset
# Adapted from: https://djangosnippets.org/snippets/2593/
class LargeTablePaginator(Paginator):
""" Overrides the count method to get an estimate instead of actual count
when not filtered
"""
def _get_estimate(self):
try:
cursor = connection.cursor()
cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table])
return int(cursor.fetchone()[0])
except:
return 0
def _get_count(self):
"""
Changed to use an estimate if the estimate is greater than 10,000
Returns the total number of objects, across all pages.
"""
if not hasattr(self, "_count") or self._count is None:
try:
estimate = 0
if not self.object_list.query.where:
estimate = self._get_estimate()
if estimate < 10000:
self._count = self.object_list.count()
else:
self._count = estimate
except (AttributeError, TypeError):
# AttributeError if object_list has no count() method.
# TypeError if object_list.count() requires arguments
# (i.e. is of type list).
self._count = len(self.object_list)
return self._count
count = property(_get_count)
@admin.register(Ping)
class PingsAdmin(admin.ModelAdmin):
search_fields = ("owner__name", "owner__code", "owner__user__email")
readonly_fields = ("owner", )
list_select_related = ("owner", "owner__user")
list_display = ("id", "created", "owner", "email", "scheme", "method",
"ua")
list_filter = ("created", SchemeListFilter, MethodListFilter,
"start", "fail")
paginator = LargeTablePaginator
def email(self, obj):
return obj.owner.user.email if obj.owner.user else None
@admin.register(Channel)
class ChannelsAdmin(admin.ModelAdmin):
class Media:
css = {
'all': ('css/admin/channels.css',)
}
search_fields = ["value", "user__email"]
list_select_related = ("user", )
list_display = ("id", "name", "email", "formatted_kind", "value",
"num_notifications")
list_filter = ("kind", )
raw_id_fields = ("user", "checks", )
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(Count("notification", distinct=True))
return qs
def email(self, obj):
return obj.user.email if obj.user else None
@mark_safe
def formatted_kind(self, obj):
if obj.kind == "email" and not obj.email_verified:
return "Email <i>(unconfirmed)</i>"
return obj.get_kind_display()
formatted_kind.short_description = "Kind"
def num_notifications(self, obj):
return obj.notification__count
num_notifications.short_description = "# Notifications"
@admin.register(Notification)
class NotificationsAdmin(admin.ModelAdmin):
search_fields = ["owner__name", "owner__code", "channel__value"]
list_select_related = ("owner", "channel")
list_display = ("id", "created", "check_status", "owner",
"channel_kind", "channel_value")
list_filter = ("created", "check_status", "channel__kind")
def channel_kind(self, obj):
return obj.channel.kind
def channel_value(self, obj):
return obj.channel.value
@admin.register(Flip)
class FlipsAdmin(admin.ModelAdmin):
list_display = ("id", "created", "processed", "owner", "old_status",
"new_status")
raw_id_fields = ("owner", )