#1.0.31 in pip

dev-linux
Ivan Maslov 5 years ago
parent 24f70a38bd
commit bdd32a6e6c

@ -1,3 +1,9 @@
iAccessible
iAccessible2
MSAA
MSAA
https://github.com/illinois-dres-aitg/pyia2/blob/master/test.py
https://github.com/NoSegfault/pyia2-1
https://www.google.com/search?sxsrf=ACYBGNTHavGimPvFykMMRIv0gPM1DNefvw%3A1574439051702&ei=iwjYXdm2KsaFmwXorJ3wDQ&q=iaccessible2+python&oq=iaccessible2+python&gs_l=psy-ab.3...4461.5554..5858...0.0..0.370.1801.0j2j2j3......0....1..gws-wiz.......0i203j0i30j0i5i30j33i160.2N55yQOH41U&ved=0ahUKEwiZqJbDmv7lAhXGwqYKHWhWB94Q4dUDCAs&uact=5
https://github.com/jongund/pyia2
https://docs.microsoft.com/en-us/windows/win32/winauto/window

@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.0.30
Version: 1.0.31
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov

@ -176,22 +176,24 @@
../../pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713
../../pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241
../../pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA-1.0.30.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.30.dist-info/METADATA,sha256=KAmO8WXVi9ZreWmoV3uXrFSx7dIlTj6s1CqsRxlSx74,3510
pyOpenRPA-1.0.30.dist-info/RECORD,,
pyOpenRPA-1.0.30.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.30.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=mlxsd8YMs9X_Een8HfOlCv5d_LVgcx21UAQphHFfD_M,6689
pyOpenRPA-1.0.31.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.31.dist-info/METADATA,sha256=iiWDhOSgM6Kq_7XjrbcApt66_WwWQugn522KbZpJQvI,3510
pyOpenRPA-1.0.31.dist-info/RECORD,,
pyOpenRPA-1.0.31.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.31.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iM-DZ7TU7o51pzIJYEkNIlVG_GzzaVUESi7Tu0Ppw8g,6717
pyOpenRPA/Orchestrator/Processor.py,sha256=GHXwC1B2py4mAtk9oZa-FVSJhx3no9oD2bvkj20uhNA,9051
pyOpenRPA/Orchestrator/Server.py,sha256=GH7P0L-83ONlRdVYu3oQqt2oCgXPXYjrcFb0tY_6SYU,12878
pyOpenRPA/Orchestrator/Server.py,sha256=TgKkqgMivzvh4cM4zpbDUdv9AXbUiPPy9uLjR1lTiJU,20229
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=ZrNEt_UoHYGOeAKN5X5jQHz-XNl1lBW47ttKUF8_cmM,4948
pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=JaHn6K7wXkK6K0qYrfcRjVQDhgWA8_qR_YzIqqDDp9w,31297
pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=jO3pjFWbmJEPQ2KroXSKYtXIesBq46PCBlKSouewODU,5430
pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124
pyOpenRPA/Orchestrator/__main__.py,sha256=mPUW2QcaefA0hWxUK8y2lk2MTuWeHl8yJW9ggGDYm44,131
pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144
pyOpenRPA/Orchestrator/__pycache__/Orchestrator.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/Processor.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/Server.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/ServerSettings.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/Timer.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/__main__.cpython-37.pyc,,
@ -427,5 +429,5 @@ pyOpenRPA/Tools/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=LSoBTiL4xkfYXS-cDG9oAR0vDCxouM2W_MKbqQiQMJ8,175
pyOpenRPA/__init__.py,sha256=qln-FbXTrYONhTRqswrXmDDj5hMxtWrjiOTBqKiE260,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -14,6 +14,7 @@ import logging
import copy
#from .Settings import Settings
import importlib
from importlib import util
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):

