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.

246 lines
6.5 KiB

10 years ago
8 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. from django.contrib import admin
  2. from django.contrib.auth.admin import UserAdmin
  3. from django.contrib.auth.models import User
  4. from django.db.models import Count, F
  5. from django.template.loader import render_to_string
  6. from django.urls import reverse
  7. from django.utils.html import escape
  8. from django.utils.safestring import mark_safe
  9. from hc.accounts.models import Profile, Project
  10. class Fieldset:
  11. name = None
  12. fields = []
  13. @classmethod
  14. def tuple(cls):
  15. return (cls.name, {"fields": cls.fields})
  16. class ProfileFieldset(Fieldset):
  17. name = "User Profile"
  18. fields = (
  19. "email",
  20. "reports_allowed",
  21. "next_report_date",
  22. "nag_period",
  23. "next_nag_date",
  24. "deletion_notice_date",
  25. "token",
  26. "sort",
  27. )
  28. class TeamFieldset(Fieldset):
  29. name = "Team"
  30. fields = (
  31. "team_limit",
  32. "check_limit",
  33. "ping_log_limit",
  34. "sms_limit",
  35. "sms_sent",
  36. "last_sms_date",
  37. )
  38. @admin.register(Profile)
  39. class ProfileAdmin(admin.ModelAdmin):
  40. class Media:
  41. css = {"all": ("css/admin/profiles.css",)}
  42. readonly_fields = ("user", "email")
  43. search_fields = ["id", "user__email"]
  44. list_per_page = 50
  45. list_select_related = ("user",)
  46. list_display = (
  47. "id",
  48. "email",
  49. "engagement",
  50. "date_joined",
  51. "last_login",
  52. "projects",
  53. "invited",
  54. "sms",
  55. "reports_allowed",
  56. )
  57. list_filter = (
  58. "user__date_joined",
  59. "user__last_login",
  60. "reports_allowed",
  61. "check_limit",
  62. )
  63. fieldsets = (ProfileFieldset.tuple(), TeamFieldset.tuple())
  64. def get_queryset(self, request):
  65. qs = super(ProfileAdmin, self).get_queryset(request)
  66. qs = qs.prefetch_related("user__project_set")
  67. qs = qs.annotate(num_members=Count("user__project__member", distinct=True))
  68. qs = qs.annotate(num_checks=Count("user__project__check", distinct=True))
  69. qs = qs.annotate(num_channels=Count("user__project__channel", distinct=True))
  70. qs = qs.annotate(plan=F("user__subscription__plan_name"))
  71. return qs
  72. @mark_safe
  73. def engagement(self, obj):
  74. result = ""
  75. if obj.num_checks == 0:
  76. result += "0 checks, "
  77. elif obj.num_checks == 1:
  78. result += "1 check, "
  79. else:
  80. result += "<strong>%d checks</strong>, " % obj.num_checks
  81. if obj.num_channels == 0:
  82. result += "0 channels"
  83. elif obj.num_channels == 1:
  84. result += "1 channel, "
  85. else:
  86. result += "<strong>%d channels</strong>, " % obj.num_channels
  87. return result
  88. @mark_safe
  89. def email(self, obj):
  90. s = escape(obj.user.email)
  91. if obj.plan:
  92. return "<span title='%s'>%s</span>" % (obj.plan, s)
  93. return s
  94. def last_login(self, obj):
  95. return obj.user.last_login
  96. def date_joined(self, obj):
  97. return obj.user.date_joined
  98. @mark_safe
  99. def projects(self, obj):
  100. return render_to_string("admin/profile_list_projects.html", {"profile": obj})
  101. def invited(self, obj):
  102. return "%d of %d" % (obj.num_members, obj.team_limit)
  103. def sms(self, obj):
  104. return "%d of %d" % (obj.sms_sent, obj.sms_limit)
  105. @admin.register(Project)
  106. class ProjectAdmin(admin.ModelAdmin):
  107. readonly_fields = ("code", "owner")
  108. list_select_related = ("owner",)
  109. list_display = ("id", "name_", "users", "engagement", "switch")
  110. search_fields = ["id", "name", "owner__email"]
  111. class Media:
  112. css = {"all": ("css/admin/projects.css",)}
  113. def get_queryset(self, request):
  114. qs = super(ProjectAdmin, self).get_queryset(request)
  115. qs = qs.annotate(num_channels=Count("channel", distinct=True))
  116. qs = qs.annotate(num_checks=Count("check", distinct=True))
  117. qs = qs.annotate(num_members=Count("member", distinct=True))
  118. return qs
  119. def name_(self, obj):
  120. if obj.name:
  121. return obj.name
  122. return "Default Project for %s" % obj.owner.email
  123. @mark_safe
  124. def users(self, obj):
  125. if obj.num_members == 0:
  126. return obj.owner.email
  127. else:
  128. return render_to_string("admin/project_list_team.html", {"project": obj})
  129. def email(self, obj):
  130. return obj.owner.email
  131. @mark_safe
  132. def engagement(self, obj):
  133. result = ""
  134. if obj.num_checks == 0:
  135. result += "0 checks, "
  136. elif obj.num_checks == 1:
  137. result += "1 check, "
  138. else:
  139. result += "<strong>%d checks</strong>, " % obj.num_checks
  140. if obj.num_channels == 0:
  141. result += "0 channels"
  142. elif obj.num_channels == 1:
  143. result += "1 channel, "
  144. else:
  145. result += "<strong>%d channels</strong>, " % obj.num_channels
  146. return result
  147. @mark_safe
  148. def switch(self, obj):
  149. url = reverse("hc-checks", args=[obj.code])
  150. return "<a href='%s'>Show Checks</a>" % url
  151. class HcUserAdmin(UserAdmin):
  152. actions = ["send_report", "send_nag"]
  153. list_display = (
  154. "id",
  155. "email",
  156. "engagement",
  157. "date_joined",
  158. "last_login",
  159. "is_staff",
  160. )
  161. list_display_links = ("id", "email")
  162. list_filter = ("last_login", "date_joined", "is_staff", "is_active")
  163. ordering = ["-id"]
  164. def get_queryset(self, request):
  165. qs = super().get_queryset(request)
  166. qs = qs.annotate(num_checks=Count("project__check", distinct=True))
  167. qs = qs.annotate(num_channels=Count("project__channel", distinct=True))
  168. return qs
  169. @mark_safe
  170. def engagement(self, user):
  171. result = ""
  172. if user.num_checks == 0:
  173. result += "0 checks, "
  174. elif user.num_checks == 1:
  175. result += "1 check, "
  176. else:
  177. result += "<strong>%d checks</strong>, " % user.num_checks
  178. if user.num_channels == 0:
  179. result += "0 channels"
  180. elif user.num_channels == 1:
  181. result += "1 channel, "
  182. else:
  183. result += "<strong>%d channels</strong>, " % user.num_channels
  184. return result
  185. def send_report(self, request, qs):
  186. for user in qs:
  187. user.profile.send_report()
  188. self.message_user(request, "%d email(s) sent" % qs.count())
  189. def send_nag(self, request, qs):
  190. for user in qs:
  191. user.profile.send_report(nag=True)
  192. self.message_user(request, "%d email(s) sent" % qs.count())
  193. admin.site.unregister(User)
  194. admin.site.register(User, HcUserAdmin)