A ton of stuff.

- Remove all Amazon related things.
- Remove all Carbon ads.
- Improve speed of the site by 80-90% by removing tag counts and hard-coding popular public tags.
- Provide a dedicated view for Favorited snipts, and remove the merging of favorited-snipt-tags into user tags (further improving performance).
master
Nick Sergeant 2012-10-17 20:52:12 -04:00
parent cacaecfcd6
commit 37665b10fe
19 changed files with 142 additions and 287 deletions

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

@ -26,7 +26,6 @@ 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

View File

@ -109,6 +109,7 @@ MIDDLEWARE_CLASSES = (
'pagination.middleware.PaginationMiddleware',
'blogs.middleware.BlogMiddleware',
'bugsnag.django.middleware.BugsnagMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
ROOT_URLCONF = 'snipt.urls'
@ -131,6 +132,7 @@ INSTALLED_APPS = (
'django.contrib.staticfiles',
'django.contrib.admin',
'debug_toolbar',
'django_bcrypt',
'haystack',
'markdown_deux',

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/">as3</a>
</li>
<li>
<a href="/public/tag/bash/">bash</a>
</li>
<li>
<a href="/public/tag/c_2/">c++</a>
</li>
<li>
<a href="/public/tag/css/">css</a>
</li>
<li>
<a href="/public/tag/django/">django</a>
</li>
<li>
<a href="/public/tag/drupal/">drupal</a>
</li>
<li>
<a href="/public/tag/git/">git</a>
</li>
<li>
<a href="/public/tag/html/">html</a>
</li>
<li>
<a href="/public/tag/java/">java</a>
</li>
<li>
<a href="/public/tag/javascript/">javascript</a>
</li>
<li>
<a href="/public/tag/jquery/">jquery</a>
</li>
<li>
<a href="/public/tag/js/">js</a>
</li>
<li>
<a href="/public/tag/linux/">linux</a>
</li>
<li>
<a href="/public/tag/mysql/">mysql</a>
</li>
<li>
<a href="/public/tag/php/">php</a>
</li>
<li>
<a href="/public/tag/python/">python</a>
</li>
<li>
<a href="/public/tag/ruby/">ruby</a>
</li>
<li>
<a href="/public/tag/sql/">sql</a>
</li>
<li>
<a href="/public/tag/wordpress/">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

@ -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 %}

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()