This is the only idea I have for stopping the spam.

master
Nick Sergeant 2016-05-10 12:35:15 -04:00
parent e674d88605
commit 3f6d6da389
10 changed files with 250 additions and 10 deletions

View File

@ -0,0 +1,103 @@
{% extends "base.html" %}
{% block page-title %}Activate account{% endblock %}
{% block body-class %}{{ block.super }} static signup pro pro-signup{% endblock %}
{% block extra-scripts %}
<script type="text/javascript" src="https://js.stripe.com/v1/"></script>
{% endblock %}
{% block js %}
{{ block.super }}
{% if debug %}
Stripe.setPublishableKey('pk_test_cgknmaWRMQeJt2adEdvH3T9l');
{% else %}
Stripe.setPublishableKey('pk_live_gUO2nCl7dhx6j0posz6gnbhA');
{% endif %}
{% endblock %}
{% block breadcrumb %}
<li><a href="/account/activate/">Activate</a></li>
{% endblock %}
{% block content %}
{% if request.GET.declined %}
<div class="alert alert-error" style="margin: 30px;">
<strong>{{ request.GET.declined }}</strong> You have not been charged. Please try again.
</div>
{% endif %}
<form class="form-horizontal static-box" id="pro-signup" method="post" action="/account/activate/">
<fieldset>
<div class="info">
Activate for a one-time fee of <span>$9</span>.
</div>
<div class="payment-form">
<div class="payment-loading"><span>Please wait&hellip;</span></div>
<div class="payment-errors alert alert-error"></div>
<div class="control-group">
<label class="control-label" for="number">Card number:</label>
<div class="controls cards">
<input type="text" class="input-xlarge" id="number" />
<img src="{{ STATIC_URL }}img/card-visa.png" alt="Visa" />
<img src="{{ STATIC_URL }}img/card-mastercard.png" alt="MasterCard" />
<img src="{{ STATIC_URL }}img/card-discover.png" alt="Discover" />
<img src="{{ STATIC_URL }}img/card-american-express.png" alt="American Express" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="exp-month">Expiration date:</label>
<div class="controls">
<select id="exp-month" class="span2 exp-month">
<option value="">----</option>
<option value="01">01 - January</option>
<option value="02">02 - February</option>
<option value="03">03 - March</option>
<option value="04">04 - April</option>
<option value="05">05 - May</option>
<option value="06">06 - June</option>
<option value="07">07 - July</option>
<option value="08">08 - August</option>
<option value="09">09 - September</option>
<option value="10">10 - October</option>
<option value="11">11 - November</option>
<option value="12">12 - December</option>
</select>
<select id="exp-year" class="span2">
<option value="">----</option>
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="cvc">Security code (CVC):</label>
<div class="controls">
<input type="text" class="input-min span1" id="cvc">
</div>
</div>
</div>
<div class="form-actions">
{% csrf_token %}
<button type="submit" class="btn btn-success">Activate &raquo;</button>
<div class="security">
<a href="https://stripe.com/help/security">Secure</a> by default. Every Snipt page is secure.
</div>
<div class="stripe">
Your credit card is stored securely with <a href="https://stripe.com">Stripe</a> and we use <a href="https://stripe.com/docs/stripe.js">Stripe.js</a> for maximum security.
</div>
</div>
<div class="form-actions" style="color: #A2A2A2;">
Prefer to pay with PayPal? Email <a href="mailto:support@snipt.net">support@snipt.net</a>.
</div>
</fieldset>
</form>
{% endblock %}

View File

@ -3,5 +3,7 @@ from django.conf.urls import *
urlpatterns = \
patterns('',
url(r'^activate/$', views.activate,
name='account-activate'),
url(r'^stats/$', views.stats, name='account-stats'),
url(r'^', views.account, name='account-detail'))

View File

@ -1,5 +1,12 @@
import datetime
import os
import stripe
from annoying.decorators import render_to
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from snipts.models import Snipt
@ -9,6 +16,51 @@ def account(request):
return {}
@login_required
@render_to('activate.html')
def activate(request):
if request.method == 'POST':
token = request.POST['token']
stripe.api_key = os.environ.get('STRIPE_SECRET_KEY',
settings.STRIPE_SECRET_KEY)
try:
customer = stripe.Customer.create(card=token,
email=request.user.email)
stripe.Charge.create(amount=900,
currency='usd',
customer=customer.id,
description='Snipt.net')
except stripe.CardError as e:
error_message = e.json_body['error']['message']
return HttpResponseRedirect('/account/activate/?declined=%s' % error_message or
'Your card was declined.')
profile = request.user.profile
profile.pro_date = datetime.datetime.now()
profile.stripe_id = customer.id
profile.save()
request.user.is_active = True
request.user.save()
send_mail('[Snipt] New signup: {}'.format(request.user.username),
"""
User: https://snipt.net/{}
Email: {}
""".format(request.user.username, request.user.email),
'support@snipt.net',
['nick@snipt.net'],
fail_silently=False)
return HttpResponseRedirect('/login-redirect/')
else:
return {}
@login_required
@render_to('stats.html')
def stats(request):

