Per-month quota for email-sending

Fix #34
This commit is contained in:
Klaas van Schelven
2025-07-28 14:41:32 +02:00
parent 13dbc4dd29
commit e363917e9c
8 changed files with 113 additions and 3 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.21 on 2025-07-28 12:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("phonehome", "0001_b_squashed_initial"),
]
operations = [
migrations.AddField(
model_name="installation",
name="email_quota_usage",
field=models.TextField(default='{"per_month": {}}'),
),
]

View File

@@ -1,6 +1,10 @@
import json
import uuid
from django.db import models
from bugsink.transaction import immediate_atomic
from bugsink.app_settings import get_settings
class Installation(models.Model):
@@ -12,6 +16,29 @@ class Installation(models.Model):
silence_email_system_warning = models.BooleanField(default=False)
email_quota_usage = models.TextField(null=False, default='{"per_month": {}}')
@classmethod
@immediate_atomic(only_if_needed=True) # minimalize write-lock-hogging (while being callable within atomic blocks)
def check_and_inc_email_quota(cls, date):
obj = cls.objects.first()
email_quota_usage = json.loads(obj.email_quota_usage)
key = date.strftime('%Y-%m')
if key not in email_quota_usage["per_month"]:
email_quota_usage['per_month'] = {key: 0} # full overwrite: no need to keep old info around.
if (get_settings().MAX_EMAILS_PER_MONTH is not None
and email_quota_usage['per_month'][key] >= get_settings().MAX_EMAILS_PER_MONTH):
return False
email_quota_usage['per_month'][key] += 1
obj.email_quota_usage = json.dumps(email_quota_usage)
obj.save()
return True
class OutboundMessage(models.Model):
attempted_at = models.DateTimeField(auto_now_add=True)