Skip to content

Commit 97c92f4

Browse files
authored
Merge pull request #103 from Intergration-Automation-Testing/dev
Dev
2 parents 6619d98 + 046e48d commit 97c92f4

File tree

11 files changed

+187
-45
lines changed

11 files changed

+187
-45
lines changed

.idea/workspace.xml

Lines changed: 1 addition & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

stable.toml renamed to dev.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# Rename to build stable version
2-
# This is stable version
1+
# Rename to build dev version
2+
# This is dev version
33
[build-system]
4-
requires = ["setuptools>=61.0"]
4+
requires = ["setuptools"]
55
build-backend = "setuptools.build_meta"
66

77
[project]
8-
name = "je_auto_control"
9-
version = "0.0.139"
8+
name = "je_auto_control_dev"
9+
version = "0.0.77"
1010
authors = [
1111
{ name = "JE-Chen", email = "[email protected]" },
1212
]

je_auto_control/__init__.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -96,31 +96,25 @@
9696
from je_auto_control.wrapper.auto_control_screen import screenshot
9797
# import screen
9898
from je_auto_control.wrapper.auto_control_screen import screen_size
99+
# Shell command
100+
from je_auto_control.utils.shell_process.shell_exec import ShellManager
101+
from je_auto_control.utils.shell_process.shell_exec import default_shell_manager
102+
# Start exe
103+
from je_auto_control.utils.start_exe.start_another_process import start_exe
99104

100105
__all__ = [
101106
"click_mouse", "mouse_keys_table", "get_mouse_position", "press_mouse", "release_mouse",
102107
"mouse_scroll", "set_mouse_position", "special_mouse_keys_table",
103108
"keyboard_keys_table", "press_keyboard_key", "release_keyboard_key", "type_keyboard", "check_key_is_press",
104-
"write", "hotkey",
105-
"screen_size", "screenshot",
106-
"locate_all_image", "locate_image_center", "locate_and_click",
107-
"CriticalExit",
108-
"AutoControlException", "AutoControlKeyboardException",
109+
"write", "hotkey", "start_exe",
110+
"screen_size", "screenshot", "locate_all_image", "locate_image_center", "locate_and_click",
111+
"CriticalExit", "AutoControlException", "AutoControlKeyboardException",
109112
"AutoControlMouseException", "AutoControlCantFindKeyException",
110-
"AutoControlScreenException", "ImageNotFoundException",
111-
"AutoControlJsonActionException", "AutoControlRecordException",
112-
"AutoControlActionNullException", "AutoControlActionException",
113-
"record", "stop_record",
114-
"read_action_json", "write_action_json",
115-
"execute_action", "execute_files", "executor", "add_command_to_executor",
116-
"multiprocess_timeout", "test_record_instance",
117-
"screenshot",
118-
"pil_screenshot",
119-
"generate_html", "generate_html_report",
120-
"generate_json", "generate_json_report",
121-
"generate_xml", "generate_xml_report",
122-
"get_dir_files_as_list", "create_project_dir",
123-
"start_autocontrol_socket_server",
124-
"callback_executor", "package_manager",
125-
"get_special_table"
113+
"AutoControlScreenException", "ImageNotFoundException", "AutoControlJsonActionException",
114+
"AutoControlRecordException", "AutoControlActionNullException", "AutoControlActionException", "record",
115+
"stop_record", "read_action_json", "write_action_json", "execute_action", "execute_files", "executor",
116+
"add_command_to_executor", "multiprocess_timeout", "test_record_instance", "screenshot", "pil_screenshot",
117+
"generate_html", "generate_html_report", "generate_json", "generate_json_report", "generate_xml",
118+
"generate_xml_report", "get_dir_files_as_list", "create_project_dir", "start_autocontrol_socket_server",
119+
"callback_executor", "package_manager", "get_special_table", "ShellManager", "default_shell_manager",
126120
]

je_auto_control/utils/callback/callback_function_executor.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import typing
22
from sys import stderr
33

4-
from je_auto_control.utils.project.create_project_structure import create_project_dir
4+
from je_auto_control.utils.shell_process.shell_exec import ShellManager
5+
from je_auto_control.utils.start_exe.start_another_process import start_exe
56
from je_auto_control.utils.exception.exception_tags import get_bad_trigger_method, get_bad_trigger_function
67
from je_auto_control.utils.exception.exceptions import CallbackExecutorException
78
# executor
89
from je_auto_control.utils.executor.action_executor import execute_action
910
from je_auto_control.utils.executor.action_executor import execute_files
10-
from je_auto_control.utils.project.create_project_structure import create_project_dir
1111
# file process
1212
from je_auto_control.utils.file_process.get_dir_file_list import get_dir_files_as_list
1313
# html report
@@ -25,6 +25,7 @@
2525
from je_auto_control.utils.json.json_file import write_action_json
2626
from je_auto_control.utils.package_manager.package_manager_class import \
2727
package_manager
28+
from je_auto_control.utils.project.create_project_structure import create_project_dir
2829
# socket server
2930
from je_auto_control.utils.socket_server.auto_control_socket_server import start_autocontrol_socket_server
3031
# test record
@@ -111,7 +112,11 @@ def __init__(self):
111112
"add_package_to_executor": package_manager.add_package_to_executor,
112113
"add_package_to_callback_executor": package_manager.add_package_to_callback_executor,
113114
# project
114-
"create_project": create_project_dir
115+
"create_project": create_project_dir,
116+
# Shell
117+
"shell_command": ShellManager().exec_shell,
118+
# Another process
119+
"execute_process": start_exe,
115120
}
116121

117122
def callback_function(

je_auto_control/utils/exception/exception_tags.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,5 @@
5959
# Callback executor
6060
get_bad_trigger_method: str = "get bad trigger method, only accept kwargs and args"
6161
get_bad_trigger_function: str = "get bad trigger function only accept function in event_dict"
62+
# Can't find file
63+
can_not_find_file: str = "Can not find file"

je_auto_control/utils/executor/action_executor.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import builtins
12
import sys
2-
import time
33
import types
4-
import builtins
54
from inspect import getmembers, isbuiltin
65

7-
from je_auto_control.utils.project.create_project_structure import create_project_dir
6+
from je_auto_control.utils.start_exe.start_another_process import start_exe
7+
from je_auto_control.utils.shell_process.shell_exec import ShellManager
88
from je_auto_control.utils.exception.exception_tags import action_is_null_error, add_command_exception_tag, \
99
executor_list_error
1010
from je_auto_control.utils.exception.exception_tags import cant_execute_action_error
@@ -18,6 +18,7 @@
1818
from je_auto_control.utils.generate_report.generate_xml_report import generate_xml_report
1919
from je_auto_control.utils.json.json_file import read_action_json
2020
from je_auto_control.utils.package_manager.package_manager_class import package_manager
21+
from je_auto_control.utils.project.create_project_structure import create_project_dir
2122
from je_auto_control.utils.test_record.record_test_class import record_action_to_list, test_record_instance
2223
from je_auto_control.wrapper.auto_control_image import locate_all_image, locate_and_click, locate_image_center
2324
from je_auto_control.wrapper.auto_control_keyboard import check_key_is_press
@@ -82,7 +83,11 @@ def __init__(self):
8283
"add_package_to_executor": package_manager.add_package_to_executor,
8384
"add_package_to_callback_executor": package_manager.add_package_to_callback_executor,
8485
# project
85-
"create_project": create_project_dir
86+
"create_project": create_project_dir,
87+
# Shell
88+
"shell_command": ShellManager().exec_shell,
89+
# Another process
90+
"execute_process": start_exe,
8691
}
8792
# get all builtin function and add to event dict
8893
for function in getmembers(builtins, isbuiltin):

je_auto_control/utils/shell_process/__init__.py

