2626logger = logging .getLogger (__name__ )
2727
2828
29+ DEFAULT_TIMEOUT = 30
30+
2931class File (object ):
3032 _class_name = '_File' # walks like a leancloud.Object
3133
@@ -35,6 +37,7 @@ def __init__(self, name='', data=None, mime_type=None):
3537 self ._url = None
3638 self ._acl = None
3739 self .current_user = leancloud .User .get_current ()
40+ self .timeout = 30
3841 self ._metadata = {
3942 'owner' : 'unknown'
4043 }
@@ -74,11 +77,20 @@ def __init__(self, name='', data=None, mime_type=None):
7477 chunk = data .read (4096 )
7578 if not chunk :
7679 break
77- checksum .update (chunk )
80+
81+ try :
82+ checksum .update (chunk )
83+ except TypeError :
84+ checksum .update (chunk .encode ('utf-8' ))
7885
7986 self ._metadata ['_checksum' ] = checksum .hexdigest ()
8087 self ._metadata ['size' ] = data .tell ()
8188
89+ # 3.5MB, 1Mbps * 30s
90+ # increase timeout
91+ if self ._metadata ['size' ] > 3750000 :
92+ self .timeout = self .timeout * int (self ._metadata ['size' ] / 3750000 )
93+
8294 data .seek (0 , os .SEEK_SET )
8395
8496 self ._source = data
@@ -164,10 +176,41 @@ def destroy(self):
164176 if response .status_code != 200 :
165177 raise LeanCloudError (1 , "the file is not sucessfully destroyed" )
166178
179+ def _save_to_qiniu_internal_py3 (self , token , key ):
180+ from qiniu .services .storage .uploader import crc32 , _form_put , put_data
181+ from qiniu .config import _BLOCK_SIZE
182+
183+ final_data = ''
184+ while True :
185+ tmp_data = self ._source .read (_BLOCK_SIZE )
186+ if len (tmp_data ) == 0 :
187+ break
188+ elif len (final_data ) == 0 :
189+ final_data = tmp_data
190+ else :
191+ final_data += tmp_data
192+ else :
193+ final_data = self ._source .data
194+
195+ crc = crc32 (final_data )
196+ return _form_put (
197+ token , key ,
198+ final_data , None ,
199+ self .mime_type , crc
200+ )
201+
167202 def _save_to_qiniu (self , token , key ):
168- import qiniu
169203 self ._source .seek (0 )
170- ret , info = qiniu .put_data (token , key , self ._source )
204+
205+ import qiniu
206+ qiniu .set_default (connection_timeout = self .timeout )
207+
208+ if six .PY3 :
209+ # use patched put_data implementation for py3k
210+ ret , info = self ._save_to_qiniu_internal_py3 (token , key )
211+ else :
212+ # use put_data implementation provided by qiniu-sdk
213+ ret , info = qiniu .put_data (token , key , self ._source )
171214 self ._source .seek (0 )
172215
173216 if info .status_code != 200 :
0 commit comments