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.

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