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 It's a relatively well-kept Django app, so you shouldn't have too many problems
getting a local copy running. getting a local copy running.
If you need help, visit `#snipt` on irc.freenode.net.
# Running the Django app # Running the Django app
1. Clone the repo. 1. Clone the repo.

View File

@ -4,7 +4,7 @@ debug = False # Some extra logging
logfile = ".gunicorn.log" # Name of the log file logfile = ".gunicorn.log" # Name of the log file
loglevel = "info" # The level at which to log loglevel = "info" # The level at which to log
pidfile = ".gunicorn.pid" # Path to a PID file 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 umask = 0 # Umask to set when daemonizing
user = None # Change process owner to user user = None # Change process owner to user
group = None # Change process group to group 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; font-weight: bold;
margin-left: 22px; 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 { nav.footer {
margin: 0 15px 32px; 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 { 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();}); 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');}} (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});} 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();} 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');}
var SniptListView=Snipt.SniptListView;this.snipt_list=new SniptListView({'snipts':this.$snipts});var that=this;this.$body.click(function(){if(!window.ui_halted&&!window.from_modal&&window.$selected){window.$selected.trigger('deselect');}
if(window.from_modal){window.from_modal=false;} if(window.from_modal){window.from_modal=false;}
that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');var $cardNumber=$('input#number');var $expMonth=$('select#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');} that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');var $cardNumber=$('input#number');var $expMonth=$('select#exp-month');var $expYear=$('select#exp-year');var $cvc=$('input#cvc');$form.submit(function(){$submit.attr('disabled','disabled');var errors=false;if(!Stripe.validateCardNumber($cardNumber.val())){$cardNumber.parents('div.control-group').addClass('error');errors=true;}else{$cardNumber.parents('div.control-group').removeClass('error');}
if(!Stripe.validateExpiry($expMonth.val(),$expYear.val())){$expMonth.parents('div.control-group').addClass('error');errors=true;}else{$expMonth.parents('div.control-group').removeClass('error');} if(!Stripe.validateExpiry($expMonth.val(),$expYear.val())){$expMonth.parents('div.control-group').addClass('error');errors=true;}else{$expMonth.parents('div.control-group').removeClass('error');}
@ -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');} if(!errors){$('.payment-errors').hide();$('.payment-loading').show();Stripe.createToken({name:$name.val(),number:$cardNumber.val(),cvc:$cvc.val(),exp_month:$expMonth.val(),exp_year:$expYear.val()},that.stripeResponseHandler);}else{$submit.removeAttr('disabled');}
return false;});} return false;});}
if(this.$body.hasClass('login')){$('input#id_username').focus();} 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);} 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'));
$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'));
(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);}} (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 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');} 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_edit = $('section#main-edit');
this.$main = $('section#main'); this.$main = $('section#main');
this.$keyboard_shortcuts = $('#keyboard-shortcuts', this.$body); this.$keyboard_shortcuts = $('#keyboard-shortcuts', this.$body);
this.$amazon_ads = $('section.amazon', this.$main);
this.keyboardShortcuts(); this.keyboardShortcuts();
this.inFieldLabels(); this.inFieldLabels();
if (this.$amazon_ads.length) {
this.initAmazonAds();
}
var SniptListView = Snipt.SniptListView; var SniptListView = Snipt.SniptListView;
this.snipt_list = new SniptListView({ 'snipts': this.$snipts }); this.snipt_list = new SniptListView({ 'snipts': this.$snipts });
@ -258,70 +253,6 @@
$form.append("<input type='hidden' name='token' value='" + token + "'/>"); $form.append("<input type='hidden' name='token' value='" + token + "'/>");
$form.get(0).submit(); $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');}} (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});} 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();} 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');}
var SniptListView=Snipt.SniptListView;this.snipt_list=new SniptListView({'snipts':this.$snipts});var that=this;this.$body.click(function(){if(!window.ui_halted&&!window.from_modal&&window.$selected){window.$selected.trigger('deselect');}
if(window.from_modal){window.from_modal=false;} if(window.from_modal){window.from_modal=false;}
that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');var $cardNumber=$('input#number');var $expMonth=$('select#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');} that.$aside_nav.removeClass('open');});this.$aside_nav_ul.click(function(e){e.stopPropagation();});$search_queries=this.$search_queries;$search_queries.focus(function(){if(window.$selected){$selected.trigger('deselect');}});this.$body.on('click','a.close',function(){$(this).parent().parent().modal('hide');window.ui_halted=false;return false;});this.$keyboard_shortcuts.on('hidden',function(){window.ui_halted=false;});if(this.$body.hasClass('pro-signup')){var $form=$('form#pro-signup');var $submit=$('button[type="submit"]',$form);var $name=$('input#name');var $cardNumber=$('input#number');var $expMonth=$('select#exp-month');var $expYear=$('select#exp-year');var $cvc=$('input#cvc');$form.submit(function(){$submit.attr('disabled','disabled');var errors=false;if(!Stripe.validateCardNumber($cardNumber.val())){$cardNumber.parents('div.control-group').addClass('error');errors=true;}else{$cardNumber.parents('div.control-group').removeClass('error');}
if(!Stripe.validateExpiry($expMonth.val(),$expYear.val())){$expMonth.parents('div.control-group').addClass('error');errors=true;}else{$expMonth.parents('div.control-group').removeClass('error');} if(!Stripe.validateExpiry($expMonth.val(),$expYear.val())){$expMonth.parents('div.control-group').addClass('error');errors=true;}else{$expMonth.parents('div.control-group').removeClass('error');}
@ -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');} if(!errors){$('.payment-errors').hide();$('.payment-loading').show();Stripe.createToken({name:$name.val(),number:$cardNumber.val(),cvc:$cvc.val(),exp_month:$expMonth.val(),exp_year:$expYear.val()},that.stripeResponseHandler);}else{$submit.removeAttr('disabled');}
return false;});} return false;});}
if(this.$body.hasClass('login')){$('input#id_username').focus();} 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);} 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'));
$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'));

View File

@ -1,6 +1,5 @@
BeautifulSoup BeautifulSoup
boto boto
bugsnag
biplist biplist
Django Django
django-annoying django-annoying
@ -15,6 +14,7 @@ gunicorn
lxml lxml
parsedatetime parsedatetime
psycopg2 psycopg2
pyelasticsearch
Pygments Pygments
python-memcached python-memcached
python-postmark python-postmark
@ -25,9 +25,6 @@ uuid
versiontools versiontools
Werkzeug 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 git+https://github.com/toastdriven/django-haystack.git@master#egg=django-haystack
hg+https://bitbucket.org/ubernostrum/django-registration#egg=django-registration hg+https://bitbucket.org/ubernostrum/django-registration#egg=django-registration
git+https://github.com/toastdriven/django-tastypie.git#egg=django-tastypie git+https://github.com/toastdriven/django-tastypie.git#egg=django-tastypie

View File

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

View File

@ -44,7 +44,7 @@
{% block content %} {% block content %}
<section class="snipts" id="snipts"> <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> <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 %} {% endif %}
{% with 'true' as detail %} {% with 'true' as detail %}

View File

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

View File

@ -7,15 +7,15 @@
{% if tag %} {% if tag %}
<li><span class="prompt">/</span> <a href="/{{ user.username }}/tag/{{ tag.slug }}/">{{ tag.name }}</a></li> <li><span class="prompt">/</span> <a href="/{{ user.username }}/tag/{{ tag.slug }}/">{{ tag.name }}</a></li>
{% endif %} {% endif %}
{% if favorites %}
<li><span class="prompt">/</span> <a href="/{{ user.username }}/favorites/">Favorited snipts</a></li>
{% endif %}
<li class="rss"> <li class="rss">
<a href="{{ request.path }}?rss{% if not public %}&api_key={{ request.user.api_key.key }}{% endif %}">RSS</a> <a href="{{ request.path }}?rss{% if not public %}&api_key={{ request.user.api_key.key }}{% endif %}">RSS</a>
</li> </li>
{% endblock %} {% endblock %}
{% block aside-top %} {% block aside-top %}
{% if not request.user.profile.is_pro %}
{% include 'carbon.html' %}
{% endif %}
<div class="profile group"> <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> <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"> <div class="meta">

View File

@ -13,7 +13,7 @@
{% block content %} {% block content %}
<section class="snipts" id="snipts"> <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> <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 %} {% endif %}
{% autopaginate snipts 10 %} {% autopaginate snipts 10 %}

View File

