Skip to content

Commit

Permalink
Merge pull request #6 from quillcraftsman/replayer
Browse files Browse the repository at this point in the history
Replayer
  • Loading branch information
quillcraftsman committed Mar 1, 2024
2 parents d85dccb + 04c4bb8 commit 7045530
Show file tree
Hide file tree
Showing 20 changed files with 327 additions and 28 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,14 @@ See more in [Full Documentation](https://replaywizard.craftsman.lol/install.html
## Quickstart

```python
from replay_wizard.capturing import capture
capture('one')
import time
from quickstart.capturing import capture_actions
from quickstart.replay import replay_actions

if __name__ == '__main__':
capture_actions()
time.sleep(5)
replay_actions()
```

### More examples in [Full Documentation][documentation_path]
Expand Down Expand Up @@ -125,9 +131,9 @@ This features will be built during 4 weeks.
- Capture mouse actions
- Save mouse actions
- Replay mouse actions
- Capture keyboards actions
- Save keyboards actions
- Replay keyboards actions
- Capture keyboards actions (Done)
- Save keyboards actions (Done)
- Replay keyboards actions (Done)
- Capture environment
- Save environment
- Replay environment
Expand Down
37 changes: 37 additions & 0 deletions docs/package/replay_wizard.capturing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
replay\_wizard.capturing package
================================

Submodules
----------

replay\_wizard.capturing.capture module
---------------------------------------

.. automodule:: replay_wizard.capturing.capture
:members:
:undoc-members:
:show-inheritance:

replay\_wizard.capturing.errors module
--------------------------------------

.. automodule:: replay_wizard.capturing.errors
:members:
:undoc-members:
:show-inheritance:

replay\_wizard.capturing.keyboard module
----------------------------------------

.. automodule:: replay_wizard.capturing.keyboard
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

.. automodule:: replay_wizard.capturing
:members:
:undoc-members:
:show-inheritance:
29 changes: 29 additions & 0 deletions docs/package/replay_wizard.models.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
replay\_wizard.models package
=============================

Submodules
----------

replay\_wizard.models.action module
-----------------------------------

.. automodule:: replay_wizard.models.action
:members:
:undoc-members:
:show-inheritance:

replay\_wizard.models.sequence module
-------------------------------------

.. automodule:: replay_wizard.models.sequence
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

.. automodule:: replay_wizard.models
:members:
:undoc-members:
:show-inheritance:
14 changes: 12 additions & 2 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
Quickstart
----------

.. literalinclude:: ../quickstart/main.py
:pyobject: main
To capture actions
==================

.. literalinclude:: ../quickstart/capturing.py
:pyobject: capture_actions

To replay actions
=================

.. literalinclude:: ../quickstart/replay.py
:pyobject: replay_actions

8 changes: 6 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"""
Manual run module
"""
from quickstart.main import main
import time
from quickstart.capturing import capture_actions
from quickstart.replay import replay_actions

if __name__ == '__main__':
main()
capture_actions()
time.sleep(5)
replay_actions()
2 changes: 1 addition & 1 deletion quickstart/main.py → quickstart/capturing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""


def main():
def capture_actions():
"""
ReplayWizard simple usage
:return:
Expand Down
13 changes: 13 additions & 0 deletions quickstart/replay.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""
Quickstart examples
"""


def replay_actions():
"""
ReplayWizard simple usage
:return:
"""
from replay_wizard.replay import replay # pylint: disable=import-outside-toplevel

replay('one')
3 changes: 3 additions & 0 deletions replay_wizard/models/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class Sequence(BaseModel):
def __len__(self):
return len(self.actions)

def __iter__(self):
return iter(self.actions)

def add(self, new_action: Action):
"""
Add action to sequence
Expand Down
4 changes: 2 additions & 2 deletions replay_wizard/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
Package info
"""
name = 'replay-wizard'
version = '0.0.2'
status = '2 - Pre-Alpha'
version = '0.1.0'
status = '3 - Alpha'
4 changes: 4 additions & 0 deletions replay_wizard/replay/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
Replay package
"""
from .core import replay
37 changes: 37 additions & 0 deletions replay_wizard/replay/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
Replay core module
"""
import json
from replay_wizard.models import Sequence, Action
from .keyboard import push_button


def replay(name, extension='sequence'):
"""
Replay sequence from file
:param name: sequence name, without extension
:param extension: sequence file extension
"""
filename = f'{name}.{extension}'
with open(filename, 'r', encoding='utf-8') as f:
sequence_dict = json.load(f)
sequence = Sequence.model_validate(sequence_dict)
replay_sequence(sequence)


def replay_action(action: Action):
"""
Replay one Action
"""
push_button(action)


def replay_sequence(sequence: Sequence):
"""
Replay sequence
:param sequence: sequence to replay
"""
for action in sequence:
replay_action(action)
21 changes: 21 additions & 0 deletions replay_wizard/replay/keyboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Keyboard replay functions
"""
import pynput
from pynput.keyboard import Key
from replay_wizard.models import Action


def push_button(action: Action):
"""
Push keyboard button
"""
value = action.value
action_type = action.action
try:
value = Key[value]
except KeyError:
pass
keyboard = pynput.keyboard.Controller()
push_function = getattr(keyboard, action_type)
push_function(value)
1 change: 1 addition & 0 deletions sequence.testdata
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "one", "actions": [{"subtype": "keyboard", "value": "m", "action": "press"}, {"subtype": "keyboard", "value": "m", "action": "release"}, {"subtype": "keyboard", "value": "o", "action": "press"}, {"subtype": "keyboard", "value": "o", "action": "release"}, {"subtype": "keyboard", "value": "u", "action": "press"}, {"subtype": "keyboard", "value": "u", "action": "release"}, {"subtype": "keyboard", "value": "r", "action": "press"}, {"subtype": "keyboard", "value": "r", "action": "release"}, {"subtype": "keyboard", "value": "backspace", "action": "press"}, {"subtype": "keyboard", "value": "backspace", "action": "release"}, {"subtype": "keyboard", "value": "s", "action": "press"}, {"subtype": "keyboard", "value": "s", "action": "release"}, {"subtype": "keyboard", "value": "t", "action": "press"}, {"subtype": "keyboard", "value": "h", "action": "press"}, {"subtype": "keyboard", "value": "t", "action": "release"}, {"subtype": "keyboard", "value": "h", "action": "release"}, {"subtype": "keyboard", "value": "i", "action": "press"}, {"subtype": "keyboard", "value": "i", "action": "release"}, {"subtype": "keyboard", "value": "s", "action": "press"}, {"subtype": "keyboard", "value": "space", "action": "press"}, {"subtype": "keyboard", "value": "s", "action": "release"}, {"subtype": "keyboard", "value": "space", "action": "release"}, {"subtype": "keyboard", "value": "i", "action": "press"}, {"subtype": "keyboard", "value": "i", "action": "release"}, {"subtype": "keyboard", "value": "s", "action": "press"}, {"subtype": "keyboard", "value": "space", "action": "press"}, {"subtype": "keyboard", "value": "s", "action": "release"}, {"subtype": "keyboard", "value": "space", "action": "release"}, {"subtype": "keyboard", "value": "t", "action": "press"}, {"subtype": "keyboard", "value": "t", "action": "release"}, {"subtype": "keyboard", "value": "backspace", "action": "press"}, {"subtype": "keyboard", "value": "backspace", "action": "release"}, {"subtype": "keyboard", "value": "r", "action": "press"}, {"subtype": "keyboard", "value": "r", "action": "release"}, {"subtype": "keyboard", "value": "e", "action": "press"}, {"subtype": "keyboard", "value": "e", "action": "release"}, {"subtype": "keyboard", "value": "p", "action": "press"}, {"subtype": "keyboard", "value": "p", "action": "release"}, {"subtype": "keyboard", "value": "l", "action": "press"}, {"subtype": "keyboard", "value": "l", "action": "release"}, {"subtype": "keyboard", "value": "a", "action": "press"}, {"subtype": "keyboard", "value": "a", "action": "release"}, {"subtype": "keyboard", "value": "y", "action": "press"}, {"subtype": "keyboard", "value": "y", "action": "release"}, {"subtype": "keyboard", "value": "enter", "action": "press"}, {"subtype": "keyboard", "value": "enter", "action": "release"}]}
43 changes: 40 additions & 3 deletions testing/test_replay_wizard/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,37 @@
"""
Pytest fixtures
"""
import pytest
from replay_wizard.models import Sequence
from pytest import fixture
from replay_wizard.models import Action, Subtypes, Sequence, ActionEnum

@pytest.fixture

@fixture
def put_a_action():
"""
Simple action fixture
"""
return Action(
subtype=Subtypes.KEYBOARD,
value='a',
timedelta=0.1,
)


@fixture
def put_enter_action():
"""
Simple action fixture
"""
action = Action(
subtype=Subtypes.KEYBOARD,
value='enter',
timedelta=0.1,
action=ActionEnum.RELEASE
)
return action


@fixture
def empty_sequence():
"""
Empty sequence fixture
Expand All @@ -13,3 +40,13 @@ def empty_sequence():
name='open youtube',
actions=[]
)


