Loadsa stuff

This commit is contained in:
Fergal Moran
2015-05-27 20:55:11 +01:00
parent 59865c42b8
commit 5ff02b5eff
19 changed files with 535 additions and 138 deletions

View File

@@ -1,3 +1,4 @@
import datetime
from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_201_CREATED
from rest_framework.views import APIView
@@ -16,8 +17,8 @@ class ActivityPlayHelper(ActivityHelper):
mix = Mix.objects.get(slug=self.request.QUERY_PARAMS.get('id'))
mix.add_play(request.user)
data = {
'user': request.user.get_nice_name() if request.user.is_authenticated() else settings.DEFAULT_USER_NAME,
'date': mix.description
'user': request.user.userprofile.get_nice_name() if request.user.is_authenticated() else settings.DEFAULT_USER_NAME,
'date': datetime.datetime.now()
}
return Response(data, HTTP_201_CREATED)
except Mix.DoesNotExist:

View File

@@ -18,7 +18,6 @@ class LoginException(Exception):
@strategy()
def register_by_access_token(request, backend):
strat = load_strategy(request)
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != b'social':
raise LoginException("Unable to register_by_access_token: No token header provided")
@@ -93,7 +92,6 @@ class ObtainUser(APIView):
model = Token
def get(self, request):
serializer = self.serializer_class(data=request.DATA)
if request.META.get('HTTP_AUTHORIZATION'):
auth = request.META.get('HTTP_AUTHORIZATION').split()
@@ -107,7 +105,7 @@ class ObtainUser(APIView):
return Response({'id': token.user_id, 'name': token.user.username, 'firstname': token.user.first_name,
'userRole': 'user', 'token': token.key})
else:
return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)
return Response(status=status.HTTP_401_UNAUTHORIZED)
class ObtainLogout(APIView):

View File

@@ -1,34 +0,0 @@
from django.core.files.base import ContentFile
from requests import request, ConnectionError
def save_profile(backend, user, response, is_new, *args, **kwargs):
if backend.name == 'google-oauth2':
if response.get('image') and response['image'].get('url'):
url = response['image'].get('url')
profile = user.userprofile
try:
response = request('GET', url)
response.raise_for_status()
except ConnectionError:
pass
else:
profile.avatar_image.save(u'',
ContentFile(response.content),
save=False)
profile.save()
elif backend.name == 'facebook':
profile = user.userprofile
url = 'http://graph.facebook.com/{0}/picture'.format(response['id'])
try:
response = request('GET', url, params={'type': 'large'})
response.raise_for_status()
except ConnectionError:
pass
else:
profile.avatar_image.save(u'',
ContentFile(response.content),
save=False
)
profile.save()

View File

