<commit_before>from common import *

class Reminder:
    instances = []
    
    def __init__(self, model, subject, template, filter, sender=REGDESK_EMAIL):
        self.model, self.subject, self.template, self.filter, self.sender = model, subject, template, filter, sender
        self.instances.append(self)
    
    def __str__(self):
        return "<Email: subject={!r}>".format(self.subject)
    
    # TODO: pre-query everything to make this fast with a single up-front time... but make sure it gets updated appropriately
    def prev(self, x):
        prev = list(Email.objects.filter(fk_tab=x.__class__.__name__, fk_id=x.id, subject=self.subject).order_by("when"))
        return prev[-1] if prev else None
    
    def should_send(self, x):
        return not self.prev(x) and self.filter(x)
    
    def send(self, x, raise_errors = True):
        try:
            body = render("emails/" + self.template, {x.__class__.__name__.lower(): x})
            format = "text" if self.template.endswith(".txt") else "html"
            send_email(self.sender, x.email, self.subject, body, format)
            Email.objects.create(fk_tab=x.__class__.__name__, fk_id=x.id, subject=self.subject, dest=x.email, body=body)
        except:
            log.error("error sending {0!r} email to {1}", self.subject, x.email, exc_info=True)
            if raise_errors:
                raise
    
    @staticmethod
    def send_all(raise_errors = False):
        models = {m: list(m.objects.select_related()) for m in [Attendee, Group]}
        if state.AUTO_EMAILS:
            for rem in Reminder.instances:
                for x in models[rem.model]:
                    if rem.should_send(x):
                        rem.send(x, raise_errors = raise_errors)


### WARNING - changing the email subject line for a reminder causes ALL of those reminders to be re-sent

Reminder(Attendee, "Reminder to pay for MAGFest", "attendee_payment_reminder.txt",
         lambda a: a.paid == NOT_PAID and a.registered < datetime.now() - timedelta(days = 7))

Reminder(Attendee, "Last chance to pay for your MAGFest badge", "attendee_payment_reminder.txt",
         lambda a: a.paid == NOT_PAID and a.registered < datetime.now() - timedelta(days = 12))

Reminder(Group, "Reminder to pay for your MAGFest group", "group_payment_reminder.txt",
         lambda g: g.tables == 0 and g.amount_owed > 0 and g.amount_paid == 0
                                 and g.registered < datetime.now() - timedelta(days = 7))

Reminder(Group, "Last chance to pay for your MAGFest group", "group_payment_reminder.txt",
         lambda g: g.tables == 0 and g.amount_owed > 0 and g.amount_paid == 0
                                 and g.registered < datetime.now() - timedelta(days = 12))

Reminder(Group, "Reminder to pay for your MAGFest Dealer registration", "dealer_payment_reminder.txt",
         lambda g: g.is_dealer and g.status == APPROVED and g.amount_owed > 0 and g.amount_paid == 0
                               and g.approved < datetime.now() - timedelta(days = 30),
         sender = MARKETPLACE_EMAIL)

Reminder(Group, "Your MAGFest Dealer registration is due in one week", "dealer_payment_reminder.txt",
         lambda g: g.is_dealer and g.status == APPROVED and g.amount_owed > 0 and g.amount_paid == 0<commit_msg>fixed missing email issue<commit_after>from common import *

class Reminder:
    instances = []
    
    def __init__(self, model, subject, template, filter, sender=REGDESK_EMAIL):
        self.model, self.subject, self.template, self.filter, self.sender = model, subject, template, filter, sender
        self.instances.append(self)
    
    def __str__(self):
        return "<Email: subject={!r}>".format(self.subject)
    
    # TODO: pre-query everything to make this fast with a single up-front time... but make sure it gets updated appropriately
    def prev(self, x):
        prev = list(Email.objects.filter(fk_tab=x.__class__.__name__, fk_id=x.id, subject=self.subject).order_by("when"))
        return prev[-1] if prev else None
    
    def should_send(self, x):
        return not self.prev(x) and self.filter(x)
    
    def send(self, x, raise_errors = True):
        try:
            body = render("emails/" + self.template, {x.__class__.__name__.lower(): x})
            format = "text" if self.template.endswith(".txt") else "html"
            send_email(self.sender, x.email, self.subject, body, format)
            Email.objects.create(fk_tab=x.__class__.__name__, fk_id=x.id, subject=self.subject, dest=x.email, body=body)
        except:
            log.error("error sending {0!r} email to {1}", self.subject, x.email, exc_info=True)
            if raise_errors:
                raise
    
    @staticmethod
    def send_all(raise_errors = False):
        models = {m: list(m.objects.select_related()) for m in [Attendee, Group]}
        if state.AUTO_EMAILS:
            for rem in Reminder.instances:
                for x in models[rem.model]:
                    if x.email and rem.should_send(x):
                        rem.send(x, raise_errors = raise_errors)


### WARNING - changing the email subject line for a reminder causes ALL of those reminders to be re-sent

Reminder(Attendee, "Reminder to pay for MAGFest", "attendee_payment_reminder.txt",
         lambda a: a.paid == NOT_PAID and a.registered < datetime.now() - timedelta(days = 7))

Reminder(Attendee, "Last chance to pay for your MAGFest badge", "attendee_payment_reminder.txt",
         lambda a: a.paid == NOT_PAID and a.registered < datetime.now() - timedelta(days = 12))

Reminder(Group, "Reminder to pay for your MAGFest group", "group_payment_reminder.txt",
         lambda g: g.tables == 0 and g.amount_owed > 0 and g.amount_paid == 0
                                 and g.registered < datetime.now() - timedelta(days = 7))

Reminder(Group, "Last chance to pay for your MAGFest group", "group_payment_reminder.txt",
         lambda g: g.tables == 0 and g.amount_owed > 0 and g.amount_paid == 0
                                 and g.registered < datetime.now() - timedelta(days = 12))

Reminder(Group, "Reminder to pay for your MAGFest Dealer registration", "dealer_payment_reminder.txt",
         lambda g: g.is_dealer and g.status == APPROVED and g.amount_owed > 0 and g.amount_paid == 0
                               and g.approved < datetime.now() - timedelta(days = 30),
         sender = MARKETPLACE_EMAIL)

Reminder(Group, "Your MAGFest Dealer registration is due in one week", "dealer_payment_reminder.txt",
         lambda g: g.is_dealer and g.status == APPROVED and g.amount_owed > 0 and g.amount_paid == 0
{'fraction_non_alphanumeric': 0.11173268823707287, 'fraction_numerical': 0.006350166313879649, 'mean_word_length': 2.664819944598338, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3184255', 'n_tokens_mistral': 2090, 'n_tokens_neox': 2023, 'n_words': 582}