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.

214 lines
6.4 KiB

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