src/backend/accounts.py \
src/backend/base.py \
src/backend/blog.py \
+ src/backend/campaigns.py \
src/backend/countries.py \
src/backend/database.py \
src/backend/decorators.py \
templates_authdir = $(templatesdir)/auth
templates_auth_messages_DATA = \
+ src/templates/auth/messages/donation-reminder.txt \
src/templates/auth/messages/password-reset.txt \
+ src/templates/auth/messages/profile-setup.txt \
+ src/templates/auth/messages/profile-setup-2.txt \
src/templates/auth/messages/register.txt
templates_auth_messagesdir = $(templates_authdir)/messages
self.backend.messages.send_template("people/messages/new-account",
recipients=["moderators@ipfire.org"], account=account)
+ # Launch all drip campaigns
+ self.backend.campaigns.launch(account)
+
return account
def create(self, uid, email, first_name, last_name, country_code=None):
def email(self):
return self._get_string("mail")
+ @property
+ def email_to(self):
+ return "%s <%s>" % (self, self.email)
+
# Mail Routing Address
def get_mail_routing_address(self):
from . import accounts
from . import blog
+from . import campaigns
from . import database
from . import geoip
from . import fireinfo
"check-mirrors" : self.mirrors.check_all,
"check-spam" : self.accounts.check_spam,
"cleanup" : self.cleanup,
+ "launch-campaigns" : self.campaigns.launch_manually,
+ "run-campaigns" : self.campaigns.run,
"scan-files" : self.releases.scan_files,
"send-all-messages" : self.messages.queue.send_all,
"test-blacklist" : self.geoip.test_blacklist,
if r:
raise SystemExit(r)
+ @lazy_property
+ def campaigns(self):
+ return campaigns.Campaigns(self)
+
@lazy_property
def groups(self):
return accounts.Groups(self)
--- /dev/null
+#!/usr/bin/python3
+
+import logging
+
+from .decorators import *
+from .misc import Object
+
+class Campaigns(Object):
+ async def launch_manually(self, uid):
+ account = self.backend.accounts.get_by_uid(uid)
+ if account:
+ self.launch(account)
+
+ def launch(self, account):
+ logging.debug("Launching all campaigns for %s" % account)
+
+ # Update old timestamps first
+ self.db.execute("UPDATE campaign_templates \
+ SET launch_at = launch_at + repeat_after \
+ WHERE (launch_at IS NOT NULL AND launch_at <= CURRENT_TIMESTAMP) \
+ AND repeat_after IS NOT NULL")
+
+ # Launch all campaigns
+ self.db.execute("INSERT INTO campaign_emails(account_uid, template, \
+ launch_at, repeat_after, groups ) \
+ SELECT %s, template, COALESCE(launch_at, CURRENT_TIMESTAMP + launch_after), \
+ repeat_after, groups FROM campaign_templates", account.uid)
+
+ def _get_campaign_emails(self, query, *args):
+ res = self.db.query(query, *args)
+
+ for row in res:
+ yield CampaignEmail(self.backend, row.id, data=row)
+
+ async def run(self):
+ with self.db.transaction():
+ emails = self._get_campaign_emails("SELECT * FROM campaign_emails \
+ WHERE launch_at <= CURRENT_TIMESTAMP ORDER BY launch_at")
+
+ # Send them all
+ for email in emails:
+ email.send()
+
+
+class CampaignEmail(Object):
+ def init(self, id, data=None):
+ self.id = id
+ self.data = data
+
+ @lazy_property
+ def account(self):
+ return self.backend.accounts.get_by_uid(self.data.account_uid)
+
+ @property
+ def template(self):
+ return self.data.template
+
+ @property
+ def repeat_after(self):
+ return self.data.repeat_after
+
+ def send(self):
+ # Delete if the account does not exist any more
+ if not self.account:
+ return self._delete()
+
+ logging.info("Sending %s to %s" % (self.template, self.account))
+
+ # Generate the email
+ self.backend.messages.send_template(self.template, account=self.account)
+
+ # Update this email for the next launch
+ self._update()
+
+ def _update(self):
+ # If this email repeats, we will update the timestamp
+ if self.repeat_after:
+ self.db.execute("UPDATE campaign_emails \
+ SET launch_at = launch_at + repeat_after \
+ WHERE id = %s", self.id)
+
+ # Otherwise we will delete it
+ else:
+ self._delete()
+
+ def _delete(self):
+ """
+ Deletes this email
+ """
+ self.db.execute("DELETE FROM campaign_emails WHERE id = %s", self.id)
import email.utils
import logging
import subprocess
+import tornado.locale
import tornado.template
from . import accounts
# Send messages
* * * * * nobody ipfire.org send-all-messages
+# Run campaigns
+*/5 * * * * nobody ipfire.org run-campaigns
+
# Cleanup once an hour
30 * * * * nobody ipfire.org cleanup
--- /dev/null
+From: Michael Tremer from the IPFire Project <michael.tremer@ipfire.org>
+To: {{ account.email_to }}
+Subject: {{ _("Please help us with your donation!") }}
+
+{{ _("Hey again, %s,") % account.first_name }}
+
+{{ _("IPFire runs on supporters' donations, people like you!") }}
+
+{{ _("Why do we need you donations?") }}
+
+* {{ _("Your money ensures the longevity and long-term success of this project.") }}
+* {{ _("It helps us fund developers and extend our skills") }}
+* {{ _("It will aid us to promote IPFire to more people around the world") }}
+* {{ _("This funds conferences, where we focus on future projects") }}
+* {{ _("It pays for our hosting") }}
+
+{{ _("All this, as you would understand, requires money. Every single donation counts.") }}
+
+{{ _("If you want to see IPFire thrive, we need your support.") }}
+
+{{ _("The best way to do this is by setting up a monthly donation which you can do here:") }}
+
+ https://www.ipfire.org/donate?frequency=monthly&amount=10
+
+{{ _("We also have other ways to donate. Please go to https://www.ipfire.org/donate for details.") }}
+
+{{ _("Thank you so much for your support,") }}
+{{ _("-Michael")}}
--- /dev/null
+From: Arne Fitzenreiter from the IPFire Project <arne.fitzenreiter@ipfire.org>
+To: {{ account.email_to }}
+Subject: {{ _("Hi!") }}
+
+{{ _("Hello once again, %s,") % account.first_name }}
+
+{{ _("we hope you are enjoying using IPFire.") }}
+
+{{ _("Did you know that you can get help from our community at https://community.ipfire.org?") }}
+{{ _("People like me often post on here, providing help and support.") }}
+
+{{ _("But we also rely on you donations. Please consider helping us by setting up a small monthly donation:") }}
+
+ https://www.ipfire.org/donate?frequency=monthly
+
+{{ _("Thank you, we really appreciate your support,") }}
+{{ _("-Arne")}}
--- /dev/null
+From: Michael Tremer from the IPFire Project <michael.tremer@ipfire.org>
+To: {{ account.email_to }}
+Subject: {{ _("Welcome to the IPFire Project!") }}
+
+{{ _("Hello %s!") % account.first_name }}
+
+{{ _("I would like to introduce myself: I'm Michael and I am one of the people behind the project. We are a team of passionate people who try to make the Internet a better place. On behalf of everyone, I would like to say: Welcome to the IPFire Project!") }}
+
+{{ _("We want you to feel a part of our team. Can I ask you to set up your profile? We would love to know a little bit more about you.") }}
+{{ _("To do this, please log on to your profile and click the edit button.") }}
+
+{{ _("I would also like to invite you to join our community at https://community.ipfire.org, if you haven't already done so.") }}
+
+{{ _("Finally, this organisation relies on the generous donations of people like you. If you can, please consider supporting this project and the team behind it, so that we can continue our long-term vision, fund developers and promote our project.") }}
+
+{{ _("You can do this at https://www.ipfire.org/donate.") }}
+
+{{ _("Thank you,") }}
+{{ _("-Michael") }}
From: IPFire Project <no-reply@ipfire.org>
To: {{ first_name }} {{ last_name }} <{{ email }}>
-Subject: {{ _("Welcome to the IPFire Project!") }}
+Subject: {{ _("Please activate your account for the IPFire Project") }}
{{ _("Hello %s!") % first_name }}