master
Nick Sergeant 2012-11-19 18:49:51 -05:00
commit f91e66a557
23 changed files with 156 additions and 309 deletions

View File

@ -5,6 +5,8 @@ This is the codebase for the website, [Snipt.net](https://snipt.net/).
It's a relatively well-kept Django app, so you shouldn't have too many problems
getting a local copy running.
If you need help, visit `#snipt` on irc.freenode.net.
# Running the Django app
1. Clone the repo.

View File

@ -4,7 +4,7 @@ debug = False # Some extra logging
logfile = ".gunicorn.log" # Name of the log file
loglevel = "info" # The level at which to log
pidfile = ".gunicorn.pid" # Path to a PID file
workers = 9 # Number of workers to initialize
workers = 3 # Number of workers to initialize
umask = 0 # Umask to set when daemonizing
user = None # Change process owner to user
group = None # Change process group to group

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -515,6 +515,16 @@ section.main {
font-weight: bold;
margin-left: 22px;
}
a.favorited-snipts {
display: inline-block;
font-weight: bold;
margin: 0 0 10px 22px;
&.active {
border-bottom: 1px solid #2B6E9B;
color: #2B6E9B;
}
}
}
nav.footer {
margin: 0 15px 32px;
@ -586,88 +596,6 @@ section.main {
}
}
}
section.amazon {
height: 122px;
margin-top: 22px;
ul {
height: 85px;
margin: 0;
li {
height: 85px;
list-style-type: none;
a {
background-repeat: no-repeat;
background-size: 50px;
color: #797B7A;
display: inline-block;
font: bold 11px $Helvetica;
padding: 0 0 0 60px;
span.title {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 115px;
}
span.description {
color: #999;
display: inline-block;
font: normal 11px $Helvetica;
height: 65px;
line-height: 13px;
margin: 5px 0 0 0;
overflow: hidden;
width: 115px;
}
&:hover {
span.title {
text-decoration: underline;
}
}
}
}
}
div.more {
background: #FFF;
margin-top: 10px;
border-top: 1px solid #E5E5E5;
@include multi-border-radius(0, 0, 5px, 5px);
span {
color: #ADADAD;
display: inline-block;
font: bold 11px $Helvetica;
margin-top: 6px;
text-align: center;
text-transform: uppercase;
width: 123px;
}
a {
display: block;
padding: 5px;
i {
display: inline-block;
@include opacity(.4);
}
&.see-previous {
float: left;
}
&.see-next {
float: right;
}
&:hover {
i {
@include opacity(1);
}
}
}
}
}
}
}
div.rochester-made {

View File

@ -131,8 +131,7 @@ var snipt={module:function(){var modules={};return function(name){if(modules[nam
return modules[name]={};};}()};jQuery(function($){var SiteView=snipt.module('site').SiteView;window.site=new SiteView();});
(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_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');}
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.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');}
@ -140,13 +139,7 @@ if(!Stripe.validateCVC($cvc.val())){$cvc.parents('div.control-group').addClass('
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();}
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);}
$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});}}
$ul=$('ul',that.$amazon_ads);$ul.hide().html(html);$lis=$('li',$ul);$lis.hide();$lis.eq(0).fadeIn('fast');if($lis.length===1){$('a',$more).fadeOut('fast');}
if($lis.length===0){that.$amazon_ads.slideUp('fast');}
$ul.show();$('div.more span',that.$amazon_ads).hide().text('Books').fadeIn('fast');}});}});})(snipt.module('site'));
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();}}});})(snipt.module('site'));
(function(Snipt){Snipt.SniptModel=Backbone.Model.extend({toSafe:function(){var snipt=this.toJSON();snipt.code=this.escape('code');snipt.title=this.escape('title');snipt.tags_list=this.escape('tags_list');if(typeof snipt.tags==='object'){for(var i;i<snipt.tags.length;i++){snipt.tags[i].name=_.escape(snipt.tags[i].name);}}
return snipt;}});Snipt.SniptView=Backbone.View.extend({tagName:'article',initialize:function(){this.model.view=this;this.model.bind('change',this.render,this);this.template=_.template($('#snipt').html());this.editTemplate=_.template($('#edit').html());this.initLocalVars();this.initLineNumbers();},events:{'click a.copy':'copyFromClick','click a.edit':'edit','click a.favorite':'favoriteToggle','click a.embed':'embedFromClick','click a.expand':'expand','click .container':'selectFromClick','copyClose':'copyClose','copyRaw':'copy','detail':'detail','deselect':'deselect','destroy':'destroy','edit':'edit','embed':'embed','embedClose':'embedClose','expand':'expand','fadeAndRemove':'fadeAndRemove','goToAuthor':'goToAuthor','next':'next','prev':'prev','selectSnipt':'select'},copy:function(){$('textarea',this.$copyModal).remove();window.ui_halted=true;this.$copyModalBody.append('<textarea class="raw"></textarea>');$textarea=$('textarea.raw',this.$copyModalBody).val(this.model.get('code'));this.$copyModal.modal('show');$textarea.select();},copyClose:function(){$('textarea',this.$copyModal).remove();},copyFromClick:function(){this.copy();return false;},deselect:function(){this.$el.removeClass('selected');window.$selected=false;},detail:function(){window.location=this.model.get('absolute_url');},destroy:function(){this.model.destroy();},edit:function(){window.editing=true;window.ui_halted=true;this.select();that=this;var editPane=this.editTemplate({snipt:this.model.toSafe()});window.site.$main.hide();window.site.$body.addClass('detail editing');window.site.$main_edit.html(editPane);$('option[value="'+this.model.get('lexer')+'"]',window.site.$main_edit).attr('selected','selected');var $selectLexer=$('select#id_lexer',window.site.$main_edit);$selectLexer.chosen();$('label.blog-post input',window.site.$main_edit).on('change',function(){var $checkbox=$(this);var $label=$checkbox.parent();var $publish_date=$label.siblings('label.publish-date');if($checkbox.attr('checked')){$label.removeClass('is-not-blog-post').addClass('is-blog-post');$publish_date.show();}else{$label.addClass('is-not-blog-post').removeClass('is-blog-post');$publish_date.hide();}
return false;}).trigger('change');$('label.public input',window.site.$main_edit).on('change',function(){var $checkbox=$(this);var $label=$checkbox.parent();if($checkbox.attr('checked')){$label.removeClass('is-private').addClass('is-public');}else{$label.addClass('is-private').removeClass('is-public');}

View File

@ -52,15 +52,10 @@
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 });
@ -258,70 +253,6 @@
$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);
}
$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
});
}
}
$ul = $('ul', that.$amazon_ads);
$ul.hide().html(html);
$lis = $('li', $ul);
$lis.hide();
$lis.eq(0).fadeIn('fast');
if ($lis.length === 1) {
$('a', $more).fadeOut('fast');
}
if ($lis.length === 0) {
that.$amazon_ads.slideUp('fast');
}
$ul.show();
$('div.more span', that.$amazon_ads).hide().text('Books').fadeIn('fast');
}
});
}
});

View File

@ -1,8 +1,7 @@
(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_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');}
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.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');}
@ -10,10 +9,4 @@ if(!Stripe.validateCVC($cvc.val())){$cvc.parents('div.control-group').addClass('
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();}
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);}
$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});}}
$ul=$('ul',that.$amazon_ads);$ul.hide().html(html);$lis=$('li',$ul);$lis.hide();$lis.eq(0).fadeIn('fast');if($lis.length===1){$('a',$more).fadeOut('fast');}
if($lis.length===0){that.$amazon_ads.slideUp('fast');}
$ul.show();$('div.more span',that.$amazon_ads).hide().text('Books').fadeIn('fast');}});}});})(snipt.module('site'));
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();}}});})(snipt.module('site'));

View File

@ -1,6 +1,5 @@
BeautifulSoup
boto
bugsnag
biplist
Django
django-annoying
@ -15,6 +14,7 @@ gunicorn
lxml
parsedatetime
psycopg2
pyelasticsearch
Pygments
python-memcached
python-postmark
@ -25,9 +25,6 @@ uuid
versiontools
Werkzeug
git+git://github.com/dlo/bottlenose.git
git+git://github.com/yoavaviram/python-amazon-simple-product-api.git
git+git://github.com/toastdriven/pyelasticsearch.git
git+https://github.com/toastdriven/django-haystack.git@master#egg=django-haystack
hg+https://bitbucket.org/ubernostrum/django-registration#egg=django-registration
git+https://github.com/toastdriven/django-tastypie.git#egg=django-tastypie

