#UpgradePackageinPIP

dev-linux
Ivan Maslov 5 years ago
parent 9f411c5b93
commit fb9d29e1a1

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

@ -1,11 +1,11 @@
pyOpenRPA-1.0.37.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pyOpenRPA-1.0.39.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.37.dist-info/METADATA,sha256=NvEs1xItXmuAnPaTzTs5kDpr6NhwdD4_WyFwvG9UTLo,3510 pyOpenRPA-1.0.39.dist-info/METADATA,sha256=KSr_y71FFd5y4tYQHnz80Pj_96WCYKwWbW5eK0hd4KM,3510
pyOpenRPA-1.0.37.dist-info/RECORD,, pyOpenRPA-1.0.39.dist-info/RECORD,,
pyOpenRPA-1.0.37.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 pyOpenRPA-1.0.39.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.37.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 pyOpenRPA-1.0.39.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=UKp7eqvWDM91kYLwl2mo0UB8Pw-qu8eJCsR9NEXD1aU,6436 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=UKp7eqvWDM91kYLwl2mo0UB8Pw-qu8eJCsR9NEXD1aU,6436
pyOpenRPA/Orchestrator/Processor.py,sha256=HQQyOVX-d5vPO-YULyTxVOtXtUMfvpAaSVO4xXxaKVI,9107 pyOpenRPA/Orchestrator/Processor.py,sha256=kmGNIqe6AZMSrzCt1QlonEy58ecFeLunjo8AeRMsufU,11091
pyOpenRPA/Orchestrator/Server.py,sha256=aWDecl4_UUU00YG-pOXxyL7IvN5NK3efABt92y6M2kg,22136 pyOpenRPA/Orchestrator/Server.py,sha256=QQK1rMZSg-pL9pJ059AoxIHHj4aFr1OWivdOEKPh9cs,22026
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=jOXJTLwg8cJx6D-rN8J4dn5RCb2nepAhCH4F9hYVUdM,4912 pyOpenRPA/Orchestrator/ServerSettings.py,sha256=jOXJTLwg8cJx6D-rN8J4dn5RCb2nepAhCH4F9hYVUdM,4912
pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095 pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=su4tsDD_ZMbQz6Tbmqj55SM0ZZxuQw9tfPcytaB8wzs,32953 pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=su4tsDD_ZMbQz6Tbmqj55SM0ZZxuQw9tfPcytaB8wzs,32953
@ -195,7 +195,7 @@ pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,
pyOpenRPA/Robot/OrchestratorConnector.py,sha256=Fihxz-jH9M4VakXEE0SZ0Vo9tLEQk8Tcg_C4HoH45gI,20037 pyOpenRPA/Robot/OrchestratorConnector.py,sha256=Fihxz-jH9M4VakXEE0SZ0Vo9tLEQk8Tcg_C4HoH45gI,20037
pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453 pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453
pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878 pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878
pyOpenRPA/Robot/UIDesktop.py,sha256=MWdWr0dZpk1PL1rsD91q6_8v687CSDBx1_T7IuHd3-E,77473 pyOpenRPA/Robot/UIDesktop.py,sha256=3I2bllTDvR9d10O2ltkjoKmYw34wkkDAZfPlRpwbj30,77476
pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890 pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890
pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524 pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524
pyOpenRPA/Robot/Utils/ProcessCommunicator.py,sha256=8GfmLnOvAdosmt7YNT86uEV9cjhKippssCX62wOMJwM,8039 pyOpenRPA/Robot/Utils/ProcessCommunicator.py,sha256=8GfmLnOvAdosmt7YNT86uEV9cjhKippssCX62wOMJwM,8039
@ -235,6 +235,18 @@ pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/ExcelCom.py,sha256=hp0dvXOEC7Au00ueh7pqxkdixV-PC-km7tCt-wRunYs,343
pyOpenRPA/Tools/RobotDB/RobotDB.py,sha256=DZSb17fiCAYLdNVTLFJ7nTbQhk29PjzxE9OL6ydCDcI,1645
pyOpenRPA/Tools/RobotDB/Server.py,sha256=RO4Rj5-hmrRB41XKm4CrSFtauzKj3wNq4VmgcxhseeY,19838
pyOpenRPA/Tools/RobotDB/ServerSettings.py,sha256=5p9JwrpKHh68oVHIWazTajB6AOfzeapARbvGcJOFmNc,7406
pyOpenRPA/Tools/RobotDB/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124
pyOpenRPA/Tools/RobotDB/__main__.py,sha256=w9sXIF4r_PeWJjHJutTuH8DSYpXxpgcAN0KUOjiJ6PI,140
pyOpenRPA/Tools/RobotDB/__pycache__/ExcelCom.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/RobotDB.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/Server.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/ServerSettings.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=qU5SXwHgQU177MjqEHyOwJDLAcSVnIkKKw76iD09J1w,7275 pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=qU5SXwHgQU177MjqEHyOwJDLAcSVnIkKKw76iD09J1w,7275
pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=H7ciateTh-hml8z69EYZjYgqdTZGkDRtnFwuYnytrCw,3278 pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=H7ciateTh-hml8z69EYZjYgqdTZGkDRtnFwuYnytrCw,3278
pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392 pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392
@ -255,5 +267,5 @@ pyOpenRPA/Tools/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=32Po3gFALn9l6ft6LTFVJBkBj-1p5hP83AVcQ_FTa0s,175 pyOpenRPA/__init__.py,sha256=iZp06tUV8Mw7GGdUcuW_faV4YaQEJa_n5BqxOl0cwx8,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -7,6 +7,7 @@ import sys
import subprocess import subprocess
import copy import copy
import importlib import importlib
import psutil
#Input arg #Input arg
# [ # [
# { # {
@ -38,6 +39,13 @@ import importlib
# #
# }, # },
# { # {
# "Type":"ProcessStartIfTurnedOff",
# "CheckTaskName":"", #Check if current task name is not active (then start process),
# "Path":"",
# "ArgList":[]
#
# },
# {
# "Type":"ProcessStop", # "Type":"ProcessStop",
# "Name":"", # "Name":"",
# "FlagForce":True, # "FlagForce":True,
@ -71,6 +79,7 @@ def Activity(inActivity):
inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f")
#Alias (compatibility) #Alias (compatibility)
lItem = inActivity lItem = inActivity
lCurrentDateTime = datetime.datetime.now()
########################################################### ###########################################################
#Обработка запроса на отправку команды на удаленную машину #Обработка запроса на отправку команды на удаленную машину
########################################################### ###########################################################
@ -138,11 +147,33 @@ def Activity(inActivity):
#Вид активности - запуск процесса #Вид активности - запуск процесса
#Запись в массив отработанных активностей #Запись в массив отработанных активностей
#Лог #Лог
mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)}) mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)})
#Запустить процесс #Запустить процесс
lItemArgs=[lItem["processPath"]] lItemArgs=[lItem["Path"]]
lItemArgs.extend(lItem["processArgs"]) lItemArgs.extend(lItem["ArgList"])
subprocess.Popen(lItemArgs,shell=True) subprocess.Popen(lItemArgs,shell=True)
#####################################
#ProcessStartIfTurnedOff
#####################################
if lItem["Type"]=="ProcessStartIfTurnedOff":
#Check if process running
#remove .exe from Taskname if exists
lCheckTaskName = lItem["CheckTaskName"]
if len(lCheckTaskName)>4:
if lCheckTaskName[-4:].upper() != ".EXE":
lCheckTaskName = lCheckTaskName+".exe"
else:
lCheckTaskName = lCheckTaskName+".exe"
#Check if process exist
if not CheckIfProcessRunning(lCheckTaskName):
#Вид активности - запуск процесса
#Запись в массив отработанных активностей
#Лог
mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)})
#Запустить процесс
lItemArgs=[lItem["Path"]]
lItemArgs.extend(lItem["ArgList"])
subprocess.Popen(lItemArgs,shell=True)
################################# #################################
#ProcessStop #ProcessStop
################################# #################################
@ -150,7 +181,7 @@ def Activity(inActivity):
#Вид активности - остановка процесса #Вид активности - остановка процесса
#часовой пояс пока не учитываем #часовой пояс пока не учитываем
#Сформировать команду на завершение #Сформировать команду на завершение
lActivityCloseCommand='taskkill /im '+lItem["processName"] lActivityCloseCommand='taskkill /im '+lItem["Name"]
#TODO Сделать безопасную обработку,если параметра нет в конфигурации #TODO Сделать безопасную обработку,если параметра нет в конфигурации
if lItem.get('FlagForce',False): if lItem.get('FlagForce',False):
lActivityCloseCommand+=" /F" lActivityCloseCommand+=" /F"
@ -158,7 +189,7 @@ def Activity(inActivity):
if lItem.get('User',"")!="": if lItem.get('User',"")!="":
lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"' lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"'
#Лог #Лог
mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processName"], "activityStartDateTime":str(lCurrentDateTime)}) mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Name"], "activityStartDateTime":str(lCurrentDateTime)})
#Завершить процесс #Завершить процесс
os.system(lActivityCloseCommand) os.system(lActivityCloseCommand)
################################# #################################
@ -213,4 +244,18 @@ def ActivityListOrDict(inActivityListOrDict):
return lResult return lResult
if type(inActivityListOrDict)==dict: if type(inActivityListOrDict)==dict:
#Dict activity #Dict activity
return Activity(inActivityListOrDict) return Activity(inActivityListOrDict)
def CheckIfProcessRunning(processName):
'''
Check if there is any running process that contains the given name processName.
'''
#Iterate over the all the running process
for proc in psutil.process_iter():
try:
# Check if process name contains the given name string.
if processName.lower() in proc.name().lower():
return True
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
return False;

