Last active
September 29, 2022 03:21
-
-
Save iydon/12e0a0f47b12391d2275b8be51a983a1 to your computer and use it in GitHub Desktop.
A recorder for keyboard and mouse events.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fire | |
import time | |
class Recorder: | |
'''A recorder for keyboard and mouse events. | |
''' | |
def __init__(self, log_name='record.log', keyboard=True, mouse=True, speed=1): | |
self._log_name = log_name | |
self._keyboard = keyboard | |
self._mouse = mouse | |
self._speed = float(speed) | |
# record | |
self._last_time = time.time() | |
self._last_position = [0, 0] | |
def record(self): | |
'''Record keyboard and mouse events. | |
''' | |
# import | |
from pynput import keyboard, mouse | |
# body | |
print('hello~') | |
with open(self._log_name, 'w') as f: | |
f.write(f'{self._last_time}\n') | |
# on-function | |
def on_press(key): | |
f.write(f'{self._dt()}\tkeyboard.press({key})\n') | |
def on_release(key): | |
f.write(f'{self._dt()}\tkeyboard.release({key})\n') | |
def on_move(x, y): | |
f.write(f'{self._dt()}\tmouse.move{self._ds(x, y)}\n') | |
def on_click(x, y , button, pressed): | |
f.write(f'{self._dt()}\tmouse.position = {x}, {y} ; ') | |
f.write(f'mouse.{"press" if pressed else "release"}({button})\n') | |
def on_scroll(x, y ,dx, dy): | |
f.write(f'{self._dt()}\tmouse.position = {x}, {y} ; ') | |
f.write(f'mouse.scroll({dx}, {dy})\n') | |
# listen events | |
keyboard_kwargs = dict(on_press=on_press, on_release=on_release) | |
mouse_kwargs = dict(on_move=on_move, on_click=on_click, on_scroll=on_scroll) | |
while True: | |
if self._keyboard and self._mouse: | |
with keyboard.Listener(**keyboard_kwargs) as keyboard_listener, \ | |
mouse.Listener(**mouse_kwargs) as mouse_listener: | |
keyboard_listener.join() | |
mouse_listener.join() | |
elif self._keyboard and not self._mouse: | |
with keyboard.Listener(**keyboard_kwargs) as keyboard_listener: | |
keyboard_listener.join() | |
elif not self._keyboard and self._mouse: | |
with mouse.Listener(**mouse_kwargs) as mouse_listener: | |
mouse_listener.join() | |
else: | |
break | |
def review(self): | |
'''Review keyboard and mouse events. | |
''' | |
# import | |
from pynput.keyboard import Key, Controller as KC | |
from pynput.mouse import Button, Controller as MC | |
# body | |
keyboard = KC() | |
mouse = MC() | |
with open(self._log_name, 'r') as f: | |
timestamp, *commands = [line.split('\t') for line in f.readlines()] | |
localtime = time.localtime(float(timestamp[0])) | |
print(time.strftime('%Y-%m-%d %H:%M:%S', localtime)) | |
for dt, command in commands: | |
time.sleep(float(dt)/self._speed) | |
exec(command) | |
def interact(self, colors='Linux', **kwargs): | |
'''Interact with Record class and debug. | |
''' | |
import IPython | |
IPython.embed(colors=colors, **kwargs) | |
def _dt(self): | |
t = time.time() | |
dt = t - self._last_time | |
self._last_time = t | |
return dt * self._speed | |
def _ds(self, x, y): | |
_x, _y = self._last_position | |
dx, dy = x-_x, y-_y | |
self._last_position = [x, y] | |
return dx, dy | |
if __name__ == '__main__': | |
try: | |
fire.Fire(Recorder) | |
except KeyboardInterrupt: | |
print('\nBye~') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment