aboutsummaryrefslogtreecommitdiffstats
path: root/github3/helpers.py
blob: 62b28aaafd6c4affe1af15faf4e90926cafaef9a (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
# -*- 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, string_keys=None, date_keys=None, object_map=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 string_keys:
        for in_key in string_keys:
            # print in_key
            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:
                # TODO: Fix date formatting.
                out_date = datetime.strptime(in_date, '%Y-%m-%dT%H:%M:%SZ')
            except TypeError:
                out_date = None

            obj.__dict__[in_key] = out_date

    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):
    """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