@ -9,27 +9,16 @@ import uuid
import datetime
import os #for path operations
from http import cookies
from desktopmagic.screengrab_win32 import (
getDisplayRects, saveScreenToBmp, saveRectToBmp, getScreenAsImage,
getRectAsImage, getDisplaysAsImages)
global mGlobalDict
def SaveScreenshot(inFilePath):
# grab fullscreen
# Save the entire virtual screen as a PNG
lScreenshot = getScreenAsImage()
lScreenshot.save('screenshot.png', format='png')
#lScreenshot = ScreenshotSecondScreen.grab_screen()
# save image file
#lScreenshot.save('screenshot.png')
from . import ServerSettings
#inGlobalDict
# "JSONConfigurationDict":<JSON>
class RobotDaemonServer(Thread):
def __init__(self,name,inGlobalDict):
Thread.__init__(self)
self.name = name
# Update the global dict
ServerSettings.SettingsUpdate(mGlobalDict)
def run(self):
inServerAddress="";
inPort = mGlobalDict["Server"]["ListenPort"];
@ -52,6 +41,8 @@ def AuthenticateVerify(inRequest):
######################################
#Way 1 - try to find AuthToken
lCookies = cookies.SimpleCookie(inRequest.headers.get("Cookie", ""))
inRequest.OpenRPA = {}
inRequest.OpenRPA["AuthToken"] = None
#pdb.set_trace()
if "AuthToken" in lCookies:
lCookieAuthToken = lCookies.get("AuthToken", "").value
@ -61,6 +52,8 @@ def AuthenticateVerify(inRequest):
#Auth Token Has Been Founded
lResult["Domain"] = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["Domain"]
lResult["User"] = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["User"]
#Set auth token
inRequest.OpenRPA["AuthToken"] = lCookieAuthToken
#Exit earlier
return lResult
######################################
@ -71,7 +64,7 @@ def AuthenticateVerify(inRequest):
":")
lUser = llHeaderAuthorizationDecodedUserPasswordList[0]
lPassword = llHeaderAuthorizationDecodedUserPasswordList[1]
lDomain = None
lDomain = ""
if "\\" in lUser:
lDomain = lUser.split("\\")[0]
lUser = lUser.split("\\")[1]
@ -95,8 +88,10 @@ def AuthenticateVerify(inRequest):
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now()
#Set-cookie
inRequest.OpenRPA={}
inRequest.OpenRPA["AuthToken"] = lAuthToken
inRequest.OpenRPASetCookie = {}
#New engine of server
inRequest.OpenRPAResponseDict["SetCookies"]["AuthToken"] = lAuthToken
#inRequest.OpenRPAResponse["Set-Cookie"]=[]lResult["Set-Cookie"] = lAuthToken
#pdb.set_trace()
#inRequest.send_header("Set-Cookie:", f"AuthToken={lAuthToken}")
@ -111,8 +106,156 @@ def AuthenticateBlock(inRequest):
inRequest.end_headers()
# Write content as utf-8 data
inRequest.wfile.write(bytes("", "utf8"))
#Check access before execute the action
#return bool True - go execute, False - dont execute
def UserAccessCheckBefore(inMethod, inRequest):
# Help def - Get access flag from dict
def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict):
if "FlagAccess" in inAccessRuleItem:
return inAccessRuleItem["FlagAccess"]
elif "FlagAccessDefRequestGlobalAuthenticate" in inAccessRuleItem:
return inAccessRuleItem["FlagAccessDefRequestGlobalAuthenticate"](inRequest, inGlobalDict,
inAuthenticateDict)
##########################################
inMethod=inMethod.upper()
#Prepare result false
lResult = False
lAuthToken = inRequest.OpenRPA["AuthToken"]
#go next if user is identified
lUserDict = None
if lAuthToken:
lUserDict = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]
#pdb.set_trace()
########################################
########################################
#Check general before rule (without User domain)
#Check rules
for lAccessRuleItem in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("RuleMethodMatchURLBeforeList", []):
#Go next execution if flag is false
if not lResult:
#Check if Method is identical
if lAccessRuleItem["Method"].upper() == inMethod:
#check Match type variant: BeginWith
if lAccessRuleItem["MatchType"].upper() == "BEGINWITH":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.startswith(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: Contains
elif lAccessRuleItem["MatchType"].upper() == "CONTAINS":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.contains(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: Equal
elif lAccessRuleItem["MatchType"].upper() == "EQUAL":
if lAccessRuleItem["URL"].upper() == inRequest.path.upper():
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: EqualCase
elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE":
if lAccessRuleItem["URL"] == inRequest.path:
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
#########################################
#########################################
#Do check if lResult is false
if not lResult:
#Check access by User Domain
#Check rules to find first appicable
#Check rules
for lAccessRuleItem in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("RuleDomainUserDict", {}).get((lUserDict["Domain"].upper(), lUserDict["User"].upper()), {}).get("MethodMatchURLBeforeList", []):
#Go next execution if flag is false
if not lResult:
#Check if Method is identical
if lAccessRuleItem["Method"].upper() == inMethod:
#check Match type variant: BeginWith
if lAccessRuleItem["MatchType"].upper() == "BEGINWITH":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.startswith(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
#check Match type variant: Contains
elif lAccessRuleItem["MatchType"].upper() == "CONTAINS":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.contains(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: Equal
elif lAccessRuleItem["MatchType"].upper() == "EQUAL":
if lAccessRuleItem["URL"].upper() == inRequest.path.upper():
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: EqualCase
elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE":
if lAccessRuleItem["URL"] == inRequest.path:
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
#####################################
#####################################
#Return lResult
return lResult
# HTTPRequestHandler class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#Tech def
#return {"headers":[],"body":"","statuscode":111}
def URLItemCheckDo(self, inURLItem, inMethod):
###############################
#Tech sub def - do item
################################
def URLItemDo(inURLItem,inRequest,inGlobalDict):
inResponseDict = inRequest.OpenRPAResponseDict
#Set status code 200
inResponseDict["StatusCode"] = 200
#Content-type
if "ResponseContentType" in inURLItem:
inResponseDict["Headers"]["Content-type"] = inURLItem["ResponseContentType"]
#If file path is set
if "ResponseFilePath" in inURLItem:
lFileObject = open(inURLItem["ResponseFilePath"], "rb")
# Write content as utf-8 data
inResponseDict["Body"] = lFileObject.read()
# Закрыть файловый объект
lFileObject.close()
#If function is set
if "ResponseDefRequestGlobal" in inURLItem:
inURLItem["ResponseDefRequestGlobal"](inRequest, inGlobalDict)
if "ResponseFolderPath" in inURLItem:
lRequestPath = inRequest.path
lFilePathSecondPart = lRequestPath.replace(inURLItem["URL"],"")
lFilePath = os.path.join(inURLItem["ResponseFolderPath"],lFilePathSecondPart)
#print(f"File full path {lFilePath}")
#Check if file exist
if os.path.exists(lFilePath) and os.path.isfile(lFilePath):
lFileObject = open(lFilePath, "rb")
# Write content as utf-8 data
inResponseDict["Body"] = lFileObject.read()
inResponseDict["ContentType"]= "application/octet-stream"
# Закрыть файловый объект
lFileObject.close()
##############################################
if inURLItem["Method"].upper() == inMethod.upper():
# check Match type variant: BeginWith
if inURLItem["MatchType"].upper() == "BEGINWITH":
lURLPath = self.path
lURLPath = lURLPath.upper()
if lURLPath.startswith(inURLItem["URL"].upper()):
URLItemDo(inURLItem, self, mGlobalDict)
return True
# check Match type variant: Contains
elif inURLItem["MatchType"].upper() == "CONTAINS":
lURLPath = self.path
lURLPath = lURLPath.upper()
if lURLPath.contains(inURLItem["URL"].upper()):
URLItemDo(inURLItem, self, mGlobalDict)
return True
# check Match type variant: Equal
elif inURLItem["MatchType"].upper() == "EQUAL":
if inURLItem["URL"].upper() == self.path.upper():
URLItemDo(inURLItem, self, mGlobalDict)
return True
# check Match type variant: EqualCase
elif inURLItem["MatchType"].upper() == "EQUALCASE":
if inURLItem["URL"] == self.path:
URLItemDo(inURLItem, self, mGlobalDict)
return True
return False
#ResponseContentTypeFile
def SendResponseContentTypeFile(self, inContentType, inFilePath):
# Send response status code
@ -120,16 +263,33 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Send headers
self.send_header('Content-type', inContentType)
#Check if var exist
if hasattr(self, "OpenRPA"):
if hasattr(self, "OpenRPASetCookie"):
self.send_header("Set-Cookie", f"AuthToken={self.OpenRPA['AuthToken']}")
self.end_headers()
lFileObject = open(inFilePath, "rb")
# Write content as utf-8 data
self.wfile.write(lFileObject.read())
#Закрыть файловый объект
lFileObject.close()
# GET
lFileObject.close()
# ResponseContentTypeFile
def ResponseDictSend(self):
inResponseDict = self.OpenRPAResponseDict
# Send response status code
self.send_response(inResponseDict["StatusCode"])
# Send headers
for lItemKey, lItemValue in inResponseDict["Headers"].items():
self.send_header(lItemKey, lItemValue)
# Send headers: Set-Cookie
for lItemKey, lItemValue in inResponseDict["SetCookies"].items():
self.send_header("Set-Cookie", f"{lItemKey}={lItemValue}")
#Close headers section in response
self.end_headers()
# Write content as utf-8 data
self.wfile.write(inResponseDict["Body"])
def do_GET(self):
# Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
@ -144,74 +304,54 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
AuthenticateBlock(self)
#####################################
else:
lOrchestratorFolder = "\\".join(__file__.split("\\")[:-1])
#Мост между файлом и http запросом (новый формат)
if self.path == "/":
self.SendResponseContentTypeFile('text/html', os.path.join(lOrchestratorFolder, "Web\\Index.xhtml"))
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.css':
self.SendResponseContentTypeFile('text/css', os.path.join(lOrchestratorFolder, "..\\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(lOrchestratorFolder, "..\\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(lOrchestratorFolder,"..\\Resources\\Web\\jQuery\\jquery-3.1.1.min.js"))
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Google/LatoItalic.css':
self.SendResponseContentTypeFile('font/css', os.path.join(lOrchestratorFolder, "..\\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(lOrchestratorFolder,"..\\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(lOrchestratorFolder, "Web\\favicon.ico"))
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Handlebars/handlebars-v4.1.2.js':
self.SendResponseContentTypeFile('application/javascript', os.path.join(lOrchestratorFolder,"..\\Resources\\Web\\Handlebars\\handlebars-v4.1.2.js"))
#Получить скриншот
if self.path.split("?")[0] == '/GetScreenshot':
#Сохранить файл на диск
SaveScreenshot("Screenshot.png")
self.SendResponseContentTypeFile('image/png',"Screenshot.png")
#Monitor
if self.path == '/Monitor/JSONDaemonListGet':
#Check the user access (if flag)
####################################
lFlagUserAccess = True
#If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("GET", self)
######################################
if lFlagUserAccess:
lOrchestratorFolder = "\\".join(__file__.split("\\")[:-1])
############################
#New server engine (url from global dict (URLList))
############################
for lURLItem in mGlobalDict["Server"]["URLList"]:
#Check if all condition are applied
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET")
if lFlagURLIsApplied:
#print("New engine")
self.ResponseDictSend()
return
#Monitor
if self.path == '/Monitor/JSONDaemonListGet':
# 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
message = json.dumps(mGlobalDict)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
#Filemanager function
if self.path.lower().startswith('/filemanager/'):
lFileURL=self.path[13:]
# check if file in FileURL - File Path Mapping Dict
if lFileURL.lower() in mGlobalDict["FileManager"]["FileURLFilePathDict"]:
self.SendResponseContentTypeFile('application/octet-stream',mGlobalDict["FileManager"]["FileURLFilePathDict"][lFileURL])
else:
#Set access denied code
# Send response status code
self.send_response(200)
self.send_response(403)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
message = json.dumps(mGlobalDict)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
if self.path == '/Monitor/ControlPanelDictGet':
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
#Create result JSON
lResultJSON={"RenderRobotList":[]}
lRenderFunctionsRobotList=mGlobalDict["ControlPanelDict"]["RobotList"]
for lItem in lRenderFunctionsRobotList:
#Выполнить вызов и записать результат
lItemResultDict=lItem["RenderFunction"](mGlobalDict)
#RunFunction
lResultJSON["RenderRobotList"].append(lItemResultDict)
# Send message back to client
message = json.dumps(lResultJSON)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
#Filemanager function
if self.path.lower().startswith('/filemanager/'):
lFileURL=self.path[13:]
# check if file in FileURL - File Path Mapping Dict
if lFileURL.lower() in mGlobalDict["FileManager"]["FileURLFilePathDict"]:
self.SendResponseContentTypeFile('application/octet-stream',mGlobalDict["FileManager"]["FileURLFilePathDict"][lFileURL])
# Auth function
# POST
def do_POST(self):
# Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
@ -226,22 +366,30 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
AuthenticateBlock(self)
#####################################
else:
#Централизованная функция получения запросов/отправки
if self.path == '/Utils/Processor':
#ReadRequest
lInputObject={}
if self.headers.get('Content-Length') is not None:
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
message = json.dumps(Processor.ActivityListOrDict(lInputObject))
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return
#Check the user access (if flag)
####################################
lFlagUserAccess = True
#If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("GET", self)
######################################
if lFlagUserAccess:
#Централизованная функция получения запросов/отправки
if self.path == '/Utils/Processor':
#ReadRequest
lInputObject={}
if self.headers.get('Content-Length') is not None:
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
message = json.dumps(Processor.ActivityListOrDict(lInputObject))
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return

@ -0,0 +1,67 @@
import json
#ControlPanelDict
from desktopmagic.screengrab_win32 import (
getDisplayRects, saveScreenToBmp, saveRectToBmp, getScreenAsImage,
getRectAsImage, getDisplaysAsImages)
def Monitor_ControlPanelDictGet(inRequest,inGlobalDict):
inResponseDict = inRequest.OpenRPAResponseDict
# Create result JSON
lResultJSON = {"RenderRobotList": []}
lRenderFunctionsRobotList = inGlobalDict["ControlPanelDict"]["RobotList"]
for lItem in lRenderFunctionsRobotList:
# Выполнить вызов и записать результат
lItemResultDict = lItem["RenderFunction"](inGlobalDict)
# RunFunction
lResultJSON["RenderRobotList"].append(lItemResultDict)
# Send message back to client
message = json.dumps(lResultJSON)
# Write content as utf-8 data
#print(bytes(message, "utf8"))
inResponseDict["Body"] = bytes(message, "utf8")
def GetScreenshot(inRequest,inGlobalDict):
# Get Screenshot
def SaveScreenshot(inFilePath):
# grab fullscreen
# Save the entire virtual screen as a PNG
lScreenshot = getScreenAsImage()
lScreenshot.save('screenshot.png', format='png')
# lScreenshot = ScreenshotSecondScreen.grab_screen()
# save image file
# lScreenshot.save('screenshot.png')
# Сохранить файл на диск
SaveScreenshot("Screenshot.png")
lFileObject = open("Screenshot.png", "rb")
# Write content as utf-8 data
inRequest.OpenRPAResponseDict["Body"] = lFileObject.read()
# Закрыть файловый объект
lFileObject.close()
def SettingsUpdate(inGlobalConfiguration):
import os
import pyOpenRPA.Orchestrator
lOrchestratorFolder = "\\".join(pyOpenRPA.Orchestrator.__file__.split("\\")[:-1])
lURLList = \
[ #List of available URLs with the orchestrator server
#{
# "Method":"GET|POST",
# "URL": "/index", #URL of the request
# "MatchType": "", #"BeginWith|Contains|Equal|EqualCase",
# "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "", #Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
#}
#Orchestrator basic dependencies
{"Method":"GET", "URL": "/", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "Web\\Index.xhtml"), "ResponseContentType": "text/html"},
{"Method":"GET", "URL": "/3rdParty/Semantic-UI-CSS-master/semantic.min.css", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.css"), "ResponseContentType": "text/css"},
{"Method":"GET", "URL": "/3rdParty/Semantic-UI-CSS-master/semantic.min.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.js"), "ResponseContentType": "application/javascript"},
{"Method":"GET", "URL": "/3rdParty/jQuery/jquery-3.1.1.min.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\jQuery\\jquery-3.1.1.min.js"), "ResponseContentType": "application/javascript"},
{"Method":"GET", "URL": "/3rdParty/Google/LatoItalic.css", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Google\\LatoItalic.css"), "ResponseContentType": "font/css"},
{"Method":"GET", "URL": "/3rdParty/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.woff2", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.woff2"), "ResponseContentType": "font/woff2"},
{"Method":"GET", "URL": "/favicon.ico", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "Web\\favicon.ico"), "ResponseContentType": "image/x-icon"},
{"Method":"GET", "URL": "/3rdParty/Handlebars/handlebars-v4.1.2.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Handlebars\\handlebars-v4.1.2.js"), "ResponseContentType": "application/javascript"},
{"Method": "GET", "URL": "/Monitor/ControlPanelDictGet", "MatchType": "Equal", "ResponseDefRequestGlobal": Monitor_ControlPanelDictGet, "ResponseContentType": "application/json"},
{"Method": "GET", "URL": "/GetScreenshot", "MatchType": "BeginWith", "ResponseDefRequestGlobal": GetScreenshot, "ResponseContentType": "image/png"}
]
inGlobalConfiguration["Server"]["URLList"]=inGlobalConfiguration["Server"]["URLList"]+lURLList
return inGlobalConfiguration

@ -1,4 +1,4 @@
import sys
lFolderPath = "\\".join(__file__.split("\\")[:-2])
sys.path.append(lFolderPath)
from Orchestrator import Orchestrator
lFolderPath = "\\".join(__file__.split("\\")[:-3])
sys.path.insert(0, lFolderPath)
from pyOpenRPA.Orchestrator import Orchestrator

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.0.30'
__version__ = 'v1.0.31'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.0.30
Version: 1.0.31
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov

@ -176,22 +176,24 @@
../../pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713
../../pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241
../../pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA-1.0.30.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.30.dist-info/METADATA,sha256=KAmO8WXVi9ZreWmoV3uXrFSx7dIlTj6s1CqsRxlSx74,3510
pyOpenRPA-1.0.30.dist-info/RECORD,,
pyOpenRPA-1.0.30.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.30.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=mlxsd8YMs9X_Een8HfOlCv5d_LVgcx21UAQphHFfD_M,6689
pyOpenRPA-1.0.31.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.31.dist-info/METADATA,sha256=iiWDhOSgM6Kq_7XjrbcApt66_WwWQugn522KbZpJQvI,3510
pyOpenRPA-1.0.31.dist-info/RECORD,,
pyOpenRPA-1.0.31.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.31.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iM-DZ7TU7o51pzIJYEkNIlVG_GzzaVUESi7Tu0Ppw8g,6717
pyOpenRPA/Orchestrator/Processor.py,sha256=GHXwC1B2py4mAtk9oZa-FVSJhx3no9oD2bvkj20uhNA,9051
pyOpenRPA/Orchestrator/Server.py,sha256=GH7P0L-83ONlRdVYu3oQqt2oCgXPXYjrcFb0tY_6SYU,12878
pyOpenRPA/Orchestrator/Server.py,sha256=TgKkqgMivzvh4cM4zpbDUdv9AXbUiPPy9uLjR1lTiJU,20229
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=ZrNEt_UoHYGOeAKN5X5jQHz-XNl1lBW47ttKUF8_cmM,4948
pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=JaHn6K7wXkK6K0qYrfcRjVQDhgWA8_qR_YzIqqDDp9w,31297
pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=jO3pjFWbmJEPQ2KroXSKYtXIesBq46PCBlKSouewODU,5430
pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124
pyOpenRPA/Orchestrator/__main__.py,sha256=mPUW2QcaefA0hWxUK8y2lk2MTuWeHl8yJW9ggGDYm44,131
pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144
pyOpenRPA/Orchestrator/__pycache__/Orchestrator.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/Processor.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/Server.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/ServerSettings.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/Timer.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/__main__.cpython-37.pyc,,
@ -427,5 +429,5 @@ pyOpenRPA/Tools/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=LSoBTiL4xkfYXS-cDG9oAR0vDCxouM2W_MKbqQiQMJ8,175
pyOpenRPA/__init__.py,sha256=qln-FbXTrYONhTRqswrXmDDj5hMxtWrjiOTBqKiE260,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -14,6 +14,7 @@ import logging
import copy
#from .Settings import Settings
import importlib
from importlib import util
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):

@ -9,27 +9,16 @@ import uuid
import datetime
import os #for path operations
from http import cookies
from desktopmagic.screengrab_win32 import (
getDisplayRects, saveScreenToBmp, saveRectToBmp, getScreenAsImage,
getRectAsImage, getDisplaysAsImages)
global mGlobalDict
def SaveScreenshot(inFilePath):
# grab fullscreen
# Save the entire virtual screen as a PNG
lScreenshot = getScreenAsImage()
lScreenshot.save('screenshot.png', format='png')
#lScreenshot = ScreenshotSecondScreen.grab_screen()
# save image file
#lScreenshot.save('screenshot.png')
from . import ServerSettings
#inGlobalDict
# "JSONConfigurationDict":<JSON>
class RobotDaemonServer(Thread):
def __init__(self,name,inGlobalDict):
Thread.__init__(self)
self.name = name
# Update the global dict
ServerSettings.SettingsUpdate(mGlobalDict)
def run(self):
inServerAddress="";
inPort = mGlobalDict["Server"]["ListenPort"];
@ -52,6 +41,8 @@ def AuthenticateVerify(inRequest):
######################################
#Way 1 - try to find AuthToken
lCookies = cookies.SimpleCookie(inRequest.headers.get("Cookie", ""))
inRequest.OpenRPA = {}
inRequest.OpenRPA["AuthToken"] = None
#pdb.set_trace()
if "AuthToken" in lCookies:
lCookieAuthToken = lCookies.get("AuthToken", "").value
@ -61,6 +52,8 @@ def AuthenticateVerify(inRequest):
#Auth Token Has Been Founded
lResult["Domain"] = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["Domain"]
lResult["User"] = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["User"]
#Set auth token
inRequest.OpenRPA["AuthToken"] = lCookieAuthToken
#Exit earlier
return lResult
######################################
@ -71,7 +64,7 @@ def AuthenticateVerify(inRequest):
":")
lUser = llHeaderAuthorizationDecodedUserPasswordList[0]
lPassword = llHeaderAuthorizationDecodedUserPasswordList[1]
lDomain = None
lDomain = ""
if "\\" in lUser:
lDomain = lUser.split("\\")[0]
lUser = lUser.split("\\")[1]
@ -95,8 +88,10 @@ def AuthenticateVerify(inRequest):
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now()
#Set-cookie
inRequest.OpenRPA={}
inRequest.OpenRPA["AuthToken"] = lAuthToken
inRequest.OpenRPASetCookie = {}
#New engine of server
inRequest.OpenRPAResponseDict["SetCookies"]["AuthToken"] = lAuthToken
#inRequest.OpenRPAResponse["Set-Cookie"]=[]lResult["Set-Cookie"] = lAuthToken
#pdb.set_trace()
#inRequest.send_header("Set-Cookie:", f"AuthToken={lAuthToken}")
@ -111,8 +106,156 @@ def AuthenticateBlock(inRequest):
inRequest.end_headers()
# Write content as utf-8 data
inRequest.wfile.write(bytes("", "utf8"))
#Check access before execute the action
#return bool True - go execute, False - dont execute
def UserAccessCheckBefore(inMethod, inRequest):
# Help def - Get access flag from dict
def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict):
if "FlagAccess" in inAccessRuleItem:
return inAccessRuleItem["FlagAccess"]
elif "FlagAccessDefRequestGlobalAuthenticate" in inAccessRuleItem:
return inAccessRuleItem["FlagAccessDefRequestGlobalAuthenticate"](inRequest, inGlobalDict,
inAuthenticateDict)
##########################################
inMethod=inMethod.upper()
#Prepare result false
lResult = False
lAuthToken = inRequest.OpenRPA["AuthToken"]
#go next if user is identified
lUserDict = None
if lAuthToken:
lUserDict = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]
#pdb.set_trace()
########################################
########################################
#Check general before rule (without User domain)
#Check rules
for lAccessRuleItem in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("RuleMethodMatchURLBeforeList", []):
#Go next execution if flag is false
if not lResult:
#Check if Method is identical
if lAccessRuleItem["Method"].upper() == inMethod:
#check Match type variant: BeginWith
if lAccessRuleItem["MatchType"].upper() == "BEGINWITH":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.startswith(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: Contains
elif lAccessRuleItem["MatchType"].upper() == "CONTAINS":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.contains(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: Equal
elif lAccessRuleItem["MatchType"].upper() == "EQUAL":
if lAccessRuleItem["URL"].upper() == inRequest.path.upper():
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: EqualCase
elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE":
if lAccessRuleItem["URL"] == inRequest.path:
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
#########################################
#########################################
#Do check if lResult is false
if not lResult:
#Check access by User Domain
#Check rules to find first appicable
#Check rules
for lAccessRuleItem in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("RuleDomainUserDict", {}).get((lUserDict["Domain"].upper(), lUserDict["User"].upper()), {}).get("MethodMatchURLBeforeList", []):
#Go next execution if flag is false
if not lResult:
#Check if Method is identical
if lAccessRuleItem["Method"].upper() == inMethod:
#check Match type variant: BeginWith
if lAccessRuleItem["MatchType"].upper() == "BEGINWITH":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.startswith(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
#check Match type variant: Contains
elif lAccessRuleItem["MatchType"].upper() == "CONTAINS":
lURLPath = inRequest.path
lURLPath = lURLPath.upper()
if lURLPath.contains(lAccessRuleItem["URL"].upper()):
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: Equal
elif lAccessRuleItem["MatchType"].upper() == "EQUAL":
if lAccessRuleItem["URL"].upper() == inRequest.path.upper():
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
# check Match type variant: EqualCase
elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE":
if lAccessRuleItem["URL"] == inRequest.path:
lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict)
#####################################
#####################################
#Return lResult
return lResult
# HTTPRequestHandler class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#Tech def
#return {"headers":[],"body":"","statuscode":111}
def URLItemCheckDo(self, inURLItem, inMethod):
###############################
#Tech sub def - do item
################################
def URLItemDo(inURLItem,inRequest,inGlobalDict):
inResponseDict = inRequest.OpenRPAResponseDict
#Set status code 200
inResponseDict["StatusCode"] = 200
#Content-type
if "ResponseContentType" in inURLItem:
inResponseDict["Headers"]["Content-type"] = inURLItem["ResponseContentType"]
#If file path is set
if "ResponseFilePath" in inURLItem:
lFileObject = open(inURLItem["ResponseFilePath"], "rb")
# Write content as utf-8 data
inResponseDict["Body"] = lFileObject.read()
# Закрыть файловый объект
lFileObject.close()
#If function is set
if "ResponseDefRequestGlobal" in inURLItem:
inURLItem["ResponseDefRequestGlobal"](inRequest, inGlobalDict)
if "ResponseFolderPath" in inURLItem:
lRequestPath = inRequest.path
lFilePathSecondPart = lRequestPath.replace(inURLItem["URL"],"")
lFilePath = os.path.join(inURLItem["ResponseFolderPath"],lFilePathSecondPart)
#print(f"File full path {lFilePath}")
#Check if file exist
if os.path.exists(lFilePath) and os.path.isfile(lFilePath):
lFileObject = open(lFilePath, "rb")
# Write content as utf-8 data
inResponseDict["Body"] = lFileObject.read()
inResponseDict["ContentType"]= "application/octet-stream"
# Закрыть файловый объект
lFileObject.close()
##############################################
if inURLItem["Method"].upper() == inMethod.upper():
# check Match type variant: BeginWith
if inURLItem["MatchType"].upper() == "BEGINWITH":
lURLPath = self.path
lURLPath = lURLPath.upper()
if lURLPath.startswith(inURLItem["URL"].upper()):
URLItemDo(inURLItem, self, mGlobalDict)
return True
# check Match type variant: Contains
elif inURLItem["MatchType"].upper() == "CONTAINS":
lURLPath = self.path
lURLPath = lURLPath.upper()
if lURLPath.contains(inURLItem["URL"].upper()):
URLItemDo(inURLItem, self, mGlobalDict)
return True
# check Match type variant: Equal
elif inURLItem["MatchType"].upper() == "EQUAL":
if inURLItem["URL"].upper() == self.path.upper():
URLItemDo(inURLItem, self, mGlobalDict)
return True
# check Match type variant: EqualCase
elif inURLItem["MatchType"].upper() == "EQUALCASE":
if inURLItem["URL"] == self.path:
URLItemDo(inURLItem, self, mGlobalDict)
return True
return False
#ResponseContentTypeFile
def SendResponseContentTypeFile(self, inContentType, inFilePath):
# Send response status code
@ -120,16 +263,33 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Send headers
self.send_header('Content-type', inContentType)
#Check if var exist
if hasattr(self, "OpenRPA"):
if hasattr(self, "OpenRPASetCookie"):
self.send_header("Set-Cookie", f"AuthToken={self.OpenRPA['AuthToken']}")
self.end_headers()
lFileObject = open(inFilePath, "rb")
# Write content as utf-8 data
self.wfile.write(lFileObject.read())
#Закрыть файловый объект
lFileObject.close()
# GET
lFileObject.close()
# ResponseContentTypeFile
def ResponseDictSend(self):
inResponseDict = self.OpenRPAResponseDict
# Send response status code
self.send_response(inResponseDict["StatusCode"])
# Send headers
for lItemKey, lItemValue in inResponseDict["Headers"].items():
self.send_header(lItemKey, lItemValue)
# Send headers: Set-Cookie
for lItemKey, lItemValue in inResponseDict["SetCookies"].items():
self.send_header("Set-Cookie", f"{lItemKey}={lItemValue}")
#Close headers section in response
self.end_headers()
# Write content as utf-8 data
self.wfile.write(inResponseDict["Body"])
def do_GET(self):
# Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
@ -144,74 +304,54 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
AuthenticateBlock(self)
#####################################
else:
lOrchestratorFolder = "\\".join(__file__.split("\\")[:-1])
#Мост между файлом и http запросом (новый формат)
if self.path == "/":
self.SendResponseContentTypeFile('text/html', os.path.join(lOrchestratorFolder, "Web\\Index.xhtml"))
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.css':
self.SendResponseContentTypeFile('text/css', os.path.join(lOrchestratorFolder, "..\\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(lOrchestratorFolder, "..\\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(lOrchestratorFolder,"..\\Resources\\Web\\jQuery\\jquery-3.1.1.min.js"))
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Google/LatoItalic.css':
self.SendResponseContentTypeFile('font/css', os.path.join(lOrchestratorFolder, "..\\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(lOrchestratorFolder,"..\\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(lOrchestratorFolder, "Web\\favicon.ico"))
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Handlebars/handlebars-v4.1.2.js':
self.SendResponseContentTypeFile('application/javascript', os.path.join(lOrchestratorFolder,"..\\Resources\\Web\\Handlebars\\handlebars-v4.1.2.js"))
#Получить скриншот
if self.path.split("?")[0] == '/GetScreenshot':
#Сохранить файл на диск
SaveScreenshot("Screenshot.png")
self.SendResponseContentTypeFile('image/png',"Screenshot.png")
#Monitor
if self.path == '/Monitor/JSONDaemonListGet':
#Check the user access (if flag)
####################################
lFlagUserAccess = True
#If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("GET", self)
######################################
if lFlagUserAccess:
lOrchestratorFolder = "\\".join(__file__.split("\\")[:-1])
############################
#New server engine (url from global dict (URLList))
############################
for lURLItem in mGlobalDict["Server"]["URLList"]:
#Check if all condition are applied
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET")
if lFlagURLIsApplied:
#print("New engine")
self.ResponseDictSend()
return
#Monitor
if self.path == '/Monitor/JSONDaemonListGet':
# 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
message = json.dumps(mGlobalDict)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
#Filemanager function
if self.path.lower().startswith('/filemanager/'):
lFileURL=self.path[13:]
# check if file in FileURL - File Path Mapping Dict
if lFileURL.lower() in mGlobalDict["FileManager"]["FileURLFilePathDict"]:
self.SendResponseContentTypeFile('application/octet-stream',mGlobalDict["FileManager"]["FileURLFilePathDict"][lFileURL])
else:
#Set access denied code
# Send response status code
self.send_response(200)
self.send_response(403)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
message = json.dumps(mGlobalDict)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
if self.path == '/Monitor/ControlPanelDictGet':
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
#Create result JSON
lResultJSON={"RenderRobotList":[]}
lRenderFunctionsRobotList=mGlobalDict["ControlPanelDict"]["RobotList"]
for lItem in lRenderFunctionsRobotList:
#Выполнить вызов и записать результат
lItemResultDict=lItem["RenderFunction"](mGlobalDict)
#RunFunction
lResultJSON["RenderRobotList"].append(lItemResultDict)
# Send message back to client
message = json.dumps(lResultJSON)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
#Filemanager function
if self.path.lower().startswith('/filemanager/'):
lFileURL=self.path[13:]
# check if file in FileURL - File Path Mapping Dict
if lFileURL.lower() in mGlobalDict["FileManager"]["FileURLFilePathDict"]:
self.SendResponseContentTypeFile('application/octet-stream',mGlobalDict["FileManager"]["FileURLFilePathDict"][lFileURL])
# Auth function
# POST
def do_POST(self):
# Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
@ -226,22 +366,30 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
AuthenticateBlock(self)
#####################################
else:
#Централизованная функция получения запросов/отправки
if self.path == '/Utils/Processor':
#ReadRequest
lInputObject={}
if self.headers.get('Content-Length') is not None:
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
message = json.dumps(Processor.ActivityListOrDict(lInputObject))
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return
#Check the user access (if flag)
####################################
lFlagUserAccess = True
#If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("GET", self)
######################################
if lFlagUserAccess:
#Централизованная функция получения запросов/отправки
if self.path == '/Utils/Processor':
#ReadRequest
lInputObject={}
if self.headers.get('Content-Length') is not None:
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
message = json.dumps(Processor.ActivityListOrDict(lInputObject))
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return

@ -0,0 +1,67 @@
import json
#ControlPanelDict
from desktopmagic.screengrab_win32 import (
getDisplayRects, saveScreenToBmp, saveRectToBmp, getScreenAsImage,
getRectAsImage, getDisplaysAsImages)
def Monitor_ControlPanelDictGet(inRequest,inGlobalDict):
inResponseDict = inRequest.OpenRPAResponseDict
# Create result JSON
lResultJSON = {"RenderRobotList": []}
lRenderFunctionsRobotList = inGlobalDict["ControlPanelDict"]["RobotList"]
for lItem in lRenderFunctionsRobotList:
# Выполнить вызов и записать результат
lItemResultDict = lItem["RenderFunction"](inGlobalDict)
# RunFunction
lResultJSON["RenderRobotList"].append(lItemResultDict)
# Send message back to client
message = json.dumps(lResultJSON)
# Write content as utf-8 data
#print(bytes(message, "utf8"))
inResponseDict["Body"] = bytes(message, "utf8")
def GetScreenshot(inRequest,inGlobalDict):
# Get Screenshot
def SaveScreenshot(inFilePath):
# grab fullscreen
# Save the entire virtual screen as a PNG
lScreenshot = getScreenAsImage()
lScreenshot.save('screenshot.png', format='png')
# lScreenshot = ScreenshotSecondScreen.grab_screen()
# save image file
# lScreenshot.save('screenshot.png')
# Сохранить файл на диск
SaveScreenshot("Screenshot.png")
lFileObject = open("Screenshot.png", "rb")
# Write content as utf-8 data
inRequest.OpenRPAResponseDict["Body"] = lFileObject.read()
# Закрыть файловый объект
lFileObject.close()
def SettingsUpdate(inGlobalConfiguration):
import os
import pyOpenRPA.Orchestrator
lOrchestratorFolder = "\\".join(pyOpenRPA.Orchestrator.__file__.split("\\")[:-1])
lURLList = \
[ #List of available URLs with the orchestrator server
#{
# "Method":"GET|POST",
# "URL": "/index", #URL of the request
# "MatchType": "", #"BeginWith|Contains|Equal|EqualCase",
# "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "", #Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
#}
#Orchestrator basic dependencies
{"Method":"GET", "URL": "/", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "Web\\Index.xhtml"), "ResponseContentType": "text/html"},
{"Method":"GET", "URL": "/3rdParty/Semantic-UI-CSS-master/semantic.min.css", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.css"), "ResponseContentType": "text/css"},
{"Method":"GET", "URL": "/3rdParty/Semantic-UI-CSS-master/semantic.min.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.js"), "ResponseContentType": "application/javascript"},
{"Method":"GET", "URL": "/3rdParty/jQuery/jquery-3.1.1.min.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\jQuery\\jquery-3.1.1.min.js"), "ResponseContentType": "application/javascript"},
{"Method":"GET", "URL": "/3rdParty/Google/LatoItalic.css", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Google\\LatoItalic.css"), "ResponseContentType": "font/css"},
{"Method":"GET", "URL": "/3rdParty/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.woff2", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.woff2"), "ResponseContentType": "font/woff2"},
{"Method":"GET", "URL": "/favicon.ico", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "Web\\favicon.ico"), "ResponseContentType": "image/x-icon"},
{"Method":"GET", "URL": "/3rdParty/Handlebars/handlebars-v4.1.2.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Handlebars\\handlebars-v4.1.2.js"), "ResponseContentType": "application/javascript"},
{"Method": "GET", "URL": "/Monitor/ControlPanelDictGet", "MatchType": "Equal", "ResponseDefRequestGlobal": Monitor_ControlPanelDictGet, "ResponseContentType": "application/json"},
{"Method": "GET", "URL": "/GetScreenshot", "MatchType": "BeginWith", "ResponseDefRequestGlobal": GetScreenshot, "ResponseContentType": "image/png"}
]
inGlobalConfiguration["Server"]["URLList"]=inGlobalConfiguration["Server"]["URLList"]+lURLList
return inGlobalConfiguration

@ -1,4 +1,4 @@
import sys
lFolderPath = "\\".join(__file__.split("\\")[:-2])
sys.path.append(lFolderPath)
from Orchestrator import Orchestrator
lFolderPath = "\\".join(__file__.split("\\")[:-3])
sys.path.insert(0, lFolderPath)
from pyOpenRPA.Orchestrator import Orchestrator

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.0.30'
__version__ = 'v1.0.31'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.0.30
Version: 1.0.31
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov

@ -9,6 +9,7 @@ pyOpenRPA.egg-info/top_level.txt
pyOpenRPA/Orchestrator/Orchestrator.py
pyOpenRPA/Orchestrator/Processor.py
pyOpenRPA/Orchestrator/Server.py
pyOpenRPA/Orchestrator/ServerSettings.py
pyOpenRPA/Orchestrator/Timer.py
pyOpenRPA/Orchestrator/__init__.py
pyOpenRPA/Orchestrator/__main__.py

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.0.30'
__version__ = 'v1.0.31'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -1,4 +1,6 @@
Beta before 1.0.1 (new way of OpenRPA with improovments. Sorry, but no backward compatibility)/ Backward compatibility will start from 1.0.1
[1.0.31]
Orchestrator new engine - test 2 is ready. Go to PIP
[1.0.30]
RobotScreenActive - robot, which monitor the active screen and run Console session if screen disappear
[1.0.29]

Loading…
Cancel
Save