Browse Source

Moar Heroku stuff.

master
Nick Sergeant 6 years ago
parent
commit
a2a81bbe02
  1. 66
      Makefile
  2. 54
      accounts/views.py
  3. 3
      media/css/snipt.css
  4. 1755
      media/js/snipt-all.min.js
  5. 210
      media/js/src/modules/site.min.js
  6. 45
      media/js/src/team.min.js
  7. 11
      templates/ad-detail.html
  8. 4
      templates/ad-leaderboard-pro.html
  9. 5
      templates/ad-leaderboard-teams.html
  10. 4
      templates/ad-leaderboard.html
  11. 7
      templates/ad-sidebar.html
  12. 7
      templates/base.html
  13. 4
      templates/registration/registration_form.html
  14. 4
      urls.py

66
Makefile

@ -1,4 +1,70 @@
assets:
@cat media/css/bootstrap.min.css \
media/css/blog-themes/pro-adams/style.css \
media/css/highlightjs-themes/tomorrow.css \
media/css/themes.css \
> media/css/pro.css
@cat media/css/bootstrap.min.css \
media/css/style.css \
media/css/themes.css \
media/css/chosen.css \
media/css/codemirror.css \
media/css/codemirror-themes/ambiance.css \
media/css/codemirror-themes/blackboard.css \
media/css/codemirror-themes/cobalt.css \
media/css/codemirror-themes/eclipse.css \
media/css/codemirror-themes/elegant.css \
media/css/codemirror-themes/erlang-dark.css \
media/css/codemirror-themes/lesser-dark.css \
media/css/codemirror-themes/monokai.css \
media/css/codemirror-themes/neat.css \
media/css/codemirror-themes/night.css \
media/css/codemirror-themes/rubyblue.css \
media/css/codemirror-themes/solarized.css \
media/css/codemirror-themes/twilight.css \
media/css/codemirror-themes/vibrant-ink.css \
media/css/codemirror-themes/xq-dark.css \
media/css/highlightjs-themes/tomorrow.css \
media/css/blog-themes/default/style.css \
> media/css/snipt.css
@cat media/js/src/account.js > media/js/src/account.min.js
@cat media/js/src/snipts.js > media/js/src/snipts.min.js
@cat media/js/src/jobs.js > media/js/src/jobs.min.js
@cat media/js/src/application.js > media/js/src/application.min.js
@cat media/js/src/team.js > media/js/src/team.min.js
@cat media/js/src/modules/site.js > media/js/src/modules/site.min.js
@cat media/js/src/modules/snipt.js > media/js/src/modules/snipt.min.js
@cat media/js/src/pro.js > media/js/src/pro.min.js
@cat media/js/libs/jquery.min.js \
media/js/libs/jquery-ui.min.js \
media/js/libs/angular.min.js \
media/js/libs/angular-route.min.js \
media/js/libs/underscore.js \
media/js/libs/json2.js \
media/js/libs/backbone.js \
media/js/libs/bootstrap.min.js \
media/js/plugins/jquery.hotkeys.js \
media/js/plugins/jquery.infieldlabel.js \
media/js/plugins/jquery.chosen.js \
media/js/src/application.min.js \
media/js/src/modules/site.min.js \
media/js/src/modules/snipt.min.js \
media/js/src/account.min.js \
media/js/src/snipts.min.js \
media/js/src/jobs.min.js \
media/js/src/team.min.js \
media/js/libs/codemirror.js \
media/js/libs/highlight.js \
> media/js/snipt-all.min.js
@cat media/js/libs/highlight.js \
media/js/src/pro.js \
> media/js/pro-all.min.js
deploy:
make assets
git add .
git commit -m "Asset autocompilation."
git push
git push heroku heroku:master
sass:

54
accounts/views.py

@ -1,12 +1,6 @@
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 HttpResponseBadRequest, HttpResponseRedirect
from django.http import HttpResponseRedirect
from snipts.models import Snipt
@ -19,49 +13,9 @@ def account(request):
@login_required
@render_to('activate.html')
def activate(request):
if request.method == 'POST':
if 'stripeToken' not in request.POST:
return HttpResponseBadRequest()
token = request.POST['stripeToken']
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=500,
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 {}
request.user.is_active = True
request.user.save()
return HttpResponseRedirect('/login-redirect/')
@login_required

3
media/css/snipt.css

File diff suppressed because one or more lines are too long

1755
media/js/snipt-all.min.js vendored

File diff suppressed because one or more lines are too long

210
media/js/src/modules/site.min.js vendored

@ -1,14 +1,198 @@
(function(Site) {
(function(Site){var Snipt=snipt.module('snipt');Backbone.oldSync=Backbone.sync;Backbone.Model.prototype.idAttribute='resource_uri';var addSlash=function(str){return str+((str.length>0&&str.charAt(str.length-1)==='/')?'':'/');};Backbone.sync=function(method,model,options){options.headers=_.extend({'Authorization':'ApiKey '+window.user+':'+window.api_key},options.headers);return Backbone.oldSync(method,model,options);};Backbone.Model.prototype.url=function(){var url=this.id;if(!url){url=this.urlRoot;url=url||this.collection&&(_.isFunction(this.collection.url)?this.collection.url():this.collection.url);if(url&&this.has('id')){url=addSlash(url)+this.get('id');}}
url=url&&addSlash(url);if(typeof url==='undefined'){url='/api/private/snipt/';this.unset('id',{'silent':true});this.unset('user',{'silent':true});}
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_main=$('aside.main',this.$body);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.keyboardShortcuts();this.inFieldLabels();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;}
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.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({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;});}
if(this.$body.hasClass('login')){$('input#id_username').focus();}
if(window.gittip_username){this.$aside_main.html(this.$aside_main.html().replace(/\[\[.*gittip.*\]\]/,'<iframe style="border: 0; margin: 0; padding: 0;" src="https://www.gittip.com/'+window.gittip_username+'/widget.html" width="48pt" height="22pt"></iframe>'));$('iframe',this.$aside_main).parent('p').prev('p').css('margin-bottom','10px');}
$('div.markdown pre code').each(function(i,e){hljs.highlightBlock(e);});var $embeddedTweets=$('div.embedded-tweet');if($embeddedTweets.length){$.each($embeddedTweets,function(){var $tweetPlaceholder=$(this);var tweetID=$tweetPlaceholder.attr('data-tweet-id');$.ajax({url:'https://api.twitter.com/1/statuses/oembed.json?id='+tweetID+'&align=center',dataType:'jsonp',type:'get',success:function(resp){$tweetPlaceholder.replaceWith($(resp.html));}});});}
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','Ctrl+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');}}});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();}}});})(snipt.module('site'));
var Snipt = snipt.module('snipt');
Backbone.oldSync = Backbone.sync;
Backbone.Model.prototype.idAttribute = 'resource_uri';
var addSlash = function(str) {
return str + ((str.length > 0 && str.charAt(str.length - 1) === '/') ? '' : '/');
};
Backbone.sync = function(method, model, options) {
options.headers = _.extend({
'Authorization': 'ApiKey ' + window.user + ':' + window.api_key
}, options.headers);
return Backbone.oldSync(method, model, options);
};
Backbone.Model.prototype.url = function() {
var url = this.id;
if (!url) {
url = this.urlRoot;
url = url || this.collection && (_.isFunction(this.collection.url) ? this.collection.url() : this.collection.url);
if (url && this.has('id')) {
url = addSlash(url) + this.get('id');
}
}
url = url && addSlash(url);
if (typeof url === 'undefined') {
url = '/api/private/snipt/';
this.unset('id', {'silent': true});
this.unset('user', {'silent': true});
}
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_main = $('aside.main', this.$body);
this.$aside_nav = $('aside.nav', this.$body);
this.$teams_nav = $('li.teams-nav', this.$body);
this.$add_snipt = $('li.add-snipt', 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.keyboardShortcuts();
this.inFieldLabels();
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;
}
that.$aside_nav.removeClass('open');
that.$teams_nav.removeClass('open');
that.$add_snipt.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('login')) {
$('input#id_username').focus();
}
// Populate any GitTip widgets.
if (window.gittip_username) {
this.$aside_main.html(this.$aside_main.html().replace(
/\[\[.*gittip.*\]\]/,
'<iframe style="border: 0; margin: 0; padding: 0;" src="https://www.gittip.com/' + window.gittip_username + '/widget.html" width="48pt" height="22pt"></iframe>')
);
$('iframe', this.$aside_main).parent('p').prev('p').css('margin-bottom', '10px');
}
// Highlight any Markdown code.
$('div.markdown pre code').each(function(i, e) {
hljs.highlightBlock(e);
});
// Populate any embedded tweets.
var $embeddedTweets = $('div.embedded-tweet');
if ($embeddedTweets.length) {
$.each($embeddedTweets, function() {
var $tweetPlaceholder = $(this);
var tweetID = $tweetPlaceholder.attr('data-tweet-id');
$.ajax({
url: 'https://api.twitter.com/1/statuses/oembed.json?id=' + tweetID + '&align=center',
dataType: 'jsonp',
type: 'get',
success: function(resp) {
$tweetPlaceholder.replaceWith($(resp.html));
}
});
});
}
window.ui_halted = false;
},
events: {
'showKeyboardShortcuts': 'showKeyboardShortcuts',
'click a.mini-profile': 'toggleMiniProfile',
'click a.teams-nav': 'toggleTeamsNav'
},
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', 'Ctrl+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');
}
}
});
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;
},
toggleTeamsNav: function(e) {
this.$teams_nav.toggleClass('open');
return false;
},
inFieldLabels: function () {
$('div.infield label', this.$body).inFieldLabels({
fadeDuration: 200
});
}
});
})(snipt.module('site'));

