Bump babel from 2.9.1 to 2.10.3
[mygpo.git] / mygpo / api / __init__.py
blobf15a6cda5c2cc6cdbf26b1eb4a9366a3893afea2
1 from datetime import datetime
3 from django.core.exceptions import ObjectDoesNotExist
4 from django.http import HttpResponseBadRequest, HttpResponseNotFound
5 from django.views.decorators.csrf import csrf_exempt
6 from django.views.decorators.cache import never_cache
7 from django.utils.decorators import method_decorator
8 from django.views import View
10 from mygpo.utils import parse_request_body
11 from mygpo.api.exceptions import ParameterMissing
12 from mygpo.decorators import cors_origin
13 from mygpo.api.basic_auth import require_valid_user, check_username
16 import logging
18 logger = logging.getLogger(__name__)
21 class RequestException(Exception):
22 """Raised if the request is malfored or otherwise invalid"""
25 class APIView(View):
26 @method_decorator(csrf_exempt)
27 @method_decorator(require_valid_user)
28 @method_decorator(check_username)
29 @method_decorator(never_cache)
30 @method_decorator(cors_origin())
31 def dispatch(self, *args, **kwargs):
32 """Dispatches request and does generic error handling"""
33 try:
34 return super(APIView, self).dispatch(*args, **kwargs)
36 except ObjectDoesNotExist as e:
37 return HttpResponseNotFound(str(e))
39 except (RequestException, ParameterMissing) as e:
40 return HttpResponseBadRequest(str(e))
42 def parsed_body(self, request):
43 """Returns the object parsed from the JSON request body"""
45 if not request.body:
46 raise RequestException("POST data must not be empty")
48 try:
49 # TODO: implementation of parse_request_body can be moved here
50 # after all views using it have been refactored
51 return parse_request_body(request)
52 except (UnicodeDecodeError, ValueError):
53 msg = "Could not decode request body for user {}: {}".format(
54 request.user.username, request.body.decode("ascii", errors="replace")
56 logger.warning(msg, exc_info=True)
57 raise RequestException(msg)
59 def get_since(self, request):
60 """Returns parsed "since" GET parameter"""
61 since_ = request.GET.get("since", None)
63 if since_ is None:
64 raise RequestException("parameter 'since' missing")
66 try:
67 since_ = int(since_)
68 since = datetime.fromtimestamp(since_)
69 except ValueError:
70 raise RequestException("'since' is not a valid timestamp")
72 if since_ < 0:
73 raise RequestException("'since' must be a non-negative number")
75 return since