Files
dss/spa/api/v1/UserResource.py
2014-09-02 21:56:38 +01:00

173 lines
7.1 KiB
Python
Executable File

from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.db.models import Count, Q, F
from tastypie import fields
from tastypie.authentication import Authentication
from tastypie.authorization import Authorization
from django.conf.urls import url
from tastypie.constants import ALL, ALL_WITH_RELATIONS
from tastypie.http import HttpGone, HttpMultipleChoices
from tastypie.utils import trailing_slash
from tastypie_msgpack import Serializer
from dss import settings
from spa.api.v1.BaseResource import BaseResource
from spa.api.v1.PlaylistResource import PlaylistResource
from spa.models.basemodel import BaseModel
from spa.models.userprofile import UserProfile
from spa.models.mix import Mix
from core.tasks import update_geo_info_task
class UserResource(BaseResource):
following = fields.ToManyField(to='self', attribute='following', related_name='following', null=True)
followers = fields.ToManyField(to='self', attribute='followers', related_name='followers', null=True)
favourites = fields.ToManyField('spa.api.v1.MixResource.MixResource', 'favourites', null=True)
playlists = fields.ToManyField('spa.api.v1.PlaylistResource.PlaylistResource', 'playlists',
related_name='user', null=True, full=True)
class Meta:
queryset = UserProfile.objects.all().annotate(mix_count=Count('mixes')).order_by('-mix_count')
serializer = Serializer()
resource_name = 'user'
if not settings.DEBUG:
excludes = ['is_active', 'is_staff', 'is_superuser', 'password']
ordering = ['mix_count']
filtering = {
'slug': ALL,
'display_name': ALL,
'following': ALL_WITH_RELATIONS,
'followers': ALL_WITH_RELATIONS,
'favourites': ALL_WITH_RELATIONS,
'playlists': ALL_WITH_RELATIONS,
}
authorization = Authorization()
authentication = Authentication()
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<pk>\d+)%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
url(r"^(?P<resource_name>%s)/(?P<slug>[\w\d_.-]+)%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
def apply_filters(self, request, applicable_filters):
semi_filtered = super(UserResource, self).apply_filters(request, applicable_filters)
q = request.GET.get('q', None)
if q is not None:
semi_filtered = semi_filtered.filter(
Q(user__first_name__icontains=q) |
Q(user__last_name__icontains=q) |
Q(display_name__icontains=q)
)
return semi_filtered
def obj_create(self, bundle, **kwargs):
return super(UserResource, self).obj_create(bundle, **kwargs)
def obj_update(self, bundle, skip_errors=False, **kwargs):
return super(UserResource, self).obj_update(bundle, skip_errors, **kwargs)
def _create_playlist(self, request):
pass
def get_playlists(self, request, **kwargs):
if request.method == 'POST':
return self._create_playlist(request)
try:
basic_bundle = self.build_bundle(request=request)
obj = self.cached_obj_get(bundle=basic_bundle,
**self.remove_api_resource_names(kwargs))
except ObjectDoesNotExist:
return HttpGone()
child_resource = PlaylistResource()
return child_resource.get_list(request, mix=obj)
def dehydrate_description(self, bundle):
return bundle.obj.get_profile_description()
def dehydrate(self, bundle):
del bundle.data['activity_sharing_networks']
bundle.data['display_name'] = bundle.obj.get_nice_name()
bundle.data['avatar_image'] = bundle.obj.get_avatar_image()
bundle = BaseResource.dehydrate_bitfield(
bundle=bundle,
field_name='email_notifications',
object_field=bundle.obj.email_notifications,
choices=UserProfile.NOTIFICATION_CHOICES,
)
bundle = BaseResource.dehydrate_bitfield(
bundle=bundle,
field_name='activity_sharing_facebook',
object_field=bundle.obj.activity_sharing_facebook,
choices=UserProfile.NOTIFICATION_CHOICES,
)
bundle = BaseResource.dehydrate_bitfield(
bundle=bundle,
field_name='activity_sharing_twitter',
object_field=bundle.obj.activity_sharing_twitter,
choices=UserProfile.NOTIFICATION_CHOICES,
)
if bundle.obj.user.id == bundle.request.user.id:
bundle.data['email'] = bundle.obj.email
bundle.data['first_name'] = bundle.obj.first_name
bundle.data['last_name'] = bundle.obj.last_name
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['is_following'] = bundle.obj.is_follower(bundle.request.user)
bundle.data['url'] = bundle.obj.get_profile_url()
bundle.data['date_joined'] = bundle.obj.user.date_joined
bundle.data['last_login'] = bundle.obj.user.last_login
bundle.data['mix_count'] = bundle.obj.mix_count
bundle.data['thumbnail'] = bundle.obj.get_small_profile_image()
return bundle
def hydrate(self, bundle):
bundle = BaseResource.hydrate_bitfield(
bundle=bundle,
field_name='email_notifications',
object_field=UserProfile.email_notifications,
choices=UserProfile.NOTIFICATION_CHOICES,
)
bundle = BaseResource.hydrate_bitfield(
bundle=bundle,
field_name='activity_sharing_facebook',
object_field=UserProfile.activity_sharing_facebook,
choices=UserProfile.NOTIFICATION_CHOICES,
)
bundle = BaseResource.hydrate_bitfield(
bundle=bundle,
field_name='activity_sharing_twitter',
object_field=UserProfile.activity_sharing_twitter,
choices=UserProfile.NOTIFICATION_CHOICES,
)
return bundle
def get_followers(self, request, **kwargs):
try:
basic_bundle = self.build_bundle(request=request)
obj = self.cached_obj_get(bundle=basic_bundle, **self.remove_api_resource_names(kwargs))
except ObjectDoesNotExist:
return HttpGone()
except MultipleObjectsReturned:
return HttpMultipleChoices("More than one resource is found at this URI.")
child_resource = UserResource()
return child_resource.get_list(request, followers__in=obj)