from http.server import BaseHTTPRequestHandler, HTTPServer import pdb import pywinauto import json import subprocess import zlib import os import sys import traceback from . import RobotConnector from . import JSONNormalize from ..Tools import Usage import importlib #Единый глобальный словарь (За основу взять из Settings.py) global gSettingsDict #Call Settings function from argv[1] file ################################################ lSubmoduleFunctionName = "Settings" lFileFullPath = sys.argv[1] lModuleName = (lFileFullPath.split("\\")[-1])[0:-3] lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath) lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification) lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec) gSettingsDict = None if lSubmoduleFunctionName in dir(lTechModuleFromSpec): # Run SettingUpdate function in submodule gSettingsDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() ################################################# RobotConnector.mGlobalDict = gSettingsDict #Init the robot RobotConnector.UIDesktop.Utils.ProcessBitness.SettingsInit(gSettingsDict["ProcessBitness"]) from pyOpenRPA.Utils.Render import Render from pyOpenRPA.Tools import CrossOS # https://schedule.readthedocs.io/en/stable/examples.html lFileStr = CrossOS.PathJoinList(CrossOS.PathSplitList(__file__)[:-2] + ["Resources","Web","orpa","studio.xhtml"]) gRender = Render(inTemplatePathStr=lFileStr,inTemplateRefreshBool=True) from pyOpenRPA import __version__ # HTTP Studio web server class class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): #ResponseContentTypeFile def SendResponseContentTypeFile(self,inContentType,inFilePath): # Send response status code self.send_response(200) # Send headers self.send_header('Content-type',inContentType) self.end_headers() lFileObject = open(inFilePath, "rb") # Write content as utf-8 data self.wfile.write(lFileObject.read()) #Закрыть файловый объект lFileObject.close() # GET def do_GET(self): lStudioFolder = "\\".join(__file__.split("\\")[:-1]) #Мост между файлом и http запросом (новый формат) if self.path == "/": # Пример использования global gRender lStr = gRender.Generate(inDataDict={"title":"СТУДИЯ PYOPENRPA", "subtitle":"ПОИСК UIO СЕЛЕКТОРА", "version":__version__}) # Send response status code self.send_response(200) # Send headers self.send_header('Content-type','text/html') self.end_headers() # Write content as utf-8 data self.wfile.write(bytes(lStr, "utf8")) #Мост между файлом и http запросом (новый формат) if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.css")) #Мост между файлом и http запросом (новый формат) if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.js")) #Мост между файлом и http запросом (новый формат) if self.path == '/3rdParty/jQuery/jquery-3.1.1.min.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\jQuery\\jquery-3.1.1.min.js")) #Мост между файлом и http запросом (новый формат) if self.path == '/3rdParty/Google/LatoItalic.css': self.SendResponseContentTypeFile('font/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Google\\LatoItalic.css")) #Мост между файлом и http запросом (новый формат) if self.path == '/3rdParty/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.woff2': self.SendResponseContentTypeFile('font/woff2', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.woff2")) #Мост между файлом и http запросом (новый формат) if self.path == '/favicon.ico': self.SendResponseContentTypeFile('image/x-icon', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\favicon.ico")) #Мост между файлом и http запросом (новый формат) if self.path == '/pyOpenRPA_logo.png' or self.path == '/orpa/resources/Web/orpa/logo.png': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\logo.png")) #Мост между файлом и http запросом (новый формат) if self.path == '/pyOpenRPA_logo.png' or self.path == '/orpa/resources/Web/orpa/logo.png': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\logo.png")) if self.path == '/orpa/resources/Web/orpa/styleset/home.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\home.css")) if self.path == '/orpa/resources/Web/orpa/styleset/home.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\home.js")) if self.path == '/orpa/resources/Web/orpa/styleset/bg1.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg1.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg2.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg2.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg3.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg3.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg4.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg4.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg5.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg5.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg6.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg6.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg7.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg7.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg8.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg8.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg9.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg9.jpg")) if self.path == '/orpa/resources/Web/orpa/styleset/bg10.jpg': self.SendResponseContentTypeFile('image/png', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\bg10.jpg")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/site.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\site.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/reset.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\reset.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/container.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\container.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/grid.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\grid.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/header.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\header.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/image.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\image.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/divider.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\divider.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/menu.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\menu.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/dropdown.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\dropdown.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/segment.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\segment.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/button.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\button.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/list.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\list.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/sidebar.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\sidebar.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/icon.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\icon.css")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/components/transition.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\components\\transition.css")) if self.path == '/orpa/resources/Web/orpa/styleset/sidebar.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\sidebar.js")) if self.path == '/orpa/resources/Web/orpa/styleset/transition.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\transition.js")) if self.path == '/orpa/resources/Web/orpa/styleset/docs.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\docs.js")) if self.path == '/orpa/resources/Web/orpa/styleset/visibility.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\visibility.js")) if self.path == '/orpa/resources/Web/orpa/styleset/highlight.min.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\highlight.min.js")) if self.path == '/orpa/resources/Web/orpa/styleset/less.min.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\less.min.js")) if self.path == '/orpa/resources/Web/orpa/styleset/easing.min.js': self.SendResponseContentTypeFile('application/javascript', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\styleset\\easing.min.js")) if self.path == '/metadata.json': self.SendResponseContentTypeFile('application/json', os.path.join(lStudioFolder, "..\\Resources\\Web\\orpa\\\styleset\\metadata.json")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.woff2': self.SendResponseContentTypeFile('font/woff2', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.woff2")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.woff': self.SendResponseContentTypeFile('font/woff', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.woff")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.ttf': self.SendResponseContentTypeFile('font/ttf', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.ttf")) if self.path == '/orpa/resources/Web/Semantic-UI-CSS-master/semantic.min.css': self.SendResponseContentTypeFile('text/css', os.path.join(lStudioFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.css")) # POST def do_POST(self): #Restart studio if self.path == '/RestartStudio': #self.shutdown() # Send response status code self.send_response(200) # Send headers self.send_header('Content-type','application/json') self.end_headers() message = json.dumps({"Result":"Restart is in progress!"}) # Write content as utf-8 data self.wfile.write(bytes(message, "utf8")) os.execl(sys.executable,os.path.abspath(__file__),*sys.argv) sys.exit(0) if self.path == '/GUIAction': #Обернуть в try, чтобы вернуть ответ, что сообщение не может быть обработано # pdb.set_trace() # Send response status code self.send_response(200) # Send headers self.send_header('Content-type','application/json') self.end_headers() try: #ReadRequest lInputByteArrayLength = int(self.headers.get('Content-Length')) lInputByteArray=self.rfile.read(lInputByteArrayLength) #Превращение массива байт в объект lInputObject=json.loads(lInputByteArray.decode('utf8')) # Send message back to client #{'functionName':'', 'argsArray':[]} #pdb.set_trace() lRequestObject=lInputObject #Отправить команду роботу lResponseObject=RobotConnector.ActivityRun(lRequestObject) #Normalize JSON before send in response lResponseObject=JSONNormalize.JSONNormalizeDictList(lResponseObject) #Dump DICT LIST in JSON message = json.dumps(lResponseObject) except Exception as e: #Установить флаг ошибки lProcessResponse={"Result":None} lProcessResponse["ErrorFlag"]=True #Зафиксировать traceback lProcessResponse["ErrorTraceback"]=traceback.format_exc() #Зафиксировать Error message lProcessResponse["ErrorMessage"]=str(e) #lProcessResponse["ErrorArgs"]=str(e.args) message = json.dumps(lProcessResponse) finally: # Write content as utf-8 data self.wfile.write(bytes(message, "utf8")) if self.path == '/GUIActionList': #ReadRequest lInputByteArrayLength = int(self.headers.get('Content-Length')) lInputByteArray=self.rfile.read(lInputByteArrayLength) #Превращение массива байт в объект lInputObject=json.loads(lInputByteArray.decode('utf8')) # Send response status code self.send_response(200) # Send headers self.send_header('Content-type','application/json') self.end_headers() # Send message back to client #{'functionName':'', 'argsArray':[]} lRequestObject=lInputObject lOutputObject=[] #pdb.set_trace() lResponseObject=RobotConnector.ActivityListRun(lRequestObject) #Сформировать текстовый ответ message = json.dumps(lResponseObject) # Write content as utf-8 data self.wfile.write(bytes(message, "utf8")) return def run(): inServerAddress = ""; inPort = gSettingsDict["Server"]["ListenPort"]; # Server settings # Choose port 8080, for port 80, which is normally used for a http server, you need root access server_address = (inServerAddress, inPort) httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) # Logging gSettingsDict["Logger"].info(f"Сервер:: Прослушиваемый URL: {inServerAddress}, Прослушиваемый порт: {inPort}") # Запуск адреса в браузере os.system(f"explorer http://127.0.0.1:{str(inPort)}") Usage.Process(inComponentStr="Studio") httpd.serve_forever() run()