def get_ready_data(): ''' 登录前获取记住的账号信息以便自动填写 :return: ''' try: data = {} if flask_utils.is_local_server: if Conf.get('USER', 'account'): data['account'] = Conf.get('USER', 'account') data['password'] = Conf.get('USER', 'password') data['remember_pass'] = Conf.get('USER', 'remember_pass') data['auto_login'] = Conf.get('USER', 'auto_login') return {'content': data} else: return {'content': 'not_ready'} else: if 'account' in session and request.cookies['account'] == session['account']: data['account'] = session['account'] data['password'] = session['password'] data['remember_pass'] = session['remember_pass'] data['auto_login'] = session['auto_login'] return {'content': data} else: return {'content': 'not_ready'} except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500)
def logout(): try: resp = Response(json.dumps({'content': '登出成功'}), mimetype='application/json', status=200) if flask_utils.is_local_server: # Conf.set('USER', 'account', '') # Conf.set('USER', 'password', '') # Conf.set('USER', 'dynamicPass', '') # Conf.set('USER', 'remember_pass', '') # Conf.set('USER', 'auto_login', 'false') Conf.set('USER', 'is_login', 'false') # session.pop('account', None) else: session.pop('account', None) session.pop('password', None) session.pop('dynamicPass', None) session.pop('remember_pass', None) session.pop('auto_login', None) resp.set_cookie('account', '') resp.headers.extend(flask_utils.Cross_Origin_Headers(request)) return resp except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500)
def need_set_vm_server(): if is_local_server: if (not Conf.get('SERVER', 'ip')) or (not Conf.get('SERVER', 'port')): abort(400,"请先设置服务器地址和端口") else: session.permanent = True # 关闭浏览器重新打开还保存session permanent_session_lifetime = timedelta(days=30) # session失效时间 if (not session['vm_server_host']) or (not session['vm_server_port']): abort(400,"请先设置服务器地址和端口")
def start_spice(configId = 0): data_dict = {} data_dict['account'] = Conf.get('USER', 'account') data_dict['password'] = Conf.get('USER', 'password') data_dict['mac'] = dev_info.get_mac_address() data_dict['systemType'] = dev_info.get_system_type()[0] #data_dict['systemName'] = dev_info.get_system_type()[1] data_dict['configId'] = configId response = requests.get('{0}{1}'.format(flask_utils.vm_server(), 'api/ServerSPICEConsole'), data_dict, verify=False) if response.status_code==200: content = json.loads(response.content.decode()) if content['status']== 'ACTIVE': return content raise Exception('status:%s,%s' % (content['status'],content['status_zh']))
def need_login(): pass if is_local_server: # if Conf.get('USER','account') and 'account' in session and session['account']==Conf.get('USER','account'): for item_str in dont_need_login_list: if not request.path.find(item_str,0,len(request.path))==-1: return if Conf.get('USER', 'account') and Conf.get('USER', 'is_login')=='true': need_set_vm_server() else: abort(401) else: if 'account' in session and request.cookies['account'] == session['account']: need_set_vm_server() else: abort(401)
def wifi_list(receiver, x_post=None, y_post=None): ''' 打开wifi窗口并返回该对象 :return: web_app ''' if not is_windows: web_app = htmlPy.WebAppGUI(title=u"Python Website", width=224, height=500, developer_mode=True) # 禁掉右键 if not Conf.get('BACKEND_SERVER', 'mode') == 'debug': web_app.right_click_setting(htmlPy.settings.DISABLE) # 获取中心点坐标 cp = QtGui.QDesktopWidget().availableGeometry().center() x, y = re.findall(r'\d+', str(cp)) # 修改窗口坐标 web_app.x_pos = int(x) * 2 - web_app.width - (20 if x_post == None else x_post) web_app.y_pos = int(y) * 2 - web_app.height - (40 if y_post == None else y_post) # 隐藏菜单栏 # web_app.window.setWindowFlags(QtCore.Qt.FramelessWindowHint) web_app.url = u"%s#/wifi" % base_url t = threading.Thread(target=close_message_listener_htmlpy, args=(receiver, web_app)) # 接收关闭信号并关闭窗口的线程 t.start() web_app.start() else: t = threading.Thread(target=close_message_listener, args=(receiver,)) # 接收关闭信号并关闭窗口的线程 t.start() uid = webview.create_window("wifi列表", "%s#/wifi" % base_url, width=224, height=500, ) return uid
def is_login(): ''' 登录前获取记住的账号信息以便自动填写 :return: ''' try: if Conf.get('USER','is_login')=='false': return {'content':False} else: return {'content':{ 'account':Conf.get('USER','account'), 'password': Conf.get('USER', 'password') }} except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500, '设置默认虚机失败')
def get_vm_server(): ''' 设置服务器 :return: ''' try: data = {} if flask_utils.is_local_server: data['vm_server_host'] = Conf.get('SERVER', 'ip') data['vm_server_port'] = Conf.get('SERVER', 'port') else: data['vm_server_host'] = session['vm_server_host'] data['vm_server_port'] = session['vm_server_port'] return data except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500)
def set_vm_server(): ''' 设置服务器 :return: ''' try: data = request.args if flask_utils.is_local_server: Conf.set('SERVER', 'ip', data['vm_server_host']) Conf.set('SERVER', 'port', data['vm_server_port']) else: session['vm_server_host'] = data['vm_server_host'] session['vm_server_port'] = data['vm_server_port'] return '设置默认虚机服务器成功' except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500)
def all(): ''' 打开ip窗口并返回该对象 :return: web_app ''' if not is_windows: # 生产模式 if not Conf.get('BACKEND_SERVER', 'mode') == 'debug': web_app = htmlPy.WebAppGUI(title=u"Python Website", width=1440, height=838, developer_mode=True, plugins=True) web_app.right_click_setting(htmlPy.settings.DISABLE) else: # debug模式 web_app = htmlPy.WebAppGUI(title=u"Python Website", width=1440, height=838, developer_mode=True, plugins=True) # # 获取中心点坐标 # cp = QtGui.QDesktopWidget().availableGeometry().center() # x, y = re.findall(r'\d+', str(cp)) # # 修改窗口坐标 # web_app.x_pos = int(x) - web_app.width / 2 # web_app.y_pos = int(y) - web_app.height / 2 # # 隐藏菜单栏 # web_app.window.setWindowFlags(QtCore.Qt.FramelessWindowHint) web_app.url = u"http://127.0.0.1:5082/#/login" # web_app.url = u"http://127.0.0.1:8080/#/" # web_app.url = u"https://cn.vuejs.org/v2/guide/components-props.html" # t = threading.Thread(target=close_message_listener_htmlpy, args=(receiver, web_app)) # 接收关闭信号并关闭窗口的线程 # t.start() web_app.start() else: # 生产模式 if not Conf.get('BACKEND_SERVER', 'mode') == 'debug': webview.create_window("bd_desk", "http://127.0.0.1:5082/#/login", debug=False, fullscreen=True) else: # debug模式 webview.create_window("bd_desk", "http://192.168.100.107:8080/#/login", width=1440, height=838, debug=True, fullscreen=False)
def link_vm(): ''' 需要数据 :return: ''' # 跨域和返回数据设置 data = request.args.to_dict() # 需要configId, vm_name current_app.logger.debug(data) try: vm_status_data = server.start_spice(data['configId']) current_app.logger.debug("vm_status_data: %s" % vm_status_data) console = vm_status_data['console'] if Conf.get('SERVER', 'ip') and Conf.get('SERVER', 'port'): vm_operate.spice_connect_vm( vm_operate.set_remote_viewer_argv(Conf.get('SERVER', 'ip'), Conf.get('SERVER', 'port'), Conf.get('USER', 'account'), Conf.get('USER', 'password'), console, data['vm_name'])) return {'content': 'success'} else: current_app.logger.error(os.path.abspath(__file__) + '还没设置ip和port') abort(400, '请先设置服务器ip和port') except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500)
def set_default_vm(): ''' 登录前获取记住的账号信息以便自动填写 :return: ''' try: data = request.args if flask_utils.is_local_server: Conf.set('VMS', 'default_vm', data['default_vm']) resp = Response('设置默认虚机成功', status=200) else: session['default_vm'] = data['default_vm'] resp = Response('设置默认虚机成功', status=200) resp.set_cookie('default_vm', data['default_vm'], 3600 * 24 * 30) resp.set_cookie('default_vm_name', data['default_vm_name'], 3600 * 24 * 30) resp.headers.extend(flask_utils.Cross_Origin_Headers(request)) return resp except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500, '设置默认虚机失败')
def create_locl_vm(): print('################## in thread') state = vclient.create(config_id, cpu, ram, image_id, os_type, image_size, volume_size, name, Conf.get('SERVER', 'ip'), Conf.get('SERVER', 'port'), Conf.get('USER', 'account'), Conf.get('USER', 'password'))['results']['state'] print('################## create in thread') # { # 'building': '虚机正在创建中', # 'downloading_image': '正在下载镜像', # 'download_completed': '下载镜像完成', # 'builded': '虚机已创建', # 'active': '虚机活动中,请切换到虚机', # 'shutdown': '虚机在关机状态', # 'error': '创建虚机出现错误', # } print('################## vm state:{0}'.format(state)) while True: time.sleep(2) vm_status = vclient.get_status(config_id) if vm_status['code'] == 0: if vm_status['results'] in ['builded', 'shutdown', 'active']: vclient.start(config_id) break else: pass else: abort(500, vm_action_status_map[vm_status['code']])
def get_current_mac(): ''' 当前连接虚机服务器的mac :return: ''' try: p = subprocess.Popen("ip route get {0}".format(Conf.get('SERVER', 'ip')), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdoutput, erroutput) = p.communicate() dev_name = re.findall(r'dev (.+?(?= )) ', stdoutput.decode())[0] p = subprocess.Popen("ip link show dev {0}".format(dev_name), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdoutput, erroutput) = p.communicate() current_mac = re.findall(r'link/ether (.+?(?= ))', stdoutput.decode())[0] return {'content': current_mac} except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500)
def all(): ''' 打开ip窗口并返回该对象 :return: web_app ''' # 生产模式 if not Conf.get('BACKEND_SERVER', 'mode') == 'debug': webview.create_window("bd_desk", "http://127.0.0.1:5082/#/login", debug=False, fullscreen=False) else: # debug模式 # webview.create_window("bd_desk", "http://127.0.0.1:5082/#/login", debug=False,fullscreen=False) webview.create_window("bd_desk", "http://192.168.100.110:8080/#/snapshot", width=1440, height=838, debug=True, fullscreen=False)
def get_or_post(api_route): try: path = api_route.replace('.', '/') if path == 'api/login': raise Exception('此方法不能用于登录') query_string = request.query_string.decode() if flask_utils.is_local_server: query_string = 'account={0}&password={1}&{2}'.format( Conf.get('USER', 'account'), Conf.get('USER', 'password'), query_string) else: query_string = 'account={0}&password={1}&{2}'.format( session['account'], session['password'], query_string) if request.method == 'GET': response = requests.get('{0}{1}?{2}'.format( flask_utils.vm_server(), path, query_string), verify=False) elif request.method == 'POST': response = requests.post('{0}{1}?{2}'.format( flask_utils.vm_server(), path, query_string), data=request.form.to_dict(), verify=False) else: raise Exception('目前只支持get和post两种方法') if response.status_code == 200: if path == 'api/EditPassword' and response.json( )['errorinfo'] == 'success': if flask_utils.is_local_server: Conf.set('USER', 'password', request.args['newPassword']) else: if flask_utils.is_local_server: Conf.set('USER', 'password', request.args['newPassword']) else: session['password'] = request.args['newPassword'] return json.loads(response.content.decode()) else: raise Exception(str(response.status_code)) except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) return {'content': e.message}, 500
#encoding:utf-8 import sys import requests from Utils.conf import Conf base_url = 'http://%s:%s/' % (Conf.get( 'BACKEND_SERVER', 'IP'), Conf.get('BACKEND_SERVER', 'PORT')) if __name__ == "__main__": if sys.argv[1] == 'ip': requests.post(base_url + 'open_ip_setting') elif sys.argv[1] == 'wifi': requests.post(base_url + (("open_wifi_list?x=%s&y=%s" % (sys.argv[2], sys.argv[3]) ) if len(sys.argv) > 2 else 'open_wifi_list')) elif sys.argv[1] == 'wifi_set': requests.post(base_url + 'open_wifi_setting') elif sys.argv[1] == 'screen_set': requests.post(base_url + 'open_screen_setting')
def login(): try: path = 'api/login' query_string = request.query_string.decode() response = requests.get('{0}/{1}?{2}'.format(flask_utils.vm_server(), path, query_string), verify=False) if not response.status_code == 200: raise Exception(str(response.status_code) + ':' + response.json()['errorinfo']) if response.json()['errorinfo'] == 'success': resp = Response(json.dumps({'content': response.json()['errorinfo']}), mimetype='application/json', status=200) if flask_utils.is_local_server: Conf.set('USER', 'account', request.args.to_dict()['account']) Conf.set('USER', 'password', request.args.to_dict()['password']) Conf.set('USER', 'dynamicPass', request.args.to_dict()['dynamicPass']) Conf.set('USER', 'remember_pass', request.args.to_dict()['remember_pass']) Conf.set('USER', 'auto_login', request.args.to_dict()['auto_login']) Conf.set('USER', 'is_login', 'true') # session.permanent=False # session['account'] = request.args.to_dict()['account'] else: session['account'] = request.args.to_dict()['account'] session['password'] = request.args.to_dict()['password'] session['dynamicPass'] = request.args.to_dict()['dynamicPass'] session['remember_pass'] = request.args.to_dict()['remember_pass'] session['auto_login'] = request.args.to_dict()['auto_login'] if request.args.to_dict()['remember_pass'] == 'false': resp.set_cookie('account', request.args.to_dict()['account']) if request.args.to_dict()['remember_pass'] == 'true': resp.set_cookie('account', request.args.to_dict()['account'], 3600 * 24 * 30) # 如果记住密码,则保存一个月 resp.headers.extend(flask_utils.Cross_Origin_Headers(request)) return resp else: abort(400,response.json()['errorinfo']) except HTTPException as e: raise e except Exception as e: current_app.logger.error(traceback.format_exc()) abort(500)
def get_ip_port_to_pool(): ''' 定时获取ip_port到备用池 :return: ''' try: lock = threading.Lock() def add_to_useful(ip_port, useful_list): try: logger.debug('测试ip_port:{0}'.format(ip_port['ip_with_port'])) is_useful = pickle.loads( fanqiang_service_client.run( Transformer().FanqiangService().test_useful_fanqiang( ip_port).done()).data) if is_useful: try: lock.acquire() logger.debug('{0}能用'.format(ip_port['ip_with_port'])) useful_list.append(ip_port) finally: lock.release() except Exception: logger.error(traceback.format_exc()) # 先读取存下来的pool with open('file/bak_pool', 'rb') as fr: try: cache.ip_port_pool = pickle.load(fr) logger.debug('从文件读到的数量为:{0}'.format(len(cache.ip_port_pool))) except EOFError: pass except Exception: logger.error(traceback.format_exc()) new_num = int(Conf.get('IP_PORT_POOL', 'new_num')) while True: useful_list = [] ## 开20个线程筛掉之前没用的ip_port(由于xmlrpc不支持并发,所以有问题) # q = queue.Queue() # tf = thread_utils.ThreadFactory() # for i in range(20): # t = threading.Thread(target=tf.queue_threads_worker, args=(q, add_to_useful)) # t.start() # tf.all_task_done = False # for ip_port in cache.ip_port_pool: # q.put({'ip_port': ip_port, 'useful_list': useful_list}) # q.join() # tf.all_task_done = True for ip_port in cache.ip_port_pool: logger.debug('测试ip_port:{0}'.format(ip_port['ip_with_port'])) is_useful = pickle.loads( fanqiang_service_client.run( Transformer().FanqiangService().test_useful_fanqiang( ip_port).done()).data) if is_useful: logger.debug('{0}能用'.format(ip_port['ip_with_port'])) useful_list.append(ip_port) cache.ip_port_pool = useful_list # 如果cache.ip_port_pool不及预期,获取能翻墙的ip_port if len(cache.ip_port_pool) < int( Conf.get('IP_PORT_POOL', 'bak_num')): new_num += 1 logger.debug('pool数量{0}达不到要求的{1}'.format( len(cache.ip_port_pool), Conf.get('IP_PORT_POOL', 'bak_num'))) ip_port_list = pickle.loads( fanqiang_service_client.run(Transformer().FanqiangService( ).get_useful_fanqiang_ip_port_from_mongo( new_num).done()).data) cache.ip_port_pool.extend(ip_port_list) # ------------去重------------ ip_port_map = {} for ip_port_dict in cache.ip_port_pool: ip_port_map[ip_port_dict['ip_with_port']] = ip_port_dict new_ip_list = [] for ip_port_dict in ip_port_map.values(): new_ip_list.append(ip_port_dict) cache.ip_port_pool = new_ip_list # ------------去重------------ else: new_num -= 1 # 把能用的写到文件里面 with open('file/bak_pool', 'wb') as fw: try: logger.debug('写到的数量为:{0}'.format(len(cache.ip_port_pool))) pickle.dump(cache.ip_port_pool, fw) except EOFError: pass except Exception: logger.error(traceback.format_exc()) # 每分钟检查一次 time.sleep(60) except Exception: logger.error(traceback.format_exc()) logger.error('get_ip_port_to_pool 线程错误关闭') get_ip_port_to_pool()
# self.queue.put(('debug',value)) # # @property # def info(self): # return # # @info.setter # def info(self,value): # self.queue.put(('info',value)) # # @property # def warning(self): # return # # @warning.setter # def warning(self,value): # self.queue.put(('warning',value)) # # @property # def error(self): # return # # @error.setter # def error(self,value): # self.queue.put(('error',value)) log_level = logging.DEBUG if Conf.get('DEFAULT', 'mode') == 'debug' else logging.ERROR logger = Log('log/server', log_level).logger # client_logger = Log('log/client',log_level).logger # 不知道为什么会和上面的logger重复
# Cross_Origin_Headers = { # "Access-Control-Allow-Credentials": "true", # 'Access-Control-Allow-Origin': 'http://127.0.0.1:8080', # # 'Access-Control-Allow-Origin': 'http://172.16.110.19:8080' # } def Cross_Origin_Headers(request): Origin_Header = request.headers.environ['HTTP_ORIGIN'] return { "Access-Control-Allow-Credentials": "true", 'Access-Control-Allow-Origin': Origin_Header, } backend_server_ip = Conf.get('BACKEND_SERVER', 'ip') # is_local_server = backend_server_ip=='127.0.0.1' or backend_server_ip=='localhost' #本地服务器就说明是盒子版 is_local_server = True def vm_server(): return 'https://{0}:{1}/'.format(Conf.get('SERVER', 'ip'), Conf.get('SERVER', 'port')) def need_set_vm_server(): if is_local_server: if (not Conf.get('SERVER', 'ip')) or (not Conf.get('SERVER', 'port')): abort(400,"请先设置服务器地址和端口") else: session.permanent = True # 关闭浏览器重新打开还保存session permanent_session_lifetime = timedelta(days=30) # session失效时间 if (not session['vm_server_host']) or (not session['vm_server_port']):
class SERVERS_FOR_CLIENT: DB = 'http://{0}:{1}'.format(Conf.get('DB', 'ip'), Conf.get('DB', 'port'))
from datetime import timedelta from app import windows from router import blueprints from flask import Flask, render_template, session, request, Response, abort, jsonify from Utils import log_utils from Utils import flask_utils from Utils.conf import Conf import logging from logging.handlers import RotatingFileHandler import multiprocessing # 初始化config.ini的某些配置 Conf.set('USER', 'is_login', 'false') app = Flask(__name__, static_folder='Front/dist/static', template_folder='Front/dist') app.secret_key = '123456' app.config.update( DEBUG=True if Conf.get('BACKEND_SERVER', 'mode') == 'debug' else False, # PERMANENT_SESSION_LIFETIME=timedelta(days=30), SESSION_PERMANENT=False, SESSION_COOKIE_PATH='/', # SESSION_COOKIE_NAME='ccw_test' ) # 解决jinja和vue的冲突 app.jinja_env.variable_start_string = '#{ '
def vm_server(): return 'https://{0}:{1}/'.format(Conf.get('SERVER', 'ip'), Conf.get('SERVER', 'port'))
count = len(text) if count < length: add = (length - count) # \0 backspace text = text + ('\0' * add) elif count > length: add = (length - (count % length)) text = text + ('\0' * add) self.ciphertext = cryptor.encrypt(text) # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题 # 所以这里统一把加密后的字符串转化为16进制字符串 return b2a_hex(self.ciphertext) # 解密后,去掉补足的空格用strip() 去掉 def decrypt(self, text): cryptor = AES.new(self.key, self.mode, b'0000000000000000') plain_text = cryptor.decrypt(a2b_hex(text)) return plain_text.rstrip('\0') bd_crypt = BdCrypt(Conf.get('BACKEND_SERVER','bd_key')) # 初始化密钥 if __name__ == '__main__': pc = BdCrypt(Conf.get('BACKEND_SERVER','bd_key')) # 初始化密钥 e = pc.encrypt('你麻痹') # 加密 d = pc.decrypt(e) # 解密 print("加密:", e) print("解密:", d)
class SERVERS_FOR_CLIENT: FanqiangService = 'http://{0}:{1}'.format( Conf.get('FanqiangService', 'ip'), Conf.get('FanqiangService', 'port'))