python清華大学ネットワークアシスタントの実現

20965 ワード

最終目標は以下の機能を達成したいと考えています.
  • (1)キャンパスネットワークへの登録
  • (2)キャンパスネットワークへの登録
  • (3)現在のネットワークステータスを問い合わせる
  • (4)トラフィック、勘定科目残高、現在のユーザー・グループなどの基本情報
  • (5)本口座の現在のオンラインIP情報を問い合わせる
  • (6)毎日のトラフィック使用明細を問合せ、ヒストグラム
  • を生成
    使用方法
    使用前に同級カタログの下にUSERNAME_PASSWORD.txtファイルでキャンパスネットワークのアカウントとパスワードを変更します.tunet.pyは外部コマンドに設定されています.パラメータは以下の通りです.-h,--help:ヘルプ-vを表示します.--version:現在の清華大学ネットワークアシスタントのバージョン番号を表示します.-u:ユーザー名を入力します.-p:パスワードを入力します.-a:後でユーザー名とパスワードを入力します.他のキャンパスネットワークアカウント-iにログインできます.--login:ネットワーク操作(他の操作がない場合は、デフォルトでネットワーク操作を行います)-o,--logout:ネットワーク切断操作-c,--check:現在のネットワーク状態-qをチェック、--query:トラフィック、アカウント残高、現在のユーザーグループなどの基本情報を照会し、本アカウントの現在のオンラインIP情報を照会し、毎日のトラフィック使用詳細を照会し、ヒストグラムを生成し、照会結果はUSER_DETAIL_INFOMATION.LOGに保存します.ファイルの下
    説明
    (1)USER_DETAIL_INFOMATION.LOGファイル最近の総合照会結果を保存(2)USERNAME_PASWORD.txtファイルユーザーのアカウントとパスワードを保存
    バージョンv 1.2更新内容
    (1)アカウントとパスワードを追加したファイル管理(2)性能調整(3)パラメータを持たない場合、デフォルトでキャンパスネットワークに接続し、入力を簡略化する
    3バージョンv 1.1更新内容:
    (1)総合検索機能を追加した:トラフィック、アカウント残高、現在のユーザーグループなどの基本情報を検索し、本アカウントの現在のオンラインIP情報を検索し、毎日のトラフィック使用明細を検索し、ヒストグラムを生成し、検索結果はUSER_DETAIL_INFOMATION.LOGファイルに保存する
    バージョンv 1.0更新内容:
    (1)基本的なネットワーク接続、ネットワーク切断、および現在のネットワークの状態を確認する操作を提供する
    QUERY
    import sys, time, os
    import urllib.request, hashlib, http.cookiejar
    import codecs, re
    
    query_login_url  = 'https://usereg.tsinghua.edu.cn/do.php'
    user_info_url    = 'https://usereg.tsinghua.edu.cn/user_info.php'
    online_state_url = 'https://usereg.tsinghua.edu.cn/online_user_ipv4.php'
    query_logout_url = 'https://usereg.tsinghua.edu.cn/do.php'
    
    info_header = [ '#' * 89,
                    '#\t\t\t\tUser Flux Detail Infomation\t\t\t\t#',
                    '#' * 89]
    
    #########################################################
    #                   File I/O Modules                    #
    #########################################################
    
    def create_path(relative_path):
        base_path = os.path.abspath(os.path.dirname(sys.argv[0]))
        return os.path.join(base_path, relative_path)
    
    def write_inline(file_handler, contents):
        for line in contents:
            file_handler.write(line + '\r
    ') def save_query(contents): relative_path = 'USER_DETAIL_INFOMATION.LOG' file_handler = open(create_path(relative_path), 'w') write_inline(file_handler, info_header) file_handler.write('\t\t\t\tDatetime: ' + time.strftime('%Y-%m-%d %H:%M:%S') + '\r
    ' + '-' * 89 + '\r
    ') write_inline(file_handler, contents) file_handler.write('\r
    ') file_handler.close() ######################################################### # Connection Modules # ######################################################### def create_opener(): cookie = http.cookiejar.CookieJar() cookie_proc = urllib.request.HTTPCookieProcessor(cookie) return urllib.request.build_opener(cookie_proc) def response_login(login_data): request_url = urllib.request.Request(query_login_url, login_data.encode()) response_url = urllib.request.urlopen(request_url) return response_url.read().decode() ######################################################### # Main Login/Logout Modules # ######################################################### def query_login(username, password): hashcd_md5 = hashlib.md5() hashcd_md5.update(password.encode()) tr_password = hashcd_md5.hexdigest() login_data = 'user_login_name=' + username + '&user_password=' + tr_password + '&action=login' urllib.request.install_opener(create_opener()) answer = response_login(login_data) if answer == 'ok': return True else: return False def query_logout(): logout_data = 'action=logout' request_url = urllib.request.Request(query_logout_url, logout_data.encode()) response_url = urllib.request.urlopen(request_url) print ('Your flux details and other infomations are saved in USER_DETAIL_INFOMATION.LOG under the SAME directory') ######################################################### # Data Post-Process Modules # ######################################################### def post_process(info): end_time = time.strftime('%Y-%m-%d') start_time = end_time[:8:] + '01' flux_detail_url = 'https://usereg.tsinghua.edu.cn/user_detail_list.php?action=balance2&user_login_name=&user_real_name=&desc=&order=&start_time=' + start_time + '&end_time=' + end_time + '&user_ip=&user_mac=&nas_ip=&nas_port=&is_ipv6=0&page=1&offset=200' response_usr = urllib.request.urlopen(user_info_url) response_state = urllib.request.urlopen(online_state_url) response_details = urllib.request.urlopen(flux_detail_url) info = flux_account_query(info, response_usr) info = online_state_query(info, response_state) info = flux_detail_query(info, response_details) return info ######################################################### # Integrated Query Modules # ######################################################### flux_account_keys = (' ', ' ', ' ', ' ', ' ', ' (IPV4)', ' (IPV4)', ' (IPV6)', ' (IPV6)', ' ') online_state_keys = () flux_detail_keys = () #Auxiliary Function def turn_key(key): if key[-5:-1] == 'byte': flux, unit = key.split('(') flux = float(flux) / 1024 / 1024 new_key = '-->' + str(int(flux)) + '(MB)' key += new_key return key def get_days(year, month): month_length = (31,28,31,30,31,30,31,31,30,31,30,31) month_length_leap = (31,29,31,30,31,30,31,31,30,31,30,31) if year % 400 == 0 or year % 100 != 0 and year % 4 == 0: return month_length_leap[month-1] else: return month_length[month-1] def solve_flux(flux): unit = flux[-1] val = float(flux[:len(flux)-1:]) if unit == 'B': val /= 1024 * 1024 elif unit == 'K': val /= 1024 elif unit == 'G': val *= 1024 return int(val) def trans_content(response): raw = response.read().decode('gb2312') raw = re.sub(']+>| |[
    \t]+|-->',' ',raw) raw = re.sub(' +', ' ', raw) return raw def push_front(figure, line): tf = [] tf.append(line) return tf + figure def display_fluxAccount_onlineState(info): print() for line in info: if line[0] != '-': print(line) else: print() def display_flux_detail(fluxin, year, month, day): maxflux = 0 divide = 10 figure = [] for flux in fluxin: if flux > maxflux: maxflux = flux top = str(int(maxflux)) + 'MB|' length = len(top) mid = str(int(maxflux / 2)) + 'MB|' mid = ' ' * (length - len(mid)) + mid bottom = '0MB|' bottom = ' ' * (length - len(bottom)) + bottom unit = maxflux / divide for i in range(day): fluxin[i] = int(fluxin[i] / unit) for i in range(divide): line = '' if i == divide - 1: line = top elif i == int((divide - 1) / 2): line = mid elif i == 0: line = bottom else: line = ' ' * (length - 1) + '|' for j in range(day): if fluxin[j] > 0: line += '**' fluxin[j] -= 1 else: line += ' ' figure = push_front(figure, line) figure = push_front(figure, '** **') figure.append(' ' * length + '--' * day) date_front = str(year) + '-' + str(month) +'-' + '1' date_rear = str(year) + '-' + str(month) +'-' + str(day) date_mid = str(year) + '-' + str(month) +'-' + '15' figure.append(' %s\t\t\t%s\t\t\t%s' %(date_front, date_mid, date_rear)) for line in figure: print(line) print() #Integrated Query def flux_account_query(info, response): info.append('** **') done = trans_content(response) match = re.search(' .*?( ) ', done) done = match.group() tlist = done.split(' ') line = '' for key in tlist: if line != '': key = turn_key(key) line = line + '\t: ' + key info.append(line) line = '' elif key in flux_account_keys: line = key info.append('-' * 89) return info def online_state_query(info, response): info.append('** **') done = trans_content(response) match = re.search('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*\d{2}:\d{2}', done) if match == None: info.append(' IP ') else: info.append(' IP \t \t ') done = match.group() tlist = done.split(' ') line = '' count = 0 for key in tlist: if count == 0: if re.search('\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}', key) != None: line = key count += 1 elif count == 1: if re.search('\d{4}-\d{2}-\d{2}', key) != None: line += '\t' + key count += 1 elif count == 2: if re.search('\d{2}:\d{2}:\d{2}', key) != None: line += '\t' + key info.append(line) line = '' count = 0 info.append('-' * 89) display_fluxAccount_onlineState(info); return info def flux_detail_query(info, response): info.append('** **') info.append(' \t \t ') done = trans_content(response) year, month = time.strftime('%Y %m').split(' ') days = get_days(int(year), int(month)) tlist = done.split(' ') fluxin_perday = [0 for i in range(days)] fluxout_perday = [0 for i in range(days)] offline_date = True count = 0 for key in tlist: if re.search('\d{4}-\d{2}-\d{2}', key) and offline_date: offline_date = False elif re.search('\d{4}-\d{2}-\d{2}', key) and not offline_date: offline_date = True year, month, day = key.split('-') iday = int(day) elif re.search('\d+[.]\d*[BKMG]', key) and count == 0: fluxin_perday[iday-1] += solve_flux(key) count += 1 elif re.search('\d+[.]\d*[BKMG]', key) and count == 1: fluxout_perday[iday-1] += solve_flux(key) count += 1 elif re.search('\d+[.]\d*[BKMG]', key) and count == 2: count = 0 for i in range(days): if i + 1 < 10: d = '0' + str(i + 1) else: d = str(i + 1) info.append('%s\t%s\t%s' %(time.strftime('%Y-%m-') + d, str(fluxin_perday[i]) + 'MB', str(fluxout_perday[i]) + 'MB')) display_flux_detail(fluxin_perday, int(year), int(month), days) return info ######################################################### # Main Part # ######################################################### def tunet_query(username, password): print('FETCHING DATA FROM http://usereg.tsinghua.edu.cn, PLEASE WAIT FOR A MOMENT...') is_login = query_login(username, password) if is_login: info = [] info = post_process(info) save_query(info) query_logout() else: print ('CAN\'T CAPTURE YOUR FLUX DATA, PLEASE TRY AGAIN LATER') def pytunet_query(): username = 'hhy14' password = '123456' tunet_query(username, password) if __name__ == '__main__': pytunet_query()

    CONNECT
    import time
    import urllib.request, hashlib
    import codecs
    
    login_url  = 'http://net.tsinghua.edu.cn/cgi-bin/do_login'
    logout_url = 'http://net.tsinghua.edu.cn/cgi-bin/do_logout'
    check_url  = 'http://net.tsinghua.edu.cn/cgi-bin/do_login'
    query_url  = 'https://usereg.tsinghua.edu.cn/login.php'
    
    times_cnt = {1: 'FIRST', 2: 'SECOND', 3: 'THIRD', 4: 'FORTH', 5: 'FIFTH'}
    ret_type  = {'logout_ok'       : 'LOGOUT SUCCESS',
                'not_online_error' : 'NOT ONLINE',
                'ip_exist_error'   : 'IP ALREADY EXISTS',
                'user_tab_error'   : 'THE CERTIFICATION PROGRAM WAS NOT STARTED',
                'username_error'   : 'WRONG USERNAME',
                'user_group_error' : 'ACCOUNT INFOMATION INCORRECT',
                'password_error'   : 'WRONG PASSWORD',
                'status_error'     : 'ACCOUNT OVERDUE, PLEASE RECHARGE',
                'available_error'  : 'ACCOUNT HAS BEEN SUSPENDED',
                'delete_error'     : 'ACCOUNT HAS BEEN DELETED',
                'usernum_error'    : 'USERS NUMBER LIMITED',
                'online_num_error' : 'USERS NUMBER LIMITED',
                'mode_error'       : 'DISABLE WEB REGISTRY',
                'time_policy_error': 'CURRENT TIME IS NOT ALLOWED TO CONNECT',
                'flux_error'       : 'FLUX OVER',
                'ip_error'         : 'IP NOT VALID',
                'mac_error'        : 'MAC NOT VALID',
                'sync_error'       : 'YOUR INFOMATION HAS BEEN MODIFIED, PLEASE TRY AGAIN AFTER 2 MINUTES',
                'ip_alloc'         : 'THE IP HAS BEEN ASSIGNED TO OTHER USER'
                }
    
    version  = '1.2'
    sleep_time = 8
    
    #########################################################
    #               Main Login/Logout Modules               #
    #########################################################
    
    def trans_content(response):
        content = response.read().decode()
        ret = ''
        for ch in content:
            if ch.isalpha() or ch == '_':
                ret += ch
        return ret
    
    def tunet_login(username, password):
        hashcd_md5 = hashlib.md5()
        hashcd_md5.update(password.encode())
        tr_password = hashcd_md5.hexdigest()
        login_data = 'username=' + username + '&password=' + tr_password + '&drop=0&type=1&n=100'
        login_data = login_data.encode()
        request_url = urllib.request.Request(login_url, login_data)
        response_url = urllib.request.urlopen(request_url)
        ret = trans_content(response_url)
        print (ret_type.get(ret, 'CONNECTED'))
        return ret
    
    def tunet_logout():
        response_url = urllib.request.urlopen(logout_url)
        ret = trans_content(response_url)
        print (ret_type.get(ret, 'CONNECTED'))
        return ret
    
    def tunet_check():
        check_data = 'action=check_online'
        check_data = check_data.encode()
        request_url = urllib.request.Request(check_url, check_data)
        response_url = urllib.request.urlopen(request_url)
        ret = trans_content(response_url)
        if ret == '':
            print ('NOT ONLINE')
        else:
            print (ret_type.get(ret, 'CONNECTED'))
        return ret
    
    #########################################################
    #                   Help&Version Modules                #
    #########################################################
    
    def tunet_help():
        print ('-h, --help   : show all options of Tsinghua University Internet Connector')
        print ('-v, --version: show version of Tsinghua University Internet Connector')
        print ('-u           : input your username after \'-u\'')
        print ('-p           : input your password after \'-p\'')
        print ('-a           : enter username and password later, you can login other campus network account')
        print ('-i, --login  : login operation')
        print ('-o, --logout : logout operation')
        print ('-c, --check  : check the internet')
        print ('-q, --query  : query basic infomation, online state and flux usage details')
    
    def tunet_version():
        print ('Tsinghua University Internet Connector ', version)
    
    def tunet_others():
        print ('UNKNOWN OPTIONS')
        print ('WHICH OPTION DO YOU WANT?')
        tunet_help()
        print ('IF ANY ERROR, PLEASE CONTACT [email protected].')
    
    #########################################################
    #                       Main Part                       #
    #########################################################
    
    def tunet_connect(username, password):
        ret = 'ip_exist_error'
        for count in range(5):
            print ('%s attempts to connect...' % times_cnt.get(count + 1))
            if ret != tunet_login(username, password):
                break
            if count == 4:
                print ('please try to reconnect after 1 minute')
                break
            print ('try to reconnect after %s seconds' %sleep_time)
            time.sleep(sleep_time)
            print ()
    

    PYTUNET
    #########################################################
    #                       Welcome                         #
    #   Tsinghua University Internet Connector in Python    #
    #                    Version: v1.2                      #
    #                   Date: 2015/04/05                    #
    #           By: Haoyu hu    Email: [email protected]       #
    #           Address: Tsinghua University                #
    #########################################################
    
    import pytunet_connect
    import pytunet_query
    import sys, getopt, getpass, os, re
    
    def pytunet():
        relative_path = 'USERNAME_PASSWORD.txt'
        file_handler = open(pytunet_query.create_path(relative_path), 'r')
        lines = file_handler.readlines()
        if len(lines) != 2:
            print('%s IS DAMAGED, PLEASE CHECK THE CONTENT FORMAT IN THE FILE:' %relative_path)
            print('CONTENT FORMAT AS FOLLOWS:')
            print('username=huhy14
    password=123456') exit(1) username = re.sub('\s', '', lines[0]) password = re.sub('\s', '', lines[1]) _, username = username.split('=') _, password = password.split('=') file_handler.close() try: options, args = getopt.getopt(sys.argv[1:], 'achiop:qu:v', ['help', 'login', 'logout', 'check', 'version', 'query']) except getopt.GetoptError: pytunet_connect.tunet_others() sys.exit(1) want_login = False want_query = False flag = False name, value = None, None for name, value in options: if name in ('-h', '--help'): pytunet_connect.tunet_help() sys.exit(0) elif name in ('-v', '--version'): pytunet_connect.tunet_version() sys.exit(0) elif name == '-a': flag = True elif name == '-u': username = value elif name == '-p': password = value elif name in ('-i', '--login'): want_login = True elif name in ('-o', '--logout'): pytunet_connect.tunet_logout() sys.exit(0) elif name in ('-c', '--check'): pytunet_connect.tunet_check() sys.exit(0) elif name in ('-q', '--query'): want_query = True if flag: username = input('username: ') password = getpass.getpass('password: ') print (password) if want_query: pytunet_query.tunet_query(username, password) if want_login or not want_query and not want_login: pytunet_connect.tunet_connect(username, password) # if not want_query and not want_login: # print ('WARNING: YOU JUST DIDN\'T DO ANYTHING! IF YOU WANT TO CONNECT TO THE CAMPUS NETWORK, THE COMMAND MUST INCLUDE -i OR --login') # print() # pytunet_connect.tunet_help() if __name__ == '__main__': pytunet()