summaryrefslogtreecommitdiffstats
path: root/reporting/api/service/result.py
blob: fa6553ca205baa0f1a9f9916087c9944f53ee22b (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
import json
import logging
from collections import defaultdict

from tornado.gen import coroutine
from tornado.gen import Return
from tornado.httpclient import AsyncHTTPClient

from api import conf as consts
from api.extension.client import NoQueueTimeoutHTTPClient

LOG = logging.getLogger(__name__)
AsyncHTTPClient.configure(NoQueueTimeoutHTTPClient)


class Result(object):

    def __init__(self):
        self._url = '{}/results?period={}&version={}&page={}'
        self._client = AsyncHTTPClient()
        self._result = defaultdict(list)

    @property
    @coroutine
    def result(self):
        if not self._result:
            yield self.update_results()
        raise Return(self._result)

    @coroutine
    def update_results(self):
        LOG.info('start update results')

        for version in consts.versions:
            yield self._update_version_result(version)

        LOG.info('results update finished')

    @coroutine
    def _update_version_result(self, version):
        total_page = yield self._get_total_page(version)

        responses = yield self._fetch_results(version, total_page)

        self._update_version_dict(version, responses)

    @coroutine
    def _fetch_results(self, version, total_page):
        urls = [self._url.format(consts.base_url, consts.period, version, i)
                for i in range(1, total_page + 1)]
        responses = yield [self._client.fetch(url) for url in urls]
        raise Return(responses)

    @coroutine
    def _get_total_page(self, version):
        url = self._url.format(consts.base_url, consts.period, version, 1)
        response = yield self._client.fetch(url)
        raise Return(json.loads(response.body)['pagination']['total_pages'])

    def _update_version_dict(self, version, responses):
        for response in responses:
            results = json.loads(response.body)['results']
            for result in results:
                data = {k: v for k, v in result.items() if k != 'details'}
                self._result[version].append(data)


class ResultCache(Result):

    @classmethod
    @coroutine
    def update(cls):
        cls._check()

        yield cls.cache.update_results()

    @classmethod
    @coroutine
    def get(cls, version):
        cls._check()

        result = yield cls.cache.result
        raise Return(result[version])

    @classmethod
    def _check(cls):
        try:
            cls.cache
        except AttributeError:
            cls.cache = cls()