Pro-everything
parent
806c09495a
commit
b7afdcc48b
|
@ -4,7 +4,7 @@ from accounts.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
class UserProfileAdmin(admin.ModelAdmin):
|
class UserProfileAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user', 'is_pro',)
|
list_display = ('user', 'is_pro', 'stripe_id',)
|
||||||
search_fields = ('user__username',)
|
search_fields = ('user__username',)
|
||||||
|
|
||||||
admin.site.register(UserProfile, UserProfileAdmin)
|
admin.site.register(UserProfile, UserProfileAdmin)
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Adding field 'UserProfile.stripe_id'
|
||||||
|
db.add_column('accounts_userprofile', 'stripe_id',
|
||||||
|
self.gf('django.db.models.fields.IntegerField')(null=True, blank=True),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Deleting field 'UserProfile.stripe_id'
|
||||||
|
db.delete_column('accounts_userprofile', 'stripe_id')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'accounts.userprofile': {
|
||||||
|
'Meta': {'object_name': 'UserProfile'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_pro': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'stripe_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||||
|
},
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['accounts']
|
|
@ -0,0 +1,66 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
|
||||||
|
# Changing field 'UserProfile.stripe_id'
|
||||||
|
db.alter_column('accounts_userprofile', 'stripe_id', self.gf('django.db.models.fields.CharField')(max_length=100, null=True))
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
|
||||||
|
# Changing field 'UserProfile.stripe_id'
|
||||||
|
db.alter_column('accounts_userprofile', 'stripe_id', self.gf('django.db.models.fields.IntegerField')(null=True))
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'accounts.userprofile': {
|
||||||
|
'Meta': {'object_name': 'UserProfile'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_pro': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'stripe_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||||
|
},
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['accounts']
|
|
@ -1,13 +1,10 @@
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
import caching.base
|
|
||||||
|
|
||||||
|
class UserProfile(models.Model):
|
||||||
class UserProfile(caching.base.CachingMixin, models.Model):
|
|
||||||
user = models.ForeignKey(User, unique=True)
|
user = models.ForeignKey(User, unique=True)
|
||||||
is_pro = models.BooleanField(default=False)
|
is_pro = models.BooleanField(default=False)
|
||||||
|
stripe_id = models.CharField(max_length=100, null=True, blank=True)
|
||||||
objects = caching.base.CachingManager()
|
|
||||||
|
|
||||||
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
|
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1282,6 +1282,26 @@ div.profile {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
a.pro {
|
||||||
|
background: #DFDFDF;
|
||||||
|
color: #3299B7;
|
||||||
|
clear: left;
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
font: bold italic 11px $Helvetica;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 5px 0;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
width: 100%;
|
||||||
|
@include border-radius(3px);
|
||||||
|
@include box-shadow(0, 0, 3px, #FFF);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #D8D8D8;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
div.empty-snipts {
|
div.empty-snipts {
|
||||||
background: rgba(128, 128, 128, .08);
|
background: rgba(128, 128, 128, .08);
|
||||||
|
@ -1750,6 +1770,33 @@ body.pro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fieldset {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
div.payment-errors {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
div.payment-loading {
|
||||||
|
background: rgba(#F2F2F2, .6);
|
||||||
|
display: none;
|
||||||
|
height: 202px;
|
||||||
|
position: absolute;
|
||||||
|
top: 37px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
span {
|
||||||
|
background: #FFF;
|
||||||
|
border: 3px solid #3299B7;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 80px auto 0 auto;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 120px;
|
||||||
|
@include border-radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
div.stripe {
|
div.stripe {
|
||||||
color: #C2C2C2;
|
color: #C2C2C2;
|
||||||
font: bold 11px/15px $Helvetica;
|
font: bold 11px/15px $Helvetica;
|
||||||
|
@ -1764,6 +1811,14 @@ body.pro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.form-horizontal {
|
||||||
|
fieldset {
|
||||||
|
padding-top: 18px;
|
||||||
|
}
|
||||||
|
div.form-actions {
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body.tags {
|
body.tags {
|
||||||
|
|
|
@ -134,12 +134,12 @@ url=url&&addSlash(url);if(typeof url==='undefined'){url='/api/private/snipt/';th
|
||||||
return url||null;};Site.SiteView=Backbone.View.extend({el:'body',initialize:function(opts){this.$body=$(this.el);this.$html=$('html');this.$html_body=this.$body.add(this.$html);this.$aside_nav=$('aside.nav',this.$body);this.$aside_nav_ul=$('ul',this.$aside_nav);this.$search_form=$('form.search',this.$body);this.$search_query=$('input#search-query',this.$body);this.$search_page_query=$('input.search-query',this.$body);this.$search_queries=this.$search_query.add(this.$search_page_query);this.$snipts=$('section#snipts article.snipt',this.$body);this.$modals=$('div.modal',this.$snipts);this.$main_edit=$('section#main-edit');this.$main=$('section#main');this.$keyboard_shortcuts=$('#keyboard-shortcuts',this.$body);this.$amazon_ads=$('section.amazon',this.$main);this.keyboardShortcuts();this.inFieldLabels();if(this.$amazon_ads.length){this.initAmazonAds();}
|
return url||null;};Site.SiteView=Backbone.View.extend({el:'body',initialize:function(opts){this.$body=$(this.el);this.$html=$('html');this.$html_body=this.$body.add(this.$html);this.$aside_nav=$('aside.nav',this.$body);this.$aside_nav_ul=$('ul',this.$aside_nav);this.$search_form=$('form.search',this.$body);this.$search_query=$('input#search-query',this.$body);this.$search_page_query=$('input.search-query',this.$body);this.$search_queries=this.$search_query.add(this.$search_page_query);this.$snipts=$('section#snipts article.snipt',this.$body);this.$modals=$('div.modal',this.$snipts);this.$main_edit=$('section#main-edit');this.$main=$('section#main');this.$keyboard_shortcuts=$('#keyboard-shortcuts',this.$body);this.$amazon_ads=$('section.amazon',this.$main);this.keyboardShortcuts();this.inFieldLabels();if(this.$amazon_ads.length){this.initAmazonAds();}
|
||||||
var SniptListView=Snipt.SniptListView;this.snipt_list=new SniptListView({'snipts':this.$snipts});var that=this;this.$body.click(function(){if(!window.ui_halted&&!window.from_modal&&window.$selected){window.$selected.trigger('deselect');}
|
var SniptListView=Snipt.SniptListView;this.snipt_list=new SniptListView({'snipts':this.$snipts});var that=this;this.$body.click(function(){if(!window.ui_halted&&!window.from_modal&&window.$selected){window.$selected.trigger('deselect');}
|
||||||
if(window.from_modal){window.from_modal=false;}
|
if(window.from_modal){window.from_modal=false;}
|
||||||
that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');var $cardNumber=$('input#number');var $expMonth=$('select[name="exp-month"]');var $expYear=$('select[name="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');}
|
that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');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.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(!Stripe.validateCVC($cvc.val())){$cvc.parents('div.control-group').addClass('error');errors=true;}else{$cvc.parents('div.control-group').removeClass('error');}
|
||||||
if(!errors){Stripe.createToken({name:$name.val(),number:$cardNumber.val(),cvc:$cvc.val(),exp_month:$expMonth.val(),exp_year:$expYear.val()},that.stripeResponseHandler);}else{$submit.removeAttr('disabled');}
|
if(!errors){$('.payment-errors').hide();$('.payment-loading').show();Stripe.createToken({name:$name.val(),number:$cardNumber.val(),cvc:$cvc.val(),exp_month:$expMonth.val(),exp_year:$expYear.val()},that.stripeResponseHandler);}else{$submit.removeAttr('disabled');}
|
||||||
return false;});}
|
return false;});}
|
||||||
window.ui_halted=false;},events:{'showKeyboardShortcuts':'showKeyboardShortcuts','click a.mini-profile':'toggleMiniProfile'},keyboardShortcuts:function(){var $body=this.$body;var that=this;$search_queries=this.$search_queries;$search_page_query=this.$search_page_query;$search_query=this.$search_query;$document=$(document);$document.bind('keydown','/',function(e){if(!window.ui_halted){e.preventDefault();if($body.hasClass('search')){$search_page_query.focus();}else{$search_query.focus();}}});$document.bind('keydown','h',function(e){if(!window.ui_halted){window.ui_halted=true;$body.trigger('showKeyboardShortcuts');}else{if(that.$keyboard_shortcuts.is(':visible')){that.$keyboard_shortcuts.modal('hide');}}});$document.bind('keydown','t',function(e){if(!window.ui_halted){window.open('','_blank');}});$document.bind('keydown','r',function(e){if(!window.ui_halted){location.reload(true);}});$document.bind('keydown','Ctrl+h',function(e){if(!window.ui_halted){history.go(-1);}});$document.bind('keydown','Ctrl+l',function(e){if(!window.ui_halted){history.go(1);}});this.$search_queries.bind('keydown','esc',function(e){if(!window.ui_halted){e.preventDefault();this.blur();}});},showKeyboardShortcuts:function(){this.$keyboard_shortcuts.modal('toggle');},toggleMiniProfile:function(e){this.$aside_nav.toggleClass('open');return false;},inFieldLabels:function(){$('div.infield label',this.$body).inFieldLabels({fadeDuration:200});},stripeResponseHandler:function(status,response){console.log(status);console.log(response);if(response.error){}else{}},initAmazonAds:function(){var $more=$('div.more',this.$amazon_ads);var that=this;var adTemplate=$('script#amazon-ad').html();$('a',$more).on('click',function(){var $current=$('li:visible',that.$amazon_ads);$('li',that.$amazon_ads).hide();if($(this).hasClass('see-previous')){var $prev=$current.prev();if($prev.length){$prev=$prev;}else{$prev=$('li',that.$amazon_ads).eq(-1);}
|
window.ui_halted=false;},events:{'showKeyboardShortcuts':'showKeyboardShortcuts','click a.mini-profile':'toggleMiniProfile'},keyboardShortcuts:function(){var $body=this.$body;var that=this;$search_queries=this.$search_queries;$search_page_query=this.$search_page_query;$search_query=this.$search_query;$document=$(document);$document.bind('keydown','/',function(e){if(!window.ui_halted){e.preventDefault();if($body.hasClass('search')){$search_page_query.focus();}else{$search_query.focus();}}});$document.bind('keydown','h',function(e){if(!window.ui_halted){window.ui_halted=true;$body.trigger('showKeyboardShortcuts');}else{if(that.$keyboard_shortcuts.is(':visible')){that.$keyboard_shortcuts.modal('hide');}}});$document.bind('keydown','t',function(e){if(!window.ui_halted){window.open('','_blank');}});$document.bind('keydown','r',function(e){if(!window.ui_halted){location.reload(true);}});$document.bind('keydown','Ctrl+h',function(e){if(!window.ui_halted){history.go(-1);}});$document.bind('keydown','Ctrl+l',function(e){if(!window.ui_halted){history.go(1);}});this.$search_queries.bind('keydown','esc',function(e){if(!window.ui_halted){e.preventDefault();this.blur();}});},showKeyboardShortcuts:function(){this.$keyboard_shortcuts.modal('toggle');},toggleMiniProfile:function(e){this.$aside_nav.toggleClass('open');return false;},inFieldLabels:function(){$('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;$('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();}},initAmazonAds:function(){var $more=$('div.more',this.$amazon_ads);var that=this;var adTemplate=$('script#amazon-ad').html();$('a',$more).on('click',function(){var $current=$('li:visible',that.$amazon_ads);$('li',that.$amazon_ads).hide();if($(this).hasClass('see-previous')){var $prev=$current.prev();if($prev.length){$prev=$prev;}else{$prev=$('li',that.$amazon_ads).eq(-1);}
|
||||||
$prev.fadeIn('fast');}else{var $next=$current.next();if($next.length){$next=$next;}else{$next=$('li',that.$amazon_ads).eq(0);}
|
$prev.fadeIn('fast');}else{var $next=$current.next();if($next.length){$next=$next;}else{$next=$('li',that.$amazon_ads).eq(0);}
|
||||||
$next.fadeIn('fast');}
|
$next.fadeIn('fast');}
|
||||||
return false;});$.getJSON('/api/public/a/',{'q':window.tag},function(resp){if(resp.result.length===0){that.$amazon_ads.slideUp('fast');}else{var html='';for(var i=0;i<resp.result.length;i++){if(resp.result[i].image){html+=_.template(adTemplate,{url:resp.result[i].url,title:resp.result[i].title,review:resp.result[i].review,image:resp.result[i].image});}}
|
return false;});$.getJSON('/api/public/a/',{'q':window.tag},function(resp){if(resp.result.length===0){that.$amazon_ads.slideUp('fast');}else{var html='';for(var i=0;i<resp.result.length;i++){if(resp.result[i].image){html+=_.template(adTemplate,{url:resp.result[i].url,title:resp.result[i].title,review:resp.result[i].review,image:resp.result[i].image});}}
|
||||||
|
|
|
@ -103,8 +103,8 @@
|
||||||
|
|
||||||
var $name = $('input#name');
|
var $name = $('input#name');
|
||||||
var $cardNumber = $('input#number');
|
var $cardNumber = $('input#number');
|
||||||
var $expMonth = $('select[name="exp-month"]');
|
var $expMonth = $('select#exp-month');
|
||||||
var $expYear = $('select[name="exp-year"]');
|
var $expYear = $('select#exp-year');
|
||||||
var $cvc = $('input#cvc');
|
var $cvc = $('input#cvc');
|
||||||
|
|
||||||
$form.submit(function() {
|
$form.submit(function() {
|
||||||
|
@ -135,6 +135,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errors) {
|
if (!errors) {
|
||||||
|
|
||||||
|
$('.payment-errors').hide();
|
||||||
|
$('.payment-loading').show();
|
||||||
|
|
||||||
Stripe.createToken({
|
Stripe.createToken({
|
||||||
name: $name.val(),
|
name: $name.val(),
|
||||||
number: $cardNumber.val(),
|
number: $cardNumber.val(),
|
||||||
|
@ -142,6 +146,7 @@
|
||||||
exp_month: $expMonth.val(),
|
exp_month: $expMonth.val(),
|
||||||
exp_year: $expYear.val()
|
exp_year: $expYear.val()
|
||||||
}, that.stripeResponseHandler);
|
}, that.stripeResponseHandler);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$submit.removeAttr('disabled');
|
$submit.removeAttr('disabled');
|
||||||
}
|
}
|
||||||
|
@ -227,19 +232,27 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
stripeResponseHandler: function(status, response) {
|
stripeResponseHandler: function(status, response) {
|
||||||
console.log(status);
|
|
||||||
console.log(response);
|
var $form = $('form#pro-signup');
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
// show the errors on the form
|
$('button[type="submit"]', $form).removeAttr('disabled');
|
||||||
//$(".payment-errors").text(response.error.message);
|
$('.payment-loading').hide();
|
||||||
|
$('.payment-errors').text(response.error.message).show();
|
||||||
} else {
|
} else {
|
||||||
//var form$ = $("#payment-form");
|
var token = response.id;
|
||||||
// token contains id, last4, and card type
|
|
||||||
//var token = response['id'];
|
// Kill all of the form details so none of it touches our server.
|
||||||
// insert the token into the form so it gets submitted to the server
|
// Note, this is unnecessary, because the inputs themselves do not
|
||||||
//form$.append("<input type='hidden' name='stripeToken' value='" + token + "'/>");
|
// have a name attr, meaning they'll never get sent to begin with.
|
||||||
// and submit
|
$('input#name').val('');
|
||||||
//form$.get(0).submit();
|
$('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();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initAmazonAds: function() {
|
initAmazonAds: function() {
|
||||||
|
|
|
@ -4,12 +4,12 @@ url=url&&addSlash(url);if(typeof url==='undefined'){url='/api/private/snipt/';th
|
||||||
return url||null;};Site.SiteView=Backbone.View.extend({el:'body',initialize:function(opts){this.$body=$(this.el);this.$html=$('html');this.$html_body=this.$body.add(this.$html);this.$aside_nav=$('aside.nav',this.$body);this.$aside_nav_ul=$('ul',this.$aside_nav);this.$search_form=$('form.search',this.$body);this.$search_query=$('input#search-query',this.$body);this.$search_page_query=$('input.search-query',this.$body);this.$search_queries=this.$search_query.add(this.$search_page_query);this.$snipts=$('section#snipts article.snipt',this.$body);this.$modals=$('div.modal',this.$snipts);this.$main_edit=$('section#main-edit');this.$main=$('section#main');this.$keyboard_shortcuts=$('#keyboard-shortcuts',this.$body);this.$amazon_ads=$('section.amazon',this.$main);this.keyboardShortcuts();this.inFieldLabels();if(this.$amazon_ads.length){this.initAmazonAds();}
|
return url||null;};Site.SiteView=Backbone.View.extend({el:'body',initialize:function(opts){this.$body=$(this.el);this.$html=$('html');this.$html_body=this.$body.add(this.$html);this.$aside_nav=$('aside.nav',this.$body);this.$aside_nav_ul=$('ul',this.$aside_nav);this.$search_form=$('form.search',this.$body);this.$search_query=$('input#search-query',this.$body);this.$search_page_query=$('input.search-query',this.$body);this.$search_queries=this.$search_query.add(this.$search_page_query);this.$snipts=$('section#snipts article.snipt',this.$body);this.$modals=$('div.modal',this.$snipts);this.$main_edit=$('section#main-edit');this.$main=$('section#main');this.$keyboard_shortcuts=$('#keyboard-shortcuts',this.$body);this.$amazon_ads=$('section.amazon',this.$main);this.keyboardShortcuts();this.inFieldLabels();if(this.$amazon_ads.length){this.initAmazonAds();}
|
||||||
var SniptListView=Snipt.SniptListView;this.snipt_list=new SniptListView({'snipts':this.$snipts});var that=this;this.$body.click(function(){if(!window.ui_halted&&!window.from_modal&&window.$selected){window.$selected.trigger('deselect');}
|
var SniptListView=Snipt.SniptListView;this.snipt_list=new SniptListView({'snipts':this.$snipts});var that=this;this.$body.click(function(){if(!window.ui_halted&&!window.from_modal&&window.$selected){window.$selected.trigger('deselect');}
|
||||||
if(window.from_modal){window.from_modal=false;}
|
if(window.from_modal){window.from_modal=false;}
|
||||||
that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');var $cardNumber=$('input#number');var $expMonth=$('select[name="exp-month"]');var $expYear=$('select[name="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');}
|
that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');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.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(!Stripe.validateCVC($cvc.val())){$cvc.parents('div.control-group').addClass('error');errors=true;}else{$cvc.parents('div.control-group').removeClass('error');}
|
||||||
if(!errors){Stripe.createToken({name:$name.val(),number:$cardNumber.val(),cvc:$cvc.val(),exp_month:$expMonth.val(),exp_year:$expYear.val()},that.stripeResponseHandler);}else{$submit.removeAttr('disabled');}
|
if(!errors){$('.payment-errors').hide();$('.payment-loading').show();Stripe.createToken({name:$name.val(),number:$cardNumber.val(),cvc:$cvc.val(),exp_month:$expMonth.val(),exp_year:$expYear.val()},that.stripeResponseHandler);}else{$submit.removeAttr('disabled');}
|
||||||
return false;});}
|
return false;});}
|
||||||
window.ui_halted=false;},events:{'showKeyboardShortcuts':'showKeyboardShortcuts','click a.mini-profile':'toggleMiniProfile'},keyboardShortcuts:function(){var $body=this.$body;var that=this;$search_queries=this.$search_queries;$search_page_query=this.$search_page_query;$search_query=this.$search_query;$document=$(document);$document.bind('keydown','/',function(e){if(!window.ui_halted){e.preventDefault();if($body.hasClass('search')){$search_page_query.focus();}else{$search_query.focus();}}});$document.bind('keydown','h',function(e){if(!window.ui_halted){window.ui_halted=true;$body.trigger('showKeyboardShortcuts');}else{if(that.$keyboard_shortcuts.is(':visible')){that.$keyboard_shortcuts.modal('hide');}}});$document.bind('keydown','t',function(e){if(!window.ui_halted){window.open('','_blank');}});$document.bind('keydown','r',function(e){if(!window.ui_halted){location.reload(true);}});$document.bind('keydown','Ctrl+h',function(e){if(!window.ui_halted){history.go(-1);}});$document.bind('keydown','Ctrl+l',function(e){if(!window.ui_halted){history.go(1);}});this.$search_queries.bind('keydown','esc',function(e){if(!window.ui_halted){e.preventDefault();this.blur();}});},showKeyboardShortcuts:function(){this.$keyboard_shortcuts.modal('toggle');},toggleMiniProfile:function(e){this.$aside_nav.toggleClass('open');return false;},inFieldLabels:function(){$('div.infield label',this.$body).inFieldLabels({fadeDuration:200});},stripeResponseHandler:function(status,response){console.log(status);console.log(response);if(response.error){}else{}},initAmazonAds:function(){var $more=$('div.more',this.$amazon_ads);var that=this;var adTemplate=$('script#amazon-ad').html();$('a',$more).on('click',function(){var $current=$('li:visible',that.$amazon_ads);$('li',that.$amazon_ads).hide();if($(this).hasClass('see-previous')){var $prev=$current.prev();if($prev.length){$prev=$prev;}else{$prev=$('li',that.$amazon_ads).eq(-1);}
|
window.ui_halted=false;},events:{'showKeyboardShortcuts':'showKeyboardShortcuts','click a.mini-profile':'toggleMiniProfile'},keyboardShortcuts:function(){var $body=this.$body;var that=this;$search_queries=this.$search_queries;$search_page_query=this.$search_page_query;$search_query=this.$search_query;$document=$(document);$document.bind('keydown','/',function(e){if(!window.ui_halted){e.preventDefault();if($body.hasClass('search')){$search_page_query.focus();}else{$search_query.focus();}}});$document.bind('keydown','h',function(e){if(!window.ui_halted){window.ui_halted=true;$body.trigger('showKeyboardShortcuts');}else{if(that.$keyboard_shortcuts.is(':visible')){that.$keyboard_shortcuts.modal('hide');}}});$document.bind('keydown','t',function(e){if(!window.ui_halted){window.open('','_blank');}});$document.bind('keydown','r',function(e){if(!window.ui_halted){location.reload(true);}});$document.bind('keydown','Ctrl+h',function(e){if(!window.ui_halted){history.go(-1);}});$document.bind('keydown','Ctrl+l',function(e){if(!window.ui_halted){history.go(1);}});this.$search_queries.bind('keydown','esc',function(e){if(!window.ui_halted){e.preventDefault();this.blur();}});},showKeyboardShortcuts:function(){this.$keyboard_shortcuts.modal('toggle');},toggleMiniProfile:function(e){this.$aside_nav.toggleClass('open');return false;},inFieldLabels:function(){$('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;$('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();}},initAmazonAds:function(){var $more=$('div.more',this.$amazon_ads);var that=this;var adTemplate=$('script#amazon-ad').html();$('a',$more).on('click',function(){var $current=$('li:visible',that.$amazon_ads);$('li',that.$amazon_ads).hide();if($(this).hasClass('see-previous')){var $prev=$current.prev();if($prev.length){$prev=$prev;}else{$prev=$('li',that.$amazon_ads).eq(-1);}
|
||||||
$prev.fadeIn('fast');}else{var $next=$current.next();if($next.length){$next=$next;}else{$next=$('li',that.$amazon_ads).eq(0);}
|
$prev.fadeIn('fast');}else{var $next=$current.next();if($next.length){$next=$next;}else{$next=$('li',that.$amazon_ads).eq(0);}
|
||||||
$next.fadeIn('fast');}
|
$next.fadeIn('fast');}
|
||||||
return false;});$.getJSON('/api/public/a/',{'q':window.tag},function(resp){if(resp.result.length===0){that.$amazon_ads.slideUp('fast');}else{var html='';for(var i=0;i<resp.result.length;i++){if(resp.result[i].image){html+=_.template(adTemplate,{url:resp.result[i].url,title:resp.result[i].title,review:resp.result[i].review,image:resp.result[i].image});}}
|
return false;});$.getJSON('/api/public/a/',{'q':window.tag},function(resp){if(resp.result.length===0){that.$amazon_ads.slideUp('fast');}else{var html='';for(var i=0;i<resp.result.length;i++){if(resp.result[i].image){html+=_.template(adTemplate,{url:resp.result[i].url,title:resp.result[i].title,review:resp.result[i].review,image:resp.result[i].image});}}
|
||||||
|
|
|
@ -15,12 +15,10 @@ from snipts.utils import slugify_uniquely
|
||||||
|
|
||||||
import datetime, md5, re
|
import datetime, md5, re
|
||||||
|
|
||||||
import caching.base
|
|
||||||
|
|
||||||
|
|
||||||
site = Site.objects.all()[0]
|
site = Site.objects.all()[0]
|
||||||
|
|
||||||
class Snipt(caching.base.CachingMixin, models.Model):
|
class Snipt(models.Model):
|
||||||
"""An individual Snipt."""
|
"""An individual Snipt."""
|
||||||
|
|
||||||
user = models.ForeignKey(User, blank=True, null=True)
|
user = models.ForeignKey(User, blank=True, null=True)
|
||||||
|
@ -44,8 +42,6 @@ class Snipt(caching.base.CachingMixin, models.Model):
|
||||||
modified = models.DateTimeField(auto_now=True, editable=False)
|
modified = models.DateTimeField(auto_now=True, editable=False)
|
||||||
publish_date = models.DateTimeField(blank=True, null=True)
|
publish_date = models.DateTimeField(blank=True, null=True)
|
||||||
|
|
||||||
objects = caching.base.CachingManager()
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
|
||||||
if not self.slug:
|
if not self.slug:
|
||||||
|
@ -158,14 +154,12 @@ class Snipt(caching.base.CachingMixin, models.Model):
|
||||||
else:
|
else:
|
||||||
return get_lexer_by_name(self.lexer).name
|
return get_lexer_by_name(self.lexer).name
|
||||||
|
|
||||||
class Favorite(caching.base.CachingMixin, models.Model):
|
class Favorite(models.Model):
|
||||||
snipt = models.ForeignKey(Snipt)
|
snipt = models.ForeignKey(Snipt)
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
|
|
||||||
created = models.DateTimeField(auto_now_add=True, editable=False)
|
created = models.DateTimeField(auto_now_add=True, editable=False)
|
||||||
modified = models.DateTimeField(auto_now=True, editable=False)
|
modified = models.DateTimeField(auto_now=True, editable=False)
|
||||||
|
|
||||||
objects = caching.base.CachingManager()
|
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'{} favorited by {}'.format(self.snipt.title, self.user.username)
|
return u'{} favorited by {}'.format(self.snipt.title, self.user.username)
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{% if user.profile.is_pro %}
|
||||||
|
<a class="pro" href="/pro/">Pro</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% include "snipts/tags-user.html" %}
|
{% include "snipts/tags-user.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -165,7 +165,7 @@
|
||||||
<div class="heading">
|
<div class="heading">
|
||||||
<h1>{{ tag.name }}</h1>
|
<h1>{{ tag.name }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<section class="amazon">
|
<section class="amazon {% if request.user.is_authenticated %}{% if request.user.profile.is_pro %}hidden{% endif %}{% endif %}">
|
||||||
<ul></ul>
|
<ul></ul>
|
||||||
<div class="more group">
|
<div class="more group">
|
||||||
<span></span>
|
<span></span>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block page-title %}Sign up for Snipt Pro{% endblock %}
|
||||||
|
|
||||||
|
{% block body-class %}{{ block.super }} static pro pro-signup{% endblock %}
|
||||||
|
|
||||||
|
{% block breadcrumb %}
|
||||||
|
<li><a href="/pro/">Snipt Pro</a></li>
|
||||||
|
<li><span class="prompt">/</span> <a href="/pro/signup/">Sign up</a></li>
|
||||||
|
<li><span class="prompt">/</span> <a href="#">Complete</a></li>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="static-box">
|
||||||
|
<h2>Snipt <span class="pro">Pro</span> members</h2>
|
||||||
|
<p><strong>Congratulations!</strong> You're now a Snipt Pro.</p>
|
||||||
|
<p>You should <a target="blank" href="http://twitter.com/intent/tweet?text=I'm now a Snipt Pro. Are you? https://snipt.net/pro/">tell the world</a>. If you ever need anything at all, <a href="mailto:nick@snipt.net">email Nick</a> directly.</p>
|
||||||
|
<p>We'll bill you again (for $19 USD) exactly one year from now. We'll give you a heads up.</p>
|
||||||
|
<p>Also, you rock. :)</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
Stripe.setPublishableKey('pk_RUeu9JcZVSzIr9qsJAnYrNJntJ8Vd');
|
Stripe.setPublishableKey('pk_dHS5OwimSS1q73HB1YejiNfw37eI3');
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
|
@ -24,19 +24,21 @@
|
||||||
<img src="/static/images/stripe.png" alt="" />
|
<img src="/static/images/stripe.png" alt="" />
|
||||||
</a>
|
</a>
|
||||||
<h2>Snipt <span class="pro">Pro</span> signup</h2>
|
<h2>Snipt <span class="pro">Pro</span> signup</h2>
|
||||||
<form class="form-horizontal" id="pro-signup" method="post" action="">
|
<form class="form-horizontal" id="pro-signup" method="post" action="/pro/signup/complete/">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
<div class="payment-loading"><span>Please wait…</span></div>
|
||||||
<legend>$19 USD will be charged to your card annually. Also, you rock. Tell yourself that every year, too.</legend>
|
<legend>$19 USD will be charged to your card annually. Also, you rock. Tell yourself that every year, too.</legend>
|
||||||
|
<div class="payment-errors alert alert-error"></div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label" for="name">Name on card:</label>
|
<label class="control-label" for="name">Name on card:</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="input-xlarge" id="name">
|
<input type="text" class="input-xlarge" id="name" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label" for="number">Card number:</label>
|
<label class="control-label" for="number">Card number:</label>
|
||||||
<div class="controls cards">
|
<div class="controls cards">
|
||||||
<input type="text" class="input-xlarge" id="number">
|
<input type="text" class="input-xlarge" id="number" />
|
||||||
<img src="/static/images/card-visa.png" alt="Visa" />
|
<img src="/static/images/card-visa.png" alt="Visa" />
|
||||||
<img src="/static/images/card-mastercard.png" alt="MasterCard" />
|
<img src="/static/images/card-mastercard.png" alt="MasterCard" />
|
||||||
<img src="/static/images/card-discover.png" alt="Discover" />
|
<img src="/static/images/card-discover.png" alt="Discover" />
|
||||||
|
@ -46,7 +48,7 @@
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label" for="exp-month">Expiration date:</label>
|
<label class="control-label" for="exp-month">Expiration date:</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<select name="exp-month" class="span2 exp-month">
|
<select id="exp-month" class="span2 exp-month">
|
||||||
<option value="">----</option>
|
<option value="">----</option>
|
||||||
<option value="01">01 - January</option>
|
<option value="01">01 - January</option>
|
||||||
<option value="02">02 - February</option>
|
<option value="02">02 - February</option>
|
||||||
|
@ -61,7 +63,7 @@
|
||||||
<option value="11">11 - November</option>
|
<option value="11">11 - November</option>
|
||||||
<option value="12">12 - December</option>
|
<option value="12">12 - December</option>
|
||||||
</select>
|
</select>
|
||||||
<select name="exp-year" class="span1">
|
<select id="exp-year" class="span1">
|
||||||
<option value="">----</option>
|
<option value="">----</option>
|
||||||
<option value="2012">2012</option>
|
<option value="2012">2012</option>
|
||||||
<option value="2013">2013</option>
|
<option value="2013">2013</option>
|
||||||
|
@ -84,6 +86,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
|
{% csrf_token %}
|
||||||
<button type="submit" class="btn btn-success">Sign up</button>
|
<button type="submit" class="btn btn-success">Sign up</button>
|
||||||
<div class="security">
|
<div class="security">
|
||||||
<a href="https://stripe.com/help/security">Secure</a> by default. Every page on Snipt is secured with HTTPS.
|
<a href="https://stripe.com/help/security">Secure</a> by default. Every page on Snipt is secured with HTTPS.
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li>No advertisements.</li>
|
<li>No advertisements.</li>
|
||||||
<li>“Pro” badge throughout the site.</li>
|
<li>“Pro” badge throughout the site.</li>
|
||||||
<li>You’re supporting current and future development. This stuff takes time and money.</li>
|
<li>You’re <strong>supporting</strong> current and future development. This stuff takes time and money.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h6>Planned Pro features (not in order):</h6>
|
<h6>Planned Pro features (not in order):</h6>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -25,8 +25,7 @@
|
||||||
<li>Ability to theme your embedded snipts in a specific theme.</li>
|
<li>Ability to theme your embedded snipts in a specific theme.</li>
|
||||||
<li>Custom domain and premium (Pro-only) themes for your <a href="https://blog.snipt.net/announcing-the-sniptnet-blogging-platform/">Snipt blog</a>.</li>
|
<li>Custom domain and premium (Pro-only) themes for your <a href="https://blog.snipt.net/announcing-the-sniptnet-blogging-platform/">Snipt blog</a>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>Pro accounts are opening soon… sit tight!</h3>
|
<h3>Pro accounts are just $19/year.</h3>
|
||||||
<!--<h3>Pro accounts are $19/year.</h3>-->
|
<h4><a href="/pro/signup/" class="btn btn-large btn-success">Sign Up Now</a></h4>
|
||||||
<!--<h4><a href="/pro/signup/" class="btn btn-large btn-success">Sign Up Now</a></h4>-->
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
6
urls.py
6
urls.py
|
@ -1,4 +1,4 @@
|
||||||
from views import amazon_search, amazon_image, lexers, pro_signup, sitemap, tags
|
from views import amazon_search, amazon_image, lexers, pro_signup, sitemap, tags, pro_signup_complete
|
||||||
from django.conf.urls.defaults import include, patterns, url
|
from django.conf.urls.defaults import include, patterns, url
|
||||||
from django.views.generic.simple import direct_to_template
|
from django.views.generic.simple import direct_to_template
|
||||||
from registration.forms import RegistrationFormUniqueEmail
|
from registration.forms import RegistrationFormUniqueEmail
|
||||||
|
@ -34,9 +34,11 @@ urlpatterns = patterns('',
|
||||||
url(r'^robots.txt$', direct_to_template, {'template': 'robots.txt'}),
|
url(r'^robots.txt$', direct_to_template, {'template': 'robots.txt'}),
|
||||||
url(r'^humans.txt$', direct_to_template, {'template': 'humans.txt'}),
|
url(r'^humans.txt$', direct_to_template, {'template': 'humans.txt'}),
|
||||||
url(r'^sitemap.xml$', sitemap),
|
url(r'^sitemap.xml$', sitemap),
|
||||||
|
url(r'^tags/$', tags),
|
||||||
|
|
||||||
url(r'^pro/$', direct_to_template, {'template': 'pro.html'}),
|
url(r'^pro/$', direct_to_template, {'template': 'pro.html'}),
|
||||||
url(r'^pro/signup/$', pro_signup),
|
url(r'^pro/signup/$', pro_signup),
|
||||||
url(r'^tags/$', tags),
|
url(r'^pro/signup/complete/$', pro_signup_complete),
|
||||||
|
|
||||||
url(r'^api/public/lexer/$', lexers),
|
url(r'^api/public/lexer/$', lexers),
|
||||||
url(r'^api/public/a/$', amazon_search),
|
url(r'^api/public/a/$', amazon_search),
|
||||||
|
|
27
views.py
27
views.py
|
@ -12,6 +12,8 @@ from taggit.models import Tag
|
||||||
|
|
||||||
import os, urllib
|
import os, urllib
|
||||||
|
|
||||||
|
import stripe
|
||||||
|
|
||||||
|
|
||||||
@ajax_request
|
@ajax_request
|
||||||
def amazon_search(request):
|
def amazon_search(request):
|
||||||
|
@ -95,6 +97,31 @@ def pro_signup(request):
|
||||||
return HttpResponseRedirect('/' + request.user.username + '/')
|
return HttpResponseRedirect('/' + request.user.username + '/')
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@render_to('pro-signup-complete.html')
|
||||||
|
def pro_signup_complete(request):
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
|
||||||
|
token = request.POST['token']
|
||||||
|
stripe.api_key = '5XchbRsWVbksTRWSX67kOdBnCf01DxSh'
|
||||||
|
|
||||||
|
customer = stripe.Customer.create(
|
||||||
|
card = token,
|
||||||
|
plan = 'snipt-pro',
|
||||||
|
email = request.user.email
|
||||||
|
)
|
||||||
|
|
||||||
|
profile = request.user.profile
|
||||||
|
profile.is_pro = True
|
||||||
|
profile.stripe_id = customer.id
|
||||||
|
profile.save()
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
else:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
def sitemap(request):
|
def sitemap(request):
|
||||||
|
|
||||||
tags = Tag.objects.filter(snipt__public=True)
|
tags = Tag.objects.filter(snipt__public=True)
|
||||||
|
|
Loading…
Reference in New Issue