@ -425,8 +425,6 @@ class RobotDaemonServer(Thread):
#httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) #httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
# Logging # Logging
mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}") mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
# Запуск адреса в браузере
os.system("explorer http://127.0.0.1:8081")
#httpd.serve_forever() #httpd.serve_forever()
httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler) httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler)
#print('Starting server, use <Ctrl-C> to stop') #print('Starting server, use <Ctrl-C> to stop')

@ -1208,7 +1208,7 @@ def UIOSelector_Highlight(inUIOSelector):
UIO_Highlight(UIOSelector_Get_UIO(inUIOSelector)) UIO_Highlight(UIOSelector_Get_UIO(inUIOSelector))
else: else:
# Run function from other process with help of PIPE # Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool", lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Highlight",
"ArgumentList": [inUIOSelector], "ArgumentList": [inUIOSelector],
"ArgumentDict": {}} "ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами # Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
@ -1233,7 +1233,7 @@ def UIOSelector_FocusHighlight(inUIOSelector):
UIO_FocusHighlight(UIOSelector_Get_UIO(inUIOSelector)) UIO_FocusHighlight(UIOSelector_Get_UIO(inUIOSelector))
else: else:
# Run function from other process with help of PIPE # Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool", lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_FocusHighlight",
"ArgumentList": [inUIOSelector], "ArgumentList": [inUIOSelector],
"ArgumentDict": {}} "ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами # Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами

@ -0,0 +1,11 @@
import win32com.client as win32
def OpenWorkbook(xlapp, xlfile):
try:
xlwb = xlapp.Workbooks(xlfile)
except Exception as e:
try:
xlwb = xlapp.Workbooks.Open(xlfile)
except Exception as e:
print(e)
xlwb = None
return(xlwb)

@ -0,0 +1,41 @@
import subprocess
import json
import datetime
import time
import codecs
import os
import signal
import sys #Get input argument
import pdb
from . import Server
import logging
import copy
#from .Settings import Settings
import importlib
from importlib import util
#Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict
#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)
mGlobalDict = None
if lSubmoduleFunctionName in dir(lTechModuleFromSpec):
# Run SettingUpdate function in submodule
mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)()
#################################################
#mGlobalDict = Settings.Settings(sys.argv[1])
Server.mGlobalDict = mGlobalDict
#Инициализация настроечных параметров
lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonStartDateTime=datetime.datetime.now()
#Инициализация сервера
lThreadServer = Server.RobotDaemonServer("ServerThread", mGlobalDict)
lThreadServer.start()

@ -0,0 +1,395 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
import threading
import json
from threading import Thread
import importlib
import pdb
import base64
import uuid
import datetime
import os #for path operations
from http import cookies
global mGlobalDict
from . import ServerSettings
#Authenticate function ()
# return dict
# {
# "Domain": "", #Empty if Auth is not success
# "User": "" #Empty if Auth is not success
# }
def AuthenticateVerify(inRequest):
lResult={"Domain": "", "User": ""}
######################################
#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
if lCookieAuthToken:
#Find AuthToken in GlobalDict
if lCookieAuthToken in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("AuthTokensDict", {}):
#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
######################################
#Way 2 - try to logon
lHeaderAuthorization = inRequest.headers.get("Authorization", "").split(" ")
if len(lHeaderAuthorization) == 2:
llHeaderAuthorizationDecodedUserPasswordList = base64.b64decode(lHeaderAuthorization[1]).decode("utf-8").split(
":")
lUser = llHeaderAuthorizationDecodedUserPasswordList[0]
lPassword = llHeaderAuthorizationDecodedUserPasswordList[1]
lDomain = ""
if "\\" in lUser:
lDomain = lUser.split("\\")[0]
lUser = lUser.split("\\")[1]
#Try to logon - use processor
lLogonResult = Processor.Activity(
{
"Type": "WindowsLogon",
"Domain": lDomain,
"User": lUser,
"Password": lPassword
}
)
#Check result
if lLogonResult["Result"]:
lResult["Domain"] = lLogonResult["Domain"]
lResult["User"] = lLogonResult["User"]
#Create token
lAuthToken=str(uuid.uuid1())
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {}
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["FlagDoNotExpire"] = False
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now()
#Set-cookie
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}")
######################################
return lResult
def AuthenticateBlock(inRequest):
# Send response status code
inRequest.send_response(401)
# Send headers
inRequest.send_header('Content-type', 'text/html')
inRequest.send_header('WWW-Authenticate', 'Basic') # Always ask login pass
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
#pdb.set_trace()
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
self.send_response(200)
# Send headers
self.send_header('Content-type', inContentType)
#Check if var exist
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()
# 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": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
#####################################
lFlagAccessUserBlock=False
lAuthenticateDict = {"Domain": "", "User": ""}
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lAuthenticateDict = AuthenticateVerify(self)
if not lAuthenticateDict["User"]:
lFlagAccessUserBlock=True
# Logging
mGlobalDict["Logger"].info(f"HTTP request /. Domain: {lAuthenticateDict['Domain']}, User: {lAuthenticateDict['User']}")
if lFlagAccessUserBlock:
AuthenticateBlock(self)
#####################################
else:
#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:
self.ResponseDictSend()
return
else:
#Set access denied code
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
# POST
def do_POST(self):
# Prepare result dict
#pdb.set_trace()
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
#####################################
lFlagAccessUserBlock=False
lAuthenticateDict = {"Domain": "", "User": ""}
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lAuthenticateDict = AuthenticateVerify(self)
if not lAuthenticateDict["User"]:
lFlagAccessUserBlock=True
if lFlagAccessUserBlock:
AuthenticateBlock(self)
#####################################
else:
#Check the user access (if flag)
####################################
lFlagUserAccess = True
#If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("POST", 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, "POST")
if lFlagURLIsApplied:
self.ResponseDictSend()
return
return
else:
#Set access denied code
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
return
#Logging
#!Turn it on to stop print in console
#def log_message(self, format, *args):
# return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
def finish_request(self, request, client_address):
request.settimeout(30)
# "super" can not be used because BaseServer is not created from object
HTTPServer.finish_request(self, request, client_address)
#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"];
# 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
mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
#httpd.serve_forever()
httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler)
#print('Starting server, use <Ctrl-C> to stop')
httpd.serve_forever()

