parent
9f411c5b93
commit
fb9d29e1a1
@ -1,6 +1,6 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: pyOpenRPA
|
||||
Version: 1.0.37
|
||||
Version: 1.0.39
|
||||
Summary: First open source RPA platform for business
|
||||
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
|
||||
Author: Ivan Maslov
|
@ -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,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
|
@ -1,6 +1,6 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: pyOpenRPA
|
||||
Version: 1.0.37
|
||||
Version: 1.0.39
|
||||
Summary: First open source RPA platform for business
|
||||
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
|
||||
Author: Ivan Maslov
|
@ -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,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
|
Loading…
Reference in new issue