NewsBlur-viq/apps/profile/models.py

197 lines
8.1 KiB
Python
Raw Normal View History

import datetime
2009-06-16 03:08:55 +00:00
from django.db import models
from django.db import IntegrityError
from django.db.utils import DatabaseError
from django.db.models.signals import post_save
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.core.urlresolvers import reverse
from django.template.loader import render_to_string
from celery.task import Task
2010-10-16 23:24:55 -04:00
from apps.reader.models import UserSubscription
from apps.rss_feeds.models import Feed
from apps.rss_feeds.tasks import NewFeeds
from utils import log as logging
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)
send_emails = models.BooleanField(default=True)
preferences = models.TextField(default="{}")
view_settings = models.TextField(default="{}")
collapsed_folders = models.TextField(default="[]")
feed_pane_size = models.IntegerField(default=240)
tutorial_finished = models.BooleanField(default=False)
hide_mobile = models.BooleanField(default=False)
last_seen_on = models.DateTimeField(default=datetime.datetime.now)
last_seen_ip = models.CharField(max_length=50, blank=True, null=True)
timezone = TimeZoneField(default="America/New_York")
secret_token = models.CharField(max_length=12, blank=True, null=True)
def __unicode__(self):
return "%s <%s> (Premium: %s)" % (self.user, self.user.email, self.is_premium)
def save(self, *args, **kwargs):
if not self.secret_token:
self.secret_token = generate_secret_token(self.user.username, 12)
try:
super(Profile, self).save(*args, **kwargs)
except DatabaseError:
print " ---> Profile not saved. Table isn't there yet."
def activate_premium(self):
self.send_new_premium_email()
self.is_premium = True
self.save()
subs = UserSubscription.objects.filter(user=self.user)
for sub in subs:
sub.active = True
try:
sub.save()
sub.feed.setup_feed_for_premium_subscribers()
except IntegrityError, Feed.DoesNotExist:
pass
self.queue_new_feeds()
logging.user(self.user, "~BY~SK~FW~SBNEW PREMIUM ACCOUNT! WOOHOO!!! ~FR%s subscriptions~SN!" % (subs.count()))
message = """Woohoo!
User: %(user)s
Feeds: %(feeds)s
Sincerely,
NewsBlur""" % {'user': self.user.username, 'feeds': subs.count()}
mail_admins('New premium account', message, fail_silently=True)
def queue_new_feeds(self, new_feeds=None):
if not new_feeds:
new_feeds = UserSubscription.objects.filter(user=self.user,
feed__fetched_once=False,
active=True).values('feed_id')
new_feeds = list(set([f['feed_id'] for f in new_feeds]))
logging.user(self.user, "~BB~FW~SBQueueing NewFeeds: ~FC(%s) %s" % (len(new_feeds), new_feeds))
size = 4
publisher = Task.get_publisher(exchange="new_feeds")
for t in (new_feeds[pos:pos + size] for pos in xrange(0, len(new_feeds), size)):
NewFeeds.apply_async(args=(t,), queue="new_feeds", publisher=publisher)
publisher.connection.close()
def refresh_stale_feeds(self, exclude_new=False):
stale_cutoff = datetime.datetime.now() - datetime.timedelta(days=7)
stale_feeds = UserSubscription.objects.filter(user=self.user, active=True, feed__last_update__lte=stale_cutoff)
if exclude_new:
stale_feeds = stale_feeds.filter(feed__fetched_once=True)
all_feeds = UserSubscription.objects.filter(user=self.user, active=True)
logging.user(self.user, "~FG~BBRefreshing stale feeds: ~SB%s/%s" % (
stale_feeds.count(), all_feeds.count()))
for sub in stale_feeds:
sub.feed.fetched_once = False
sub.feed.save()
if stale_feeds:
stale_feeds = list(set([f.feed.pk for f in stale_feeds]))
self.queue_new_feeds(new_feeds=stale_feeds)
def send_new_user_email(self):
if not self.user.email or not self.send_emails:
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(fail_silently=True)
logging.user(self.user, "~BB~FM~SBSending email for new user: %s" % self.user.email)
def send_new_premium_email(self, force=False):
if not self.user.email or not self.send_emails:
return
if self.is_premium and not force:
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(fail_silently=True)
logging.user(self.user, "~BB~FM~SBSending email for new premium: %s" % self.user.email)
def send_forgot_password_email(self, email=None):
if not self.user.email and not email:
print "Please provide an email address."
return
if not self.user.email and email:
self.user.email = email
self.user.save()
user = self.user
text = render_to_string('mail/email_forgot_password.txt', locals())
html = render_to_string('mail/email_forgot_password.xhtml', locals())
subject = "Forgot your password 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(fail_silently=True)
logging.user(self.user, "~BB~FM~SBSending email for forgotten password: %s" % self.user.email)
def autologin_url(self, next=None):
return reverse('autologin', kwargs={
'username': self.user.username,
'secret': self.secret_token
}) + ('?' + next + '=1' if next else '')
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
else:
Profile.objects.get_or_create(user=instance)
2010-10-16 18:52:52 -04:00
post_save.connect(create_profile, sender=User)
def paypal_signup(sender, **kwargs):
ipn_obj = sender
user = User.objects.get(username=ipn_obj.custom)
try:
if not user.email:
user.email = ipn_obj.payer_email
user.save()
except:
pass
user.profile.activate_premium()
subscription_signup.connect(paypal_signup)
def change_password(user, old_password, new_password):
user_db = authenticate(username=user.username, password=old_password)
if user_db is None:
return -1
else:
user_db.set_password(new_password)
user_db.save()
return 1