2015-03-23 02:22:35 +01:00
|
|
|
from django.core.exceptions import ObjectDoesNotExist
|
2012-05-11 02:08:46 +00:00
|
|
|
from tastypie import fields
|
2013-02-21 06:26:06 +00:00
|
|
|
from tastypie.authorization import DjangoAuthorization
|
2013-03-03 14:50:40 -08:00
|
|
|
from tastypie.constants import ALL, ALL_WITH_RELATIONS
|
2013-03-02 17:00:58 -08:00
|
|
|
from tastypie.exceptions import Unauthorized
|
2013-02-25 15:10:15 -08:00
|
|
|
from tastypie.resources import ModelResource
|
|
|
|
|
from django_images.models import Thumbnail
|
2012-07-06 20:01:33 +00:00
|
|
|
|
2013-03-03 04:47:34 -08:00
|
|
|
from .models import Pin, Image
|
2018-02-08 21:57:49 -05:00
|
|
|
from users.models import User
|
2012-05-11 02:08:46 +00:00
|
|
|
|
|
|
|
|
|
2013-03-02 17:00:58 -08:00
|
|
|
class PinryAuthorization(DjangoAuthorization):
|
|
|
|
|
"""
|
|
|
|
|
Pinry-specific Authorization backend with object-level permission checking.
|
|
|
|
|
"""
|
|
|
|
|
def update_detail(self, object_list, bundle):
|
|
|
|
|
klass = self.base_checks(bundle.request, bundle.obj.__class__)
|
|
|
|
|
|
|
|
|
|
if klass is False:
|
|
|
|
|
raise Unauthorized("You are not allowed to access that resource.")
|
|
|
|
|
|
2016-02-04 01:34:19 +00:00
|
|
|
permission = '%s.change_%s' % (klass._meta.app_label, klass._meta.model_name)
|
2013-03-02 17:00:58 -08:00
|
|
|
|
|
|
|
|
if not bundle.request.user.has_perm(permission, bundle.obj):
|
|
|
|
|
raise Unauthorized("You are not allowed to access that resource.")
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delete_detail(self, object_list, bundle):
|
|
|
|
|
klass = self.base_checks(bundle.request, bundle.obj.__class__)
|
|
|
|
|
|
|
|
|
|
if klass is False:
|
|
|
|
|
raise Unauthorized("You are not allowed to access that resource.")
|
|
|
|
|
|
2016-02-04 01:34:19 +00:00
|
|
|
permission = '%s.delete_%s' % (klass._meta.app_label, klass._meta.model_name)
|
2013-03-02 17:00:58 -08:00
|
|
|
|
|
|
|
|
if not bundle.request.user.has_perm(permission, bundle.obj):
|
|
|
|
|
raise Unauthorized("You are not allowed to access that resource.")
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
2013-02-20 07:59:45 +00:00
|
|
|
class UserResource(ModelResource):
|
2013-02-25 15:10:15 -08:00
|
|
|
gravatar = fields.CharField(readonly=True)
|
2013-02-22 01:28:56 +01:00
|
|
|
|
|
|
|
|
def dehydrate_gravatar(self, bundle):
|
|
|
|
|
return bundle.obj.gravatar
|
|
|
|
|
|
2013-02-20 07:59:45 +00:00
|
|
|
class Meta:
|
2013-02-25 15:10:15 -08:00
|
|
|
list_allowed_methods = ['get']
|
2013-03-03 14:50:40 -08:00
|
|
|
filtering = {
|
|
|
|
|
'username': ALL
|
|
|
|
|
}
|
2013-02-20 07:59:45 +00:00
|
|
|
queryset = User.objects.all()
|
|
|
|
|
resource_name = 'user'
|
2013-02-25 15:10:15 -08:00
|
|
|
fields = ['username']
|
2013-02-20 07:59:45 +00:00
|
|
|
include_resource_uri = False
|
|
|
|
|
|
|
|
|
|
|
2013-02-25 15:10:15 -08:00
|
|
|
def filter_generator_for(size):
|
|
|
|
|
def wrapped_func(bundle, **kwargs):
|
2015-03-23 03:30:13 +01:00
|
|
|
if hasattr(bundle.obj, '_prefetched_objects_cache') and 'thumbnail' in bundle.obj._prefetched_objects_cache:
|
|
|
|
|
for thumbnail in bundle.obj._prefetched_objects_cache['thumbnail']:
|
|
|
|
|
if thumbnail.size == size:
|
|
|
|
|
return thumbnail
|
|
|
|
|
raise ObjectDoesNotExist()
|
|
|
|
|
else:
|
|
|
|
|
return bundle.obj.get_by_size(size)
|
2013-02-25 15:10:15 -08:00
|
|
|
return wrapped_func
|
|
|
|
|
|
2013-02-23 20:33:10 +01:00
|
|
|
|
2013-02-25 15:10:15 -08:00
|
|
|
class ThumbnailResource(ModelResource):
|
2012-05-11 02:08:46 +00:00
|
|
|
class Meta:
|
2013-02-25 15:10:15 -08:00
|
|
|
list_allowed_methods = ['get']
|
|
|
|
|
fields = ['image', 'width', 'height']
|
|
|
|
|
queryset = Thumbnail.objects.all()
|
|
|
|
|
resource_name = 'thumbnail'
|
2012-05-11 02:08:46 +00:00
|
|
|
include_resource_uri = False
|
2013-02-25 15:10:15 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class ImageResource(ModelResource):
|
|
|
|
|
standard = fields.ToOneField(ThumbnailResource, full=True,
|
|
|
|
|
attribute=lambda bundle: filter_generator_for('standard')(bundle))
|
|
|
|
|
thumbnail = fields.ToOneField(ThumbnailResource, full=True,
|
|
|
|
|
attribute=lambda bundle: filter_generator_for('thumbnail')(bundle))
|
2013-03-02 11:55:02 -08:00
|
|
|
square = fields.ToOneField(ThumbnailResource, full=True,
|
|
|
|
|
attribute=lambda bundle: filter_generator_for('square')(bundle))
|
2013-02-25 15:10:15 -08:00
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
fields = ['image', 'width', 'height']
|
|
|
|
|
include_resource_uri = False
|
|
|
|
|
resource_name = 'image'
|
|
|
|
|
queryset = Image.objects.all()
|
2013-02-21 06:26:06 +00:00
|
|
|
authorization = DjangoAuthorization()
|
2012-05-11 02:08:46 +00:00
|
|
|
|
2013-02-25 15:10:15 -08:00
|
|
|
|
|
|
|
|
class PinResource(ModelResource):
|
|
|
|
|
submitter = fields.ToOneField(UserResource, 'submitter', full=True)
|
|
|
|
|
image = fields.ToOneField(ImageResource, 'image', full=True)
|
|
|
|
|
tags = fields.ListField()
|
|
|
|
|
|
|
|
|
|
def hydrate_image(self, bundle):
|
|
|
|
|
url = bundle.data.get('url', None)
|
|
|
|
|
if url:
|
|
|
|
|
image = Image.objects.create_for_url(url)
|
|
|
|
|
bundle.data['image'] = '/api/v1/image/{}/'.format(image.pk)
|
|
|
|
|
return bundle
|
|
|
|
|
|
2013-04-05 19:34:31 +02:00
|
|
|
def hydrate(self, bundle):
|
|
|
|
|
"""Run some early/generic processing
|
|
|
|
|
|
|
|
|
|
Make sure that user is authorized to create Pins first, before
|
|
|
|
|
we hydrate the Image resource, creating the Image object in process
|
|
|
|
|
"""
|
|
|
|
|
submitter = bundle.data.get('submitter', None)
|
|
|
|
|
if not submitter:
|
|
|
|
|
bundle.data['submitter'] = '/api/v1/user/{}/'.format(bundle.request.user.pk)
|
|
|
|
|
else:
|
|
|
|
|
if not '/api/v1/user/{}/'.format(bundle.request.user.pk) == submitter:
|
|
|
|
|
raise Unauthorized("You are not authorized to create Pins for other users")
|
|
|
|
|
return bundle
|
|
|
|
|
|
2013-02-25 15:10:15 -08:00
|
|
|
def dehydrate_tags(self, bundle):
|
|
|
|
|
return map(str, bundle.obj.tags.all())
|
|
|
|
|
|
2012-09-28 04:42:13 +00:00
|
|
|
def build_filters(self, filters=None):
|
|
|
|
|
orm_filters = super(PinResource, self).build_filters(filters)
|
2013-03-03 09:11:26 -08:00
|
|
|
if filters and 'tag' in filters:
|
2012-09-28 04:42:13 +00:00
|
|
|
orm_filters['tags__name__in'] = filters['tag'].split(',')
|
|
|
|
|
return orm_filters
|
|
|
|
|
|
|
|
|
|
def save_m2m(self, bundle):
|
2013-03-03 06:20:50 -08:00
|
|
|
tags = bundle.data.get('tags', None)
|
|
|
|
|
if tags:
|
|
|
|
|
bundle.obj.tags.set(*tags)
|
2012-09-28 04:42:13 +00:00
|
|
|
return super(PinResource, self).save_m2m(bundle)
|
2013-02-25 15:10:15 -08:00
|
|
|
|
|
|
|
|
class Meta:
|
2013-03-03 08:24:26 -08:00
|
|
|
fields = ['id', 'url', 'origin', 'description']
|
2013-02-26 01:21:57 -08:00
|
|
|
ordering = ['id']
|
2013-03-03 14:50:40 -08:00
|
|
|
filtering = {
|
|
|
|
|
'submitter': ALL_WITH_RELATIONS
|
|
|
|
|
}
|
2015-03-23 02:30:54 +01:00
|
|
|
queryset = Pin.objects.all().select_related('submitter', 'image'). \
|
2015-03-23 02:22:35 +01:00
|
|
|
prefetch_related('image__thumbnail_set', 'tags')
|
2013-02-25 15:10:15 -08:00
|
|
|
resource_name = 'pin'
|
|
|
|
|
include_resource_uri = False
|
2013-02-26 02:10:08 -08:00
|
|
|
always_return_data = True
|
2013-03-02 17:00:58 -08:00
|
|
|
authorization = PinryAuthorization()
|