]> git.ipfire.org Git - ipfire.org.git/blame - src/backend/campaigns.py
Implement drip campaigns
[ipfire.org.git] / src / backend / campaigns.py
CommitLineData
d73bba54
MT
1#!/usr/bin/python3
2
3import logging
4
5from .decorators import *
6from .misc import Object
7
8class Campaigns(Object):
9 async def launch_manually(self, uid):
10 account = self.backend.accounts.get_by_uid(uid)
11 if account:
12 self.launch(account)
13
14 def launch(self, account):
15 logging.debug("Launching all campaigns for %s" % account)
16
17 # Update old timestamps first
18 self.db.execute("UPDATE campaign_templates \
19 SET launch_at = launch_at + repeat_after \
20 WHERE (launch_at IS NOT NULL AND launch_at <= CURRENT_TIMESTAMP) \
21 AND repeat_after IS NOT NULL")
22
23 # Launch all campaigns
24 self.db.execute("INSERT INTO campaign_emails(account_uid, template, \
25 launch_at, repeat_after, groups ) \
26 SELECT %s, template, COALESCE(launch_at, CURRENT_TIMESTAMP + launch_after), \
27 repeat_after, groups FROM campaign_templates", account.uid)
28
29 def _get_campaign_emails(self, query, *args):
30 res = self.db.query(query, *args)
31
32 for row in res:
33 yield CampaignEmail(self.backend, row.id, data=row)
34
35 async def run(self):
36 with self.db.transaction():
37 emails = self._get_campaign_emails("SELECT * FROM campaign_emails \
38 WHERE launch_at <= CURRENT_TIMESTAMP ORDER BY launch_at")
39
40 # Send them all
41 for email in emails:
42 email.send()
43
44
45class CampaignEmail(Object):
46 def init(self, id, data=None):
47 self.id = id
48 self.data = data
49
50 @lazy_property
51 def account(self):
52 return self.backend.accounts.get_by_uid(self.data.account_uid)
53
54 @property
55 def template(self):
56 return self.data.template
57
58 @property
59 def repeat_after(self):
60 return self.data.repeat_after
61
62 def send(self):
63 # Delete if the account does not exist any more
64 if not self.account:
65 return self._delete()
66
67 logging.info("Sending %s to %s" % (self.template, self.account))
68
69 # Generate the email
70 self.backend.messages.send_template(self.template, account=self.account)
71
72 # Update this email for the next launch
73 self._update()
74
75 def _update(self):
76 # If this email repeats, we will update the timestamp
77 if self.repeat_after:
78 self.db.execute("UPDATE campaign_emails \
79 SET launch_at = launch_at + repeat_after \
80 WHERE id = %s", self.id)
81
82 # Otherwise we will delete it
83 else:
84 self._delete()
85
86 def _delete(self):
87 """
88 Deletes this email
89 """
90 self.db.execute("DELETE FROM campaign_emails WHERE id = %s", self.id)