aboutsummaryrefslogtreecommitdiffstats
path: root/pygithub3/resources/base.py
blob: 4c65b8b8a2b7619594ec0f15809ba64a3641709a (plain) (blame)
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
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

from datetime import datetime

from pygithub3.core.utils import json

GITHUB_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'


class Resource(object):

    _dates = ()
    _maps = {}
    _collection_maps = {}

    def __init__(self, attrs):
        """ """
        self._attrs = attrs
        self.__set_attrs()

    def __set_attrs(self):
        for attr in self._attrs:
            setattr(self, attr, self._attrs[attr])

    def __str__(self):
        return "<%s>" % self.__class__.__name__

    def __repr__(self):
        return self.__str__()

    @classmethod
    def loads(self, json_content):
        resource_chunk = json.loads(json_content)
        if not hasattr(resource_chunk, 'items'):
            return [self.__load(raw_resource)
                    for raw_resource in resource_chunk]
        else:
            return self.__load(resource_chunk)

    @classmethod
    def __load(self, raw_resource):
        def self_resource(func):
            def wrapper(resource, raw_resource):
                if resource == 'self':
                    resource = self
                return func(resource, raw_resource)
            return wrapper

        def parse_date(string_date):
            try:
                date = datetime.strptime(string_date, GITHUB_DATE_FORMAT)
            except TypeError:
                date = None
            return date

        @self_resource
        def parse_map(resource, raw_resource):
            if hasattr(raw_resource, 'items'):
                return resource.__load(raw_resource)

        @self_resource
        def parse_collection_map(resource, raw_resources):
            # Dict of resources (Ex: Gist file)
            if hasattr(raw_resources, 'items'):
                dict_map = {}
                for key, raw_resource in raw_resources.items():
                    dict_map[key] = resource.__load(raw_resource)
                return dict_map
            # list of resources
            elif hasattr(raw_resources, '__iter__'):
                return [resource.__load(raw_resource)
                        for raw_resource in raw_resources]

        new_resource = raw_resource.copy()
        new_resource.update(dict([
            (attr, parse_date(raw_resource[attr]))
             for attr in self._dates if attr in raw_resource]))
        new_resource.update(dict([
            (attr, parse_map(resource, raw_resource[attr]))
             for attr, resource in self._maps.items()
             if attr in raw_resource]))
        new_resource.update(dict([
            (attr, parse_collection_map(resource, raw_resource[attr]))
             for attr, resource in self._collection_maps.items()
             if attr in raw_resource]))

        return self(new_resource)


class Raw(Resource):

    @classmethod
    def loads(self, json_content):
        return json.loads(json_content)