@ -0,0 +1,168 @@
import json
from . import ExcelCom
import os
import sqlite3
import win32com.client
import time
import pythoncom
#Insert in DB
def SQLInsert(inRequest,inGlobalDict):
inResponseDict = inRequest.OpenRPAResponseDict
# Create result JSON
lResultJSON = {"Status": "OK", "ErrorMessage":"", "Result":[]}
#Set status code 200
inResponseDict["StatusCode"] = 200
try:
#Read the body
#ReadRequest
lInputJSON={}
if inRequest.headers.get('Content-Length') is not None:
lInputByteArrayLength = int(inRequest.headers.get('Content-Length'))
lInputByteArray=inRequest.rfile.read(lInputByteArrayLength)
#print(lInputByteArray.decode('utf8'))
#Превращение массива байт в объект
lInputJSON=json.loads(lInputByteArray.decode('utf8'))
########################################
conn = sqlite3.connect(inGlobalDict["SQLite"]["DBPath"])
c = conn.cursor()
# Loop for rows
for lRowItem in lInputJSON:
lRowResult={"Status": "OK", "ErrorMessage":""}
try:
my_dict = lRowItem["RowDict"]
# Insert a row of data
columns = ', '.join(my_dict.keys())
placeholders = ':'+', :'.join(my_dict.keys())
query = f'INSERT INTO {lRowItem["TableName"]} (%s) VALUES (%s)' % (columns, placeholders)
c.execute(query, my_dict)
except Exception as e:
lRowResult["Status"]="ERROR"
lRowResult["ErrorMessage"]=str(e)
finally:
lResultJSON["Result"].append(lRowResult)
# Save (commit) the changes
conn.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()
except Exception as e:
lResultJSON["Status"]="ERROR"
lResultJSON["ErrorMessage"]=str(e)
finally:
########################################
# Send message back to client
message = json.dumps(lResultJSON)
print(message)
# Write content as utf-8 data
inResponseDict["Body"] = bytes(message, "utf8")
################################################
#Export SQLite to Excel
def SQLExportXLS(inRequest,inGlobalDict):
#Step 1 - read SQLite
conn = sqlite3.connect(inGlobalDict["SQLite"]["DBPath"])
c = conn.cursor()
# Loop for rows
# for lRowItem in lInputJSON:
# my_dict = lRowItem["RowDict"]
# # Insert a row of data
# columns = ', '.join(my_dict.keys())
# placeholders = ':'+', :'.join(my_dict.keys())
query = f'select * from Test'
#create data array
#row = range(0,10)
i = 0
data_array = []
for row in c.execute(query):
# use the cursor as an iterable
data_array.append(row)
i += 1
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()
#step 2 - insert in XLS
pythoncom.CoInitialize()
#write the array to an excel file
#excel = win32com.client.Dispatch("Excel.Application")
excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
excel.Visible = True
excel.DisplayAlerts = False
#excel.ScreenUpdating = False
#book = excel.Workbooks.Add()
#sheet = book.Worksheets(1)
#Read input JSON
lInputJSON={}
if inRequest.headers.get('Content-Length') is not None:
lInputByteArrayLength = int(inRequest.headers.get('Content-Length'))
lInputByteArray=inRequest.rfile.read(lInputByteArrayLength)
#print(lInputByteArray.decode('utf8'))
#Превращение массива байт в объект
lInputJSON=json.loads(lInputByteArray.decode('utf8'))
#Config
lOffsetRow = lInputJSON["OffsetRow"]
lOffsetCol = lInputJSON["OffsetCol"]
lXLSTemplatePath = lInputJSON["XLSTemplatePath"]
lXLSSheetName = lInputJSON["XLSSheetName"]
lXLSResultPath = lInputJSON["XLSResultPath"]
lXLSResultFlagSendInResponse = lInputJSON["XLSResultFlagSendInResponse"]
lXLSResultFlagDeleteAfterSend = lInputJSON["XLSResultFlagDeleteAfterSend"]
try:
#excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
book = ExcelCom.OpenWorkbook(excel, lXLSTemplatePath)
sheet = book.Worksheets(lXLSSheetName)
excel.Visible = True
#single loop, writing a row to a range
#Logic
start = time.time()
row = 0
for line in data_array:
row += 1
sheet.Range(sheet.Cells(row+lOffsetRow,1+lOffsetCol), sheet.Cells(row+lOffsetRow, len(line)+lOffsetCol)).Value = line
if lXLSResultPath:
book.SaveAs(Filename = lXLSResultPath)
#excel.ScreenUpdating = True
except Exception as e:
print(e)
finally:
# RELEASES RESOURCES
sheet = None
book = None
excel.DisplayAlerts = True
excel.Quit()
excel = None
pythoncom.CoUninitialize()
#####################
#Step 3 - Send file content to client
#####################
if lXLSResultFlagSendInResponse and lXLSResultPath:
lFileObject = open(lXLSResultPath, "rb")
# Write content as utf-8 data
inRequest.OpenRPAResponseDict["Body"] = lFileObject.read()
# Закрыть файловый объект
lFileObject.close()
#####################
#Step 4 - Delete after send
#####################
if lXLSResultFlagDeleteAfterSend and lXLSResultPath:
if os.path.exists(lXLSResultPath):
os.remove(lXLSResultPath)
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":"POST", "URL": "/SQLInsert", "MatchType": "EqualCase", "ResponseDefRequestGlobal": SQLInsert, "ResponseContentType": "application/json"},
{"Method":"POST", "URL": "/SQLExportXLS.xlsx", "MatchType": "EqualCase", "ResponseDefRequestGlobal": SQLExportXLS, "ResponseContentType": "application/octet-stream"}
]
inGlobalConfiguration["Server"]["URLList"]=inGlobalConfiguration["Server"]["URLList"]+lURLList
return inGlobalConfiguration

@ -0,0 +1,7 @@
r"""
The OpenRPA package (from UnicodeLabs)
"""
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'

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

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

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

