1616import select
1717import base64
1818import md5
19+ import rsa
1920from zlib import crc32
2021import cStringIO
2122import signal
@@ -115,22 +116,24 @@ def __init__(self):
115116 @staticmethod
116117 def _check_cookie_file ():
117118 def correct_do ():
118- g = open (cookie_file , 'wb' )
119- pk .dump ({}, g )
120- g .close ()
119+ with open (cookie_file , 'wb' ) as g :
120+ pk .dump ({}, g )
121121 print s % (1 , 97 , ' please login' )
122- sys . exit ( 1 )
122+ return
123123
124124 if not os .path .exists (cookie_file ):
125125 correct_do ()
126+ return {}
126127
127128 try :
128129 j = pk .load (open (cookie_file ))
129130 except :
130131 correct_do ()
132+ return {}
131133
132134 if type (j ) != type ({}):
133135 correct_do ()
136+ return {}
134137
135138 for i in j :
136139 if type (j [i ]) != type ({}):
@@ -185,60 +188,64 @@ def check_login(self):
185188 def login (self , username , password ):
186189 print s % (1 , 97 , '\n -- login' )
187190
188- # Check if we have to deal with verify codes
189- params = {
190- 'tpl' : 'pp' ,
191- 'callback' : 'bdPass.api.login._needCodestringCheckCallback' ,
192- 'index' : 0 ,
193- 'logincheck' : '' ,
194- 'time' : 0 ,
195- 'username' : username
196- }
197-
198- # Ask server
199- url = 'https://passport.baidu.com/v2/api/?logincheck'
200- r = ss .get (url , params = params )
201- # Callback for verify code if we need
202- #codestring = r.content[r.content.index('(')+1:r.content.index(')')]
203- codestring = re .search (r'\((.+?)\)' , r .content ).group (1 )
204- codestring = json .loads (codestring )['codestring' ]
205- codestring = codestring if codestring else ""
206- url = 'https://passport.baidu.com/cgi-bin/genimage?' + codestring
207- verifycode = self .save_img (url , 'gif' ) if codestring != "" else ""
208-
209- # Now we'll do login
210191 # Get token
211- ss .get ('http://www.baidu.com' )
212- t = ss .get ('https://passport.baidu.com/v2/api/?getapi&class=login' \
213- '&tpl=pp&tangram=false' ).text
214- token = re .search (r'login_token=\'(.+?)\'' , t ).group (1 )
192+ token = self ._get_bdstoken ()
193+
194+ # get publickey
195+ url = 'https://passport.baidu.com/v2/getpublickey?token=%s' % token
196+ r = ss .get (url )
197+ j = json .loads (r .content .replace ('\' ' , '"' ))
198+ pubkey = j ['pubkey' ]
199+ key = rsa .PublicKey .load_pkcs1_openssl_pem (pubkey )
200+ password_encoded = base64 .b64encode (rsa .encrypt (password , key ))
201+ rsakey = j ['key' ]
215202
216203 # Construct post body
217204 data = {
218- 'token' : token ,
219- 'ppui_logintime' : '1600000' ,
220- 'charset' :'utf-8' ,
221- 'codestring' : codestring ,
222- 'isPhone' : 'false' ,
223- 'index' : 0 ,
224- 'u' : '' ,
225- 'safeflg' : 0 ,
226- 'staticpage' : 'http://www.baidu.com/cache/user/html/jump.html' ,
227- 'loginType' : 1 ,
228- 'tpl' : 'pp' ,
229- 'callback' : 'parent.bd__pcbs__qvljue' ,
230- 'username' : username ,
231- 'password' : password ,
232- 'verifycode' : verifycode ,
233- 'mem_pass' : 'on' ,
234- 'apiver' : 'v3'
205+ "staticpage" : "http://www.baidu.com/cache/user/html/v3Jump.html" ,
206+ "charset" : "UTF-8" ,
207+ "token" : token ,
208+ "tpl" : "pp" ,
209+ "subpro" : "" ,
210+ "apiver" : "v3" ,
211+ "tt" : int (time .time ()),
212+ "codestring" : "" ,
213+ "safeflg" : "0" ,
214+ "isPhone" : "" ,
215+ "quick_user" : "0" ,
216+ "logintype" : "dialogLogin" ,
217+ "logLoginType" : "pc_loginDialog" ,
218+ "idc" : "" ,
219+ "loginmerge" : "true" ,
220+ "splogin" : "rate" ,
221+ "username" : username ,
222+ "password" : password_encoded ,
223+ "verifycode" : "" ,
224+ "mem_pass" : "on" ,
225+ "rsakey" : str (rsakey ),
226+ "crypttype" : "12" ,
227+ "ppui_logintime" : "40228" ,
228+ "callback" : "parent.bd__pcbs__uvwly2" ,
235229 }
236230
237- # Post!
238- # XXX : do not handle errors
239- url = 'https://passport.baidu.com/v2/api/?login'
240- ss .post (url , data = data )
241- #self.save_cookies()
231+ while True :
232+ # Post!
233+ # XXX : do not handle errors
234+ url = 'https://passport.baidu.com/v2/api/?login'
235+ r = ss .post (url , data = data )
236+
237+ # Callback for verify code if we need
238+ #codestring = r.content[r.content.index('(')+1:r.content.index(')')]
239+ if 'err_no=0' in r .content :
240+ break
241+ else :
242+ t = re .search ('codeString=(.+?)&' , r .content )
243+ codestring = t .group (1 ) if t else ""
244+ vcurl = 'https://passport.baidu.com/cgi-bin/genimage?' + codestring
245+ verifycode = self .save_img (vcurl , 'gif' ) if codestring != "" else ""
246+ data ['codestring' ] = codestring
247+ data ['verifycode' ] = verifycode
248+ #self.save_cookies()
242249
243250 def save_cookies (self , username , on = 0 ):
244251 self .username = username
@@ -525,7 +532,7 @@ def _get_dlink(self, i):
525532 self ._get_dsign ()
526533
527534 def _get_dlink2 (self , i ):
528- j = self ._meta ([i ['path' ].encode ('utf8' )])
535+ j = self ._meta ([i ['path' ].encode ('utf8' )], dlink = 1 )
529536 if j :
530537 return j ['info' ][0 ]['dlink' ].encode ('utf8' )
531538 else :
@@ -538,7 +545,7 @@ def download(self, paths):
538545 base_dir = '' if os .path .split (path )[0 ] == '/' \
539546 else os .path .split (path )[0 ]
540547
541- meta = self ._meta ([path ])
548+ meta = self ._meta ([path ], dlink = 1 )
542549 if meta :
543550 if meta ['info' ][0 ]['isdir' ]:
544551 dir_loop = [path ]
@@ -706,23 +713,27 @@ def _make_dir(self, dir_):
706713 else :
707714 return ENoError
708715
709- def _meta (self , file_list ):
716+ def _meta (self , file_list , dlink = 0 ):
710717 p = {
711718 "channel" : "chunlei" ,
712719 "app_id" : "250528" ,
713720 "method" : "filemetas" ,
714- "dlink" : 1 ,
721+ "dlink" : dlink ,
715722 "blocks" : 0 , # 0 or 1
716723 #"bdstoken": self._get_bdstoken()
717724 }
718725 data = {'target' : json .dumps (file_list )}
719726 url = 'http://pan.baidu.com/api/filemetas'
720- r = ss .post (url , params = p , data = data )
721- j = r .json ()
722- if j ['errno' ] == 0 :
723- return j
724- else :
725- return False
727+ while True :
728+ try :
729+ r = ss .post (url , params = p , data = data )
730+ j = r .json ()
731+ if j ['errno' ] == 0 :
732+ return j
733+ else :
734+ return False
735+ except Exception :
736+ time .sleep (1 )
726737
727738 ################################################################
728739 # for upload
@@ -868,6 +879,10 @@ def _upload_file(self, lpath, rpath):
868879 print s % (1 , 94 , ' ++ uploading:' ), lpath
869880
870881 __current_file_size = os .path .getsize (lpath )
882+ if __current_file_size == 0 :
883+ print s % (1 , 91 , ' |-- file is empty, missing.' )
884+ return
885+
871886 self .__current_file_size = __current_file_size
872887 upload_function = self ._get_upload_function ()
873888
@@ -920,41 +935,43 @@ def _upload_file(self, lpath, rpath):
920935 else :
921936 print s % (1 , 91 , ' |-- slice_md5 does\' n match, retry.' )
922937 self .upload_datas [lpath ]['slice_md5s' ].append (self .__slice_md5 )
923- # self.save_upload_datas()
938+ self .save_upload_datas ()
924939 start_time = print_process_bar (f .tell (), __current_file_size , slice , start_time , \
925940 pre = ' ' , msg = '%s/%s' % (str (piece + 1 ), str (pieces )))
926941 result = self ._combine_file (lpath , rpath )
927942 if result == ENoError :
928943 self .upload_datas [lpath ]['is_over' ] = True
929944 self .upload_datas [lpath ]['remotepaths' ].update ([rpath ])
930945 del self .upload_datas [lpath ]['slice_md5s' ]
931- # self.save_upload_datas()
946+ self .save_upload_datas ()
932947 print s % (1 , 92 , '\n |-- success.\n ' )
933948 break
934949 else :
935- print s % (1 , 91 , '\n !! Error at _combine_file:' ), result ['error_msg' ]
936- sys .exit (1 )
950+ print s % (1 , 91 , '\n !! Error at _combine_file:' ), result
951+ break
952+ #sys.exit(1)
937953
938954 elif m == '_upload_one_file' :
939955 time .sleep (2 )
940956 result = self ._upload_one_file (lpath , rpath )
941957 if result == ENoError :
942958 self .upload_datas [lpath ]['is_over' ] = True
943959 self .upload_datas [lpath ]['remotepaths' ].update ([rpath ])
944- # self.save_upload_datas()
960+ self .save_upload_datas ()
945961 print s % (1 , 92 , '\n |-- success.\n ' )
946962 break
947963 else :
948- print s % (1 , 91 , '\n !! Error at _upload_one_file:' ), result ['error_msg' ]
949- sys .exit (1 )
964+ print s % (1 , 91 , '\n !! Error at _upload_one_file:' ), result
965+ break
966+ #sys.exit(1)
950967
951968 elif m == '_rapidupload_file' :
952969 time .sleep (2 )
953970 result = self ._rapidupload_file (lpath , rpath )
954971 if result == ENoError :
955972 self .upload_datas [lpath ]['is_over' ] = True
956973 self .upload_datas [lpath ]['remotepaths' ].update ([rpath ])
957- # self.save_upload_datas()
974+ self .save_upload_datas ()
958975 print s % (1 , 92 , ' |-- RapidUpload: Success.\n ' )
959976 break
960977 else :
@@ -2201,6 +2218,7 @@ def sighandler(signum, frame):
22012218 print s % (1 , 91 , " !! Signal:" ), signum
22022219 if args .comd in ('u' , 'upload' ):
22032220 px .save_upload_datas ()
2221+
22042222 #print s % (1, 91, " !! Frame: %s" % frame)
22052223 sys .exit (1 )
22062224
@@ -2274,6 +2292,8 @@ def main(argv):
22742292 #######################################################
22752293
22762294 if comd == 'login' or comd == 'g' :
2295+ x = panbaiducom_HOME ()
2296+
22772297 if len (xxx ) < 1 :
22782298 username = raw_input (s % (1 , 97 , ' username: ' ))
22792299 password = getpass (s % (1 , 97 , ' password: ' ))
@@ -2286,7 +2306,6 @@ def main(argv):
22862306 else :
22872307 print s % (1 , 91 , ' login\n login username\n login username password' )
22882308
2289- x = panbaiducom_HOME ()
22902309 x .login (username , password )
22912310 result = x .check_login ()
22922311 if result :
0 commit comments