ok-script 0.0.71__tar.gz → 0.0.72__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 (183) hide show
  1. {ok-script-0.0.71 → ok-script-0.0.72}/PKG-INFO +1 -1
  2. {ok-script-0.0.71 → ok-script-0.0.72}/ok/OK.py +3 -3
  3. {ok-script-0.0.71 → ok-script-0.0.72}/ok/feature/Box.py +11 -3
  4. {ok-script-0.0.71 → ok-script-0.0.72}/ok/feature/Feature.py +3 -0
  5. {ok-script-0.0.71 → ok-script-0.0.72}/ok/feature/FeatureSet.py +8 -8
  6. ok-script-0.0.72/ok/firebase/Analytics.py +164 -0
  7. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/App.py +3 -3
  8. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/MainWindow.py +12 -3
  9. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/StartController.py +13 -15
  10. {ok-script-0.0.71 → ok-script-0.0.72}/ok/ocr/OCR.py +8 -3
  11. {ok-script-0.0.71 → ok-script-0.0.72}/ok/task/TaskExecutor.py +8 -9
  12. {ok-script-0.0.71 → ok-script-0.0.72}/ok_script.egg-info/PKG-INFO +1 -1
  13. {ok-script-0.0.71 → ok-script-0.0.72}/ok_script.egg-info/SOURCES.txt +1 -1
  14. {ok-script-0.0.71 → ok-script-0.0.72}/setup.py +1 -1
  15. ok-script-0.0.71/ok/firebase/FireBaseAnalytics.py +0 -200
  16. {ok-script-0.0.71 → ok-script-0.0.72}/README.md +0 -0
  17. {ok-script-0.0.71 → ok-script-0.0.72}/ok/__init__.py +0 -0
  18. {ok-script-0.0.71 → ok-script-0.0.72}/ok/alas/__init__.py +0 -0
  19. {ok-script-0.0.71 → ok-script-0.0.72}/ok/alas/emulator_base.py +0 -0
  20. {ok-script-0.0.71 → ok-script-0.0.72}/ok/alas/emulator_windows.py +0 -0
  21. {ok-script-0.0.71 → ok-script-0.0.72}/ok/alas/platform_base.py +0 -0
  22. {ok-script-0.0.71 → ok-script-0.0.72}/ok/alas/platform_windows.py +0 -0
  23. {ok-script-0.0.71 → ok-script-0.0.72}/ok/alas/utils.py +0 -0
  24. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/BaseCaptureMethod.py +0 -0
  25. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/HwndWindow.py +0 -0
  26. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/__init__.py +0 -0
  27. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/adb/ADBCaptureMethod.py +0 -0
  28. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/adb/DeviceManager.py +0 -0
  29. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
  30. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/adb/__init__.py +0 -0
  31. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/adb/bin/__init__.py +0 -0
  32. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/image/ImageCaptureMethod.py +0 -0
  33. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/image/__init__.py +0 -0
  34. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
  35. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/BitBltCaptureMethod.py +0 -0
  36. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
  37. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +0 -0
  38. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/__init__.py +0 -0
  39. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/d3d11.py +0 -0
  40. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/dump.py +0 -0
  41. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/utils.py +0 -0
  42. {ok-script-0.0.71 → ok-script-0.0.72}/ok/capture/windows/window.py +0 -0
  43. {ok-script-0.0.71 → ok-script-0.0.72}/ok/color/Color.py +0 -0
  44. {ok-script-0.0.71 → ok-script-0.0.72}/ok/color/__init__.py +0 -0
  45. {ok-script-0.0.71 → ok-script-0.0.72}/ok/config/Config.py +0 -0
  46. {ok-script-0.0.71 → ok-script-0.0.72}/ok/config/InfoDict.py +0 -0
  47. {ok-script-0.0.71 → ok-script-0.0.72}/ok/config/__init__.py +0 -0
  48. {ok-script-0.0.71 → ok-script-0.0.72}/ok/feature/FindFeature.py +0 -0
  49. {ok-script-0.0.71 → ok-script-0.0.72}/ok/feature/__init__.py +0 -0
  50. {ok-script-0.0.71 → ok-script-0.0.72}/ok/firebase/__init__.py +0 -0
  51. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/Communicate.py +0 -0
  52. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/MessageWindow.py +0 -0
  53. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/TabTitles.py +0 -0
  54. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/__init__.py +0 -0
  55. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/about/AboutTab.py +0 -0
  56. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/about/HttpTextEdit.py +0 -0
  57. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/about/VersionCard.py +0 -0
  58. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/about/__init__.py +0 -0
  59. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/common/OKIcon.py +0 -0
  60. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/common/__init__.py +0 -0
  61. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/common/config.py +0 -0
  62. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/common/style_sheet.py +0 -0
  63. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/debug/AspectRatioWidget.py +0 -0
  64. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/debug/DebugTab.py +0 -0
  65. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/debug/FrameWidget.py +0 -0
  66. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/debug/InfoWidget.py +0 -0
  67. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/debug/LoggerWidget.py +0 -0
  68. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/debug/Screenshot.py +0 -0
  69. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/debug/__init__.py +0 -0
  70. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/i18n/__init__.py +0 -0
  71. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/i18n/path.py +0 -0
  72. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/i18n/update.py +0 -0
  73. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/icon/__init__.py +0 -0
  74. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/icon/icon.py +0 -0
  75. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/overlay/OverlayWindow.py +0 -0
  76. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/overlay/__init__.py +0 -0
  77. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/qss/__init__.py +0 -0
  78. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/resources.py +0 -0
  79. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/settings/SettingTab.py +0 -0
  80. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/settings/__init__.py +0 -0
  81. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/start/SelectCaptureListView.py +0 -0
  82. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/start/StartCard.py +0 -0
  83. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/start/StartTab.py +0 -0
  84. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/start/__init__.py +0 -0
  85. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/ConfigItemFactory.py +0 -0
  86. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
  87. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
  88. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/LabelAndDropDown.py +0 -0
  89. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
  90. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/LabelAndList.py +0 -0
  91. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
  92. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
  93. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/LabelAndWidget.py +0 -0
  94. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/ModifyListDialog.py +0 -0
  95. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/ModifyListItem.py +0 -0
  96. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
  97. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/StartButton.py +0 -0
  98. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/TaskCard.py +0 -0
  99. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/TaskOpButton.py +0 -0
  100. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/TooltipTableWidget.py +0 -0
  101. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/TriggerTaskTab.py +0 -0
  102. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/tasks/__init__.py +0 -0
  103. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/util/Alert.py +0 -0
  104. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/util/InitWorker.py +0 -0
  105. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/util/__init__.py +0 -0
  106. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/Card.py +0 -0
  107. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/EmptyCard.py +0 -0
  108. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/FramelessDialog.py +0 -0
  109. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/ListTableWidgetItem.py +0 -0
  110. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
  111. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/StartLoadingDialog.py +0 -0
  112. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/StatusBar.py +0 -0
  113. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/Tab.py +0 -0
  114. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/TabWidget.py +0 -0
  115. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
  116. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/YesNonWidgetItem.py +0 -0
  117. {ok-script-0.0.71 → ok-script-0.0.72}/ok/gui/widget/__init__.py +0 -0
  118. {ok-script-0.0.71 → ok-script-0.0.72}/ok/interaction/ADBInteraction.py +0 -0
  119. {ok-script-0.0.71 → ok-script-0.0.72}/ok/interaction/BaseInteraction.py +0 -0
  120. {ok-script-0.0.71 → ok-script-0.0.72}/ok/interaction/DoNothingInteraction.py +0 -0
  121. {ok-script-0.0.71 → ok-script-0.0.72}/ok/interaction/Win32Interaction.py +0 -0
  122. {ok-script-0.0.71 → ok-script-0.0.72}/ok/interaction/__init__.py +0 -0
  123. {ok-script-0.0.71 → ok-script-0.0.72}/ok/logging/Logger.py +0 -0
  124. {ok-script-0.0.71 → ok-script-0.0.72}/ok/logging/__init__.py +0 -0
  125. {ok-script-0.0.71 → ok-script-0.0.72}/ok/ocr/__init__.py +0 -0
  126. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  127. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  128. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  129. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  130. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  131. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  132. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  133. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  134. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  135. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Media/__init__.py +0 -0
  136. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  137. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Security/__init__.py +0 -0
  138. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  139. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  140. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/Windows/__init__.py +0 -0
  141. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/__init__.py +0 -0
  142. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/delegate.py +0 -0
  143. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/export.py +0 -0
  144. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/idldsl.py +0 -0
  145. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/inspectable.py +0 -0
  146. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/roapi.py +0 -0
  147. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/types.py +0 -0
  148. {ok-script-0.0.71 → ok-script-0.0.72}/ok/rotypes/winstring.py +0 -0
  149. {ok-script-0.0.71 → ok-script-0.0.72}/ok/save/BlackBarProcessor.py +0 -0
  150. {ok-script-0.0.71 → ok-script-0.0.72}/ok/save/PostProcessor.py +0 -0
  151. {ok-script-0.0.71 → ok-script-0.0.72}/ok/save/SaveByInterval.py +0 -0
  152. {ok-script-0.0.71 → ok-script-0.0.72}/ok/save/SaveByKeyPress.py +0 -0
  153. {ok-script-0.0.71 → ok-script-0.0.72}/ok/save/SaveMethodBase.py +0 -0
  154. {ok-script-0.0.71 → ok-script-0.0.72}/ok/save/__init__.py +0 -0
  155. {ok-script-0.0.71 → ok-script-0.0.72}/ok/scene/FeatureScene.py +0 -0
  156. {ok-script-0.0.71 → ok-script-0.0.72}/ok/scene/Scene.py +0 -0
  157. {ok-script-0.0.71 → ok-script-0.0.72}/ok/scene/__init__.py +0 -0
  158. {ok-script-0.0.71 → ok-script-0.0.72}/ok/stats/StreamStats.py +0 -0
  159. {ok-script-0.0.71 → ok-script-0.0.72}/ok/stats/__init__.py +0 -0
  160. {ok-script-0.0.71 → ok-script-0.0.72}/ok/task/BaseTask.py +0 -0
  161. {ok-script-0.0.71 → ok-script-0.0.72}/ok/task/ExecutorOperation.py +0 -0
  162. {ok-script-0.0.71 → ok-script-0.0.72}/ok/task/OneTimeTask.py +0 -0
  163. {ok-script-0.0.71 → ok-script-0.0.72}/ok/task/TriggerTask.py +0 -0
  164. {ok-script-0.0.71 → ok-script-0.0.72}/ok/task/__init__.py +0 -0
  165. {ok-script-0.0.71 → ok-script-0.0.72}/ok/update/GithubMultiDownloader.py +0 -0
  166. {ok-script-0.0.71 → ok-script-0.0.72}/ok/update/Updater.py +0 -0
  167. {ok-script-0.0.71 → ok-script-0.0.72}/ok/update/__init__.py +0 -0
  168. {ok-script-0.0.71 → ok-script-0.0.72}/ok/update/gen_md5.py +0 -0
  169. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/Handler.py +0 -0
  170. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/__init__.py +0 -0
  171. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/exit_event.py +0 -0
  172. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/json.py +0 -0
  173. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/list.py +0 -0
  174. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/path.py +0 -0
  175. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/thread.py +0 -0
  176. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/win32_process.py +0 -0
  177. {ok-script-0.0.71 → ok-script-0.0.72}/ok/util/yaml.py +0 -0
  178. {ok-script-0.0.71 → ok-script-0.0.72}/ok_script.egg-info/dependency_links.txt +0 -0
  179. {ok-script-0.0.71 → ok-script-0.0.72}/ok_script.egg-info/requires.txt +0 -0
  180. {ok-script-0.0.71 → ok-script-0.0.72}/ok_script.egg-info/top_level.txt +0 -0
  181. {ok-script-0.0.71 → ok-script-0.0.72}/setup.cfg +0 -0
  182. {ok-script-0.0.71 → ok-script-0.0.72}/tests/__init__.py +0 -0
  183. {ok-script-0.0.71 → ok-script-0.0.72}/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.71
