Templating emails -- new account and new premium.

This commit is contained in:
Samuel Clay 2011-09-19 08:56:16 -07:00
parent 2a3c93a3e4
commit afae94cf7d
10 changed files with 176 additions and 96 deletions

View file

@ -2,19 +2,23 @@ import datetime
from django.db import models
from django.db import IntegrityError
from django.db.utils import DatabaseError
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.core.mail import mail_admins
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django.core.mail import mail_admins
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from celery.task import Task
from apps.reader.models import UserSubscription
from apps.rss_feeds.models import Feed
from paypal.standard.ipn.signals import subscription_signup
from apps.rss_feeds.tasks import NewFeeds
from celery.task import Task
from utils import log as logging
from vendor.timezones.fields import TimeZoneField
from utils.user_functions import generate_secret_token
from vendor.timezones.fields import TimeZoneField
from vendor.paypal.standard.ipn.signals import subscription_signup
class Profile(models.Model):
user = models.OneToOneField(User, unique=True, related_name="profile")
is_premium = models.BooleanField(default=False)
@ -30,7 +34,7 @@ class Profile(models.Model):
secret_token = models.CharField(max_length=12, blank=True, null=True)
def __unicode__(self):
return "%s" % self.user
return "%s <%s> (Premium: %s)" % (self.user, self.user.email, self.is_premium)
def save(self, *args, **kwargs):
if not self.secret_token:
@ -95,6 +99,34 @@ NewsBlur""" % {'user': self.user.username, 'feeds': subs.count()}
if stale_feeds:
stale_feeds = list(set([f.feed.pk for f in stale_feeds]))
self.queue_new_feeds(new_feeds=stale_feeds)
def mail_new_account(self):
if not self.user.email:
return
user = self.user
text = render_to_string('mail/email_new_account.txt', locals())
html = render_to_string('mail/email_new_account.xhtml', locals())
subject = "Welcome to NewsBlur, %s" % (self.user.username)
msg = EmailMultiAlternatives(subject, text,
from_email='NewsBlur <%s>' % settings.HELLO_EMAIL,
to=['%s <%s>' % (user, user.email)])
msg.attach_alternative(html, "text/html")
msg.send()
def mail_new_premium(self):
if not self.user.email:
return
user = self.user
text = render_to_string('mail/email_new_premium.txt', locals())
html = render_to_string('mail/email_new_premium.xhtml', locals())
subject = "Thanks for going premium on NewsBlur!"
msg = EmailMultiAlternatives(subject, text,
from_email='NewsBlur <%s>' % settings.HELLO_EMAIL,
to=['%s <%s>' % (user, user.email)])
msg.attach_alternative(html, "text/html")
msg.send()
def create_profile(sender, instance, created, **kwargs):

View file

@ -8,7 +8,7 @@ import urllib
from collections import defaultdict
from operator import itemgetter
from BeautifulSoup import BeautifulStoneSoup
from nltk.collocations import TrigramCollocationFinder, BigramCollocationFinder, TrigramAssocMeasures, BigramAssocMeasures
# from nltk.collocations import TrigramCollocationFinder, BigramCollocationFinder, TrigramAssocMeasures, BigramAssocMeasures
from django.db import models
from django.db import IntegrityError
from django.core.cache import cache
@ -867,39 +867,39 @@ class Feed(models.Model):
self.save()
def calculate_collocations_story_content(self,
collocation_measures=TrigramAssocMeasures,
collocation_finder=TrigramCollocationFinder):
stories = MStory.objects.filter(story_feed_id=self.pk)
story_content = ' '.join([s.story_content for s in stories if s.story_content])
return self.calculate_collocations(story_content, collocation_measures, collocation_finder)
def calculate_collocations_story_title(self,
collocation_measures=BigramAssocMeasures,
collocation_finder=BigramCollocationFinder):
stories = MStory.objects.filter(story_feed_id=self.pk)
story_titles = ' '.join([s.story_title for s in stories if s.story_title])
return self.calculate_collocations(story_titles, collocation_measures, collocation_finder)
def calculate_collocations(self, content,
collocation_measures=TrigramAssocMeasures,
collocation_finder=TrigramCollocationFinder):
content = re.sub(r'&#8217;', '\'', content)
content = re.sub(r'&amp;', '&', content)
try:
content = unicode(BeautifulStoneSoup(content,
convertEntities=BeautifulStoneSoup.HTML_ENTITIES))
except ValueError, e:
print "ValueError, ignoring: %s" % e
content = re.sub(r'</?\w+\s+[^>]*>', '', content)
content = re.split(r"[^A-Za-z-'&]+", content)
finder = collocation_finder.from_words(content)
finder.apply_freq_filter(3)
best = finder.nbest(collocation_measures.pmi, 10)
phrases = [' '.join(phrase) for phrase in best]
return phrases
# def calculate_collocations_story_content(self,
# collocation_measures=TrigramAssocMeasures,
# collocation_finder=TrigramCollocationFinder):
# stories = MStory.objects.filter(story_feed_id=self.pk)
# story_content = ' '.join([s.story_content for s in stories if s.story_content])
# return self.calculate_collocations(story_content, collocation_measures, collocation_finder)
#
# def calculate_collocations_story_title(self,
# collocation_measures=BigramAssocMeasures,
# collocation_finder=BigramCollocationFinder):
# stories = MStory.objects.filter(story_feed_id=self.pk)
# story_titles = ' '.join([s.story_title for s in stories if s.story_title])
# return self.calculate_collocations(story_titles, collocation_measures, collocation_finder)
#
# def calculate_collocations(self, content,
# collocation_measures=TrigramAssocMeasures,
# collocation_finder=TrigramCollocationFinder):
# content = re.sub(r'&#8217;', '\'', content)
# content = re.sub(r'&amp;', '&', content)
# try:
# content = unicode(BeautifulStoneSoup(content,
# convertEntities=BeautifulStoneSoup.HTML_ENTITIES))
# except ValueError, e:
# print "ValueError, ignoring: %s" % e
# content = re.sub(r'</?\w+\s+[^>]*>', '', content)
# content = re.split(r"[^A-Za-z-'&]+", content)
#
# finder = collocation_finder.from_words(content)
# finder.apply_freq_filter(3)
# best = finder.nbest(collocation_measures.pmi, 10)
# phrases = [' '.join(phrase) for phrase in best]
#
# return phrases
class Meta:
db_table="feeds"

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

View file

@ -47,7 +47,7 @@ LOGIN_URL = '/reader/login'
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/admin/'
SECRET_KEY = 'YOUR_SECRET_KEY'
EMAIL_BACKEND = 'django_ses.SESBackend'
EMAIL_BACKEND = 'seacucumber.backend.SESBackend'
# ===============
@ -302,6 +302,7 @@ TEST_RUNNER = "utils.testrunner.TestRunner"
SESSION_COOKIE_NAME = 'newsblur_sessionid'
SESSION_COOKIE_AGE = 60*60*24*365*2 # 2 years
SERVER_EMAIL = 'server@newsblur.com'
HELLO_EMAIL = 'hello@newsblur.com'
# ===========
# = Logging =
@ -322,6 +323,7 @@ INSTALLED_APPS = (
'django.contrib.admin',
'django_extensions',
'djcelery',
'seacucumber',
'compress',
'apps.rss_feeds',
'apps.reader',

View file

@ -0,0 +1,19 @@
{% block body %}{% endblock body %}
-----------------------------------------------------------------------------
Stay up to date and in touch with me, yr. developer, in a few different ways:
* Follow @samuelclay on Twitter: http://twitter.com/samuelclay
* Follow @newsblur on Twitter: http://twitter.com/newsblur
* Follow the constantly evolving source code on GitHub: http://github.com/samuelclay
{% block resources_header %}There are a few resources that would make sense to follow if you end up loving NewsBlur:{% endblock resources_header %}
* Read the NewsBlur Blog: http://blog.newsblur.com
* Get support on NewsBlur's Get Satisfaction: http://getsatisfaction.com/newsblur
* Download the free NewsBlur iPhone app: http://itunes.com/newsblur
-----------------------------------------------------------------------------
Don't want to be notified about anything NewsBlur related? Opt-out of emails from NewsBlur: http://www.newsblur.com/optout.

View file

@ -1,41 +1,66 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
</head>
<body bgcolor="#F5F6F4" text="#000000" link="#003399" vlink="#003399" alink="#DC181E" topmargin="0" leftmargin="0" marginheight="0" marginwidth="0">
<table cellpadding="0" cellspacing="0" border="0" bgcolor="#F5F6F4" width="100%" height="100%" style="padding-bottom:24px;">
<tr>
<td>
<table cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF" align="left" width="644" style="padding: 20px; margin-top: 24px;">
<tr>
<td style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;color:#333;">
{% block body %}{% endblock %}
</td>
</tr>
<tr>
<td colspan="2" style="border-top: 3px solid black; padding-top: 12px;" align="center">
<table>
<tr>
<td>
<a href="http://thebolditalic.com/"><img alt="Logo_email_black" border="false" src="http://thebolditalic.com/images/logo_email_black.png" /></a>
</td>
<td>
<p style="font-size:12px;"> Don't want to be notified about Idea activity? Go to '<a href="http://thebolditalic.com/users/Samuelclay/edit" style="color:#00BBFF; text-decoration:none;">My Ac=
count</a>' to update your email settings.<br /> The Bold Italic and The B=
old Italic Logo are registered trademarks of The Bold Italic, 100 Pine St=
reet, Suite 250, San Francisco, CA 94111.</p>
</td>
</tr>
</head>
<body bgcolor="#F5F6F4" text="#000000" link="#003399" vlink="#003399" alink="#DC181E" topmargin="0" leftmargin="0" marginheight="0" marginwidth="0">
<table cellpadding="0" cellspacing="0" border="0" bgcolor="#F5F6F4" width="100%" height="100%" style="padding-bottom:24px;">
<tr>
<td>
<center>
<table cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF" align="left" width="644" style="padding: 20px; margin-top: 24px;align:center;border: 1px solid #BABABA;">
<tr>
<td align="center">
<a href="http://www.newsblur.com/login"><img alt="NewsBlur" src="http://www.newsblur.com/media/img/logo_newsblur_blur.png" title="NewsBlur" style="width:312px;height:55px;border: none;"></a>
</td>
</tr>
<tr>
<td style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:16px;color:#333;">
{% block body %}{% endblock %}
<p style="line-height: 20px;border-top: 3px solid #404040;margin-top: 18px;padding-top: 18px">Stay up to date and in touch with me, yr. developer, in a few different ways:</p>
<p style="line-height: 20px;">
<ul style="list-style: none;">
<li><a href="http://twitter.com/samuelclay" style="text-decoration:none"><img src="http://www.newsblur.com/media/img/reader/twitter_icon_2.png" style="width:16px;height:16px;vertical-align:top;"> Follow @samuelclay on Twitter</a>.</li>
<li><a href="http://twitter.com/newsblur" style="text-decoration:none"><img src="http://www.newsblur.com/media/img/reader/twitter.png" style="width:16px;height:16px;vertical-align:top;"> Follow @newsblur on Twitter</a>.</li>
<li><a href="http://github.com/samuelclay" style="text-decoration:none"><img src="http://www.newsblur.com/media/img/reader/github_icon.png" style="width:16px;height:16px;vertical-align:top;"> Follow the constantly evolving source code on GitHub</a>.</li>
</ul>
</p>
<p style="line-height: 20px;">{% block resources_header %}There are a few resources that would make sense to follow if you end up loving NewsBlur:{% endblock resources_header %}</p>
<p style="line-height: 20px;">
<ul style="list-style: none;">
<li><a href="http://blog.newsblur.com" style="text-decoration:none"><img src="http://www.newsblur.com/media/img/favicon.png" style="width:16px;height:16px;vertical-align:top;"> Read the NewsBlur Blog</a>.</li>
<li><a href="http://getsatisfaction.com/newsblur" style="text-decoration:none"><img src="http://www.newsblur.com/media/img/reader/getsatisfaction.png" style="width:16px;height:16px;vertical-align:top;"> Get support on NewsBlur's Get Satisfaction</a>.</li>
<li><a href="http://itunes.com/newsblur" style="text-decoration:none"><img src="http://nb.local.host:8000/media/img/reader/iphone_icon.png" style="width:16px;height:16px;vertical-align:top;"> Download the free NewsBlur iPhone app</a>.</li>
</ul>
</p>
</td>
</tr>
<tr>
<td style="border-top: 3px solid #404040; padding-top: 4px;" align="center">
<table>
<tr>
<td>
<p style="font-size:12px;">
Don't want to be notified about anything NewsBlur related? <a href="http://www.newsblur.com/" style="color:#1C4D84; text-decoration:none;">Opt-out of emails from NewsBlur</a>.
</p>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center">
<a href="http://www.newsblur.com/login"><img alt="NewsBlur" src="http://www.newsblur.com/media/img/logo_newsblur.png" title="NewsBlur" style="width:312px;height:55px;border: none;"></a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</center>
</td>
</tr>
</table>
</body>
</body>
</html>

View file

@ -0,0 +1,7 @@
{% extends "mail/email_base.txt" %}
{% block body %}Welcome to NewsBlur, {{ user.username }}.
OK, firstly, thank you for trying out new software. It's not quite what you're used to, but you might find NewsBlur to be a perfect fit. There's a lot packed into a minimal interface.
Spend a few days trying out NewsBlur. I hope you end up loving it.{% endblock body %}

View file

@ -1,25 +1,9 @@
{% extends "email_base.xhtml" %}
{% extends "mail/email_base.xhtml" %}
{% block body %}
<table cellspacing="0" cellpadding="0" style="width:100%;">
<tr>
<td align="center">
<img alt="NewsBlur" src="http://www.newsblur.com/media/img/logo_newsblur.png" title="NewsBlur" />
</td>
</tr>
</table>
<p style="font-size: 37px; color:#555555; margin-top: 12px;margin-bottom: 10px;padding-top:6px;">Welcome, {{ user.name }}.</p>
<p style="font-size: 37px; color:#555555; margin-top: 18px;margin-bottom: 10px;padding-top:6px;">Welcome to NewsBlur, {{ user.username }}.</p>
<p style="line-height: 20px;">OK, firstly, thank you for trying out new software. It's not quite what you're used to, but you might find NewsBlur to be a perfect fit. There's a lot packed into a minimal interface.</p>
<p style="line-height: 20px;">Spend a few days trying out NewsBlur. I hope you end up loving it.</p>
<p style="line-height: 20px;">Stay up to date and in touch with me, yr. developer, in a few different ways:</p>
<p style="line-height: 20px;">
<ul>
<li><a href="http://twitter.com/samuelclay">Follow @samuelclay on Twitter</a>.</li>
<li><a href="http://twitter.com/samuelclay">Follow @newsblur on Twitter</a>.</li>
<li><a href="http://github.com/samuelclay">Peak at the source code on GitHub</a>.</li>
<li><a href="http://blog.newsblur.com">Read the NewsBlur Blog</a>.</li>
<li><a href="http://getsatisfaction.com/newsblur">Get support on NewsBlur's Get Satisfaction</a>.</li>
<li><a href="http://itunes.com/newsblur">Download the free NewsBlur iPhone app</a>.</li>
</ul>
</p>
{% endblock %}
{% endblock %}
{% block resources_header %}There are a few resources that would make sense to follow if you end up loving NewsBlur:{% endblock resources_header %}

View file

@ -0,0 +1,3 @@
{% extends "mail/email_base.txt" %}
{% block body %}Thank you, thank you, thank you!{% endblock body %}

View file

@ -0,0 +1,8 @@
{% extends "mail/email_base.xhtml" %}
{% block body %}
<p style="font-size: 37px; color:#555555; margin-top: 18px;margin-bottom: 10px;padding-top:6px;">Thank you, thank you, thank you!</p>
<p style="line-height: 20px;">A huge thanks for going premium.</p>
{% endblock %}
{% block resources_header %}Now that you're premium, you may want to follow a few resources:{% endblock resources_header %}