@ -1,11 +1,11 @@
pyOpenRPA-1.0.37.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pyOpenRPA-1.0.39.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.37.dist-info/METADATA,sha256=NvEs1xItXmuAnPaTzTs5kDpr6NhwdD4_WyFwvG9UTLo,3510 pyOpenRPA-1.0.39.dist-info/METADATA,sha256=KSr_y71FFd5y4tYQHnz80Pj_96WCYKwWbW5eK0hd4KM,3510
pyOpenRPA-1.0.37.dist-info/RECORD,, pyOpenRPA-1.0.39.dist-info/RECORD,,
pyOpenRPA-1.0.37.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 pyOpenRPA-1.0.39.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.37.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 pyOpenRPA-1.0.39.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=UKp7eqvWDM91kYLwl2mo0UB8Pw-qu8eJCsR9NEXD1aU,6436 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=UKp7eqvWDM91kYLwl2mo0UB8Pw-qu8eJCsR9NEXD1aU,6436
pyOpenRPA/Orchestrator/Processor.py,sha256=HQQyOVX-d5vPO-YULyTxVOtXtUMfvpAaSVO4xXxaKVI,9107 pyOpenRPA/Orchestrator/Processor.py,sha256=kmGNIqe6AZMSrzCt1QlonEy58ecFeLunjo8AeRMsufU,11091
pyOpenRPA/Orchestrator/Server.py,sha256=aWDecl4_UUU00YG-pOXxyL7IvN5NK3efABt92y6M2kg,22136 pyOpenRPA/Orchestrator/Server.py,sha256=QQK1rMZSg-pL9pJ059AoxIHHj4aFr1OWivdOEKPh9cs,22026
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=jOXJTLwg8cJx6D-rN8J4dn5RCb2nepAhCH4F9hYVUdM,4912 pyOpenRPA/Orchestrator/ServerSettings.py,sha256=jOXJTLwg8cJx6D-rN8J4dn5RCb2nepAhCH4F9hYVUdM,4912
pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095 pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=su4tsDD_ZMbQz6Tbmqj55SM0ZZxuQw9tfPcytaB8wzs,32953 pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=su4tsDD_ZMbQz6Tbmqj55SM0ZZxuQw9tfPcytaB8wzs,32953
@ -195,7 +195,7 @@ pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,
pyOpenRPA/Robot/OrchestratorConnector.py,sha256=Fihxz-jH9M4VakXEE0SZ0Vo9tLEQk8Tcg_C4HoH45gI,20037 pyOpenRPA/Robot/OrchestratorConnector.py,sha256=Fihxz-jH9M4VakXEE0SZ0Vo9tLEQk8Tcg_C4HoH45gI,20037
pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453 pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453
pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878 pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878
pyOpenRPA/Robot/UIDesktop.py,sha256=MWdWr0dZpk1PL1rsD91q6_8v687CSDBx1_T7IuHd3-E,77473 pyOpenRPA/Robot/UIDesktop.py,sha256=3I2bllTDvR9d10O2ltkjoKmYw34wkkDAZfPlRpwbj30,77476
pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890 pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890
pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524 pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524
pyOpenRPA/Robot/Utils/ProcessCommunicator.py,sha256=8GfmLnOvAdosmt7YNT86uEV9cjhKippssCX62wOMJwM,8039 pyOpenRPA/Robot/Utils/ProcessCommunicator.py,sha256=8GfmLnOvAdosmt7YNT86uEV9cjhKippssCX62wOMJwM,8039
@ -235,6 +235,18 @@ pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/ExcelCom.py,sha256=hp0dvXOEC7Au00ueh7pqxkdixV-PC-km7tCt-wRunYs,343
pyOpenRPA/Tools/RobotDB/RobotDB.py,sha256=DZSb17fiCAYLdNVTLFJ7nTbQhk29PjzxE9OL6ydCDcI,1645
pyOpenRPA/Tools/RobotDB/Server.py,sha256=RO4Rj5-hmrRB41XKm4CrSFtauzKj3wNq4VmgcxhseeY,19838
pyOpenRPA/Tools/RobotDB/ServerSettings.py,sha256=5p9JwrpKHh68oVHIWazTajB6AOfzeapARbvGcJOFmNc,7406
pyOpenRPA/Tools/RobotDB/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124
pyOpenRPA/Tools/RobotDB/__main__.py,sha256=w9sXIF4r_PeWJjHJutTuH8DSYpXxpgcAN0KUOjiJ6PI,140
pyOpenRPA/Tools/RobotDB/__pycache__/ExcelCom.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/RobotDB.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/Server.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/ServerSettings.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotDB/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=qU5SXwHgQU177MjqEHyOwJDLAcSVnIkKKw76iD09J1w,7275 pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=qU5SXwHgQU177MjqEHyOwJDLAcSVnIkKKw76iD09J1w,7275
pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=H7ciateTh-hml8z69EYZjYgqdTZGkDRtnFwuYnytrCw,3278 pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=H7ciateTh-hml8z69EYZjYgqdTZGkDRtnFwuYnytrCw,3278
pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392 pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392
@ -255,5 +267,5 @@ pyOpenRPA/Tools/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=32Po3gFALn9l6ft6LTFVJBkBj-1p5hP83AVcQ_FTa0s,175 pyOpenRPA/__init__.py,sha256=iZp06tUV8Mw7GGdUcuW_faV4YaQEJa_n5BqxOl0cwx8,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -7,6 +7,7 @@ import sys
import subprocess import subprocess
import copy import copy
import importlib import importlib
import psutil
#Input arg #Input arg
# [ # [
# { # {
@ -38,6 +39,13 @@ import importlib
# #
# }, # },
# { # {
# "Type":"ProcessStartIfTurnedOff",
# "CheckTaskName":"", #Check if current task name is not active (then start process),
# "Path":"",
# "ArgList":[]
#
# },
# {
# "Type":"ProcessStop", # "Type":"ProcessStop",
# "Name":"", # "Name":"",
# "FlagForce":True, # "FlagForce":True,
@ -71,6 +79,7 @@ def Activity(inActivity):
inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f")
#Alias (compatibility) #Alias (compatibility)
lItem = inActivity lItem = inActivity
lCurrentDateTime = datetime.datetime.now()
########################################################### ###########################################################
#Обработка запроса на отправку команды на удаленную машину #Обработка запроса на отправку команды на удаленную машину
########################################################### ###########################################################
@ -138,11 +147,33 @@ def Activity(inActivity):
#Вид активности - запуск процесса #Вид активности - запуск процесса
#Запись в массив отработанных активностей #Запись в массив отработанных активностей
#Лог #Лог
mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)}) mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)})
#Запустить процесс #Запустить процесс
lItemArgs=[lItem["processPath"]] lItemArgs=[lItem["Path"]]
lItemArgs.extend(lItem["processArgs"]) lItemArgs.extend(lItem["ArgList"])
subprocess.Popen(lItemArgs,shell=True) subprocess.Popen(lItemArgs,shell=True)
#####################################
#ProcessStartIfTurnedOff
#####################################
if lItem["Type"]=="ProcessStartIfTurnedOff":
#Check if process running
#remove .exe from Taskname if exists
lCheckTaskName = lItem["CheckTaskName"]
if len(lCheckTaskName)>4:
if lCheckTaskName[-4:].upper() != ".EXE":
lCheckTaskName = lCheckTaskName+".exe"
else:
lCheckTaskName = lCheckTaskName+".exe"
#Check if process exist
if not CheckIfProcessRunning(lCheckTaskName):
#Вид активности - запуск процесса
#Запись в массив отработанных активностей
#Лог
mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)})
#Запустить процесс
lItemArgs=[lItem["Path"]]
lItemArgs.extend(lItem["ArgList"])
subprocess.Popen(lItemArgs,shell=True)
################################# #################################
#ProcessStop #ProcessStop
################################# #################################
@ -150,7 +181,7 @@ def Activity(inActivity):
#Вид активности - остановка процесса #Вид активности - остановка процесса
#часовой пояс пока не учитываем #часовой пояс пока не учитываем
#Сформировать команду на завершение #Сформировать команду на завершение
lActivityCloseCommand='taskkill /im '+lItem["processName"] lActivityCloseCommand='taskkill /im '+lItem["Name"]
#TODO Сделать безопасную обработку,если параметра нет в конфигурации #TODO Сделать безопасную обработку,если параметра нет в конфигурации
if lItem.get('FlagForce',False): if lItem.get('FlagForce',False):
lActivityCloseCommand+=" /F" lActivityCloseCommand+=" /F"
@ -158,7 +189,7 @@ def Activity(inActivity):
if lItem.get('User',"")!="": if lItem.get('User',"")!="":
lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"' lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"'
#Лог #Лог
mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processName"], "activityStartDateTime":str(lCurrentDateTime)}) mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Name"], "activityStartDateTime":str(lCurrentDateTime)})
#Завершить процесс #Завершить процесс
os.system(lActivityCloseCommand) os.system(lActivityCloseCommand)
################################# #################################
@ -213,4 +244,18 @@ def ActivityListOrDict(inActivityListOrDict):
return lResult return lResult
if type(inActivityListOrDict)==dict: if type(inActivityListOrDict)==dict:
#Dict activity #Dict activity
return Activity(inActivityListOrDict) return Activity(inActivityListOrDict)
def CheckIfProcessRunning(processName):
'''
Check if there is any running process that contains the given name processName.
'''
#Iterate over the all the running process
for proc in psutil.process_iter():
try:
# Check if process name contains the given name string.
if processName.lower() in proc.name().lower():
return True
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
return False;

