summaryrefslogtreecommitdiff
path: root/showcase/models.py
blob: 7f2d423d6f71c1ba5efedf3023c6e6f1c82a4717 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import json
import requests

from django.conf import settings
from django.core.cache import cache
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db import models
from django.utils.translation import ugettext_lazy as _

from wagtail.admin.edit_handlers import FieldPanel

from home.models import BasePage


class ExternalSourceType(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)
    panels = [
        FieldPanel('name'),
        FieldPanel('slug'),
    ]

    class Meta:
        verbose_name = _("External source type")
        verbose_name_plural = _("External source types")

    def __str__(self):
        return self.name


class ExternalSource(models.Model):
    name = models.CharField(max_length=200)
    error = models.TextField(null=True, blank=True)
    source_type = models.ForeignKey(ExternalSourceType,
                                    on_delete=models.PROTECT)
    api_url = models.URLField()
    api_key = models.CharField(max_length=500, null=True, blank=True)
    panels = [
        FieldPanel('name'),
        FieldPanel('source_type'),
        FieldPanel('api_url'),
        FieldPanel('api_key'),
    ]

    class Meta:
        verbose_name = _("External source")
        verbose_name_plural = _("External sources")

    def __str__(self):
        return self.name

    def get_data(self):
        key = "{}{}-data-{}".format(
            settings.WAGTAIL_SITE_NAME, settings.WAGTAIL_EXTRA_SLUG,
            self.pk
        )
        data = cache.get(key)
        if data:
            return data
        data = []
        headers = {}
        base_error = str(_("Error while fetching the source:")) + " "
        if self.api_key:
            headers = {'Authorization': 'token {}'.format(self.api_key)}
        try:
            response = requests.get(self.api_url, headers=headers)
            if response.status_code == 401:
                self.error = base_error + str(_("permisssion denied - check "
                                                "your API key"))
            else:
                data = json.loads(response.text)
                cache.set(key, data)
                self.error = ""
        except json.JSONDecodeError:
            self.error = base_error + str(_("invalid source"))
        except requests.exceptions.Timeout:
            self.error = base_error + str(_("connection time out"))
        except requests.exceptions.TooManyRedirects:
            self.error = base_error + str(_("too many redirection"))
        except requests.exceptions.RequestException as e:
            self.error = base_error + str(_("unknown error")) + " - " + str(e)
        self.save()
        return data

    @property
    def data(self):
        return self.get_data()

    def get_item(self, item_number):
        if item_number >= len(self.data):
            return
        return self.data[item_number]


class ShowCase(BasePage):
    external_source = models.ForeignKey(ExternalSource,
                                        on_delete=models.PROTECT)
    content_panels = [
        FieldPanel('external_source')
    ] + BasePage.content_panels

    class Meta:
        verbose_name = _("Show case")
        verbose_name_plural = _("Show cases")

    @property
    def data(self):
        return self.external_source.get_data()

    def get_context(self, request):
        context = super(ShowCase, self).get_context(request)
        page = request.GET.get('page', 1)

        paginator = Paginator(self.data, 10)
        try:
            paginated_data = paginator.page(page)
        except PageNotAnInteger:
            paginated_data = paginator.page(1)
        except EmptyPage:
            paginated_data = paginator.page(paginator.num_pages)

        context['paginated_data'] = paginated_data
        if paginator.num_pages > 1:
            context['paginator'] = paginator
        return context