22
33import ConfigParser
44import cookielib
5- import json
5+
6+ # json module is not supported in versions of Python < 2.6 so try to load the
7+ # simplejson module instead. Note that as of simplejson v2.1.1, Python 2.4
8+ # support was dropped. You will need to look for v2.1.0 specifically for
9+ # Python 2.4 support.
10+ try :
11+ import json
12+ except ImportError :
13+ import simplejson as json
14+
615import oauth2 as oauth
716import urllib
817import urllib2
18+
19+ # parse_qs is in the urlparse module as of 2.6, but in cgi in earlier versions.
20+ try :
21+ from urlparse import parse_qs
22+ except ImportError :
23+ from cgi import parse_qs
24+
925import urlparse
1026
1127__version__ = '0.1.0'
@@ -107,8 +123,8 @@ def request(self, url, method='GET', headers={}, data=None, sign=False):
107123 # Since we are using a urllib2.Request object we need to assign a value
108124 # other than None to "data" in order to make the request a POST request,
109125 # even if there is no data to post.
110- if method == 'POST' :
111- data = data if data else ''
126+ if method == 'POST' and not data :
127+ data = ''
112128
113129 req = urllib2 .Request (url , headers = headers , data = data )
114130
@@ -124,7 +140,23 @@ def request(self, url, method='GET', headers={}, data=None, sign=False):
124140 if data :
125141 req .add_data (urllib .urlencode (req .get_data ()))
126142
127- return urllib2 .urlopen (req )
143+ # In 2.4 and 2.5, urllib2 throws errors for all non 200 status codes.
144+ # The OpenX API uses 201 create responses and 204 for delete respones.
145+ # We'll catch those errors and return the HTTPError object since it can
146+ # (thankfully) be used just like a Response object. A handler is
147+ # probably a better approach, but this is quick and works.
148+ res = '[]'
149+ try :
150+ res = urllib2 .urlopen (req )
151+ except urllib2 .HTTPError , err :
152+ if err .code in [201 , 204 ]:
153+ res = err
154+ else :
155+ # TODO: Decide on format and what extra data to alert user for
156+ # troubleshooting.
157+ raise err
158+
159+ return res
128160
129161 def fetch_request_token (self ):
130162 """Helper method to fetch and set request token.
@@ -140,8 +172,11 @@ def authorize_token(self, email=None, password=None):
140172 # Give precedence to credentials passed in methods calls over those set
141173 # in the instance. This allows you to override user creds that may have
142174 # been loaded from a file.
143- email = email if email else self ._email
144- password = password if password else self ._password
175+ if not email :
176+ email = self ._email
177+
178+ if not password :
179+ password = self ._password
145180
146181 if not email or not password :
147182 self ._email = self ._password = None
@@ -161,7 +196,7 @@ def authorize_token(self, email=None, password=None):
161196 # Clear user credentials.
162197 self ._email = self ._password = None
163198
164- verifier = urlparse . parse_qs (res .read ())['oauth_verifier' ][0 ]
199+ verifier = parse_qs (res .read ())['oauth_verifier' ][0 ]
165200 self ._token .set_verifier (verifier )
166201
167202 def fetch_access_token (self ):
@@ -229,10 +264,17 @@ def logoff(self):
229264 def _resolve_url (self , url ):
230265 """"""
231266 parse_res = urlparse .urlparse (url )
232- if not parse_res .scheme :
267+
268+ # 2.4 returns a tuple instead of ParseResult. Since ParseResult is a
269+ # subclass or tuple we can access URL components similarly across
270+ # 2.4 - 2.7. Yay!
271+
272+ # If there is no scheme specified we create a fully qualified URL.
273+ if not parse_res [0 ]:
233274 url = '%s://%s%s%s' % (self .scheme , self .domain , self .api_path ,
234- parse_res .path )
235- url = url + '?' + parse_res .query if parse_res .query else url
275+ parse_res [2 ])
276+ if parse_res [4 ]:
277+ url = url + '?' + parse_res [4 ]
236278
237279 return url
238280
@@ -268,8 +310,8 @@ def client_from_file(file_path='.ox3rc', env=None):
268310
269311 # Load default env if no env is specified. The default env is just the first
270312 # env listed.
271- env_ids = [ e for e in cp . get ( 'ox3apiclient' , 'envs' ). split ( ' \n ' ) if e ]
272- env = env if env else env_ids [0 ]
313+ if not env :
314+ env = [ e for e in cp . get ( 'ox3apiclient' , 'envs' ). split ( ' \n ' ) if e ] [0 ]
273315
274316 # Required parameters for a ox3apiclient.Client instance.
275317 required_params = [
0 commit comments