3
+ Version: 0.0.72
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
@@ -41,7 +41,6 @@ class OK:
41
41
  self.init_device_manager()
42
42
  from ok.gui.debug.Screenshot import Screenshot
43
43
  self.screenshot = Screenshot(self.exit_event)
44
- self.do_init()
45
44
  if config.get("use_gui"):
46
45
  from ok.gui.App import App
47
46
  self.app = App(config, self.exit_event)
@@ -49,6 +48,7 @@ class OK:
49
48
  else:
50
49
  self.device_manager.set_preferred_device()
51
50
  self.device_manager.start()
51
+ self.do_init()
52
52
  except Exception as e:
53
53
  logger.error(f'__init__ error', e)
54
54
  self.quit()
@@ -102,9 +102,9 @@ class OK:
102
102
 
103
103
  template_matching = self.config.get('template_matching')
104
104
  if template_matching is not None:
105
- coco_feature_folder = self.config.get('template_matching').get('coco_feature_folder')
105
+ coco_feature_json = self.config.get('template_matching').get('coco_feature_json')
106
106
  from ok.feature.FeatureSet import FeatureSet
107
- self.feature_set = FeatureSet(coco_feature_folder,
107
+ self.feature_set = FeatureSet(coco_feature_json,
108
108
  default_horizontal_variance=template_matching.get(
109
109
  'default_horizontal_variance', 0),
110
110
  default_vertical_variance=template_matching.get('default_vertical_variance',
@@ -6,12 +6,20 @@ from typing import List
6
6
 
7
7
 
8
8
  class Box:
9
- def __init__(self, x: int, y: int, width: int, height: int, confidence: float = 1, name=None) -> None:
9
+ def __init__(self, x: int | float, y: int | float, width: int | float = 0, height: int | float = 0,
10
+ confidence: float = 1,
11
+ name=None, to_x: int | float = -1, to_y: int | float = -1) -> None:
10
12
  self.name = name
11
13
  self.x = int(x)
12
14
  self.y = int(y)
13
- self.width = int(width)
14
- self.height = int(height)
15
+ if to_x != -1 and to_y != -1:
16
+ self.width = int(to_x - x)
17
+ self.height = int(to_y - y)
18
+ else:
19
+ self.width = int(width)
20
+ self.height = int(height)
21
+ if self.width <= 0 or self.height <= 0:
22
+ raise ValueError(f'width and height must be greater than zero {x} {y} {width} {height} {to_x} {to_y}')
15
23
  self.confidence = confidence
16
24
 
17
25
  def __eq__(self, other):
@@ -18,3 +18,6 @@ class Feature:
18
18
  self.y = y
19
19
  self.width = width
20
20
  self.height = height
21
+
22
+ def __str__(self) -> str:
23
+ return f'self.x: {self.x}, self.y: {self.y}, width: {self.width}, height: {self.height}'
@@ -21,19 +21,20 @@ class FeatureSet:
21
21
  feature_dict: Dict[str, Feature] = {}
22
22
  box_dict: Dict[str, Box] = {}
23
23
 
24
- def __init__(self, coco_folder: str, default_horizontal_variance=0,
24
+ def __init__(self, coco_json: str, default_horizontal_variance=0,
25
25
  default_vertical_variance=0, default_threshold=0.95) -> None:
26
26
  """
27
27
  Initialize the FeatureSet by loading images and annotations from a COCO dataset.
28
28
 
29
29
  Args:
30
- coco_folder (str): Directory containing the JSON file and images.
30
+ coco_json (str): Directory containing the JSON file and images.
31
31
  width (int): Scale images to this width.
32
32
  height (int): Scale images to this height.
33
33
  """
34
- self.coco_folder = resource_path(coco_folder)
34
+ self.coco_json = resource_path(coco_json)
35
+ self.coco_folder = os.path.dirname(self.coco_json)
35
36
 
36
- logger.debug(f'Loading features from {self.coco_folder}')
37
+ logger.debug(f'Loading features from {self.coco_json}')
37
38
 
38
39
  # Process images and annotations
39
40
  self.width = 0
@@ -62,8 +63,7 @@ class FeatureSet:
62
63
  """
63
64
  self.feature_dict.clear()
64
65
  self.box_dict.clear()
65
- json_path = os.path.join(self.coco_folder, '_annotations.coco.json')
66
- with open(json_path, 'r') as file:
66
+ with open(self.coco_json, 'r') as file:
67
67
  data = json.load(file)
68
68
 
69
69
  # Create a map from image ID to file name
@@ -78,7 +78,7 @@ class FeatureSet:
78
78
  bbox = annotation['bbox']
79
79
 
80
80
  # Load and scale the image
81
- image_path = f'{self.coco_folder}/{image_map[image_id]}'
81
+ image_path = str(os.path.join(self.coco_folder, image_map[image_id]))
82
82
  image = cv2.imread(image_path)
83
83
  _, original_width = image.shape[:2]
84
84
  if image is None:
@@ -168,7 +168,7 @@ class FeatureSet:
168
168
  if vertical_variance == 0:
169
169
  vertical_variance = self.default_vertical_variance
170
170
  if category_name not in self.feature_dict:
171
- raise ValueError(f"FeatureSet: {category_name} not found in featureDict")
171
+ raise ValueError(f"FeatureSet: " + category_name + " not found in featureDict")
172
172
  feature = self.feature_dict[category_name]
173
173
  feature_width, feature_height = feature.width, feature.height
174
174
  if x != -1 and y != -1:
@@ -0,0 +1,164 @@
1
+ import ctypes
2
+ import hashlib
3
+ import locale
4
+ import random
5
+ import uuid
6
+
7
+ import requests
8
+ import wmi
9
+
10
+ from ok.config.Config import Config
11
+ from ok.logging.Logger import get_logger
12
+ from ok.util.Handler import Handler
13
+
14
+ logger = get_logger(__name__)
15
+
16
+
17
+ class Analytics:
18
+ def __init__(self, app_config, exit_event):
19
+ self.report_url = app_config.get('analytics').get('report_url')
20
+ self.app_config = app_config
21
+ self._config = None
22
+ self._handler = Handler(exit_event, __name__)
23
+ self._handler.post(self.send_alive, 20)
24
+ self._user_properties = None
25
+ self._fv = 1
26
+
27
+ @property
28
+ def user_properties(self):
29
+ if self._user_properties is None:
30
+ c = wmi.WMI()
31
+
32
+ # Get OS information
33
+ os_info = c.Win32_OperatingSystem()[0]
34
+ os_version = os_info.Version.split(".")[0]
35
+ os_build = int(os_info.BuildNumber)
36
+
37
+ if os_version == "10" and os_build >= 22000: # Windows 11 starts from build 22000
38
+ os_version = "11"
39
+
40
+ # Get CPU information
41
+ cpu_info = c.Win32_Processor()[0]
42
+ cpu_name = cpu_info.Name.strip()
43
+
44
+ # Get total memory (in GB)
45
+ total_memory = float(os_info.TotalVisibleMemorySize) / 1048576 # KB to GB
46
+
47
+ # Get graphics card information
48
+ gpu_info = c.Win32_VideoController()
49
+ gpu_name = None
50
+ for gpu in reversed(gpu_info):
51
+ if "intel" not in gpu.Name.lower() and "microsoft" not in gpu.Name.lower():
52
+ gpu_name = gpu.Name
53
+ break
54
+ if not gpu_name and gpu_info:
55
+ gpu_name = gpu_info[0].Name
56
+
57
+ # Put the information into a dictionary
58
+ self._user_properties = {
59
+ "os": 'windows',
60
+ "os_version": os_version,
61
+ "os_build": os_build,
62
+ "cpu": cpu_name,
63
+ "memory": int(total_memory),
64
+ "gpu": gpu_name,
65
+ }
66
+ return self._user_properties
67
+
68
+ #
69
+ # def report_open(self):
70
+ # self._handler.post(self.send_gtag, 5)
71
+ # # self.send_event('app_open', {'version': self.app_config.get('version'), 'debug': self.app_config.get('debug')})
72
+
73
+ @property
74
+ def client_id(self):
75
+ if self._config is None:
76
+ self._config = Config({'client_id': ''}, self.app_config.get("config_folder") or "config", 'statistics')
77
+ if not self._config.get('client_id'):
78
+ self._config['client_id'] = self.get_unique_client_id()
79
+ else:
80
+ self._fv = 0
81
+ return self._config.get('client_id')
82
+
83
+ def send_alive(self):
84
+
85
+ params = {
86
+ "device_id": self.client_id,
87
+ "app_version": self.app_config.get('version'),
88
+ "app_name": self.app_config.get('app_id') or self.app_config.get('gui_title'),
89
+ 'locale': locale.getdefaultlocale()[0],
90
+ 'sr': get_screen_resolution(),
91
+ "os": 'windows',
92
+ }
93
+
94
+ params.update(self.user_properties)
95
+
96
+ logger.debug(f'send report {params}')
97
+
98
+ response = requests.post(self.report_url, json=params)
99
+
100
+ if response.status_code == 200:
101
+ logger.debug(f'Successfully send report')
102
+ else:
103
+ logger.debug(f'Failed to send event: {response.status_code} - {response.text}')
104
+
105
+ self._handler.post(self.send_alive, 3600)
106
+
107
+ def get_unique_client_id(self):
108
+ user_dict = self.user_properties.copy()
109
+ user_dict['mac'] = uuid.getnode()
110
+ del user_dict['os_build']
111
+ return hash_dict_keys_values(user_dict)
112
+
113
+
114
+ def get_bios_serial_number():
115
+ try:
116
+ c = wmi.WMI()
117
+ for bios in c.Win32_BIOS():
118
+ return bios.SerialNumber.strip()
119
+ except Exception as e:
120
+ print(f"Error retrieving BIOS serial number: {e}")
121
+ return None
122
+
123
+
124
+ def random_number():
125
+ return random.randint(0, 2147483647)
126
+
127
+
128
+ def get_screen_resolution():
129
+ user32 = ctypes.windll.user32
130
+ screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
131
+ return f"{screensize[0]}x{screensize[1]}"
132
+
133
+
134
+ def hash_dict_keys_values(my_dict):
135
+ # Sort the dictionary by keys
136
+ sorted_items = sorted(my_dict.items())
137
+
138
+ # Initialize an empty string to store concatenated key-value pairs
139
+ concatenated_kv = ''
140
+
141
+ # Concatenate sorted key-value pairs
142
+ for key, value in sorted_items:
143
+ concatenated_kv += f'{key}{value}'
144
+
145
+ # Encode the concatenated string
146
+ encoded_kv = concatenated_kv.encode()
147
+
148
+ # Create a new md5 hash object
149
+ hash_object = hashlib.md5(encoded_kv)
150
+
151
+ # Get the hexadecimal representation of the hash
152
+ hash_hex = hash_object.hexdigest()
153
+
154
+ return hash_hex
155
+
156
+
157
+ if __name__ == '__main__':
158
+ # Generate a unique client ID (UUID)
159
+ client_id = str(uuid.uuid4())
160
+ analytics = Analytics('G-9W3F3EQ19G', api_secret='eAkNmhrERiGg8Q3Riuxerw')
161
+ # Send a test event
162
+ analytics.send_event('app_open')
163
+ analytics.send_event('test1')
164
+ analytics.send_event('test2')
@@ -8,7 +8,7 @@ from qfluentwidgets import FluentTranslator, qconfig, Theme
8
8
 
9
9
  import ok
10
10
  import ok.gui.resources
11
- from ok.firebase.FireBaseAnalytics import FireBaseAnalytics
11
+ from ok.firebase.Analytics import Analytics
12
12
  from ok.gui.Communicate import communicate
13
13
  from ok.gui.MainWindow import MainWindow
14
14
  from ok.gui.MessageWindow import MessageWindow
@@ -49,8 +49,8 @@ class App:
49
49
  self.main_window = None
50
50
  self.exit_event = exit_event
51
51
  self.icon = QIcon(self.config.get('gui_icon') or ":/icon/icon.ico")
52
- if self.config.get('firebase'):
53
- self.fire_base_analytics = FireBaseAnalytics(self.config, self.exit_event)
52
+ if self.config.get('analytics'):
53
+ self.fire_base_analytics = Analytics(self.config, self.exit_event)
54
54
 
55
55
  translator = QTranslator(self.app)
56
56
  full_path = os.path.join(i18n_path, f"{self.locale.name()}")
@@ -1,3 +1,6 @@
1
+ import os
2
+ import sys
3
+
1
4
  from PySide6.QtCore import QObject, Signal, Qt
2
5
  from PySide6.QtGui import QKeySequence, QShortcut
3
6
  from PySide6.QtWidgets import QMenu, QSystemTrayIcon
@@ -58,7 +61,9 @@ class MainWindow(MSFluentWindow):
58
61
  self.addSubInterface(about_tab, FluentIcon.QUESTION, self.tr('About'),
59
62
  position=NavigationItemPosition.BOTTOM)
60
63
  # Styling the tabs and content if needed, for example:
61
- self.setWindowTitle(f'{title} {version}')
64
+ dev = self.tr('Debug')
65
+ release = self.tr('Release')
66
+ self.setWindowTitle(f'{title} {version} {dev if debug else release}')
62
67
 
63
68
  communicate.executor_paused.connect(self.executor_paused)
64
69
  communicate.tab.connect(self.navigate_tab)
@@ -162,12 +167,16 @@ class MainWindow(MSFluentWindow):
162
167
 
163
168
  def closeEvent(self, event):
164
169
  # Create a message box that asks the user if they really want to close the window
170
+ if sys.platform == 'win32' and 'shutdown' in os.environ.get('SESSIONNAME', '').lower():
171
+ event.accept()
172
+ return
173
+
174
+ # Your existing code for the message box
165
175
  if ok.gui.ok.exit_event.is_set():
166
176
  event.accept()
167
177
  return
168
178
  title = self.tr('Exit')
169
- content = self.tr(
170
- "Are you sure you want to exit the app?")
179
+ content = self.tr("Are you sure you want to exit the app?")
171
180
  w = MessageBox(title, content, self.window())
172
181
  if w.exec():
173
182
  logger.info("Window closed")
@@ -15,10 +15,8 @@ logger = get_logger(__name__)
15
15
  class StartController(QObject):
16
16
  def __init__(self, app_config, exit_event):
17
17
  super().__init__()
18
- self.executor = ok.gui.executor
19
18
  self.config = app_config
20
19
  self.exit_event = exit_event
21
- self.device_manager = ok.gui.device_manager
22
20
  self.handler = Handler(exit_event, __name__)
23
21
 
24
22
  def start(self, task=None):
@@ -26,18 +24,18 @@ class StartController(QObject):
26
24
 
27
25
  def do_start(self, task=None):
28
26
  communicate.starting_emulator.emit(False, None, 30)
29
- self.device_manager.do_refresh()
27
+ ok.gui.device_manager.do_refresh()
30
28
 
31
- device = self.device_manager.get_preferred_device()
29
+ device = ok.gui.device_manager.get_preferred_device()
32
30
 
33
31
  if device and not device['connected'] and device.get('full_path'):
34
- path = self.device_manager.get_exe_path(device)
32
+ path = ok.gui.device_manager.get_exe_path(device)
35
33
  if path:
36
34
  logger.info(f"starting game {path}")
37
35
  execute(path)
38
36
  wait_until = time.time() + 30
39
37
  while not self.exit_event.is_set():
40
- self.device_manager.do_refresh()
38
+ ok.gui.device_manager.do_refresh()
41
39
  error = self.check_device_error()
42
40
  if error is None:
43
41
  break
@@ -60,24 +58,24 @@ class StartController(QObject):
60
58
  if task:
61
59
  task.enable()
62
60
  task.unpause()
63
- self.executor.start()
61
+ ok.gui.executor.start()
64
62
  communicate.starting_emulator.emit(True, None, 0)
65
63
 
66
64
  def check_device_error(self):
67
- device = self.device_manager.get_preferred_device()
65
+ device = ok.gui.device_manager.get_preferred_device()
68
66
  if not device:
69
67
  return self.tr('No game selected!')
70
- if self.device_manager.capture_method is None:
68
+ if ok.gui.device_manager.capture_method is None:
71
69
  return self.tr("Selected capture method is not supported by the game or your system!")
72
- if not self.device_manager.device_connected():
73
- logger.error(f'Emulator is not connected {self.device_manager.device}')
70
+ if not ok.gui.device_manager.device_connected():
71
+ logger.error(f'Emulator is not connected {ok.gui.device_manager.device}')
74
72
  return self.tr("Emulator is not connected, start the emulator first!")
75
- if not self.device_manager.capture_method.connected():
76
- logger.error(f'Game window is not connected {self.device_manager.capture_method}')
73
+ if not ok.gui.device_manager.capture_method.connected():
74
+ logger.error(f'Game window is not connected {ok.gui.device_manager.capture_method}')
77
75
  return self.tr("Game window is not connected, please select the game window and capture method.")
78
76
  supported_ratio = self.config.get(
79
77
  'supported_screen_ratio')
80
- supported, resolution = self.executor.check_frame_and_resolution(supported_ratio)
78
+ supported, resolution = ok.gui.executor.check_frame_and_resolution(supported_ratio)
81
79
  if not supported:
82
80
  return self.tr(
83
81
  "Window resolution {resolution} is not supported, the supported ratio is {supported_ratio}, check if game windows is minimized, resized or out of screen.",
@@ -88,6 +86,6 @@ class StartController(QObject):
88
86
  if device and device['device'] == "adb" and self.config.get('adb'):
89
87
  packages = self.config.get('adb').get('packages')
90
88
  if packages:
91
- started = self.device_manager.adb_ensure_in_front(packages)
89
+ started = ok.gui.device_manager.adb_ensure_in_front(packages)
92
90
  if not started:
93
91
  return self.tr("Can't start game, make sure the game is installed")
@@ -1,4 +1,5 @@
1
1
  import time
2
+ from typing import List, Pattern
2
3
 
3
4
  import cv2
4
5
 
@@ -14,7 +15,9 @@ class OCR:
14
15
  ocr_default_threshold = 0.5
15
16
  ocr_target_height = 0
16
17
 
17
- def ocr(self, x=0, y=0, to_x=1, to_y=1, width=0, height=0, box: Box = None, name=None, match=None, threshold=0,
18
+ def ocr(self, x=0, y=0, to_x=1, to_y=1, match: str | List[str] | Pattern[str] | List[Pattern[str]] | None = None,
19
+ width=0, height=0, box: Box = None, name=None,
20
+ threshold=0,
18
21
  frame=None, target_height=0):
19
22
  if hasattr(self, 'paused') and self.paused:
20
23
  self.sleep(1)
@@ -72,7 +75,8 @@ class OCR:
72
75
  f"ocr_zone {box} found result: {len(detected_boxes)}) time: {(time.time() - start):.2f} scale_factor: {scale_factor:.2f}")
73
76
  return sort_boxes(detected_boxes)
74
77
 
75
- def wait_click_ocr(self, x=0, y=0, to_x=1, to_y=1, width=0, height=0, box=None, name=None, match=None, threshold=0,
78
+ def wait_click_ocr(self, x=0, y=0, to_x=1, to_y=1, width=0, height=0, box=None, name=None,
79
+ match: str | List[str] | Pattern[str] | List[Pattern[str]] | None = None, threshold=0,
76
80
  frame=None, target_height=0, time_out=0):
77
81
  box = self.wait_ocr(x, y, width=width, height=height, to_x=to_x, to_y=to_y, box=box, name=name, match=match,
78
82
  threshold=threshold,
@@ -83,7 +87,8 @@ class OCR:
83
87
  else:
84
88
  logger.error(f'wait ocr no box {x} {y} {width} {height} {to_x} {to_y} {match}')
85
89
 
86
- def wait_ocr(self, x=0, y=0, to_x=1, to_y=1, width=0, height=0, name=None, box=None, match=None, threshold=0,
90
+ def wait_ocr(self, x=0, y=0, to_x=1, to_y=1, width=0, height=0, name=None, box=None,
91
+ match: str | List[str] | Pattern[str] | List[Pattern[str]] | None = None, threshold=0,
87
92
  frame=None, target_height=0, time_out=0):
88
93
  return self.wait_until(lambda:
89
94
  self.ocr(x, y, to_x=to_x, to_y=to_y, width=width, height=height, box=box, name=name,
@@ -186,15 +186,14 @@ class TaskExecutor:
186
186
  if pre_action is not None:
187
187
  pre_action()
188
188
  self.sleep(wait_until_before_delay)
189
- self._frame = self.next_frame()
190
- if self._frame is not None:
191
- result = condition()
192
- self.add_frame_stats()
193
- result_str = list_or_obj_to_str(result)
194
- if result:
195
- logger.debug(f"found result {result_str}")
196
- self.sleep(self.wait_until_check_delay)
197
- return result
189
+ self.next_frame()
190
+ result = condition()
191
+ self.add_frame_stats()
192
+ result_str = list_or_obj_to_str(result)
193
+ if result:
194
+ logger.debug(f"found result {result_str}")
195
+ self.sleep(self.wait_until_check_delay)
196
+ return result
198
197
  if post_action is not None:
199
198
  post_action()
200
199
  if time.time() - start > time_out:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ok-script
3
- Version: 0.0.71
3
+ Version: 0.0.72
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
@@ -37,7 +37,7 @@ ok/feature/Feature.py
37
37
  ok/feature/FeatureSet.py
38
38
  ok/feature/FindFeature.py
39
39
  ok/feature/__init__.py
40
- ok/firebase/FireBaseAnalytics.py
40
+ ok/firebase/Analytics.py
41
41
  ok/firebase/__init__.py
42
42
  ok/gui/App.py
43
43
  ok/gui/Communicate.py
@@ -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.71",
8
+ version="0.0.72",
9
9
  author="ok-oldking",
10
10
  author_email="firedcto@gmail.com",
11
11
  description="Automation with Computer Vision for Python",