View File

@ -96,6 +96,62 @@
window.ui_halted = false;
});
if (this.$body.hasClass('pro-signup')) {
var $form = $('form#pro-signup');
var $submit = $('button[type="submit"]', $form);
var $cardNumber = $('input#number');
var $expMonth = $('select#exp-month');
var $expYear = $('select#exp-year');
var $cvc = $('input#cvc');
$form.submit(function() {
$submit.attr('disabled', 'disabled');
var errors = false;
if (!Stripe.validateCardNumber($cardNumber.val())) {
$cardNumber.parents('div.control-group').addClass('error');
errors = true;
} else {
$cardNumber.parents('div.control-group').removeClass('error');
}
if (!Stripe.validateExpiry($expMonth.val(), $expYear.val())) {
$expMonth.parents('div.control-group').addClass('error');
errors = true;
} else {
$expMonth.parents('div.control-group').removeClass('error');
}
if (!Stripe.validateCVC($cvc.val())) {
$cvc.parents('div.control-group').addClass('error');
errors = true;
} else {
$cvc.parents('div.control-group').removeClass('error');
}
if (!errors) {
$('.payment-errors').hide();
$('.payment-loading').show();
Stripe.createToken({
number: $cardNumber.val(),
cvc: $cvc.val(),
exp_month: $expMonth.val(),
exp_year: $expYear.val()
}, that.stripeResponseHandler);
} else {
$submit.removeAttr('disabled');
}
return false;
});
}
if (this.$body.hasClass('login')) {
$('input#id_username').focus();
}
@ -192,6 +248,30 @@
$('div.infield label', this.$body).inFieldLabels({
fadeDuration: 200
});
},
stripeResponseHandler: function(status, response) {
var $form = $('form#pro-signup');
if (response.error) {
$('button[type="submit"]', $form).removeAttr('disabled');
$('.payment-loading').hide();
$('.payment-errors').text(response.error.message).show();
} else {
var token = response.id;
// Kill all of the form details so none of it touches our server.
// Note, this is unnecessary, because the inputs themselves do not
// have a name attr, meaning they'll never get sent to begin with.
$('input#name').val('');
$('input#number').val('');
$('select#exp-month').val('');
$('select#exp-year').val('');
$('input#cvc').val('');
$form.append("<input type='hidden' name='token' value='" + token + "'/>");
$form.get(0).submit();
}
}
});

View File

@ -27,9 +27,13 @@
{% empty %}
<div class="empty-snipts">
{% if request.user == user and not request.user.is_active %}
Welcome! Please click the activation link in your email in order to create your first snipt.
Welcome! Please <a target="_self" href="/account/activate/">activate your account</a> to create your first snipt.
{% else %}
No snipts to show here. Sorry!
{% if request.user == user %}
Welcome! Create your first snipt by clicking "Add Snipt" above.
{% else %}
No snipts to show here. Sorry!
{% endif %}
{% endif %}
</div>
{% endfor %}

View File

@ -97,7 +97,7 @@
<div class="inner">
<h2>Personal accounts</h2>
<p>
Individuals can post public and <code>private</code> snippets for free, making them perfect
Individuals can post public and <code>private</code> snippets, making them perfect
for storing and organizing code you never want to forget.
</p>
</div>

View File

@ -2,10 +2,6 @@ Hey there,
Welcome to Snipt. If you ever have any thoughts or issues with the site whatsoever, please feel free to contact me directly.
To complete your registration, please activate your account here:
https://{{site.domain}}{% url 'registration_activate' activation_key %}
Thanks!
Nick Sergeant

View File

@ -21,6 +21,9 @@
{% endif %}
{% endif %}
<fieldset>
<div class="info" style="line-height: 35px;">
Create an account for a one-time fee of <span>$9</span>.
</div>
<div style="padding-top: 30px;" class="control-group {% if form.errors.username %}error{% endif %}">
<label class="control-label" for="id_username">Username</label>
<div class="controls">

View File

@ -11,8 +11,8 @@ from snipts.api import (PublicSniptResource,
from snipts.views import search
from tastypie.api import Api
from utils.views import SniptRegistrationView
from views import (homepage, lexers, login_redirect, sitemap, tags,
user_api_key)
from views import (homepage, lexers, login_redirect, sitemap,
tags, user_api_key)
public_api = Api(api_name='public')
public_api.register(PublicSniptResource())

View File

@ -12,4 +12,4 @@ class SniptRegistrationView(RegistrationView):
return super(RegistrationView, self).dispatch(request, *args, **kwargs)
def get_success_url(self, request, user):
return '/{}/'.format(user.username)
return '/account/activate/'