View File

@ -130,6 +130,7 @@ INSTALLED_APPS = (
'django.contrib.staticfiles',
'django.contrib.admin',
'debug_toolbar',
'django_bcrypt',
'haystack',
'markdown_deux',
@ -162,11 +163,11 @@ LOGGING = {
}
},
'loggers': {
#'django.request': {
#'handlers': ['mail_admins'],
#'level': 'ERROR',
#'propagate': True,
#},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}

View File

@ -44,7 +44,7 @@
{% block content %}
<section class="snipts" id="snipts">
{% if not request.user.profile.is_pro %}
{% if request.user.is_authenticated and not request.user.profile.is_pro %}
<div class="alert alert-info site-notice"><a href="/pro/">Snipt Pro</a>: Support the development of Snipt and get exclusive features for only $19/year.</div>
{% endif %}
{% with 'true' as detail %}

View File

@ -11,8 +11,5 @@
{% endblock %}
{% block aside-top %}
{% if not request.user.profile.is_pro %}
{% include 'carbon.html' %}
{% endif %}
{% include "snipts/tags-public.html" %}
{% endblock %}

View File

@ -7,15 +7,15 @@
{% if tag %}
<li><span class="prompt">/</span> <a href="/{{ user.username }}/tag/{{ tag.slug }}/">{{ tag.name }}</a></li>
{% endif %}
{% if favorites %}
<li><span class="prompt">/</span> <a href="/{{ user.username }}/favorites/">Favorited snipts</a></li>
{% endif %}
<li class="rss">
<a href="{{ request.path }}?rss{% if not public %}&api_key={{ request.user.api_key.key }}{% endif %}">RSS</a>
</li>
{% endblock %}
{% block aside-top %}
{% if not request.user.profile.is_pro %}
{% include 'carbon.html' %}
{% endif %}
<div class="profile group">
<span class="avatar" title="Manage your avatar at Gravatar.com" style="background-image: url('https://secure.gravatar.com/avatar/{{ user.email|md5 }}?s=50');"></span>
<div class="meta">

View File

@ -13,7 +13,7 @@
{% block content %}
<section class="snipts" id="snipts">
{% if not request.user.profile.is_pro %}
{% if request.user.is_authenticated and not request.user.profile.is_pro %}
<div class="alert alert-info site-notice"><a href="/pro/">Snipt Pro</a>: Support the development of Snipt and get exclusive features for only $19/year.</div>
{% endif %}
{% autopaginate snipts 10 %}

View File

@ -1,11 +1,63 @@
<section class="tags">
<h1>Popular public tags</h1>
<ul>
{% for t in tags %}
<li>
<a {% if tag.name == t.name %}class="active"{% endif %} href="/public/tag/{{ t.slug }}/">{{ t.name }} ({{ t.count }})</a>
</li>
{% endfor %}
<li>
<a href="/public/tag/as3/" {% if tag.name == 'as3' %}class="active"{% endif %}>as3</a>
</li>
<li>
<a href="/public/tag/bash/" {% if tag.name == 'bash' %}class="active"{% endif %}>bash</a>
</li>
<li>
<a href="/public/tag/c_2/" {% if tag.name == 'c++' %}class="active"{% endif %}>c++</a>
</li>
<li>
<a href="/public/tag/css/" {% if tag.name == 'css' %}class="active"{% endif %}>css</a>
</li>
<li>
<a href="/public/tag/django/" {% if tag.name == 'django' %}class="active"{% endif %}>django</a>
</li>
<li>
<a href="/public/tag/drupal/" {% if tag.name == 'drupal' %}class="active"{% endif %}>drupal</a>
</li>
<li>
<a href="/public/tag/git/" {% if tag.name == 'git' %}class="active"{% endif %}>git</a>
</li>
<li>
<a href="/public/tag/html/" {% if tag.name == 'html' %}class="active"{% endif %}>html</a>
</li>
<li>
<a href="/public/tag/java/" {% if tag.name == 'java' %}class="active"{% endif %}>java</a>
</li>
<li>
<a href="/public/tag/javascript/" {% if tag.name == 'javascript' %}class="active"{% endif %}>javascript</a>
</li>
<li>
<a href="/public/tag/jquery/" {% if tag.name == 'jquery' %}class="active"{% endif %}>jquery</a>
</li>
<li>
<a href="/public/tag/js/" {% if tag.name == 'js' %}class="active"{% endif %}>js</a>
</li>
<li>
<a href="/public/tag/linux/" {% if tag.name == 'linux' %}class="active"{% endif %}>linux</a>
</li>
<li>
<a href="/public/tag/mysql/" {% if tag.name == 'mysql' %}class="active"{% endif %}>mysql</a>
</li>
<li>
<a href="/public/tag/php/" {% if tag.name == 'php' %}class="active"{% endif %}>php</a>
</li>
<li>
<a href="/public/tag/python/" {% if tag.name == 'python' %}class="active"{% endif %}>python</a>
</li>
<li>
<a href="/public/tag/ruby/" {% if tag.name == 'ruby' %}class="active"{% endif %}>ruby</a>
</li>
<li>
<a href="/public/tag/sql/" {% if tag.name == 'sql' %}class="active"{% endif %}>sql</a>
</li>
<li>
<a href="/public/tag/wordpress/" {% if tag.name == 'wordpress' %}class="active"{% endif %}>wordpress</a>
</li>
</ul>
<a href="/tags/" class="all-tags">View all tags &raquo;</a>
</section>

View File

@ -1,16 +1,13 @@
{% if tags %}
<section class="tags">
{% if user.username == 'blog' %}
<h1>Posts by month / year</h1>
{% else %}
<h1>{{ user.username }}'s tags</h1>
{% endif %}
<ul>
{% for t in tags %}
<li>
<a {% if tag.name == t.name %}class="active"{% endif %} href="/{{ user.username }}/tag/{{ t.slug }}/">{{ t.name }} ({{ t.count }})</a>
</li>
{% endfor %}
</ul>
</section>
{% endif %}
<section class="tags">
{% if request.user == user %}
<a href="/{{ user }}/favorites/" class="favorited-snipts {% if 'favorites' in request.path %}active{% endif %}">View favorited snipts &raquo;</a>
{% endif %}
<h1>{{ user.username }}'s tags</h1>
<ul>
{% for t in tags %}
<li>
<a {% if tag.name == t.name %}class="active"{% endif %} href="/{{ user.username }}/tag/{{ t.slug }}/">{{ t.name }}</a>
</li>
{% endfor %}
</ul>
</section>

View File

@ -11,5 +11,6 @@ urlpatterns = patterns('',
url(r'^raw/(?P<snipt_key>[^/]+)/$', views.raw, name='raw'),
url(r'^(?P<username_or_custom_slug>[^/]+)/$', views.list_user, name='list-user'),
url(r'^(?P<username_or_custom_slug>[^/]+)/tag/(?P<tag_slug>[^/]+)/$', views.list_user, name='list-user-tag'),
url(r'^(?P<username>[^/]+)/favorites/$', views.favorites, name='favorites'),
url(r'^(?P<username>[^/]+)/(?P<snipt_slug>[^/]+)/$', views.detail, name='detail'),
)

View File

@ -79,17 +79,48 @@ def embed(request, snipt_key):
context_instance=RequestContext(request),
mimetype='application/javascript')
@render_to('snipts/list-user.html')
def favorites(request, username):
if request.user.username != username:
raise Http404
if request.blog_user:
raise Http404
public = False
favorites = Favorite.objects.filter(user=request.user).values('snipt')
favorites = [f['snipt'] for f in favorites]
snipts = Snipt.objects.filter(Q(pk__in=favorites))
tags = Tag.objects.filter(snipt__user=request.user).distinct()
tags = tags.order_by('name')
snipts = snipts.order_by('-created')
context = {
'favorites': favorites,
'has_snipts': True,
'public': public,
'public_user': False,
'snipts': snipts,
'tags': tags,
'user': request.user,
}
if 'rss' in request.GET:
context['snipts'] = context['snipts'][:20]
return rss(request, context)
return context
@render_to('snipts/list-public.html')
def list_public(request, tag_slug=None):
if request.blog_user:
return blog_list(request)
tags = Tag.objects.filter(snipt__public=True)
tags = tags.annotate(count=Count('taggit_taggeditem_items__id'))
tags = tags.order_by('-count')[:20]
tags = sorted(tags, key=lambda tag: tag.name)
snipts = Snipt.objects.filter(public=True).order_by('-created')
if tag_slug:
@ -102,7 +133,6 @@ def list_public(request, tag_slug=None):
'has_snipts': True,
'public': True,
'snipts': snipts,
'tags': tags,
'tag': tag,
}
@ -134,13 +164,13 @@ def list_user(request, username_or_custom_slug, tag_slug=None):
favorites = [f['snipt'] for f in favorites]
snipts = snipts.filter(Q(user=user) | Q(pk__in=favorites))
tags = tags.filter(Q(snipt__user=user) | Q(snipt__pk__in=favorites))
tags = tags.filter(snipt__user=user).distinct()
else:
tags = tags.filter(snipt__user=user, snipt__public=True)
tags = tags.filter(snipt__user=user, snipt__public=True).distinct()
snipts = snipts.filter(user=user, public=True)
public = True
tags = tags.annotate(count=Count('taggit_taggeditem_items__id'))
tags = tags.order_by('name')
snipts = snipts.order_by('-created')

