Skip to content

Commit

Permalink
nonblocking interface (#4)
Browse files Browse the repository at this point in the history
* nonblocking interface
  • Loading branch information
spyoungtech authored Dec 12, 2018
1 parent 550dae7 commit 9d049a3
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 16 deletions.
41 changes: 38 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

A Python wrapper around AHK.

# Installation

```
pip install ahk
```


# Usage

```python
Expand All @@ -11,11 +18,39 @@ ahk.mouse_move(x=100, y=100, speed=10) # blocks until mouse finishes moving
print(ahk.mouse_position) # (100, 100)
```

# Installation
![ahk](https://raw.githubusercontent.com/spyoungtech/ahk/master/docs/_static/ahk.gif)

## non-blocking modes

You can also opt for a non-blocking interface, so you can do other stuff while AHK scripts run.

```python
import time
from ahk import AHK
ahk = AHK()
ahk.mouse_position = (200, 200) # moves the mouse instantly to the position
start = time.time()
ahk.mouse_move(x=100, y=100, speed=30, blocking=False)
while True: # report mouse position while it moves
t = round(time.time() - start, 4)
position = ahk.mouse_position
print(t, position)
if position == (100, 100):
break
```
pip install ahk

You should see an output something like

```
0.032 (187, 187)
0.094 (173, 173)
0.137 (164, 164)
...
0.788 (100, 103)
0.831 (100, 101)
0.873 (100, 100)
```


## Dependencies

Expand All @@ -36,4 +71,4 @@ Right now this is just an exploration of an idea. It may not even be a particula

There's still a bit to be done in the way of implementation.

The vision is to provide additional interfaces that implement the most important parts of the AHK API in a Pythonic way.
The vision is to provide additional interfaces that implement the most important parts of the AHK API in a Pythonic way.
7 changes: 4 additions & 3 deletions ahk/mouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def mouse_position(self, position):
x, y = position
self.mouse_move(x=x, y=y, speed=0, relative=False)

def _mouse_move(self, x=None, y=None, speed=None, relative=False, mode=None):
def _mouse_move(self, x=None, y=None, speed=None, relative=False, mode=None, persistent=True, blocking=True):
if x is None and y is None:
raise ValueError('Position argument(s) missing. Must provide x and/or y coordinates')
if speed is None:
Expand All @@ -61,9 +61,10 @@ def _mouse_move(self, x=None, y=None, speed=None, relative=False, mode=None):
script = make_script(f'''
CoordMode Mouse, {mode}
MouseMove, {x}, {y} , {speed}{relative}
''')
''', persistent=persistent, blocking=blocking)
return script

def mouse_move(self, *args, **kwargs):
blocking = kwargs.get('blocking')
script = self._mouse_move(*args, **kwargs)
self.run_script(script_text=script)
self.run_script(script, blocking=blocking)
16 changes: 11 additions & 5 deletions ahk/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from contextlib import suppress
from shutil import which
from ahk.utils import logger

import time

class ScriptEngine(object):
def __init__(self, executable_path: str='', keep_scripts: bool=False, **kwargs):
Expand All @@ -21,13 +21,19 @@ def __init__(self, executable_path: str='', keep_scripts: bool=False, **kwargs):
self.executable_path = executable_path

def _run_script(self, script_path, **kwargs):
blocking = kwargs.pop('blocking', True)
runargs = [self.executable_path, script_path]
decode = kwargs.pop('decode', False)
result = subprocess.run(runargs, stdin=None, stderr=None, stdout=subprocess.PIPE, **kwargs)
if decode:
return result.stdout.decode()
if blocking:
result = subprocess.run(runargs, stdin=None, stderr=None, stdout=subprocess.PIPE, **kwargs)
if decode:
return result.stdout.decode()
else:
return result.stdout
else:
return result.stdout
p = subprocess.Popen(runargs, stdout=subprocess.PIPE, **kwargs)
p.stdout.readline() # give script a chance to read the script or else we'll delete it too quick
return p

def run_script(self, script_text: str, delete=None, decode=True, **runkwargs):
if delete is None:
Expand Down
4 changes: 3 additions & 1 deletion ahk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
logger.setLevel(logging.ERROR)


def make_script(body, directives=None, persistent=True):
def make_script(body, directives=None, persistent=True, blocking=True):
"""
Convenience function to dedent script body as well as add #Persistent directive and Exit/ExitApp
:param body: body of the script
Expand All @@ -39,4 +39,6 @@ def make_script(body, directives=None, persistent=True):
{body}
{exit_}
''')
if not blocking:
script = 'FileAppend, "`r`n", *\n' + script
return script
6 changes: 3 additions & 3 deletions ahk/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ def _all_window_titles(self):
WinGet windows, List
Loop %windows%
{
id := windows%A_Index%
WinGetTitle wt, ahk_id %id%
r .= wt . "`n"
id := windows%A_Index%
WinGetTitle wt, ahk_id %id%
r .= wt . "`n"
}
FileAppend, %r%, *
''')
Expand Down
Binary file added docs/_static/ahk.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name='ahk',
version='0.1.1',
version='0.2.0',
url='/~https://github.com/spyoungtech/ahk',
description='A Python wrapper for AHK',
author_email='spencer.young@spyoung.com',
Expand Down

0 comments on commit 9d049a3

Please sign in to comment.