@fixture
def one_action_sequence(empty_sequence, put_a_action):
"""
sequence with one action
"""

empty_sequence.add(put_a_action)
return empty_sequence
13 changes: 0 additions & 13 deletions testing/test_replay_wizard/test_models/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,6 @@
Pytest fixtures
"""
from pytest import fixture
from replay_wizard.models import Action, Subtypes


@fixture
def put_a_action():
"""
Simple action fixture
"""
return Action(
subtype=Subtypes.KEYBOARD,
value='a',
timedelta=0.1,
)


@fixture
Expand Down
13 changes: 13 additions & 0 deletions testing/test_replay_wizard/test_models/test_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,16 @@ def test_in(empty_sequence, put_a_action):
assert (put_a_action in empty_sequence) is False
empty_sequence.add(put_a_action)
assert put_a_action in empty_sequence


def test_for(one_action_sequence, put_a_action):
"""
Test for method
"""
one_action_sequence.add(put_a_action)
one_action_sequence.add(put_a_action)
count = 0
for action in one_action_sequence:
count += 1
assert isinstance(action, Action)
assert count == len(one_action_sequence)
File renamed without changes.
40 changes: 40 additions & 0 deletions testing/test_replay_wizard/test_replay/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Pytest fixtures
"""
from pytest import fixture


class MockKeyboardController:
"""
Mock class for pynput Controller
"""

action_list = []

def press(self, key):
"""
Mocked press method
"""
self.action_list.append(('PRESS', key))

def release(self, key):
"""
Mocked release method
"""
self.action_list.append(('RELEASE', key))

@classmethod
def clear(cls):
"""
Clear action lint after testing
Because it's class property
"""
cls.action_list.clear()


@fixture
def mocked_keyboard_controller():
"""
Mock keyboard kontroller from pynput
"""
return MockKeyboardController
Loading

0 comments on commit 7045530

Please sign in to comment.