Browse Source

Merge branch 'master-dev' of https://github.com/gjwang/wxBot into master-dev

liuwons 9 years ago
parent
commit
38ef2ecf16
1 changed files with 60 additions and 23 deletions
  1. 60 23
      wxbot.py

+ 60 - 23
wxbot.py

@@ -9,10 +9,14 @@ import urllib
 import time
 import re
 import random
-from requests.exceptions import *
 import webbrowser
+from requests.exceptions import ConnectionError, ReadTimeout
 import HTMLParser
 
+UNKONWN = 'unkonwn'
+SUCCESS = '200'
+SCANED  = '201'
+TIMEOUT = '408'
 
 class WXBot:
     """WXBot, a framework to process WeChat messages"""
@@ -668,15 +672,19 @@ class WXBot:
     def run(self):
         self.get_uuid()
         self.gen_qr_code('qr.png')
-        print '[INFO] Please use WeCaht to scan the QR code .'
-        self.wait4login(1)
-        print '[INFO] Please confirm to login .'
-        self.wait4login(0)
+        print '[INFO] Please use WeChat to scan the QR code .'
+        
+        result = self.wait4login()
+        if result != SUCCESS:
+            print '[ERROR] Web WeChat login failed. failed code=%s'%(result, )
+            return
+        
         if self.login():
             print '[INFO] Web WeChat login succeed .'
         else:
             print '[ERROR] Web WeChat login failed .'
             return
+
         if self.init():
             print '[INFO] Web WeChat init succeed .'
         else:
@@ -716,29 +724,58 @@ class WXBot:
         elif self.conf['qr'] == 'tty':
             print(qr.terminal(quiet_zone=1))
 
-    def wait4login(self, tip):
-        time.sleep(tip)
-        url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s' \
-              % (tip, self.uuid, int(time.time()))
+    def do_request(self, url):
         r = self.session.get(url)
         r.encoding = 'utf-8'
         data = r.text
         param = re.search(r'window.code=(\d+);', data)
         code = param.group(1)
-
-        if code == '201':
-            return True
-        elif code == '200':
-            param = re.search(r'window.redirect_uri="(\S+?)";', data)
-            redirect_uri = param.group(1) + '&fun=new'
-            self.redirect_uri = redirect_uri
-            self.base_uri = redirect_uri[:redirect_uri.rfind('/')]
-            return True
-        elif code == '408':
-            print '[ERROR] WeChat login timeout .'
-        else:
-            print '[ERROR] WeChat login exception .'
-        return False
+        return code, data
+
+    def wait4login(self):
+        '''
+        http comet:
+        tip=1, the request wait for user to scan the qr, 
+               201: scaned
+               408: timeout
+        tip=0, the request wait for user confirm, 
+               200: confirmed
+        '''
+        LOGIN_TEMPLATE = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s'
+        tip = 1
+
+        try_later_secs = 1
+        MAX_RETRY_TIMES = 10
+        
+        code = UNKONWN
+        
+        retry_time = MAX_RETRY_TIMES
+        while retry_time > 0:
+            url = LOGIN_TEMPLATE % (tip, self.uuid, int(time.time()))
+            code, data = self.do_request(url)
+            if code == SCANED:
+                print '[INFO] Please confirm to login .'
+                tip = 0
+            elif code == SUCCESS: #confirmed sucess
+                param = re.search(r'window.redirect_uri="(\S+?)";', data)
+                redirect_uri = param.group(1) + '&fun=new'
+                self.redirect_uri = redirect_uri
+                self.base_uri = redirect_uri[:redirect_uri.rfind('/')]
+                return code
+            elif code == TIMEOUT:
+                print '[ERROR] WeChat login timeout. retry in %s secs later...'%(try_later_secs, )
+
+                tip = 1 #need to reset tip, because the server will reset the peer connection
+                retry_time -= 1
+                time.sleep(try_later_secs)
+            else:
+                print ('[ERROR] WeChat login exception return_code=%s. retry in %s secs later...' % 
+                        (code, try_later_secs))
+                tip = 1
+                retry_time -= 1
+                time.sleep(try_later_secs)
+            
+        return code
 
     def login(self):
         if len(self.redirect_uri) < 4: