From a08e70f2c14f37d00aa40567544a66a34fb8e369 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Mon, 1 Jun 2020 23:19:45 +0300 Subject: [PATCH 01/19] # Orchestrator RDP Active fixes after Test + UAT (critical fixes) --- .../INSTALLER | 0 .../pyOpenRPA-1.1.4.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.4.dist-info}/RECORD | 16 +++++------ .../WHEEL | 0 .../top_level.txt | 0 .../Orchestrator/RobotRDPActive/Connector.py | 27 ++++++++++++------- .../Orchestrator/RobotRDPActive/Processor.py | 4 +-- .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- .../INSTALLER | 0 .../pyOpenRPA-1.1.4.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.4.dist-info}/RECORD | 16 +++++------ .../WHEEL | 0 .../top_level.txt | 0 .../Orchestrator/RobotRDPActive/Connector.py | 27 ++++++++++++------- .../Orchestrator/RobotRDPActive/Processor.py | 4 +-- .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- Sources/pyOpenRPA/__init__.py | 2 +- v1.1.3 => v1.1.4 | 0 18 files changed, 61 insertions(+), 43 deletions(-) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.3.dist-info => pyOpenRPA-1.1.4.dist-info}/INSTALLER (100%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info}/METADATA (99%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info}/RECORD (98%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.3.dist-info => pyOpenRPA-1.1.4.dist-info}/WHEEL (100%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.3.dist-info => pyOpenRPA-1.1.4.dist-info}/top_level.txt (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.3.dist-info => pyOpenRPA-1.1.4.dist-info}/INSTALLER (100%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info}/METADATA (99%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info}/RECORD (98%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.3.dist-info => pyOpenRPA-1.1.4.dist-info}/WHEEL (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.3.dist-info => pyOpenRPA-1.1.4.dist-info}/top_level.txt (100%) rename v1.1.3 => v1.1.4 (100%) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA index b9dc232e..4e938337 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.3 +Version: 1.1.4 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.3.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD similarity index 98% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD index 0703f47b..b6d8893d 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD @@ -1,8 +1,8 @@ -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-1.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.4.dist-info/METADATA,sha256=E8N30TKbMhQ1CUfXUxJT7T9MUmNpNx7lBcss27Y2pbg,3541 +pyOpenRPA-1.1.4.dist-info/RECORD,, +pyOpenRPA-1.1.4.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.4.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 @@ -14,9 +14,9 @@ pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6G 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=8H_7KTUy_9m4FwbXIlDBUdX4-z3RtsaQRmYzSVdpBIU,25171 +pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=MkxTVaOVITl1V3EvH3oNx2gbCx3EeRS9Gb_83rmjdjg,25553 pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=goBIuwTmpdiAkimhrsqy3Y41BeljUsMQO8TaZgpx0I0,8650 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=NMIcP38qE7LcIvm9IJMoDVE1VCDLx6WgJHqUzV6IN7A,8720 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 @@ -300,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=zLXCLfZm0anOTnxES7ijiJFJqTniSxBCuqjNArOBU5Q,174 +pyOpenRPA/__init__.py,sha256=esqQQhb49aasfe2keriHnVJulnmS1EWRJgsf0fp5UmQ,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.3.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt 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 0d969130..ff93abd7 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 @@ -21,6 +21,8 @@ gRecoveryWindowRUNRetryIntervalSecInt = 3 # Retry interval for retry gRecoveryCMDResponsibleRetryCountInt = 3 # Retry iteration count is CMD is not responsible gRecoveryCMDResponsibleRetryIntervalSecInt = 3 # Retry interval for retry +gKeyboardHotkeyDelaySecFloat = 0.6 # Const for delay - important for work with RDP!!!! + #Connect to RDP session """ { @@ -312,16 +314,15 @@ def SystemCMDRun(inSessionHexStr, inCMDCommandStr = "echo 1", inModeStr="CROSSCH lCMDPostFixStr = f"& (echo {lCrosscheckKeyStr} | clip)" elif inModeStr == "LISTEN": lCMDPostFixStr = f"| clip" - keyboard.press_and_release('win+r') - time.sleep(1) # Wait for RUN window will appear - lRDPWindow.type_keys("^(a)") # Select all - keyboard.press_and_release("backspace") # Delete selected all - time.sleep(0.5) # Wait for RUN window will appear ctrl+a+backspace is async - so we need some timeout... + KeyboardHotkey("win","r") # win+r + KeyboardHotkey("ctrl","a") # Select all + keyboard.send("backspace") # Delete selected all + time.sleep(gKeyboardHotkeyDelaySecFloat) # Wait for RUN window will appear ctrl+a+backspace is async - so we need some timeout... lInputStr = f"cmd /c ({inCMDCommandStr}) {lCMDPostFixStr}" # Generate the output string for RUN window keyboard.write(lInputStr) # Write new text - time.sleep(0.5) - lRDPWindow.type_keys("^(a)") # Select all - lRDPWindow.type_keys("^(c)") # Copy data + time.sleep(gKeyboardHotkeyDelaySecFloat) + KeyboardHotkey("ctrl","a") # Select all + KeyboardHotkey("ctrl","c") # Copy data # Check the clipboard lClipboardWaitTimeStartSec = time.time() lClipboardStr = Clipboard.TextGet() # Get text from clipboard @@ -392,4 +393,12 @@ def SystemRDPWarningClickOk(): UIDesktop.UIOSelector_Get_UIO([{"title": "Remote Desktop Connection", "class_name": "#32770", "backend": "win32"}, {"title": "OK", "class_name": "Button"}]).click() except Exception as e: - pass \ No newline at end of file + pass +# Bugfix with RDP work +def KeyboardHotkey(inModifierKeyStr,inKeyStr, inDelaySecFloat=gKeyboardHotkeyDelaySecFloat): + keyboard.press(inModifierKeyStr) + time.sleep(inDelaySecFloat) + keyboard.send(inKeyStr) + time.sleep(inDelaySecFloat) + keyboard.release(inModifierKeyStr) + time.sleep(inDelaySecFloat) \ 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 3b670128..ae71eab7 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 @@ -64,8 +64,8 @@ def RDPSessionLogoff(inRDPSessionKeyStr): # Calculate the session Hex lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) if lSessionHex: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) + # Run CMD - dont crosscheck because CMD dont return value to the clipboard when logoff + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList return lResult 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 6c4252f6..87219230 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.3' +__version__ = 'v1.1.4' __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.3.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/INSTALLER rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA similarity index 99% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA index b9dc232e..4e938337 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/METADATA +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.3 +Version: 1.1.4 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.3.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD similarity index 98% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD index 0703f47b..b6d8893d 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/RECORD +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD @@ -1,8 +1,8 @@ -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-1.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.4.dist-info/METADATA,sha256=E8N30TKbMhQ1CUfXUxJT7T9MUmNpNx7lBcss27Y2pbg,3541 +pyOpenRPA-1.1.4.dist-info/RECORD,, +pyOpenRPA-1.1.4.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.4.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 @@ -14,9 +14,9 @@ pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6G 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=8H_7KTUy_9m4FwbXIlDBUdX4-z3RtsaQRmYzSVdpBIU,25171 +pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=MkxTVaOVITl1V3EvH3oNx2gbCx3EeRS9Gb_83rmjdjg,25553 pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=goBIuwTmpdiAkimhrsqy3Y41BeljUsMQO8TaZgpx0I0,8650 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=NMIcP38qE7LcIvm9IJMoDVE1VCDLx6WgJHqUzV6IN7A,8720 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 @@ -300,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=zLXCLfZm0anOTnxES7ijiJFJqTniSxBCuqjNArOBU5Q,174 +pyOpenRPA/__init__.py,sha256=esqQQhb49aasfe2keriHnVJulnmS1EWRJgsf0fp5UmQ,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.3.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/WHEEL similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/WHEEL rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/WHEEL diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.3.dist-info/top_level.txt rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt 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 0d969130..ff93abd7 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 @@ -21,6 +21,8 @@ gRecoveryWindowRUNRetryIntervalSecInt = 3 # Retry interval for retry gRecoveryCMDResponsibleRetryCountInt = 3 # Retry iteration count is CMD is not responsible gRecoveryCMDResponsibleRetryIntervalSecInt = 3 # Retry interval for retry +gKeyboardHotkeyDelaySecFloat = 0.6 # Const for delay - important for work with RDP!!!! + #Connect to RDP session """ { @@ -312,16 +314,15 @@ def SystemCMDRun(inSessionHexStr, inCMDCommandStr = "echo 1", inModeStr="CROSSCH lCMDPostFixStr = f"& (echo {lCrosscheckKeyStr} | clip)" elif inModeStr == "LISTEN": lCMDPostFixStr = f"| clip" - keyboard.press_and_release('win+r') - time.sleep(1) # Wait for RUN window will appear - lRDPWindow.type_keys("^(a)") # Select all - keyboard.press_and_release("backspace") # Delete selected all - time.sleep(0.5) # Wait for RUN window will appear ctrl+a+backspace is async - so we need some timeout... + KeyboardHotkey("win","r") # win+r + KeyboardHotkey("ctrl","a") # Select all + keyboard.send("backspace") # Delete selected all + time.sleep(gKeyboardHotkeyDelaySecFloat) # Wait for RUN window will appear ctrl+a+backspace is async - so we need some timeout... lInputStr = f"cmd /c ({inCMDCommandStr}) {lCMDPostFixStr}" # Generate the output string for RUN window keyboard.write(lInputStr) # Write new text - time.sleep(0.5) - lRDPWindow.type_keys("^(a)") # Select all - lRDPWindow.type_keys("^(c)") # Copy data + time.sleep(gKeyboardHotkeyDelaySecFloat) + KeyboardHotkey("ctrl","a") # Select all + KeyboardHotkey("ctrl","c") # Copy data # Check the clipboard lClipboardWaitTimeStartSec = time.time() lClipboardStr = Clipboard.TextGet() # Get text from clipboard @@ -392,4 +393,12 @@ def SystemRDPWarningClickOk(): UIDesktop.UIOSelector_Get_UIO([{"title": "Remote Desktop Connection", "class_name": "#32770", "backend": "win32"}, {"title": "OK", "class_name": "Button"}]).click() except Exception as e: - pass \ No newline at end of file + pass +# Bugfix with RDP work +def KeyboardHotkey(inModifierKeyStr,inKeyStr, inDelaySecFloat=gKeyboardHotkeyDelaySecFloat): + keyboard.press(inModifierKeyStr) + time.sleep(inDelaySecFloat) + keyboard.send(inKeyStr) + time.sleep(inDelaySecFloat) + keyboard.release(inModifierKeyStr) + time.sleep(inDelaySecFloat) \ 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 3b670128..ae71eab7 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 @@ -64,8 +64,8 @@ def RDPSessionLogoff(inRDPSessionKeyStr): # Calculate the session Hex lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) if lSessionHex: - # Run CMD - Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="CROSSCHECK", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) + # Run CMD - dont crosscheck because CMD dont return value to the clipboard when logoff + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN", inLogger=gSettings["Logger"], inRDPConfigurationItem=gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]) gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList return lResult 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 6c4252f6..87219230 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.3' +__version__ = 'v1.1.4' __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 6c4252f6..87219230 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.1.3' +__version__ = 'v1.1.4' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/v1.1.3 b/v1.1.4 similarity index 100% rename from v1.1.3 rename to v1.1.4 From 77c7cebd047673ed08ffd55bce51954603017e12 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Tue, 2 Jun 2020 08:23:17 +0300 Subject: [PATCH 02/19] # Add Activity in RDP: RDPSessionMonitorStop --- Sources/pyOpenRPA/Orchestrator/Processor.py | 2 +- Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py | 7 +++++++ v1.1.4 => v1.1.5 | 0 3 files changed, 8 insertions(+), 1 deletion(-) rename v1.1.4 => v1.1.5 (100%) diff --git a/Sources/pyOpenRPA/Orchestrator/Processor.py b/Sources/pyOpenRPA/Orchestrator/Processor.py index b1800f58..18f51448 100644 --- a/Sources/pyOpenRPA/Orchestrator/Processor.py +++ b/Sources/pyOpenRPA/Orchestrator/Processor.py @@ -56,7 +56,7 @@ import psutil # "Type":"ProcessStop", # "Name":"", # "FlagForce":True, -# "User":"" #Empty, user or %username% +# "User":"" #Empty - all users, user or %username% # }, # { # "Type":"PythonStart", diff --git a/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py b/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py index ae71eab7..20cd033e 100644 --- a/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py +++ b/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py @@ -56,6 +56,13 @@ def RDPSessionReconnect(inRDPSessionKeyStr): Connector.Session(lRDPConfigurationItem) return True +# Stop track the RDP session. Current def dont kill RDP session - only stop to track it (it can give ) +def RDPSessionMonitorStop(inRDPSessionKeyStr): + global gSettings + lResult = True + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList + return lResult + # Logoff the RDP session def RDPSessionLogoff(inRDPSessionKeyStr): global gSettings diff --git a/v1.1.4 b/v1.1.5 similarity index 100% rename from v1.1.4 rename to v1.1.5 From 636a8e63bbc6b3670832115d606c20d92d7120ce Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Tue, 2 Jun 2020 08:25:14 +0300 Subject: [PATCH 03/19] # Add updated python with openRPA to 1.1.5 --- .../INSTALLER | 0 .../pyOpenRPA-1.1.5.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.5.dist-info}/RECORD | 18 +++++++++--------- .../WHEEL | 0 .../top_level.txt | 0 .../pyOpenRPA/Orchestrator/Processor.py | 2 +- .../Orchestrator/RobotRDPActive/Processor.py | 7 +++++++ .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- .../INSTALLER | 0 .../pyOpenRPA-1.1.5.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.5.dist-info}/RECORD | 18 +++++++++--------- .../WHEEL | 0 .../top_level.txt | 0 .../pyOpenRPA/Orchestrator/Processor.py | 2 +- .../Orchestrator/RobotRDPActive/Processor.py | 7 +++++++ .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- Sources/pyOpenRPA/__init__.py | 2 +- 17 files changed, 39 insertions(+), 25 deletions(-) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.4.dist-info => pyOpenRPA-1.1.5.dist-info}/INSTALLER (100%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info}/METADATA (99%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info}/RECORD (97%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.4.dist-info => pyOpenRPA-1.1.5.dist-info}/WHEEL (100%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.4.dist-info => pyOpenRPA-1.1.5.dist-info}/top_level.txt (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.4.dist-info => pyOpenRPA-1.1.5.dist-info}/INSTALLER (100%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info}/METADATA (99%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info}/RECORD (97%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.4.dist-info => pyOpenRPA-1.1.5.dist-info}/WHEEL (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.4.dist-info => pyOpenRPA-1.1.5.dist-info}/top_level.txt (100%) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA index 4e938337..48b0e094 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.4 +Version: 1.1.5 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.4.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD similarity index 97% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD index b6d8893d..af5054a1 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD @@ -1,22 +1,22 @@ -pyOpenRPA-1.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.4.dist-info/METADATA,sha256=E8N30TKbMhQ1CUfXUxJT7T9MUmNpNx7lBcss27Y2pbg,3541 -pyOpenRPA-1.1.4.dist-info/RECORD,, -pyOpenRPA-1.1.4.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.4.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.5.dist-info/METADATA,sha256=oa4ndZiOhpyVqByJvk5F5fSyQ62ke1RPGhwO9UFDG3c,3541 +pyOpenRPA-1.1.5.dist-info/RECORD,, +pyOpenRPA-1.1.5.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.5.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 pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0,408 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 -pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 +pyOpenRPA/.idea/workspace.xml,sha256=lPQFI_kfLXE7-PICt5O--RAJU_0f8APV_q5Rm5q9xq8,2912 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 -pyOpenRPA/Orchestrator/Processor.py,sha256=mPSv3xO1ah1BzhQdfltt77_tJrmKP9CAfwqeFAqeTFY,11364 +pyOpenRPA/Orchestrator/Processor.py,sha256=ur0jDDteyBzfXR4DXnpUfBwNEW-M2nEtgyd-HQoPVtQ,11376 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=MkxTVaOVITl1V3EvH3oNx2gbCx3EeRS9Gb_83rmjdjg,25553 pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=NMIcP38qE7LcIvm9IJMoDVE1VCDLx6WgJHqUzV6IN7A,8720 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=PkJxD04pjniU2eaHY_v8UK9aXRYoc6mNLyN-vek89cc,9036 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 @@ -300,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=esqQQhb49aasfe2keriHnVJulnmS1EWRJgsf0fp5UmQ,174 +pyOpenRPA/__init__.py,sha256=ngE8yR10-argUOXI73_B2fC66l80-yt6r6KHN7c-Kkg,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.4.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt 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 b1800f58..18f51448 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 @@ -56,7 +56,7 @@ import psutil # "Type":"ProcessStop", # "Name":"", # "FlagForce":True, -# "User":"" #Empty, user or %username% +# "User":"" #Empty - all users, user or %username% # }, # { # "Type":"PythonStart", 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 ae71eab7..20cd033e 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 @@ -56,6 +56,13 @@ def RDPSessionReconnect(inRDPSessionKeyStr): Connector.Session(lRDPConfigurationItem) return True +# Stop track the RDP session. Current def dont kill RDP session - only stop to track it (it can give ) +def RDPSessionMonitorStop(inRDPSessionKeyStr): + global gSettings + lResult = True + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList + return lResult + # Logoff the RDP session def RDPSessionLogoff(inRDPSessionKeyStr): global gSettings 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 87219230..ab89af4d 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.4' +__version__ = 'v1.1.5' __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.4.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/INSTALLER rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA similarity index 99% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA index 4e938337..48b0e094 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/METADATA +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.4 +Version: 1.1.5 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.4.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD similarity index 97% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD index b6d8893d..af5054a1 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/RECORD +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD @@ -1,22 +1,22 @@ -pyOpenRPA-1.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.4.dist-info/METADATA,sha256=E8N30TKbMhQ1CUfXUxJT7T9MUmNpNx7lBcss27Y2pbg,3541 -pyOpenRPA-1.1.4.dist-info/RECORD,, -pyOpenRPA-1.1.4.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.4.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.5.dist-info/METADATA,sha256=oa4ndZiOhpyVqByJvk5F5fSyQ62ke1RPGhwO9UFDG3c,3541 +pyOpenRPA-1.1.5.dist-info/RECORD,, +pyOpenRPA-1.1.5.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.5.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 pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0,408 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 -pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 +pyOpenRPA/.idea/workspace.xml,sha256=lPQFI_kfLXE7-PICt5O--RAJU_0f8APV_q5Rm5q9xq8,2912 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 -pyOpenRPA/Orchestrator/Processor.py,sha256=mPSv3xO1ah1BzhQdfltt77_tJrmKP9CAfwqeFAqeTFY,11364 +pyOpenRPA/Orchestrator/Processor.py,sha256=ur0jDDteyBzfXR4DXnpUfBwNEW-M2nEtgyd-HQoPVtQ,11376 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=MkxTVaOVITl1V3EvH3oNx2gbCx3EeRS9Gb_83rmjdjg,25553 pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=NMIcP38qE7LcIvm9IJMoDVE1VCDLx6WgJHqUzV6IN7A,8720 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=PkJxD04pjniU2eaHY_v8UK9aXRYoc6mNLyN-vek89cc,9036 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 @@ -300,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=esqQQhb49aasfe2keriHnVJulnmS1EWRJgsf0fp5UmQ,174 +pyOpenRPA/__init__.py,sha256=ngE8yR10-argUOXI73_B2fC66l80-yt6r6KHN7c-Kkg,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.4.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/WHEEL similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/WHEEL rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/WHEEL diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.4.dist-info/top_level.txt rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt 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 b1800f58..18f51448 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 @@ -56,7 +56,7 @@ import psutil # "Type":"ProcessStop", # "Name":"", # "FlagForce":True, -# "User":"" #Empty, user or %username% +# "User":"" #Empty - all users, user or %username% # }, # { # "Type":"PythonStart", 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 ae71eab7..20cd033e 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 @@ -56,6 +56,13 @@ def RDPSessionReconnect(inRDPSessionKeyStr): Connector.Session(lRDPConfigurationItem) return True +# Stop track the RDP session. Current def dont kill RDP session - only stop to track it (it can give ) +def RDPSessionMonitorStop(inRDPSessionKeyStr): + global gSettings + lResult = True + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) # Remove item from RDPList + return lResult + # Logoff the RDP session def RDPSessionLogoff(inRDPSessionKeyStr): global gSettings 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 87219230..ab89af4d 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.4' +__version__ = 'v1.1.5' __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 87219230..ab89af4d 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.1.4' +__version__ = 'v1.1.5' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file From 26cf5634092061e53845a73411ee8cb3332bf9ea Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sat, 6 Jun 2020 10:57:25 +0300 Subject: [PATCH 04/19] # Add new code to WorkLogger (detect keys with current language) --- Utils/WorkLogger/PythonDebug_64.cmd | 2 +- .../pyWorkLogger/Catcher/Keyboard.py | 97 +++++++++++++++++++ .../pyWorkLogger/Catcher/__init__.py | 0 Utils/WorkLogger/pyWorkLogger/__init__.py | 0 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py create mode 100644 Utils/WorkLogger/pyWorkLogger/Catcher/__init__.py create mode 100644 Utils/WorkLogger/pyWorkLogger/__init__.py diff --git a/Utils/WorkLogger/PythonDebug_64.cmd b/Utils/WorkLogger/PythonDebug_64.cmd index e77dc7e2..20ca488a 100644 --- a/Utils/WorkLogger/PythonDebug_64.cmd +++ b/Utils/WorkLogger/PythonDebug_64.cmd @@ -1,2 +1,2 @@ -..\..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe WorkLogger.py +..\..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe "pyWorkLogger\Catcher\Keyboard.py" pause >nul \ No newline at end of file diff --git a/Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py b/Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py new file mode 100644 index 00000000..82c05da6 --- /dev/null +++ b/Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py @@ -0,0 +1,97 @@ +from pynput import keyboard + + +# Init the keyboard listener +def Init(inGSettings): + pass +def lang(): + # https://stackoverflow.com/questions/42047253/how-to-detect-current-keyboard-language-in-python + # My keyboard is set to the English - United States keyboard + import ctypes + # For debugging Windows error codes in the current thread + user32 = ctypes.WinDLL('user32', use_last_error=True) + curr_window = user32.GetForegroundWindow() + thread_id = user32.GetWindowThreadProcessId(curr_window, 0) + # Made up of 0xAAABBBB, AAA = HKL (handle object) & BBBB = language ID + klid = user32.GetKeyboardLayout(thread_id) + # Language ID -> low 10 bits, Sub-language ID -> high 6 bits + # Extract language ID from KLID + lid = klid & (2**16 - 1) + # Convert language ID from decimal to hexadecimal + lid_hex = hex(lid) + + # I switched my keyboard to the Russian keyboard + curr_window = user32.GetForegroundWindow() + thread_id = user32.GetWindowThreadProcessId(curr_window, 0) + klid = user32.GetKeyboardLayout(thread_id) + #print("LANG:", klid) + # Extract language ID from KLID + lid = klid & (2**16 - 1) + # Convert language ID from decimal to hexadecimal + lid_hex = hex(lid) + #print("LANG:",lid) + return klid + +# https://stackoverflow.com/questions/38224277/tounicodeex-always-returns-0-in-python +from ctypes import * +_ToUnicodeEx = WinDLL('user32').ToUnicodeEx +_ToUnicodeEx.argtypes = [c_uint,c_uint,POINTER(c_char),POINTER(c_wchar),c_int,c_uint,c_void_p] +_ToUnicodeEx.restype = c_int +def ToUn(vk,sc,wfl,hkid): + kst = create_string_buffer(256) + b = create_unicode_buffer(5) + windll.User32.GetKeyboardState(kst) + y= _ToUnicodeEx(vk,sc,kst,b,5,wfl,hkid) + VK_SHIFT = 0x10 + VK_CAPITAL = 0x14 + shifted = False + # TODO UPPER CASE https://stackoverflow.com/questions/42037204/why-getkeystate-changed-the-behavior-of-tounicodeex + if windll.User32.GetKeyboardState(VK_SHIFT) < 0: + shifted = True + if windll.User32.GetKeyboardState(VK_CAPITAL) < 0: + shifted = True + if shifted: + return b.value.upper() + return b.value +#print(ToUn(65,0,0,windll.User32.GetKeyboardLayout(1))) +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Technical defs +import pdb +def on_press(key): + try: + print('alphanumeric key {0} pressed'.format( + key.char)) + #print("__",dir(key)) + import win32api + MAPVK_VK_TO_CHAR = 0 + #scancode = win32api.MapVirtualKey(key.vk, MAPVK_VK_TO_CHAR) + from ctypes import windll + #result = windll.User32.MapVirtualKeyExA(key.vk,MAPVK_VK_TO_CHAR,windll.User32.GetKeyboardLayout(1)) + print("WINDOWS:",ToUn(key.vk, key._scan, 0, lang())) + + #print("WINDOWS:",result) + except AttributeError: + print('special key {0} pressed'.format( + key)) + return True + +def on_release(key): + print('{0} released'.format( + key)) + #pdb.set_trace() + if key == keyboard.Key.esc: + # Stop listener + return True + +# Collect events until released +while True: + with keyboard.Listener( + on_press=on_press, + on_release=on_release) as listener: + listener.join() + +# ...or, in a non-blocking fashion: +listener = keyboard.Listener( + on_press=on_press, + on_release=on_release) +listener.start() \ No newline at end of file diff --git a/Utils/WorkLogger/pyWorkLogger/Catcher/__init__.py b/Utils/WorkLogger/pyWorkLogger/Catcher/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Utils/WorkLogger/pyWorkLogger/__init__.py b/Utils/WorkLogger/pyWorkLogger/__init__.py new file mode 100644 index 00000000..e69de29b From 04e441a25984613e47c609077e6c9f7a37865c46 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sat, 6 Jun 2020 23:55:38 +0300 Subject: [PATCH 05/19] WorkLogger in progress --- .../pyWorkLogger/Catcher/Keyboard.py | 98 +++++++++++++------ 1 file changed, 67 insertions(+), 31 deletions(-) diff --git a/Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py b/Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py index 82c05da6..92f00814 100644 --- a/Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py +++ b/Utils/WorkLogger/pyWorkLogger/Catcher/Keyboard.py @@ -1,29 +1,22 @@ from pynput import keyboard - - +import datetime # datetime functions +import time # time functions # Init the keyboard listener def Init(inGSettings): pass -def lang(): +def lang(inKLID = None): # https://stackoverflow.com/questions/42047253/how-to-detect-current-keyboard-language-in-python # My keyboard is set to the English - United States keyboard import ctypes # For debugging Windows error codes in the current thread user32 = ctypes.WinDLL('user32', use_last_error=True) - curr_window = user32.GetForegroundWindow() - thread_id = user32.GetWindowThreadProcessId(curr_window, 0) - # Made up of 0xAAABBBB, AAA = HKL (handle object) & BBBB = language ID - klid = user32.GetKeyboardLayout(thread_id) - # Language ID -> low 10 bits, Sub-language ID -> high 6 bits - # Extract language ID from KLID - lid = klid & (2**16 - 1) - # Convert language ID from decimal to hexadecimal - lid_hex = hex(lid) - # I switched my keyboard to the Russian keyboard curr_window = user32.GetForegroundWindow() thread_id = user32.GetWindowThreadProcessId(curr_window, 0) - klid = user32.GetKeyboardLayout(thread_id) + # Made up of 0xAAABBBB, AAA = HKL (handle object) & BBBB = language ID + klid = inKLID + if klid is None: + klid = user32.GetKeyboardLayout(thread_id) # English = 67699721, Russian = 68748313 #print("LANG:", klid) # Extract language ID from KLID lid = klid & (2**16 - 1) @@ -57,41 +50,84 @@ def ToUn(vk,sc,wfl,hkid): # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Technical defs import pdb +SpecialKeyList = [] +inList = [ + # { + # "EventDatetime": datetime.datetime.now(), + # "EventTypeStr": "HOTKEY" # HOTKEY | CHARACTER | DELETE + # "ValueStr": "" # HOTKEY: alt_l+shift or ctrl_l+c + # } +] + def on_press(key): + lResult = { "EventDatetime": datetime.datetime.now(), "EventTypeStr": "HOTKEY", "ValueStr": ""} try: - print('alphanumeric key {0} pressed'.format( - key.char)) + #print('alphanumeric key {0} pressed'.format( + # key.char)) #print("__",dir(key)) import win32api MAPVK_VK_TO_CHAR = 0 #scancode = win32api.MapVirtualKey(key.vk, MAPVK_VK_TO_CHAR) from ctypes import windll #result = windll.User32.MapVirtualKeyExA(key.vk,MAPVK_VK_TO_CHAR,windll.User32.GetKeyboardLayout(1)) - print("WINDOWS:",ToUn(key.vk, key._scan, 0, lang())) - - #print("WINDOWS:",result) + lDestKey = ToUn(key.vk, key._scan, 0, lang()) + if str(key).isupper(): + lDestKey = lDestKey.upper() + #print("WINDOWS:",lDestKey) + # Add result in list + if len(SpecialKeyList) > 0 and not (len(SpecialKeyList)==1 and "shift" in SpecialKeyList): + lDestKey = ToUn(key.vk, key._scan, 0, 67699721) # English = 67699721 + lResult["EventTypeStr"] = "HOTKEY" + lResult["ValueStr"] = '+'.join(SpecialKeyList)+f"+{lDestKey}" + else: + lResult["EventTypeStr"] = "CHARACTER" + lResult["ValueStr"] = lDestKey + print(lResult) + inList.append(lResult) except AttributeError: - print('special key {0} pressed'.format( - key)) - return True + #print('special key {0} pressed'.format( + # key)) + lKeyStr = str(key)[4:] + # Check if not the delete or backspace + if lKeyStr != "backspace" and lKeyStr != "delete": + SpecialKeyList.append(lKeyStr) + # Add result in list + if len(SpecialKeyList) >= 2 or (lKeyStr != "shift" and lKeyStr != "ctrl_l" and lKeyStr != "ctrl_r" and lKeyStr != "alt_l" and lKeyStr != "alt_r" and lKeyStr != "shift_r"): + lResult["EventTypeStr"] = "HOTKEY" + lResult["ValueStr"] = '+'.join(SpecialKeyList) + inList.append(lResult) + print(lResult) + else: + lResult["EventTypeStr"] = "DELETE" + lResult["ValueStr"] = ('+'.join(SpecialKeyList)+f"+{lKeyStr}" if len(SpecialKeyList)>0 else f"{lKeyStr}") + inList.append(lResult) + print(lResult) + #return True def on_release(key): - print('{0} released'.format( - key)) - #pdb.set_trace() + if len(SpecialKeyList)>0: + try: + SpecialKeyList.remove(str(key)[4:]) + except Exception as e: + pass if key == keyboard.Key.esc: # Stop listener return True # Collect events until released -while True: - with keyboard.Listener( - on_press=on_press, - on_release=on_release) as listener: - listener.join() +#while True: +# with keyboard.Listener( +# on_press=on_press, +# on_release=on_release) as listener: +# listener.join() # ...or, in a non-blocking fashion: listener = keyboard.Listener( on_press=on_press, on_release=on_release) -listener.start() \ No newline at end of file +listener.start() +import pprint +while True: + time.sleep(5) + #print(inList) + #pprint.pprint(inList) \ No newline at end of file From b03d854e90f5129091065fd16009df80d084f7a7 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sun, 7 Jun 2020 10:28:08 +0300 Subject: [PATCH 06/19] # Worklogger --- .../mouse-0.7.1.dist-info/INSTALLER | 1 + .../mouse-0.7.1.dist-info/LICENSE.txt | 21 ++ .../mouse-0.7.1.dist-info/METADATA | 62 ++++ .../mouse-0.7.1.dist-info/RECORD | 22 ++ .../site-packages/mouse-0.7.1.dist-info/WHEEL | 6 + .../mouse-0.7.1.dist-info/top_level.txt | 1 + .../Lib/site-packages/mouse/__init__.py | 272 ++++++++++++++++++ .../Lib/site-packages/mouse/__main__.py | 27 ++ .../Lib/site-packages/mouse/_generic.py | 72 +++++ .../Lib/site-packages/mouse/_mouse_event.py | 20 ++ .../Lib/site-packages/mouse/_mouse_tests.py | 271 +++++++++++++++++ .../Lib/site-packages/mouse/_nixcommon.py | 165 +++++++++++ .../Lib/site-packages/mouse/_nixmouse.py | 131 +++++++++ .../Lib/site-packages/mouse/_winmouse.py | 216 ++++++++++++++ .../mouse-0.7.1.dist-info/INSTALLER | 1 + .../mouse-0.7.1.dist-info/LICENSE.txt | 21 ++ .../mouse-0.7.1.dist-info/METADATA | 62 ++++ .../mouse-0.7.1.dist-info/RECORD | 22 ++ .../site-packages/mouse-0.7.1.dist-info/WHEEL | 6 + .../mouse-0.7.1.dist-info/top_level.txt | 1 + .../Lib/site-packages/mouse/__init__.py | 272 ++++++++++++++++++ .../Lib/site-packages/mouse/__main__.py | 27 ++ .../Lib/site-packages/mouse/_generic.py | 72 +++++ .../Lib/site-packages/mouse/_mouse_event.py | 20 ++ .../Lib/site-packages/mouse/_mouse_tests.py | 271 +++++++++++++++++ .../Lib/site-packages/mouse/_nixcommon.py | 165 +++++++++++ .../Lib/site-packages/mouse/_nixmouse.py | 131 +++++++++ .../Lib/site-packages/mouse/_winmouse.py | 216 ++++++++++++++ .../WorkLogger/pyWorkLogger/Catcher/Mouse.py | 125 ++++++++ 29 files changed, 2699 insertions(+) create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/METADATA create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/RECORD create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__init__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__main__.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_generic.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_event.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_tests.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixcommon.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixmouse.py create mode 100644 Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_winmouse.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/METADATA create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/RECORD create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__init__.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__main__.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_generic.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_event.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_tests.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixcommon.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixmouse.py create mode 100644 Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_winmouse.py create mode 100644 Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt new file mode 100644 index 00000000..4f3cb7b8 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Lucas Boppre Niehues + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/METADATA new file mode 100644 index 00000000..c6dfc0d2 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/METADATA @@ -0,0 +1,62 @@ +Metadata-Version: 2.1 +Name: mouse +Version: 0.7.1 +Summary: Hook and simulate mouse events on Windows and Linux +Home-page: https://github.com/boppreh/mouse +Author: BoppreH +Author-email: boppreh@gmail.com +License: MIT +Keywords: mouse hook simulate hotkey +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: Unix +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Description-Content-Type: text/markdown + + +mouse +===== + +Take full control of your mouse with this small Python library. Hook global events, register hotkeys, simulate mouse movement and clicks, and much more. + +_Huge thanks to [Kirill Pavlov](http://kirillpavlov.com/) for donating the package name. If you are looking for the Cheddargetter.com client implementation, [`pip install mouse==0.5.0`](https://pypi.python.org/pypi/mouse/0.5.0)._ + +## Features + +- Global event hook on all mice devices (captures events regardless of focus). +- **Listen** and **sends** mouse events. +- Works with **Windows** and **Linux** (requires sudo). +- **Pure Python**, no C modules to be compiled. +- **Zero dependencies**. Trivial to install and deploy, just copy the files. +- **Python 2 and 3**. +- Includes **high level API** (e.g. [record](#mouse.record) and [play](#mouse.play). +- Events automatically captured in separate thread, doesn't block main program. +- Tested and documented. + +This program makes no attempt to hide itself, so don't use it for keyloggers. + +## Usage + +Install the [PyPI package](https://pypi.python.org/pypi/mouse/): + + $ sudo pip install mouse + +or clone the repository (no installation required, source files are sufficient): + + $ git clone https://github.com/boppreh/mouse + +Then check the [API docs](https://github.com/boppreh/mouse#api) to see what features are available. + + +## Known limitations: + +- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21) +- To avoid depending on X the Linux parts reads raw device files (`/dev/input/input*`) but this requries root. +- Other applications, such as some games, may register hooks that swallow all key events. In this case `mouse` will be unable to report events. + + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/RECORD new file mode 100644 index 00000000..c46d9df0 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/RECORD @@ -0,0 +1,22 @@ +mouse-0.7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +mouse-0.7.1.dist-info/LICENSE.txt,sha256=K_FKUlVV0FqAHC0sKJAVBPt2q-58LX6_tM_HUI198Pc,1077 +mouse-0.7.1.dist-info/METADATA,sha256=7MmeikMZ3xgUFvcSNMnCnXugXuG0ag8QjFoOV1k9mr0,2455 +mouse-0.7.1.dist-info/RECORD,, +mouse-0.7.1.dist-info/WHEEL,sha256=JZXtYepZFsf4IoivNpnSgKIc4qTHan08DRd56koo_DM,116 +mouse-0.7.1.dist-info/top_level.txt,sha256=FiA9sXRt9_B8X6je4BlPesL9EakrmGZ0fDKPK09Ql6U,6 +mouse/__init__.py,sha256=HGaiOxH8PuKnU2oCLN5pEN4yuvxH1JoxT1QXwITFlf0,9147 +mouse/__main__.py,sha256=Rir1qIanuA6OUsVIywo71MgF1PrVCdZ77F1FPOu4JA0,625 +mouse/__pycache__/__init__.cpython-37.pyc,, +mouse/__pycache__/__main__.cpython-37.pyc,, +mouse/__pycache__/_generic.cpython-37.pyc,, +mouse/__pycache__/_mouse_event.cpython-37.pyc,, +mouse/__pycache__/_mouse_tests.cpython-37.pyc,, +mouse/__pycache__/_nixcommon.cpython-37.pyc,, +mouse/__pycache__/_nixmouse.cpython-37.pyc,, +mouse/__pycache__/_winmouse.cpython-37.pyc,, +mouse/_generic.py,sha256=STzfL7AUAkcAq6XUyxpQiOYnBnQ1TZjWL1cSFSZ61_o,2132 +mouse/_mouse_event.py,sha256=zRQGO6M6nbA-jvhI0yz4HzvQNcScF48PZ9iRegcTVjQ,422 +mouse/_mouse_tests.py,sha256=gNa_NW5sRIsbLMG35ZfXal3eHS2mEpEPhysJRDq0gQA,10000 +mouse/_nixcommon.py,sha256=FNXiCv7u_A0SzcYJQlYDJBSdIN6IUTVLG4g7oqXgj6o,5552 +mouse/_nixmouse.py,sha256=3htKn9XkUApFqp3rGCT-ZQIqJFf4iGqoxxoO9MY2x4k,3576 +mouse/_winmouse.py,sha256=lWAnfGq0etNjFR-vE9e3r9N7Amg5wU957B4ZS3YMTz0,6449 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL new file mode 100644 index 00000000..8b701e93 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.6) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt new file mode 100644 index 00000000..3e41be96 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt @@ -0,0 +1 @@ +mouse diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__init__.py new file mode 100644 index 00000000..3a21f46e --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__init__.py @@ -0,0 +1,272 @@ +# -*- coding: utf-8 -*- +""" +mouse +===== + +Take full control of your mouse with this small Python library. Hook global events, register hotkeys, simulate mouse movement and clicks, and much more. + +_Huge thanks to [Kirill Pavlov](http://kirillpavlov.com/) for donating the package name. If you are looking for the Cheddargetter.com client implementation, [`pip install mouse==0.5.0`](https://pypi.python.org/pypi/mouse/0.5.0)._ + +## Features + +- Global event hook on all mice devices (captures events regardless of focus). +- **Listen** and **sends** mouse events. +- Works with **Windows** and **Linux** (requires sudo). +- **Pure Python**, no C modules to be compiled. +- **Zero dependencies**. Trivial to install and deploy, just copy the files. +- **Python 2 and 3**. +- Includes **high level API** (e.g. [record](#mouse.record) and [play](#mouse.play). +- Events automatically captured in separate thread, doesn't block main program. +- Tested and documented. + +This program makes no attempt to hide itself, so don't use it for keyloggers. + +## Usage + +Install the [PyPI package](https://pypi.python.org/pypi/mouse/): + + $ sudo pip install mouse + +or clone the repository (no installation required, source files are sufficient): + + $ git clone https://github.com/boppreh/mouse + +Then check the [API docs](https://github.com/boppreh/mouse#api) to see what features are available. + + +## Known limitations: + +- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21) +- To avoid depending on X the Linux parts reads raw device files (`/dev/input/input*`) but this requries root. +- Other applications, such as some games, may register hooks that swallow all key events. In this case `mouse` will be unable to report events. +""" +# TODO +# - infinite wait +# - mouse.on_move +version = '0.7.1' + +import time as _time + +import platform as _platform +if _platform.system() == 'Windows': + from. import _winmouse as _os_mouse +elif _platform.system() == 'Linux': + from. import _nixmouse as _os_mouse +else: + raise OSError("Unsupported platform '{}'".format(_platform.system())) + +from ._mouse_event import ButtonEvent, MoveEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE +from ._generic import GenericListener as _GenericListener + +_pressed_events = set() +class _MouseListener(_GenericListener): + def init(self): + _os_mouse.init() + def pre_process_event(self, event): + if isinstance(event, ButtonEvent): + if event.event_type in (UP, DOUBLE): + _pressed_events.discard(event.button) + else: + _pressed_events.add(event.button) + return True + + def listen(self): + _os_mouse.listen(self.queue) + +_listener = _MouseListener() + +def is_pressed(button=LEFT): + """ Returns True if the given button is currently pressed. """ + _listener.start_if_necessary() + return button in _pressed_events + +def press(button=LEFT): + """ Presses the given button (but doesn't release). """ + _os_mouse.press(button) + +def release(button=LEFT): + """ Releases the given button. """ + _os_mouse.release(button) + +def click(button=LEFT): + """ Sends a click with the given button. """ + _os_mouse.press(button) + _os_mouse.release(button) + +def double_click(button=LEFT): + """ Sends a double click with the given button. """ + click(button) + click(button) + +def right_click(): + """ Sends a right click with the given button. """ + click(RIGHT) + +def wheel(delta=1): + """ Scrolls the wheel `delta` clicks. Sign indicates direction. """ + _os_mouse.wheel(delta) + +def move(x, y, absolute=True, duration=0): + """ + Moves the mouse. If `absolute`, to position (x, y), otherwise move relative + to the current position. If `duration` is non-zero, animates the movement. + """ + x = int(x) + y = int(y) + + # Requires an extra system call on Linux, but `move_relative` is measured + # in millimiters so we would lose precision. + position_x, position_y = get_position() + + if not absolute: + x = position_x + x + y = position_y + y + + if duration: + start_x = position_x + start_y = position_y + dx = x - start_x + dy = y - start_y + + if dx == 0 and dy == 0: + _time.sleep(duration) + else: + # 120 movements per second. + # Round and keep float to ensure float division in Python 2 + steps = max(1.0, float(int(duration * 120.0))) + for i in range(int(steps)+1): + move(start_x + dx*i/steps, start_y + dy*i/steps) + _time.sleep(duration/steps) + else: + _os_mouse.move_to(x, y) + +def drag(start_x, start_y, end_x, end_y, absolute=True, duration=0): + """ + Holds the left mouse button, moving from start to end position, then + releases. `absolute` and `duration` are parameters regarding the mouse + movement. + """ + if is_pressed(): + release() + move(start_x, start_y, absolute, 0) + press() + move(end_x, end_y, absolute, duration) + release() + +def on_button(callback, args=(), buttons=(LEFT, MIDDLE, RIGHT, X, X2), types=(UP, DOWN, DOUBLE)): + """ Invokes `callback` with `args` when the specified event happens. """ + if not isinstance(buttons, (tuple, list)): + buttons = (buttons,) + if not isinstance(types, (tuple, list)): + types = (types,) + + def handler(event): + if isinstance(event, ButtonEvent): + if event.event_type in types and event.button in buttons: + callback(*args) + _listener.add_handler(handler) + return handler + +def on_click(callback, args=()): + """ Invokes `callback` with `args` when the left button is clicked. """ + return on_button(callback, args, [LEFT], [UP]) + +def on_double_click(callback, args=()): + """ + Invokes `callback` with `args` when the left button is double clicked. + """ + return on_button(callback, args, [LEFT], [DOUBLE]) + +def on_right_click(callback, args=()): + """ Invokes `callback` with `args` when the right button is clicked. """ + return on_button(callback, args, [RIGHT], [UP]) + +def on_middle_click(callback, args=()): + """ Invokes `callback` with `args` when the middle button is clicked. """ + return on_button(callback, args, [MIDDLE], [UP]) + +def wait(button=LEFT, target_types=(UP, DOWN, DOUBLE)): + """ + Blocks program execution until the given button performs an event. + """ + from threading import Lock + lock = Lock() + lock.acquire() + handler = on_button(lock.release, (), [button], target_types) + lock.acquire() + _listener.remove_handler(handler) + +def get_position(): + """ Returns the (x, y) mouse position. """ + return _os_mouse.get_position() + +def hook(callback): + """ + Installs a global listener on all available mouses, invoking `callback` + each time it is moved, a key status changes or the wheel is spun. A mouse + event is passed as argument, with type either `mouse.ButtonEvent`, + `mouse.WheelEvent` or `mouse.MoveEvent`. + + Returns the given callback for easier development. + """ + _listener.add_handler(callback) + return callback + +def unhook(callback): + """ + Removes a previously installed hook. + """ + _listener.remove_handler(callback) + +def unhook_all(): + """ + Removes all hooks registered by this application. Note this may include + hooks installed by high level functions, such as `record`. + """ + del _listener.handlers[:] + +def record(button=RIGHT, target_types=(DOWN,)): + """ + Records all mouse events until the user presses the given button. + Then returns the list of events recorded. Pairs well with `play(events)`. + + Note: this is a blocking function. + Note: for more details on the mouse hook and events see `hook`. + """ + recorded = [] + hook(recorded.append) + wait(button=button, target_types=target_types) + unhook(recorded.append) + return recorded + +def play(events, speed_factor=1.0, include_clicks=True, include_moves=True, include_wheel=True): + """ + Plays a sequence of recorded events, maintaining the relative time + intervals. If speed_factor is <= 0 then the actions are replayed as fast + as the OS allows. Pairs well with `record()`. + + The parameters `include_*` define if events of that type should be inluded + in the replay or ignored. + """ + last_time = None + for event in events: + if speed_factor > 0 and last_time is not None: + _time.sleep((event.time - last_time) / speed_factor) + last_time = event.time + + if isinstance(event, ButtonEvent) and include_clicks: + if event.event_type == UP: + _os_mouse.release(event.button) + else: + _os_mouse.press(event.button) + elif isinstance(event, MoveEvent) and include_moves: + _os_mouse.move_to(event.x, event.y) + elif isinstance(event, WheelEvent) and include_wheel: + _os_mouse.wheel(event.delta) + +replay = play +hold = press + +if __name__ == '__main__': + print('Recording... Double click to stop and replay.') + play(record()) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__main__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__main__.py new file mode 100644 index 00000000..1a84defc --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/__main__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +import mouse +import fileinput +import json +import sys + +class_by_name = { + 'ButtonEvent': mouse.ButtonEvent, + 'WheelEvent': mouse.WheelEvent, + 'MoveEvent': mouse.MoveEvent, +} + +def print_event_json(event): + # Could use json.dumps(event.__dict__()), but this way we guarantee semantic order. + d = event._asdict() + d['event_class'] = event.__class__.__name__ + print(json.dumps(d)) + sys.stdout.flush() +mouse.hook(print_event_json) + +def load(line): + d = json.loads(line) + class_ = class_by_name[d['event_class']] + del d['event_class'] + return class_(**d) + +mouse.play(load(line) for line in fileinput.input()) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_generic.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_generic.py new file mode 100644 index 00000000..04f029e7 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_generic.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +from threading import Thread, Lock +import traceback +import functools + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +class GenericListener(object): + lock = Lock() + + def __init__(self): + self.handlers = [] + self.listening = False + self.queue = Queue() + + def invoke_handlers(self, event): + for handler in self.handlers: + try: + if handler(event): + # Stop processing this hotkey. + return 1 + except Exception as e: + traceback.print_exc() + + def start_if_necessary(self): + """ + Starts the listening thread if it wasn't already. + """ + self.lock.acquire() + try: + if not self.listening: + self.init() + + self.listening = True + self.listening_thread = Thread(target=self.listen) + self.listening_thread.daemon = True + self.listening_thread.start() + + self.processing_thread = Thread(target=self.process) + self.processing_thread.daemon = True + self.processing_thread.start() + finally: + self.lock.release() + + def pre_process_event(self, event): + raise NotImplementedError('This method should be implemented in the child class.') + + def process(self): + """ + Loops over the underlying queue of events and processes them in order. + """ + assert self.queue is not None + while True: + event = self.queue.get() + if self.pre_process_event(event): + self.invoke_handlers(event) + self.queue.task_done() + + def add_handler(self, handler): + """ + Adds a function to receive each event captured, starting the capturing + process if necessary. + """ + self.start_if_necessary() + self.handlers.append(handler) + + def remove_handler(self, handler): + """ Removes a previously added event handler. """ + self.handlers.remove(handler) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_event.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_event.py new file mode 100644 index 00000000..38b89610 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_event.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from collections import namedtuple + +LEFT = 'left' +RIGHT = 'right' +MIDDLE = 'middle' +WHEEL = 'wheel' +X = 'x' +X2 = 'x2' + +UP = 'up' +DOWN = 'down' +DOUBLE = 'double' +VERTICAL = 'vertical' +HORIZONTAL = 'horizontal' + + +ButtonEvent = namedtuple('ButtonEvent', ['event_type', 'button', 'time']) +WheelEvent = namedtuple('WheelEvent', ['delta', 'time']) +MoveEvent = namedtuple('MoveEvent', ['x', 'y', 'time']) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_tests.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_tests.py new file mode 100644 index 00000000..b3e9f9ad --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_mouse_tests.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +import unittest +import time + +from ._mouse_event import MoveEvent, ButtonEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE +import mouse + +class FakeOsMouse(object): + def __init__(self): + self.append = None + self.position = (0, 0) + self.queue = None + self.init = lambda: None + + def listen(self, queue): + self.listening = True + self.queue = queue + + def press(self, button): + self.append((DOWN, button)) + + def release(self, button): + self.append((UP, button)) + + def get_position(self): + return self.position + + def move_to(self, x, y): + self.append(('move', (x, y))) + self.position = (x, y) + + def wheel(self, delta): + self.append(('wheel', delta)) + + def move_relative(self, x, y): + self.position = (self.position[0] + x, self.position[1] + y) + +class TestMouse(unittest.TestCase): + @staticmethod + def setUpClass(): + mouse._os_mouse= FakeOsMouse() + mouse._listener.start_if_necessary() + assert mouse._os_mouse.listening + + def setUp(self): + self.events = [] + mouse._pressed_events.clear() + mouse._os_mouse.append = self.events.append + + def tearDown(self): + mouse.unhook_all() + # Make sure there's no spill over between tests. + self.wait_for_events_queue() + + def wait_for_events_queue(self): + mouse._listener.queue.join() + + def flush_events(self): + self.wait_for_events_queue() + events = list(self.events) + # Ugly, but requried to work in Python2. Python3 has list.clear + del self.events[:] + return events + + def press(self, button=LEFT): + mouse._os_mouse.queue.put(ButtonEvent(DOWN, button, time.time())) + self.wait_for_events_queue() + + def release(self, button=LEFT): + mouse._os_mouse.queue.put(ButtonEvent(UP, button, time.time())) + self.wait_for_events_queue() + + def double_click(self, button=LEFT): + mouse._os_mouse.queue.put(ButtonEvent(DOUBLE, button, time.time())) + self.wait_for_events_queue() + + def click(self, button=LEFT): + self.press(button) + self.release(button) + + def wheel(self, delta=1): + mouse._os_mouse.queue.put(WheelEvent(delta, time.time())) + self.wait_for_events_queue() + + def move(self, x=0, y=0): + mouse._os_mouse.queue.put(MoveEvent(x, y, time.time())) + self.wait_for_events_queue() + + def test_hook(self): + events = [] + self.press() + mouse.hook(events.append) + self.press() + mouse.unhook(events.append) + self.press() + self.assertEqual(len(events), 1) + + def test_is_pressed(self): + self.assertFalse(mouse.is_pressed()) + self.press() + self.assertTrue(mouse.is_pressed()) + self.release() + self.press(X2) + self.assertFalse(mouse.is_pressed()) + + self.assertTrue(mouse.is_pressed(X2)) + self.press(X2) + self.assertTrue(mouse.is_pressed(X2)) + self.release(X2) + self.release(X2) + self.assertFalse(mouse.is_pressed(X2)) + + def test_buttons(self): + mouse.press() + self.assertEqual(self.flush_events(), [(DOWN, LEFT)]) + mouse.release() + self.assertEqual(self.flush_events(), [(UP, LEFT)]) + mouse.click() + self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT)]) + mouse.double_click() + self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT), (DOWN, LEFT), (UP, LEFT)]) + mouse.right_click() + self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)]) + mouse.click(RIGHT) + self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)]) + mouse.press(X2) + self.assertEqual(self.flush_events(), [(DOWN, X2)]) + + def test_position(self): + self.assertEqual(mouse.get_position(), mouse._os_mouse.get_position()) + + def test_move(self): + mouse.move(0, 0) + self.assertEqual(mouse._os_mouse.get_position(), (0, 0)) + mouse.move(100, 500) + self.assertEqual(mouse._os_mouse.get_position(), (100, 500)) + mouse.move(1, 2, False) + self.assertEqual(mouse._os_mouse.get_position(), (101, 502)) + + mouse.move(0, 0) + mouse.move(100, 499, True, duration=0.01) + self.assertEqual(mouse._os_mouse.get_position(), (100, 499)) + mouse.move(100, 1, False, duration=0.01) + self.assertEqual(mouse._os_mouse.get_position(), (200, 500)) + mouse.move(0, 0, False, duration=0.01) + self.assertEqual(mouse._os_mouse.get_position(), (200, 500)) + + def triggers(self, fn, events, **kwargs): + self.triggered = False + def callback(): + self.triggered = True + handler = fn(callback, **kwargs) + + for event_type, arg in events: + if event_type == DOWN: + self.press(arg) + elif event_type == UP: + self.release(arg) + elif event_type == DOUBLE: + self.double_click(arg) + elif event_type == 'WHEEL': + self.wheel() + + mouse._listener.remove_handler(handler) + return self.triggered + + def test_on_button(self): + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)])) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, RIGHT)])) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, X)])) + + self.assertFalse(self.triggers(mouse.on_button, [('WHEEL', '')])) + + self.assertFalse(self.triggers(mouse.on_button, [(DOWN, X)], buttons=MIDDLE)) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE)) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE)) + self.assertFalse(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE, types=UP)) + self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=MIDDLE, types=UP)) + + self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) + self.assertFalse(self.triggers(mouse.on_button, [(UP, X)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) + + def test_ons(self): + self.assertTrue(self.triggers(mouse.on_click, [(UP, LEFT)])) + self.assertFalse(self.triggers(mouse.on_click, [(UP, RIGHT)])) + self.assertFalse(self.triggers(mouse.on_click, [(DOWN, LEFT)])) + self.assertFalse(self.triggers(mouse.on_click, [(DOWN, RIGHT)])) + + self.assertTrue(self.triggers(mouse.on_double_click, [(DOUBLE, LEFT)])) + self.assertFalse(self.triggers(mouse.on_double_click, [(DOUBLE, RIGHT)])) + self.assertFalse(self.triggers(mouse.on_double_click, [(DOWN, RIGHT)])) + + self.assertTrue(self.triggers(mouse.on_right_click, [(UP, RIGHT)])) + self.assertTrue(self.triggers(mouse.on_middle_click, [(UP, MIDDLE)])) + + def test_wait(self): + # If this fails it blocks. Unfortunately, but I see no other way of testing. + from threading import Thread, Lock + lock = Lock() + lock.acquire() + def t(): + mouse.wait() + lock.release() + Thread(target=t).start() + self.press() + lock.acquire() + + def test_record_play(self): + from threading import Thread, Lock + lock = Lock() + lock.acquire() + def t(): + self.recorded = mouse.record(RIGHT) + lock.release() + Thread(target=t).start() + self.click() + self.wheel(5) + self.move(100, 50) + self.press(RIGHT) + lock.acquire() + + self.assertEqual(len(self.recorded), 5) + self.assertEqual(self.recorded[0]._replace(time=None), ButtonEvent(DOWN, LEFT, None)) + self.assertEqual(self.recorded[1]._replace(time=None), ButtonEvent(UP, LEFT, None)) + self.assertEqual(self.recorded[2]._replace(time=None), WheelEvent(5, None)) + self.assertEqual(self.recorded[3]._replace(time=None), MoveEvent(100, 50, None)) + self.assertEqual(self.recorded[4]._replace(time=None), ButtonEvent(DOWN, RIGHT, None)) + + mouse.play(self.recorded, speed_factor=0) + events = self.flush_events() + self.assertEqual(len(events), 5) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('wheel', 5)) + self.assertEqual(events[3], ('move', (100, 50))) + self.assertEqual(events[4], (DOWN, RIGHT)) + + mouse.play(self.recorded) + events = self.flush_events() + self.assertEqual(len(events), 5) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('wheel', 5)) + self.assertEqual(events[3], ('move', (100, 50))) + self.assertEqual(events[4], (DOWN, RIGHT)) + + mouse.play(self.recorded, include_clicks=False) + events = self.flush_events() + self.assertEqual(len(events), 2) + self.assertEqual(events[0], ('wheel', 5)) + self.assertEqual(events[1], ('move', (100, 50))) + + mouse.play(self.recorded, include_moves=False) + events = self.flush_events() + self.assertEqual(len(events), 4) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('wheel', 5)) + self.assertEqual(events[3], (DOWN, RIGHT)) + + mouse.play(self.recorded, include_wheel=False) + events = self.flush_events() + self.assertEqual(len(events), 4) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('move', (100, 50))) + self.assertEqual(events[3], (DOWN, RIGHT)) + +if __name__ == '__main__': + unittest.main() diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixcommon.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixcommon.py new file mode 100644 index 00000000..d240f998 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixcommon.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +import struct +import os +import atexit +from time import time as now +from threading import Thread +from glob import glob +try: + from queue import Queue +except ImportError: + from Queue import Queue + +event_bin_format = 'llHHI' + +# Taken from include/linux/input.h +# https://www.kernel.org/doc/Documentation/input/event-codes.txt +EV_SYN = 0x00 +EV_KEY = 0x01 +EV_REL = 0x02 +EV_ABS = 0x03 +EV_MSC = 0x04 + +def make_uinput(): + import fcntl, struct + + # Requires uinput driver, but it's usually available. + uinput = open("/dev/uinput", 'wb') + UI_SET_EVBIT = 0x40045564 + fcntl.ioctl(uinput, UI_SET_EVBIT, EV_KEY) + + UI_SET_KEYBIT = 0x40045565 + for i in range(256): + fcntl.ioctl(uinput, UI_SET_KEYBIT, i) + + BUS_USB = 0x03 + uinput_user_dev = "80sHHHHi64i64i64i64i" + axis = [0] * 64 * 4 + uinput.write(struct.pack(uinput_user_dev, b"Virtual Keyboard", BUS_USB, 1, 1, 1, 0, *axis)) + uinput.flush() # Without this you may get Errno 22: Invalid argument. + + UI_DEV_CREATE = 0x5501 + fcntl.ioctl(uinput, UI_DEV_CREATE) + UI_DEV_DESTROY = 0x5502 + #fcntl.ioctl(uinput, UI_DEV_DESTROY) + + return uinput + +class EventDevice(object): + def __init__(self, path): + self.path = path + self._input_file = None + self._output_file = None + + @property + def input_file(self): + if self._input_file is None: + try: + self._input_file = open(self.path, 'rb') + except IOError as e: + if e.strerror == 'Permission denied': + print('Permission denied ({}). You must be sudo to access global events.'.format(self.path)) + exit() + + def try_close(): + try: + self._input_file.close + except: + pass + atexit.register(try_close) + return self._input_file + + @property + def output_file(self): + if self._output_file is None: + self._output_file = open(self.path, 'wb') + atexit.register(self._output_file.close) + return self._output_file + + def read_event(self): + data = self.input_file.read(struct.calcsize(event_bin_format)) + seconds, microseconds, type, code, value = struct.unpack(event_bin_format, data) + return seconds + microseconds / 1e6, type, code, value, self.path + + def write_event(self, type, code, value): + integer, fraction = divmod(now(), 1) + seconds = int(integer) + microseconds = int(fraction * 1e6) + data_event = struct.pack(event_bin_format, seconds, microseconds, type, code, value) + + # Send a sync event to ensure other programs update. + sync_event = struct.pack(event_bin_format, seconds, microseconds, EV_SYN, 0, 0) + + self.output_file.write(data_event + sync_event) + self.output_file.flush() + +class AggregatedEventDevice(object): + def __init__(self, devices, output=None): + self.event_queue = Queue() + self.devices = devices + self.output = output or self.devices[0] + def start_reading(device): + while True: + self.event_queue.put(device.read_event()) + for device in self.devices: + thread = Thread(target=start_reading, args=[device]) + thread.setDaemon(True) + thread.start() + + def read_event(self): + return self.event_queue.get(block=True) + + def write_event(self, type, code, value): + self.output.write_event(type, code, value) + +import re +from collections import namedtuple +DeviceDescription = namedtuple('DeviceDescription', 'event_file is_mouse is_keyboard') +device_pattern = r"""N: Name="([^"]+?)".+?H: Handlers=([^\n]+)""" +def list_devices_from_proc(type_name): + try: + with open('/proc/bus/input/devices') as f: + description = f.read() + except FileNotFoundError: + return + + devices = {} + for name, handlers in re.findall(device_pattern, description, re.DOTALL): + path = '/dev/input/event' + re.search(r'event(\d+)', handlers).group(1) + if type_name in handlers: + yield EventDevice(path) + +def list_devices_from_by_id(type_name): + for path in glob('/dev/input/by-id/*-event-' + type_name): + yield EventDevice(path) + +def aggregate_devices(type_name): + # Some systems have multiple keyboards with different range of allowed keys + # on each one, like a notebook with a "keyboard" device exclusive for the + # power button. Instead of figuring out which keyboard allows which key to + # send events, we create a fake device and send all events through there. + uinput = make_uinput() + fake_device = EventDevice('uinput Fake Device') + fake_device._input_file = uinput + fake_device._output_file = uinput + + # We don't aggregate devices from different sources to avoid + # duplicates. + + devices_from_proc = list(list_devices_from_proc(type_name)) + if devices_from_proc: + return AggregatedEventDevice(devices_from_proc, output=fake_device) + + # breaks on mouse for virtualbox + # was getting /dev/input/by-id/usb-VirtualBox_USB_Tablet-event-mouse + devices_from_by_id = list(list_devices_from_by_id(type_name)) + if devices_from_by_id: + return AggregatedEventDevice(devices_from_by_id, output=fake_device) + + # If no keyboards were found we can only use the fake device to send keys. + return fake_device + + +def ensure_root(): + if os.geteuid() != 0: + raise ImportError('You must be root to use this library on linux.') diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixmouse.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixmouse.py new file mode 100644 index 00000000..5e3b595d --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_nixmouse.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +import struct +from subprocess import check_output +import re +from ._nixcommon import EV_KEY, EV_REL, EV_MSC, EV_SYN, EV_ABS, aggregate_devices, ensure_root +from ._mouse_event import ButtonEvent, WheelEvent, MoveEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN + +import ctypes +import ctypes.util +from ctypes import c_uint32, c_uint, c_int, c_void_p, byref + +display = None +window = None +x11 = None +def build_display(): + global display, window, x11 + if display and window and x11: return + x11 = ctypes.cdll.LoadLibrary(ctypes.util.find_library('X11')) + # Required because we will have multiple threads calling x11, + # such as the listener thread and then main using "move_to". + x11.XInitThreads() + # Explicitly set XOpenDisplay.restype to avoid segfault on 64 bit OS. + # http://stackoverflow.com/questions/35137007/get-mouse-position-on-linux-pure-python + x11.XOpenDisplay.restype = c_void_p + display = c_void_p(x11.XOpenDisplay(0)) + window = x11.XDefaultRootWindow(display) + +def get_position(): + build_display() + root_id, child_id = c_void_p(), c_void_p() + root_x, root_y, win_x, win_y = c_int(), c_int(), c_int(), c_int() + mask = c_uint() + ret = x11.XQueryPointer(display, c_uint32(window), byref(root_id), byref(child_id), + byref(root_x), byref(root_y), + byref(win_x), byref(win_y), byref(mask)) + return root_x.value, root_y.value + +def move_to(x, y): + build_display() + x11.XWarpPointer(display, None, window, 0, 0, 0, 0, x, y) + x11.XFlush(display) + +REL_X = 0x00 +REL_Y = 0x01 +REL_Z = 0x02 +REL_HWHEEL = 0x06 +REL_WHEEL = 0x08 + +ABS_X = 0x00 +ABS_Y = 0x01 + +BTN_MOUSE = 0x110 +BTN_LEFT = 0x110 +BTN_RIGHT = 0x111 +BTN_MIDDLE = 0x112 +BTN_SIDE = 0x113 +BTN_EXTRA = 0x114 + +button_by_code = { + BTN_LEFT: LEFT, + BTN_RIGHT: RIGHT, + BTN_MIDDLE: MIDDLE, + BTN_SIDE: X, + BTN_EXTRA: X2, +} +code_by_button = {button: code for code, button in button_by_code.items()} + +device = None +def build_device(): + global device + if device: return + ensure_root() + device = aggregate_devices('mouse') +init = build_device + +def listen(queue): + build_device() + + while True: + time, type, code, value, device_id = device.read_event() + if type == EV_SYN or type == EV_MSC: + continue + + event = None + arg = None + + if type == EV_KEY: + event = ButtonEvent(DOWN if value else UP, button_by_code.get(code, '?'), time) + elif type == EV_REL: + value, = struct.unpack('i', struct.pack('I', value)) + + if code == REL_WHEEL: + event = WheelEvent(value, time) + elif code in (REL_X, REL_Y): + x, y = get_position() + event = MoveEvent(x, y, time) + + if event is None: + # Unknown event type. + continue + + queue.put(event) + +def press(button=LEFT): + build_device() + device.write_event(EV_KEY, code_by_button[button], 0x01) + +def release(button=LEFT): + build_device() + device.write_event(EV_KEY, code_by_button[button], 0x00) + +def move_relative(x, y): + build_device() + # Note relative events are not in terms of pixels, but millimeters. + if x < 0: + x += 2**32 + if y < 0: + y += 2**32 + device.write_event(EV_REL, REL_X, x) + device.write_event(EV_REL, REL_Y, y) + +def wheel(delta=1): + build_device() + if delta < 0: + delta += 2**32 + device.write_event(EV_REL, REL_WHEEL, delta) + + +if __name__ == '__main__': + #listen(print) + move_to(100, 200) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_winmouse.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_winmouse.py new file mode 100644 index 00000000..b5806a22 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/mouse/_winmouse.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +import ctypes +import time +from ctypes import c_short, c_char, c_uint8, c_int32, c_int, c_uint, c_uint32, c_long, byref, Structure, CFUNCTYPE, POINTER +from ctypes.wintypes import DWORD, BOOL, HHOOK, MSG, LPWSTR, WCHAR, WPARAM, LPARAM +LPMSG = POINTER(MSG) + +import atexit + +from ._mouse_event import ButtonEvent, WheelEvent, MoveEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE, WHEEL, HORIZONTAL, VERTICAL + +#user32 = ctypes.windll.user32 +user32 = ctypes.WinDLL('user32', use_last_error = True) + +class MSLLHOOKSTRUCT(Structure): + _fields_ = [("x", c_long), + ("y", c_long), + ('data', c_int32), + ('reserved', c_int32), + ("flags", DWORD), + ("time", c_int), + ] + +LowLevelMouseProc = CFUNCTYPE(c_int, WPARAM, LPARAM, POINTER(MSLLHOOKSTRUCT)) + +SetWindowsHookEx = user32.SetWindowsHookExA +#SetWindowsHookEx.argtypes = [c_int, LowLevelMouseProc, c_int, c_int] +SetWindowsHookEx.restype = HHOOK + +CallNextHookEx = user32.CallNextHookEx +#CallNextHookEx.argtypes = [c_int , c_int, c_int, POINTER(MSLLHOOKSTRUCT)] +CallNextHookEx.restype = c_int + +UnhookWindowsHookEx = user32.UnhookWindowsHookEx +UnhookWindowsHookEx.argtypes = [HHOOK] +UnhookWindowsHookEx.restype = BOOL + +GetMessage = user32.GetMessageW +GetMessage.argtypes = [LPMSG, c_int, c_int, c_int] +GetMessage.restype = BOOL + +TranslateMessage = user32.TranslateMessage +TranslateMessage.argtypes = [LPMSG] +TranslateMessage.restype = BOOL + +DispatchMessage = user32.DispatchMessageA +DispatchMessage.argtypes = [LPMSG] + +GetDoubleClickTime = user32.GetDoubleClickTime + +# Beware, as of 2016-01-30 the official docs have a very incomplete list. +# This one was compiled from experience and may be incomplete. +WM_MOUSEMOVE = 0x200 +WM_LBUTTONDOWN = 0x201 +WM_LBUTTONUP = 0x202 +WM_LBUTTONDBLCLK = 0x203 +WM_RBUTTONDOWN = 0x204 +WM_RBUTTONUP = 0x205 +WM_RBUTTONDBLCLK = 0x206 +WM_MBUTTONDOWN = 0x207 +WM_MBUTTONUP = 0x208 +WM_MBUTTONDBLCLK = 0x209 +WM_MOUSEWHEEL = 0x20A +WM_XBUTTONDOWN = 0x20B +WM_XBUTTONUP = 0x20C +WM_XBUTTONDBLCLK = 0x20D +WM_NCXBUTTONDOWN = 0x00AB +WM_NCXBUTTONUP = 0x00AC +WM_NCXBUTTONDBLCLK = 0x00AD +WM_MOUSEHWHEEL = 0x20E +WM_LBUTTONDOWN = 0x0201 +WM_LBUTTONUP = 0x0202 +WM_MOUSEMOVE = 0x0200 +WM_MOUSEWHEEL = 0x020A +WM_MOUSEHWHEEL = 0x020E +WM_RBUTTONDOWN = 0x0204 +WM_RBUTTONUP = 0x0205 + +buttons_by_wm_code = { + WM_LBUTTONDOWN: (DOWN, LEFT), + WM_LBUTTONUP: (UP, LEFT), + WM_LBUTTONDBLCLK: (DOUBLE, LEFT), + + WM_RBUTTONDOWN: (DOWN, RIGHT), + WM_RBUTTONUP: (UP, RIGHT), + WM_RBUTTONDBLCLK: (DOUBLE, RIGHT), + + WM_MBUTTONDOWN: (DOWN, MIDDLE), + WM_MBUTTONUP: (UP, MIDDLE), + WM_MBUTTONDBLCLK: (DOUBLE, MIDDLE), + + WM_XBUTTONDOWN: (DOWN, X), + WM_XBUTTONUP: (UP, X), + WM_XBUTTONDBLCLK: (DOUBLE, X), +} + +MOUSEEVENTF_ABSOLUTE = 0x8000 +MOUSEEVENTF_MOVE = 0x1 +MOUSEEVENTF_WHEEL = 0x800 +MOUSEEVENTF_HWHEEL = 0x1000 +MOUSEEVENTF_LEFTDOWN = 0x2 +MOUSEEVENTF_LEFTUP = 0x4 +MOUSEEVENTF_RIGHTDOWN = 0x8 +MOUSEEVENTF_RIGHTUP = 0x10 +MOUSEEVENTF_MIDDLEDOWN = 0x20 +MOUSEEVENTF_MIDDLEUP = 0x40 +MOUSEEVENTF_XDOWN = 0x0080 +MOUSEEVENTF_XUP = 0x0100 + +simulated_mouse_codes = { + (WHEEL, HORIZONTAL): MOUSEEVENTF_HWHEEL, + (WHEEL, VERTICAL): MOUSEEVENTF_WHEEL, + + (DOWN, LEFT): MOUSEEVENTF_LEFTDOWN, + (UP, LEFT): MOUSEEVENTF_LEFTUP, + + (DOWN, RIGHT): MOUSEEVENTF_RIGHTDOWN, + (UP, RIGHT): MOUSEEVENTF_RIGHTUP, + + (DOWN, MIDDLE): MOUSEEVENTF_MIDDLEDOWN, + (UP, MIDDLE): MOUSEEVENTF_MIDDLEUP, + + (DOWN, X): MOUSEEVENTF_XDOWN, + (UP, X): MOUSEEVENTF_XUP, +} + +NULL = c_int(0) + +WHEEL_DELTA = 120 + +init = lambda: None + +previous_button_event = None # defined in global scope +def listen(queue): + + def low_level_mouse_handler(nCode, wParam, lParam): + global previous_button_event + + struct = lParam.contents + # Can't use struct.time because it's usually zero. + t = time.time() + + if wParam == WM_MOUSEMOVE: + event = MoveEvent(struct.x, struct.y, t) + elif wParam == WM_MOUSEWHEEL: + event = WheelEvent(struct.data / (WHEEL_DELTA * (2<<15)), t) + elif wParam in buttons_by_wm_code: + type, button = buttons_by_wm_code.get(wParam, ('?', '?')) + if wParam >= WM_XBUTTONDOWN: + button = {0x10000: X, 0x20000: X2}[struct.data] + event = ButtonEvent(type, button, t) + + if (event.event_type == DOWN) and previous_button_event is not None: + # https://msdn.microsoft.com/en-us/library/windows/desktop/gg153548%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 + if event.time - previous_button_event.time <= GetDoubleClickTime() / 1000.0: + event = ButtonEvent(DOUBLE, event.button, event.time) + + previous_button_event = event + else: + # Unknown event type. + return CallNextHookEx(NULL, nCode, wParam, lParam) + + queue.put(event) + return CallNextHookEx(NULL, nCode, wParam, lParam) + + WH_MOUSE_LL = c_int(14) + mouse_callback = LowLevelMouseProc(low_level_mouse_handler) + mouse_hook = SetWindowsHookEx(WH_MOUSE_LL, mouse_callback, NULL, NULL) + + # Register to remove the hook when the interpreter exits. Unfortunately a + # try/finally block doesn't seem to work here. + atexit.register(UnhookWindowsHookEx, mouse_hook) + + msg = LPMSG() + while not GetMessage(msg, NULL, NULL, NULL): + TranslateMessage(msg) + DispatchMessage(msg) + +def _translate_button(button): + if button == X or button == X2: + return X, {X: 0x10000, X2: 0x20000}[button] + else: + return button, 0 + +def press(button=LEFT): + button, data = _translate_button(button) + code = simulated_mouse_codes[(DOWN, button)] + user32.mouse_event(code, 0, 0, data, 0) + +def release(button=LEFT): + button, data = _translate_button(button) + code = simulated_mouse_codes[(UP, button)] + user32.mouse_event(code, 0, 0, data, 0) + +def wheel(delta=1): + code = simulated_mouse_codes[(WHEEL, VERTICAL)] + user32.mouse_event(code, 0, 0, int(delta * WHEEL_DELTA), 0) + +def move_to(x, y): + user32.SetCursorPos(int(x), int(y)) + +def move_relative(x, y): + user32.mouse_event(MOUSEEVENTF_MOVE, int(x), int(y), 0, 0) + +class POINT(Structure): + _fields_ = [("x", c_long), ("y", c_long)] + +def get_position(): + point = POINT() + user32.GetCursorPos(byref(point)) + return (point.x, point.y) + +if __name__ == '__main__': + def p(e): + print(e) + listen(p) diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt new file mode 100644 index 00000000..4f3cb7b8 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Lucas Boppre Niehues + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/METADATA new file mode 100644 index 00000000..c6dfc0d2 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/METADATA @@ -0,0 +1,62 @@ +Metadata-Version: 2.1 +Name: mouse +Version: 0.7.1 +Summary: Hook and simulate mouse events on Windows and Linux +Home-page: https://github.com/boppreh/mouse +Author: BoppreH +Author-email: boppreh@gmail.com +License: MIT +Keywords: mouse hook simulate hotkey +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: Unix +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Description-Content-Type: text/markdown + + +mouse +===== + +Take full control of your mouse with this small Python library. Hook global events, register hotkeys, simulate mouse movement and clicks, and much more. + +_Huge thanks to [Kirill Pavlov](http://kirillpavlov.com/) for donating the package name. If you are looking for the Cheddargetter.com client implementation, [`pip install mouse==0.5.0`](https://pypi.python.org/pypi/mouse/0.5.0)._ + +## Features + +- Global event hook on all mice devices (captures events regardless of focus). +- **Listen** and **sends** mouse events. +- Works with **Windows** and **Linux** (requires sudo). +- **Pure Python**, no C modules to be compiled. +- **Zero dependencies**. Trivial to install and deploy, just copy the files. +- **Python 2 and 3**. +- Includes **high level API** (e.g. [record](#mouse.record) and [play](#mouse.play). +- Events automatically captured in separate thread, doesn't block main program. +- Tested and documented. + +This program makes no attempt to hide itself, so don't use it for keyloggers. + +## Usage + +Install the [PyPI package](https://pypi.python.org/pypi/mouse/): + + $ sudo pip install mouse + +or clone the repository (no installation required, source files are sufficient): + + $ git clone https://github.com/boppreh/mouse + +Then check the [API docs](https://github.com/boppreh/mouse#api) to see what features are available. + + +## Known limitations: + +- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21) +- To avoid depending on X the Linux parts reads raw device files (`/dev/input/input*`) but this requries root. +- Other applications, such as some games, may register hooks that swallow all key events. In this case `mouse` will be unable to report events. + + diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/RECORD new file mode 100644 index 00000000..c46d9df0 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/RECORD @@ -0,0 +1,22 @@ +mouse-0.7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +mouse-0.7.1.dist-info/LICENSE.txt,sha256=K_FKUlVV0FqAHC0sKJAVBPt2q-58LX6_tM_HUI198Pc,1077 +mouse-0.7.1.dist-info/METADATA,sha256=7MmeikMZ3xgUFvcSNMnCnXugXuG0ag8QjFoOV1k9mr0,2455 +mouse-0.7.1.dist-info/RECORD,, +mouse-0.7.1.dist-info/WHEEL,sha256=JZXtYepZFsf4IoivNpnSgKIc4qTHan08DRd56koo_DM,116 +mouse-0.7.1.dist-info/top_level.txt,sha256=FiA9sXRt9_B8X6je4BlPesL9EakrmGZ0fDKPK09Ql6U,6 +mouse/__init__.py,sha256=HGaiOxH8PuKnU2oCLN5pEN4yuvxH1JoxT1QXwITFlf0,9147 +mouse/__main__.py,sha256=Rir1qIanuA6OUsVIywo71MgF1PrVCdZ77F1FPOu4JA0,625 +mouse/__pycache__/__init__.cpython-37.pyc,, +mouse/__pycache__/__main__.cpython-37.pyc,, +mouse/__pycache__/_generic.cpython-37.pyc,, +mouse/__pycache__/_mouse_event.cpython-37.pyc,, +mouse/__pycache__/_mouse_tests.cpython-37.pyc,, +mouse/__pycache__/_nixcommon.cpython-37.pyc,, +mouse/__pycache__/_nixmouse.cpython-37.pyc,, +mouse/__pycache__/_winmouse.cpython-37.pyc,, +mouse/_generic.py,sha256=STzfL7AUAkcAq6XUyxpQiOYnBnQ1TZjWL1cSFSZ61_o,2132 +mouse/_mouse_event.py,sha256=zRQGO6M6nbA-jvhI0yz4HzvQNcScF48PZ9iRegcTVjQ,422 +mouse/_mouse_tests.py,sha256=gNa_NW5sRIsbLMG35ZfXal3eHS2mEpEPhysJRDq0gQA,10000 +mouse/_nixcommon.py,sha256=FNXiCv7u_A0SzcYJQlYDJBSdIN6IUTVLG4g7oqXgj6o,5552 +mouse/_nixmouse.py,sha256=3htKn9XkUApFqp3rGCT-ZQIqJFf4iGqoxxoO9MY2x4k,3576 +mouse/_winmouse.py,sha256=lWAnfGq0etNjFR-vE9e3r9N7Amg5wU957B4ZS3YMTz0,6449 diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL new file mode 100644 index 00000000..8b701e93 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.6) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt new file mode 100644 index 00000000..3e41be96 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse-0.7.1.dist-info/top_level.txt @@ -0,0 +1 @@ +mouse diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__init__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__init__.py new file mode 100644 index 00000000..3a21f46e --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__init__.py @@ -0,0 +1,272 @@ +# -*- coding: utf-8 -*- +""" +mouse +===== + +Take full control of your mouse with this small Python library. Hook global events, register hotkeys, simulate mouse movement and clicks, and much more. + +_Huge thanks to [Kirill Pavlov](http://kirillpavlov.com/) for donating the package name. If you are looking for the Cheddargetter.com client implementation, [`pip install mouse==0.5.0`](https://pypi.python.org/pypi/mouse/0.5.0)._ + +## Features + +- Global event hook on all mice devices (captures events regardless of focus). +- **Listen** and **sends** mouse events. +- Works with **Windows** and **Linux** (requires sudo). +- **Pure Python**, no C modules to be compiled. +- **Zero dependencies**. Trivial to install and deploy, just copy the files. +- **Python 2 and 3**. +- Includes **high level API** (e.g. [record](#mouse.record) and [play](#mouse.play). +- Events automatically captured in separate thread, doesn't block main program. +- Tested and documented. + +This program makes no attempt to hide itself, so don't use it for keyloggers. + +## Usage + +Install the [PyPI package](https://pypi.python.org/pypi/mouse/): + + $ sudo pip install mouse + +or clone the repository (no installation required, source files are sufficient): + + $ git clone https://github.com/boppreh/mouse + +Then check the [API docs](https://github.com/boppreh/mouse#api) to see what features are available. + + +## Known limitations: + +- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21) +- To avoid depending on X the Linux parts reads raw device files (`/dev/input/input*`) but this requries root. +- Other applications, such as some games, may register hooks that swallow all key events. In this case `mouse` will be unable to report events. +""" +# TODO +# - infinite wait +# - mouse.on_move +version = '0.7.1' + +import time as _time + +import platform as _platform +if _platform.system() == 'Windows': + from. import _winmouse as _os_mouse +elif _platform.system() == 'Linux': + from. import _nixmouse as _os_mouse +else: + raise OSError("Unsupported platform '{}'".format(_platform.system())) + +from ._mouse_event import ButtonEvent, MoveEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE +from ._generic import GenericListener as _GenericListener + +_pressed_events = set() +class _MouseListener(_GenericListener): + def init(self): + _os_mouse.init() + def pre_process_event(self, event): + if isinstance(event, ButtonEvent): + if event.event_type in (UP, DOUBLE): + _pressed_events.discard(event.button) + else: + _pressed_events.add(event.button) + return True + + def listen(self): + _os_mouse.listen(self.queue) + +_listener = _MouseListener() + +def is_pressed(button=LEFT): + """ Returns True if the given button is currently pressed. """ + _listener.start_if_necessary() + return button in _pressed_events + +def press(button=LEFT): + """ Presses the given button (but doesn't release). """ + _os_mouse.press(button) + +def release(button=LEFT): + """ Releases the given button. """ + _os_mouse.release(button) + +def click(button=LEFT): + """ Sends a click with the given button. """ + _os_mouse.press(button) + _os_mouse.release(button) + +def double_click(button=LEFT): + """ Sends a double click with the given button. """ + click(button) + click(button) + +def right_click(): + """ Sends a right click with the given button. """ + click(RIGHT) + +def wheel(delta=1): + """ Scrolls the wheel `delta` clicks. Sign indicates direction. """ + _os_mouse.wheel(delta) + +def move(x, y, absolute=True, duration=0): + """ + Moves the mouse. If `absolute`, to position (x, y), otherwise move relative + to the current position. If `duration` is non-zero, animates the movement. + """ + x = int(x) + y = int(y) + + # Requires an extra system call on Linux, but `move_relative` is measured + # in millimiters so we would lose precision. + position_x, position_y = get_position() + + if not absolute: + x = position_x + x + y = position_y + y + + if duration: + start_x = position_x + start_y = position_y + dx = x - start_x + dy = y - start_y + + if dx == 0 and dy == 0: + _time.sleep(duration) + else: + # 120 movements per second. + # Round and keep float to ensure float division in Python 2 + steps = max(1.0, float(int(duration * 120.0))) + for i in range(int(steps)+1): + move(start_x + dx*i/steps, start_y + dy*i/steps) + _time.sleep(duration/steps) + else: + _os_mouse.move_to(x, y) + +def drag(start_x, start_y, end_x, end_y, absolute=True, duration=0): + """ + Holds the left mouse button, moving from start to end position, then + releases. `absolute` and `duration` are parameters regarding the mouse + movement. + """ + if is_pressed(): + release() + move(start_x, start_y, absolute, 0) + press() + move(end_x, end_y, absolute, duration) + release() + +def on_button(callback, args=(), buttons=(LEFT, MIDDLE, RIGHT, X, X2), types=(UP, DOWN, DOUBLE)): + """ Invokes `callback` with `args` when the specified event happens. """ + if not isinstance(buttons, (tuple, list)): + buttons = (buttons,) + if not isinstance(types, (tuple, list)): + types = (types,) + + def handler(event): + if isinstance(event, ButtonEvent): + if event.event_type in types and event.button in buttons: + callback(*args) + _listener.add_handler(handler) + return handler + +def on_click(callback, args=()): + """ Invokes `callback` with `args` when the left button is clicked. """ + return on_button(callback, args, [LEFT], [UP]) + +def on_double_click(callback, args=()): + """ + Invokes `callback` with `args` when the left button is double clicked. + """ + return on_button(callback, args, [LEFT], [DOUBLE]) + +def on_right_click(callback, args=()): + """ Invokes `callback` with `args` when the right button is clicked. """ + return on_button(callback, args, [RIGHT], [UP]) + +def on_middle_click(callback, args=()): + """ Invokes `callback` with `args` when the middle button is clicked. """ + return on_button(callback, args, [MIDDLE], [UP]) + +def wait(button=LEFT, target_types=(UP, DOWN, DOUBLE)): + """ + Blocks program execution until the given button performs an event. + """ + from threading import Lock + lock = Lock() + lock.acquire() + handler = on_button(lock.release, (), [button], target_types) + lock.acquire() + _listener.remove_handler(handler) + +def get_position(): + """ Returns the (x, y) mouse position. """ + return _os_mouse.get_position() + +def hook(callback): + """ + Installs a global listener on all available mouses, invoking `callback` + each time it is moved, a key status changes or the wheel is spun. A mouse + event is passed as argument, with type either `mouse.ButtonEvent`, + `mouse.WheelEvent` or `mouse.MoveEvent`. + + Returns the given callback for easier development. + """ + _listener.add_handler(callback) + return callback + +def unhook(callback): + """ + Removes a previously installed hook. + """ + _listener.remove_handler(callback) + +def unhook_all(): + """ + Removes all hooks registered by this application. Note this may include + hooks installed by high level functions, such as `record`. + """ + del _listener.handlers[:] + +def record(button=RIGHT, target_types=(DOWN,)): + """ + Records all mouse events until the user presses the given button. + Then returns the list of events recorded. Pairs well with `play(events)`. + + Note: this is a blocking function. + Note: for more details on the mouse hook and events see `hook`. + """ + recorded = [] + hook(recorded.append) + wait(button=button, target_types=target_types) + unhook(recorded.append) + return recorded + +def play(events, speed_factor=1.0, include_clicks=True, include_moves=True, include_wheel=True): + """ + Plays a sequence of recorded events, maintaining the relative time + intervals. If speed_factor is <= 0 then the actions are replayed as fast + as the OS allows. Pairs well with `record()`. + + The parameters `include_*` define if events of that type should be inluded + in the replay or ignored. + """ + last_time = None + for event in events: + if speed_factor > 0 and last_time is not None: + _time.sleep((event.time - last_time) / speed_factor) + last_time = event.time + + if isinstance(event, ButtonEvent) and include_clicks: + if event.event_type == UP: + _os_mouse.release(event.button) + else: + _os_mouse.press(event.button) + elif isinstance(event, MoveEvent) and include_moves: + _os_mouse.move_to(event.x, event.y) + elif isinstance(event, WheelEvent) and include_wheel: + _os_mouse.wheel(event.delta) + +replay = play +hold = press + +if __name__ == '__main__': + print('Recording... Double click to stop and replay.') + play(record()) diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__main__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__main__.py new file mode 100644 index 00000000..1a84defc --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/__main__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +import mouse +import fileinput +import json +import sys + +class_by_name = { + 'ButtonEvent': mouse.ButtonEvent, + 'WheelEvent': mouse.WheelEvent, + 'MoveEvent': mouse.MoveEvent, +} + +def print_event_json(event): + # Could use json.dumps(event.__dict__()), but this way we guarantee semantic order. + d = event._asdict() + d['event_class'] = event.__class__.__name__ + print(json.dumps(d)) + sys.stdout.flush() +mouse.hook(print_event_json) + +def load(line): + d = json.loads(line) + class_ = class_by_name[d['event_class']] + del d['event_class'] + return class_(**d) + +mouse.play(load(line) for line in fileinput.input()) \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_generic.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_generic.py new file mode 100644 index 00000000..04f029e7 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_generic.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +from threading import Thread, Lock +import traceback +import functools + +try: + from queue import Queue +except ImportError: + from Queue import Queue + +class GenericListener(object): + lock = Lock() + + def __init__(self): + self.handlers = [] + self.listening = False + self.queue = Queue() + + def invoke_handlers(self, event): + for handler in self.handlers: + try: + if handler(event): + # Stop processing this hotkey. + return 1 + except Exception as e: + traceback.print_exc() + + def start_if_necessary(self): + """ + Starts the listening thread if it wasn't already. + """ + self.lock.acquire() + try: + if not self.listening: + self.init() + + self.listening = True + self.listening_thread = Thread(target=self.listen) + self.listening_thread.daemon = True + self.listening_thread.start() + + self.processing_thread = Thread(target=self.process) + self.processing_thread.daemon = True + self.processing_thread.start() + finally: + self.lock.release() + + def pre_process_event(self, event): + raise NotImplementedError('This method should be implemented in the child class.') + + def process(self): + """ + Loops over the underlying queue of events and processes them in order. + """ + assert self.queue is not None + while True: + event = self.queue.get() + if self.pre_process_event(event): + self.invoke_handlers(event) + self.queue.task_done() + + def add_handler(self, handler): + """ + Adds a function to receive each event captured, starting the capturing + process if necessary. + """ + self.start_if_necessary() + self.handlers.append(handler) + + def remove_handler(self, handler): + """ Removes a previously added event handler. """ + self.handlers.remove(handler) diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_event.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_event.py new file mode 100644 index 00000000..38b89610 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_event.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from collections import namedtuple + +LEFT = 'left' +RIGHT = 'right' +MIDDLE = 'middle' +WHEEL = 'wheel' +X = 'x' +X2 = 'x2' + +UP = 'up' +DOWN = 'down' +DOUBLE = 'double' +VERTICAL = 'vertical' +HORIZONTAL = 'horizontal' + + +ButtonEvent = namedtuple('ButtonEvent', ['event_type', 'button', 'time']) +WheelEvent = namedtuple('WheelEvent', ['delta', 'time']) +MoveEvent = namedtuple('MoveEvent', ['x', 'y', 'time']) diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_tests.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_tests.py new file mode 100644 index 00000000..b3e9f9ad --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_mouse_tests.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +import unittest +import time + +from ._mouse_event import MoveEvent, ButtonEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE +import mouse + +class FakeOsMouse(object): + def __init__(self): + self.append = None + self.position = (0, 0) + self.queue = None + self.init = lambda: None + + def listen(self, queue): + self.listening = True + self.queue = queue + + def press(self, button): + self.append((DOWN, button)) + + def release(self, button): + self.append((UP, button)) + + def get_position(self): + return self.position + + def move_to(self, x, y): + self.append(('move', (x, y))) + self.position = (x, y) + + def wheel(self, delta): + self.append(('wheel', delta)) + + def move_relative(self, x, y): + self.position = (self.position[0] + x, self.position[1] + y) + +class TestMouse(unittest.TestCase): + @staticmethod + def setUpClass(): + mouse._os_mouse= FakeOsMouse() + mouse._listener.start_if_necessary() + assert mouse._os_mouse.listening + + def setUp(self): + self.events = [] + mouse._pressed_events.clear() + mouse._os_mouse.append = self.events.append + + def tearDown(self): + mouse.unhook_all() + # Make sure there's no spill over between tests. + self.wait_for_events_queue() + + def wait_for_events_queue(self): + mouse._listener.queue.join() + + def flush_events(self): + self.wait_for_events_queue() + events = list(self.events) + # Ugly, but requried to work in Python2. Python3 has list.clear + del self.events[:] + return events + + def press(self, button=LEFT): + mouse._os_mouse.queue.put(ButtonEvent(DOWN, button, time.time())) + self.wait_for_events_queue() + + def release(self, button=LEFT): + mouse._os_mouse.queue.put(ButtonEvent(UP, button, time.time())) + self.wait_for_events_queue() + + def double_click(self, button=LEFT): + mouse._os_mouse.queue.put(ButtonEvent(DOUBLE, button, time.time())) + self.wait_for_events_queue() + + def click(self, button=LEFT): + self.press(button) + self.release(button) + + def wheel(self, delta=1): + mouse._os_mouse.queue.put(WheelEvent(delta, time.time())) + self.wait_for_events_queue() + + def move(self, x=0, y=0): + mouse._os_mouse.queue.put(MoveEvent(x, y, time.time())) + self.wait_for_events_queue() + + def test_hook(self): + events = [] + self.press() + mouse.hook(events.append) + self.press() + mouse.unhook(events.append) + self.press() + self.assertEqual(len(events), 1) + + def test_is_pressed(self): + self.assertFalse(mouse.is_pressed()) + self.press() + self.assertTrue(mouse.is_pressed()) + self.release() + self.press(X2) + self.assertFalse(mouse.is_pressed()) + + self.assertTrue(mouse.is_pressed(X2)) + self.press(X2) + self.assertTrue(mouse.is_pressed(X2)) + self.release(X2) + self.release(X2) + self.assertFalse(mouse.is_pressed(X2)) + + def test_buttons(self): + mouse.press() + self.assertEqual(self.flush_events(), [(DOWN, LEFT)]) + mouse.release() + self.assertEqual(self.flush_events(), [(UP, LEFT)]) + mouse.click() + self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT)]) + mouse.double_click() + self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT), (DOWN, LEFT), (UP, LEFT)]) + mouse.right_click() + self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)]) + mouse.click(RIGHT) + self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)]) + mouse.press(X2) + self.assertEqual(self.flush_events(), [(DOWN, X2)]) + + def test_position(self): + self.assertEqual(mouse.get_position(), mouse._os_mouse.get_position()) + + def test_move(self): + mouse.move(0, 0) + self.assertEqual(mouse._os_mouse.get_position(), (0, 0)) + mouse.move(100, 500) + self.assertEqual(mouse._os_mouse.get_position(), (100, 500)) + mouse.move(1, 2, False) + self.assertEqual(mouse._os_mouse.get_position(), (101, 502)) + + mouse.move(0, 0) + mouse.move(100, 499, True, duration=0.01) + self.assertEqual(mouse._os_mouse.get_position(), (100, 499)) + mouse.move(100, 1, False, duration=0.01) + self.assertEqual(mouse._os_mouse.get_position(), (200, 500)) + mouse.move(0, 0, False, duration=0.01) + self.assertEqual(mouse._os_mouse.get_position(), (200, 500)) + + def triggers(self, fn, events, **kwargs): + self.triggered = False + def callback(): + self.triggered = True + handler = fn(callback, **kwargs) + + for event_type, arg in events: + if event_type == DOWN: + self.press(arg) + elif event_type == UP: + self.release(arg) + elif event_type == DOUBLE: + self.double_click(arg) + elif event_type == 'WHEEL': + self.wheel() + + mouse._listener.remove_handler(handler) + return self.triggered + + def test_on_button(self): + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)])) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, RIGHT)])) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, X)])) + + self.assertFalse(self.triggers(mouse.on_button, [('WHEEL', '')])) + + self.assertFalse(self.triggers(mouse.on_button, [(DOWN, X)], buttons=MIDDLE)) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE)) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE)) + self.assertFalse(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE, types=UP)) + self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=MIDDLE, types=UP)) + + self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) + self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) + self.assertFalse(self.triggers(mouse.on_button, [(UP, X)], buttons=[MIDDLE, LEFT], types=[UP, DOWN])) + + def test_ons(self): + self.assertTrue(self.triggers(mouse.on_click, [(UP, LEFT)])) + self.assertFalse(self.triggers(mouse.on_click, [(UP, RIGHT)])) + self.assertFalse(self.triggers(mouse.on_click, [(DOWN, LEFT)])) + self.assertFalse(self.triggers(mouse.on_click, [(DOWN, RIGHT)])) + + self.assertTrue(self.triggers(mouse.on_double_click, [(DOUBLE, LEFT)])) + self.assertFalse(self.triggers(mouse.on_double_click, [(DOUBLE, RIGHT)])) + self.assertFalse(self.triggers(mouse.on_double_click, [(DOWN, RIGHT)])) + + self.assertTrue(self.triggers(mouse.on_right_click, [(UP, RIGHT)])) + self.assertTrue(self.triggers(mouse.on_middle_click, [(UP, MIDDLE)])) + + def test_wait(self): + # If this fails it blocks. Unfortunately, but I see no other way of testing. + from threading import Thread, Lock + lock = Lock() + lock.acquire() + def t(): + mouse.wait() + lock.release() + Thread(target=t).start() + self.press() + lock.acquire() + + def test_record_play(self): + from threading import Thread, Lock + lock = Lock() + lock.acquire() + def t(): + self.recorded = mouse.record(RIGHT) + lock.release() + Thread(target=t).start() + self.click() + self.wheel(5) + self.move(100, 50) + self.press(RIGHT) + lock.acquire() + + self.assertEqual(len(self.recorded), 5) + self.assertEqual(self.recorded[0]._replace(time=None), ButtonEvent(DOWN, LEFT, None)) + self.assertEqual(self.recorded[1]._replace(time=None), ButtonEvent(UP, LEFT, None)) + self.assertEqual(self.recorded[2]._replace(time=None), WheelEvent(5, None)) + self.assertEqual(self.recorded[3]._replace(time=None), MoveEvent(100, 50, None)) + self.assertEqual(self.recorded[4]._replace(time=None), ButtonEvent(DOWN, RIGHT, None)) + + mouse.play(self.recorded, speed_factor=0) + events = self.flush_events() + self.assertEqual(len(events), 5) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('wheel', 5)) + self.assertEqual(events[3], ('move', (100, 50))) + self.assertEqual(events[4], (DOWN, RIGHT)) + + mouse.play(self.recorded) + events = self.flush_events() + self.assertEqual(len(events), 5) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('wheel', 5)) + self.assertEqual(events[3], ('move', (100, 50))) + self.assertEqual(events[4], (DOWN, RIGHT)) + + mouse.play(self.recorded, include_clicks=False) + events = self.flush_events() + self.assertEqual(len(events), 2) + self.assertEqual(events[0], ('wheel', 5)) + self.assertEqual(events[1], ('move', (100, 50))) + + mouse.play(self.recorded, include_moves=False) + events = self.flush_events() + self.assertEqual(len(events), 4) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('wheel', 5)) + self.assertEqual(events[3], (DOWN, RIGHT)) + + mouse.play(self.recorded, include_wheel=False) + events = self.flush_events() + self.assertEqual(len(events), 4) + self.assertEqual(events[0], (DOWN, LEFT)) + self.assertEqual(events[1], (UP, LEFT)) + self.assertEqual(events[2], ('move', (100, 50))) + self.assertEqual(events[3], (DOWN, RIGHT)) + +if __name__ == '__main__': + unittest.main() diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixcommon.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixcommon.py new file mode 100644 index 00000000..d240f998 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixcommon.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +import struct +import os +import atexit +from time import time as now +from threading import Thread +from glob import glob +try: + from queue import Queue +except ImportError: + from Queue import Queue + +event_bin_format = 'llHHI' + +# Taken from include/linux/input.h +# https://www.kernel.org/doc/Documentation/input/event-codes.txt +EV_SYN = 0x00 +EV_KEY = 0x01 +EV_REL = 0x02 +EV_ABS = 0x03 +EV_MSC = 0x04 + +def make_uinput(): + import fcntl, struct + + # Requires uinput driver, but it's usually available. + uinput = open("/dev/uinput", 'wb') + UI_SET_EVBIT = 0x40045564 + fcntl.ioctl(uinput, UI_SET_EVBIT, EV_KEY) + + UI_SET_KEYBIT = 0x40045565 + for i in range(256): + fcntl.ioctl(uinput, UI_SET_KEYBIT, i) + + BUS_USB = 0x03 + uinput_user_dev = "80sHHHHi64i64i64i64i" + axis = [0] * 64 * 4 + uinput.write(struct.pack(uinput_user_dev, b"Virtual Keyboard", BUS_USB, 1, 1, 1, 0, *axis)) + uinput.flush() # Without this you may get Errno 22: Invalid argument. + + UI_DEV_CREATE = 0x5501 + fcntl.ioctl(uinput, UI_DEV_CREATE) + UI_DEV_DESTROY = 0x5502 + #fcntl.ioctl(uinput, UI_DEV_DESTROY) + + return uinput + +class EventDevice(object): + def __init__(self, path): + self.path = path + self._input_file = None + self._output_file = None + + @property + def input_file(self): + if self._input_file is None: + try: + self._input_file = open(self.path, 'rb') + except IOError as e: + if e.strerror == 'Permission denied': + print('Permission denied ({}). You must be sudo to access global events.'.format(self.path)) + exit() + + def try_close(): + try: + self._input_file.close + except: + pass + atexit.register(try_close) + return self._input_file + + @property + def output_file(self): + if self._output_file is None: + self._output_file = open(self.path, 'wb') + atexit.register(self._output_file.close) + return self._output_file + + def read_event(self): + data = self.input_file.read(struct.calcsize(event_bin_format)) + seconds, microseconds, type, code, value = struct.unpack(event_bin_format, data) + return seconds + microseconds / 1e6, type, code, value, self.path + + def write_event(self, type, code, value): + integer, fraction = divmod(now(), 1) + seconds = int(integer) + microseconds = int(fraction * 1e6) + data_event = struct.pack(event_bin_format, seconds, microseconds, type, code, value) + + # Send a sync event to ensure other programs update. + sync_event = struct.pack(event_bin_format, seconds, microseconds, EV_SYN, 0, 0) + + self.output_file.write(data_event + sync_event) + self.output_file.flush() + +class AggregatedEventDevice(object): + def __init__(self, devices, output=None): + self.event_queue = Queue() + self.devices = devices + self.output = output or self.devices[0] + def start_reading(device): + while True: + self.event_queue.put(device.read_event()) + for device in self.devices: + thread = Thread(target=start_reading, args=[device]) + thread.setDaemon(True) + thread.start() + + def read_event(self): + return self.event_queue.get(block=True) + + def write_event(self, type, code, value): + self.output.write_event(type, code, value) + +import re +from collections import namedtuple +DeviceDescription = namedtuple('DeviceDescription', 'event_file is_mouse is_keyboard') +device_pattern = r"""N: Name="([^"]+?)".+?H: Handlers=([^\n]+)""" +def list_devices_from_proc(type_name): + try: + with open('/proc/bus/input/devices') as f: + description = f.read() + except FileNotFoundError: + return + + devices = {} + for name, handlers in re.findall(device_pattern, description, re.DOTALL): + path = '/dev/input/event' + re.search(r'event(\d+)', handlers).group(1) + if type_name in handlers: + yield EventDevice(path) + +def list_devices_from_by_id(type_name): + for path in glob('/dev/input/by-id/*-event-' + type_name): + yield EventDevice(path) + +def aggregate_devices(type_name): + # Some systems have multiple keyboards with different range of allowed keys + # on each one, like a notebook with a "keyboard" device exclusive for the + # power button. Instead of figuring out which keyboard allows which key to + # send events, we create a fake device and send all events through there. + uinput = make_uinput() + fake_device = EventDevice('uinput Fake Device') + fake_device._input_file = uinput + fake_device._output_file = uinput + + # We don't aggregate devices from different sources to avoid + # duplicates. + + devices_from_proc = list(list_devices_from_proc(type_name)) + if devices_from_proc: + return AggregatedEventDevice(devices_from_proc, output=fake_device) + + # breaks on mouse for virtualbox + # was getting /dev/input/by-id/usb-VirtualBox_USB_Tablet-event-mouse + devices_from_by_id = list(list_devices_from_by_id(type_name)) + if devices_from_by_id: + return AggregatedEventDevice(devices_from_by_id, output=fake_device) + + # If no keyboards were found we can only use the fake device to send keys. + return fake_device + + +def ensure_root(): + if os.geteuid() != 0: + raise ImportError('You must be root to use this library on linux.') diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixmouse.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixmouse.py new file mode 100644 index 00000000..5e3b595d --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_nixmouse.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +import struct +from subprocess import check_output +import re +from ._nixcommon import EV_KEY, EV_REL, EV_MSC, EV_SYN, EV_ABS, aggregate_devices, ensure_root +from ._mouse_event import ButtonEvent, WheelEvent, MoveEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN + +import ctypes +import ctypes.util +from ctypes import c_uint32, c_uint, c_int, c_void_p, byref + +display = None +window = None +x11 = None +def build_display(): + global display, window, x11 + if display and window and x11: return + x11 = ctypes.cdll.LoadLibrary(ctypes.util.find_library('X11')) + # Required because we will have multiple threads calling x11, + # such as the listener thread and then main using "move_to". + x11.XInitThreads() + # Explicitly set XOpenDisplay.restype to avoid segfault on 64 bit OS. + # http://stackoverflow.com/questions/35137007/get-mouse-position-on-linux-pure-python + x11.XOpenDisplay.restype = c_void_p + display = c_void_p(x11.XOpenDisplay(0)) + window = x11.XDefaultRootWindow(display) + +def get_position(): + build_display() + root_id, child_id = c_void_p(), c_void_p() + root_x, root_y, win_x, win_y = c_int(), c_int(), c_int(), c_int() + mask = c_uint() + ret = x11.XQueryPointer(display, c_uint32(window), byref(root_id), byref(child_id), + byref(root_x), byref(root_y), + byref(win_x), byref(win_y), byref(mask)) + return root_x.value, root_y.value + +def move_to(x, y): + build_display() + x11.XWarpPointer(display, None, window, 0, 0, 0, 0, x, y) + x11.XFlush(display) + +REL_X = 0x00 +REL_Y = 0x01 +REL_Z = 0x02 +REL_HWHEEL = 0x06 +REL_WHEEL = 0x08 + +ABS_X = 0x00 +ABS_Y = 0x01 + +BTN_MOUSE = 0x110 +BTN_LEFT = 0x110 +BTN_RIGHT = 0x111 +BTN_MIDDLE = 0x112 +BTN_SIDE = 0x113 +BTN_EXTRA = 0x114 + +button_by_code = { + BTN_LEFT: LEFT, + BTN_RIGHT: RIGHT, + BTN_MIDDLE: MIDDLE, + BTN_SIDE: X, + BTN_EXTRA: X2, +} +code_by_button = {button: code for code, button in button_by_code.items()} + +device = None +def build_device(): + global device + if device: return + ensure_root() + device = aggregate_devices('mouse') +init = build_device + +def listen(queue): + build_device() + + while True: + time, type, code, value, device_id = device.read_event() + if type == EV_SYN or type == EV_MSC: + continue + + event = None + arg = None + + if type == EV_KEY: + event = ButtonEvent(DOWN if value else UP, button_by_code.get(code, '?'), time) + elif type == EV_REL: + value, = struct.unpack('i', struct.pack('I', value)) + + if code == REL_WHEEL: + event = WheelEvent(value, time) + elif code in (REL_X, REL_Y): + x, y = get_position() + event = MoveEvent(x, y, time) + + if event is None: + # Unknown event type. + continue + + queue.put(event) + +def press(button=LEFT): + build_device() + device.write_event(EV_KEY, code_by_button[button], 0x01) + +def release(button=LEFT): + build_device() + device.write_event(EV_KEY, code_by_button[button], 0x00) + +def move_relative(x, y): + build_device() + # Note relative events are not in terms of pixels, but millimeters. + if x < 0: + x += 2**32 + if y < 0: + y += 2**32 + device.write_event(EV_REL, REL_X, x) + device.write_event(EV_REL, REL_Y, y) + +def wheel(delta=1): + build_device() + if delta < 0: + delta += 2**32 + device.write_event(EV_REL, REL_WHEEL, delta) + + +if __name__ == '__main__': + #listen(print) + move_to(100, 200) diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_winmouse.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_winmouse.py new file mode 100644 index 00000000..b5806a22 --- /dev/null +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/mouse/_winmouse.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +import ctypes +import time +from ctypes import c_short, c_char, c_uint8, c_int32, c_int, c_uint, c_uint32, c_long, byref, Structure, CFUNCTYPE, POINTER +from ctypes.wintypes import DWORD, BOOL, HHOOK, MSG, LPWSTR, WCHAR, WPARAM, LPARAM +LPMSG = POINTER(MSG) + +import atexit + +from ._mouse_event import ButtonEvent, WheelEvent, MoveEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE, WHEEL, HORIZONTAL, VERTICAL + +#user32 = ctypes.windll.user32 +user32 = ctypes.WinDLL('user32', use_last_error = True) + +class MSLLHOOKSTRUCT(Structure): + _fields_ = [("x", c_long), + ("y", c_long), + ('data', c_int32), + ('reserved', c_int32), + ("flags", DWORD), + ("time", c_int), + ] + +LowLevelMouseProc = CFUNCTYPE(c_int, WPARAM, LPARAM, POINTER(MSLLHOOKSTRUCT)) + +SetWindowsHookEx = user32.SetWindowsHookExA +#SetWindowsHookEx.argtypes = [c_int, LowLevelMouseProc, c_int, c_int] +SetWindowsHookEx.restype = HHOOK + +CallNextHookEx = user32.CallNextHookEx +#CallNextHookEx.argtypes = [c_int , c_int, c_int, POINTER(MSLLHOOKSTRUCT)] +CallNextHookEx.restype = c_int + +UnhookWindowsHookEx = user32.UnhookWindowsHookEx +UnhookWindowsHookEx.argtypes = [HHOOK] +UnhookWindowsHookEx.restype = BOOL + +GetMessage = user32.GetMessageW +GetMessage.argtypes = [LPMSG, c_int, c_int, c_int] +GetMessage.restype = BOOL + +TranslateMessage = user32.TranslateMessage +TranslateMessage.argtypes = [LPMSG] +TranslateMessage.restype = BOOL + +DispatchMessage = user32.DispatchMessageA +DispatchMessage.argtypes = [LPMSG] + +GetDoubleClickTime = user32.GetDoubleClickTime + +# Beware, as of 2016-01-30 the official docs have a very incomplete list. +# This one was compiled from experience and may be incomplete. +WM_MOUSEMOVE = 0x200 +WM_LBUTTONDOWN = 0x201 +WM_LBUTTONUP = 0x202 +WM_LBUTTONDBLCLK = 0x203 +WM_RBUTTONDOWN = 0x204 +WM_RBUTTONUP = 0x205 +WM_RBUTTONDBLCLK = 0x206 +WM_MBUTTONDOWN = 0x207 +WM_MBUTTONUP = 0x208 +WM_MBUTTONDBLCLK = 0x209 +WM_MOUSEWHEEL = 0x20A +WM_XBUTTONDOWN = 0x20B +WM_XBUTTONUP = 0x20C +WM_XBUTTONDBLCLK = 0x20D +WM_NCXBUTTONDOWN = 0x00AB +WM_NCXBUTTONUP = 0x00AC +WM_NCXBUTTONDBLCLK = 0x00AD +WM_MOUSEHWHEEL = 0x20E +WM_LBUTTONDOWN = 0x0201 +WM_LBUTTONUP = 0x0202 +WM_MOUSEMOVE = 0x0200 +WM_MOUSEWHEEL = 0x020A +WM_MOUSEHWHEEL = 0x020E +WM_RBUTTONDOWN = 0x0204 +WM_RBUTTONUP = 0x0205 + +buttons_by_wm_code = { + WM_LBUTTONDOWN: (DOWN, LEFT), + WM_LBUTTONUP: (UP, LEFT), + WM_LBUTTONDBLCLK: (DOUBLE, LEFT), + + WM_RBUTTONDOWN: (DOWN, RIGHT), + WM_RBUTTONUP: (UP, RIGHT), + WM_RBUTTONDBLCLK: (DOUBLE, RIGHT), + + WM_MBUTTONDOWN: (DOWN, MIDDLE), + WM_MBUTTONUP: (UP, MIDDLE), + WM_MBUTTONDBLCLK: (DOUBLE, MIDDLE), + + WM_XBUTTONDOWN: (DOWN, X), + WM_XBUTTONUP: (UP, X), + WM_XBUTTONDBLCLK: (DOUBLE, X), +} + +MOUSEEVENTF_ABSOLUTE = 0x8000 +MOUSEEVENTF_MOVE = 0x1 +MOUSEEVENTF_WHEEL = 0x800 +MOUSEEVENTF_HWHEEL = 0x1000 +MOUSEEVENTF_LEFTDOWN = 0x2 +MOUSEEVENTF_LEFTUP = 0x4 +MOUSEEVENTF_RIGHTDOWN = 0x8 +MOUSEEVENTF_RIGHTUP = 0x10 +MOUSEEVENTF_MIDDLEDOWN = 0x20 +MOUSEEVENTF_MIDDLEUP = 0x40 +MOUSEEVENTF_XDOWN = 0x0080 +MOUSEEVENTF_XUP = 0x0100 + +simulated_mouse_codes = { + (WHEEL, HORIZONTAL): MOUSEEVENTF_HWHEEL, + (WHEEL, VERTICAL): MOUSEEVENTF_WHEEL, + + (DOWN, LEFT): MOUSEEVENTF_LEFTDOWN, + (UP, LEFT): MOUSEEVENTF_LEFTUP, + + (DOWN, RIGHT): MOUSEEVENTF_RIGHTDOWN, + (UP, RIGHT): MOUSEEVENTF_RIGHTUP, + + (DOWN, MIDDLE): MOUSEEVENTF_MIDDLEDOWN, + (UP, MIDDLE): MOUSEEVENTF_MIDDLEUP, + + (DOWN, X): MOUSEEVENTF_XDOWN, + (UP, X): MOUSEEVENTF_XUP, +} + +NULL = c_int(0) + +WHEEL_DELTA = 120 + +init = lambda: None + +previous_button_event = None # defined in global scope +def listen(queue): + + def low_level_mouse_handler(nCode, wParam, lParam): + global previous_button_event + + struct = lParam.contents + # Can't use struct.time because it's usually zero. + t = time.time() + + if wParam == WM_MOUSEMOVE: + event = MoveEvent(struct.x, struct.y, t) + elif wParam == WM_MOUSEWHEEL: + event = WheelEvent(struct.data / (WHEEL_DELTA * (2<<15)), t) + elif wParam in buttons_by_wm_code: + type, button = buttons_by_wm_code.get(wParam, ('?', '?')) + if wParam >= WM_XBUTTONDOWN: + button = {0x10000: X, 0x20000: X2}[struct.data] + event = ButtonEvent(type, button, t) + + if (event.event_type == DOWN) and previous_button_event is not None: + # https://msdn.microsoft.com/en-us/library/windows/desktop/gg153548%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 + if event.time - previous_button_event.time <= GetDoubleClickTime() / 1000.0: + event = ButtonEvent(DOUBLE, event.button, event.time) + + previous_button_event = event + else: + # Unknown event type. + return CallNextHookEx(NULL, nCode, wParam, lParam) + + queue.put(event) + return CallNextHookEx(NULL, nCode, wParam, lParam) + + WH_MOUSE_LL = c_int(14) + mouse_callback = LowLevelMouseProc(low_level_mouse_handler) + mouse_hook = SetWindowsHookEx(WH_MOUSE_LL, mouse_callback, NULL, NULL) + + # Register to remove the hook when the interpreter exits. Unfortunately a + # try/finally block doesn't seem to work here. + atexit.register(UnhookWindowsHookEx, mouse_hook) + + msg = LPMSG() + while not GetMessage(msg, NULL, NULL, NULL): + TranslateMessage(msg) + DispatchMessage(msg) + +def _translate_button(button): + if button == X or button == X2: + return X, {X: 0x10000, X2: 0x20000}[button] + else: + return button, 0 + +def press(button=LEFT): + button, data = _translate_button(button) + code = simulated_mouse_codes[(DOWN, button)] + user32.mouse_event(code, 0, 0, data, 0) + +def release(button=LEFT): + button, data = _translate_button(button) + code = simulated_mouse_codes[(UP, button)] + user32.mouse_event(code, 0, 0, data, 0) + +def wheel(delta=1): + code = simulated_mouse_codes[(WHEEL, VERTICAL)] + user32.mouse_event(code, 0, 0, int(delta * WHEEL_DELTA), 0) + +def move_to(x, y): + user32.SetCursorPos(int(x), int(y)) + +def move_relative(x, y): + user32.mouse_event(MOUSEEVENTF_MOVE, int(x), int(y), 0, 0) + +class POINT(Structure): + _fields_ = [("x", c_long), ("y", c_long)] + +def get_position(): + point = POINT() + user32.GetCursorPos(byref(point)) + return (point.x, point.y) + +if __name__ == '__main__': + def p(e): + print(e) + listen(p) diff --git a/Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py b/Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py new file mode 100644 index 00000000..5a3a510c --- /dev/null +++ b/Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py @@ -0,0 +1,125 @@ +import datetime # datetime functions +import time # time functions +# Init the keyboard listener +def Init(inGSettings): + pass + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Technical defs +import pdb +SpecialKeyList = [] +inList = [ + # { + # "EventStartDatetime": datetime.datetime.now(), + # "EventEndDatetime": datetime.datetime.now(), + # "EventTypeStr": "MOVE", # MOVE | CLICK | SCROLL | SELECT + # "ValueInt": "" # MOVE: point count + # } +] +gMoveWaitNextPointPercentFloat = 4 +gMoveWaitNextPointSecondsFloat = None +gMovePrevious = None # {"EventDatetime": datetime.datetime.now(), "XInt": None, "YInt": None} +gMovePointCountInt = None +gMoveFirstDatetime = None +gMoveCloseCheckIntervalSecondsFloat = 3 + +from pynput import mouse +import mouse as mouse_new # https://github.com/boppreh/mouse#mouse.hook +def on_move(x, y): + global gMovePrevious + global gMoveWaitNextPointSecondsFloat + global gMoveWaitNextPointPercentFloat + global gMovePointCountInt + global gMoveFirstDatetime + lNowDatetime = datetime.datetime.now() + if gMovePrevious is None: + gMoveFirstDatetime = lNowDatetime + gMovePrevious = {"EventDatetime": gMoveFirstDatetime, "XInt": x, "YInt": y} + gMovePointCountInt = 1 + else: + lMovePreviousNew = {"EventDatetime": lNowDatetime, "XInt": x, "YInt": y} + lNewOldDeltaSecondsFloat = (lMovePreviousNew["EventDatetime"]-gMovePrevious["EventDatetime"]).total_seconds() + if gMoveWaitNextPointSecondsFloat is None: # We have no wait time - just calculate it + gMoveWaitNextPointSecondsFloat = lNewOldDeltaSecondsFloat * gMoveWaitNextPointPercentFloat # in the end for the next point + gMovePrevious = {"EventDatetime": lNowDatetime, "XInt": x, "YInt": y} + gMovePointCountInt = gMovePointCountInt + 1 + else: # check if we apply in time - else create new move record + if gMoveWaitNextPointSecondsFloat >= lNewOldDeltaSecondsFloat: # In applied second wait range + # Rewrite the globals + gMoveWaitNextPointSecondsFloat = lNewOldDeltaSecondsFloat * gMoveWaitNextPointPercentFloat # in the end for the next point + gMovePrevious = {"EventDatetime": lNowDatetime, "XInt": x, "YInt": y} + gMovePointCountInt = gMovePointCountInt + 1 + else: + # Add in result list + lResult = { + "EventStartDatetime": gMoveFirstDatetime, + "EventEndDatetime": lNowDatetime, + "EventTypeStr": "MOVE", # MOVE | CLICK | SCROLL | SELECT + "ValueInt": gMovePointCountInt # MOVE: point count + } + inList.append(lResult) + print(lResult) + # Close the move + gMoveWaitNextPointSecondsFloat = None + gMovePrevious = None + gMovePointCountInt = None + gMoveFirstDatetime= None + #print('Pointer moved to {0}'.format( + # (x, y))) + +def on_click(x, y, button, pressed): + print('{0} at {1}'.format( + 'Pressed' if pressed else 'Released', + (x, y))) + print(button) + if not pressed: + # Stop listener + return True + +def on_scroll(x, y, dx, dy): + print('Scrolled {0} at {1}'.format( + 'down' if dy < 0 else 'up', + (x, y))) + +# Collect events until released +#with mouse.Listener( +# on_move=on_move, +# on_click=on_click, +# on_scroll=on_scroll) as listener: +# listener.join() + +# ...or, in a non-blocking fashion: +#listener = mouse.Listener( +# on_move=on_move, +# on_click=on_click, +# on_scroll=on_scroll) +#listener.start() +def Test(inArg): + if type(inArg) is mouse_new._mouse_event.MoveEvent: + on_move(x = inArg.x, y = inArg.y) +mouse_new.hook(Test) + +import pprint +while True: + # Check move interval + lNowDatetime = datetime.datetime.now() + if gMovePrevious is not None and gMoveWaitNextPointSecondsFloat is not None: + lNewOldDeltaSecondsFloat = (lNowDatetime - gMovePrevious["EventDatetime"]).total_seconds() + if lNewOldDeltaSecondsFloat > gMoveWaitNextPointSecondsFloat: + # Add in result list + lResult = { + "EventStartDatetime": gMoveFirstDatetime, + "EventEndDatetime": lNowDatetime, + "EventTypeStr": "MOVE", # MOVE | CLICK | SCROLL | SELECT + "ValueInt": gMovePointCountInt # MOVE: point count + } + inList.append(lResult) + print(lResult) + # Close the move + gMoveWaitNextPointSecondsFloat = None + gMovePrevious = None + gMovePointCountInt = None + gMoveFirstDatetime = None + time.sleep(gMoveCloseCheckIntervalSecondsFloat) + #print(inList) + #pprint.pprint(inList) \ No newline at end of file From e9005c1fe2e767da4b880b58242b1eb94d990e72 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sun, 7 Jun 2020 18:57:29 +0300 Subject: [PATCH 07/19] # Worklogger --- .../WorkLogger/pyWorkLogger/Catcher/Mouse.py | 126 ++++++++++++++---- 1 file changed, 102 insertions(+), 24 deletions(-) diff --git a/Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py b/Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py index 5a3a510c..7ff82f77 100644 --- a/Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py +++ b/Utils/WorkLogger/pyWorkLogger/Catcher/Mouse.py @@ -16,6 +16,7 @@ inList = [ # "ValueInt": "" # MOVE: point count # } ] +gMoveWaitNextPointSecondsMaxFloat = 5 gMoveWaitNextPointPercentFloat = 4 gMoveWaitNextPointSecondsFloat = None gMovePrevious = None # {"EventDatetime": datetime.datetime.now(), "XInt": None, "YInt": None} @@ -50,31 +51,104 @@ def on_move(x, y): gMovePrevious = {"EventDatetime": lNowDatetime, "XInt": x, "YInt": y} gMovePointCountInt = gMovePointCountInt + 1 else: - # Add in result list - lResult = { - "EventStartDatetime": gMoveFirstDatetime, - "EventEndDatetime": lNowDatetime, - "EventTypeStr": "MOVE", # MOVE | CLICK | SCROLL | SELECT - "ValueInt": gMovePointCountInt # MOVE: point count - } - inList.append(lResult) - print(lResult) - # Close the move - gMoveWaitNextPointSecondsFloat = None - gMovePrevious = None - gMovePointCountInt = None - gMoveFirstDatetime= None + if "left" not in SpecialKeyList: + pass + # Add in result list + #lResult = { + # "EventStartDatetime": gMoveFirstDatetime, + # "EventEndDatetime": lNowDatetime, + # "EventTypeStr": "MOVE", # MOVE | CLICK | SCROLL | SELECT + # "ValueInt": gMovePointCountInt # MOVE: point count + #} + #inList.append(lResult) + #print(lResult) + ## Close the move + #gMoveWaitNextPointSecondsFloat = None + #gMovePrevious = None + #gMovePointCountInt = None + #gMoveFirstDatetime= None #print('Pointer moved to {0}'.format( # (x, y))) -def on_click(x, y, button, pressed): - print('{0} at {1}'.format( - 'Pressed' if pressed else 'Released', - (x, y))) - print(button) - if not pressed: - # Stop listener - return True +def on_click(inButtonEvent): + global SpecialKeyList + global gMovePrevious + global gMoveWaitNextPointSecondsFloat + global gMoveWaitNextPointPercentFloat + global gMovePointCountInt + global gMoveFirstDatetime + lNowDatetime = datetime.datetime.now() + if inButtonEvent.button=="left" and inButtonEvent.event_type == "down": + SpecialKeyList.append("left") + # Close the previous move action + if gMovePrevious is not None: + # Add in result list + lResult = { + "EventStartDatetime": gMoveFirstDatetime, + "EventEndDatetime": lNowDatetime, + "EventTypeStr": "MOVE", # MOVE | CLICK | SCROLL | SELECT + "ValueInt": gMovePointCountInt # MOVE: point count + } + inList.append(lResult) + print(lResult) + # Close the move + gMoveWaitNextPointSecondsFloat = None + gMovePrevious = None + gMovePointCountInt = None + gMoveFirstDatetime = None + elif inButtonEvent.button=="left" and inButtonEvent.event_type == "up": + if "left" in SpecialKeyList: SpecialKeyList.remove("left") + # Close the previous move action + if gMovePrevious is not None: + # Add in result list + lResult = { + "EventStartDatetime": gMoveFirstDatetime, + "EventEndDatetime": lNowDatetime, + "EventTypeStr": "SELECT", # MOVE | CLICK | SCROLL | SELECT + "ValueInt": gMovePointCountInt # MOVE: point count + } + inList.append(lResult) + print(lResult) + # Close the move + gMoveWaitNextPointSecondsFloat = None + gMovePrevious = None + gMovePointCountInt = None + gMoveFirstDatetime = None + else: + # Add in result list + lResult = { + "EventStartDatetime": lNowDatetime, + "EventEndDatetime": lNowDatetime, + "EventTypeStr": "CLICK", # MOVE | CLICK | SCROLL | SELECT + "ValueInt": 'left' # MOVE: point count + } + inList.append(lResult) + print(lResult) + # Close the move + gMoveWaitNextPointSecondsFloat = None + gMovePrevious = None + gMovePointCountInt = None + gMoveFirstDatetime = None + elif inButtonEvent.button=="right" and inButtonEvent.event_type == "up": + # Add in result list + lResult = { + "EventStartDatetime": lNowDatetime, + "EventEndDatetime": lNowDatetime, + "EventTypeStr": "CLICK", # MOVE | CLICK | SCROLL | SELECT + "ValueInt": 'right' # MOVE: point count + } + inList.append(lResult) + print(lResult) + elif inButtonEvent.button=="middle" and inButtonEvent.event_type == "up": + # Add in result list + lResult = { + "EventStartDatetime": lNowDatetime, + "EventEndDatetime": lNowDatetime, + "EventTypeStr": "CLICK", # MOVE | CLICK | SCROLL | SELECT + "ValueInt": 'middle' # MOVE: point count + } + inList.append(lResult) + print(lResult) def on_scroll(x, y, dx, dy): print('Scrolled {0} at {1}'.format( @@ -97,15 +171,19 @@ def on_scroll(x, y, dx, dy): def Test(inArg): if type(inArg) is mouse_new._mouse_event.MoveEvent: on_move(x = inArg.x, y = inArg.y) + elif type(inArg) is mouse_new._mouse_event.ButtonEvent: + on_click(inButtonEvent = inArg) + elif type(inArg) is mouse_new._mouse_event.WheelEvent: + print(inArg) mouse_new.hook(Test) import pprint while True: # Check move interval lNowDatetime = datetime.datetime.now() - if gMovePrevious is not None and gMoveWaitNextPointSecondsFloat is not None: + if gMovePrevious is not None and gMoveWaitNextPointSecondsMaxFloat is not None and "left" not in SpecialKeyList: lNewOldDeltaSecondsFloat = (lNowDatetime - gMovePrevious["EventDatetime"]).total_seconds() - if lNewOldDeltaSecondsFloat > gMoveWaitNextPointSecondsFloat: + if lNewOldDeltaSecondsFloat > gMoveWaitNextPointSecondsMaxFloat: # Add in result list lResult = { "EventStartDatetime": gMoveFirstDatetime, From ea8233e79d380a564e7510d9dd8ced873d52aaee Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Mon, 8 Jun 2020 13:55:37 +0300 Subject: [PATCH 08/19] # Add Orchestrator:WebFront - mGlobal.Processor.Send(inDataList) --- .../INSTALLER | 0 .../pyOpenRPA-1.1.6.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.6.dist-info}/RECORD | 16 ++++++++-------- .../WHEEL | 0 .../top_level.txt | 0 .../pyOpenRPA/Orchestrator/Web/Index.xhtml | 15 +++++++++++++++ .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- .../INSTALLER | 0 .../pyOpenRPA-1.1.6.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.6.dist-info}/RECORD | 16 ++++++++-------- .../WHEEL | 0 .../top_level.txt | 0 .../pyOpenRPA/Orchestrator/Web/Index.xhtml | 15 +++++++++++++++ .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml | 15 +++++++++++++++ Sources/pyOpenRPA/__init__.py | 2 +- v1.1.5 => v1.1.6 | 0 17 files changed, 66 insertions(+), 21 deletions(-) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.5.dist-info => pyOpenRPA-1.1.6.dist-info}/INSTALLER (100%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info}/METADATA (99%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info}/RECORD (98%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.5.dist-info => pyOpenRPA-1.1.6.dist-info}/WHEEL (100%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.5.dist-info => pyOpenRPA-1.1.6.dist-info}/top_level.txt (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.5.dist-info => pyOpenRPA-1.1.6.dist-info}/INSTALLER (100%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info}/METADATA (99%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info}/RECORD (98%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.5.dist-info => pyOpenRPA-1.1.6.dist-info}/WHEEL (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.5.dist-info => pyOpenRPA-1.1.6.dist-info}/top_level.txt (100%) rename v1.1.5 => v1.1.6 (100%) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA index 48b0e094..961dce31 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.5 +Version: 1.1.6 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.5.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD similarity index 98% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD index af5054a1..cb4be827 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD @@ -1,14 +1,14 @@ -pyOpenRPA-1.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.5.dist-info/METADATA,sha256=oa4ndZiOhpyVqByJvk5F5fSyQ62ke1RPGhwO9UFDG3c,3541 -pyOpenRPA-1.1.5.dist-info/RECORD,, -pyOpenRPA-1.1.5.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.5.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.6.dist-info/METADATA,sha256=rwuV9eOeBt3pIq0mHtx_kopH7R27AwoO2vc3ht08rto,3541 +pyOpenRPA-1.1.6.dist-info/RECORD,, +pyOpenRPA-1.1.6.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.6.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 pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0,408 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 -pyOpenRPA/.idea/workspace.xml,sha256=lPQFI_kfLXE7-PICt5O--RAJU_0f8APV_q5Rm5q9xq8,2912 +pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 pyOpenRPA/Orchestrator/Processor.py,sha256=ur0jDDteyBzfXR4DXnpUfBwNEW-M2nEtgyd-HQoPVtQ,11376 @@ -36,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=giviLTJ1GJyVayvPski2GkcB6Wd2MFYVw5yK6gSsx84,38272 +pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=yPIAa6jr3VVzWXiL59LEVaaGPrKglkVzxtACpb-HOwA,38637 pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144 @@ -300,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=ngE8yR10-argUOXI73_B2fC66l80-yt6r6KHN7c-Kkg,174 +pyOpenRPA/__init__.py,sha256=yokfvSsMRc8Ebg9aXbfXgfuYBKGBh8GrSbEpb5wjBgQ,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.5.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt 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 db422ff4..e64da833 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 @@ -492,6 +492,21 @@ dataType: "text" }); } + mGlobal.Processor.Send = function(inData) { + lData = inData + $.ajax({ + type: "POST", + url: 'Utils/Processor', + data: JSON.stringify(lData), + success: + function(lData,l2,l3) + { + var lResponseJSON=JSON.parse(lData) + ///TODO Show error if exist error + }, + dataType: "text" + }); + } mGlobal.Processor.LogListShow = function() { lData = [ { 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 ab89af4d..9bc9cbe0 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.5' +__version__ = 'v1.1.6' __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.5.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/INSTALLER rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA similarity index 99% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA index 48b0e094..961dce31 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/METADATA +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.5 +Version: 1.1.6 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.5.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD similarity index 98% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD index af5054a1..cb4be827 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/RECORD +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD @@ -1,14 +1,14 @@ -pyOpenRPA-1.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.5.dist-info/METADATA,sha256=oa4ndZiOhpyVqByJvk5F5fSyQ62ke1RPGhwO9UFDG3c,3541 -pyOpenRPA-1.1.5.dist-info/RECORD,, -pyOpenRPA-1.1.5.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.5.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.6.dist-info/METADATA,sha256=rwuV9eOeBt3pIq0mHtx_kopH7R27AwoO2vc3ht08rto,3541 +pyOpenRPA-1.1.6.dist-info/RECORD,, +pyOpenRPA-1.1.6.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.6.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 pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0,408 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 -pyOpenRPA/.idea/workspace.xml,sha256=lPQFI_kfLXE7-PICt5O--RAJU_0f8APV_q5Rm5q9xq8,2912 +pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 pyOpenRPA/Orchestrator/Processor.py,sha256=ur0jDDteyBzfXR4DXnpUfBwNEW-M2nEtgyd-HQoPVtQ,11376 @@ -36,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=giviLTJ1GJyVayvPski2GkcB6Wd2MFYVw5yK6gSsx84,38272 +pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=yPIAa6jr3VVzWXiL59LEVaaGPrKglkVzxtACpb-HOwA,38637 pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144 @@ -300,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=ngE8yR10-argUOXI73_B2fC66l80-yt6r6KHN7c-Kkg,174 +pyOpenRPA/__init__.py,sha256=yokfvSsMRc8Ebg9aXbfXgfuYBKGBh8GrSbEpb5wjBgQ,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.5.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/WHEEL similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/WHEEL rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/WHEEL diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.5.dist-info/top_level.txt rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt 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 db422ff4..e64da833 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 @@ -492,6 +492,21 @@ dataType: "text" }); } + mGlobal.Processor.Send = function(inData) { + lData = inData + $.ajax({ + type: "POST", + url: 'Utils/Processor', + data: JSON.stringify(lData), + success: + function(lData,l2,l3) + { + var lResponseJSON=JSON.parse(lData) + ///TODO Show error if exist error + }, + dataType: "text" + }); + } mGlobal.Processor.LogListShow = function() { lData = [ { 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 ab89af4d..9bc9cbe0 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.5' +__version__ = 'v1.1.6' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml b/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml index db422ff4..e64da833 100644 --- a/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml +++ b/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml @@ -492,6 +492,21 @@ dataType: "text" }); } + mGlobal.Processor.Send = function(inData) { + lData = inData + $.ajax({ + type: "POST", + url: 'Utils/Processor', + data: JSON.stringify(lData), + success: + function(lData,l2,l3) + { + var lResponseJSON=JSON.parse(lData) + ///TODO Show error if exist error + }, + dataType: "text" + }); + } mGlobal.Processor.LogListShow = function() { lData = [ { diff --git a/Sources/pyOpenRPA/__init__.py b/Sources/pyOpenRPA/__init__.py index ab89af4d..9bc9cbe0 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.1.5' +__version__ = 'v1.1.6' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/v1.1.5 b/v1.1.6 similarity index 100% rename from v1.1.5 rename to v1.1.6 From 4466355318b6eeb7ca8f738c18961ed2eb02cb2d Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Mon, 8 Jun 2020 16:32:21 +0300 Subject: [PATCH 09/19] # Orchestrator::RobotRDPActive: Dont create RDP is session is exist! --- .../Orchestrator/RobotRDPActive/Processor.py | 46 ++++++++++--------- v1.1.6 => v1.1.7 | 0 2 files changed, 24 insertions(+), 22 deletions(-) rename v1.1.6 => v1.1.7 (100%) diff --git a/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py b/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py index 20cd033e..39e6d05e 100644 --- a/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py +++ b/Sources/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py @@ -11,28 +11,30 @@ gSettings = None # Gsettings will be initialized after the import module # Create new RDPSession in RobotRDPActive def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr): global gSettings - lRDPConfigurationItem = { # Init the configuration item - "Host": inHostStr, # Host address, example "77.77.22.22" - "Port": inPortStr, # RDP Port, example "3389" - "Login": inLoginStr, # Login, example "test" - "Password": inPasswordStr, # Password, example "test" - "Screen": { - "Width": 1680, # Width of the remote desktop in pixels, example 1680 - "Height": 1050, # Height of the remote desktop in pixels, example 1050 - # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example - "FlagUseAllMonitors": False, # True or False, example False - "DepthBit": "32" # "32" or "24" or "16" or "15", example "32" - }, - "SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"] - ###### Will updated in program ############ - "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example "" - "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False - "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 - } - gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem # Add item in RDPList - Connector.Session(lRDPConfigurationItem) # Create the RDP session - Connector.SystemRDPWarningClickOk() # Click all warning messages + # ATTENTION - dont connect if RDP session is exist + if inRDPSessionKeyStr not in gSettings["RobotRDPActive"]["RDPList"]: + lRDPConfigurationItem = { # Init the configuration item + "Host": inHostStr, # Host address, example "77.77.22.22" + "Port": inPortStr, # RDP Port, example "3389" + "Login": inLoginStr, # Login, example "test" + "Password": inPasswordStr, # Password, example "test" + "Screen": { + "Width": 1680, # Width of the remote desktop in pixels, example 1680 + "Height": 1050, # Height of the remote desktop in pixels, example 1050 + # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example + "FlagUseAllMonitors": False, # True or False, example False + "DepthBit": "32" # "32" or "24" or "16" or "15", example "32" + }, + "SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"] + ###### Will updated in program ############ + "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example "" + "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False + "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 + } + 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 diff --git a/v1.1.6 b/v1.1.7 similarity index 100% rename from v1.1.6 rename to v1.1.7 From 0f22e8ebebaab34604212316e3b18a51041a2c37 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Mon, 8 Jun 2020 16:34:39 +0300 Subject: [PATCH 10/19] # Python upgrade to pyOpenRPA 1.1.7 --- .../INSTALLER | 0 .../pyOpenRPA-1.1.7.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.7.dist-info}/RECORD | 16 +++---- .../WHEEL | 0 .../top_level.txt | 0 .../Orchestrator/RobotRDPActive/Processor.py | 46 ++++++++++--------- .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- .../INSTALLER | 0 .../pyOpenRPA-1.1.7.dist-info}/METADATA | 2 +- .../pyOpenRPA-1.1.7.dist-info}/RECORD | 16 +++---- .../WHEEL | 0 .../top_level.txt | 0 .../Orchestrator/RobotRDPActive/Processor.py | 46 ++++++++++--------- .../Lib/site-packages/pyOpenRPA/__init__.py | 2 +- Sources/pyOpenRPA/__init__.py | 2 +- 15 files changed, 69 insertions(+), 65 deletions(-) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.6.dist-info => pyOpenRPA-1.1.7.dist-info}/INSTALLER (100%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info}/METADATA (99%) rename Resources/{WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info => WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info}/RECORD (98%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.6.dist-info => pyOpenRPA-1.1.7.dist-info}/WHEEL (100%) rename Resources/WPy32-3720/python-3.7.2/Lib/site-packages/{pyOpenRPA-1.1.6.dist-info => pyOpenRPA-1.1.7.dist-info}/top_level.txt (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.6.dist-info => pyOpenRPA-1.1.7.dist-info}/INSTALLER (100%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info}/METADATA (99%) rename Resources/{WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info => WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info}/RECORD (98%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.6.dist-info => pyOpenRPA-1.1.7.dist-info}/WHEEL (100%) rename Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/{pyOpenRPA-1.1.6.dist-info => pyOpenRPA-1.1.7.dist-info}/top_level.txt (100%) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/METADATA index 961dce31..e165311a 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.6 +Version: 1.1.7 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.6.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/RECORD similarity index 98% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/RECORD index cb4be827..faa045d0 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/RECORD @@ -1,14 +1,14 @@ -pyOpenRPA-1.1.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.6.dist-info/METADATA,sha256=rwuV9eOeBt3pIq0mHtx_kopH7R27AwoO2vc3ht08rto,3541 -pyOpenRPA-1.1.6.dist-info/RECORD,, -pyOpenRPA-1.1.6.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.6.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.7.dist-info/METADATA,sha256=1-INEcLwD0cOjRbapwir23aemV9ibQZ4wV4TiXRPjic,3541 +pyOpenRPA-1.1.7.dist-info/RECORD,, +pyOpenRPA-1.1.7.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.7.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 pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0,408 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 -pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 +pyOpenRPA/.idea/workspace.xml,sha256=b6vLBJkXjoocb4ZXHCdzrfzL2o6PuG7x_3qJ14Va9-U,2754 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 pyOpenRPA/Orchestrator/Processor.py,sha256=ur0jDDteyBzfXR4DXnpUfBwNEW-M2nEtgyd-HQoPVtQ,11376 @@ -16,7 +16,7 @@ pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py,sha256=6otw1WnR2_evvQ5LGyOVh0BLk pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py,sha256=YB5HJL-Qf4IlVrFHyRv_ZMJ0Vo4vjyYqWKjvrTnf1k4,1564 pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=MkxTVaOVITl1V3EvH3oNx2gbCx3EeRS9Gb_83rmjdjg,25553 pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=PkJxD04pjniU2eaHY_v8UK9aXRYoc6mNLyN-vek89cc,9036 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=HcysWMmxMxSjaUybqovoCZToGrvzC0WFSVZbw6nfa68,9254 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 @@ -300,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=yokfvSsMRc8Ebg9aXbfXgfuYBKGBh8GrSbEpb5wjBgQ,174 +pyOpenRPA/__init__.py,sha256=m5yh4PYhwUL7CDaoIiQC7iIbXn8LQ2tjTyPUFQx6Ulo,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.6.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/top_level.txt 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 20cd033e..39e6d05e 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 @@ -11,28 +11,30 @@ gSettings = None # Gsettings will be initialized after the import module # Create new RDPSession in RobotRDPActive def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr): global gSettings - lRDPConfigurationItem = { # Init the configuration item - "Host": inHostStr, # Host address, example "77.77.22.22" - "Port": inPortStr, # RDP Port, example "3389" - "Login": inLoginStr, # Login, example "test" - "Password": inPasswordStr, # Password, example "test" - "Screen": { - "Width": 1680, # Width of the remote desktop in pixels, example 1680 - "Height": 1050, # Height of the remote desktop in pixels, example 1050 - # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example - "FlagUseAllMonitors": False, # True or False, example False - "DepthBit": "32" # "32" or "24" or "16" or "15", example "32" - }, - "SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"] - ###### Will updated in program ############ - "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example "" - "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False - "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 - } - gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem # Add item in RDPList - Connector.Session(lRDPConfigurationItem) # Create the RDP session - Connector.SystemRDPWarningClickOk() # Click all warning messages + # ATTENTION - dont connect if RDP session is exist + if inRDPSessionKeyStr not in gSettings["RobotRDPActive"]["RDPList"]: + lRDPConfigurationItem = { # Init the configuration item + "Host": inHostStr, # Host address, example "77.77.22.22" + "Port": inPortStr, # RDP Port, example "3389" + "Login": inLoginStr, # Login, example "test" + "Password": inPasswordStr, # Password, example "test" + "Screen": { + "Width": 1680, # Width of the remote desktop in pixels, example 1680 + "Height": 1050, # Height of the remote desktop in pixels, example 1050 + # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example + "FlagUseAllMonitors": False, # True or False, example False + "DepthBit": "32" # "32" or "24" or "16" or "15", example "32" + }, + "SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"] + ###### Will updated in program ############ + "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example "" + "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False + "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 + } + 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 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 9bc9cbe0..5f867ed2 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.6' +__version__ = 'v1.1.7' __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.6.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/INSTALLER rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/METADATA similarity index 99% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/METADATA index 961dce31..e165311a 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/METADATA +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.1.6 +Version: 1.1.7 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.6.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/RECORD similarity index 98% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/RECORD index cb4be827..faa045d0 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/RECORD +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/RECORD @@ -1,14 +1,14 @@ -pyOpenRPA-1.1.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.1.6.dist-info/METADATA,sha256=rwuV9eOeBt3pIq0mHtx_kopH7R27AwoO2vc3ht08rto,3541 -pyOpenRPA-1.1.6.dist-info/RECORD,, -pyOpenRPA-1.1.6.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.1.6.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.7.dist-info/METADATA,sha256=1-INEcLwD0cOjRbapwir23aemV9ibQZ4wV4TiXRPjic,3541 +pyOpenRPA-1.1.7.dist-info/RECORD,, +pyOpenRPA-1.1.7.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.7.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 pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0,408 pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191 -pyOpenRPA/.idea/workspace.xml,sha256=kcCP7x0iSOAWJdy7YtntGrgsQ04QIq0b6_9w04DKxfg,2555 +pyOpenRPA/.idea/workspace.xml,sha256=b6vLBJkXjoocb4ZXHCdzrfzL2o6PuG7x_3qJ14Va9-U,2754 pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iVp7DlLZHsURBOBegfDG4LanqSrI0A5a6GebP1cBOnI,8301 pyOpenRPA/Orchestrator/Processor.py,sha256=ur0jDDteyBzfXR4DXnpUfBwNEW-M2nEtgyd-HQoPVtQ,11376 @@ -16,7 +16,7 @@ pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py,sha256=6otw1WnR2_evvQ5LGyOVh0BLk pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py,sha256=YB5HJL-Qf4IlVrFHyRv_ZMJ0Vo4vjyYqWKjvrTnf1k4,1564 pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=MkxTVaOVITl1V3EvH3oNx2gbCx3EeRS9Gb_83rmjdjg,25553 pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657 -pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=PkJxD04pjniU2eaHY_v8UK9aXRYoc6mNLyN-vek89cc,9036 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=HcysWMmxMxSjaUybqovoCZToGrvzC0WFSVZbw6nfa68,9254 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 @@ -300,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=yokfvSsMRc8Ebg9aXbfXgfuYBKGBh8GrSbEpb5wjBgQ,174 +pyOpenRPA/__init__.py,sha256=m5yh4PYhwUL7CDaoIiQC7iIbXn8LQ2tjTyPUFQx6Ulo,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.6.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/WHEEL similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/WHEEL rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/WHEEL diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/top_level.txt similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.6.dist-info/top_level.txt rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.1.7.dist-info/top_level.txt 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 20cd033e..39e6d05e 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 @@ -11,28 +11,30 @@ gSettings = None # Gsettings will be initialized after the import module # Create new RDPSession in RobotRDPActive def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr): global gSettings - lRDPConfigurationItem = { # Init the configuration item - "Host": inHostStr, # Host address, example "77.77.22.22" - "Port": inPortStr, # RDP Port, example "3389" - "Login": inLoginStr, # Login, example "test" - "Password": inPasswordStr, # Password, example "test" - "Screen": { - "Width": 1680, # Width of the remote desktop in pixels, example 1680 - "Height": 1050, # Height of the remote desktop in pixels, example 1050 - # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example - "FlagUseAllMonitors": False, # True or False, example False - "DepthBit": "32" # "32" or "24" or "16" or "15", example "32" - }, - "SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"] - ###### Will updated in program ############ - "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example "" - "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False - "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 - } - gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem # Add item in RDPList - Connector.Session(lRDPConfigurationItem) # Create the RDP session - Connector.SystemRDPWarningClickOk() # Click all warning messages + # ATTENTION - dont connect if RDP session is exist + if inRDPSessionKeyStr not in gSettings["RobotRDPActive"]["RDPList"]: + lRDPConfigurationItem = { # Init the configuration item + "Host": inHostStr, # Host address, example "77.77.22.22" + "Port": inPortStr, # RDP Port, example "3389" + "Login": inLoginStr, # Login, example "test" + "Password": inPasswordStr, # Password, example "test" + "Screen": { + "Width": 1680, # Width of the remote desktop in pixels, example 1680 + "Height": 1050, # Height of the remote desktop in pixels, example 1050 + # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example + "FlagUseAllMonitors": False, # True or False, example False + "DepthBit": "32" # "32" or "24" or "16" or "15", example "32" + }, + "SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"] + ###### Will updated in program ############ + "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example "" + "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False + "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 + } + 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 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 9bc9cbe0..5f867ed2 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.6' +__version__ = 'v1.1.7' __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 9bc9cbe0..5f867ed2 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The OpenRPA package (from UnicodeLabs) """ -__version__ = 'v1.1.6' +__version__ = 'v1.1.7' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file From 4c8d0e3187164d008c02e6f3e21c66199c0bfbc8 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Wed, 10 Jun 2020 19:21:07 +0300 Subject: [PATCH 11/19] v1.1.8 UIDesktop minor bugfix from pywinauto with ctype.ArgumentError Add Orchestrator UserRole model, Add Web render with user roles --- .../Settings/SettingsOrchestratorExample.py | 15 +- Orchestrator/Template_Settings_AccessUser.py | 16 ++ Sources/pyOpenRPA/Orchestrator/Server.py | 56 ++++++- .../pyOpenRPA/Orchestrator/ServerSettings.py | 13 +- .../pyOpenRPA/Orchestrator/Web/Index.xhtml | 151 ++++-------------- Sources/pyOpenRPA/Robot/UIDesktop.py | 20 ++- 6 files changed, 146 insertions(+), 125 deletions(-) diff --git a/Orchestrator/Settings/SettingsOrchestratorExample.py b/Orchestrator/Settings/SettingsOrchestratorExample.py index f023aebc..97552b72 100644 --- a/Orchestrator/Settings/SettingsOrchestratorExample.py +++ b/Orchestrator/Settings/SettingsOrchestratorExample.py @@ -101,8 +101,19 @@ def Settings(): # "FlagAccess": True # } # ], - # "ControlPanelKeyAllowedList":[] # If empty - all is allowed - #} + # "ControlPanelKeyAllowedList":[], # If empty - all is allowed + # "RoleHierarchyAllowedDict": { + # "Orchestrator":{ + # "Controls": { + # "RestartOrchestrator": {}, # Feature to restart orchestrator on virtual machine + # "LookMachineScreenshots": {} # Feature to look machina screenshots + # }, + # "RDPActive": { # Robot RDP active module + # "ListRead": {} # Access to read RDP session list + # } + # } + # } + # } }, "RuleMethodMatchURLBeforeList": [ #General MethodMatchURL list (no domain/user) # { diff --git a/Orchestrator/Template_Settings_AccessUser.py b/Orchestrator/Template_Settings_AccessUser.py index 1b7febbd..62644543 100644 --- a/Orchestrator/Template_Settings_AccessUser.py +++ b/Orchestrator/Template_Settings_AccessUser.py @@ -1,3 +1,19 @@ +# Role model - if len of keys in dict is 0 - all access. If at least len is 1 - only this access +# "Orchestrator":{ +# "Controls": { +# "RestartOrchestrator": {}, # Feature to restart orchestrator on virtual machine +# "LookMachineScreenshots": {} # Feature to look machina screenshots +# }, +# "RDPActive": { # Robot RDP active module +# "ListRead": {} # Access to read RDP session list +# } +# } +# } +# USAGE in .py +# inRequest. +# inRequest.OpenRPA["DefUserRoleAccessAsk"](["Orchestrator","RDPActive","Controls"]) - return True or False +# inRequest.OpenRPA["DefUserRoleHierarchyGet"]() - Return dict of the role hierarchy or {} + # Init Section gUserNameStr = "Login" # User name without domain name gDomainNameStr = "" # DOMAIN or EMPTY str if no domain diff --git a/Sources/pyOpenRPA/Orchestrator/Server.py b/Sources/pyOpenRPA/Orchestrator/Server.py index be70002d..08d6b2cc 100644 --- a/Sources/pyOpenRPA/Orchestrator/Server.py +++ b/Sources/pyOpenRPA/Orchestrator/Server.py @@ -22,6 +22,8 @@ from http import cookies global gSettingsDict from . import ServerSettings import copy + + #Authenticate function () # return dict # { @@ -33,10 +35,6 @@ def AuthenticateVerify(inRequest): ###################################### #Way 1 - try to find AuthToken lCookies = cookies.SimpleCookie(inRequest.headers.get("Cookie", "")) - inRequest.OpenRPA = {} - inRequest.OpenRPA["AuthToken"] = None - inRequest.OpenRPA["Domain"] = None - inRequest.OpenRPA["User"] = None #pdb.set_trace() if "AuthToken" in lCookies: lCookieAuthToken = lCookies.get("AuthToken", "").value @@ -193,6 +191,34 @@ def UserAccessCheckBefore(inMethod, inRequest): return lResult # HTTPRequestHandler class class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): + # Def to check User Role access grants + def UserRoleAccessAsk(self, inRoleKeyList): + lResult = True # Init flag + lRoleHierarchyDict = self.UserRoleHierarchyGet() # get the Hierarchy + # Try to get value from key list + lKeyValue = lRoleHierarchyDict # Init the base + for lItem in inRoleKeyList: + if type(lKeyValue) is dict: + if lItem in lKeyValue: # Has key + lKeyValue = lKeyValue[lItem] # Get the value and go to the next loop iteration + else: # Else branch - true or false + if len(lKeyValue)>0: # False - if Dict has some elements + lResult = False # Set the False Flag + else: + lResult = True # Set the True flag + break # Stop the loop + else: # Has element with no detalization - return True + lResult = True # Set the flag + break # Close the loop + return lResult # Return the result + + # Def to get hierarchy of the current user roles + # if return {} - all is available + def UserRoleHierarchyGet(self): + lDomainUpperStr = self.OpenRPA["Domain"].upper() + lUserUpperStr = self.OpenRPA["User"].upper() + return gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("RuleDomainUserDict", {}).get((lDomainUpperStr, lUserUpperStr), {}).get("RoleHierarchyAllowedDict", {}) + #Tech def #return {"headers":[],"body":"","statuscode":111} def URLItemCheckDo(self, inURLItem, inMethod): @@ -287,6 +313,12 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): # Write content as utf-8 data self.wfile.write(inResponseDict["Body"]) def do_GET(self): + self.OpenRPA = {} + self.OpenRPA["AuthToken"] = None + self.OpenRPA["Domain"] = None + self.OpenRPA["User"] = None + self.OpenRPA["DefUserRoleAccessAsk"]=self.UserRoleAccessAsk # Alias for def + self.OpenRPA["DefUserRoleHierarchyGet"]=self.UserRoleHierarchyGet # Alias for def # Prepare result dict lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": b"", "StatusCode": None} self.OpenRPAResponseDict = lResponseDict @@ -350,6 +382,13 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): self.end_headers() # POST def do_POST(self): + lL = gSettingsDict["Logger"] + self.OpenRPA = {} + self.OpenRPA["AuthToken"] = None + self.OpenRPA["Domain"] = None + self.OpenRPA["User"] = None + self.OpenRPA["DefUserRoleAccessAsk"]=self.UserRoleAccessAsk # Alias for def + self.OpenRPA["DefUserRoleHierarchyGet"]=self.UserRoleHierarchyGet # Alias for def # Prepare result dict #pdb.set_trace() lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": b"", "StatusCode": None} @@ -360,8 +399,14 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): ##################################### lFlagAccessUserBlock=False lAuthenticateDict = {"Domain": "", "User": ""} + lIsSuperToken = False # Is supertoken if gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): lAuthenticateDict = AuthenticateVerify(self) + # Get Flag is supertoken (True|False) + lDomainUpperStr = self.OpenRPA["Domain"].upper() + lUserUpperStr = self.OpenRPA["User"].upper() + lIsSuperToken = gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("AuthTokensDict", {}).get( + (lDomainUpperStr, lUserUpperStr), {}).get("FlagDoNotExpire", False) if not lAuthenticateDict["User"]: lFlagAccessUserBlock=True if lFlagAccessUserBlock: @@ -401,6 +446,9 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): # Send headers self.send_header('Content-type','application/json') self.end_headers() + # Logging info about processor activity if not SuperToken () + if not lIsSuperToken: + if lL: lL.info(f"Server:: User activity from web. Domain: {self.OpenRPA['Domain']}, Username: {self.OpenRPA['User']}, Activity: {lInputObject}") # Send message back to client message = json.dumps(Processor.ActivityListOrDict(lInputObject)) # Write content as utf-8 data diff --git a/Sources/pyOpenRPA/Orchestrator/ServerSettings.py b/Sources/pyOpenRPA/Orchestrator/ServerSettings.py index e30e1c30..464f7eaa 100644 --- a/Sources/pyOpenRPA/Orchestrator/ServerSettings.py +++ b/Sources/pyOpenRPA/Orchestrator/ServerSettings.py @@ -47,6 +47,16 @@ def Monitor_ControlPanelDictGet(inRequest,inGlobalDict): # Write content as utf-8 data inResponseDict["Body"] = bytes(message, "utf8") +# UserAccess get rights hierarchy dict in json +def UserRoleHierarchyGet(inRequest,inGlobalDict): + inResponseDict = inRequest.OpenRPAResponseDict + # Create result JSON + lResultDict = inRequest.OpenRPA["DefUserRoleHierarchyGet"]() # Get the User Role Hierarchy list + # Send message back to client + message = json.dumps(lResultDict) + # Write content as utf-8 data + inResponseDict["Body"] = bytes(message, "utf8") + def GetScreenshot(inRequest,inGlobalDict): # Get Screenshot def SaveScreenshot(inFilePath): @@ -90,7 +100,8 @@ def SettingsUpdate(inGlobalConfiguration): {"Method":"GET", "URL": "/3rdParty/Handlebars/handlebars-v4.1.2.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Handlebars\\handlebars-v4.1.2.js"), "ResponseContentType": "application/javascript"}, {"Method": "GET", "URL": "/Monitor/ControlPanelDictGet", "MatchType": "Equal", "ResponseDefRequestGlobal": Monitor_ControlPanelDictGet, "ResponseContentType": "application/json"}, {"Method": "GET", "URL": "/GetScreenshot", "MatchType": "BeginWith", "ResponseDefRequestGlobal": GetScreenshot, "ResponseContentType": "image/png"}, - {"Method": "GET", "URL": "/Orchestrator/RobotRDPActive/ControlPanelDictGet", "MatchType": "Equal","ResponseDefRequestGlobal": RobotRDPActive_ControlPanelDictGet, "ResponseContentType": "application/json"} + {"Method": "GET", "URL": "/Orchestrator/RobotRDPActive/ControlPanelDictGet", "MatchType": "Equal","ResponseDefRequestGlobal": RobotRDPActive_ControlPanelDictGet, "ResponseContentType": "application/json"}, + {"Method": "POST", "URL": "/Orchestrator/UserRoleHierarchyGet", "MatchType": "Equal","ResponseDefRequestGlobal": UserRoleHierarchyGet, "ResponseContentType": "application/json"} ] inGlobalConfiguration["Server"]["URLList"]=inGlobalConfiguration["Server"]["URLList"]+lURLList return inGlobalConfiguration \ No newline at end of file diff --git a/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml b/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml index e64da833..48292227 100644 --- a/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml +++ b/Sources/pyOpenRPA/Orchestrator/Web/Index.xhtml @@ -388,37 +388,6 @@ dataType: "text" }); } - - /////////////////////////////// - ///Scheduler functions - /////////////////////////////// - - mGlobal.Scheduler = {} - mGlobal.Scheduler.ActivityTimeListShow = function() { - lData = [ - { - "Type":"GlobalDictKeyListValueGet", - "KeyList":["Scheduler","ActivityTimeList"] - } - ] - $.ajax({ - type: "POST", - url: 'Utils/Processor', - data: JSON.stringify(lData), - success: - function(lData,l2,l3) - { - var lResponseJSON=JSON.parse(lData) - lResponseJSON[0]["Result"].forEach(function(lItem){lItem["processPathName"]=("processPath" in lItem ? lItem["processPath"] : lItem["processName"])}) - ///Отправить запрос на формирование таблицы - lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-info-table-planloglist",lResponseJSON[0]); - ///Установить HTML код - $('.ui.modal.basic .content').html(lHTMLCode); - $('.ui.modal.basic').modal('show'); - }, - dataType: "text" - }); - } /////////////////////////////// ///Processor functions /////////////////////////////// @@ -507,32 +476,6 @@ dataType: "text" }); } - mGlobal.Processor.LogListShow = function() { - lData = [ - { - "Type":"GlobalDictKeyListValueGet", - "KeyList":["Processor","LogList"] - } - ] - ///Обнулить таблицу - $('.ui.modal.basic .content').html(""); - $.ajax({ - type: "POST", - url: 'Utils/Processor', - data: JSON.stringify(lData), - success: - function(lData,l2,l3) - { - var lResponseJSON=JSON.parse(lData) - ///Отправить запрос на формирование таблицы - lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-info-table-activitylogschedulelist",lResponseJSON["actionListResult"][0]) - ///Установить HTML код - $('.ui.modal.basic .content').html(lHTMLCode); - $('.ui.modal.basic').modal('show'); - }, - dataType: "text" - }); - } mGlobal.Server= {} mGlobal.Server.JSONGet=function(inMethod, inURL, inDataJSON, inCallback) { @@ -661,6 +604,37 @@ ///Установить HTML код lElementParentElement.insertAdjacentHTML("beforeend",lHTMLCode); } + // Check user roles and update the Orchestrator UI + mGlobal.UserRoleUpdate=function() { + $.ajax({ + type: "POST", + url: 'Orchestrator/UserRoleHierarchyGet', + data: "", + success: + function(lData,l2,l3) + { + var lResponseDict=JSON.parse(lData) + //Turn on the Lookmachine screenshot button + var lDict = ((lResponseDict["Orchestrator"] || {})["Controls"] || {}) // Get the Controls dict + if ("LookMachineScreenshots" in lDict || Object.keys(lDict).length == 0) { + $(".openrpa-control-lookmachinescreenshot").show() //Show button + } + //Turn on the restart orchestrator button + var lDict = ((lResponseDict["Orchestrator"] || {})["Controls"] || {}) // Get the Controls dict + if ("RestartOrchestrator" in lDict || Object.keys(lDict).length == 0) { + $(".openrpa-control-restartorchestrator").show() //Show button + } + //Turn on the rdp session list + var lDict = ((lResponseDict["Orchestrator"] || {})["RDPActive"] || {}) // Get the Controls dict + if ("ListRead" in lDict || Object.keys(lDict).length == 0) { + $(".openrpa-rdpactive-title").show() //Show section + $(".openrpa-robotrdpactive-control-panel-general").show() //Show section + } + }, + dataType: "text" + }); + } + mGlobal.UserRoleUpdate() // Cal the update User Roles function }) ; @@ -781,75 +755,20 @@

...

-

Robot RDP active list

+
- - - - @@ -781,75 +755,20 @@

...

-

Robot RDP active list

+
- - - - @@ -781,75 +755,20 @@

...

-

Robot RDP active list

+
- - - -