@ -425,8 +425,6 @@ class RobotDaemonServer(Thread):
#httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) #httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
# Logging # Logging
mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}") mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
# Запуск адреса в браузере
os.system("explorer http://127.0.0.1:8081")
#httpd.serve_forever() #httpd.serve_forever()
httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler) httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler)
#print('Starting server, use <Ctrl-C> to stop') #print('Starting server, use <Ctrl-C> to stop')

@ -1208,7 +1208,7 @@ def UIOSelector_Highlight(inUIOSelector):
UIO_Highlight(UIOSelector_Get_UIO(inUIOSelector)) UIO_Highlight(UIOSelector_Get_UIO(inUIOSelector))
else: else:
# Run function from other process with help of PIPE # Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool", lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Highlight",
"ArgumentList": [inUIOSelector], "ArgumentList": [inUIOSelector],
"ArgumentDict": {}} "ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами # Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
@ -1233,7 +1233,7 @@ def UIOSelector_FocusHighlight(inUIOSelector):
UIO_FocusHighlight(UIOSelector_Get_UIO(inUIOSelector)) UIO_FocusHighlight(UIOSelector_Get_UIO(inUIOSelector))
else: else:
# Run function from other process with help of PIPE # Run function from other process with help of PIPE
lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool", lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_FocusHighlight",
"ArgumentList": [inUIOSelector], "ArgumentList": [inUIOSelector],
"ArgumentDict": {}} "ArgumentDict": {}}
# Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами # Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами

@ -0,0 +1,11 @@
import win32com.client as win32
def OpenWorkbook(xlapp, xlfile):
try:
xlwb = xlapp.Workbooks(xlfile)
except Exception as e:
try:
xlwb = xlapp.Workbooks.Open(xlfile)
except Exception as e:
print(e)
xlwb = None
return(xlwb)

@ -0,0 +1,41 @@
import subprocess
import json
import datetime
import time
import codecs
import os
import signal
import sys #Get input argument
import pdb
from . import Server
import logging
import copy
#from .Settings import Settings
import importlib
from importlib import util
#Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict
#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)
mGlobalDict = None
if lSubmoduleFunctionName in dir(lTechModuleFromSpec):
# Run SettingUpdate function in submodule
mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)()
#################################################
#mGlobalDict = Settings.Settings(sys.argv[1])
Server.mGlobalDict = mGlobalDict
#Инициализация настроечных параметров
lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonStartDateTime=datetime.datetime.now()
#Инициализация сервера
lThreadServer = Server.RobotDaemonServer("ServerThread", mGlobalDict)
lThreadServer.start()

@ -0,0 +1,395 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
import threading
import json
from threading import Thread
import importlib
import pdb
import base64
import uuid
import datetime
import os #for path operations
from http import cookies
global mGlobalDict
from . import ServerSettings
#Authenticate function ()
# return dict
# {
# "Domain": "", #Empty if Auth is not success
# "User": "" #Empty if Auth is not success
# }
def AuthenticateVerify(inRequest):
lResult={"Domain": "", "User": ""}
######################################
#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
if lCookieAuthToken:
#Find AuthToken in GlobalDict
if lCookieAuthToken in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("AuthTokensDict", {}):
#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
######################################
#Way 2 - try to logon
lHeaderAuthorization = inRequest.headers.get("Authorization", "").split(" ")
if len(lHeaderAuthorization) == 2:
llHeaderAuthorizationDecodedUserPasswordList = base64.b64decode(lHeaderAuthorization[1]).decode("utf-8").split(
":")
lUser = llHeaderAuthorizationDecodedUserPasswordList[0]
lPassword = llHeaderAuthorizationDecodedUserPasswordList[1]
lDomain = ""
if "\\" in lUser:
lDomain = lUser.split("\\")[0]
lUser = lUser.split("\\")[1]
#Try to logon - use processor
lLogonResult = Processor.Activity(
{
"Type": "WindowsLogon",
"Domain": lDomain,
"User": lUser,
"Password": lPassword
}
)
#Check result
if lLogonResult["Result"]:
lResult["Domain"] = lLogonResult["Domain"]
lResult["User"] = lLogonResult["User"]
#Create token
lAuthToken=str(uuid.uuid1())
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {}
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["FlagDoNotExpire"] = False
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now()
#Set-cookie
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}")
######################################
return lResult
def AuthenticateBlock(inRequest):
# Send response status code
inRequest.send_response(401)
# Send headers
inRequest.send_header('Content-type', 'text/html')
inRequest.send_header('WWW-Authenticate', 'Basic') # Always ask login pass
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
#pdb.set_trace()
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
self.send_response(200)
# Send headers
self.send_header('Content-type', inContentType)
#Check if var exist
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()
# 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": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
#####################################
lFlagAccessUserBlock=False
lAuthenticateDict = {"Domain": "", "User": ""}
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lAuthenticateDict = AuthenticateVerify(self)
if not lAuthenticateDict["User"]:
lFlagAccessUserBlock=True
# Logging
mGlobalDict["Logger"].info(f"HTTP request /. Domain: {lAuthenticateDict['Domain']}, User: {lAuthenticateDict['User']}")
if lFlagAccessUserBlock:
AuthenticateBlock(self)
#####################################
else:
#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:
self.ResponseDictSend()
return
else:
#Set access denied code
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
# POST
def do_POST(self):
# Prepare result dict
#pdb.set_trace()
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
#####################################
#Do authentication
#Check if authentication is turned on
#####################################
lFlagAccessUserBlock=False
lAuthenticateDict = {"Domain": "", "User": ""}
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lAuthenticateDict = AuthenticateVerify(self)
if not lAuthenticateDict["User"]:
lFlagAccessUserBlock=True
if lFlagAccessUserBlock:
AuthenticateBlock(self)
#####################################
else:
#Check the user access (if flag)
####################################
lFlagUserAccess = True
#If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("POST", 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, "POST")
if lFlagURLIsApplied:
self.ResponseDictSend()
return
return
else:
#Set access denied code
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
return
#Logging
#!Turn it on to stop print in console
#def log_message(self, format, *args):
# return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
def finish_request(self, request, client_address):
request.settimeout(30)
# "super" can not be used because BaseServer is not created from object
HTTPServer.finish_request(self, request, client_address)
#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"];
# 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
mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
#httpd.serve_forever()
httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler)
#print('Starting server, use <Ctrl-C> to stop')
httpd.serve_forever()

@ -0,0 +1,168 @@
import json
from . import ExcelCom
import os
import sqlite3
import win32com.client
import time
import pythoncom
#Insert in DB
def SQLInsert(inRequest,inGlobalDict):
inResponseDict = inRequest.OpenRPAResponseDict
# Create result JSON
lResultJSON = {"Status": "OK", "ErrorMessage":"", "Result":[]}
#Set status code 200
inResponseDict["StatusCode"] = 200
try:
#Read the body
#ReadRequest
lInputJSON={}
if inRequest.headers.get('Content-Length') is not None:
lInputByteArrayLength = int(inRequest.headers.get('Content-Length'))
lInputByteArray=inRequest.rfile.read(lInputByteArrayLength)
#print(lInputByteArray.decode('utf8'))
#Превращение массива байт в объект
lInputJSON=json.loads(lInputByteArray.decode('utf8'))
########################################
conn = sqlite3.connect(inGlobalDict["SQLite"]["DBPath"])
c = conn.cursor()
# Loop for rows
for lRowItem in lInputJSON:
lRowResult={"Status": "OK", "ErrorMessage":""}
try:
my_dict = lRowItem["RowDict"]
# Insert a row of data
columns = ', '.join(my_dict.keys())
placeholders = ':'+', :'.join(my_dict.keys())
query = f'INSERT INTO {lRowItem["TableName"]} (%s) VALUES (%s)' % (columns, placeholders)
c.execute(query, my_dict)
except Exception as e:
lRowResult["Status"]="ERROR"
lRowResult["ErrorMessage"]=str(e)
finally:
lResultJSON["Result"].append(lRowResult)
# Save (commit) the changes
conn.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()
except Exception as e:
lResultJSON["Status"]="ERROR"
lResultJSON["ErrorMessage"]=str(e)
finally:
########################################
# Send message back to client
message = json.dumps(lResultJSON)
print(message)
# Write content as utf-8 data
inResponseDict["Body"] = bytes(message, "utf8")
################################################
#Export SQLite to Excel
def SQLExportXLS(inRequest,inGlobalDict):
#Step 1 - read SQLite
conn = sqlite3.connect(inGlobalDict["SQLite"]["DBPath"])
c = conn.cursor()
# Loop for rows
# for lRowItem in lInputJSON:
# my_dict = lRowItem["RowDict"]
# # Insert a row of data
# columns = ', '.join(my_dict.keys())
# placeholders = ':'+', :'.join(my_dict.keys())
query = f'select * from Test'
#create data array
#row = range(0,10)
i = 0
data_array = []
for row in c.execute(query):
# use the cursor as an iterable
data_array.append(row)
i += 1
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()
#step 2 - insert in XLS
pythoncom.CoInitialize()
#write the array to an excel file
#excel = win32com.client.Dispatch("Excel.Application")
excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
excel.Visible = True
excel.DisplayAlerts = False
#excel.ScreenUpdating = False
#book = excel.Workbooks.Add()
#sheet = book.Worksheets(1)
#Read input JSON
lInputJSON={}
if inRequest.headers.get('Content-Length') is not None:
lInputByteArrayLength = int(inRequest.headers.get('Content-Length'))
lInputByteArray=inRequest.rfile.read(lInputByteArrayLength)
#print(lInputByteArray.decode('utf8'))
#Превращение массива байт в объект
lInputJSON=json.loads(lInputByteArray.decode('utf8'))
#Config
lOffsetRow = lInputJSON["OffsetRow"]
lOffsetCol = lInputJSON["OffsetCol"]
lXLSTemplatePath = lInputJSON["XLSTemplatePath"]
lXLSSheetName = lInputJSON["XLSSheetName"]
lXLSResultPath = lInputJSON["XLSResultPath"]
lXLSResultFlagSendInResponse = lInputJSON["XLSResultFlagSendInResponse"]
lXLSResultFlagDeleteAfterSend = lInputJSON["XLSResultFlagDeleteAfterSend"]
try:
#excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
book = ExcelCom.OpenWorkbook(excel, lXLSTemplatePath)
sheet = book.Worksheets(lXLSSheetName)
excel.Visible = True
#single loop, writing a row to a range
#Logic
start = time.time()
row = 0
for line in data_array:
row += 1
sheet.Range(sheet.Cells(row+lOffsetRow,1+lOffsetCol), sheet.Cells(row+lOffsetRow, len(line)+lOffsetCol)).Value = line
if lXLSResultPath:
book.SaveAs(Filename = lXLSResultPath)
#excel.ScreenUpdating = True
except Exception as e:
print(e)
finally:
# RELEASES RESOURCES
sheet = None
book = None
excel.DisplayAlerts = True
excel.Quit()
excel = None
pythoncom.CoUninitialize()
#####################
#Step 3 - Send file content to client
#####################
if lXLSResultFlagSendInResponse and lXLSResultPath:
lFileObject = open(lXLSResultPath, "rb")
# Write content as utf-8 data
inRequest.OpenRPAResponseDict["Body"] = lFileObject.read()
# Закрыть файловый объект
lFileObject.close()
#####################
#Step 4 - Delete after send
#####################
if lXLSResultFlagDeleteAfterSend and lXLSResultPath:
if os.path.exists(lXLSResultPath):
os.remove(lXLSResultPath)
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":"POST", "URL": "/SQLInsert", "MatchType": "EqualCase", "ResponseDefRequestGlobal": SQLInsert, "ResponseContentType": "application/json"},
{"Method":"POST", "URL": "/SQLExportXLS.xlsx", "MatchType": "EqualCase", "ResponseDefRequestGlobal": SQLExportXLS, "ResponseContentType": "application/octet-stream"}
]
inGlobalConfiguration["Server"]["URLList"]=inGlobalConfiguration["Server"]["URLList"]+lURLList
return inGlobalConfiguration

@ -0,0 +1,7 @@
r"""
The OpenRPA package (from UnicodeLabs)
"""
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'

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

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

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