aboutsummaryrefslogtreecommitdiffstats
path: root/github3/helpers.py
blob: 391fe1e248c0b47c77d6375e8aec8c7150d70548 (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
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
127
128
129
130
131
132
133
134
135
# -*- coding: utf-8 -*-

"""
github3.helpers
~~~~~~~~~~~~~~~~

This module provides various helper functions to the rest of the package.
"""

import inspect
from datetime import datetime

from dateutil.parser import parse as parse_datetime


def is_collection(obj):
    """Tests if an object is a collection."""

    col = getattr(obj, '__getitem__', False)
    val = False if (not col) else True

    if isinstance(obj, basestring):
        val = False

    return val


# from arc90/python-readability-api
def to_python(obj,
    in_dict,
    str_keys=None,
    date_keys=None,
    int_keys=None,
    object_map=None,
    bool_keys=None, **kwargs):
    """Extends a given object for API Consumption.

    :param obj: Object to extend.
    :param in_dict: Dict to extract data from.
    :param string_keys: List of in_dict keys that will be extracted as strings.
    :param date_keys: List of in_dict keys that will be extrad as datetimes.
    :param object_map: Dict of {key, obj} map, for nested object results.
    """

    if str_keys:
        for in_key in str_keys:
            obj.__dict__[in_key] = in_dict.get(in_key)

    if date_keys:
        for in_key in date_keys:
            in_date = in_dict.get(in_key)
            try:
                out_date = datetime.strptime(in_date, '%Y-%m-%dT%H:%M:%SZ')
            except TypeError:
                out_date = None

            obj.__dict__[in_key] = out_date

    if int_keys:
        for in_key in int_keys:
            obj.__dict__[in_key] = int(in_dict.get(in_key))

    if bool_keys:
        for in_key in bool_keys:
            obj.__dict__[in_key] = bool(in_dict.get(in_key))

    if object_map:

        for (k, v) in object_map.items():
            obj.__dict__[k] = v.new_from_dict(in_dict.get(k))

    obj.__dict__.update(kwargs)

    return obj


# from arc90/python-readability-api
def to_api(in_dict, int_keys=None, date_keys=None, bool_keys=None):
    """Extends a given object for API Production."""

    # Cast all int_keys to int()
    if int_keys:
        for in_key in int_keys:
            if (in_key in in_dict) and (in_dict.get(in_key, None) is not None):
                in_dict[in_key] = int(in_dict[in_key])

    # Cast all date_keys to datetime.isoformat
    if date_keys:
        for in_key in date_keys:
            if (in_key in in_dict) and (in_dict.get(in_key, None) is not None):

                _from = in_dict[in_key]

                if isinstance(_from, basestring):
                    dtime = parse_datetime(_from)

                elif isinstance(_from, datetime):
                    dtime = _from

                in_dict[in_key] = dtime.isoformat()

            elif (in_key in in_dict) and in_dict.get(in_key, None) is None:
                del in_dict[in_key]

    # Remove all Nones
    for k, v in in_dict.items():
        if v is None:
            del in_dict[k]

    return in_dict



# from kennethreitz/showme
def get_scope(f, args=None):
    """Get scope of given function for Exception scopes."""

    if args is None:
        args=list()

    scope = inspect.getmodule(f).__name__
    # guess that function is a method of it's class
    try:
        if f.func_name in dir(args[0].__class__):
            scope += '.' + args[0].__class__.__name__
            scope += '.' + f.__name__
        else:
            scope += '.' + f.__name__
    except IndexError:
        scope += '.' + f.__name__

    # scrub readability.models namespace
    scope = scope.replace('readability.api.', '')

    return scope