NewsBlur/apps/profile/views.py

820 lines
31 KiB
Python
Raw Normal View History

import stripe
2017-12-08 16:43:30 -08:00
import requests
import datetime
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
2017-12-08 16:43:30 -08:00
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.contrib.auth import logout as logout_user
2014-02-14 15:30:46 -08:00
from django.contrib.auth import login as login_user
2014-04-03 12:44:04 -07:00
from django.db.models.aggregates import Sum
2010-10-16 18:52:52 -04:00
from django.http import HttpResponse, HttpResponseRedirect
2010-10-23 11:13:44 -04:00
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.urls import reverse
from django.shortcuts import render
from django.core.mail import mail_admins
from django.conf import settings
2015-07-09 20:09:35 -07:00
from apps.profile.models import Profile, PaymentHistory, RNewUserQueue, MRedeemedCode, MGiftCode
2014-04-03 12:44:04 -07:00
from apps.reader.models import UserSubscription, UserSubscriptionFolders, RUserStory
from apps.profile.forms import StripePlusPaymentForm, PLANS, DeleteAccountForm
from apps.profile.forms import ForgotPasswordForm, ForgotPasswordReturnForm, AccountSettingsForm
2014-11-06 13:33:34 -08:00
from apps.profile.forms import RedeemCodeForm
from apps.reader.forms import SignupForm, LoginForm
from apps.rss_feeds.models import MStarredStory, MStarredStoryCounts
2012-04-20 08:45:29 -07:00
from apps.social.models import MSocialServices, MActivity, MSocialProfile
from apps.analyzer.models import MClassifierTitle, MClassifierAuthor, MClassifierFeed, MClassifierTag
from utils import json_functions as json
from utils.user_functions import ajax_login_required
from utils.view_functions import render_to, is_true
from utils.user_functions import get_user
from utils import log as logging
from vendor.paypalapi.exceptions import PayPalAPIResponseError
from 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', 'days_of_unread')
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 list(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)
2012-03-07 16:32:02 -08:00
elif preference_name in SPECIAL_PREFERENCES:
if preference_name == 'autofollow_friends':
social_services = MSocialServices.get_user(request.user.pk)
2012-03-07 16:32:02 -08:00
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()
2013-07-18 15:13:39 -07:00
logging.user(request, "~FMSaving preference: %s" % new_preferences)
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
2014-02-14 15:30:46 -08:00
@csrf_protect
def login(request):
form = LoginForm()
if request.method == "POST":
form = LoginForm(data=request.POST)
if form.is_valid():
login_user(request, form.get_user(), backend='django.contrib.auth.backends.ModelBackend')
logging.user(form.get_user(), "~FG~BBOAuth Login~FW")
return HttpResponseRedirect(request.POST['next'] or reverse('index'))
return render(request, 'accounts/login.html', {
'form': form,
'next': request.POST.get('next', "") or request.GET.get('next', "")
})
2017-12-08 16:43:30 -08:00
@csrf_exempt
2014-02-14 15:30:46 -08:00
def signup(request):
2017-12-08 16:43:30 -08:00
form = SignupForm(prefix="signup")
recaptcha = request.POST.get('g-recaptcha-response', None)
recaptcha_error = None
if settings.ENFORCE_SIGNUP_CAPTCHA:
if not recaptcha:
recaptcha_error = "Please hit the \"I'm not a robot\" button."
else:
response = requests.post('https://www.google.com/recaptcha/api/siteverify', {
'secret': settings.RECAPTCHA_SECRET_KEY,
'response': recaptcha,
})
result = response.json()
if not result['success']:
recaptcha_error = "Really, please hit the \"I'm not a robot\" button."
2014-02-14 15:30:46 -08:00
if request.method == "POST":
2017-12-08 16:43:30 -08:00
form = SignupForm(data=request.POST, prefix="signup")
if form.is_valid() and not recaptcha_error:
2014-02-14 15:30:46 -08:00
new_user = form.save()
login_user(request, new_user, backend='django.contrib.auth.backends.ModelBackend')
2015-06-27 10:59:06 -07:00
logging.user(new_user, "~FG~SB~BBNEW SIGNUP: ~FW%s" % new_user.email)
2014-02-14 15:30:46 -08:00
new_user.profile.activate_free()
return HttpResponseRedirect(request.POST['next'] or reverse('index'))
2014-02-14 15:30:46 -08:00
return render(request, 'accounts/signup.html', {
2014-02-14 15:30:46 -08:00
'form': form,
2017-12-08 16:43:30 -08:00
'recaptcha_error': recaptcha_error,
'next': request.POST.get('next', "")
})
2014-11-06 13:33:34 -08:00
@login_required
@csrf_protect
def redeem_code(request):
2014-11-06 14:41:55 -08:00
code = request.GET.get('code', None)
form = RedeemCodeForm(initial={'gift_code': code})
2014-11-06 13:33:34 -08:00
if request.method == "POST":
form = RedeemCodeForm(data=request.POST)
if form.is_valid():
2014-11-06 14:55:27 -08:00
gift_code = request.POST['gift_code']
MRedeemedCode.redeem(user=request.user, gift_code=gift_code)
return render(request, 'reader/paypal_return.xhtml')
2014-11-06 13:33:34 -08:00
return render(request, 'accounts/redeem_code.html', {
2014-11-06 13:33:34 -08:00
'form': form,
'code': request.POST.get('code', ""),
'next': request.POST.get('next', "")
})
2014-11-06 13:33:34 -08:00
@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[list(form.errors.keys())[0]][0]
payload = {
"username": request.user.username,
"email": request.user.email,
2012-04-20 08:45:29 -07:00
"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')
feed_layout_setting = request.POST.get('feed_layout_setting')
view_settings = json.decode(request.user.profile.view_settings)
setting = view_settings.get(feed_id, {})
if isinstance(setting, str): 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
if feed_layout_setting: setting['l'] = feed_layout_setting
view_settings[feed_id] = setting
request.user.profile.view_settings = json.encode(view_settings)
request.user.profile.save()
logging.user(request, "~FMView settings: %s/%s/%s/%s" % (feed_view_setting,
feed_order_setting, feed_read_filter_setting, feed_layout_setting))
response = dict(code=code)
return response
@ajax_login_required
@require_POST
@json.json_view
def clear_view_setting(request):
code = 1
view_setting_type = request.POST.get('view_setting_type')
view_settings = json.decode(request.user.profile.view_settings)
new_view_settings = {}
removed = 0
for feed_id, view_setting in list(view_settings.items()):
if view_setting_type == 'layout' and 'l' in view_setting:
del view_setting['l']
removed += 1
if view_setting_type == 'view' and 'v' in view_setting:
del view_setting['v']
removed += 1
if view_setting_type == 'order' and 'o' in view_setting:
del view_setting['o']
removed += 1
if view_setting_type == 'order' and 'r' in view_setting:
del view_setting['r']
removed += 1
new_view_settings[feed_id] = view_setting
request.user.profile.view_settings = json.encode(new_view_settings)
request.user.profile.save()
logging.user(request, "~FMClearing view settings: %s (found %s)" % (view_setting_type, removed))
response = dict(code=code, view_settings=view_settings, removed=removed)
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()
2013-07-18 15:13:39 -07:00
logging.user(request, "~FMCollapsing folder: %s" % collapsed_folders)
response = dict(code=code)
return response
2010-10-16 18:52:52 -04:00
def paypal_webhooks(request):
data = json.decode(request.body)
logging.user(request, f" ---> {data['event_type']}: {data}")
if data['event_type'] == "BILLING.SUBSCRIPTION.ACTIVATED":
user = User.objects.get(pk=int(data['resource']['custom_id']))
user.profile.store_paypal_sub_id(data['resource']['id'])
plan = Profile.paypal_plan_id_to_plan(data['resource']['plan_id'])
if plan == "premium":
user.profile.activate_premium()
elif plan == "archive":
user.profile.activate_archive()
user.profile.cancel_premium_stripe()
elif data['event_type'] == "PAYMENT.SALE.COMPLETED":
user = User.objects.get(pk=int(data['resource']['custom']))
user.profile.setup_premium_history()
return HttpResponse("OK")
2010-10-16 18:52:52 -04:00
def paypal_form(request):
2010-10-23 11:13:44 -04:00
domain = Site.objects.get_current().domain
2010-10-16 18:52:52 -04:00
paypal_dict = {
"cmd": "_xclick-subscriptions",
"business": "samuel@ofbrooklyn.com",
2010-10-16 18:52:52 -04:00
"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",
2010-10-23 11:13:44 -04:00
"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,
2010-10-16 18:52:52 -04:00
}
# Create the instance.
form = PayPalPaymentsForm(initial=paypal_dict, button_type="subscribe")
logging.user(request, "~FBLoading paypal/feedchooser")
2010-10-16 18:52:52 -04:00
# Output the button.
2020-06-08 00:10:52 -04:00
return HttpResponse(form.render(), content_type='text/html')
def paypal_return(request):
return render(request, 'reader/paypal_return.xhtml', {
'user_profile': request.user.profile,
})
@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
2010-10-23 10:46:35 -04:00
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()
2011-10-19 18:14:56 -07:00
if retries >= 30:
code = -1
2013-03-13 23:07:50 -07:00
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,
}
@ajax_login_required
@json.json_view
def save_ios_receipt(request):
receipt = request.POST.get('receipt')
product_identifier = request.POST.get('product_identifier')
transaction_identifier = request.POST.get('transaction_identifier')
2018-02-07 12:46:28 -08:00
logging.user(request, "~BM~FBSaving iOS Receipt: %s %s" % (product_identifier, transaction_identifier))
paid = request.user.profile.activate_ios_premium(transaction_identifier)
if paid:
2019-08-22 20:07:16 -07:00
logging.user(request, "~BM~FBSending iOS Receipt email: %s %s" % (product_identifier, transaction_identifier))
subject = "iOS Premium: %s (%s)" % (request.user.profile, product_identifier)
message = """User: %s (%s) -- Email: %s, product: %s, txn: %s, receipt: %s""" % (request.user.username, request.user.pk, request.user.email, product_identifier, transaction_identifier, receipt)
mail_admins(subject, message, fail_silently=True)
2019-08-22 20:07:16 -07:00
else:
logging.user(request, "~BM~FBNot sending iOS Receipt email, already paid: %s %s" % (product_identifier, transaction_identifier))
return request.user.profile
@ajax_login_required
@json.json_view
def save_android_receipt(request):
order_id = request.POST.get('order_id')
product_id = request.POST.get('product_id')
logging.user(request, "~BM~FBSaving Android Receipt: %s %s" % (product_id, order_id))
paid = request.user.profile.activate_android_premium(order_id)
if paid:
logging.user(request, "~BM~FBSending Android Receipt email: %s %s" % (product_id, order_id))
2020-11-12 10:11:48 -05:00
subject = "Android Premium: %s (%s)" % (request.user.profile, product_id)
message = """User: %s (%s) -- Email: %s, product: %s, order: %s""" % (request.user.username, request.user.pk, request.user.email, product_id, order_id)
mail_admins(subject, message, fail_silently=True)
else:
logging.user(request, "~BM~FBNot sending Android Receipt email, already paid: %s %s" % (product_id, order_id))
return request.user.profile
@login_required
def stripe_form(request):
user = request.user
success_updating = False
stripe.api_key = settings.STRIPE_SECRET
plan = PLANS[0][0]
renew = is_true(request.GET.get('renew', False))
2013-05-24 12:11:52 -07:00
error = None
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 = None
current_premium = (user.profile.is_premium and
user.profile.premium_expire and
user.profile.premium_expire > datetime.datetime.now())
# Are they changing their existing card?
if user.profile.stripe_id:
customer = stripe.Customer.retrieve(user.profile.stripe_id)
try:
2018-07-24 10:54:36 -04:00
card = customer.sources.create(source=zebra_form.cleaned_data['stripe_token'])
2021-04-29 15:25:02 -04:00
except stripe.error.CardError:
error = "This card was declined."
else:
customer.default_card = card.id
customer.save()
user.profile.strip_4_digits = zebra_form.cleaned_data['last_4_digits']
user.profile.save()
user.profile.activate_premium() # TODO: Remove, because webhooks are slow
success_updating = True
2013-05-24 12:11:52 -07:00
else:
try:
customer = stripe.Customer.create(**{
2018-07-24 10:54:36 -04:00
'source': zebra_form.cleaned_data['stripe_token'],
'plan': zebra_form.cleaned_data['plan'],
'email': user.email,
'description': user.username,
})
2021-04-29 15:25:02 -04:00
except stripe.error.CardError:
error = "This card was declined."
else:
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
# Check subscription to ensure latest plan, otherwise cancel it and subscribe
if success_updating and customer and customer.subscriptions.total_count == 1:
subscription = customer.subscriptions.data[0]
if subscription['plan']['id'] != "newsblur-premium-36":
for sub in customer.subscriptions:
sub.delete()
customer = stripe.Customer.retrieve(user.profile.stripe_id)
2018-07-24 10:58:43 -04:00
if success_updating and customer and customer.subscriptions.total_count == 0:
params = dict(
customer=customer.id,
items=[
{
"plan": "newsblur-premium-36",
},
])
premium_expire = user.profile.premium_expire
if current_premium and premium_expire:
if premium_expire < (datetime.datetime.now() + datetime.timedelta(days=365)):
params['billing_cycle_anchor'] = premium_expire.strftime('%s')
params['trial_end'] = premium_expire.strftime('%s')
stripe.Subscription.create(**params)
else:
zebra_form = StripePlusPaymentForm(email=user.email, plan=plan)
if success_updating:
return render(request, 'reader/paypal_return.xhtml')
2013-03-14 10:01:38 -07:00
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
2013-05-13 18:20:33 -07:00
new_user_queue_position -= 1
immediate_charge = True
if user.profile.premium_expire and user.profile.premium_expire > datetime.datetime.now():
immediate_charge = False
2013-03-14 10:01:38 -07:00
logging.user(request, "~BM~FBLoading Stripe form")
return render(request, '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,
'renew': renew,
'immediate_charge': immediate_charge,
2013-05-24 12:11:52 -07:00
'error': error,
}
)
@login_required
def switch_subscription(request):
stripe.api_key = settings.STRIPE_SECRET
plan = request.POST['plan']
if plan == "change":
return stripe_checkout(request)
switch_successful = request.user.profile.switch_subscription(plan)
logging.user(request, "~FCSwitching subscription to ~SB%s~SN~FC (%s)" %(
plan,
'~FGsucceeded~FC' if switch_successful else '~FRfailed~FC'
))
if switch_successful:
return HttpResponseRedirect(reverse('stripe-return'))
return stripe_checkout(request)
2022-01-21 16:41:22 -05:00
@login_required
def stripe_checkout(request):
stripe.api_key = settings.STRIPE_SECRET
2022-01-21 16:41:22 -05:00
domain = Site.objects.get_current().domain
plan = request.POST['plan']
if plan == "change":
checkout_session = stripe.billing_portal.Session.create(
customer=request.user.profile.stripe_id,
2022-01-27 12:33:37 -05:00
return_url="http://%s%s?next=payments" % (domain, reverse('index')),
)
return HttpResponseRedirect(checkout_session.url, status=303)
price = Profile.plan_to_stripe_price(plan)
2022-01-24 16:27:37 -05:00
session_dict = {
"line_items": [
2022-01-21 16:41:22 -05:00
{
'price': price,
2022-01-21 16:41:22 -05:00
'quantity': 1,
},
],
2022-01-24 16:27:37 -05:00
"mode": 'subscription',
"metadata": {"newsblur_user_id": request.user.pk},
"success_url": "http://%s%s" % (domain, reverse('stripe-return')),
"cancel_url": "http://%s%s" % (domain, reverse('index')),
}
if request.user.profile.stripe_id:
session_dict['customer'] = request.user.profile.stripe_id
else:
session_dict["customer_email"] = request.user.email
checkout_session = stripe.checkout.Session.create(**session_dict)
2022-01-21 16:41:22 -05:00
logging.user(request, "~BM~FBLoading Stripe checkout")
return HttpResponseRedirect(checkout_session.url, status=303)
@render_to('reader/activities_module.xhtml')
def load_activities(request):
user = get_user(request)
2020-06-08 11:24:42 -04:00
page = max(1, int(request.GET.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',
2012-12-03 15:03:47 -08:00
}
@ajax_login_required
@json.json_view
def payment_history(request):
user = request.user
if request.user.is_staff:
2020-06-08 11:24:42 -04:00
user_id = request.GET.get('user_id', request.user.pk)
user = User.objects.get(pk=user_id)
history = PaymentHistory.objects.filter(user=user)
2014-04-03 12:44:04 -07:00
statistics = {
"created_date": user.date_joined,
2014-04-03 12:44:04 -07:00
"last_seen_date": user.profile.last_seen_on,
2015-07-21 10:55:17 -07:00
"last_seen_ip": user.profile.last_seen_ip,
"timezone": str(user.profile.timezone),
2014-04-03 12:44:04 -07:00
"stripe_id": user.profile.stripe_id,
"paypal_email": user.profile.latest_paypal_email,
2014-04-03 12:44:04 -07:00
"profile": user.profile,
"feeds": UserSubscription.objects.filter(user=user).count(),
"email": user.email,
"read_story_count": RUserStory.read_story_count(user.pk),
"feed_opens": UserSubscription.objects.filter(user=user).aggregate(sum=Sum('feed_opens'))['sum'],
"training": {
'title_ps': MClassifierTitle.objects.filter(user_id=user.pk, score__gt=0).count(),
'title_ng': MClassifierTitle.objects.filter(user_id=user.pk, score__lt=0).count(),
'tag_ps': MClassifierTag.objects.filter(user_id=user.pk, score__gt=0).count(),
'tag_ng': MClassifierTag.objects.filter(user_id=user.pk, score__lt=0).count(),
'author_ps': MClassifierAuthor.objects.filter(user_id=user.pk, score__gt=0).count(),
'author_ng': MClassifierAuthor.objects.filter(user_id=user.pk, score__lt=0).count(),
'feed_ps': MClassifierFeed.objects.filter(user_id=user.pk, score__gt=0).count(),
'feed_ng': MClassifierFeed.objects.filter(user_id=user.pk, score__lt=0).count(),
}
2014-04-03 12:44:04 -07:00
}
2022-01-26 15:51:26 -05:00
next_invoice = None
stripe_customer = user.profile.stripe_customer()
if stripe_customer:
try:
invoice = stripe.Invoice.upcoming(customer=stripe_customer.id)
for lines in invoice.lines.data:
next_invoice = dict(payment_date=datetime.datetime.fromtimestamp(lines.period.start),
payment_amount=invoice.amount_due/100.0,
payment_provider="(scheduled)",
scheduled=True)
break
except stripe.error.InvalidRequestError:
pass
return {
'is_premium': user.profile.is_premium,
2022-01-26 15:51:26 -05:00
'is_archive': user.profile.is_archive,
'is_pro': user.profile.is_pro,
'premium_expire': user.profile.premium_expire,
2022-01-26 15:51:26 -05:00
'premium_renewal': user.profile.premium_renewal,
2014-04-03 12:44:04 -07:00
'payments': history,
'statistics': statistics,
2022-01-26 15:51:26 -05:00
'next_invoice': next_invoice,
}
@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):
2020-06-08 11:25:23 -04:00
user_id = request.POST.get('user_id')
partial = request.POST.get('partial', False)
user = User.objects.get(pk=user_id)
try:
2013-07-04 11:29:41 -07:00
refunded = user.profile.refund_premium(partial=partial)
2021-01-26 12:24:24 -05:00
except stripe.error.InvalidRequestError as e:
refunded = e
except PayPalAPIResponseError as 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):
2020-06-08 11:25:23 -04:00
user_id = request.POST.get('user_id')
user = User.objects.get(pk=user_id)
gift = MGiftCode.add(gifting_user_id=User.objects.get(username='samuel').pk,
receiving_user_id=user.pk)
MRedeemedCode.redeem(user, gift.gift_code)
return {'code': user.profile.is_premium}
2014-07-09 11:30:34 -07:00
@staff_member_required
@ajax_login_required
@json.json_view
def never_expire_premium(request):
2020-06-08 11:25:52 -04:00
user_id = request.POST.get('user_id')
2021-01-03 14:05:17 -05:00
years = int(request.POST.get('years', 0))
user = User.objects.get(pk=user_id)
if user.profile.is_premium:
2021-01-03 13:59:33 -05:00
if years:
user.profile.premium_expire = datetime.datetime.now() + datetime.timedelta(days=365*years)
else:
user.profile.premium_expire = None
user.profile.save()
return {'code': 1}
return {'code': -1}
2014-07-09 11:30:34 -07:00
@staff_member_required
@ajax_login_required
@json.json_view
def update_payment_history(request):
2020-06-08 11:25:52 -04:00
user_id = request.POST.get('user_id')
2014-07-09 11:30:34 -07:00
user = User.objects.get(pk=user_id)
user.profile.setup_premium_history(set_premium_expire=False)
2014-07-09 11:30:34 -07:00
return {'code': 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,
}
@ajax_login_required
@json.json_view
def delete_starred_stories(request):
timestamp = request.POST.get('timestamp', None)
if timestamp:
delete_date = datetime.datetime.fromtimestamp(int(timestamp))
else:
delete_date = datetime.datetime.now()
starred_stories = MStarredStory.objects.filter(user_id=request.user.pk,
starred_date__lte=delete_date)
stories_deleted = starred_stories.count()
starred_stories.delete()
MStarredStoryCounts.count_for_user(request.user.pk, total_only=True)
starred_counts, starred_count = MStarredStoryCounts.user_counts(request.user.pk, include_total=True)
logging.user(request.user, "~BC~FRDeleting %s/%s starred stories (%s)" % (stories_deleted,
stories_deleted+starred_count, delete_date))
return dict(code=1, stories_deleted=stories_deleted, starred_counts=starred_counts,
starred_count=starred_count)
@ajax_login_required
@json.json_view
def delete_all_sites(request):
request.user.profile.send_opml_export_email(reason="You have deleted all of your sites, so here's a backup of all of your subscriptions just in case.")
subs = UserSubscription.objects.filter(user=request.user)
sub_count = subs.count()
subs.delete()
usf = UserSubscriptionFolders.objects.get(user=request.user)
usf.folders = '[]'
usf.save()
logging.user(request.user, "~BC~FRDeleting %s sites" % sub_count)
return dict(code=1)
@login_required
@render_to('profile/email_optout.xhtml')
def email_optout(request):
user = request.user
user.profile.send_emails = False
user.profile.save()
return {
"user": user,
}
@json.json_view
def ios_subscription_status(request):
logging.debug(" ---> iOS Subscription Status: %s" % request.body)
data = json.decode(request.body)
subject = "iOS Subscription Status: %s" % data.get('notification_type', "[missing]")
message = """%s""" % (request.body)
mail_admins(subject, message)
return {
"code": 1
}
2020-11-13 11:18:18 -05:00
def trigger_error(request):
logging.user(request.user, "~BR~FW~SBTriggering divison by zero")
2020-11-13 11:18:18 -05:00
division_by_zero = 1 / 0
return HttpResponseRedirect(reverse('index'))