1+ import re
2+ import six
3+ import datetime
4+
5+ from django .conf import settings
6+ from django .http import HttpResponse
7+
8+ from tastypie .api import Api
9+ from tastypie .serializers import Serializer
10+ from tastypie .exceptions import BadRequest , ApiFieldError
11+ from tastypie .utils .mime import determine_format , build_content_type
12+ from tastypie .utils import is_valid_jsonp_callback_value
13+ from tastypie .fields import ApiField
14+
15+ import debug # pyflakes:ignore
16+
17+ #
18+ # /json/doc
19+ # /json/name
20+ #
21+ #
22+ #
23+ #
24+ #
25+ #
26+ #
27+
28+ _api_list = []
29+
30+ for _app in settings .INSTALLED_APPS :
31+ _module_dict = globals ()
32+ if '.' in _app :
33+ _root , _name = _app .split ('.' , 1 )
34+ if _root == 'ietf' :
35+ if not '.' in _name :
36+ _api = Api (api_name = _name )
37+ _module_dict [_name ] = _api
38+ _api_list .append ((_name , _api ))
39+
40+ def top_level (request ):
41+ available_resources = {}
42+
43+ for name in sorted ([ name for name , api in _api_list ]):
44+ available_resources [name ] = {
45+ 'list_endpoint' : '/api/%s/' % name ,
46+ }
47+
48+ serializer = Serializer ()
49+ desired_format = determine_format (request , serializer )
50+
51+ options = {}
52+
53+ if 'text/javascript' in desired_format :
54+ callback = request .GET .get ('callback' , 'callback' )
55+
56+ if not is_valid_jsonp_callback_value (callback ):
57+ raise BadRequest ('JSONP callback name is invalid.' )
58+
59+ options ['callback' ] = callback
60+
61+ serialized = serializer .serialize (available_resources , desired_format , options )
62+ return HttpResponse (content = serialized , content_type = build_content_type (desired_format ))
63+
64+ def autodiscover ():
65+ """
66+ Auto-discover INSTALLED_APPS resources.py modules and fail silently when
67+ not present. This forces an import on them to register any admin bits they
68+ may want.
69+ """
70+
71+ from django .conf import settings
72+ from django .utils .importlib import import_module
73+ from django .utils .module_loading import module_has_submodule
74+
75+
76+ for app in settings .INSTALLED_APPS :
77+ mod = import_module (app )
78+ # Attempt to import the app's admin module.
79+ try :
80+ import_module ('%s.resources' % (app , ))
81+ except :
82+ # Decide whether to bubble up this error. If the app just
83+ # doesn't have an admin module, we can ignore the error
84+ # attempting to import it, otherwise we want it to bubble up.
85+ if module_has_submodule (mod , "resources" ):
86+ raise
87+
88+ TIMEDELTA_REGEX = re .compile ('^(?P<days>\d+d)?\s?(?P<hours>\d+h)?\s?(?P<minutes>\d+m)?\s?(?P<seconds>\d+s?)$' )
89+
90+ class TimedeltaField (ApiField ):
91+ dehydrated_type = 'timedelta'
92+ help_text = "A timedelta field, with duration expressed in seconds. Ex: 132"
93+
94+ def convert (self , value ):
95+ if value is None :
96+ return None
97+
98+ if isinstance (value , six .string_types ):
99+ match = TIMEDELTA_REGEX .search (value )
100+
101+ if match :
102+ data = match .groupdict ()
103+ return datetime .timedelta (int (data ['days' ]), int (data ['hours' ]), int (data ['minutes' ]), int (data ['seconds' ]))
104+ else :
105+ raise ApiFieldError ("Timedelta provided to '%s' field doesn't appear to be a valid timedelta string: '%s'" % (self .instance_name , value ))
106+
107+ return value
108+
109+ def hydrate (self , bundle ):
110+ value = super (TimedeltaField , self ).hydrate (bundle )
111+
112+ if value and not hasattr (value , 'seconds' ):
113+ if isinstance (value , six .string_types ):
114+ try :
115+ match = TIMEDELTA_REGEX .search (value )
116+
117+ if match :
118+ data = match .groupdict ()
119+ value = datetime .timedelta (int (data ['days' ]), int (data ['hours' ]), int (data ['minutes' ]), int (data ['seconds' ]))
120+ else :
121+ raise ValueError ()
122+ except (ValueError , TypeError ):
123+ raise ApiFieldError ("Timedelta provided to '%s' field doesn't appear to be a valid datetime string: '%s'" % (self .instance_name , value ))
124+
125+ else :
126+ raise ApiFieldError ("Datetime provided to '%s' field must be a string: %s" % (self .instance_name , value ))
127+
128+ return value
129+
130+
0 commit comments