Files
dss/spa/api/v1/UserResource.py
2013-06-22 17:06:56 +01:00

137 lines
7.0 KiB
Python
Executable File

from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.db.models import Count
import humanize
from tastypie import fields
from tastypie.authentication import Authentication
from tastypie.authorization import DjangoAuthorization
from django.conf.urls import url
from tastypie.http import HttpMultipleChoices, HttpGone
from tastypie.utils import trailing_slash
from spa.api.v1.BackboneCompatibleResource import BackboneCompatibleResource
from spa.api.v1.MixResource import MixResource
from spa.models import UserProfile, Mix
class UserProfileResource(BackboneCompatibleResource):
class Meta:
queryset = UserProfile.manager.annotate(fcount=Count('followers'))
resource_name = 'profile'
include_resource_uri = False
include_absolute_url = False
always_return_data = True
authorization = DjangoAuthorization()
authentication = Authentication()
def _hydrateBitmapOption(self, source, comparator):
return True if (source & comparator) != 0 else False
def hydrate(self, bundle):
if 'activity_sharing_likes' in bundle.data:
likes = UserProfile.ACTIVITY_SHARE_LIKES if bundle.data['activity_sharing_likes'] else 0
favourites = UserProfile.ACTIVITY_SHARE_FAVOURITES if bundle.data['activity_sharing_favourites'] else 0
comments = UserProfile.ACTIVITY_SHARE_COMMENTS if bundle.data['activity_sharing_comments'] else 0
bundle.data['activity_sharing'] = (likes | favourites | comments)
del bundle.data['activity_sharing_likes']
del bundle.data['activity_sharing_favourites']
del bundle.data['activity_sharing_comments']
if 'activity_sharing_networks_facebook' in bundle.data:
facebook = UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK if bundle.data[
'activity_sharing_networks_facebook'] else 0
twitter = UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER if bundle.data[
'activity_sharing_networks_twitter'] else 0
bundle.data['activity_sharing_networks'] = (facebook | twitter)
del bundle.data['activity_sharing_networks_facebook']
del bundle.data['activity_sharing_networks_twitter']
return bundle
def obj_update(self, bundle, skip_errors=False, **kwargs):
"""
This feels extremely hacky - but for some reason, deleting from the bundle
in hydrate is not preventing the fields from being serialized at the ORM
"""
if 'activity_sharing_networks_facebook' in kwargs: del kwargs['activity_sharing_networks_facebook']
if 'activity_sharing_networks_twitter' in kwargs: del kwargs['activity_sharing_networks_twitter']
if 'activity_sharing_likes' in kwargs: del kwargs['activity_sharing_likes']
if 'activity_sharing_favourites' in kwargs: del kwargs['activity_sharing_favourites']
if 'activity_sharing_comments' in kwargs: del kwargs['activity_sharing_comments']
return super(UserProfileResource, self).obj_update(bundle, skip_errors, **kwargs)
def dehydrate(self, bundle):
del bundle.data['activity_sharing']
del bundle.data['activity_sharing_networks']
bundle.data['display_name'] = bundle.obj.get_nice_name()
bundle.data['avatar_image'] = bundle.obj.get_avatar_image()
if bundle.obj.user.id == bundle.request.user.id:
bundle.data['activity_sharing_likes'] = \
self._hydrateBitmapOption(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_LIKES)
bundle.data['activity_sharing_favourites'] = \
self._hydrateBitmapOption(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_FAVOURITES)
bundle.data['activity_sharing_comments'] = \
self._hydrateBitmapOption(bundle.obj.activity_sharing, UserProfile.ACTIVITY_SHARE_COMMENTS)
bundle.data['activity_sharing_networks_facebook'] = \
self._hydrateBitmapOption(bundle.obj.activity_sharing_networks,
UserProfile.ACTIVITY_SHARE_NETWORK_FACEBOOK)
bundle.data['activity_sharing_networks_twitter'] = \
self._hydrateBitmapOption(bundle.obj.activity_sharing_networks,
UserProfile.ACTIVITY_SHARE_NETWORK_TWITTER)
bundle.data['mix_count'] = Mix.objects.filter(user=bundle.obj).count()
bundle.data['like_count'] = Mix.objects.filter(likes__user=bundle.obj).count()
bundle.data['favourite_count'] = Mix.objects.filter(favourites__user=bundle.obj).count()
bundle.data['follower_count'] = bundle.obj.followers.count()
bundle.data['following_count'] = bundle.obj.following.count()
bundle.data['following'] = bundle.obj.is_follower(bundle.request.user)
return bundle
class UserResource(BackboneCompatibleResource):
profile = fields.ToOneField(UserProfileResource, attribute='userprofile', related_name='user', full=True)
class Meta:
queryset = User.objects.all()
resource_name = 'user'
excludes = ['is_active', 'is_staff', 'is_superuser', 'password']
authorization = DjangoAuthorization()
authentication = Authentication()
favourites = fields.ToManyField(MixResource, 'favourites')
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<userprofile__slug>[\w\d_.-]+)/favourites%s$" % (
self._meta.resource_name, trailing_slash()),
self.wrap_view('get_user_favourites'), name="api_get_user_favourites"),
url(r"^(?P<resource_name>%s)/(?P<pk>\d+)/$" % self._meta.resource_name,
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
url(r"^(?P<resource_name>%s)/(?P<userprofile__slug>[\w\d_.-]+)/$" % self._meta.resource_name,
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
def get_object_list(self, request):
return super(UserResource, self).get_object_list(request)
def get_user_favourites(self, request, **kwargs):
try:
obj = self.cached_obj_get(bundle=self.build_bundle(request=request),
**self.remove_api_resource_names(kwargs))
except ObjectDoesNotExist:
return HttpGone()
except MultipleObjectsReturned:
return HttpMultipleChoices("More than one resource is found at this URI.")
mixes = MixResource()
return mixes.get_list(request, favourites__user=obj.get_profile())
def dehydrate(self, bundle):
if bundle.obj.id != bundle.request.user.id:
del bundle.data['email']
del bundle.data['username']
bundle.data['human_last_login'] = humanize.naturaltime(bundle.obj.last_login.replace(tzinfo=None))
return bundle