1 from urllib.parse import urlparse, urlunparse, parse_qs
3 from django.shortcuts import redirect, render
4 from django.views.generic.base import TemplateView
6 from rest_framework import status, viewsets
7 from rest_framework.response import Response
10 from . import serializers
12 def _remove_utm(link):
13 parsed_link = urlparse(link)
14 parsed_link = parsed_link._replace(
18 for p in parsed_link.query.split('&')
19 if not p.startswith('utm_')
25 parsed_link.scheme + '://' if parsed_link.scheme else '',
28 ';' + parsed_link.params if parsed_link.params else '',
29 '?' + parsed_link.query if parsed_link.query else '',
30 '#' + parsed_link.fragment if parsed_link.fragment else '',
33 def _follow_redirects(link, remove_utm):
36 link = _remove_utm(link)
38 response = requests.head(link)
40 # TODO Handle timeouts
42 if 301 <= response.status_code and response.status_code <= 308:
43 # TODO Handle the different kinds of redirects correctly
45 link = response.headers.get('Location')
51 # TODO Handle error responses
55 'status': response.status_code,
58 class IndexView(TemplateView):
59 template_name = 'bigly/index.html'
61 index = IndexView.as_view()
63 def embiggen(request):
64 serializer = serializers.FollowRedirectsSerializer(data=request.GET)
66 if not serializer.is_valid():
71 'errors': serializer.errors,
76 result = _follow_redirects(
77 link = serializer.data['link'],
78 remove_utm = serializer.data['remove_utm'],
81 if serializer.data['handler'] == 'redirect':
82 return redirect(result['link'])
87 'bigly/link_info.html',
91 class FollowRedirectsViewSet(viewsets.ViewSet):
92 serializer_class = serializers.FollowRedirectsSerializer
94 def follow_redirects(self, request):
95 serializer = serializers.FollowRedirectsSerializer(data=request.query_params)
97 if not serializer.is_valid():
100 status=status.HTTP_400_BAD_REQUEST,
103 result = _follow_redirects(
104 link = serializer.data['link'],
105 remove_utm = serializer.data['remove_utm'],
110 status=status.HTTP_200_OK,
113 api_follow_redirects = FollowRedirectsViewSet.as_view({
114 'get': 'follow_redirects',