@ -1,11 +1,63 @@
<section class="tags"> <section class="tags">
<h1>Popular public tags</h1> <h1>Popular public tags</h1>
<ul> <ul>
{% for t in tags %} <li>
<li> <a href="/public/tag/as3/" {% if tag.name == 'as3' %}class="active"{% endif %}>as3</a>
<a {% if tag.name == t.name %}class="active"{% endif %} href="/public/tag/{{ t.slug }}/">{{ t.name }} ({{ t.count }})</a> </li>
</li> <li>
{% endfor %} <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> </ul>
<a href="/tags/" class="all-tags">View all tags &raquo;</a> <a href="/tags/" class="all-tags">View all tags &raquo;</a>
</section> </section>

View File

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

View File

@ -11,5 +11,6 @@ urlpatterns = patterns('',
url(r'^raw/(?P<snipt_key>[^/]+)/$', views.raw, name='raw'), 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>[^/]+)/$', 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_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'), 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), context_instance=RequestContext(request),
mimetype='application/javascript') 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') @render_to('snipts/list-public.html')
def list_public(request, tag_slug=None): def list_public(request, tag_slug=None):
if request.blog_user: if request.blog_user:
return blog_list(request) 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') snipts = Snipt.objects.filter(public=True).order_by('-created')
if tag_slug: if tag_slug:
@ -102,7 +133,6 @@ def list_public(request, tag_slug=None):
'has_snipts': True, 'has_snipts': True,
'public': True, 'public': True,
'snipts': snipts, 'snipts': snipts,
'tags': tags,
'tag': tag, 'tag': tag,
} }
@ -134,13 +164,13 @@ def list_user(request, username_or_custom_slug, tag_slug=None):
favorites = [f['snipt'] for f in favorites] favorites = [f['snipt'] for f in favorites]
snipts = snipts.filter(Q(user=user) | Q(pk__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: 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) snipts = snipts.filter(user=user, public=True)
public = True public = True
tags = tags.annotate(count=Count('taggit_taggeditem_items__id'))
tags = tags.order_by('name') tags = tags.order_by('name')
snipts = snipts.order_by('-created') snipts = snipts.order_by('-created')

View File

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

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/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> <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 %} {% 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 %}" /> <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"> <section class="main group" id="main">
{% block aside %} {% block aside %}
<aside class="main"> <aside class="main">
{% if tag %} {% if tag or favorites %}
<section class="tag-detail"> <section class="tag-detail">
<div class="heading"> <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> </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> </section>
{% endif %} {% endif %}
{% block aside-top %}{% endblock %} {% block aside-top %}{% endblock %}
@ -357,7 +341,7 @@
</div> </div>
{% endblock %} {% 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 extra-scripts %}{% endblock %}
{% block inline-js %} {% 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> <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> <h6>Current Pro features:</h6>
<ul> <ul>
<li>No advertisements (including Amazon books).</li> <li>No advertisements.</li>
<li>Stats on "views" and "favorites" for your snipts.</li> <li>Stats on "views" and "favorites" for your snipts.</li>
<li>&ldquo;Pro&rdquo; badge throughout the site.</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> <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) sitemap, tags, pro_signup_complete, stats)
from django.conf.urls.defaults import include, patterns, url from django.conf.urls.defaults import include, patterns, url
from django.views.generic.simple import direct_to_template from django.views.generic.simple import direct_to_template
@ -41,12 +41,10 @@ urlpatterns = patterns('',
url(r'^pro/signup/$', pro_signup), url(r'^pro/signup/$', pro_signup),
url(r'^pro/signup/complete/$', pro_signup_complete), url(r'^pro/signup/complete/$', pro_signup_complete),
url(r'^jobs/$', jobs), #url(r'^jobs/$', jobs),
url(r'^stats/$', stats), url(r'^stats/$', stats),
url(r'^api/public/lexer/$', lexers), 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(public_api.urls)),
url(r'^api/', include(private_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 django.template import RequestContext
from snipts.utils import get_lexers_list from snipts.utils import get_lexers_list
from django.db.models import Count from django.db.models import Count
from amazon.api import AmazonAPI
from django.conf import settings from django.conf import settings
from snipts.models import Snipt from snipts.models import Snipt
from taggit.models import Tag from taggit.models import Tag
@ -15,58 +14,9 @@ import os, urllib
import stripe 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 @ajax_request
def lexers(request): def lexers(request):
lexers = get_lexers_list() lexers = get_lexers_list()