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.

211 lines
6.3 KiB

10 years ago
6 years ago
10 years ago
10 years ago
6 years ago
6 years ago
9 years ago
6 years ago
6 years ago
6 years ago
6 years ago
9 years ago
6 years ago
9 years ago
9 years ago
6 years ago
9 years ago
9 years ago
6 years ago
9 years ago
9 years ago
6 years ago
9 years ago
6 years ago
6 years ago
  1. from django.contrib import admin
  2. from django.core.paginator import Paginator
  3. from django.db import connection
  4. from django.db.models import Count
  5. from django.utils.safestring import mark_safe
  6. from hc.api.models import Channel, Check, Flip, Notification, Ping
  7. from hc.lib.date import format_duration
  8. @admin.register(Check)
  9. class ChecksAdmin(admin.ModelAdmin):
  10. class Media:
  11. css = {
  12. 'all': ('css/admin/checks.css',)
  13. }
  14. search_fields = ["name", "user__email", "code"]
  15. list_display = ("id", "name_tags", "created", "code", "timeout_schedule",
  16. "status", "email", "last_start", "last_ping", "n_pings")
  17. list_select_related = ("user", )
  18. list_filter = ("status", "kind", "last_ping",
  19. "last_start")
  20. actions = ["send_alert"]
  21. def email(self, obj):
  22. return obj.user.email if obj.user else None
  23. def name_tags(self, obj):
  24. if not obj.tags:
  25. return obj.name
  26. return "%s [%s]" % (obj.name, obj.tags)
  27. def timeout_schedule(self, obj):
  28. if obj.kind == "simple":
  29. return format_duration(obj.timeout)
  30. elif obj.kind == "cron":
  31. return obj.schedule
  32. else:
  33. return "Unknown"
  34. timeout_schedule.short_description = "Schedule"
  35. def send_alert(self, request, qs):
  36. for check in qs:
  37. check.send_alert()
  38. self.message_user(request, "%d alert(s) sent" % qs.count())
  39. send_alert.short_description = "Send Alert"
  40. class SchemeListFilter(admin.SimpleListFilter):
  41. title = "Scheme"
  42. parameter_name = 'scheme'
  43. def lookups(self, request, model_admin):
  44. return (
  45. ('http', "HTTP"),
  46. ('https', "HTTPS"),
  47. ('email', "Email"),
  48. )
  49. def queryset(self, request, queryset):
  50. if self.value():
  51. queryset = queryset.filter(scheme=self.value())
  52. return queryset
  53. class MethodListFilter(admin.SimpleListFilter):
  54. title = "Method"
  55. parameter_name = 'method'
  56. methods = ["HEAD", "GET", "POST", "PUT", "DELETE"]
  57. def lookups(self, request, model_admin):
  58. return zip(self.methods, self.methods)
  59. def queryset(self, request, queryset):
  60. if self.value():
  61. queryset = queryset.filter(method=self.value())
  62. return queryset
  63. class KindListFilter(admin.SimpleListFilter):
  64. title = "Kind"
  65. parameter_name = 'kind'
  66. kinds = ["start", "fail"]
  67. def lookups(self, request, model_admin):
  68. return zip(self.kinds, self.kinds)
  69. def queryset(self, request, queryset):
  70. if self.value():
  71. queryset = queryset.filter(kind=self.value())
  72. return queryset
  73. # Adapted from: https://djangosnippets.org/snippets/2593/
  74. class LargeTablePaginator(Paginator):
  75. """ Overrides the count method to get an estimate instead of actual count
  76. when not filtered
  77. """
  78. def _get_estimate(self):
  79. try:
  80. cursor = connection.cursor()
  81. cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
  82. [self.object_list.query.model._meta.db_table])
  83. return int(cursor.fetchone()[0])
  84. except:
  85. return 0
  86. def _get_count(self):
  87. """
  88. Changed to use an estimate if the estimate is greater than 10,000
  89. Returns the total number of objects, across all pages.
  90. """
  91. if not hasattr(self, "_count") or self._count is None:
  92. try:
  93. estimate = 0
  94. if not self.object_list.query.where:
  95. estimate = self._get_estimate()
  96. if estimate < 10000:
  97. self._count = self.object_list.count()
  98. else:
  99. self._count = estimate
  100. except (AttributeError, TypeError):
  101. # AttributeError if object_list has no count() method.
  102. # TypeError if object_list.count() requires arguments
  103. # (i.e. is of type list).
  104. self._count = len(self.object_list)
  105. return self._count
  106. count = property(_get_count)
  107. @admin.register(Ping)
  108. class PingsAdmin(admin.ModelAdmin):
  109. search_fields = ("owner__name", "owner__code", "owner__user__email")
  110. readonly_fields = ("owner", )
  111. list_select_related = ("owner", "owner__user")
  112. list_display = ("id", "created", "owner", "email", "scheme", "method",
  113. "ua")
  114. list_filter = ("created", SchemeListFilter, MethodListFilter,
  115. KindListFilter)
  116. paginator = LargeTablePaginator
  117. def email(self, obj):
  118. return obj.owner.user.email if obj.owner.user else None
  119. @admin.register(Channel)
  120. class ChannelsAdmin(admin.ModelAdmin):
  121. class Media:
  122. css = {
  123. 'all': ('css/admin/channels.css',)
  124. }
  125. search_fields = ["value", "user__email"]
  126. list_select_related = ("user", )
  127. list_display = ("id", "name", "email", "formatted_kind", "value",
  128. "num_notifications")
  129. list_filter = ("kind", )
  130. raw_id_fields = ("user", "checks", )
  131. def get_queryset(self, request):
  132. qs = super().get_queryset(request)
  133. qs = qs.annotate(Count("notification", distinct=True))
  134. return qs
  135. def email(self, obj):
  136. return obj.user.email if obj.user else None
  137. @mark_safe
  138. def formatted_kind(self, obj):
  139. if obj.kind == "email" and not obj.email_verified:
  140. return "Email <i>(unconfirmed)</i>"
  141. return obj.get_kind_display()
  142. formatted_kind.short_description = "Kind"
  143. def num_notifications(self, obj):
  144. return obj.notification__count
  145. num_notifications.short_description = "# Notifications"
  146. @admin.register(Notification)
  147. class NotificationsAdmin(admin.ModelAdmin):
  148. search_fields = ["owner__name", "owner__code", "channel__value"]
  149. list_select_related = ("owner", "channel")
  150. list_display = ("id", "created", "check_status", "owner",
  151. "channel_kind", "channel_value")
  152. list_filter = ("created", "check_status", "channel__kind")
  153. def channel_kind(self, obj):
  154. return obj.channel.kind
  155. def channel_value(self, obj):
  156. return obj.channel.value
  157. @admin.register(Flip)
  158. class FlipsAdmin(admin.ModelAdmin):
  159. list_display = ("id", "created", "processed", "owner", "old_status",
  160. "new_status")
  161. raw_id_fields = ("owner", )