Favoriting.

master
Nick Sergeant 2012-04-12 22:04:37 -04:00
parent 6af875583a
commit d4dc3ebb0f
6 changed files with 115 additions and 22 deletions

View File

@ -32,6 +32,8 @@
events: { events: {
'click a.copy': 'copyFromClick', 'click a.copy': 'copyFromClick',
'click a.edit': 'edit', 'click a.edit': 'edit',
'click a.favorite': 'favoriteToggle',
'hover a.favorite': 'favoriteHover',
'click a.embed': 'embedFromClick', 'click a.embed': 'embedFromClick',
'click a.expand': 'expand', 'click a.expand': 'expand',
'click .container': 'selectFromClick', 'click .container': 'selectFromClick',
@ -174,13 +176,52 @@
}); });
return false; return false;
}, },
favorite: function() { favoriteHover: function(e) {
if (e.type === 'mouseenter') {
if (this.$el.hasClass('favorited')) {
this.$favorite.text('Remove?');
} else {
this.$favorite.text('Favorite?');
}
} else {
if (this.$el.hasClass('favorited')) {
this.$favorite.text('Favorited');
} else {
this.$favorite.text('Favorite');
}
}
}, },
initFavorite: function() { favoriteToggle: function() {
this.$favorite.click(function() {
return false; var that = this;
});
if (this.$el.hasClass('favorited')) {
$.ajax('/api/private/favorite/' + this.model.get('favorite_id'), {
type: 'delete',
success: function() {
that.$el.removeClass('favorited');
that.$favorite.text('Removed.');
},
headers: {
'Authorization': 'ApiKey ' + window.user + ':' + window.api_key
}
});
} else {
$.ajax('/api/private/favorite/', {
data: '{"snipt": ' + this.model.get('id') + '}',
contentType: 'application/json',
type: 'post',
success: function(resp) {
that.$el.addClass('favorited');
that.model.set({'favorite_id': resp['id']}, {'silent': true});
that.$favorite.text('Favorited.');
},
headers: {
'Authorization': 'ApiKey ' + window.user + ':' + window.api_key
}
});
}
return false;
}, },
initLocalVars: function() { initLocalVars: function() {
this.$aside = $('aside', this.$el); this.$aside = $('aside', this.$el);
@ -205,10 +246,6 @@
window.ui_halted = false; window.ui_halted = false;
window.from_modal = true; window.from_modal = true;
}); });
if (this.$favorite.length) {
this.initFavorite();
}
}, },
next: function() { next: function() {
if (!window.ui_halted) { if (!window.ui_halted) {
@ -353,6 +390,7 @@
created_formatted: $created.text(), created_formatted: $created.text(),
embed_url: $('div.embed-url', $el).text(), embed_url: $('div.embed-url', $el).text(),
absolute_url: $h1.attr('href'), absolute_url: $h1.attr('href'),
favorite_id: $el.data('favorite-id'),
id: parseInt($el.attr('id').replace('snipt-', ''), 0), id: parseInt($el.attr('id').replace('snipt-', ''), 0),
key: $('div.key', $el).text(), key: $('div.key', $el).text(),
lexer: $('div.lexer', $el).text(), lexer: $('div.lexer', $el).text(),

View File

@ -5,9 +5,9 @@ from tastypie.validation import Validation
from tastypie.resources import ModelResource from tastypie.resources import ModelResource
from django.contrib.auth.models import User from django.contrib.auth.models import User
from tastypie.models import create_api_key from tastypie.models import create_api_key
from snipts.models import Favorite, Snipt
from tastypie.cache import SimpleCache from tastypie.cache import SimpleCache
from tastypie.fields import ListField from tastypie.fields import ListField
from snipts.models import Snipt
from taggit.models import Tag from taggit.models import Tag
from django.db import models from django.db import models
from tastypie import fields from tastypie import fields
@ -15,6 +15,17 @@ from tastypie import fields
models.signals.post_save.connect(create_api_key, sender=User) models.signals.post_save.connect(create_api_key, sender=User)
class FavoriteValidation(Validation):
def is_valid(self, bundle, request=None):
errors = {}
snipt = bundle.data['snipt']
if Favorite.objects.filter(user=request.user, snipt=snipt).count():
errors['duplicate'] = 'User has already favorited this snipt.'
return errors
class PublicUserResource(ModelResource): class PublicUserResource(ModelResource):
class Meta: class Meta:
queryset = User.objects.all() queryset = User.objects.all()
@ -188,3 +199,30 @@ class PrivateSniptResource(ModelResource):
tags = bundle.data.get('tags_list', []) tags = bundle.data.get('tags_list', [])
if tags != '': if tags != '':
bundle.obj.tags.set(*parse_tags(tags)) bundle.obj.tags.set(*parse_tags(tags))
class PrivateFavoriteResource(ModelResource):
user = fields.ForeignKey(PrivateUserResource, 'user', full=True)
snipt = fields.ForeignKey(PrivateSniptResource, 'snipt', full=False)
class Meta:
queryset = Favorite.objects.all().order_by('-created')
resource_name = 'favorite'
fields = ['id',]
validation = FavoriteValidation()
detail_allowed_methods = ['get', 'post', 'delete']
list_allowed_methods = ['get', 'post',]
authentication = ApiKeyAuthentication()
authorization = Authorization()
ordering = ['created',]
# TODO max_limit does not work.
max_limit = 200
always_return_data = True
cache = SimpleCache()
def obj_create(self, bundle, request=None, **kwargs):
bundle.data['user'] = request.user
bundle.data['snipt'] = Snipt.objects.get(pk=bundle.data['snipt'])
return super(PrivateFavoriteResource, self).obj_create(bundle, request,
user=request.user, **kwargs)
def apply_authorization_limits(self, request, object_list):
return object_list.filter(user=request.user)

View File

@ -1,6 +1,8 @@
{% load humanize snipt_tags %} {% load humanize snipt_tags %}
<article id="snipt-{{ snipt.pk }}" class="snipt{% if not snipt.public %} private-snipt{% endif %}{% if snipt.line_count > 8 and not detail %} expandable{% endif %}{% if snipt.user == request.user %} editable{% endif %}{% if snipt.user != request.user and request.user.is_authenticated %}{% if snipt|is_favorited_by:request.user %} favorited{% endif %}{% endif %}"> {% snipt_is_favorited_by_user as 'is_favorited' %}
<article id="snipt-{{ snipt.pk }}" class="snipt{% if not snipt.public %} private-snipt{% endif %}{% if snipt.line_count > 8 and not detail %} expandable{% endif %}{% if snipt.user == request.user %} editable{% endif %}{% if is_favorited %} favorited" data-favorite-id="{{ is_favorited }}"{% else %}"{% endif %}>
<div class="number">#{{ snipt.pk }}</div> <div class="number">#{{ snipt.pk }}</div>
<div class="group"> <div class="group">
<div class="container"> <div class="container">
@ -37,7 +39,7 @@
</li> </li>
{% if snipt.user != request.user and request.user.is_authenticated %} {% if snipt.user != request.user and request.user.is_authenticated %}
<li> <li>
{% if snipt|is_favorited_by:request.user %} {% if is_favorited %}
<a class="favorite favorited" href="#">Favorited</a> <a class="favorite favorited" href="#">Favorited</a>
{% else %} {% else %}
<a class="favorite unfavorited" href="#">Favorite</a> <a class="favorite unfavorited" href="#">Favorite</a>

View File

@ -1,14 +1,28 @@
from django import template from django import template
from templatetag_sugar.register import tag
from templatetag_sugar.parser import Variable, Constant
from snipts.models import Favorite from snipts.models import Favorite
register = template.Library() register = template.Library()
@register.filter @tag(register, [Constant('as'), Variable()])
def is_favorited_by(snipt, user): def snipt_is_favorited_by_user(context, asvar):
try:
Favorite.objects.get(snipt=snipt, user=user) user = context['request'].user
return True snipt = context['snipt']
except Favorite.DoesNotExist:
return False is_favorited = False
if user.is_authenticated():
if snipt.user != user:
try:
is_favorited = Favorite.objects.get(snipt=snipt, user=user).id
except Favorite.DoesNotExist:
pass
context[asvar] = is_favorited
return ''

View File

@ -47,12 +47,13 @@ def list_user(request, username, tag_slug=None):
snipts = Snipt.objects snipts = Snipt.objects
if user == request.user: if user == request.user:
tags = tags.filter(snipt__user=user)
public = False public = False
favorites = Favorite.objects.filter(user=user).values('snipt') favorites = Favorite.objects.filter(user=user).values('snipt')
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))
else: else:
tags = tags.filter(snipt__user=user, snipt__public=True) tags = tags.filter(snipt__user=user, snipt__public=True)
snipts = snipts.filter(user=user, public=True) snipts = snipts.filter(user=user, public=True)

View File

@ -3,7 +3,6 @@ from registration.forms import RegistrationFormUniqueEmail
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
from django.contrib import admin from django.contrib import admin
from django.conf import settings
from tastypie.api import Api from tastypie.api import Api
from snipts.api import * from snipts.api import *
@ -20,6 +19,7 @@ private_api = Api(api_name='private')
private_api.register(PrivateSniptResource()) private_api.register(PrivateSniptResource())
private_api.register(PrivateTagResource()) private_api.register(PrivateTagResource())
private_api.register(PrivateUserResource()) private_api.register(PrivateUserResource())
private_api.register(PrivateFavoriteResource())
urlpatterns = patterns('', urlpatterns = patterns('',