1111 https://www.documentcloud.org/help/api
1212
1313"""
14+ from __future__ import absolute_import
1415import os
16+ import six
1517import copy
1618import base64
17- import urllib
18- import urllib2
19- from toolbox import retry
20- from toolbox import DoesNotExistError
21- from toolbox import DuplicateObjectError
22- from toolbox import credentials_required
23- from toolbox import CredentialsFailedError
19+ from .toolbox import retry
20+ from six .moves import urllib
21+ from .toolbox import DoesNotExistError
22+ from .toolbox import DuplicateObjectError
23+ from .toolbox import credentials_required
24+ from .toolbox import CredentialsFailedError
2425from dateutil .parser import parse as dateparser
25- from MultipartPostHandler import MultipartPostHandler
26+ from . MultipartPostHandler import MultipartPostHandler
2627try :
2728 import json
2829except ImportError :
@@ -50,7 +51,7 @@ def _make_request(self, url, params=None, opener=None):
5051 """
5152 # Create the request object
5253 args = [i for i in [url , params ] if i ]
53- request = urllib2 .Request (* args )
54+ request = urllib2 .request . Request (* args )
5455 # If the client has credentials, include them as a header
5556 if self .username and self .password :
5657 credentials = '%s:%s' % (self .username , self .password )
@@ -62,14 +63,14 @@ def _make_request(self, url, params=None, opener=None):
6263 # If the request provides a custom opener, like the upload request,
6364 # which relies on a multipart request, it is applied here.
6465 if opener :
65- opener = urllib2 .build_opener (opener )
66+ opener = urllib2 .request . build_opener (opener )
6667 request_method = opener .open
6768 else :
68- request_method = urllib2 .urlopen
69+ request_method = urllib2 .request . urlopen
6970 # Make the request
7071 try :
7172 response = request_method (request )
72- except urllib2 .HTTPError , e :
73+ except urllib2 .error . HTTPError as e :
7374 if e .code == 404 :
7475 raise DoesNotExistError ("The resource you've requested does \
7576 not exist or is unavailable without the proper credentials." )
@@ -95,7 +96,7 @@ def put(self, method, params):
9596 # Pull the document_ids out of the params
9697 document_ids = params .get ("document_ids" )
9798 del params ['document_ids' ]
98- params = urllib .urlencode (params , doseq = True )
99+ params = urllib .parse . urlencode (params , doseq = True )
99100 # These need to be specially formatted in the style documentcloud
100101 # expects arrays. The example they provide is:
101102 # ?document_ids[]=28-boumediene&document_ids[]=\
@@ -108,15 +109,16 @@ def put(self, method, params):
108109 # Pull them out of the dict
109110 data = params .get ("data" )
110111 del params ['data' ]
111- params = urllib .urlencode (params , doseq = True )
112+ params = urllib .parse . urlencode (params , doseq = True )
112113 # Format them in the style documentcloud expects
113114 # ?data['foo']=bar&data['tit']=tat
114115 params += "" .join ([
115- '&data[%s]=%s' % (key , value ) for key , value in data .items ()
116+ '&data[%s]=%s' % (key , value ) for key , value in
117+ list (data .items ())
116118 ])
117119 else :
118120 # Otherwise, we can just use the vanilla urllib prep method
119- params = urllib .urlencode (params , doseq = True )
121+ params = urllib .parse . urlencode (params , doseq = True )
120122 # Make the request
121123 self ._make_request (
122124 self .BASE_URI + method ,
@@ -129,7 +131,7 @@ def fetch(self, method, params=None):
129131 """
130132 # Encode params if they exist
131133 if params :
132- params = urllib .urlencode (params , doseq = True )
134+ params = urllib .parse . urlencode (params , doseq = True )
133135 content = self ._make_request (
134136 self .BASE_URI + method ,
135137 params ,
@@ -268,7 +270,7 @@ def upload(
268270 if project :
269271 params ['project' ] = project
270272 if data :
271- for key , value in data .items ():
273+ for key , value in list ( data .items () ):
272274 is_valid_data_keyword (key )
273275 params ['data[%s]' % key ] = value
274276 if secure :
@@ -425,7 +427,7 @@ def create(self, title, description=None, document_ids=None):
425427 }
426428 if description :
427429 params ['description' ] = description
428- params = urllib .urlencode (params , doseq = True )
430+ params = urllib .parse . urlencode (params , doseq = True )
429431 if document_ids :
430432 # These need to be specially formatted in the style documentcloud
431433 # expects arrays. The example they provide is:
@@ -489,7 +491,7 @@ def __str__(self):
489491 return self .__unicode__ ().encode ("utf-8" )
490492
491493 def __unicode__ (self ):
492- return unicode (self .title )
494+ return six . u (self .title )
493495
494496
495497class Annotation (BaseAPIObject ):
@@ -506,14 +508,14 @@ def __str__(self):
506508 return self .__unicode__ ().encode ("utf-8" )
507509
508510 def __unicode__ (self ):
509- return u''
511+ return six . u ( '' )
510512
511513 def get_location (self ):
512514 """
513515 Return the location as a good
514516 """
515517 image_string = self .__dict__ ['location' ]['image' ]
516- image_ints = map (int , image_string .split ("," ))
518+ image_ints = list ( map (int , image_string .split ("," ) ))
517519 return Location (* image_ints )
518520 location = property (get_location )
519521
@@ -623,7 +625,7 @@ def set_data(self, data):
623625 if not isinstance (data , type ({})):
624626 raise TypeError ("This attribute must be a dictionary." )
625627 # Validate keywords
626- for keyword in data .keys ():
628+ for keyword in list ( data .keys () ):
627629 is_valid_data_keyword (keyword )
628630 # Set the attribute
629631 self .__dict__ ['data' ] = data
@@ -676,7 +678,7 @@ def get_entities(self):
676678 "documents/%s/entities.json" % self .id
677679 ).get ("entities" )
678680 obj_list = []
679- for type , entity_list in entities .items ():
681+ for type , entity_list in list ( entities .items () ):
680682 for entity in entity_list :
681683 entity ['type' ] = type
682684 obj = Entity (entity )
@@ -691,10 +693,10 @@ def get_entities(self):
691693
692694 def _get_url (self , url ):
693695 if self .access == 'public' :
694- req = urllib2 .Request (url )
696+ req = urllib2 .request . Request (url )
695697 try :
696- return urllib2 .urlopen (req ).read ()
697- except urllib2 .HTTPError :
698+ return urllib2 .request . urlopen (req ).read ()
699+ except urllib2 .error . HTTPError :
698700 raise NotImplementedError (
699701 "Currently, DocumentCloud only allows you to access this \
700702 resource on public documents."
@@ -931,7 +933,7 @@ class Entity(BaseAPIObject):
931933 Keywords and such extracted from the document by OpenCalais.
932934 """
933935 def __unicode__ (self ):
934- return unicode (self .value )
936+ return six . u (self .value )
935937
936938
937939class Location (object ):
@@ -945,7 +947,7 @@ def __str__(self):
945947 return self .__unicode__ ().encode ("utf-8" )
946948
947949 def __unicode__ (self ):
948- return u''
950+ return six . u ( '' )
949951
950952 def __init__ (self , top , right , bottom , left ):
951953 self .top = top
@@ -959,7 +961,7 @@ class Mention(BaseAPIObject):
959961 A mention of a search found in the document.
960962 """
961963 def __unicode__ (self ):
962- return unicode ("Page %s" % (self .page ))
964+ return six . u ("Page %s" % (self .page ))
963965
964966
965967class Project (BaseAPIObject ):
@@ -1058,7 +1060,7 @@ def __str__(self):
10581060 return self .__unicode__ ().encode ("utf-8" )
10591061
10601062 def __unicode__ (self ):
1061- return u''
1063+ return six . u ( '' )
10621064
10631065 def __getattr__ (self , name ):
10641066 # When these attrs don't exist in the DocumentCloud db,
0 commit comments