NewsBlur/apps/profile/views.py
2013-05-13 18:20:33 -07:00

392 lines
No EOL
14 KiB
Python

import stripe
import datetime
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
from django.contrib.auth import logout as logout_user
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.sites.models import Site
from django.contrib.auth.models import User
from django.contrib.admin.views.decorators import staff_member_required
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.core.mail import mail_admins
from django.conf import settings
from apps.profile.models import Profile, PaymentHistory, RNewUserQueue
from apps.reader.models import UserSubscription
from apps.profile.forms import StripePlusPaymentForm, PLANS, DeleteAccountForm
from apps.profile.forms import ForgotPasswordForm, ForgotPasswordReturnForm, AccountSettingsForm
from apps.social.models import MSocialServices, MActivity, MSocialProfile
from utils import json_functions as json
from utils.user_functions import ajax_login_required
from utils.view_functions import render_to
from utils.user_functions import get_user
from utils import log as logging
from vendor.paypal.standard.forms import PayPalPaymentsForm
SINGLE_FIELD_PREFS = ('timezone','feed_pane_size','hide_mobile','send_emails',
'hide_getting_started', 'has_setup_feeds', 'has_found_friends',
'has_trained_intelligence',)
SPECIAL_PREFERENCES = ('old_password', 'new_password', 'autofollow_friends', 'dashboard_date',)
@ajax_login_required
@require_POST
@json.json_view
def set_preference(request):
code = 1
message = ''
new_preferences = request.POST
preferences = json.decode(request.user.profile.preferences)
for preference_name, preference_value in new_preferences.items():
if preference_value in ['true','false']: preference_value = True if preference_value == 'true' else False
if preference_name in SINGLE_FIELD_PREFS:
setattr(request.user.profile, preference_name, preference_value)
elif preference_name in SPECIAL_PREFERENCES:
if preference_name == 'autofollow_friends':
social_services, _ = MSocialServices.objects.get_or_create(user_id=request.user.pk)
social_services.autofollow = preference_value
social_services.save()
elif preference_name == 'dashboard_date':
request.user.profile.dashboard_date = datetime.datetime.utcnow()
else:
if preference_value in ["true", "false"]:
preference_value = True if preference_value == "true" else False
preferences[preference_name] = preference_value
if preference_name == 'intro_page':
logging.user(request, "~FBAdvancing intro to page ~FM~SB%s" % preference_value)
request.user.profile.preferences = json.encode(preferences)
request.user.profile.save()
response = dict(code=code, message=message, new_preferences=new_preferences)
return response
@ajax_login_required
@json.json_view
def get_preference(request):
code = 1
preference_name = request.POST.get('preference')
preferences = json.decode(request.user.profile.preferences)
payload = preferences
if preference_name:
payload = preferences.get(preference_name)
response = dict(code=code, payload=payload)
return response
@ajax_login_required
@require_POST
@json.json_view
def set_account_settings(request):
code = -1
message = 'OK'
form = AccountSettingsForm(user=request.user, data=request.POST)
if form.is_valid():
form.save()
code = 1
else:
message = form.errors[form.errors.keys()[0]][0]
payload = {
"username": request.user.username,
"email": request.user.email,
"social_profile": MSocialProfile.profile(request.user.pk)
}
return dict(code=code, message=message, payload=payload)
@ajax_login_required
@require_POST
@json.json_view
def set_view_setting(request):
code = 1
feed_id = request.POST['feed_id']
feed_view_setting = request.POST.get('feed_view_setting')
feed_order_setting = request.POST.get('feed_order_setting')
feed_read_filter_setting = request.POST.get('feed_read_filter_setting')
view_settings = json.decode(request.user.profile.view_settings)
setting = view_settings.get(feed_id, {})
if isinstance(setting, basestring): setting = {'v': setting}
if feed_view_setting: setting['v'] = feed_view_setting
if feed_order_setting: setting['o'] = feed_order_setting
if feed_read_filter_setting: setting['r'] = feed_read_filter_setting
view_settings[feed_id] = setting
request.user.profile.view_settings = json.encode(view_settings)
request.user.profile.save()
response = dict(code=code)
return response
@ajax_login_required
@json.json_view
def get_view_setting(request):
code = 1
feed_id = request.POST['feed_id']
view_settings = json.decode(request.user.profile.view_settings)
response = dict(code=code, payload=view_settings.get(feed_id))
return response
@ajax_login_required
@require_POST
@json.json_view
def set_collapsed_folders(request):
code = 1
collapsed_folders = request.POST['collapsed_folders']
request.user.profile.collapsed_folders = collapsed_folders
request.user.profile.save()
response = dict(code=code)
return response
@ajax_login_required
def paypal_form(request):
domain = Site.objects.get_current().domain
paypal_dict = {
"cmd": "_xclick-subscriptions",
"business": "samuel@ofbrooklyn.com",
"a3": "12.00", # price
"p3": 1, # duration of each unit (depends on unit)
"t3": "Y", # duration unit ("M for Month")
"src": "1", # make payments recur
"sra": "1", # reattempt payment on payment error
"no_note": "1", # remove extra notes (optional)
"item_name": "NewsBlur Premium Account",
"notify_url": "http://%s%s" % (domain, reverse('paypal-ipn')),
"return_url": "http://%s%s" % (domain, reverse('paypal-return')),
"cancel_return": "http://%s%s" % (domain, reverse('index')),
"custom": request.user.username,
}
# Create the instance.
form = PayPalPaymentsForm(initial=paypal_dict, button_type="subscribe")
logging.user(request, "~FBLoading paypal/feedchooser")
# Output the button.
return HttpResponse(form.render(), mimetype='text/html')
def paypal_return(request):
return render_to_response('reader/paypal_return.xhtml', {
}, context_instance=RequestContext(request))
@login_required
def activate_premium(request):
return HttpResponseRedirect(reverse('index'))
@ajax_login_required
@json.json_view
def profile_is_premium(request):
# Check tries
code = 0
retries = int(request.GET['retries'])
profile = Profile.objects.get(user=request.user)
subs = UserSubscription.objects.filter(user=request.user)
total_subs = subs.count()
activated_subs = subs.filter(active=True).count()
if retries >= 30:
code = -1
if not request.user.profile.is_premium:
subject = "Premium activation failed: %s (%s/%s)" % (request.user, activated_subs, total_subs)
message = """User: %s (%s) -- Email: %s""" % (request.user.username, request.user.pk, request.user.email)
mail_admins(subject, message, fail_silently=True)
request.user.profile.is_premium = True
request.user.profile.save()
return {
'is_premium': profile.is_premium,
'code': code,
'activated_subs': activated_subs,
'total_subs': total_subs,
}
@login_required
def stripe_form(request):
user = request.user
success_updating = False
stripe.api_key = settings.STRIPE_SECRET
plan = int(request.GET.get('plan', 2))
plan = PLANS[plan-1][0]
if request.method == 'POST':
zebra_form = StripePlusPaymentForm(request.POST, email=user.email)
if zebra_form.is_valid():
user.email = zebra_form.cleaned_data['email']
user.save()
customer = stripe.Customer.create(**{
'card': zebra_form.cleaned_data['stripe_token'],
'plan': zebra_form.cleaned_data['plan'],
'email': user.email,
'description': user.username,
})
user.profile.strip_4_digits = zebra_form.cleaned_data['last_4_digits']
user.profile.stripe_id = customer.id
user.profile.save()
user.profile.activate_premium() # TODO: Remove, because webhooks are slow
success_updating = True
else:
zebra_form = StripePlusPaymentForm(email=user.email, plan=plan)
if success_updating:
return render_to_response('reader/paypal_return.xhtml',
{}, context_instance=RequestContext(request))
new_user_queue_count = RNewUserQueue.user_count()
new_user_queue_position = RNewUserQueue.user_position(request.user.pk)
new_user_queue_behind = 0
if new_user_queue_position >= 0:
new_user_queue_behind = new_user_queue_count - new_user_queue_position
new_user_queue_position -= 1
logging.user(request, "~BM~FBLoading Stripe form")
return render_to_response('profile/stripe_form.xhtml',
{
'zebra_form': zebra_form,
'publishable': settings.STRIPE_PUBLISHABLE,
'success_updating': success_updating,
'new_user_queue_count': new_user_queue_count - 1,
'new_user_queue_position': new_user_queue_position,
'new_user_queue_behind': new_user_queue_behind,
},
context_instance=RequestContext(request)
)
@render_to('reader/activities_module.xhtml')
def load_activities(request):
user = get_user(request)
page = max(1, int(request.REQUEST.get('page', 1)))
activities, has_next_page = MActivity.user(user.pk, page=page)
return {
'activities': activities,
'page': page,
'has_next_page': has_next_page,
'username': 'You',
}
@ajax_login_required
@json.json_view
def payment_history(request):
user = request.user
if request.user.is_staff:
user_id = request.REQUEST.get('user_id', request.user.pk)
user = User.objects.get(pk=user_id)
history = PaymentHistory.objects.filter(user=user)
return {
'is_premium': user.profile.is_premium,
'premium_expire': user.profile.premium_expire,
'payments': history
}
@ajax_login_required
@json.json_view
def cancel_premium(request):
canceled = request.user.profile.cancel_premium()
return {'code': 1 if canceled else -1}
@staff_member_required
@ajax_login_required
@json.json_view
def refund_premium(request):
user_id = request.REQUEST.get('user_id')
user = User.objects.get(pk=user_id)
try:
refunded = user.profile.refund_premium()
except stripe.InvalidRequestError, e:
refunded = e
return {'code': 1 if refunded else -1, 'refunded': refunded}
@staff_member_required
@ajax_login_required
@json.json_view
def upgrade_premium(request):
user_id = request.REQUEST.get('user_id')
user = User.objects.get(pk=user_id)
upgraded = user.profile.activate_premium()
return {'code': 1 if upgraded else -1}
@login_required
@render_to('profile/delete_account.xhtml')
def delete_account(request):
if request.method == 'POST':
form = DeleteAccountForm(request.POST, user=request.user)
if form.is_valid():
logging.user(request.user, "~SK~BC~FRDeleting ~SB%s~SN's account." %
request.user.username)
request.user.profile.delete_user(confirm=True)
logout_user(request)
return HttpResponseRedirect(reverse('index'))
else:
logging.user(request.user, "~BC~FRFailed attempt to delete ~SB%s~SN's account." %
request.user.username)
else:
logging.user(request.user, "~BC~FRAttempting to delete ~SB%s~SN's account." %
request.user.username)
form = DeleteAccountForm(user=request.user)
return {
'delete_form': form,
}
@render_to('profile/forgot_password.xhtml')
def forgot_password(request):
if request.method == 'POST':
form = ForgotPasswordForm(request.POST)
if form.is_valid():
logging.user(request.user, "~BC~FRForgot password: ~SB%s" % request.POST['email'])
try:
user = User.objects.get(email__iexact=request.POST['email'])
except User.MultipleObjectsReturned:
user = User.objects.filter(email__iexact=request.POST['email'])[0]
user.profile.send_forgot_password_email()
return HttpResponseRedirect(reverse('index'))
else:
logging.user(request.user, "~BC~FRFailed forgot password: ~SB%s~SN" %
request.POST['email'])
else:
logging.user(request.user, "~BC~FRAttempting to retrieve forgotton password.")
form = ForgotPasswordForm()
return {
'forgot_password_form': form,
}
@login_required
@render_to('profile/forgot_password_return.xhtml')
def forgot_password_return(request):
if request.method == 'POST':
logging.user(request.user, "~BC~FRReseting ~SB%s~SN's password." %
request.user.username)
new_password = request.POST.get('password', '')
request.user.set_password(new_password)
request.user.save()
return HttpResponseRedirect(reverse('index'))
else:
logging.user(request.user, "~BC~FRAttempting to reset ~SB%s~SN's password." %
request.user.username)
form = ForgotPasswordReturnForm()
return {
'forgot_password_return_form': form,
}