Commit ecd5fdec authored by Zeyu DONG's avatar Zeyu DONG
Browse files

rearrange Exception

parent 2f01ffcf
Loading
Loading
Loading
Loading
+48 −57
Original line number Diff line number Diff line
@@ -6,11 +6,14 @@ import os
import re
import sys
import traceback
from time import sleep

import requests

from time import sleep
from bs4 import BeautifulSoup

from urllib3.exceptions import ResponseError
from requests.exceptions import ConnectionError

logging.basicConfig(
    format="[%(asctime)s.%(msecs)03d] - %(levelname)s - %(message)s",
    datefmt='%Y/%b/%d %H:%M:%S',
@@ -20,11 +23,6 @@ logging.getLogger('requests').setLevel(logging.WARNING)

login = requests.session()

CONNECTED = 10001
CONNECTION_TIMEOUT = 10002
NEED_LOGIN = 10003


def load_config():
   with open('./config.json') as f:
      config = json.load(f)
@@ -60,24 +58,13 @@ def do_login(url, username, password):


def test_network(url):
   try:
   with login.get(url, timeout=10, allow_redirects=False) as test:
      if 300 > test.status_code >= 200:
             return CONNECTED, None
         return None
      elif test.status_code == 302:
             content = login.get(test.headers['Location'], timeout=10).content
             soup_login = BeautifulSoup(content, 'html5lib')
             if 'CAS' not in soup_login.title.string:
                logging.warning('Not connected to a SUSTC network')
                return CONNECTED, None
             else:
                return NEED_LOGIN, re.search(r'window\.location = \'(.*)\';', soup_login.text).group(1)
         return test.headers['Location']
      else:
             logging.warning('Recieved status code {code}, consider updating \'captive_portal_server\''.format(code=test.status_code))
             return CONNECTION_TIMEOUT, None
   except requests.RequestException:
       return CONNECTION_TIMEOUT, None

         raise ResponseError("Invalid status code {code}".format(code=test.status_code))

def main():
   logging.info('Program started.')
@@ -86,50 +73,54 @@ def main():
      os.chdir(os.path.dirname(sys.argv[0]))  # To read config in the same directory
   except OSError:
      pass
   
   config = load_config()
   times_retry_login = config['max_times_retry_login']
   test_url = config['captive_portal_server']
   logging.info('Configurations successfully imported.')
   
   while True:
   while times_retry_login >= 0:
      logging.info('Checking network status...')
      status, rem_link = test_network(test_url)
      if status == CONNECTION_TIMEOUT:
         logging.info('Connection FAILED. Try again in ' + str(config['interval_retry_connection']) + ' sec.')
         times_retry_login -= 1
      elif status == CONNECTED:
      try:
         link = test_network(test_url)
         if not link:
            logging.info('You are already logged in.')
         break
      elif status == NEED_LOGIN:
            return
         else:
            content = login.get(link, timeout=10).content
            soup_login = BeautifulSoup(content, 'html5lib')
            
            if 'CAS' not in soup_login.title.string:
               logging.warning('Not connected to a SUSTC network')
               return
            
            logging.info('You are offline. Starting login...')
            
            rem_link = re.search(r'window\.location = \'(.*)\';', soup_login.text).group(1)
            hostname = 'http://enet.10000.gd.cn:10001/sz/sz112/'
         url = hostname + rem_link
            service = hostname + rem_link

         success, err = do_login(url, config['username'], config['password'])
            success, err = do_login(service, config['username'], config['password'])

            if err:
            times_retry_login -= 1
               logging.error('Error occurred: ' + err.text)
               times_retry_login -= 1
            elif success:
               logging.info('Login successful')
            break
               return
      except ConnectionError as err:
         logging.warn('Connection FAILED. Try again in ' + str(config['interval_retry_connection']) + ' sec.')
         times_retry_login -= 1

      if times_retry_login > 0:
      # If keep trying to login too many times, it may trigger security alarm on the CAS server
      logging.info('Try again in {time} sec. {attempt} attempt(s) remaining.'.format(time=config['interval_retry_connection'], attempt=times_retry_login))
      else:
         logging.info('Attempts used up. The program will quit.')
         sys.exit(-1)
      sleep(config['interval_retry_connection'])
   
   logging.info('Online.')
   sys.exit(0)
   logging.error('Attempts used up. The program will quit.')


if __name__ == '__main__':
   try:
      main()
   except ResponseError as err:
      logging.error('{msg}, consider updating \'captive_portal_server\''.format(msg=str(err)))
   except Exception as e:
      logging.error("".join(traceback.format_exc()))