Skip to content

Commit 0aae373

Browse files
committed
initial commit
0 parents  commit 0aae373

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

README.md

Whitespace-only changes.

ahk/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from ahk.autohotkey import AHK
2+
__all__ = ['AHK']

ahk/autohotkey.py

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from tempfile import NamedTemporaryFile
2+
import os
3+
import ast
4+
import subprocess
5+
import shutil
6+
from textwrap import dedent
7+
import time
8+
from contextlib import suppress
9+
import logging
10+
11+
class AHK(object):
12+
def __init__(self, executable_path: str='', keep_scripts: bool=False):
13+
"""
14+
15+
:param executable_path: the path to the AHK executable. Defaults to environ['AHK_PATH'] otherwise tries 'AutoHotkeyA32.exe'
16+
:param keep_scripts:
17+
:raises RuntimeError: if AHK executable is not provided and cannot be found in environment variables or PATH
18+
"""
19+
self.speed = 2
20+
self.keep_scripts = bool(keep_scripts)
21+
executable_path = executable_path or os.environ.get('AHK_PATH') or shutil.which('AutoHotkey.exe') or shutil.which('AutoHotkeyA32.exe')
22+
self.executable_path = executable_path
23+
24+
def _run_script(self, script_path, **kwargs):
25+
result = subprocess.run([self.executable_path, script_path], stdin=None, stderr=None, stdout=subprocess.PIPE, **kwargs)
26+
return result.stdout.decode()
27+
28+
def run_script(self, script_text:str, delete=None, blocking=True, **runkwargs):
29+
if blocking is False:
30+
script_text = script_text.lstrip('#Persistent')
31+
if delete is None:
32+
delete = not self.keep_scripts
33+
try:
34+
with NamedTemporaryFile(mode='w', delete=False) as temp_script:
35+
temp_script.write(script_text)
36+
result = self._run_script(temp_script.name)
37+
except Exception as e:
38+
logging.critical('Something went terribly wrong: %s', e)
39+
result = None
40+
finally:
41+
if delete:
42+
with suppress(OSError):
43+
os.remove(temp_script.name)
44+
return result
45+
46+
def _mouse_position(self):
47+
return dedent('''
48+
#Persistent
49+
MouseGetPos, xpos, ypos
50+
s .= Format("({}, {})", xpos, ypos)
51+
FileAppend, %s%, *
52+
ExitApp
53+
''')
54+
55+
@property
56+
def mouse_position(self):
57+
response = self.run_script(self._mouse_position())
58+
return ast.literal_eval(response)
59+
60+
@mouse_position.setter
61+
def mouse_position(self, position):
62+
x, y = position
63+
self.move_mouse(x=x, y=y, speed=0, relative=False)
64+
65+
def _move_mouse(self, x=None, y=None, speed=None, relative=False):
66+
if x is None and y is None:
67+
raise ValueError('Position argument(s) missing. Must provide x and/or y coordinates')
68+
if speed is None:
69+
speed = self.speed
70+
if relative and (x is None or y is None):
71+
x = x or 0
72+
y = y or 0
73+
elif not relative and (x is None or y is None):
74+
posx, posy = self.mouse_position
75+
x = x or posx
76+
y = y or posy
77+
78+
if relative:
79+
relative = ', R'
80+
else:
81+
relative = ''
82+
script = dedent(f'''\
83+
#Persistent
84+
MouseMove, {x}, {y} , {speed}{relative}
85+
ExitApp
86+
''')
87+
return script
88+
89+
def move_mouse(self, *args, **kwargs):
90+
script = self._move_mouse(*args, **kwargs)
91+
response = self.run_script(script_text=script)
92+
return response or None

setup.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from setuptools import setup
2+
3+
4+
setup(
5+
name='ahk',
6+
version='0.0.1',
7+
url='https://github.com/spyoungtech/ahk',
8+
description='A (POC) Python wrapper for AHK',
9+
author_email='[email protected]',
10+
author='Spencer Young',
11+
packages=['ahk']
12+
)

0 commit comments

Comments
 (0)