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.

199 lines
6.0 KiB

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