天天看點

bcloud 研究之登陸流程

大概看懂了登入流程,作以記錄

主要涉及到的有三個檔案,分别是SigninDialog.py,auth.py,和gutil.py三個檔案,SigninDialog.py提供登陸對話框和相關函數調用整合,auth.py提供一些授權的函數,gutil.py主要用到了多線程的一個函數封裝。

先看SigninDialog.py,裡面實作了兩個類SigninVcodeDialog,SigninDialog,前者是登陸驗證碼的對話框,後者是登陸的對話框,主要看後者,其初始化是在建構一些GUI,不重要,跳到434行,這是登陸的切入點,代碼摘下來

        username =self.username_combo.get_child().get_text()

       password = self.password_entry.get_text()

       if not self.password_changed and self.signin_check.get_active():

           cookie, tokens = self.load_auth(username)

           if cookie and tokens:

                self.update_profile(username,password, cookie, tokens)

                return

       cookie = RequestCookie()

       tokens = {}

       verifycode = ''

       codeString = ''

       password_enc = ''

       rsakey = ''

       self.signin_button.set_label(_('Get BAIDUID...'))

       gutil.async_call(auth.get_BAIDUID, callback=on_get_BAIDUID

先擷取到了username和password,然後檢查本地緩存,使用本地緩存,然而要看登陸流程,繼續往下看,假如第一次登陸,那麼就會執行

           cookie = RequestCookie()

RequestCookie來自RequestCookie.py,這個檔案也要用到,剛才忘記提了。然而這個類的具體内容不重要,隻要知道它用來存Cookie就是了

然後是

                   tokens= {}

       verifycode = ''            #這是登陸時的驗證碼

       password_enc = ''    #這個是加密後的密碼

先初始化為空,後面他會指派的。

然後

                   self.signin_button.set_label(_('GetBAIDUID...'))

表示在擷取百度ID,當然這隻是改了标簽上的内容,實質性的是下一句。

                   gutil.async_call(auth.get_BAIDUID,callback=on_get_BAIDUID)

注意到gutil.async_call這個函數,看它的調用大概可以知道是用來連接配接函數的,具體看到gutil.py這個檔案94行,代碼如下:

def async_call(func, *args, callback=None):

   '''Call `func` in background thread, and then call `callback` in Gtkmain thread.

   If error occurs in `func`, error will keep the traceback and passed to

   `callback` as second parameter. Always check `error` is not None.

   '''

   def do_call():

       result = None

       error = None

       try:

           result = func(*args)

       except Exception:

           error = traceback.format_exc()

           logger.error(error)

       if callback:

           GLib.idle_add(callback, result, error)

   thread = threading.Thread(target=do_call)

   thread.daemon = True

thread.start()

注釋上說,func參數是背景線程,然後再Gtk主線程裡面調用callback,若func裡面有錯誤,他就把錯誤當成第二參數傳給callback,特别說一下,中間那個參數*arg是傳給func的

總的來說,這個函數的功能就是先執行func,傳*arg給func,然後把func的傳回和error作為第一第二參數傳給callback。

是以這句

就是調用auth.get_BAIDUID,*arg為空,回調on_get_BAIDUID

看auth.get_BAIDUID,在auth.py的29行,注釋說的很明白,擷取一個cookie – BAIDUID

傳回一個req.headers.get_all('Set-Cookie'),具體細節不了解,但不影響,知道那是個資料就是了。然後看回調的函數,是SigninDialog這個類的内建函數,在422行

                   defon_get_BAIDUID(uid_cookie, error=None):

           if error or not uid_cookie:

               logger.error('SigninDialog.on_get_BAIDUID: %s, %s' %

                             (uid_cookie,error))

                self.signin_failed(

                        _('Failed to getBAIDUID cookie, please try again.'))

           else:

                cookie.load_list(uid_cookie)

                self.signin_button.set_label(_('GetTOKEN...'))

               gutil.async_call(auth.get_token, cookie, callback=on_get_token)

可以看到,顯示一個處理錯誤的機制,然後沒出錯的話

                   cookie.load_list(uid_cookie)  

處理一下資料

                   self.signin_button.set_label(_('GetTOKEN...'))

更新顯示的内容

                   gutil.async_call(auth.get_token,cookie, callback=on_get_token)

連接配接auth.get_token和on_get_token,給auth.get_token傳入cookie,這個cookie是最早就定義了的,cookie.load_list(uid_cookie)相當于把上一步獲得的傳回值加進去。

整個過程都是這個樣子的模式,實作了那種動态顯示現在在幹嘛的機制,運用了多線程。剩下的代碼就是照着這個思路寫的。

最後,這隻是初步看了個輪廓,細節待鑽研,以後補充。