diff --git a/Sources/pyOpenRPA/Tools/RobotDB/ExcelCom.py b/Sources/pyOpenRPA/Tools/RobotDB/ExcelCom.py new file mode 100644 index 00000000..41bf0ea6 --- /dev/null +++ b/Sources/pyOpenRPA/Tools/RobotDB/ExcelCom.py @@ -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) \ No newline at end of file diff --git a/Sources/pyOpenRPA/Tools/RobotDB/HowToUse b/Sources/pyOpenRPA/Tools/RobotDB/HowToUse index c2b5e516..c77ebd23 100644 --- a/Sources/pyOpenRPA/Tools/RobotDB/HowToUse +++ b/Sources/pyOpenRPA/Tools/RobotDB/HowToUse @@ -14,10 +14,6 @@ $(document).ready(function() { success: null, dataType: "html" }); - - -SQLInsert - data: [{"TableName":"",RowDict:{"Key1":Value1, "Key2":Value2}}] $(document).ready(function() { @@ -25,9 +21,42 @@ $(document).ready(function() { $("#myid").addClass("highlight"); $.ajax({ type: "POST", - url: "http://localhost:81/", + url: "http://localhost:8081/", data: '[{"TableName":"Test", "RowDict":{"Name":"Name1","Description":"DescTest", "Money":100, "Date":"01.01.2020"}}]', success: null, dataType: "html" }); -}); \ No newline at end of file +}); + + + +/SQLInsert +POST + + +Result: json +{ + "Status":"OK"|"ERROR", #General status (OK or Error in general alg) + "ErrorMessage":"", #Error message if Status = ERROR + "Result":[ + { + "Status":"OK"|"ERROR", #Row status (OK or Error in current insert) + "ErrorMessage":"", #Error message if Status = ERROR + }, + {} + ] +} + +/SQLExportXLS.xlsx +POST +Args: { + "XLSTemplatePath":"C:\\Path\\To\\XLS template.xlsx", + "XLSSheetName":"SheetName", + "OffsetRow": 2, + "OffsetCol":1, + "XLSResultPath": "C:\\Path\\To\\XLS Result.xlsx", + "XLSResultFlagSendInResponse": true, + "XLSResultFlagDeleteAfterSend": true +} + +Result: xls file \ No newline at end of file diff --git a/Sources/pyOpenRPA/Tools/RobotDB/ServerSettings.py b/Sources/pyOpenRPA/Tools/RobotDB/ServerSettings.py index 3c533528..3620dd75 100644 --- a/Sources/pyOpenRPA/Tools/RobotDB/ServerSettings.py +++ b/Sources/pyOpenRPA/Tools/RobotDB/ServerSettings.py @@ -1,59 +1,150 @@ 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 = {"FlagSQLInsert": False} - #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')) - ######################################## - print(lInputJSON) - import sqlite3 + 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'INSERT INTO {lRowItem["TableName"]} (%s) VALUES (%s)' % (columns, placeholders) - c.execute(query, my_dict) - # Save (commit) the changes - conn.commit() +# 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() - ######################################## - # Send message back to client - message = json.dumps(lResultJSON) - # Write content as utf-8 data - inResponseDict["Body"] = bytes(message, "utf8") - -def GetScreenshot(inRequest,inGlobalDict): - # Get Screenshot - def SaveScreenshot(inFilePath): - # grab fullscreen - # Save the entire virtual screen as a PNG - lScreenshot = getScreenAsImage() - lScreenshot.save('screenshot.png', format='png') - # lScreenshot = ScreenshotSecondScreen.grab_screen() - # save image file - # lScreenshot.save('screenshot.png') - # Сохранить файл на диск - SaveScreenshot("Screenshot.png") - lFileObject = open("Screenshot.png", "rb") - # Write content as utf-8 data - inRequest.OpenRPAResponseDict["Body"] = lFileObject.read() - # Закрыть файловый объект - lFileObject.close() + #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 @@ -70,8 +161,8 @@ def SettingsUpdate(inGlobalConfiguration): # "ResponseDefRequestGlobal": None #Function with str result #} #Orchestrator basic dependencies - {"Method":"POST", "URL": "/", "MatchType": "EqualCase", "ResponseDefRequestGlobal": SQLInsert, "ResponseContentType": "text/html"}, - {"Method":"GET", "URL": "/3rdParty/Semantic-UI-CSS-master/semantic.min.css", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.css"), "ResponseContentType": "text/css"} + {"Method":"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 \ No newline at end of file diff --git a/Sources/pyOpenRPA/__init__.py b/Sources/pyOpenRPA/__init__.py index eeeef317..1ce87e12 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.0.37' +__version__ = 'v1.0.38' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Utils/RobotDB/DB.db b/Utils/RobotDB/DB.db index e611941f..991a5252 100644 Binary files a/Utils/RobotDB/DB.db and b/Utils/RobotDB/DB.db differ diff --git a/Utils/RobotDB/SettingsExample.py b/Utils/RobotDB/SettingsExample.py index f8f5fd62..3a97df1b 100644 --- a/Utils/RobotDB/SettingsExample.py +++ b/Utils/RobotDB/SettingsExample.py @@ -14,16 +14,16 @@ def Settings(): }, "Server": { "ListenPort_": "Порт, по которому можно подключиться к демону", - "ListenPort": 81, + "ListenPort": 8081, "ListenURLList": [ { "Description": "Local machine test", "URL_": "Сетевое расположение сервера демона", - "URL": "http://127.0.0.1:81" + "URL": "http://127.0.0.1:8081" } ], "AccessUsers": { #Default - all URL is blocked - "FlagCredentialsAsk": True, #Turn on Authentication + "FlagCredentialsAsk": False, #Turn on Authentication "RuleDomainUserDict": { #("DOMAIN", "USER"): { !!!!!only in upper case!!!! # "MethodMatchURLBeforeList": [ diff --git a/Utils/RobotDB/Test.xlsx b/Utils/RobotDB/Test.xlsx new file mode 100644 index 00000000..857e0e24 Binary files /dev/null and b/Utils/RobotDB/Test.xlsx differ diff --git a/v1.0.37 b/v1.0.38 similarity index 100% rename from v1.0.37 rename to v1.0.38