@@ -1,8 +1,9 @@
import json
# from django.core.serializers import serialize
from django.db.models import Count
from rest_framework import serializers
from core.utils.html import strip_tags
from dss import settings
from spa import models
from spa.models import Activity
from spa.models.activity import ActivityDownload, ActivityPlay
from spa.models.genre import Genre
@@ -12,41 +13,6 @@ from spa.models.mix import Mix, MixUpdateException
from spa.models.comment import Comment
class InlineUserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = (
'slug',
'first_name',
'last_name',
'display_name',
'avatar_image',
'avatar_image_tiny',
)
first_name = serializers.ReadOnlyField(source='get_first_name')
last_name = serializers.ReadOnlyField(source='get_last_name')
display_name = serializers.ReadOnlyField(source='get_nice_name')
avatar_image = serializers.SerializerMethodField()
avatar_image_tiny = serializers.SerializerMethodField()
def get_avatar_image(self, obj):
return obj.get_sized_avatar_image(64, 64)
def get_avatar_image_tiny(self, obj):
return obj.get_sized_avatar_image(32, 32)
def to_representation(self, instance):
if instance.user.is_anonymous():
return {
'avatar_image': settings.DEFAULT_USER_IMAGE,
'display_name': settings.DEFAULT_USER_NAME,
'slug': ''
}
return super(serializers.ModelSerializer, self).to_representation(instance)
class InlineMixSerializer(serializers.ModelSerializer):
class Meta:
model = Mix
@@ -114,7 +80,7 @@ class InlineActivityDownloadSerializer(InlineActivitySerializer):
class MixSerializer(serializers.ModelSerializer):
class Meta:
model = Mix
model = models.Mix
fields = [
'id',
'slug',
@@ -137,13 +103,13 @@ class MixSerializer(serializers.ModelSerializer):
]
slug = serializers.ReadOnlyField(required=False)
user = InlineUserProfileSerializer(many=False, required=False, read_only=True)
user = serializers.SlugRelatedField(slug_field='slug', read_only=True)
waveform_url = serializers.ReadOnlyField(source='get_waveform_url')
waveform_progress_url = serializers.ReadOnlyField(source='get_waveform_progress_url')
mix_image = serializers.ReadOnlyField(source='get_image_url')
can_edit = serializers.SerializerMethodField()
genres = GenreSerializer(many=True, required=False, read_only=True)
genres = GenreSerializer(many=True, required=False, read_only=False)
likes = LikeSerializer(many=True, required=False, read_only=False) # slug_field='slug', many=True, read_only=True)
favourites = serializers.SlugRelatedField(slug_field='slug', many=True, read_only=True)
plays = InlineActivityPlaySerializer(many=True, read_only=True, source='activity_plays')
@@ -175,10 +141,17 @@ class MixSerializer(serializers.ModelSerializer):
validated_data.pop('likes', None)
# get any likes that aren't in passed bundle
plays = validated_data['downloads']
for play in plays:
instance.add_play(play)
validated_data.pop('downloads', None)
if 'downloads' in validated_data:
plays = validated_data['downloads'] or []
for play in plays:
instance.add_play(play)
validated_data.pop('downloads', None)
if 'genres' in validated_data:
genres = validated_data['genres'] or []
for genre in genres:
instance.add_genre(genre)
validated_data.pop('genres', None)
return super(MixSerializer, self).update(instance, validated_data)
except MixUpdateException, ex:
@@ -188,7 +161,7 @@ class MixSerializer(serializers.ModelSerializer):
return super(MixSerializer, self).is_valid(raise_exception)
def get_avatar_image(self, obj):
return obj.user.get_sized_avatar_image(32, 32)
return obj.user.get_sized_avatar_image(64, 64)
def get_can_edit(self, obj):
user = self.context['request'].user
@@ -210,9 +183,55 @@ class MixSerializer(serializers.ModelSerializer):
return obj.is_liked(user) if user.is_authenticated() else False
class InlineUserProfileSerializer(serializers.ModelSerializer):
profile_image_small = serializers.SerializerMethodField()
profile_image_medium = serializers.SerializerMethodField()
profile_image_header = serializers.SerializerMethodField()
class Meta:
model = UserProfile
fields = (
'slug',
'first_name',
'last_name',
'display_name',
'profile_image_small',
'profile_image_medium',
'profile_image_header',
)
first_name = serializers.ReadOnlyField(source='get_first_name')
last_name = serializers.ReadOnlyField(source='get_last_name')
display_name = serializers.ReadOnlyField(source='get_nice_name')
def get_avatar_image(self, obj):
return obj.get_sized_avatar_image(64, 64)
def get_avatar_image_tiny(self, obj):
return obj.get_sized_avatar_image(64, 64)
def to_representation(self, instance):
if instance.user.is_anonymous():
return {
'avatar_image': settings.DEFAULT_USER_IMAGE,
'display_name': settings.DEFAULT_USER_NAME,
'slug': ''
}
return super(serializers.ModelSerializer, self).to_representation(instance)
def get_profile_image_small(self, obj):
return obj.get_sized_avatar_image(64, 64)
def get_profile_image_medium(self, obj):
return obj.get_sized_avatar_image(170, 170)
def get_profile_image_header(self, obj):
return obj.get_sized_avatar_image(1200, 150)
class UserProfileSerializer(serializers.ModelSerializer):
roles = serializers.SerializerMethodField()
mixes = InlineMixSerializer(many=True, required=False)
likes = serializers.SlugRelatedField(slug_field='slug', many=True, read_only=True)
favourites = serializers.SlugRelatedField(slug_field='slug', many=True, read_only=True)
following = InlineUserProfileSerializer(many=True, read_only=True)
@@ -224,6 +243,7 @@ class UserProfileSerializer(serializers.ModelSerializer):
date_joined = serializers.SerializerMethodField()
last_login = serializers.SerializerMethodField()
title = serializers.SerializerMethodField()
description = serializers.SerializerMethodField()
profile_image_small = serializers.SerializerMethodField()
profile_image_medium = serializers.SerializerMethodField()
profile_image_header = serializers.SerializerMethodField()
@@ -246,7 +266,6 @@ class UserProfileSerializer(serializers.ModelSerializer):
'profile_image_medium',
'profile_image_header',
'slug',
'mixes',
'likes',
'isme',
'favourites',
@@ -258,12 +277,15 @@ class UserProfileSerializer(serializers.ModelSerializer):
def get_title(self, obj):
try:
if obj.description:
return obj.description[:75] + (obj.description[75:] and '..')
return strip_tags(obj.description[:128] + (obj.description[128:] and '..'))
else:
return settings.DEFAULT_USER_TITLE
except:
return settings.DEFAULT_USER_TITLE
def get_description(self, obj):
return obj.description if obj.description else settings.DEFAULT_USER_TITLE
def get_roles(self, obj):
return obj.get_roles()
@@ -276,15 +298,6 @@ class UserProfileSerializer(serializers.ModelSerializer):
def get_last_login(self, obj):
return obj.user.last_login
def get_profile_image_small(self, obj):
return obj.get_sized_avatar_image(32, 32)
def get_profile_image_medium(self, obj):
return obj.get_sized_avatar_image(170, 170)
def get_profile_image_header(self, obj):
return obj.get_sized_avatar_image(1200, 150)
def get_top_tags(self, obj):
return list(
Genre.objects.filter(mix__user__slug='fergalmoran').
@@ -292,11 +305,19 @@ class UserProfileSerializer(serializers.ModelSerializer):
order_by('-total').
values('total', 'description', 'slug')[0:3])
def get_profile_image_small(self, obj):
return obj.get_sized_avatar_image(64, 64)
def get_profile_image_medium(self, obj):
return obj.get_sized_avatar_image(170, 170)
def get_profile_image_header(self, obj):
return obj.get_sized_avatar_image(1200, 150)
class CommentSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.SlugRelatedField(slug_field='slug', read_only=True)
user = InlineUserProfileSerializer(source='get_comment_user', read_only=True)
avatar_image = serializers.SerializerMethodField()
user_display_name = serializers.SerializerMethodField('get_display_name')
mix = serializers.PrimaryKeyRelatedField(read_only=True)
can_edit = serializers.SerializerMethodField()
@@ -308,27 +329,35 @@ class CommentSerializer(serializers.HyperlinkedModelSerializer):
'time_index',
'date_created',
'user',
'user_display_name',
'avatar_image',
'mix',
'can_edit',
'can_edit'
)
def get_comment_user(self, obj):
try:
if obj.user is not None:
return obj.user.get_nice_name()
except:
pass
return settings.DEFAULT_USER_NAME
def get_display_name(self, obj):
if obj.user is not None:
return obj.user.get_nice_name()
return obj.user.userprofile.get_nice_name()
else:
return settings.DEFAULT_USER_NAME
def get_avatar_image(self, obj):
if obj.user is not None:
return obj.user.get_sized_avatar_image(48, 48)
return obj.user.userprofile.get_sized_avatar_image(48, 48)
else:
return settings.DEFAULT_USER_IMAGE
def get_can_edit(self, obj):
user = self.context['request'].user
if user.is_authenticated():
if user is not None and user.is_authenticated():
return user.is_staff or obj.user.id == user.userprofile.id
return False

View File

@@ -1,43 +1,38 @@
from api.auth import ObtainAuthToken, ObtainUser, ObtainLogout
from api.activity_helpers import ActivityPlayHelper
from api.views import CommentViewSet, MixViewSet, UserProfileViewSet, NotificationViewSet, PartialMixUploadView, \
GenreViewSet, ActivityViewSet, HitlistViewset, AttachedImageUploadView, DownloadItemView, SearchResultsView
from django.conf.urls import url, patterns, include
from rest_framework_nested import routers
from django.conf.urls import patterns, url, include
from rest_framework.routers import DefaultRouter
router = routers.SimpleRouter(trailing_slash=True)
router.register(r'notification', NotificationViewSet)
router.register(r'hitlist', HitlistViewset)
router.register(r'comments', CommentViewSet)
router.register(r'user', UserProfileViewSet, base_name='userprofile')
router.register(r'activity', ActivityViewSet, base_name='activity')
from api import views, auth, activity_helpers
router.register(r'mix', MixViewSet)
mix_router = routers.NestedSimpleRouter(router, r'mix', lookup='mix')
mix_router.register('comments', CommentViewSet)
router = DefaultRouter() # trailing_slash=True)
router.register(r'user', views.UserProfileViewSet)
router.register(r'mix', views.MixViewSet)
router.register(r'notification', views.NotificationViewSet)
router.register(r'hitlist', views.HitlistViewSet)
router.register(r'comments', views.CommentViewSet)
router.register(r'activity', views.ActivityViewSet, base_name='activity')
router.register(r'genre', views.GenreViewSet, base_name='genre')
"""
router.register(r'hitlist', HitlistViewset, base_name='hitlist')
router.register(r'notification', NotificationViewSet, base_name='notification')
"""
router.register(r'genre', GenreViewSet, base_name='genre')
urlpatterns = patterns(
'',
url(r'^', include(router.urls)),
url(r'^', include(mix_router.urls)),
url(r'_download/', DownloadItemView.as_view()),
url(r'_upload/$', PartialMixUploadView.as_view()),
url(r'_image/$', AttachedImageUploadView.as_view()),
url(r'_search/$', SearchResultsView.as_view()),
# url(r'^', include(mix_router.urls)),
url(r'_download/', views.DownloadItemView.as_view()),
url(r'_upload/$', views.PartialMixUploadView.as_view()),
url(r'_image/$', views.AttachedImageUploadView.as_view()),
url(r'_search/$', views.SearchResultsView.as_view()),
url(r'^', include(router.urls)),
url(r'^login/', ObtainAuthToken.as_view()),
url(r'^user/', ObtainUser.as_view()),
url(r'^logout/', ObtainLogout.as_view()),
#url(r'^_tr/', RefreshToken.as_view()),
url(r'^login/', auth.ObtainAuthToken.as_view()),
url(r'^logout/', auth.ObtainLogout.as_view()),
# url(r'^_tr/', RefreshToken.as_view()),
url(r'^__user/', auth.ObtainUser.as_view()),
url(r'^_act/play', ActivityPlayHelper.as_view()),
url(r'^_act/play', activity_helpers.ActivityPlayHelper.as_view()),
url('', include('social.apps.django_app.urls', namespace='social')),
)

View File

@@ -6,36 +6,41 @@ from django.core.files.base import ContentFile
from django.core.files.storage import FileSystemStorage
from django.db.models import Count
from django.http.response import HttpResponse
from django.utils.encoding import smart_str
from rest_framework import viewsets
from rest_framework import views
from rest_framework.decorators import detail_route
from rest_framework.permissions import BasePermission
from rest_framework.parsers import FileUploadParser
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework.status import HTTP_202_ACCEPTED, HTTP_401_UNAUTHORIZED, HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND, \
HTTP_200_OK, HTTP_204_NO_CONTENT
from rest_framework import filters
from api.serialisers import MixSerializer, UserProfileSerializer, NotificationSerializer, \
ActivitySerializer, HitlistSerializer, CommentSerializer, GenreSerializer
from api import serializers
from dss import settings
from core.tasks import create_waveform_task, archive_mix_task
from core.tasks import create_waveform_task
from spa.models.genre import Genre
from spa.models.activity import Activity, ActivityPlay
from spa.models.activity import ActivityPlay
from spa.models.mix import Mix
from spa.models.comment import Comment
from spa.models.notification import Notification
from spa.models.userprofile import UserProfile
logger = logging.getLogger(__name__)
class AnonymousWriteUserDelete(BasePermission):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return True
class CommentViewSet(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
permission_classes = (IsAuthenticatedOrReadOnly,)
serializer_class = serializers.CommentSerializer
permission_classes = (AnonymousWriteUserDelete,)
filter_fields = (
'comment',
'mix__slug',
@@ -49,30 +54,45 @@ class CommentViewSet(viewsets.ModelViewSet):
try:
mix = Mix.objects.get(pk=self.request.DATA['mix_id'])
if mix is not None:
serializer.save(mix=mix, user=self.request.user.userprofile)
serializer.save(
mix=mix,
user=self.request.user if self.request.user.is_authenticated() else None
)
except Mix.DoesNotExist:
pass
except Exception, ex:
pass
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.annotate(mix_count=Count('mixes')).order_by('-mix_count')
serializer_class = UserProfileSerializer
serializer_class = serializers.UserProfileSerializer
permission_classes = (IsAuthenticatedOrReadOnly,)
lookup_field = 'slug'
filter_fields = (
'slug',
)
def get_queryset(self):
if 'following' in self.request.QUERY_PARAMS:
ret = UserProfile.objects.filter(following__slug__in=[self.request.QUERY_PARAMS['following']])
elif 'followers' in self.request.QUERY_PARAMS:
ret = UserProfile.objects.filter(followers__slug__in=[self.request.QUERY_PARAMS['followers']])
else:
ret = super(UserProfileViewSet, self).get_queryset()
return ret
class MixViewSet(viewsets.ModelViewSet):
queryset = Mix.objects.all()
serializer_class = MixSerializer
lookup_field = 'slug'
serializer_class = serializers.MixSerializer
permission_classes = (IsAuthenticatedOrReadOnly,)
lookup_field = 'slug'
filter_fields = (
'waveform_generated',
'slug',
'user',
'user__slug',
'is_featured',
)
@@ -126,7 +146,7 @@ class SearchResultsView(views.APIView):
'slug': mix.slug,
'url': mix.get_absolute_url(),
'description': mix.description
} for mix in Mix.objects.filter(title__icontains=q)[0:10]]
} for mix in Mix.objects.filter(title__icontains=q)[0:10]]
return Response(m)
return HttpResponse(status=HTTP_204_NO_CONTENT)
@@ -165,14 +185,14 @@ class PartialMixUploadView(views.APIView):
raise
class HitlistViewset(viewsets.ModelViewSet):
class HitlistViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all().annotate(mix_count=Count('mixes')).order_by('-mix_count')[0:10]
serializer_class = HitlistSerializer
serializer_class = serializers.HitlistSerializer
class ActivityViewSet(viewsets.ModelViewSet):
queryset = ActivityPlay.objects.all() #select_subclasses()
serializer_class = ActivitySerializer
queryset = ActivityPlay.objects.all() # select_subclasses()
serializer_class = serializers.ActivitySerializer
def get_queryset(self):
user = self.request.user
@@ -194,7 +214,7 @@ class DownloadItemView(views.APIView):
class NotificationViewSet(viewsets.ModelViewSet):
queryset = Notification.objects.all()
serializer_class = NotificationSerializer
serializer_class = serializers.NotificationSerializer
def get_queryset(self):
user = self.request.user
@@ -206,7 +226,7 @@ class NotificationViewSet(viewsets.ModelViewSet):
class GenreViewSet(viewsets.ModelViewSet):
queryset = Genre.objects.all()
serializer_class = GenreSerializer
serializer_class = serializers.GenreSerializer
def get_queryset(self):
if 'q' in self.request.QUERY_PARAMS: