This is the only idea I have for stopping the spam.
parent
e674d88605
commit
3f6d6da389
|
@ -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…</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 »</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 %}
|
|
@ -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'))
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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">
|
||||
|
|
4
urls.py
4
urls.py
|
@ -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())
|
||||
|
|
|
@ -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/'
|
||||
|
|
Loading…
Reference in New Issue