Whitespace-only changes.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import queue
2+
import shlex
3+
import subprocess
4+
import sys
5+
from threading import Thread
6+
7+
8+
class ShellManager(object):
9+
10+
def __init__(
11+
self,
12+
shell_encoding: str = "utf-8",
13+
program_buffer: int = 10240000,
14+
):
15+
"""
16+
:param shell_encoding: shell command read output encoding
17+
:param program_buffer: buffer size
18+
"""
19+
self.read_program_error_output_from_thread = None
20+
self.read_program_output_from_thread = None
21+
self.still_run_shell: bool = True
22+
self.process = None
23+
self.run_output_queue: queue = queue.Queue()
24+
self.run_error_queue: queue = queue.Queue()
25+
self.program_encoding: str = shell_encoding
26+
self.program_buffer: int = program_buffer
27+
28+
def exec_shell(self, shell_command: [str, list]) -> None:
29+
"""
30+
:param shell_command: shell command will run
31+
:return: if error return result and True else return result and False
32+
"""
33+
try:
34+
self.exit_program()
35+
if sys.platform in ["win32", "cygwin", "msys"]:
36+
args = shell_command
37+
else:
38+
args = shlex.split(shell_command)
39+
self.process = subprocess.Popen(
40+
args=args,
41+
stdout=subprocess.PIPE,
42+
stderr=subprocess.PIPE,
43+
shell=True,
44+
)
45+
self.still_run_shell = True
46+
# program output message queue thread
47+
self.read_program_output_from_thread = Thread(
48+
target=self.read_program_output_from_process,
49+
daemon=True
50+
)
51+
self.read_program_output_from_thread.start()
52+
# program error message queue thread
53+
self.read_program_error_output_from_thread = Thread(
54+
target=self.read_program_error_output_from_process,
55+
daemon=True
56+
)
57+
self.read_program_error_output_from_thread.start()
58+
except Exception as error:
59+
print(repr(error), file=sys.stderr)
60+
61+
# tkinter_ui update method
62+
def pull_text(self) -> None:
63+
try:
64+
if not self.run_error_queue.empty():
65+
error_message = self.run_error_queue.get_nowait()
66+
error_message = str(error_message).strip()
67+
if error_message:
68+
print(error_message, file=sys.stderr)
69+
if not self.run_output_queue.empty():
70+
output_message = self.run_output_queue.get_nowait()
71+
output_message = str(output_message).strip()
72+
if output_message:
73+
print(output_message)
74+
except queue.Empty:
75+
pass
76+
if self.process.returncode == 0:
77+
self.exit_program()
78+
elif self.process.returncode is not None:
79+
self.exit_program()
80+
if self.still_run_shell:
81+
# poll return code
82+
self.process.poll()
83+
84+
# exit program change run flag to false and clean read thread and queue and process
85+
def exit_program(self) -> None:
86+
self.still_run_shell = False
87+
if self.read_program_output_from_thread is not None:
88+
self.read_program_output_from_thread = None
89+
if self.read_program_error_output_from_thread is not None:
90+
self.read_program_error_output_from_thread = None
91+
self.print_and_clear_queue()
92+
if self.process is not None:
93+
self.process.terminate()
94+
print(f"Shell command exit with code {self.process.returncode}")
95+
self.process = None
96+
97+
def print_and_clear_queue(self) -> None:
98+
try:
99+
for std_output in iter(self.run_output_queue.get_nowait, None):
100+
std_output = str(std_output).strip()
101+
if std_output:
102+
print(std_output)
103+
for std_err in iter(self.run_error_queue.get_nowait, None):
104+
std_err = str(std_err).strip()
105+
if std_err:
106+
print(std_err, file=sys.stderr)
107+
except queue.Empty:
108+
pass
109+
self.run_output_queue = queue.Queue()
110+
self.run_error_queue = queue.Queue()
111+
112+
def read_program_output_from_process(self) -> None:
113+
while self.still_run_shell:
114+
program_output_data = self.process.stdout.raw.read(
115+
self.program_buffer) \
116+
.decode(self.program_encoding)
117+
self.run_output_queue.put_nowait(program_output_data)
118+
119+
def read_program_error_output_from_process(self) -> None:
120+
while self.still_run_shell:
121+
program_error_output_data = self.process.stderr.raw.read(
122+
self.program_buffer) \
123+
.decode(self.program_encoding)
124+
self.run_error_queue.put_nowait(program_error_output_data)
125+
126+
127+
default_shell_manager = ShellManager()

je_auto_control/utils/start_exe/__init__.py

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from pathlib import Path
2+
3+
from je_auto_control.utils.exception.exception_tags import can_not_find_file
4+
from je_auto_control.utils.exception.exceptions import AutoControlException
5+
6+
from je_auto_control.utils.shell_process.shell_exec import ShellManager
7+
8+
9+
def start_exe(exe_path: str):
10+
exe_path = Path(exe_path)
11+
if exe_path.exists() and exe_path.is_file():
12+
process_manager = ShellManager()
13+
process_manager.exec_shell(str(exe_path))
14+
else:
15+
raise AutoControlException(can_not_find_file)

0 commit comments

Comments
 (0)