66 from urlparse import parse_qsl
77
88from .exceptions import QuickbooksException , SevereException
9+ import textwrap
910
1011try :
1112 from rauth import OAuth1Session , OAuth1Service
@@ -116,18 +117,18 @@ def get_authorize_url(self):
116117 Returns the Authorize URL as returned by QB, and specified by OAuth 1.0a.
117118 :return URI:
118119 """
119- self .authorize_url = self .authorize_url [:self .authorize_url .find ('?' )] if '?' in self .authorize_url else self .authorize_url
120+ self .authorize_url = self .authorize_url [:self .authorize_url .find ('?' )] \
121+ if '?' in self .authorize_url else self .authorize_url
120122 if self .qbService is None :
121123 self .set_up_service ()
122124
123125 response = self .qbService .get_raw_request_token (
124- params = {'oauth_callback' : self .callback_url })
126+ params = {'oauth_callback' : self .callback_url })
125127
126128 oauth_resp = dict (parse_qsl (response .text ))
127129
128130 self .request_token = oauth_resp ['oauth_token' ]
129131 self .request_token_secret = oauth_resp ['oauth_token_secret' ]
130-
131132 return self .qbService .get_authorize_url (self .request_token )
132133
133134 def set_up_service (self ):
@@ -157,7 +158,7 @@ def get_access_tokens(self, oauth_verifier):
157158
158159 return session
159160
160- def make_request (self , request_type , url , request_body = None , content_type = 'application/json' ):
161+ def make_request (self , request_type , url , request_body = None , content_type = 'application/json' , file = None ):
161162
162163 params = {}
163164
@@ -169,13 +170,52 @@ def make_request(self, request_type, url, request_body=None, content_type='appli
169170
170171 if self .session is None :
171172 self .create_session ()
172-
173173 headers = {
174174 'Content-Type' : content_type ,
175175 'Accept' : 'application/json'
176176 }
177-
178- req = self .session .request (request_type , url , True , self .company_id , headers = headers , params = params , data = request_body )
177+ if file :
178+ url = url .replace ('attachable' , 'upload' )
179+ file_name = file .name + ""
180+ if "/" in file_name :
181+ file_name = file_name .rsplit ("/" , 1 )[1 ]
182+ boundary = '-------------PythonMultipartPost'
183+ headers .update ({
184+ 'Content-Type' : 'multipart/form-data; boundary=%s' % boundary ,
185+ 'Accept-Encoding' : 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' ,
186+ 'User-Agent' : 'OAuth gem v0.4.7' ,
187+ 'Accept' : 'application/json' ,
188+ 'Connection' : 'close'
189+ })
190+ extension = file_name .rsplit ("." , 1 )[1 ]
191+
192+ mime_type = {
193+ "pdf" : "pdf" ,
194+ "xlsx" : "vnd.ms-excel" ,
195+ "pptx" : "vnd.ms-powerpoint" }.get (extension , "plain/text" )
196+ binary_data = file .read ()
197+
198+ request_body = textwrap .dedent (
199+ """
200+ --%s
201+ Content-Disposition: form-data; name="file_metadata_01"
202+ Content-Type: application/json
203+
204+ %s
205+
206+ --%s
207+ Content-Disposition: form-data; name="file_content_01"; filename="%s"
208+ Content-Type: application/%s
209+ Content-Length: %d
210+ Content-Transfer-Encoding: binary
211+
212+ %s
213+
214+ --%s--
215+ """
216+ ) % (boundary , request_body , boundary , file_name , mime_type , len (binary_data ), binary_data , boundary )
217+ req = self .session .request (request_type , url , True , self .company_id , headers = headers , params = params ,
218+ data = request_body )
179219
180220 try :
181221 result = req .json ()
@@ -212,11 +252,11 @@ def handle_exceptions(self, results):
212252 else :
213253 raise QuickbooksException (message , code , detail )
214254
215- def create_object (self , qbbo , request_body ):
255+ def create_object (self , qbbo , request_body , _file = None ):
216256 self .isvalid_object_name (qbbo )
217257
218258 url = self .api_url + "/company/{0}/{1}" .format (self .company_id , qbbo .lower ())
219- results = self .make_request ("POST" , url , request_body )
259+ results = self .make_request ("POST" , url , request_body , file = file )
220260
221261 return results
222262
0 commit comments