diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA similarity index 99% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA index 88e2d1ef..b9dc232e 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.2 +Version: 1.1.3 Summary: First open source RPA platform for business Home-page: https://gitlab.com/UnicodeLabs/OpenRPA Author: Ivan Maslov diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD similarity index 95% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD index ab054615..0703f47b 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD @@ -1,8 +1,8 @@ -pyOpenRPA-1.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.2.dist-info/METADATA,sha256=i36JUYLUfNOz4jax1gu2KxREFioKKXo4g6oS6ZVo-n0,3541 -pyOpenRPA-1.1.2.dist-info/RECORD,, -pyOpenRPA-1.1.2.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.2.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.3.dist-info/METADATA,sha256=ObJb3J2niW85Wzoh8Uy_TC99RYMif_Ipn-QwE7NSv_8,3541 +pyOpenRPA-1.1.3.dist-info/RECORD,, +pyOpenRPA-1.1.3.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.3.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 pyOpenRPA/.idea/inspectionProfiles/profiles_settings.xml,sha256=YXLFmX7rPNGcnKK1uX1uKYPN0fpgskYNe7t0BV7cqkY,174 pyOpenRPA/.idea/misc.xml,sha256=ySjeaQ1DfqxaRTlFGT_3zW5r9mWuwxoAK_AX4QiuAZM,203 pyOpenRPA/.idea/modules.xml,sha256=Q__U1JIA2cjxbLRXAv-SfYY00fZA0TNlpkkbY4s3ncg,277 @@ -10,17 +10,14 @@ pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 -pyOpenRPA/Orchestrator/HowToUse.txt,sha256=ZcIgNvPUhzN0XFElqDirlm07fUb7QKLVjzvNrTk4a7k,148 -pyOpenRPA/Orchestrator/Orchestrator.py,sha256=0Q4VYZPdXV2qmLuowMWD_vERj1GQurQx_VFwfsxuucQ,7076 -pyOpenRPA/Orchestrator/Processor.py,sha256=zSsNWZtuKX5Y3q5iYCVdPpv2X7x-XzcTe5_w2CNUJ6E,12780 +pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 +pyOpenRPA/Orchestrator/Processor.py,sha256=mPSv3xO1ah1BzhQdfltt77_tJrmKP9CAfwqeFAqeTFY,11364 pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py,sha256=6otw1WnR2_evvQ5LGyOVh0BLk_nTdilViGub7p56fXQ,1531 pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py,sha256=YB5HJL-Qf4IlVrFHyRv_ZMJ0Vo4vjyYqWKjvrTnf1k4,1564 -pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=2nm5S_FOfnLkDVdlm2MVag9vL3DlyJ98LnwYNMzFNho,15914 -pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=WgGqWoPAnMeXpI_w3iuFX0KUBssvlSk9MuPBuIsNOuY,491 -pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py,sha256=4BbAozLyOlXJxNw0NAlHt38-AyV-B6-Nl1M1AY8CTtk,4212 -pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py,sha256=Y4mhNslK0EBS1LIDfK67j3lkjTZSU5xq-HUl9XNKW-U,10609 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=v-xwXHEbslqCO6QgzQdnw38pyKCQEAKf-GDVhnSyfcU,7649 -pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py,sha256=vsISwvRTMbbEtL_u9PU-rP6W71VUhAUBLMblOSGp2BE,9893 +pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=8H_7KTUy_9m4FwbXIlDBUdX4-z3RtsaQRmYzSVdpBIU,25171 +pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=goBIuwTmpdiAkimhrsqy3Y41BeljUsMQO8TaZgpx0I0,8650 +pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py,sha256=_dZQWv1lUMV8VwzeL2GclU4ZodNcYiEF7uKLrsYZjOI,10137 pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py,sha256=21N0ilFzWI1mj3X5S9tPMgwvG7BviuBxfTuqBY85Hy4,9144 pyOpenRPA/Orchestrator/RobotRDPActive/Template.rdp,sha256=JEMVYkEmNcfg_p8isdIyvj9E-2ZB5mj-R3MkcNMKxkA,2426 pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py,sha256=y8--fUvg10qEFomecl_cmdWpdGjarZBlFpMbs_GvzoQ,1077 @@ -30,8 +27,6 @@ pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/CMDStr.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Clipboard.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/ConnectorExceptions.cpython-37.pyc,, -pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/GlobalDictSessionIndex_Defs.cpython-37.pyc,, -pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Processor.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/RobotRDPActive.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Scheduler.cpython-37.pyc,, @@ -41,7 +36,7 @@ pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Orchestrator/Server.py,sha256=gqJO6FRDKTBZytJVdJgPF1PvOf05qYUyKDBJJkEpLzk,22755 pyOpenRPA/Orchestrator/ServerSettings.py,sha256=mpPAxAe6PvmKaZlreaoQAy_5wV80edz_0qc-iFrEmBQ,7123 pyOpenRPA/Orchestrator/Timer.py,sha256=HvYtEeH2Q5WVVjgds9XaBpWRmvZgwgBXurJDdVVq_T0,2097 -pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=UpIkCcR7cfkbUS0vNiyWpeR2wXg8uFBFJplT4BF0qKI,37145 +pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=giviLTJ1GJyVayvPski2GkcB6Wd2MFYVw5yK6gSsx84,38272 pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144 @@ -52,7 +47,6 @@ pyOpenRPA/Orchestrator/__pycache__/ServerSettings.cpython-37.pyc,, pyOpenRPA/Orchestrator/__pycache__/Timer.cpython-37.pyc,, pyOpenRPA/Orchestrator/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Orchestrator/__pycache__/__main__.cpython-37.pyc,, -pyOpenRPA/Orchestrator/todo.txt,sha256=OAjkuE770VZ_w1yXt6qNUT03prhODvQ0ivVoUvFLIps,419 pyOpenRPA/README.md,sha256=e2hKh7Tx6DAsX6jY_hBDhguL1L2Wiv6iugDB5otMzIA,2293 pyOpenRPA/Resources/Web/Google/LatoItalic.css,sha256=pB6OZ6F2VsaqkL-g5hW-wE_T0m9H_NltzmzjX-XAKDk,3112 pyOpenRPA/Resources/Web/Handlebars/handlebars-v4.1.2.js,sha256=h6O4BrhyPtJspLDEQwogC53uHFRozuBpxvN2S4tJHE8,171994 @@ -306,6 +300,6 @@ pyOpenRPA/Tools/Terminator.py,sha256=VcjX3gFXiCGu3MMCidhrTNsmC9wsAqfjRJdTSU9fLnU pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/__pycache__/Terminator.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, -pyOpenRPA/__init__.py,sha256=mx0F70tuKb-PzNALCeEZI3ZZcgHLBu8dsv1ILrNNH_s,174 +pyOpenRPA/__init__.py,sha256=zLXCLfZm0anOTnxES7ijiJFJqTniSxBCuqjNArOBU5Q,174 pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/HowToUse.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/HowToUse.txt deleted file mode 100644 index ed2833d1..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/HowToUse.txt +++ /dev/null @@ -1,2 +0,0 @@ -1. / robotDaemonConfiguration.json -2. runProcessOpenRPARobotDaemon_x32.cmd \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py index 93d99081..f60809c4 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py @@ -10,13 +10,13 @@ import pdb from . import Server from . import Timer from . import Processor -import logging -import copy + #from .Settings import Settings import importlib from importlib import util import threading # Multi-threading for RobotRDPActive from .RobotRDPActive import RobotRDPActive #Start robot rdp active +import uuid # Generate uuid #Единый глобальный словарь (За основу взять из Settings.py) global gSettingsDict @@ -34,6 +34,10 @@ if lSubmoduleFunctionName in dir(lTechModuleFromSpec): gSettingsDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() ################################################# #mGlobalDict = Settings.Settings(sys.argv[1]) +#Logger alias +lL = gSettingsDict["Logger"] + +if lL: lL.info("Link the gSettings in submodules") #Logging Processor.gSettingsDict = gSettingsDict Timer.gSettingsDict = gSettingsDict Timer.Processor.gSettingsDict = gSettingsDict @@ -43,34 +47,56 @@ Server.Processor.gSettingsDict = gSettingsDict #Инициализация настроечных параметров lDaemonLoopSeconds=gSettingsDict["Scheduler"]["ActivityTimeCheckLoopSeconds"] lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (, , , ) -lDaemonStartDateTime=datetime.datetime.now() +lDaemonLastDateTime=datetime.datetime.now() #Инициализация сервера lThreadServer = Server.RobotDaemonServer("ServerThread", gSettingsDict) lThreadServer.start() +if lL: lL.info("Web server has been started") #Logging + # Init the RobotRDPActive in another thread lRobotRDPActiveThread = threading.Thread(target= RobotRDPActive.RobotRDPActive, kwargs={"inGSettings":gSettingsDict}) lRobotRDPActiveThread.daemon = True # Run the thread in daemon mode. lRobotRDPActiveThread.start() # Start the thread execution. -#Logging -gSettingsDict["Logger"].info("Scheduler loop init") -# Выполнить активности при старте +if lL: lL.info("Robot RDP active has been started") #Logging + +# Orchestrator start activity +if lL: lL.info("Orchestrator start activity run") #Logging for lActivityItem in gSettingsDict["OrchestratorStart"]["ActivityList"]: Processor.ActivityListOrDict(lActivityItem) -#Вечный цикл + +if lL: lL.info("Scheduler loop start") #Logging +gDaemonActivityLogDictRefreshSecInt = 10 # The second period for clear lDaemonActivityLogDict from old items +gDaemonActivityLogDictLastTime = time.time() # The second perioad for clean lDaemonActivityLogDict from old items while True: lCurrentDateTime = datetime.datetime.now() #Циклический обход правил lFlagSearchActivityType=True + # Periodically clear the lDaemonActivityLogDict + if time.time()-gDaemonActivityLogDictLastTime>=gDaemonActivityLogDictRefreshSecInt: + gDaemonActivityLogDictLastTime = time.time() # Update the time + for lIndex, lItem in enumerate(lDaemonActivityLogDict): + if lItem["ActivityEndDateTime"] and lCurrentDateTime<=lItem["ActivityEndDateTime"]: + pass + # Activity is actual - do not delete now + else: + # remove the activity - not actual + lDaemonActivityLogDict.pop(lIndex,None) + lIterationLastDateTime = lDaemonLastDateTime # Get current datetime before iterator (need for iterate all activities in loop) + # Iterate throught the activity list for lIndex, lItem in enumerate(gSettingsDict["Scheduler"]["ActivityTimeList"]): + # Prepare GUID of the activity + lGUID = None + if "GUID" in lItem and lItem["GUID"]: + lGUID = lItem["GUID"] + else: + lGUID = str(uuid.uuid4()) + lItem["GUID"]=lGUID + #Проверка дней недели, в рамках которых можно запускать активность lItemWeekdayList=lItem.get("WeekdayList", [0, 1, 2, 3, 4, 5, 6]) if lCurrentDateTime.weekday() in lItemWeekdayList: if lFlagSearchActivityType: - #Лог - lItemCopy = copy.deepcopy(lItem) - lItemCopy["DateTimeUTCStringStart"]=datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") - gSettingsDict["Scheduler"]["LogList"].append(lItemCopy) ####################################################################### #Branch 1 - if has TimeHH:MM ####################################################################### @@ -82,16 +108,15 @@ while True: lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) #Убедиться в том, что время наступило if ( - lActivityDateTime>=lDaemonStartDateTime and - lCurrentDateTime>=lActivityDateTime and - (lIndex,lActivityDateTime) not in lDaemonActivityLogDict): - #Выполнить операцию - #Запись в массив отработанных активностей - lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime} - #Запустить процесс + lActivityDateTime>=lDaemonLastDateTime and + lCurrentDateTime>=lActivityDateTime): + # Log info about activity + if lL: lL.info(f"Scheduler:: Activity is started. Scheduler item: {lItem}") #Logging + # Do the activity Processor.ActivityListOrDict(lItem["Activity"]) + lIterationLastDateTime = datetime.datetime.now() # Set the new datetime for the new processor activity ####################################################################### - #Banch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds + #Branch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds ####################################################################### if "TimeHH:MMStart" in lItem and "TimeHH:MMStop" in lItem and "ActivityIntervalSeconds" in lItem: #Сформировать временной штамп, относительно которого надо будет проверять время @@ -104,10 +129,11 @@ while True: if ( lCurrentDateTime=lActivityDateTime and - (lIndex,lActivityDateTime) not in lDaemonActivityLogDict): + (lGUID,lActivityDateTime) not in lDaemonActivityLogDict): #Запись в массив отработанных активностей - lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime} + lDaemonActivityLogDict[(lGUID,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime, "ActivityEndDateTime":lActivityTimeEndDateTime} #Запуск циклической процедуры Timer.activityLoopStart(lItem["ActivityIntervalSeconds"], lActivityTimeEndDateTime, lItem["Activity"]) + lDaemonLastDateTime = lIterationLastDateTime # Set the new datetime for the new processor activity #Уснуть до следующего прогона time.sleep(lDaemonLoopSeconds) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py index fd09b3b3..b1800f58 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py @@ -5,7 +5,6 @@ import pdb import os import sys import subprocess -import copy import importlib import psutil #Input arg @@ -46,14 +45,12 @@ import psutil # "Type":"ProcessStart", # "Path":"", # "ArgList":[] -# # }, # { # "Type":"ProcessStartIfTurnedOff", # "CheckTaskName":"", #Check if current task name is not active (then start process), # "Path":"", # "ArgList":[] -# # }, # { # "Type":"ProcessStop", @@ -86,8 +83,6 @@ gSettingsDict = None def Activity(inActivity): #Глобальная переменная - глобальный словарь унаследованный от Settings.py global gSettingsDict - #Fill DateTimeUTCStringStart - inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") #Alias (compatibility) lItem = inActivity lCurrentDateTime = datetime.datetime.now() @@ -179,16 +174,12 @@ def Activity(inActivity): lDict=lDict[lItem2] #Return value lItem["Result"]=lDict.get(lItem["KeyList"][-1],None) - #Определить вид активности - lActivityDateTime=inActivity["DateTimeUTCStringStart"] ##################################### #ProcessStart ##################################### if lItem["Type"]=="ProcessStart": #Вид активности - запуск процесса #Запись в массив отработанных активностей - #Лог - gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) #Запустить процесс lItemArgs=[lItem["Path"]] lItemArgs.extend(lItem["ArgList"]) @@ -209,8 +200,6 @@ def Activity(inActivity): if not CheckIfProcessRunning(lCheckTaskName): #Вид активности - запуск процесса #Запись в массив отработанных активностей - #Лог - gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) #Запустить процесс lItemArgs=[lItem["Path"]] lItemArgs.extend(lItem["ArgList"]) @@ -229,8 +218,6 @@ def Activity(inActivity): #Завершить процессы только текущего пользоваиеля if lItem.get('User',"")!="": lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"' - #Лог - gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Name"], "activityStartDateTime":str(lCurrentDateTime)}) #Завершить процесс os.system(lActivityCloseCommand) ################################# @@ -263,15 +250,6 @@ def Activity(inActivity): else: lItem["Result"] = True ################################### - #Set datetime stop - lItem["DateTimeUTCStringStop"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f") - ################## - #Trace activity - ################## - #print(mGlobalDict) - if gSettingsDict["Processor"].get(f"LogType_{lItem['Type']}", True): - #Add activity in TransactionList if it is applicable - gSettingsDict["Processor"]["LogList"].append(copy.deepcopy(lItem)) #Вернуть результат return lItem diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py index 61fdc4e7..0d969130 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py @@ -10,6 +10,17 @@ import keyboard # Keyboard functions import time import random # random integers from win32api import GetSystemMetrics # Get Screen rect +import pyautogui # for hotkey operations +# System variables for recovery scenario +gRecoveryWindowRDPRetryCountInt = 3 # Retry iteration count is RDP window is not responsible +gRecoveryWindowRDPRetryIntervalSecInt = 3 # Retry interval for reconnect + +gRecoveryWindowRUNRetryCountInt = 3 # Retry iteration count is RUN window is not responsible +gRecoveryWindowRUNRetryIntervalSecInt = 3 # Retry interval for retry + +gRecoveryCMDResponsibleRetryCountInt = 3 # Retry iteration count is CMD is not responsible +gRecoveryCMDResponsibleRetryIntervalSecInt = 3 # Retry interval for retry + #Connect to RDP session """ { @@ -24,7 +35,7 @@ from win32api import GetSystemMetrics # Get Screen rect } } """ -def Session(inRDPSessionConfiguration): +def Session(inRDPSessionConfiguration, inScreenSize550x350Bool = False): #RDPConnector.SessionConnect(mConfiguration) #RDPConnector.LoginPassSet("111.222.222.111","ww","dd") (lRDPFile, lSessionHex) = SessionConfigurationCreate(inRDPSessionConfiguration) @@ -33,7 +44,7 @@ def Session(inRDPSessionConfiguration): #Set login/password SessionLoginPasswordSet(inRDPSessionConfiguration["Host"],inRDPSessionConfiguration["Login"],inRDPSessionConfiguration["Password"]) #Start session - SessionRDPStart(lRDPFile) + SessionRDPStart(lRDPFile, inScreenSize550x350Bool= inScreenSize550x350Bool) #Remove temp file time.sleep(4) #Delete file after some delay - one way to delete and run the RDP before because RDP is not read file in one moment os.remove(lRDPFile) # delete the temp rdp @@ -79,7 +90,7 @@ def SessionConfigurationCreate(inConfiguration): #Return .rdp full path return (lRDPCurrentFileFullPath, (lRDPCurrentFileFullPath.split("\\")[-1])[0:-4]) #RDPSessionStart -def SessionRDPStart(inRDPFilePath): +def SessionRDPStart(inRDPFilePath, inScreenSize550x350Bool = False): #Disable certificate warning lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 0 /f' os.system(lCMDString) @@ -137,24 +148,43 @@ def SessionRDPStart(inRDPFilePath): # Raise exception if RDP is not active if len(lWaitResult) == 0: raise ConnectorExceptions.SessionWindowNotExistError("Error when initialize the RDP session - No RDP windows has appreared!") - # Wait for init - time.sleep(3) - SessionScreenSize_X_Y_W_H(inSessionHex = lRDPFileName, inXInt = 10, inYInt = 10, inWInt = 550, inHInt = 350) #Prepare little window + time.sleep(3) # Wait for init + if inScreenSize550x350Bool: SessionScreenSize_X_Y_W_H(inSessionHex = lRDPFileName, inXInt = 10, inYInt = 10, inWInt = 550, inHInt = 350) #Prepare little window return None #Set fullscreen for app -def SessionScreenFull(inSessionHex): - #Prepare little window - try: - lRDPWindow = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHex}.*", "backend": "win32"}]) - except Exception as e: - return None - lRDPWindow.set_focus() - lRDPWindow.maximize() - #time.sleep(0.5) - if not SessionIsFullScreen(inSessionHex): - lRDPWindow.type_keys("^%{BREAK}") - time.sleep(0.5) +def SessionScreenFull(inSessionHex, inLogger = None, inRDPConfigurationItem = None): + ######################################## + lWindowRDPRetryIterator = 0 # Retry iterator if RDP window is not active + lRDPConfigurationItem = inRDPConfigurationItem # Get the RDP configuration item + lL = inLogger # Get the logger instance + lRDPWindow = None # Init the variable + while lWindowRDPRetryIterator= gRecoveryWindowRDPRetryCountInt: # Raise the error if retry count is over + if lL: lL.warning(f"RDP::SessionScreenFull: Retry count is over. Raise the error. SessionHex: {inSessionHex}.") # Log the info + raise ConnectorExceptions.SessionWindowNotExistError() # raise the error + else: + if lL: lL.warning(f"RDP::SessionScreenFull: Has no RDP configuration item - don't reconnect. Raise the error. SessionHex: {inSessionHex}") # Log the info + raise ConnectorExceptions.SessionWindowNotExistError() # raise the error return None # Set the screen size @@ -202,14 +232,14 @@ def SessionClose(inSessionHexStr): # "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK # } # example Connector.SessionCMDRun("4d1e48f3ff6c45cc810ea25d8adbeb50","start notepad", "RUN") -def SessionCMDRun(inSessionHex,inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5): +def SessionCMDRun(inSessionHex,inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5, inLogger=None, inRDPConfigurationItem=None): + lL = inLogger # Init the logger # Init the result dict lResult = {"OutStr": None,"IsResponsibleBool":True} - # Enter full screen mode - SessionScreenFull(inSessionHex) + SessionScreenFull(inSessionHex, inLogger=lL, inRDPConfigurationItem=inRDPConfigurationItem) # Enter full screen mode with recovery scenario time.sleep(2) # Run CMD operations - lResult = SystemCMDRun(inCMDCommandStr = inCMDCommandStr, inModeStr = inModeStr, inClipboardTimeoutSec = inClipboardTimeoutSec) + lResult = SystemCMDRun(inSessionHexStr = inRDPConfigurationItem["SessionHex"], inCMDCommandStr = inCMDCommandStr, inModeStr = inModeStr, inClipboardTimeoutSec = inClipboardTimeoutSec, inLogger=lL) # Exit fullscreen mode SessionScreenSize_X_Y_W_H(inSessionHex=inSessionHex, inXInt=10, inYInt=10, inWInt=550, inHInt=350) # Prepare little window @@ -233,6 +263,19 @@ def SessionIsFullScreen(inSessionHexStr): if lSessionHeight == lHeight and lSessionWeight == lWeight: lResult = True return lResult + +# Check if session is in minimized screen mode +# Return True - is in minimized +# example print(Connector.SessionIsFullScreen("")) +def SessionIsMinimizedScreen(inSessionHexStr): + #Default result + lResult = False + #Get window screen + try: + lResult = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHexStr}.*", "backend": "win32"}]).is_minimized() + except Exception as e: + pass + return lResult # Check if RDP session is responsible (check with random combination in cmd) # Attention - function will be work fine if RDP will be in full screen mode!!! (see def SessionScreenFull) # Return True - is responsible; False - is not responsible @@ -248,46 +291,90 @@ def SessionIsFullScreen(inSessionHexStr): # "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK # } # example Connector.SessionCMDRun("4d1e48f3ff6c45cc810ea25d8adbeb50","start notepad", "RUN") -def SystemCMDRun(inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5): - # Set random text to clipboard (for check purposes that clipboard text has been changed) - lClipboardTextOld = str(random.randrange(999,9999999)) +def SystemCMDRun(inSessionHexStr, inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5, inLogger = None): + lRDPWindow = None # Init the UI object + try: + lRDPWindow = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHexStr}.*", "backend": "win32"}]) + except Exception as e: + raise ConnectorExceptions.SessionWindowNotExistError() # Raise error of gui window + lL = inLogger # Alias for logger + lResult = {"OutStr": None,"IsResponsibleBool":True} # Init the result dict + lClipboardTextOld = str(random.randrange(999,9999999)) # Set random text to clipboard (for check purposes that clipboard text has been changed) Clipboard.TextSet(lClipboardTextOld) - # Init the result dict - lResult = {"OutStr": None,"IsResponsibleBool":True} lCrosscheckKeyStr = str(random.randrange(999,9999999)) - lCMDPostFixStr = "" # Case default "RUN" - if inModeStr == "CROSSCHECK": - lCMDPostFixStr = f"| echo {lCrosscheckKeyStr} | clip" - elif inModeStr == "LISTEN": - lCMDPostFixStr = f"| clip" - keyboard.press_and_release('win+r') - time.sleep(1) - # Remove old text - keyboard.press_and_release("ctrl+a") - keyboard.press_and_release("backspace") - # Write new text - keyboard.write(f"cmd /c {inCMDCommandStr} {lCMDPostFixStr}") - time.sleep(1) - # TODo cross check from clipboard - keyboard.press_and_release('enter') - # Get OutStr (Case CROSSCHECK and LISTEN) - if inModeStr == "CROSSCHECK" or inModeStr == "LISTEN": - lClipboardWaitTimeStartSec = time.time() - lResult["OutStr"] = Clipboard.TextGet() # Get text from clipboard - while lResult["OutStr"] == lClipboardTextOld and (time.time() - lClipboardWaitTimeStartSec) <= inClipboardTimeoutSec: + lRecoveryCMDResponsibleRetryIteratorInt = 0 # Init the retry iterator + while lRecoveryCMDResponsibleRetryIteratorInt= gRecoveryCMDResponsibleRetryCountInt: # raise the error if retry count is exceeded + if lL: lL.warning(f"RDP::SystemCMDRun: Retry count is over. Raise the error.") # Log the error + raise ConnectorExceptions.CMDResponsibleError() # Raise the error + time.sleep(gRecoveryCMDResponsibleRetryIntervalSecInt) # wait for some seconds before new iteration + else: # Data was recieved - do crosscheck + if inModeStr == "CROSSCHECK": + if lResult["OutStr"] == f"{lCrosscheckKeyStr} \r\n\x00\x00\x00\x00\x00": # it is ok - do futher check + lResult["IsResponsibleBool"] = True + lRecoveryCMDResponsibleRetryIteratorInt = gRecoveryCMDResponsibleRetryCountInt # turn off the iterator + else: + lResult["IsResponsibleBool"] = False + lRecoveryCMDResponsibleRetryIteratorInt = lRecoveryCMDResponsibleRetryIteratorInt + 1 # increment the iterator + if lL: lL.warning(f"RDP::SystemCMDRun: CMD command doesn't been executed (wrong clipboard data). Wait for {gRecoveryCMDResponsibleRetryIntervalSecInt}[s.] and retry from start window RUN. Current retry iterator is {lRecoveryCMDResponsibleRetryIteratorInt}. CMD Str: {lInputStr}, Clipboard data: {lResult['OutStr']}") # Log the error + if lRecoveryCMDResponsibleRetryIteratorInt >= gRecoveryCMDResponsibleRetryCountInt: # raise the error if retry count is exceeded + if lL: lL.warning(f"RDP::SystemCMDRun: Retry count is over. Raise the error.") # Log the error + raise ConnectorExceptions.CMDResponsibleError() # Raise the error + time.sleep(gRecoveryCMDResponsibleRetryIntervalSecInt) # wait for some seconds before new iteration + else: # clipboard data has been changed but mode is not crosscheck - return success from function + lRecoveryCMDResponsibleRetryIteratorInt = gRecoveryCMDResponsibleRetryCountInt # turn off the iterator + else: # Success - no cross validation is aaplicable + lRecoveryCMDResponsibleRetryIteratorInt = gRecoveryCMDResponsibleRetryCountInt # turn off the iterator + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + return lResult # return the result # Check if current RDP is responsible -def SystemRDPIsResponsible(): - return SystemCMDRun(inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK")["IsResponsibleBool"] +def SystemRDPIsResponsible(inSessionHexStr): + return SystemCMDRun(inSessionHexStr = inSessionHexStr, inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK")["IsResponsibleBool"] # Click OK on error messages def SystemRDPWarningClickOk(): # Try to click OK Error window in RUS version diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py index 3ae91409..501ca757 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py @@ -2,7 +2,9 @@ # RobotRDPActive Exceptions class ##################################### class SessionWindowNotExistError(Exception): pass #Error when Window not exists -class SessionWindowNotResponsibleError(Exception): pass # Error when Window not responding +class SessionWindowNotResponsibleError(Exception): pass # Error when Window not responding to delete +class RUNExistError(Exception): pass # Error when RUN window not identified +class CMDResponsibleError(Exception): pass # Error when command is not return class HostNoGUIError(Exception): pass # Orchestrator session has no GUI #try: # raise SessionWindowNotResponsibleError("Test") diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py deleted file mode 100644 index d4c7c82f..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py +++ /dev/null @@ -1,66 +0,0 @@ -# ATTENTION! HERE IS NO Relative import because it will be imported dynamically -# All function check the flag SessionIsWindowResponsibleBool == True else no cammand is processed -# All functions can return None, Bool or Dict { "IsSuccessful": True } -from pyOpenRPA.Tools.RobotRDPActive import CMDStr # Create CMD Strings -from pyOpenRPA.Tools.RobotRDPActive import Connector # RDP API -def ProcessStartIfNotRunning(inGlobalDict, inSessionIndex, inProcessName, inFilePath, inFlagGetAbsPath=True): - lResult = True - lCMDStr = CMDStr.ProcessStartIfNotRunning(inProcessName,inFilePath, inFlagGetAbsPath= inFlagGetAbsPath) - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") - else: - # Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.ProcessStartIfNotRunning: SessionIndex: {str(inSessionIndex)}, ProcessName: {inProcessName}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult -# Create CMD str to stop process -def ProcessStop(inGlobalDict, inSessionIndex, inProcessName, inFlagForceClose): - lResult = True - lCMDStr = f'taskkill /im "{inProcessName}" /fi "username eq %USERNAME%"' - if inFlagForceClose: - lCMDStr+= " /F" - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") - else: - # TODO Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.ProcessStop: SessionIndex: {str(inSessionIndex)}, ProcessName: {inProcessName}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult -# Send file from Host to Session RDP using shared drive in RDP -def FileStoredSend(inGlobalDict, inSessionIndex, inHostFilePath, inRDPFilePath): - lResult = True - lCMDStr = CMDStr.FileStoredSend(inHostFilePath = inHostFilePath, inRDPFilePath = inRDPFilePath) - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) - else: - # Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.FileStoredSend: SessionIndex: {str(inSessionIndex)}, HostFilePath: {inHostFilePath}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult -# Recieve file from Session RDP to Host using shared drive in RDP -def FileStoredRecieve(inGlobalDict, inSessionIndex, inRDPFilePath, inHostFilePath): - lResult = True - lCMDStr = CMDStr.FileStoredRecieve(inRDPFilePath = inRDPFilePath, inHostFilePath = inHostFilePath) - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) - else: - # Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.FileStoredRecieve: SessionIndex: {str(inSessionIndex)}, HostFilePath: {inHostFilePath}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py deleted file mode 100644 index 2f7777de..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py +++ /dev/null @@ -1,158 +0,0 @@ -from pyOpenRPA.Robot import UIDesktop -from . import Connector -import os -import time # Time wait operations -import importlib # from dynamic import module -from . import ConnectorExceptions # Exceptions classes - - -#Check for session is closed. Reopen if detected. Always keep session is active -def Monitor(inGlobalDict, inListUpdateTimeout): - lFlagWhile = True - lResponsibilityCheckLastSec = time.time() # Get current time for check interval - while lFlagWhile: - try: - # UIOSelector list init - lUIOSelectorList = [] - #Prepare selectors list for check - for lIndex, lItem in enumerate(inGlobalDict["RDPList"]): - lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']}.*", "backend": "win32"}]) - #Run wait command - #import pdb - #pdb.set_trace() - lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout) - #print(lRDPDissappearList) - ########################################### - #Analyze if flag safeturn off is activated - if inGlobalDict.get("OrchestratorToRobotResetStorage",{}).get("SafeTurnOff",False): - lFlagWhile=False - #Set status disconnected for all RDP List - for lItem in inGlobalDict["RDPList"]: - lItem["SessionIsWindowExistBool"]=False - lItem["SessionIsWindowResponsibleBool"]=False - #Kill all RDP sessions - os.system('taskkill /F /im mstsc.exe') - #Return from function - return - ########################################### - ########################################### - for lItem in lRDPDissappearList: - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False - #pdb.set_trace() - #Session start if it is not in ignore list - #add check for selector if it is not in ignoreIndexList - if lItem not in inGlobalDict["OrchestratorToRobotStorage"]["IgnoreIndexList"]: - try: - Connector.Session(inGlobalDict["RDPList"][lItem]) - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = True # Flag that session is started - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]= True - # Write in logger - info - inGlobalDict["Logger"].info(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session has been initialized!") - # catch ConnectorExceptions.SessionWindowNotExistError - except ConnectorExceptions.SessionWindowNotExistError as e: - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False - # Write in logger - warning - inGlobalDict["Logger"].warning(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session is not exist!") - # catch ConnectorExceptions.SessionWindowNotResponsibleError - except ConnectorExceptions.SessionWindowNotResponsibleError as e: - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = True # Set flag that session is disconnected - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False - # Write in logger - warning - inGlobalDict["Logger"].warning(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session is not responsible!") - # general exceptions - except Exception as e: - # Write in logger - warning - inGlobalDict["Logger"].exception(f"!!! ATTENTION !!! Unrecognized error") - ####################### - # Click all warning messages - Connector.SystemRDPWarningClickOk() - ####################### - ########################################### - #Check if from Orchestrator full screen session is set - if inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] != inGlobalDict["FullScreenSessionIndex"]: - #Do some switches - #If full screen mode we have now - if inGlobalDict["FullScreenSessionIndex"] is not None: - if inGlobalDict["RDPList"][inGlobalDict["FullScreenSessionIndex"]]["SessionIsWindowExistBool"]: - Connector.SessionScreen100x550(inGlobalDict["RDPList"][inGlobalDict["FullScreenSessionIndex"]]["SessionHex"]) - #If new session is setted - if inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] is not None: - if inGlobalDict["RDPList"][inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"]]["SessionIsWindowExistBool"]: - Connector.SessionScreenFull(inGlobalDict["RDPList"][inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"]]["SessionHex"]) - #Set one to other equal - inGlobalDict["FullScreenSessionIndex"] = inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] - ########################################### - #################################### - ##### Block check responsibility interval [ResponsibilityCheckIntervalSec] - if inGlobalDict['ResponsibilityCheckIntervalSec']: # Do check if ResponsibilityCheckIntervalSec is not None - if (time.time - lResponsibilityCheckLastSec()) > inGlobalDict['ResponsibilityCheckIntervalSec']: - # Set new time - lResponsibilityCheckLastSec = time.time() - # Do responsibility check - for lIndex, lItem in enumerate(inGlobalDict["RDPList"]): - # Check RDP responsibility - lDoCheckResponsibilityBool = True - lDoCheckResponsibilityCountMax = 20 - lDoCheckResponsibilityCountCurrent = 0 - while lDoCheckResponsibilityBool: - # Enter full screen mode - Connector.SessionScreenFull(lItem['SessionHex']) - time.sleep(2) - # Check responding - lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible() - # Check if counter is exceed - raise exception - if lDoCheckResponsibilityCountCurrent >= lDoCheckResponsibilityCountMax: - lItem["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - lItem["SessionIsWindowResponsibleBool"]=False - # Session window is not responsible - restart RDP (close window here - next loop will reconnect) - Connector.SessionClose(lItem['SessionHex']) - # Turn off the loop - lDoCheckResponsibilityBool = False - else: - # Exit fullscreen mode - Connector.SessionScreen100x550(lItem['SessionHex']) - # Wait if is not responding - if lDoCheckResponsibilityBool: - time.sleep(3) - # increase the couter - lDoCheckResponsibilityCountCurrent+=1 - #################################### - # Check ActivityList from orchestrator - lActivityListNew = [] - lActivityListOld = inGlobalDict["OrchestratorToRobotResetStorage"]["ActivityList"]+inGlobalDict["ActivityListStart"] - inGlobalDict["ActivityListStart"] = [] - for lActivityItem in lActivityListOld: - ################# - #Call function from Activity structure - ################################################ - lSubmoduleFunctionName = lActivityItem["DefName"] - lFileFullPath = lActivityItem["ModulePath"] # "path\\to\\module.py" - 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) - # Set gSettings in module - lTechModuleFromSpec.gSettings = inGlobalDict - if lSubmoduleFunctionName in dir(lTechModuleFromSpec): - # Run SettingUpdate function in submodule - #mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() - lActivityItemResult=getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(*lActivityItem["ArgList"],**lActivityItem["ArgDict"]) - lActivityItemResultType = type(lActivityItemResult) - # Check if Result is bool - if lActivityItemResultType is bool: - if not lActivityItemResult: - # Activity is not done - add to list (retry in future) - lActivityListNew.append(lActivityItem) - ################################################# - inGlobalDict["OrchestratorToRobotResetStorage"]["ActivityList"] = lActivityListNew # Override the value - except RuntimeError as e: - # case noGUI error passed - do nothing - # Write in logger - warning - inGlobalDict["Logger"].warning(f"Host session has lost the GUI") - finally: - # Wait for the next iteration - time.sleep(0.7) - return None -#TODO Def garbage window cleaner (if connection was lost) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py index 17059745..3b670128 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py @@ -30,10 +30,9 @@ def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPa "SessionIsWindowResponsibleBool": False, # Flag if RDP window is responsible (recieve commands). Check every nn seconds. If window is Responsible - window is Exist too , example False "SessionIsIgnoredBool": False # Flag to ignore RDP window False - dont ignore, True - ignore, example False } - # Add item in RDPList - gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem - # Create the RDP session - Connector.Session(lRDPConfigurationItem) + gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem # Add item in RDPList + Connector.Session(lRDPConfigurationItem) # Create the RDP session + Connector.SystemRDPWarningClickOk() # Click all warning messages return True # Disconnect the RDP session @@ -43,6 +42,7 @@ def RDPSessionDisconnect(inRDPSessionKeyStr): if lSessionHex: gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) Connector.SessionClose(inSessionHexStr=lSessionHex) + Connector.SystemRDPWarningClickOk() # Click all warning messages return True # RDP Session reconnect @@ -64,18 +64,19 @@ def RDPSessionLogoff(inRDPSessionKeyStr): # Calculate the session Hex lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) if lSessionHex: - gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList return lResult # Check RDP Session responsibility TODO NEED DEV + TEST def RDPSessionResponsibilityCheck(inRDPSessionKeyStr): global gSettings inGlobalDict = gSettings - lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]["SessionHex"] + lRDPConfigurationItem = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] # Get the alias # set the fullscreen - Connector.SessionScreenFull(inSessionHex=lSessionHex) + # ATTENTION!!! Session hex can be updated!!! + Connector.SessionScreenFull(inSessionHex=lRDPConfigurationItem["SessionHex"], inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) time.sleep(1) # Check RDP responsibility lDoCheckResponsibilityBool = True @@ -87,7 +88,7 @@ def RDPSessionResponsibilityCheck(inRDPSessionKeyStr): pass #raise ConnectorExceptions.SessionWindowNotResponsibleError("Error when initialize the RDP session - RDP window is not responding!") # Check responding - lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible() + lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible(inSessionHexStr = lRDPConfigurationItem["SessionHex"]) # Wait if is not responding if lDoCheckResponsibilityBool: time.sleep(3) @@ -105,7 +106,7 @@ def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult # Create CMD str to stop process def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceCloseBool): @@ -119,7 +120,7 @@ def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceC lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult # Send file from Host to Session RDP using shared drive in RDP def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePathStr): @@ -132,7 +133,7 @@ def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePat #lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]["SessionHex"] # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120, inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult # Recieve file from Session RDP to Host using shared drive in RDP def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFilePathStr): @@ -144,5 +145,5 @@ def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFile lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120, inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py index bcb3e76f..8f8c3029 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py @@ -9,9 +9,7 @@ def RobotRDPActive(inGSettings): # inGSettings = { # ... "RobotRDPActive": {} ... # } - #import pdb - #pdb.set_trace() - lLogger = inGSettings["Logger"] # Synonim + lL = inGSettings["Logger"] #Logger alias Processor.gSettings = inGSettings # Set gSettings in processor module mGSettingsRDPActiveDict = inGSettings["RobotRDPActive"] # Get configuration from global dict settings # Global error handler @@ -48,21 +46,17 @@ def RobotRDPActive(inGSettings): # Check if RDP window is not ignored if not lRDPConfigurationDict["SessionIsIgnoredBool"]: try: - Connector.Session(lRDPConfigurationDict) + Connector.Session(lRDPConfigurationDict, inScreenSize550x350Bool = True) lRDPConfigurationDict["SessionIsWindowExistBool"] = True # Flag that session is started - # Write in logger - info - lLogger.info( - f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session has been initialized!") + if lL: lL.info(f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session has been initialized!") #Logging # catch ConnectorExceptions.SessionWindowNotExistError except ConnectorExceptions.SessionWindowNotExistError as e: lRDPConfigurationDict["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - # Write in logger - warning - lLogger.warning( - f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session is not exist!") + if lL: lL.warning(f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session is not exist!") #Logging # general exceptions except Exception as e: - # Write in logger - warning - lLogger.exception(f"!!! ATTENTION !!! Unrecognized error") + if lL: lL.exception(f"!!! ATTENTION !!! Unrecognized error") #Logging + pass # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Safe turn off the - no need because of Orchestrator control @@ -96,18 +90,17 @@ def RobotRDPActive(inGSettings): inWInt=550, inHInt=350) # Prepare little window # Set full screen for new window - Connector.SessionScreenFull(inSessionHex=lRDPConfigurationDict["SessionHex"]) + Connector.SessionScreenFull(inSessionHex=lRDPConfigurationDict["SessionHex"], inLogger= inGSettings["Logger"], inRDPConfigurationItem=inGlobalDict["RDPList"][lRDPSessionKeyStrItem]) else: # Check all RDP window and minimize it for lRDPSessionKeyStrItem in inGlobalDict["RDPList"]: lRDPConfigurationDictItem = inGlobalDict["RDPList"][lRDPSessionKeyStrItem] - if Connector.SessionIsFullScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]): + if Connector.SessionIsFullScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]) or Connector.SessionIsMinimizedScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]): # If window is minimized - restore # if window in full screen - resize Connector.SessionScreenSize_X_Y_W_H(inSessionHex=lRDPConfigurationDictItem["SessionHex"], inXInt=10, inYInt=10, inWInt=550, inHInt=350) # Prepare little window # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Iterate the activity list in robot RDP active lActivityListNew = [] lActivityListOld = inGlobalDict["ActivityList"] @@ -115,10 +108,13 @@ def RobotRDPActive(inGSettings): for lActivityItem in lActivityListOld: lSubmoduleFunctionName = lActivityItem["DefNameStr"] if lSubmoduleFunctionName in dir(Processor): - # Run SettingUpdate function in submodule - # mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() - lActivityItemResult = getattr(Processor, lSubmoduleFunctionName)( - *lActivityItem["ArgList"], **lActivityItem["ArgDict"]) + lActivityItemResult = None # init the variable + try: # try to run function from Processor.py + lActivityItemResult = getattr(Processor, lSubmoduleFunctionName)( + *lActivityItem["ArgList"], **lActivityItem["ArgDict"]) + except Exception as e: + if lL: lL.exception(f"RDP::main: Exception when run def in processor.py - activity will be ignored. Activity item: {lActivityItem}") #Logging + lActivityItemResult = True # True - clear from repeat list lActivityItemResultType = type(lActivityItemResult) # Check if Result is bool if lActivityItemResultType is bool: @@ -129,8 +125,7 @@ def RobotRDPActive(inGSettings): # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # except RuntimeError as e: # case noGUI error passed - do nothing - # Write in logger - warning - lLogger.warning(f"Host session has lost the GUI") + if lL: lL.warning(f"Host session has lost the GUI") #Logging finally: # Wait for the next iteration time.sleep(0.7) @@ -138,5 +133,4 @@ def RobotRDPActive(inGSettings): # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #Monitor.Monitor(mGSettingsRDPActiveDict, 1) except Exception as e: - # Write in logger - warning - lLogger.exception(f"!!! ATTENTION !!! Global error handler - look at code") \ No newline at end of file + if lL: lL.exception(f"!!! ATTENTION !!! Global error handler - look at code") #Logging \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml index 0ae0cfc2..db422ff4 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml @@ -254,6 +254,34 @@ function(lData,l2,l3) { var lResponseJSON=JSON.parse(lData) + ///Escape onclick + /// RenderRobotList + lResponseJSON["RenderRobotList"].forEach( + function(lItem){ + if ('FooterButtonX2List' in lItem) { + /// FooterButtonX2List + lItem["FooterButtonX2List"].forEach( + function(lItem2){ + if ('OnClick' in lItem) { + lOnClickEscaped = lItem["OnClick"]; + lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + lItem["OnClick"] = lOnClickEscaped; + } + } + ); + /// FooterButtonX1List + lItem["FooterButtonX1List"].forEach( + function(lItem2){ + if ('OnClick' in lItem) { + lOnClickEscaped = lItem["OnClick"]; + lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + lItem["OnClick"] = lOnClickEscaped; + } + } + ); + } + } + ); ///Сформировать HTML код новой таблицы lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-control-panel",lResponseJSON) //Присвоить ответ в mGlobal.Monitor.mResponseList diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/todo.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/todo.txt deleted file mode 100644 index 5ff6b92d..00000000 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/todo.txt +++ /dev/null @@ -1,4 +0,0 @@ -1. [+] orchestrator Orchestrator/ OrchestratorMain > Orchestrator -2. [+] orchestratorProcessor -3. [+] inConfiguration. - -4. [+] orchestratorProcessor diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py index 93609808..6c4252f6 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.1.2' +__version__ = 'v1.1.3' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/INSTALLER rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/METADATA rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA index 88e2d1ef..b9dc232e 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/METADATA +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.2 +Version: 1.1.3 Summary: First open source RPA platform for business Home-page: https://gitlab.com/UnicodeLabs/OpenRPA Author: Ivan Maslov diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD similarity index 95% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/RECORD rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD index ab054615..0703f47b 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/RECORD +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD @@ -1,8 +1,8 @@ -pyOpenRPA-1.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.2.dist-info/METADATA,sha256=i36JUYLUfNOz4jax1gu2KxREFioKKXo4g6oS6ZVo-n0,3541 -pyOpenRPA-1.1.2.dist-info/RECORD,, -pyOpenRPA-1.1.2.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.2.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.3.dist-info/METADATA,sha256=ObJb3J2niW85Wzoh8Uy_TC99RYMif_Ipn-QwE7NSv_8,3541 +pyOpenRPA-1.1.3.dist-info/RECORD,, +pyOpenRPA-1.1.3.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.3.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 pyOpenRPA/.idea/inspectionProfiles/profiles_settings.xml,sha256=YXLFmX7rPNGcnKK1uX1uKYPN0fpgskYNe7t0BV7cqkY,174 pyOpenRPA/.idea/misc.xml,sha256=ySjeaQ1DfqxaRTlFGT_3zW5r9mWuwxoAK_AX4QiuAZM,203 pyOpenRPA/.idea/modules.xml,sha256=Q__U1JIA2cjxbLRXAv-SfYY00fZA0TNlpkkbY4s3ncg,277 @@ -10,17 +10,14 @@ pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 -pyOpenRPA/Orchestrator/HowToUse.txt,sha256=ZcIgNvPUhzN0XFElqDirlm07fUb7QKLVjzvNrTk4a7k,148 -pyOpenRPA/Orchestrator/Orchestrator.py,sha256=0Q4VYZPdXV2qmLuowMWD_vERj1GQurQx_VFwfsxuucQ,7076 -pyOpenRPA/Orchestrator/Processor.py,sha256=zSsNWZtuKX5Y3q5iYCVdPpv2X7x-XzcTe5_w2CNUJ6E,12780 +pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 +pyOpenRPA/Orchestrator/Processor.py,sha256=mPSv3xO1ah1BzhQdfltt77_tJrmKP9CAfwqeFAqeTFY,11364 pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py,sha256=6otw1WnR2_evvQ5LGyOVh0BLk_nTdilViGub7p56fXQ,1531 pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py,sha256=YB5HJL-Qf4IlVrFHyRv_ZMJ0Vo4vjyYqWKjvrTnf1k4,1564 -pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=2nm5S_FOfnLkDVdlm2MVag9vL3DlyJ98LnwYNMzFNho,15914 -pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=WgGqWoPAnMeXpI_w3iuFX0KUBssvlSk9MuPBuIsNOuY,491 -pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py,sha256=4BbAozLyOlXJxNw0NAlHt38-AyV-B6-Nl1M1AY8CTtk,4212 -pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py,sha256=Y4mhNslK0EBS1LIDfK67j3lkjTZSU5xq-HUl9XNKW-U,10609 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=v-xwXHEbslqCO6QgzQdnw38pyKCQEAKf-GDVhnSyfcU,7649 -pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py,sha256=vsISwvRTMbbEtL_u9PU-rP6W71VUhAUBLMblOSGp2BE,9893 +pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=8H_7KTUy_9m4FwbXIlDBUdX4-z3RtsaQRmYzSVdpBIU,25171 +pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=goBIuwTmpdiAkimhrsqy3Y41BeljUsMQO8TaZgpx0I0,8650 +pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py,sha256=_dZQWv1lUMV8VwzeL2GclU4ZodNcYiEF7uKLrsYZjOI,10137 pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py,sha256=21N0ilFzWI1mj3X5S9tPMgwvG7BviuBxfTuqBY85Hy4,9144 pyOpenRPA/Orchestrator/RobotRDPActive/Template.rdp,sha256=JEMVYkEmNcfg_p8isdIyvj9E-2ZB5mj-R3MkcNMKxkA,2426 pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py,sha256=y8--fUvg10qEFomecl_cmdWpdGjarZBlFpMbs_GvzoQ,1077 @@ -30,8 +27,6 @@ pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/CMDStr.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Clipboard.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/ConnectorExceptions.cpython-37.pyc,, -pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/GlobalDictSessionIndex_Defs.cpython-37.pyc,, -pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Processor.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/RobotRDPActive.cpython-37.pyc,, pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Scheduler.cpython-37.pyc,, @@ -41,7 +36,7 @@ pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Orchestrator/Server.py,sha256=gqJO6FRDKTBZytJVdJgPF1PvOf05qYUyKDBJJkEpLzk,22755 pyOpenRPA/Orchestrator/ServerSettings.py,sha256=mpPAxAe6PvmKaZlreaoQAy_5wV80edz_0qc-iFrEmBQ,7123 pyOpenRPA/Orchestrator/Timer.py,sha256=HvYtEeH2Q5WVVjgds9XaBpWRmvZgwgBXurJDdVVq_T0,2097 -pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=UpIkCcR7cfkbUS0vNiyWpeR2wXg8uFBFJplT4BF0qKI,37145 +pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=giviLTJ1GJyVayvPski2GkcB6Wd2MFYVw5yK6gSsx84,38272 pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144 @@ -52,7 +47,6 @@ pyOpenRPA/Orchestrator/__pycache__/ServerSettings.cpython-37.pyc,, pyOpenRPA/Orchestrator/__pycache__/Timer.cpython-37.pyc,, pyOpenRPA/Orchestrator/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Orchestrator/__pycache__/__main__.cpython-37.pyc,, -pyOpenRPA/Orchestrator/todo.txt,sha256=OAjkuE770VZ_w1yXt6qNUT03prhODvQ0ivVoUvFLIps,419 pyOpenRPA/README.md,sha256=e2hKh7Tx6DAsX6jY_hBDhguL1L2Wiv6iugDB5otMzIA,2293 pyOpenRPA/Resources/Web/Google/LatoItalic.css,sha256=pB6OZ6F2VsaqkL-g5hW-wE_T0m9H_NltzmzjX-XAKDk,3112 pyOpenRPA/Resources/Web/Handlebars/handlebars-v4.1.2.js,sha256=h6O4BrhyPtJspLDEQwogC53uHFRozuBpxvN2S4tJHE8,171994 @@ -306,6 +300,6 @@ pyOpenRPA/Tools/Terminator.py,sha256=VcjX3gFXiCGu3MMCidhrTNsmC9wsAqfjRJdTSU9fLnU pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/__pycache__/Terminator.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, -pyOpenRPA/__init__.py,sha256=mx0F70tuKb-PzNALCeEZI3ZZcgHLBu8dsv1ILrNNH_s,174 +pyOpenRPA/__init__.py,sha256=zLXCLfZm0anOTnxES7ijiJFJqTniSxBCuqjNArOBU5Q,174 pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/WHEEL similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/WHEEL rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/WHEEL diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.2.dist-info/top_level.txt rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/HowToUse.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/HowToUse.txt deleted file mode 100644 index ed2833d1..00000000 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/HowToUse.txt +++ /dev/null @@ -1,2 +0,0 @@ -1. / robotDaemonConfiguration.json -2. runProcessOpenRPARobotDaemon_x32.cmd \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py index 93d99081..f60809c4 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py @@ -10,13 +10,13 @@ import pdb from . import Server from . import Timer from . import Processor -import logging -import copy + #from .Settings import Settings import importlib from importlib import util import threading # Multi-threading for RobotRDPActive from .RobotRDPActive import RobotRDPActive #Start robot rdp active +import uuid # Generate uuid #Единый глобальный словарь (За основу взять из Settings.py) global gSettingsDict @@ -34,6 +34,10 @@ if lSubmoduleFunctionName in dir(lTechModuleFromSpec): gSettingsDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() ################################################# #mGlobalDict = Settings.Settings(sys.argv[1]) +#Logger alias +lL = gSettingsDict["Logger"] + +if lL: lL.info("Link the gSettings in submodules") #Logging Processor.gSettingsDict = gSettingsDict Timer.gSettingsDict = gSettingsDict Timer.Processor.gSettingsDict = gSettingsDict @@ -43,34 +47,56 @@ Server.Processor.gSettingsDict = gSettingsDict #Инициализация настроечных параметров lDaemonLoopSeconds=gSettingsDict["Scheduler"]["ActivityTimeCheckLoopSeconds"] lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (, , , ) -lDaemonStartDateTime=datetime.datetime.now() +lDaemonLastDateTime=datetime.datetime.now() #Инициализация сервера lThreadServer = Server.RobotDaemonServer("ServerThread", gSettingsDict) lThreadServer.start() +if lL: lL.info("Web server has been started") #Logging + # Init the RobotRDPActive in another thread lRobotRDPActiveThread = threading.Thread(target= RobotRDPActive.RobotRDPActive, kwargs={"inGSettings":gSettingsDict}) lRobotRDPActiveThread.daemon = True # Run the thread in daemon mode. lRobotRDPActiveThread.start() # Start the thread execution. -#Logging -gSettingsDict["Logger"].info("Scheduler loop init") -# Выполнить активности при старте +if lL: lL.info("Robot RDP active has been started") #Logging + +# Orchestrator start activity +if lL: lL.info("Orchestrator start activity run") #Logging for lActivityItem in gSettingsDict["OrchestratorStart"]["ActivityList"]: Processor.ActivityListOrDict(lActivityItem) -#Вечный цикл + +if lL: lL.info("Scheduler loop start") #Logging +gDaemonActivityLogDictRefreshSecInt = 10 # The second period for clear lDaemonActivityLogDict from old items +gDaemonActivityLogDictLastTime = time.time() # The second perioad for clean lDaemonActivityLogDict from old items while True: lCurrentDateTime = datetime.datetime.now() #Циклический обход правил lFlagSearchActivityType=True + # Periodically clear the lDaemonActivityLogDict + if time.time()-gDaemonActivityLogDictLastTime>=gDaemonActivityLogDictRefreshSecInt: + gDaemonActivityLogDictLastTime = time.time() # Update the time + for lIndex, lItem in enumerate(lDaemonActivityLogDict): + if lItem["ActivityEndDateTime"] and lCurrentDateTime<=lItem["ActivityEndDateTime"]: + pass + # Activity is actual - do not delete now + else: + # remove the activity - not actual + lDaemonActivityLogDict.pop(lIndex,None) + lIterationLastDateTime = lDaemonLastDateTime # Get current datetime before iterator (need for iterate all activities in loop) + # Iterate throught the activity list for lIndex, lItem in enumerate(gSettingsDict["Scheduler"]["ActivityTimeList"]): + # Prepare GUID of the activity + lGUID = None + if "GUID" in lItem and lItem["GUID"]: + lGUID = lItem["GUID"] + else: + lGUID = str(uuid.uuid4()) + lItem["GUID"]=lGUID + #Проверка дней недели, в рамках которых можно запускать активность lItemWeekdayList=lItem.get("WeekdayList", [0, 1, 2, 3, 4, 5, 6]) if lCurrentDateTime.weekday() in lItemWeekdayList: if lFlagSearchActivityType: - #Лог - lItemCopy = copy.deepcopy(lItem) - lItemCopy["DateTimeUTCStringStart"]=datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") - gSettingsDict["Scheduler"]["LogList"].append(lItemCopy) ####################################################################### #Branch 1 - if has TimeHH:MM ####################################################################### @@ -82,16 +108,15 @@ while True: lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) #Убедиться в том, что время наступило if ( - lActivityDateTime>=lDaemonStartDateTime and - lCurrentDateTime>=lActivityDateTime and - (lIndex,lActivityDateTime) not in lDaemonActivityLogDict): - #Выполнить операцию - #Запись в массив отработанных активностей - lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime} - #Запустить процесс + lActivityDateTime>=lDaemonLastDateTime and + lCurrentDateTime>=lActivityDateTime): + # Log info about activity + if lL: lL.info(f"Scheduler:: Activity is started. Scheduler item: {lItem}") #Logging + # Do the activity Processor.ActivityListOrDict(lItem["Activity"]) + lIterationLastDateTime = datetime.datetime.now() # Set the new datetime for the new processor activity ####################################################################### - #Banch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds + #Branch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds ####################################################################### if "TimeHH:MMStart" in lItem and "TimeHH:MMStop" in lItem and "ActivityIntervalSeconds" in lItem: #Сформировать временной штамп, относительно которого надо будет проверять время @@ -104,10 +129,11 @@ while True: if ( lCurrentDateTime=lActivityDateTime and - (lIndex,lActivityDateTime) not in lDaemonActivityLogDict): + (lGUID,lActivityDateTime) not in lDaemonActivityLogDict): #Запись в массив отработанных активностей - lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime} + lDaemonActivityLogDict[(lGUID,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime, "ActivityEndDateTime":lActivityTimeEndDateTime} #Запуск циклической процедуры Timer.activityLoopStart(lItem["ActivityIntervalSeconds"], lActivityTimeEndDateTime, lItem["Activity"]) + lDaemonLastDateTime = lIterationLastDateTime # Set the new datetime for the new processor activity #Уснуть до следующего прогона time.sleep(lDaemonLoopSeconds) \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py index fd09b3b3..b1800f58 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py @@ -5,7 +5,6 @@ import pdb import os import sys import subprocess -import copy import importlib import psutil #Input arg @@ -46,14 +45,12 @@ import psutil # "Type":"ProcessStart", # "Path":"", # "ArgList":[] -# # }, # { # "Type":"ProcessStartIfTurnedOff", # "CheckTaskName":"", #Check if current task name is not active (then start process), # "Path":"", # "ArgList":[] -# # }, # { # "Type":"ProcessStop", @@ -86,8 +83,6 @@ gSettingsDict = None def Activity(inActivity): #Глобальная переменная - глобальный словарь унаследованный от Settings.py global gSettingsDict - #Fill DateTimeUTCStringStart - inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") #Alias (compatibility) lItem = inActivity lCurrentDateTime = datetime.datetime.now() @@ -179,16 +174,12 @@ def Activity(inActivity): lDict=lDict[lItem2] #Return value lItem["Result"]=lDict.get(lItem["KeyList"][-1],None) - #Определить вид активности - lActivityDateTime=inActivity["DateTimeUTCStringStart"] ##################################### #ProcessStart ##################################### if lItem["Type"]=="ProcessStart": #Вид активности - запуск процесса #Запись в массив отработанных активностей - #Лог - gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) #Запустить процесс lItemArgs=[lItem["Path"]] lItemArgs.extend(lItem["ArgList"]) @@ -209,8 +200,6 @@ def Activity(inActivity): if not CheckIfProcessRunning(lCheckTaskName): #Вид активности - запуск процесса #Запись в массив отработанных активностей - #Лог - gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) #Запустить процесс lItemArgs=[lItem["Path"]] lItemArgs.extend(lItem["ArgList"]) @@ -229,8 +218,6 @@ def Activity(inActivity): #Завершить процессы только текущего пользоваиеля if lItem.get('User',"")!="": lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"' - #Лог - gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Name"], "activityStartDateTime":str(lCurrentDateTime)}) #Завершить процесс os.system(lActivityCloseCommand) ################################# @@ -263,15 +250,6 @@ def Activity(inActivity): else: lItem["Result"] = True ################################### - #Set datetime stop - lItem["DateTimeUTCStringStop"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f") - ################## - #Trace activity - ################## - #print(mGlobalDict) - if gSettingsDict["Processor"].get(f"LogType_{lItem['Type']}", True): - #Add activity in TransactionList if it is applicable - gSettingsDict["Processor"]["LogList"].append(copy.deepcopy(lItem)) #Вернуть результат return lItem diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py index 61fdc4e7..0d969130 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py @@ -10,6 +10,17 @@ import keyboard # Keyboard functions import time import random # random integers from win32api import GetSystemMetrics # Get Screen rect +import pyautogui # for hotkey operations +# System variables for recovery scenario +gRecoveryWindowRDPRetryCountInt = 3 # Retry iteration count is RDP window is not responsible +gRecoveryWindowRDPRetryIntervalSecInt = 3 # Retry interval for reconnect + +gRecoveryWindowRUNRetryCountInt = 3 # Retry iteration count is RUN window is not responsible +gRecoveryWindowRUNRetryIntervalSecInt = 3 # Retry interval for retry + +gRecoveryCMDResponsibleRetryCountInt = 3 # Retry iteration count is CMD is not responsible +gRecoveryCMDResponsibleRetryIntervalSecInt = 3 # Retry interval for retry + #Connect to RDP session """ { @@ -24,7 +35,7 @@ from win32api import GetSystemMetrics # Get Screen rect } } """ -def Session(inRDPSessionConfiguration): +def Session(inRDPSessionConfiguration, inScreenSize550x350Bool = False): #RDPConnector.SessionConnect(mConfiguration) #RDPConnector.LoginPassSet("111.222.222.111","ww","dd") (lRDPFile, lSessionHex) = SessionConfigurationCreate(inRDPSessionConfiguration) @@ -33,7 +44,7 @@ def Session(inRDPSessionConfiguration): #Set login/password SessionLoginPasswordSet(inRDPSessionConfiguration["Host"],inRDPSessionConfiguration["Login"],inRDPSessionConfiguration["Password"]) #Start session - SessionRDPStart(lRDPFile) + SessionRDPStart(lRDPFile, inScreenSize550x350Bool= inScreenSize550x350Bool) #Remove temp file time.sleep(4) #Delete file after some delay - one way to delete and run the RDP before because RDP is not read file in one moment os.remove(lRDPFile) # delete the temp rdp @@ -79,7 +90,7 @@ def SessionConfigurationCreate(inConfiguration): #Return .rdp full path return (lRDPCurrentFileFullPath, (lRDPCurrentFileFullPath.split("\\")[-1])[0:-4]) #RDPSessionStart -def SessionRDPStart(inRDPFilePath): +def SessionRDPStart(inRDPFilePath, inScreenSize550x350Bool = False): #Disable certificate warning lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 0 /f' os.system(lCMDString) @@ -137,24 +148,43 @@ def SessionRDPStart(inRDPFilePath): # Raise exception if RDP is not active if len(lWaitResult) == 0: raise ConnectorExceptions.SessionWindowNotExistError("Error when initialize the RDP session - No RDP windows has appreared!") - # Wait for init - time.sleep(3) - SessionScreenSize_X_Y_W_H(inSessionHex = lRDPFileName, inXInt = 10, inYInt = 10, inWInt = 550, inHInt = 350) #Prepare little window + time.sleep(3) # Wait for init + if inScreenSize550x350Bool: SessionScreenSize_X_Y_W_H(inSessionHex = lRDPFileName, inXInt = 10, inYInt = 10, inWInt = 550, inHInt = 350) #Prepare little window return None #Set fullscreen for app -def SessionScreenFull(inSessionHex): - #Prepare little window - try: - lRDPWindow = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHex}.*", "backend": "win32"}]) - except Exception as e: - return None - lRDPWindow.set_focus() - lRDPWindow.maximize() - #time.sleep(0.5) - if not SessionIsFullScreen(inSessionHex): - lRDPWindow.type_keys("^%{BREAK}") - time.sleep(0.5) +def SessionScreenFull(inSessionHex, inLogger = None, inRDPConfigurationItem = None): + ######################################## + lWindowRDPRetryIterator = 0 # Retry iterator if RDP window is not active + lRDPConfigurationItem = inRDPConfigurationItem # Get the RDP configuration item + lL = inLogger # Get the logger instance + lRDPWindow = None # Init the variable + while lWindowRDPRetryIterator= gRecoveryWindowRDPRetryCountInt: # Raise the error if retry count is over + if lL: lL.warning(f"RDP::SessionScreenFull: Retry count is over. Raise the error. SessionHex: {inSessionHex}.") # Log the info + raise ConnectorExceptions.SessionWindowNotExistError() # raise the error + else: + if lL: lL.warning(f"RDP::SessionScreenFull: Has no RDP configuration item - don't reconnect. Raise the error. SessionHex: {inSessionHex}") # Log the info + raise ConnectorExceptions.SessionWindowNotExistError() # raise the error return None # Set the screen size @@ -202,14 +232,14 @@ def SessionClose(inSessionHexStr): # "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK # } # example Connector.SessionCMDRun("4d1e48f3ff6c45cc810ea25d8adbeb50","start notepad", "RUN") -def SessionCMDRun(inSessionHex,inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5): +def SessionCMDRun(inSessionHex,inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5, inLogger=None, inRDPConfigurationItem=None): + lL = inLogger # Init the logger # Init the result dict lResult = {"OutStr": None,"IsResponsibleBool":True} - # Enter full screen mode - SessionScreenFull(inSessionHex) + SessionScreenFull(inSessionHex, inLogger=lL, inRDPConfigurationItem=inRDPConfigurationItem) # Enter full screen mode with recovery scenario time.sleep(2) # Run CMD operations - lResult = SystemCMDRun(inCMDCommandStr = inCMDCommandStr, inModeStr = inModeStr, inClipboardTimeoutSec = inClipboardTimeoutSec) + lResult = SystemCMDRun(inSessionHexStr = inRDPConfigurationItem["SessionHex"], inCMDCommandStr = inCMDCommandStr, inModeStr = inModeStr, inClipboardTimeoutSec = inClipboardTimeoutSec, inLogger=lL) # Exit fullscreen mode SessionScreenSize_X_Y_W_H(inSessionHex=inSessionHex, inXInt=10, inYInt=10, inWInt=550, inHInt=350) # Prepare little window @@ -233,6 +263,19 @@ def SessionIsFullScreen(inSessionHexStr): if lSessionHeight == lHeight and lSessionWeight == lWeight: lResult = True return lResult + +# Check if session is in minimized screen mode +# Return True - is in minimized +# example print(Connector.SessionIsFullScreen("")) +def SessionIsMinimizedScreen(inSessionHexStr): + #Default result + lResult = False + #Get window screen + try: + lResult = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHexStr}.*", "backend": "win32"}]).is_minimized() + except Exception as e: + pass + return lResult # Check if RDP session is responsible (check with random combination in cmd) # Attention - function will be work fine if RDP will be in full screen mode!!! (see def SessionScreenFull) # Return True - is responsible; False - is not responsible @@ -248,46 +291,90 @@ def SessionIsFullScreen(inSessionHexStr): # "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK # } # example Connector.SessionCMDRun("4d1e48f3ff6c45cc810ea25d8adbeb50","start notepad", "RUN") -def SystemCMDRun(inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5): - # Set random text to clipboard (for check purposes that clipboard text has been changed) - lClipboardTextOld = str(random.randrange(999,9999999)) +def SystemCMDRun(inSessionHexStr, inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5, inLogger = None): + lRDPWindow = None # Init the UI object + try: + lRDPWindow = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHexStr}.*", "backend": "win32"}]) + except Exception as e: + raise ConnectorExceptions.SessionWindowNotExistError() # Raise error of gui window + lL = inLogger # Alias for logger + lResult = {"OutStr": None,"IsResponsibleBool":True} # Init the result dict + lClipboardTextOld = str(random.randrange(999,9999999)) # Set random text to clipboard (for check purposes that clipboard text has been changed) Clipboard.TextSet(lClipboardTextOld) - # Init the result dict - lResult = {"OutStr": None,"IsResponsibleBool":True} lCrosscheckKeyStr = str(random.randrange(999,9999999)) - lCMDPostFixStr = "" # Case default "RUN" - if inModeStr == "CROSSCHECK": - lCMDPostFixStr = f"| echo {lCrosscheckKeyStr} | clip" - elif inModeStr == "LISTEN": - lCMDPostFixStr = f"| clip" - keyboard.press_and_release('win+r') - time.sleep(1) - # Remove old text - keyboard.press_and_release("ctrl+a") - keyboard.press_and_release("backspace") - # Write new text - keyboard.write(f"cmd /c {inCMDCommandStr} {lCMDPostFixStr}") - time.sleep(1) - # TODo cross check from clipboard - keyboard.press_and_release('enter') - # Get OutStr (Case CROSSCHECK and LISTEN) - if inModeStr == "CROSSCHECK" or inModeStr == "LISTEN": - lClipboardWaitTimeStartSec = time.time() - lResult["OutStr"] = Clipboard.TextGet() # Get text from clipboard - while lResult["OutStr"] == lClipboardTextOld and (time.time() - lClipboardWaitTimeStartSec) <= inClipboardTimeoutSec: + lRecoveryCMDResponsibleRetryIteratorInt = 0 # Init the retry iterator + while lRecoveryCMDResponsibleRetryIteratorInt= gRecoveryCMDResponsibleRetryCountInt: # raise the error if retry count is exceeded + if lL: lL.warning(f"RDP::SystemCMDRun: Retry count is over. Raise the error.") # Log the error + raise ConnectorExceptions.CMDResponsibleError() # Raise the error + time.sleep(gRecoveryCMDResponsibleRetryIntervalSecInt) # wait for some seconds before new iteration + else: # Data was recieved - do crosscheck + if inModeStr == "CROSSCHECK": + if lResult["OutStr"] == f"{lCrosscheckKeyStr} \r\n\x00\x00\x00\x00\x00": # it is ok - do futher check + lResult["IsResponsibleBool"] = True + lRecoveryCMDResponsibleRetryIteratorInt = gRecoveryCMDResponsibleRetryCountInt # turn off the iterator + else: + lResult["IsResponsibleBool"] = False + lRecoveryCMDResponsibleRetryIteratorInt = lRecoveryCMDResponsibleRetryIteratorInt + 1 # increment the iterator + if lL: lL.warning(f"RDP::SystemCMDRun: CMD command doesn't been executed (wrong clipboard data). Wait for {gRecoveryCMDResponsibleRetryIntervalSecInt}[s.] and retry from start window RUN. Current retry iterator is {lRecoveryCMDResponsibleRetryIteratorInt}. CMD Str: {lInputStr}, Clipboard data: {lResult['OutStr']}") # Log the error + if lRecoveryCMDResponsibleRetryIteratorInt >= gRecoveryCMDResponsibleRetryCountInt: # raise the error if retry count is exceeded + if lL: lL.warning(f"RDP::SystemCMDRun: Retry count is over. Raise the error.") # Log the error + raise ConnectorExceptions.CMDResponsibleError() # Raise the error + time.sleep(gRecoveryCMDResponsibleRetryIntervalSecInt) # wait for some seconds before new iteration + else: # clipboard data has been changed but mode is not crosscheck - return success from function + lRecoveryCMDResponsibleRetryIteratorInt = gRecoveryCMDResponsibleRetryCountInt # turn off the iterator + else: # Success - no cross validation is aaplicable + lRecoveryCMDResponsibleRetryIteratorInt = gRecoveryCMDResponsibleRetryCountInt # turn off the iterator + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + return lResult # return the result # Check if current RDP is responsible -def SystemRDPIsResponsible(): - return SystemCMDRun(inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK")["IsResponsibleBool"] +def SystemRDPIsResponsible(inSessionHexStr): + return SystemCMDRun(inSessionHexStr = inSessionHexStr, inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK")["IsResponsibleBool"] # Click OK on error messages def SystemRDPWarningClickOk(): # Try to click OK Error window in RUS version diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py index 3ae91409..501ca757 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py @@ -2,7 +2,9 @@ # RobotRDPActive Exceptions class ##################################### class SessionWindowNotExistError(Exception): pass #Error when Window not exists -class SessionWindowNotResponsibleError(Exception): pass # Error when Window not responding +class SessionWindowNotResponsibleError(Exception): pass # Error when Window not responding to delete +class RUNExistError(Exception): pass # Error when RUN window not identified +class CMDResponsibleError(Exception): pass # Error when command is not return class HostNoGUIError(Exception): pass # Orchestrator session has no GUI #try: # raise SessionWindowNotResponsibleError("Test") diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py deleted file mode 100644 index d4c7c82f..00000000 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py +++ /dev/null @@ -1,66 +0,0 @@ -# ATTENTION! HERE IS NO Relative import because it will be imported dynamically -# All function check the flag SessionIsWindowResponsibleBool == True else no cammand is processed -# All functions can return None, Bool or Dict { "IsSuccessful": True } -from pyOpenRPA.Tools.RobotRDPActive import CMDStr # Create CMD Strings -from pyOpenRPA.Tools.RobotRDPActive import Connector # RDP API -def ProcessStartIfNotRunning(inGlobalDict, inSessionIndex, inProcessName, inFilePath, inFlagGetAbsPath=True): - lResult = True - lCMDStr = CMDStr.ProcessStartIfNotRunning(inProcessName,inFilePath, inFlagGetAbsPath= inFlagGetAbsPath) - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") - else: - # Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.ProcessStartIfNotRunning: SessionIndex: {str(inSessionIndex)}, ProcessName: {inProcessName}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult -# Create CMD str to stop process -def ProcessStop(inGlobalDict, inSessionIndex, inProcessName, inFlagForceClose): - lResult = True - lCMDStr = f'taskkill /im "{inProcessName}" /fi "username eq %USERNAME%"' - if inFlagForceClose: - lCMDStr+= " /F" - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") - else: - # TODO Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.ProcessStop: SessionIndex: {str(inSessionIndex)}, ProcessName: {inProcessName}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult -# Send file from Host to Session RDP using shared drive in RDP -def FileStoredSend(inGlobalDict, inSessionIndex, inHostFilePath, inRDPFilePath): - lResult = True - lCMDStr = CMDStr.FileStoredSend(inHostFilePath = inHostFilePath, inRDPFilePath = inRDPFilePath) - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) - else: - # Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.FileStoredSend: SessionIndex: {str(inSessionIndex)}, HostFilePath: {inHostFilePath}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult -# Recieve file from Session RDP to Host using shared drive in RDP -def FileStoredRecieve(inGlobalDict, inSessionIndex, inRDPFilePath, inHostFilePath): - lResult = True - lCMDStr = CMDStr.FileStoredRecieve(inRDPFilePath = inRDPFilePath, inHostFilePath = inHostFilePath) - # Calculate the session Hex - lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] - # Check is Session is responsible - if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) - else: - # Write in logger - warning - inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.FileStoredRecieve: SessionIndex: {str(inSessionIndex)}, HostFilePath: {inHostFilePath}:: Session is not responsible!") - lResult = False # Set false result - function has not been done - return lResult \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py deleted file mode 100644 index 2f7777de..00000000 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py +++ /dev/null @@ -1,158 +0,0 @@ -from pyOpenRPA.Robot import UIDesktop -from . import Connector -import os -import time # Time wait operations -import importlib # from dynamic import module -from . import ConnectorExceptions # Exceptions classes - - -#Check for session is closed. Reopen if detected. Always keep session is active -def Monitor(inGlobalDict, inListUpdateTimeout): - lFlagWhile = True - lResponsibilityCheckLastSec = time.time() # Get current time for check interval - while lFlagWhile: - try: - # UIOSelector list init - lUIOSelectorList = [] - #Prepare selectors list for check - for lIndex, lItem in enumerate(inGlobalDict["RDPList"]): - lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']}.*", "backend": "win32"}]) - #Run wait command - #import pdb - #pdb.set_trace() - lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout) - #print(lRDPDissappearList) - ########################################### - #Analyze if flag safeturn off is activated - if inGlobalDict.get("OrchestratorToRobotResetStorage",{}).get("SafeTurnOff",False): - lFlagWhile=False - #Set status disconnected for all RDP List - for lItem in inGlobalDict["RDPList"]: - lItem["SessionIsWindowExistBool"]=False - lItem["SessionIsWindowResponsibleBool"]=False - #Kill all RDP sessions - os.system('taskkill /F /im mstsc.exe') - #Return from function - return - ########################################### - ########################################### - for lItem in lRDPDissappearList: - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False - #pdb.set_trace() - #Session start if it is not in ignore list - #add check for selector if it is not in ignoreIndexList - if lItem not in inGlobalDict["OrchestratorToRobotStorage"]["IgnoreIndexList"]: - try: - Connector.Session(inGlobalDict["RDPList"][lItem]) - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = True # Flag that session is started - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]= True - # Write in logger - info - inGlobalDict["Logger"].info(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session has been initialized!") - # catch ConnectorExceptions.SessionWindowNotExistError - except ConnectorExceptions.SessionWindowNotExistError as e: - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False - # Write in logger - warning - inGlobalDict["Logger"].warning(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session is not exist!") - # catch ConnectorExceptions.SessionWindowNotResponsibleError - except ConnectorExceptions.SessionWindowNotResponsibleError as e: - inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = True # Set flag that session is disconnected - inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False - # Write in logger - warning - inGlobalDict["Logger"].warning(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session is not responsible!") - # general exceptions - except Exception as e: - # Write in logger - warning - inGlobalDict["Logger"].exception(f"!!! ATTENTION !!! Unrecognized error") - ####################### - # Click all warning messages - Connector.SystemRDPWarningClickOk() - ####################### - ########################################### - #Check if from Orchestrator full screen session is set - if inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] != inGlobalDict["FullScreenSessionIndex"]: - #Do some switches - #If full screen mode we have now - if inGlobalDict["FullScreenSessionIndex"] is not None: - if inGlobalDict["RDPList"][inGlobalDict["FullScreenSessionIndex"]]["SessionIsWindowExistBool"]: - Connector.SessionScreen100x550(inGlobalDict["RDPList"][inGlobalDict["FullScreenSessionIndex"]]["SessionHex"]) - #If new session is setted - if inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] is not None: - if inGlobalDict["RDPList"][inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"]]["SessionIsWindowExistBool"]: - Connector.SessionScreenFull(inGlobalDict["RDPList"][inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"]]["SessionHex"]) - #Set one to other equal - inGlobalDict["FullScreenSessionIndex"] = inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] - ########################################### - #################################### - ##### Block check responsibility interval [ResponsibilityCheckIntervalSec] - if inGlobalDict['ResponsibilityCheckIntervalSec']: # Do check if ResponsibilityCheckIntervalSec is not None - if (time.time - lResponsibilityCheckLastSec()) > inGlobalDict['ResponsibilityCheckIntervalSec']: - # Set new time - lResponsibilityCheckLastSec = time.time() - # Do responsibility check - for lIndex, lItem in enumerate(inGlobalDict["RDPList"]): - # Check RDP responsibility - lDoCheckResponsibilityBool = True - lDoCheckResponsibilityCountMax = 20 - lDoCheckResponsibilityCountCurrent = 0 - while lDoCheckResponsibilityBool: - # Enter full screen mode - Connector.SessionScreenFull(lItem['SessionHex']) - time.sleep(2) - # Check responding - lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible() - # Check if counter is exceed - raise exception - if lDoCheckResponsibilityCountCurrent >= lDoCheckResponsibilityCountMax: - lItem["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - lItem["SessionIsWindowResponsibleBool"]=False - # Session window is not responsible - restart RDP (close window here - next loop will reconnect) - Connector.SessionClose(lItem['SessionHex']) - # Turn off the loop - lDoCheckResponsibilityBool = False - else: - # Exit fullscreen mode - Connector.SessionScreen100x550(lItem['SessionHex']) - # Wait if is not responding - if lDoCheckResponsibilityBool: - time.sleep(3) - # increase the couter - lDoCheckResponsibilityCountCurrent+=1 - #################################### - # Check ActivityList from orchestrator - lActivityListNew = [] - lActivityListOld = inGlobalDict["OrchestratorToRobotResetStorage"]["ActivityList"]+inGlobalDict["ActivityListStart"] - inGlobalDict["ActivityListStart"] = [] - for lActivityItem in lActivityListOld: - ################# - #Call function from Activity structure - ################################################ - lSubmoduleFunctionName = lActivityItem["DefName"] - lFileFullPath = lActivityItem["ModulePath"] # "path\\to\\module.py" - 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) - # Set gSettings in module - lTechModuleFromSpec.gSettings = inGlobalDict - if lSubmoduleFunctionName in dir(lTechModuleFromSpec): - # Run SettingUpdate function in submodule - #mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() - lActivityItemResult=getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(*lActivityItem["ArgList"],**lActivityItem["ArgDict"]) - lActivityItemResultType = type(lActivityItemResult) - # Check if Result is bool - if lActivityItemResultType is bool: - if not lActivityItemResult: - # Activity is not done - add to list (retry in future) - lActivityListNew.append(lActivityItem) - ################################################# - inGlobalDict["OrchestratorToRobotResetStorage"]["ActivityList"] = lActivityListNew # Override the value - except RuntimeError as e: - # case noGUI error passed - do nothing - # Write in logger - warning - inGlobalDict["Logger"].warning(f"Host session has lost the GUI") - finally: - # Wait for the next iteration - time.sleep(0.7) - return None -#TODO Def garbage window cleaner (if connection was lost) \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py index 17059745..3b670128 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py @@ -30,10 +30,9 @@ def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPa "SessionIsWindowResponsibleBool": False, # Flag if RDP window is responsible (recieve commands). Check every nn seconds. If window is Responsible - window is Exist too , example False "SessionIsIgnoredBool": False # Flag to ignore RDP window False - dont ignore, True - ignore, example False } - # Add item in RDPList - gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem - # Create the RDP session - Connector.Session(lRDPConfigurationItem) + gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem # Add item in RDPList + Connector.Session(lRDPConfigurationItem) # Create the RDP session + Connector.SystemRDPWarningClickOk() # Click all warning messages return True # Disconnect the RDP session @@ -43,6 +42,7 @@ def RDPSessionDisconnect(inRDPSessionKeyStr): if lSessionHex: gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) Connector.SessionClose(inSessionHexStr=lSessionHex) + Connector.SystemRDPWarningClickOk() # Click all warning messages return True # RDP Session reconnect @@ -64,18 +64,19 @@ def RDPSessionLogoff(inRDPSessionKeyStr): # Calculate the session Hex lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) if lSessionHex: - gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList return lResult # Check RDP Session responsibility TODO NEED DEV + TEST def RDPSessionResponsibilityCheck(inRDPSessionKeyStr): global gSettings inGlobalDict = gSettings - lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]["SessionHex"] + lRDPConfigurationItem = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] # Get the alias # set the fullscreen - Connector.SessionScreenFull(inSessionHex=lSessionHex) + # ATTENTION!!! Session hex can be updated!!! + Connector.SessionScreenFull(inSessionHex=lRDPConfigurationItem["SessionHex"], inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) time.sleep(1) # Check RDP responsibility lDoCheckResponsibilityBool = True @@ -87,7 +88,7 @@ def RDPSessionResponsibilityCheck(inRDPSessionKeyStr): pass #raise ConnectorExceptions.SessionWindowNotResponsibleError("Error when initialize the RDP session - RDP window is not responding!") # Check responding - lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible() + lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible(inSessionHexStr = lRDPConfigurationItem["SessionHex"]) # Wait if is not responding if lDoCheckResponsibilityBool: time.sleep(3) @@ -105,7 +106,7 @@ def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult # Create CMD str to stop process def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceCloseBool): @@ -119,7 +120,7 @@ def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceC lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult # Send file from Host to Session RDP using shared drive in RDP def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePathStr): @@ -132,7 +133,7 @@ def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePat #lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]["SessionHex"] # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120, inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult # Recieve file from Session RDP to Host using shared drive in RDP def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFilePathStr): @@ -144,5 +145,5 @@ def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFile lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) # Run CMD if lSessionHex: - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120, inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) return lResult \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py index bcb3e76f..8f8c3029 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py @@ -9,9 +9,7 @@ def RobotRDPActive(inGSettings): # inGSettings = { # ... "RobotRDPActive": {} ... # } - #import pdb - #pdb.set_trace() - lLogger = inGSettings["Logger"] # Synonim + lL = inGSettings["Logger"] #Logger alias Processor.gSettings = inGSettings # Set gSettings in processor module mGSettingsRDPActiveDict = inGSettings["RobotRDPActive"] # Get configuration from global dict settings # Global error handler @@ -48,21 +46,17 @@ def RobotRDPActive(inGSettings): # Check if RDP window is not ignored if not lRDPConfigurationDict["SessionIsIgnoredBool"]: try: - Connector.Session(lRDPConfigurationDict) + Connector.Session(lRDPConfigurationDict, inScreenSize550x350Bool = True) lRDPConfigurationDict["SessionIsWindowExistBool"] = True # Flag that session is started - # Write in logger - info - lLogger.info( - f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session has been initialized!") + if lL: lL.info(f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session has been initialized!") #Logging # catch ConnectorExceptions.SessionWindowNotExistError except ConnectorExceptions.SessionWindowNotExistError as e: lRDPConfigurationDict["SessionIsWindowExistBool"] = False # Set flag that session is disconnected - # Write in logger - warning - lLogger.warning( - f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session is not exist!") + if lL: lL.warning(f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session is not exist!") #Logging # general exceptions except Exception as e: - # Write in logger - warning - lLogger.exception(f"!!! ATTENTION !!! Unrecognized error") + if lL: lL.exception(f"!!! ATTENTION !!! Unrecognized error") #Logging + pass # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Safe turn off the - no need because of Orchestrator control @@ -96,18 +90,17 @@ def RobotRDPActive(inGSettings): inWInt=550, inHInt=350) # Prepare little window # Set full screen for new window - Connector.SessionScreenFull(inSessionHex=lRDPConfigurationDict["SessionHex"]) + Connector.SessionScreenFull(inSessionHex=lRDPConfigurationDict["SessionHex"], inLogger= inGSettings["Logger"], inRDPConfigurationItem=inGlobalDict["RDPList"][lRDPSessionKeyStrItem]) else: # Check all RDP window and minimize it for lRDPSessionKeyStrItem in inGlobalDict["RDPList"]: lRDPConfigurationDictItem = inGlobalDict["RDPList"][lRDPSessionKeyStrItem] - if Connector.SessionIsFullScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]): + if Connector.SessionIsFullScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]) or Connector.SessionIsMinimizedScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]): # If window is minimized - restore # if window in full screen - resize Connector.SessionScreenSize_X_Y_W_H(inSessionHex=lRDPConfigurationDictItem["SessionHex"], inXInt=10, inYInt=10, inWInt=550, inHInt=350) # Prepare little window # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Iterate the activity list in robot RDP active lActivityListNew = [] lActivityListOld = inGlobalDict["ActivityList"] @@ -115,10 +108,13 @@ def RobotRDPActive(inGSettings): for lActivityItem in lActivityListOld: lSubmoduleFunctionName = lActivityItem["DefNameStr"] if lSubmoduleFunctionName in dir(Processor): - # Run SettingUpdate function in submodule - # mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() - lActivityItemResult = getattr(Processor, lSubmoduleFunctionName)( - *lActivityItem["ArgList"], **lActivityItem["ArgDict"]) + lActivityItemResult = None # init the variable + try: # try to run function from Processor.py + lActivityItemResult = getattr(Processor, lSubmoduleFunctionName)( + *lActivityItem["ArgList"], **lActivityItem["ArgDict"]) + except Exception as e: + if lL: lL.exception(f"RDP::main: Exception when run def in processor.py - activity will be ignored. Activity item: {lActivityItem}") #Logging + lActivityItemResult = True # True - clear from repeat list lActivityItemResultType = type(lActivityItemResult) # Check if Result is bool if lActivityItemResultType is bool: @@ -129,8 +125,7 @@ def RobotRDPActive(inGSettings): # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # except RuntimeError as e: # case noGUI error passed - do nothing - # Write in logger - warning - lLogger.warning(f"Host session has lost the GUI") + if lL: lL.warning(f"Host session has lost the GUI") #Logging finally: # Wait for the next iteration time.sleep(0.7) @@ -138,5 +133,4 @@ def RobotRDPActive(inGSettings): # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #Monitor.Monitor(mGSettingsRDPActiveDict, 1) except Exception as e: - # Write in logger - warning - lLogger.exception(f"!!! ATTENTION !!! Global error handler - look at code") \ No newline at end of file + if lL: lL.exception(f"!!! ATTENTION !!! Global error handler - look at code") #Logging \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml index 0ae0cfc2..db422ff4 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml @@ -254,6 +254,34 @@ function(lData,l2,l3) { var lResponseJSON=JSON.parse(lData) + ///Escape onclick + /// RenderRobotList + lResponseJSON["RenderRobotList"].forEach( + function(lItem){ + if ('FooterButtonX2List' in lItem) { + /// FooterButtonX2List + lItem["FooterButtonX2List"].forEach( + function(lItem2){ + if ('OnClick' in lItem) { + lOnClickEscaped = lItem["OnClick"]; + lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + lItem["OnClick"] = lOnClickEscaped; + } + } + ); + /// FooterButtonX1List + lItem["FooterButtonX1List"].forEach( + function(lItem2){ + if ('OnClick' in lItem) { + lOnClickEscaped = lItem["OnClick"]; + lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + lItem["OnClick"] = lOnClickEscaped; + } + } + ); + } + } + ); ///Сформировать HTML код новой таблицы lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-control-panel",lResponseJSON) //Присвоить ответ в mGlobal.Monitor.mResponseList diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/todo.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/todo.txt deleted file mode 100644 index 5ff6b92d..00000000 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/todo.txt +++ /dev/null @@ -1,4 +0,0 @@ -1. [+] orchestrator Orchestrator/ OrchestratorMain > Orchestrator -2. [+] orchestratorProcessor -3. [+] inConfiguration. - -4. [+] orchestratorProcessor diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py index 93609808..6c4252f6 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.1.2' +__version__ = 'v1.1.3' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Sources/pyOpenRPA/__init__.py b/Sources/pyOpenRPA/__init__.py index 93609808..6c4252f6 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.1.2' +__version__ = 'v1.1.3' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/v1.1.2 b/v1.1.3 similarity index 100% rename from v1.1.2 rename to v1.1.3