大概看懂了登入流程,作以記錄
主要涉及到的有三個檔案,分别是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)相當于把上一步獲得的傳回值加進去。
整個過程都是這個樣子的模式,實作了那種動态顯示現在在幹嘛的機制,運用了多線程。剩下的代碼就是照着這個思路寫的。
最後,這隻是初步看了個輪廓,細節待鑽研,以後補充。