ok-script 0.0.77__tar.gz → 0.0.79__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. {ok-script-0.0.77 → ok-script-0.0.79}/PKG-INFO +1 -1
  2. {ok-script-0.0.77 → ok-script-0.0.79}/ok/OK.py +19 -11
  3. {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/platform_windows.py +2 -0
  4. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/DeviceManager.py +7 -4
  5. {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/FeatureSet.py +2 -1
  6. {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/FindFeature.py +1 -1
  7. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/App.py +6 -0
  8. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/MainWindow.py +2 -5
  9. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/MessageWindow.py +2 -1
  10. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/DebugTab.py +5 -5
  11. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/StartTab.py +2 -0
  12. {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/BaseTask.py +12 -0
  13. {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/ExecutorOperation.py +7 -0
  14. {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/TaskExecutor.py +1 -2
  15. {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/GithubMultiDownloader.py +8 -1
  16. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/Handler.py +23 -43
  17. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/exit_event.py +1 -1
  18. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/win32_process.py +2 -2
  19. {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/PKG-INFO +1 -1
  20. {ok-script-0.0.77 → ok-script-0.0.79}/setup.py +1 -1
  21. {ok-script-0.0.77 → ok-script-0.0.79}/README.md +0 -0
  22. {ok-script-0.0.77 → ok-script-0.0.79}/ok/__init__.py +0 -0
  23. {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/__init__.py +0 -0
  24. {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/emulator_base.py +0 -0
  25. {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/emulator_windows.py +0 -0
  26. {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/platform_base.py +0 -0
  27. {ok-script-0.0.77 → ok-script-0.0.79}/ok/alas/utils.py +0 -0
  28. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/BaseCaptureMethod.py +0 -0
  29. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/HwndWindow.py +0 -0
  30. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/__init__.py +0 -0
  31. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/ADBCaptureMethod.py +0 -0
  32. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
  33. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/__init__.py +0 -0
  34. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/adb/bin/__init__.py +0 -0
  35. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/image/ImageCaptureMethod.py +0 -0
  36. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/image/__init__.py +0 -0
  37. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
  38. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/BitBltCaptureMethod.py +0 -0
  39. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
  40. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +0 -0
  41. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/__init__.py +0 -0
  42. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/d3d11.py +0 -0
  43. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/dump.py +0 -0
  44. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/utils.py +0 -0
  45. {ok-script-0.0.77 → ok-script-0.0.79}/ok/capture/windows/window.py +0 -0
  46. {ok-script-0.0.77 → ok-script-0.0.79}/ok/color/Color.py +0 -0
  47. {ok-script-0.0.77 → ok-script-0.0.79}/ok/color/__init__.py +0 -0
  48. {ok-script-0.0.77 → ok-script-0.0.79}/ok/config/Config.py +0 -0
  49. {ok-script-0.0.77 → ok-script-0.0.79}/ok/config/InfoDict.py +0 -0
  50. {ok-script-0.0.77 → ok-script-0.0.79}/ok/config/__init__.py +0 -0
  51. {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/Box.py +0 -0
  52. {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/Feature.py +0 -0
  53. {ok-script-0.0.77 → ok-script-0.0.79}/ok/feature/__init__.py +0 -0
  54. {ok-script-0.0.77 → ok-script-0.0.79}/ok/firebase/Analytics.py +0 -0
  55. {ok-script-0.0.77 → ok-script-0.0.79}/ok/firebase/__init__.py +0 -0
  56. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/Communicate.py +0 -0
  57. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/StartController.py +0 -0
  58. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/TabTitles.py +0 -0
  59. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/__init__.py +0 -0
  60. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/AboutTab.py +0 -0
  61. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/HttpTextEdit.py +0 -0
  62. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/VersionCard.py +0 -0
  63. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/about/__init__.py +0 -0
  64. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/OKIcon.py +0 -0
  65. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/__init__.py +0 -0
  66. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/config.py +0 -0
  67. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/common/style_sheet.py +0 -0
  68. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/AspectRatioWidget.py +0 -0
  69. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/FrameWidget.py +0 -0
  70. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/InfoWidget.py +0 -0
  71. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/LoggerWidget.py +0 -0
  72. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/Screenshot.py +0 -0
  73. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/debug/__init__.py +0 -0
  74. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/i18n/__init__.py +0 -0
  75. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/i18n/path.py +0 -0
  76. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/i18n/update.py +0 -0
  77. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/icon/__init__.py +0 -0
  78. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/icon/icon.py +0 -0
  79. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/overlay/OverlayWindow.py +0 -0
  80. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/overlay/__init__.py +0 -0
  81. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/qss/__init__.py +0 -0
  82. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/resources.py +0 -0
  83. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/settings/SettingTab.py +0 -0
  84. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/settings/__init__.py +0 -0
  85. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/SelectCaptureListView.py +0 -0
  86. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/StartCard.py +0 -0
  87. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/start/__init__.py +0 -0
  88. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ConfigItemFactory.py +0 -0
  89. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
  90. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
  91. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndDropDown.py +0 -0
  92. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
  93. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndList.py +0 -0
  94. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
  95. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
  96. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/LabelAndWidget.py +0 -0
  97. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ModifyListDialog.py +0 -0
  98. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/ModifyListItem.py +0 -0
  99. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
  100. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/StartButton.py +0 -0
  101. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TaskCard.py +0 -0
  102. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TaskOpButton.py +0 -0
  103. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TooltipTableWidget.py +0 -0
  104. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/TriggerTaskTab.py +0 -0
  105. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/tasks/__init__.py +0 -0
  106. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/util/Alert.py +0 -0
  107. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/util/InitWorker.py +0 -0
  108. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/util/__init__.py +0 -0
  109. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/Card.py +0 -0
  110. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/EmptyCard.py +0 -0
  111. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/FramelessDialog.py +0 -0
  112. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/ListTableWidgetItem.py +0 -0
  113. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
  114. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/StartLoadingDialog.py +0 -0
  115. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/StatusBar.py +0 -0
  116. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/Tab.py +0 -0
  117. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/TabWidget.py +0 -0
  118. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
  119. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/YesNonWidgetItem.py +0 -0
  120. {ok-script-0.0.77 → ok-script-0.0.79}/ok/gui/widget/__init__.py +0 -0
  121. {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/ADBInteraction.py +0 -0
  122. {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/BaseInteraction.py +0 -0
  123. {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/DoNothingInteraction.py +0 -0
  124. {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/Win32Interaction.py +0 -0
  125. {ok-script-0.0.77 → ok-script-0.0.79}/ok/interaction/__init__.py +0 -0
  126. {ok-script-0.0.77 → ok-script-0.0.79}/ok/logging/Logger.py +0 -0
  127. {ok-script-0.0.77 → ok-script-0.0.79}/ok/logging/__init__.py +0 -0
  128. {ok-script-0.0.77 → ok-script-0.0.79}/ok/ocr/OCR.py +0 -0
  129. {ok-script-0.0.77 → ok-script-0.0.79}/ok/ocr/__init__.py +0 -0
  130. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  131. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  132. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  133. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  134. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  135. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  136. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  137. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  138. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  139. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Media/__init__.py +0 -0
  140. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  141. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Security/__init__.py +0 -0
  142. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  143. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  144. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/Windows/__init__.py +0 -0
  145. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/__init__.py +0 -0
  146. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/delegate.py +0 -0
  147. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/export.py +0 -0
  148. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/idldsl.py +0 -0
  149. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/inspectable.py +0 -0
  150. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/roapi.py +0 -0
  151. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/types.py +0 -0
  152. {ok-script-0.0.77 → ok-script-0.0.79}/ok/rotypes/winstring.py +0 -0
  153. {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/BlackBarProcessor.py +0 -0
  154. {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/PostProcessor.py +0 -0
  155. {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/SaveByInterval.py +0 -0
  156. {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/SaveByKeyPress.py +0 -0
  157. {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/SaveMethodBase.py +0 -0
  158. {ok-script-0.0.77 → ok-script-0.0.79}/ok/save/__init__.py +0 -0
  159. {ok-script-0.0.77 → ok-script-0.0.79}/ok/scene/FeatureScene.py +0 -0
  160. {ok-script-0.0.77 → ok-script-0.0.79}/ok/scene/Scene.py +0 -0
  161. {ok-script-0.0.77 → ok-script-0.0.79}/ok/scene/__init__.py +0 -0
  162. {ok-script-0.0.77 → ok-script-0.0.79}/ok/stats/StreamStats.py +0 -0
  163. {ok-script-0.0.77 → ok-script-0.0.79}/ok/stats/__init__.py +0 -0
  164. {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/OneTimeTask.py +0 -0
  165. {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/TriggerTask.py +0 -0
  166. {ok-script-0.0.77 → ok-script-0.0.79}/ok/task/__init__.py +0 -0
  167. {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/Updater.py +0 -0
  168. {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/__init__.py +0 -0
  169. {ok-script-0.0.77 → ok-script-0.0.79}/ok/update/gen_md5.py +0 -0
  170. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/__init__.py +0 -0
  171. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/json.py +0 -0
  172. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/list.py +0 -0
  173. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/path.py +0 -0
  174. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/thread.py +0 -0
  175. {ok-script-0.0.77 → ok-script-0.0.79}/ok/util/yaml.py +0 -0
  176. {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/SOURCES.txt +0 -0
  177. {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/dependency_links.txt +0 -0
  178. {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/requires.txt +0 -0
  179. {ok-script-0.0.77 → ok-script-0.0.79}/ok_script.egg-info/top_level.txt +0 -0
  180. {ok-script-0.0.77 → ok-script-0.0.79}/setup.cfg +0 -0
  181. {ok-script-0.0.77 → ok-script-0.0.79}/tests/__init__.py +0 -0
  182. {ok-script-0.0.77 → ok-script-0.0.79}/tests/test_updater.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ok-script
3
- Version: 0.0.77
3
+ Version: 0.0.79
4
4
  Summary: Automation with Computer Vision for Python
5
5
  Home-page: https://github.com/ok-oldking/ok-script
6
6
  Author: ok-oldking
@@ -11,7 +11,6 @@ from ok.util.exit_event import ExitEvent
11
11
  from ok.util.path import install_path_isascii
12
12
  from ok.util.win32_process import check_mutex
13
13
 
14
- check_mutex()
15
14
  logger = get_logger(__name__)
16
15
 
17
16
 
@@ -27,6 +26,7 @@ class OK:
27
26
  app = None
28
27
  screenshot = None
29
28
  exit_event = ExitEvent()
29
+ init_error = None
30
30
 
31
31
  def __init__(self, config: Dict[str, Any]):
32
32
  print(f"AutoHelper init, config: {config}")
@@ -57,7 +57,8 @@ class OK:
57
57
  def start(self):
58
58
  try:
59
59
  if self.config.get("use_gui"):
60
- self.app.show_main_window()
60
+ if not self.init_error:
61
+ self.app.show_main_window()
61
62
  self.app.exec()
62
63
  else:
63
64
  self.task_executor.start()
@@ -91,14 +92,6 @@ class OK:
91
92
 
92
93
  def do_init(self):
93
94
  logger.info(f"initializing {self.__class__.__name__}, config: {self.config}")
94
- if self.config.get('ocr'):
95
- isascii, path = install_path_isascii()
96
- if not isascii:
97
- self.app.show_path_ascii_error(path)
98
- return False
99
- from rapidocr_openvino import RapidOCR
100
- inference_num_threads = self.config.get('ocr').get('inference_num_threads', -1)
101
- self.ocr = RapidOCR(inference_num_threads=inference_num_threads)
102
95
 
103
96
  template_matching = self.config.get('template_matching')
104
97
  if template_matching is not None:
@@ -117,10 +110,25 @@ class OK:
117
110
  trigger_tasks=self.config.get('trigger_tasks', []),
118
111
  scenes=self.config['scenes'],
119
112
  feature_set=self.feature_set,
120
- ocr=self.ocr, config_folder=self.config.get("config_folder"))
113
+ config_folder=self.config.get("config_folder"))
121
114
 
122
115
  ok.gui.executor = self.task_executor
123
116
 
117
+ if self.config.get('ocr'):
118
+ isascii, path = install_path_isascii()
119
+ if not isascii:
120
+ self.app.show_path_ascii_error(path)
121
+ self.init_error = True
122
+ return False
123
+ from rapidocr_openvino import RapidOCR
124
+ inference_num_threads = self.config.get('ocr').get('inference_num_threads', -1)
125
+ self.ocr = RapidOCR(inference_num_threads=inference_num_threads)
126
+ self.task_executor.ocr = self.ocr
127
+
128
+ if not check_mutex():
129
+ self.init_error = True
130
+ self.app.show_already_running_error()
131
+
124
132
  return True
125
133
 
126
134
  def wait_task(self):
@@ -44,6 +44,8 @@ def get_emulator_exe(instance: EmulatorInstance):
44
44
  elif instance == Emulator.BlueStacks4:
45
45
  # BlueStacks\Client\Bluestacks.exe -vmname Android_1
46
46
  return f'"{exe}" -vmname {instance.name}'
47
+ elif instance == Emulator.LDPlayerFamily:
48
+ return f'"{exe}" -name {instance.name}'
47
49
  else:
48
50
  raise EmulatorUnknown(f'Cannot start an unknown emulator instance: {instance}')
49
51
 
@@ -55,6 +55,9 @@ class DeviceManager:
55
55
  def adb_connect(self, addr):
56
56
  try:
57
57
  for info in self.adb.list():
58
+ if self.exit_event.is_set():
59
+ logger.error(f"adb_connect exit_event is set")
60
+ return None
58
61
  if info.serial == addr:
59
62
  if info.state == 'offline':
60
63
  logger.debug(f'adb_connect offline disconnect first {addr}')
@@ -185,7 +188,7 @@ class DeviceManager:
185
188
  if self.config.get("preferred") != imei:
186
189
  logger.info(f'preferred device did change {imei}')
187
190
  self.config["preferred"] = imei
188
- self.handler.post(self.start, remove_existing=True, skip_if_running=True)
191
+ self.start()
189
192
  logger.debug(f'preferred device: {preferred}')
190
193
 
191
194
  def adb_get_imei(self, device):
@@ -215,7 +218,7 @@ class DeviceManager:
215
218
  def set_capture(self, capture):
216
219
  if self.config.get("capture") != capture:
217
220
  self.config['capture'] = capture
218
- self.handler.post(self.start, remove_existing=True, skip_if_running=True)
221
+ self.start()
219
222
 
220
223
  def get_hwnd_name(self):
221
224
  preferred = self.get_preferred_device()
@@ -280,7 +283,7 @@ class DeviceManager:
280
283
  communicate.adb_devices.emit(True)
281
284
 
282
285
  def update_resolution_for_hwnd(self):
283
- if self.hwnd is not None and self.hwnd.frame_aspect_ratio == 0:
286
+ if self.hwnd is not None and self.hwnd.frame_aspect_ratio == 0 and self.adb_capture_config:
284
287
  width, height = self.get_resolution()
285
288
  logger.debug(f'update resolution for {self.hwnd} {width}x{height}')
286
289
  self.hwnd.update_frame_size(width, height)
@@ -372,7 +375,7 @@ class DeviceManager:
372
375
  packages = [packages]
373
376
  for package in packages:
374
377
  if package == front.package:
375
- return False
378
+ return True
376
379
 
377
380
  def adb_start_package(self, package):
378
381
  self.shell(f'monkey -p {package} -c android.intent.category.LAUNCHER 1')
@@ -105,7 +105,8 @@ class FeatureSet:
105
105
  self.feature_dict[category_name] = Feature(image, x, y, w, h)
106
106
  self.box_dict[category_name] = Box(x, y, w, h, name=category_name)
107
107
 
108
- def get_box_by_name(self, category_name: str) -> Box:
108
+ def get_box_by_name(self, mat, category_name: str) -> Box:
109
+ self.check_size(mat)
109
110
  if category_name in self.box_dict:
110
111
  return self.box_dict[category_name]
111
112
  else:
@@ -18,7 +18,7 @@ class FindFeature:
18
18
  threshold, use_gray_scale, x, y, to_x, to_y, width, height)
19
19
 
20
20
  def get_box_by_name(self, name):
21
- return self.feature_set.get_box_by_name(name)
21
+ return self.feature_set.get_box_by_name(self.executor.frame, name)
22
22
 
23
23
  def find_feature_and_set(self, features, horizontal_variance=0, vertical_variance=0, threshold=0):
24
24
  ret = True
@@ -79,6 +79,12 @@ class App:
79
79
  message_window = MessageWindow(self.icon, title, message, exit_event=self.exit_event)
80
80
  message_window.show()
81
81
 
82
+ def show_already_running_error(self):
83
+ title = QCoreApplication.translate("app", 'Error')
84
+ content = QCoreApplication.translate("app",
85
+ "Another instance is already running")
86
+ self.show_message_window(title, content)
87
+
82
88
  def show_path_ascii_error(self, path):
83
89
  title = QCoreApplication.translate("app", 'Error')
84
90
  content = QCoreApplication.translate("app",
@@ -2,12 +2,10 @@ import os
2
2
  import sys
3
3
 
4
4
  from PySide6.QtCore import QObject, Signal, Qt
5
- from PySide6.QtGui import QKeySequence, QShortcut
6
5
  from PySide6.QtWidgets import QMenu, QSystemTrayIcon
7
6
  from qfluentwidgets import FluentIcon, NavigationItemPosition, MSFluentWindow, InfoBar, InfoBarPosition, MessageBox
8
7
 
9
8
  import ok.gui
10
- from ok.capture.windows.dump import dump_threads
11
9
  from ok.gui.Communicate import communicate
12
10
  from ok.gui.about.AboutTab import AboutTab
13
11
  from ok.gui.debug.DebugTab import DebugTab
@@ -68,8 +66,6 @@ class MainWindow(MSFluentWindow):
68
66
  communicate.executor_paused.connect(self.executor_paused)
69
67
  communicate.tab.connect(self.navigate_tab)
70
68
 
71
-
72
-
73
69
  # Create a context menu for the tray
74
70
  menu = QMenu()
75
71
  exit_action = menu.addAction(self.tr("Exit"))
@@ -167,10 +163,11 @@ class MainWindow(MSFluentWindow):
167
163
  def closeEvent(self, event):
168
164
  # Create a message box that asks the user if they really want to close the window
169
165
  if sys.platform == 'win32' and 'shutdown' in os.environ.get('SESSIONNAME', '').lower():
166
+ logger.info("system shutting down")
167
+ ok.gui.ok.quit()
170
168
  event.accept()
171
169
  return
172
170
 
173
- # Your existing code for the message box
174
171
  if ok.gui.ok.exit_event.is_set():
175
172
  event.accept()
176
173
  return
@@ -27,8 +27,9 @@ class MessageWindow(FramelessWindow):
27
27
  self.message_label = BodyLabel(message)
28
28
  self.message_label.setWordWrap(True)
29
29
  self.vBoxLayout = QVBoxLayout(self)
30
+ self.vBoxLayout.setAlignment(Qt.AlignCenter)
30
31
  self.setLayout(self.vBoxLayout)
31
- self.vBoxLayout.addWidget(self.message_label, 0, Qt.AlignVCenter)
32
+ self.vBoxLayout.addWidget(self.message_label, 1, Qt.AlignVCenter)
32
33
  self.confirm_button = PushButton(self.tr('Confirm'))
33
34
  self.vBoxLayout.addWidget(self.confirm_button, 0, Qt.AlignCenter)
34
35
  self.confirm_button.clicked.connect(self.quit)
@@ -1,9 +1,8 @@
1
1
  import subprocess
2
2
  from ctypes import windll, wintypes
3
3
 
4
- from PySide6.QtCore import Qt, Signal, QEvent
5
- from PySide6.QtGui import QShortcut, QKeySequence
6
- from PySide6.QtWidgets import QWidget, QFileDialog, QCompleter, QVBoxLayout, QHBoxLayout, QMessageBox
4
+ from PySide6.QtCore import Qt, Signal
5
+ from PySide6.QtWidgets import QWidget, QFileDialog, QCompleter, QVBoxLayout, QHBoxLayout
7
6
  from _ctypes import byref
8
7
  from qfluentwidgets import PushButton, FlowLayout, ComboBox, SearchLineEdit, TextEdit
9
8
 
@@ -110,6 +109,7 @@ class DebugTab(Tab):
110
109
  if msg.message == 0x0312: # WM_HOTKEY
111
110
  logger.debug(f'hotkey pressed {msg}')
112
111
  if msg.wParam == 1:
112
+ logger.debug('dumping threads')
113
113
  dump_threads()
114
114
  elif msg.wParam == 2:
115
115
  self.handler.post(self.capture)
@@ -124,9 +124,9 @@ class DebugTab(Tab):
124
124
  VK_S = 0x53
125
125
 
126
126
  if not windll.user32.RegisterHotKey(None, 1, MOD_ALT | MOD_CONTROL, VK_D):
127
- print("Failed to register hotkey for Alt+Ctrl+D")
127
+ logger.debug("Failed to register hotkey for Alt+Ctrl+D")
128
128
  if not windll.user32.RegisterHotKey(None, 2, MOD_ALT | MOD_CONTROL, VK_S):
129
- print("Failed to register hotkey for Alt+Ctrl+S")
129
+ logger.debug("Failed to register hotkey for Alt+Ctrl+S")
130
130
  logger.debug('bind_hot_keys')
131
131
 
132
132
  def __del__(self):
@@ -82,6 +82,8 @@ class StartTab(Tab):
82
82
  preferred = ok.gui.device_manager.config.get("preferred")
83
83
  selected = self.device_list_row
84
84
 
85
+ logger.debug('update_capture')
86
+
85
87
  # Update the existing items in the device_list and ok.gui.device_manager.get_devices()
86
88
  for row, device in enumerate(devices):
87
89
  if device["imei"] == preferred:
@@ -1,8 +1,11 @@
1
+ import threading
2
+
1
3
  from ok.config.Config import Config
2
4
  from ok.config.InfoDict import InfoDict
3
5
  from ok.gui.Communicate import communicate
4
6
  from ok.logging.Logger import get_logger
5
7
  from ok.task.ExecutorOperation import ExecutorOperation
8
+ from ok.util.Handler import Handler
6
9
 
7
10
  logger = get_logger(__name__)
8
11
 
@@ -22,6 +25,15 @@ class BaseTask(ExecutorOperation):
22
25
  self.config_description = {}
23
26
  self.config_type = {}
24
27
  self._paused = False
28
+ self.lock = threading.Lock()
29
+ self._handler = None
30
+
31
+ @property
32
+ def handler(self) -> Handler:
33
+ with self.lock:
34
+ if self._handler is None:
35
+ self._handler = Handler(self.executor.exit_event, __name__)
36
+ return self._handler
25
37
 
26
38
  def pause(self):
27
39
  self.executor.pause(self)
@@ -1,6 +1,7 @@
1
1
  import queue
2
2
  from typing import List
3
3
 
4
+ from ok.color.Color import calculate_color_percentage
4
5
  from ok.feature.Box import Box, find_box_by_name, relative_box
5
6
  from ok.gui.Communicate import communicate
6
7
 
@@ -163,5 +164,11 @@ class ExecutorOperation:
163
164
  def draw_boxes(feature_name=None, boxes=None, color="red"):
164
165
  communicate.emit_draw_box(feature_name, boxes, color)
165
166
 
167
+ def calculate_color_percentage(self, color, box: Box):
168
+ percentage = calculate_color_percentage(self.frame, color, box)
169
+ box.confidence = percentage
170
+ self.draw_boxes(box.name, box)
171
+ return percentage
172
+
166
173
  def adb_shell(self, *args, **kwargs):
167
174
  return self.executor.device_manager.shell(*args, **kwargs)
@@ -10,7 +10,6 @@ from ok.scene.Scene import Scene
10
10
  from ok.stats.StreamStats import StreamStats
11
11
  from ok.task.OneTimeTask import OneTimeTask
12
12
  from ok.task.TriggerTask import TriggerTask
13
- from ok.util.exit_event import ExitEvent
14
13
 
15
14
  logger = get_logger(__name__)
16
15
 
@@ -35,7 +34,7 @@ class TaskExecutor:
35
34
 
36
35
  def __init__(self, device_manager: DeviceManager,
37
36
  wait_until_timeout=10, wait_until_before_delay=1, wait_until_check_delay=1,
38
- exit_event=ExitEvent(), trigger_tasks=[], onetime_tasks=[], scenes=[], feature_set=None,
37
+ exit_event=None, trigger_tasks=[], onetime_tasks=[], scenes=[], feature_set=None,
39
38
  ocr=None,
40
39
  config_folder=None):
41
40
  self.device_manager = device_manager
@@ -55,13 +55,14 @@ class GithubMultiDownloader:
55
55
  downloaded = os.path.getsize(file)
56
56
  if downloaded == part_size:
57
57
  logger.info(f'File {file} already downloaded')
58
+ self.downloaded += part_size
58
59
  return
59
60
  elif downloaded > part_size:
60
61
  logger.warning(f'File size error {file} {downloaded} > {part_size}')
61
62
  os.remove(file)
62
63
  else:
63
64
  part_start += downloaded
64
- self.downloaded += part_size
65
+ self.downloaded += downloaded
65
66
 
66
67
  target_size = end - part_start + 1
67
68
 
@@ -117,6 +118,12 @@ class GithubMultiDownloader:
117
118
  response.close()
118
119
  logger.debug('switch to fast proxy')
119
120
  break
121
+ if part_downloaded == target_size:
122
+ logger.debug("download_part finished")
123
+ return
124
+ else:
125
+ logger.warning(f'download_part size failed {part_downloaded} {target_size}')
126
+ return True
120
127
  except Exception as e:
121
128
  with self.lock:
122
129
  if proxy in self.proxys:
@@ -31,33 +31,40 @@ class Handler:
31
31
  while not self.task_queue:
32
32
  self.condition.wait()
33
33
 
34
- now = time.time()
35
- while self.task_queue and self.task_queue[0].execute_at <= now:
36
- scheduled_task = heapq.heappop(self.task_queue)
37
- if scheduled_task.task is None:
38
- logger.debug(f'stopping handler {self.thread.name}')
39
- return
40
- self.executing = scheduled_task.task
41
- try:
42
- scheduled_task.task()
43
- except Exception as e:
44
- logger.error(f'handler {self.thread.name} raised exception', e)
45
- self.executing = None
46
-
34
+ now = time.time()
35
+ self.condition.acquire()
36
+ if self.task_queue and self.task_queue[0].execute_at <= now:
37
+ scheduled_task = heapq.heappop(self.task_queue)
38
+ self.condition.release()
39
+ if scheduled_task.task is None:
40
+ logger.debug(f'stopping handler {self.thread.name}')
41
+ return
42
+ self.executing = scheduled_task.task
43
+ try:
44
+ scheduled_task.task()
45
+ except Exception as e:
46
+ logger.error(f'handler {self.thread.name} raised exception', e)
47
+ self.executing = None
48
+ else:
47
49
  if self.task_queue:
48
50
  next_time = self.task_queue[0].execute_at
49
51
  timeout = next_time - now
50
52
  if timeout > 0:
51
53
  self.condition.wait(timeout=timeout)
54
+ self.condition.release()
52
55
 
53
56
  def post(self, task, delay=0, remove_existing=False, skip_if_running=False):
54
57
  with self.condition:
58
+ if self.exit_event.is_set():
59
+ logger.error(f'post handler {self.thread.name} already exits')
60
+ self.condition.notify_all()
61
+ return
55
62
  if remove_existing and len(self.task_queue) > 0:
56
63
  for obj in self.task_queue.copy():
57
64
  if obj.task == task:
58
65
  self.task_queue.remove(obj)
59
66
  logger.debug(f'removing duplicate task {task}')
60
- if remove_existing and self.executing == task:
67
+ if skip_if_running and self.executing == task:
61
68
  logger.debug(f'skipping duplicate task {task}')
62
69
  return
63
70
  if delay > 0:
@@ -65,36 +72,9 @@ class Handler:
65
72
  else:
66
73
  scheduled_task = ScheduledTask(0, task)
67
74
  heapq.heappush(self.task_queue, scheduled_task)
68
- self.condition.notify()
75
+ self.condition.notify_all()
69
76
 
70
77
  def stop(self):
71
- heapq.heappush(self.task_queue, ScheduledTask(0, None))
72
78
  with self.condition:
79
+ heapq.heappush(self.task_queue, ScheduledTask(0, None))
73
80
  self.condition.notify_all()
74
-
75
-
76
- # Example usage
77
- if __name__ == "__main__":
78
- def print_message(message):
79
- from datetime import datetime
80
- print(f"{message} at {datetime.now().time()}")
81
-
82
-
83
- exit_event = ExitEvent()
84
- handler = Handler(event=ExitEvent(), name="MyHandlerThread")
85
-
86
- # Post a task to run immediately
87
- handler.post(lambda: print_message("Immediate task"))
88
-
89
- # Post a task to run after a delay (e.g., 2 seconds)
90
- handler.post_delayed(lambda: print_message("Delayed task"), 2)
91
-
92
- # Post a function to run immediately
93
- handler.post(lambda: print_message("Immediate function"))
94
-
95
- # Post a function to run after a delay (e.g., 3 seconds)
96
- handler.post_delayed(lambda: print_message("Delayed function"), 3)
97
-
98
- # Let the handler run for a while to process the tasks
99
- time.sleep(5)
100
- exit_event.set()
@@ -17,7 +17,7 @@ class ExitEvent(threading.Event):
17
17
 
18
18
  def set(self):
19
19
  super(ExitEvent, self).set()
20
- logger.debug(f"ExitEvent set event empty queues")
20
+ logger.debug(f"ExitEvent set event empty queues {self.queues} to_stops: {self.to_stops}")
21
21
  for queue in self.queues:
22
22
  queue.put(None)
23
23
 
@@ -4,7 +4,6 @@ import ctypes
4
4
  import hashlib
5
5
  import msvcrt
6
6
  import os
7
- import sys
8
7
  from ctypes import wintypes
9
8
  from typing import Union
10
9
 
@@ -34,7 +33,8 @@ def check_mutex():
34
33
  # Check if the mutex already exists
35
34
  if GetLastError() == ERROR_ALREADY_EXISTS:
36
35
  print(f"Another instance of this application is already running. {path}")
37
- sys.exit(0)
36
+ return False
37
+ return True
38
38
 
39
39
 
40
40
  def all_pids() -> list[int]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ok-script
3
- Version: 0.0.77
3
+ Version: 0.0.79
4
4
  Summary: Automation with Computer Vision for Python
5
5
  Home-page: https://github.com/ok-oldking/ok-script
6
6
  Author: ok-oldking
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="ok-script",
8
- version="0.0.77",
8
+ version="0.0.79",
9
9
  author="ok-oldking",
10
10
  author_email="firedcto@gmail.com",
11
11
  description="Automation with Computer Vision for Python",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes