1# -*- coding: utf-8 -*-
2from __future__ import absolute_import
3from __future__ import unicode_literals
4
5from datetime import datetime
6from json import dumps, loads
7
8from django.core import serializers
9from django.http import HttpResponse
10from django.utils.encoding import force_text
11from django.utils.functional import Promise
12
13
14class JSONResponseMixin(object):
15    """
16    A mixin that can be used to render a JSON response. See:
17    https://docs.djangoproject.com/en/dev/topics/class-based-views/mixins/
18    """
19    def render_to_json_response(self, context, **kwargs):
20        """
21        Returns a JSON response, transforming 'context' to make the payload.
22        """
23        return HttpResponse(
24            self.convert_context_to_json(context),
25            content_type='application/json',
26            **kwargs
27        )
28
29    def convert_context_to_json(self, context):
30        """
31        Get what we want out of the context dict and convert that to a JSON
32        object. Note that this does no object serialization b/c we're
33        not sending any objects.
34        """
35        if 'month/shift' in self.request.path:  # month calendar
36            return dumps(self.get_month_calendar_dict(context))
37        elif 'event-list/shift' in self.request.path:  # month event list
38            return dumps(self.get_month_event_list_dict(context))
39        elif 'cal-and-list/shift' in self.request.path:
40            cal = self.get_month_calendar_dict(context)
41            l = self.get_month_event_list_dict(context)
42            cal.update(l)
43            return dumps(cal)
44        else:  # day list view
45            for key, val in context.items():
46                if isinstance(val, Promise):
47                    context[key] = force_text(val)
48
49            return dumps(self.get_day_context_dict(context))
50
51    @staticmethod
52    def get_month_calendar_dict(context):
53        return dict(
54            calendar=context['calendar'],
55            month_and_year=context['month_and_year']
56        )
57
58    @staticmethod
59    def get_month_event_list_dict(context):
60        m = int(context['current']['month_num'])
61        y = int(context['current']['year'])
62        remove_these = (
63            'all_day', 'description', 'categories', 'tags', 'created_by',
64            'location',
65        )
66
67        for k, v in context['events'].items():
68            context['events'][k] = loads(serializers.serialize("json", v))
69            for event in context['events'][k]:
70                # remove unnec. fields to shorten the json response
71                for item in remove_these:
72                    del event['fields'][item]
73                event['weekday'] = datetime(  # add weekday e.g Fri, Mon, etc.
74                    y, m, k).strftime("%A")[:3]
75        return dict(
76            month=context['current']['month'], events=context['events']
77        )
78
79    @staticmethod
80    def get_day_context_dict(context):
81        events = loads(serializers.serialize("json", context['events']))
82        return dict(
83            events=events,
84            year=context['year'],
85            month=context['month_num'],
86            month_name=context['month'],
87            day=context['day'],
88            nxt=context['next'],
89            prev=context['prev'],
90        )
91