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.

77 lines
2.6 KiB

  1. from datetime import timedelta
  2. import time
  3. from django.conf import settings
  4. from django.core.management.base import BaseCommand
  5. from django.utils.timezone import now
  6. from hc.accounts.models import Profile, Member
  7. from hc.api.models import Ping
  8. from hc.lib import emails
  9. class Command(BaseCommand):
  10. help = """Send deletion notices to inactive user accounts.
  11. Conditions for sending the notice:
  12. - deletion notice has not been sent recently
  13. - last login more than a year ago
  14. - none of the owned projects has invited team members
  15. - none of the owned projects has pings in the last year
  16. - is on a free plan
  17. """
  18. def pause(self):
  19. time.sleep(1)
  20. def handle(self, *args, **options):
  21. year_ago = now() - timedelta(days=365)
  22. q = Profile.objects.order_by("id")
  23. # Exclude accounts with logins in the last year
  24. q = q.exclude(user__last_login__gt=year_ago)
  25. # Exclude accounts less than a year old
  26. q = q.exclude(user__date_joined__gt=year_ago)
  27. # Exclude accounts with the deletion notice already sent
  28. q = q.exclude(deletion_notice_date__gt=year_ago)
  29. # Exclude accounts with activity in the last year
  30. q = q.exclude(last_active_date__gt=year_ago)
  31. # Exclude paid accounts
  32. q = q.exclude(sms_limit__gt=5)
  33. sent = 0
  34. skipped_has_team = 0
  35. skipped_has_pings = 0
  36. for profile in q:
  37. members = Member.objects.filter(project__owner_id=profile.user_id)
  38. if members.exists():
  39. # Don't send deletion notice: this account has team members
  40. skipped_has_team += 1
  41. continue
  42. pings = Ping.objects.filter(owner__project__owner_id=profile.user_id)
  43. pings = pings.filter(created__gt=year_ago)
  44. if pings.exists():
  45. # Don't send deletion notice: this account has pings in the last year
  46. skipped_has_pings += 1
  47. continue
  48. self.stdout.write("Sending notice to %s" % profile.user.email)
  49. profile.deletion_notice_date = now()
  50. profile.save()
  51. ctx = {"email": profile.user.email, "support_email": settings.SUPPORT_EMAIL}
  52. emails.deletion_notice(profile.user.email, ctx)
  53. sent += 1
  54. # Throttle so we don't send too many emails at once:
  55. self.pause()
  56. return (
  57. f"Done!\n"
  58. f"* Notices sent: {sent}\n"
  59. f"* Skipped (has team members): {skipped_has_team}\n"
  60. f"* Skipped (has pings in the last year): {skipped_has_pings}\n"
  61. )