1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 from django.http import Http404
6 from django.views.generic.base import View
7 from oauthlib.common import urlencode
8 from oauthlib.oauth1 import RequestTokenEndpoint, AccessTokenEndpoint
9 from api.piston.models import KEY_SIZE, SECRET_SIZE
10 from rest_framework.permissions import IsAuthenticated
11 from rest_framework.response import Response
12 from rest_framework.views import APIView
13 from rest_framework.generics import ListAPIView, RetrieveAPIView, get_object_or_404
14 from migdal.models import Entry
15 from catalogue.models import Book
16 from .models import BookUserData
17 from . import serializers
18 from .request_validator import PistonRequestValidator
19 from .utils import oauthlib_request, oauthlib_response
22 class OAuth1RequestTokenEndpoint(RequestTokenEndpoint):
23 def _create_request(self, *args, **kwargs):
24 r = super(OAuth1RequestTokenEndpoint, self)._create_request(*args, **kwargs)
25 r.redirect_uri = 'oob'
28 def create_request_token(self, request, credentials):
30 'oauth_token': self.token_generator()[:KEY_SIZE],
31 'oauth_token_secret': self.token_generator()[:SECRET_SIZE],
33 token.update(credentials)
34 self.request_validator.save_request_token(token, request)
35 return urlencode(token.items())
38 class OAuth1RequestTokenView(View):
40 self.endpoint = OAuth1RequestTokenEndpoint(PistonRequestValidator())
42 def dispatch(self, request):
43 return oauthlib_response(
44 self.endpoint.create_request_token_response(
45 **oauthlib_request(request)
50 class OAuth1AccessTokenEndpoint(AccessTokenEndpoint):
51 def _create_request(self, *args, **kwargs):
52 r = super(OAuth1AccessTokenEndpoint, self)._create_request(*args, **kwargs)
56 def create_access_token(self, request, credentials):
57 request.realms = self.request_validator.get_realms(
58 request.resource_owner_key, request)
60 'oauth_token': self.token_generator()[:KEY_SIZE],
61 'oauth_token_secret': self.token_generator()[:SECRET_SIZE],
62 'oauth_authorized_realms': ' '.join(request.realms)
64 token.update(credentials)
65 self.request_validator.save_access_token(token, request)
66 return urlencode(token.items())
69 class OAuth1AccessTokenView(View):
71 self.endpoint = OAuth1AccessTokenEndpoint(PistonRequestValidator())
73 def dispatch(self, request):
74 return oauthlib_response(
75 self.endpoint.create_access_token_response(
76 **oauthlib_request(request)
81 class UserView(RetrieveAPIView):
82 permission_classes = [IsAuthenticated]
83 serializer_class = serializers.UserSerializer
86 return self.request.user
89 class BookUserDataView(RetrieveAPIView):
90 permission_classes = [IsAuthenticated]
91 serializer_class = serializers.BookUserDataSerializer
92 lookup_field = 'book__slug'
93 lookup_url_kwarg = 'slug'
95 def get_queryset(self):
96 return BookUserData.objects.filter(user=self.request.user)
98 def get(self, *args, **kwargs):
100 return super(BookUserDataView, self).get(*args, **kwargs)
102 return Response({"state": "not_started"})
104 def post(self, request, slug, state):
105 if state not in ('reading', 'complete'):
108 book = get_object_or_404(Book, slug=slug)
109 instance = BookUserData.update(book, request.user, state)
110 serializer = self.get_serializer(instance)
111 return Response(serializer.data)
114 class BlogView(ListAPIView):
115 serializer_class = serializers.BlogSerializer
117 def get_queryset(self):
118 after = self.request.query_params.get('after')
119 count = int(self.request.query_params.get('count', 20))
120 entries = Entry.published_objects.filter(in_stream=True).order_by('-first_published_at')
122 entries = entries.filter(first_published_at__lt=after)
124 entries = entries[:count]