45
media/js/src/team.min.js vendored

@ -0,0 +1,45 @@
(function() { 'use strict';
if (typeof angular !== 'undefined') {
var root = this;
var $ = root.jQuery;
var controllers = {};
var app = root.app;
// Services.
app.factory('TeamStorage', function($http, $q) {
return {
searchUsers: function(query) {
var promise = $http({
method: 'GET',
url: '/api/public/user/?format=json&limit=100&username__contains=' + query
});
return promise;
}
};
});
// Controllers.
controllers.TeamController = function($scope, $timeout, TeamStorage) {
$scope.users = [];
$scope.search = '';
$scope.$watch('search', function(val) {
$timeout.cancel($scope.timeout);
if (!val) return $scope.users = [];
$scope.timeout = $timeout(function() {
TeamStorage.searchUsers(val).then(function(response) {
$scope.users = response.data.objects;
});
}, 350);
});
};
// Assign the controllers.
app.controller(controllers);
}
}).call(this);

11
templates/ad-detail.html

@ -1,11 +0,0 @@
<div class="google-ads" style="margin-top: 30px;">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- New Snipt Leaderboard -->
<ins class="adsbygoogle"
style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-6776929316186576"
data-ad-slot="5792558066"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>

4
templates/ad-leaderboard-pro.html

@ -1,4 +0,0 @@
<a href="/signup" class="snipt-promo">
<button class="btn btn-success btn-large pull-right">Sign up &raquo;</button>
Sign up for Snipt!<br /><span style="font-size: 16px;">Post public snipts for free.</span>
</a>

5
templates/ad-leaderboard-teams.html

@ -1,5 +0,0 @@
<a href="/for-teams/" class="snipt-promo">
<button class="btn btn-success btn-large pull-right">More info &raquo;</button>
Announcing Snipt for Teams! <br />
<span style="font-size: 80%;">Share access to snippets, detailed diffs, and more.</span>
</a>

4
templates/ad-leaderboard.html

@ -1,4 +0,0 @@
<a href="/signup/" class="snipt-promo">
<button class="btn btn-success btn-large pull-right">Sign up &raquo;</button>
Sign up for <span class="pro -logo">Snip<span>t</span></span>: store and share your own code snippets.
</a>

7
templates/ad-sidebar.html

@ -1,7 +0,0 @@
<div style="margin-left: 15px; margin-bottom: 30px;">
<div style="background-color: white; border-radius: 5px; padding: 10px 10px 7px 10px; box-sizing: border-box;" class="ad-inner">
<!-- BuySellAds Zone Code -->
<div id="bsap_1305837" class="bsarocks bsap_b70f66b78b7f9318d905def548557dc9"></div>
<!-- End BuySellAds Zone Code -->
</div>
</div>

7
templates/base.html

@ -222,13 +222,6 @@
<aside class="main">
{% block aside-top %}{% endblock %}
{% block aside-inner %}{% endblock %}
{% if not request.user.is_authenticated %}
<div style="margin-left: 15px; margin-bottom: 30px;">
<div style="background-color: white; border-radius: 5px; margin-top: 30px; padding: 10px; box-sizing: border-box;">
<script type="text/javascript" src="https://d21djfthp4qopy.cloudfront.net/humanitybox.js"></script>
</div>
</div>
{% endif %}
<nav class="footer">
<ul>
<li class="api">

4
templates/registration/registration_form.html

@ -21,10 +21,6 @@
{% endif %}
{% endif %}
<fieldset>
<div class="info" style="line-height: 35px;">
Create an account for a one-time fee of <span>$5</span>.<br />
<small style="font-size: 14px; color: #C0C0C0;">Fully refundable within 3 days of signup. All ads removed for paid accounts.</small>
</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

@ -7,13 +7,13 @@ from django.http import HttpResponseRedirect
from django.views.generic import RedirectView, TemplateView
from django.views.static import serve
from forms import AuthenticationFormWithInactiveUsersOkay
from registration.backends.default.views import RegistrationView
from snipts.api import (PublicSniptResource,
PublicUserResource, PrivateSniptResource,
PrivateFavoriteResource, PrivateUserProfileResource,
PrivateUserResource, PublicTagResource)
from snipts.views import search
from tastypie.api import Api
from utils.views import SniptRegistrationView
from views import (homepage, lexers, login_redirect,
tags, user_api_key)
@ -53,6 +53,8 @@ urlpatterns = [
url(r'^search/$', search),
url(r'^register/$', lambda x: HttpResponseRedirect('/signup/')),
url(r'^signup/$', RegistrationView.as_view()),
url(r'^activate/complete/$', RedirectView.as_view(
url='/login-redirect/')),
url(r'^login/?$', login, {

Loading…
Cancel
Save