View File

@ -1,10 +1,3 @@
{% extends "base.html" %}
{% block page-title %}Server Error - {{ block.super }}{% endblock %}
{% block body-class %}error{% endblock %}
{% block inline-js %}{% endblock %}
{% block content %}
500: Server Error
{% endblock %}
500: Server Error<br />
<br />
We've been notified. Follow http://twitter.com/snipt for updates.

View File

@ -19,7 +19,7 @@
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/snipt.css?39" />
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/snipt.css?40" />
{% if has_snipts and not detail %}
<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ request.path }}?rss{% if not public %}&amp;api_key={{ request.user.api_key.key }}{% endif %}" />
@ -174,31 +174,15 @@
<section class="main group" id="main">
{% block aside %}
<aside class="main">
{% if tag %}
{% if tag or favorites %}
<section class="tag-detail">
<div class="heading">
<h1><span>TAG:</span> {{ tag.name }}</h1>
{% if favorites %}
<h1>Favorited snipts</h1>
{% else %}
<h1><span>TAG:</span> {{ tag.name }}</h1>
{% endif %}
</div>
<section class="amazon {% if request.user.is_authenticated %}{% if request.user.profile.is_pro %}hidden{% endif %}{% endif %}">
<ul></ul>
<div class="more group">
<span></span>
<a href="#" class="see-previous">
<i class="icon-chevron-left"></i>
</a>
<a href="#" class="see-next">
<i class="icon-chevron-right"></i>
</a>
</div>
<script id="amazon-ad" type="text/html">
<li>
<a rel="nofollow" href="<%=url %>" style="background-image: url('/api/public/a/img/?i=<%=image %>');">
<span class="title"><%=title %></span>
<span class="description"><%=review %></span>
</a>
</li>
</script>
</section>
</section>
{% endif %}
{% block aside-top %}{% endblock %}
@ -357,7 +341,7 @@
</div>
{% endblock %}
<script type="text/javascript" src="{{ STATIC_URL }}js/snipt.js?30"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/snipt.js?31"></script>
{% block extra-scripts %}{% endblock %}
{% block inline-js %}

View File

@ -14,7 +14,7 @@
<p>We're still building our <span class="pro">Pro</span> platform, but it already kicks ass. By becoming a Pro now, you'll also get access to future Pro features the moment they're released.</p>
<h6>Current Pro features:</h6>
<ul>
<li>No advertisements (including Amazon books).</li>
<li>No advertisements.</li>
<li>Stats on "views" and "favorites" for your snipts.</li>
<li>&ldquo;Pro&rdquo; badge throughout the site.</li>
<li>Custom domain for your <a href="https://blog.snipt.net/announcing-the-sniptnet-blogging-platform/">Snipt blog</a>. Contact <a href="mailto:support@snipt.net">support@snipt.net</a> to set it up.</li>

View File

@ -1,4 +1,4 @@
from views import (amazon_search, amazon_image, jobs, lexers, pro_signup,
from views import (jobs, lexers, pro_signup,
sitemap, tags, pro_signup_complete, stats)
from django.conf.urls.defaults import include, patterns, url
from django.views.generic.simple import direct_to_template
@ -41,12 +41,10 @@ urlpatterns = patterns('',
url(r'^pro/signup/$', pro_signup),
url(r'^pro/signup/complete/$', pro_signup_complete),
url(r'^jobs/$', jobs),
#url(r'^jobs/$', jobs),
url(r'^stats/$', stats),
url(r'^api/public/lexer/$', lexers),
url(r'^api/public/a/$', amazon_search),
url(r'^api/public/a/img/$', amazon_image),
url(r'^api/', include(public_api.urls)),
url(r'^api/', include(private_api.urls)),

View File

@ -6,7 +6,6 @@ from django.shortcuts import render_to_response
from django.template import RequestContext
from snipts.utils import get_lexers_list
from django.db.models import Count
from amazon.api import AmazonAPI
from django.conf import settings
from snipts.models import Snipt
from taggit.models import Tag
@ -15,58 +14,9 @@ import os, urllib
import stripe
from local_settings import AMAZON_API_KEY, AMAZON_API_SECRET, STRIPE_API_KEY
from local_settings import STRIPE_API_KEY
@ajax_request
def amazon_search(request):
products = []
if request.GET.get('q'):
amazon = AmazonAPI(AMAZON_API_KEY, AMAZON_API_SECRET, 'snipt-20')
products = amazon.search_n(5, Keywords=request.GET.get('q'), SearchIndex='Books')
result = []
for product in products:
if product.small_image_url:
small_image_url = product.small_image_url.replace('http://ecx.images-amazon.com/images/I/', '')
else:
small_image_url = None
result.append({
'image': small_image_url,
'price': product.list_price,
'review': striptags(product.editorial_review),
'reviews': product.reviews,
'title': product.title,
'url': product.offer_url,
})
return {
'result': result
}
def amazon_image(request):
if 'i' in request.GET:
img_filename = request.GET.get('i')
img_src = 'http://ecx.images-amazon.com/images/I/{}'.format(img_filename)
img_loc = os.path.join(settings.STATIC_ROOT, 'images', 'amazon', img_filename)
if settings.DEBUG:
root = '/static/images/amazon/'
else:
root = 'https://snipt.net/static/images/amazon/'
try:
open(img_loc)
return HttpResponseRedirect(root + img_filename)
except IOError:
urllib.urlretrieve(img_src, img_loc)
return HttpResponseRedirect(root + img_filename)
else:
return HttpResponseBadRequest()
@ajax_request
def lexers(request):
lexers = get_lexers_list()