ok-script 0.0.50__tar.gz → 0.0.52__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 (173) hide show
  1. {ok-script-0.0.50 → ok-script-0.0.52}/PKG-INFO +1 -1
  2. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/BaseCaptureMethod.py +14 -4
  3. {ok-script-0.0.50 → ok-script-0.0.52}/ok/color/Color.py +3 -2
  4. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/App.py +7 -4
  5. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/Communicate.py +3 -2
  6. ok-script-0.0.52/ok/gui/about/AboutTab.py +157 -0
  7. ok-script-0.0.52/ok/gui/about/HttpTextEdit.py +22 -0
  8. ok-script-0.0.52/ok/gui/about/VersionCard.py +72 -0
  9. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/resources.py +530 -465
  10. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/LabelAndDropDown.py +3 -0
  11. ok-script-0.0.52/ok/gui/widget/EmptyCard.py +14 -0
  12. ok-script-0.0.52/ok/update/GithubMultiDownloader.py +176 -0
  13. {ok-script-0.0.50 → ok-script-0.0.52}/ok/update/Updater.py +171 -58
  14. {ok-script-0.0.50 → ok-script-0.0.52}/ok_script.egg-info/PKG-INFO +1 -1
  15. {ok-script-0.0.50 → ok-script-0.0.52}/ok_script.egg-info/SOURCES.txt +3 -0
  16. {ok-script-0.0.50 → ok-script-0.0.52}/setup.py +1 -1
  17. ok-script-0.0.50/ok/gui/about/AboutTab.py +0 -135
  18. ok-script-0.0.50/ok/gui/about/VersionCard.py +0 -40
  19. {ok-script-0.0.50 → ok-script-0.0.52}/README.md +0 -0
  20. {ok-script-0.0.50 → ok-script-0.0.52}/ok/OK.py +0 -0
  21. {ok-script-0.0.50 → ok-script-0.0.52}/ok/__init__.py +0 -0
  22. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/HwndWindow.py +0 -0
  23. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/__init__.py +0 -0
  24. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/adb/ADBCaptureMethod.py +0 -0
  25. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/adb/DeviceManager.py +0 -0
  26. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
  27. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/adb/__init__.py +0 -0
  28. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/adb/bin/__init__.py +0 -0
  29. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/adb/targets.py +0 -0
  30. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/adb/vbox.py +0 -0
  31. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
  32. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/BitBltCaptureMethod.py +0 -0
  33. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
  34. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +0 -0
  35. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/__init__.py +0 -0
  36. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/d3d11.py +0 -0
  37. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/dump.py +0 -0
  38. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/utils.py +0 -0
  39. {ok-script-0.0.50 → ok-script-0.0.52}/ok/capture/windows/window.py +0 -0
  40. {ok-script-0.0.50 → ok-script-0.0.52}/ok/color/__init__.py +0 -0
  41. {ok-script-0.0.50 → ok-script-0.0.52}/ok/config/Config.py +0 -0
  42. {ok-script-0.0.50 → ok-script-0.0.52}/ok/config/InfoDict.py +0 -0
  43. {ok-script-0.0.50 → ok-script-0.0.52}/ok/config/__init__.py +0 -0
  44. {ok-script-0.0.50 → ok-script-0.0.52}/ok/feature/Box.py +0 -0
  45. {ok-script-0.0.50 → ok-script-0.0.52}/ok/feature/Feature.py +0 -0
  46. {ok-script-0.0.50 → ok-script-0.0.52}/ok/feature/FeatureSet.py +0 -0
  47. {ok-script-0.0.50 → ok-script-0.0.52}/ok/feature/FindFeature.py +0 -0
  48. {ok-script-0.0.50 → ok-script-0.0.52}/ok/feature/__init__.py +0 -0
  49. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/MainWindow.py +0 -0
  50. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/MessageWindow.py +0 -0
  51. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/TabTitles.py +0 -0
  52. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/__init__.py +0 -0
  53. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/about/__init__.py +0 -0
  54. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/common/OKIcon.py +0 -0
  55. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/common/__init__.py +0 -0
  56. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/common/config.py +0 -0
  57. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/common/style_sheet.py +0 -0
  58. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/debug/AspectRatioWidget.py +0 -0
  59. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/debug/DebugTab.py +0 -0
  60. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/debug/FrameWidget.py +0 -0
  61. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/debug/InfoWidget.py +0 -0
  62. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/debug/LoggerWidget.py +0 -0
  63. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/debug/Screenshot.py +0 -0
  64. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/debug/__init__.py +0 -0
  65. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/i18n/__init__.py +0 -0
  66. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/i18n/path.py +0 -0
  67. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/i18n/update.py +0 -0
  68. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/icon/__init__.py +0 -0
  69. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/icon/icon.py +0 -0
  70. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/overlay/OverlayWindow.py +0 -0
  71. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/overlay/__init__.py +0 -0
  72. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/qss/__init__.py +0 -0
  73. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/settings/SettingTab.py +0 -0
  74. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/settings/__init__.py +0 -0
  75. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/start/SelectCaptureListView.py +0 -0
  76. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/start/SelectHwndWindow.py +0 -0
  77. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/start/StartCard.py +0 -0
  78. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/start/StartTab.py +0 -0
  79. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/start/__init__.py +0 -0
  80. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/ConfigItemFactory.py +0 -0
  81. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
  82. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
  83. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
  84. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/LabelAndList.py +0 -0
  85. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
  86. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
  87. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/LabelAndWidget.py +0 -0
  88. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/ModifyListDialog.py +0 -0
  89. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/ModifyListItem.py +0 -0
  90. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
  91. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/StartButton.py +0 -0
  92. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/TaskCard.py +0 -0
  93. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/TaskOpButton.py +0 -0
  94. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/TooltipTableWidget.py +0 -0
  95. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/TriggerTaskTab.py +0 -0
  96. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/tasks/__init__.py +0 -0
  97. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/util/Alert.py +0 -0
  98. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/util/InitWorker.py +0 -0
  99. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/util/__init__.py +0 -0
  100. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/Card.py +0 -0
  101. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/FramelessDialog.py +0 -0
  102. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/ListTableWidgetItem.py +0 -0
  103. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
  104. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/StatusBar.py +0 -0
  105. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/Tab.py +0 -0
  106. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/TabWidget.py +0 -0
  107. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
  108. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/YesNonWidgetItem.py +0 -0
  109. {ok-script-0.0.50 → ok-script-0.0.52}/ok/gui/widget/__init__.py +0 -0
  110. {ok-script-0.0.50 → ok-script-0.0.52}/ok/interaction/ADBInteraction.py +0 -0
  111. {ok-script-0.0.50 → ok-script-0.0.52}/ok/interaction/BaseInteraction.py +0 -0
  112. {ok-script-0.0.50 → ok-script-0.0.52}/ok/interaction/Win32Interaction.py +0 -0
  113. {ok-script-0.0.50 → ok-script-0.0.52}/ok/interaction/__init__.py +0 -0
  114. {ok-script-0.0.50 → ok-script-0.0.52}/ok/logging/Logger.py +0 -0
  115. {ok-script-0.0.50 → ok-script-0.0.52}/ok/logging/__init__.py +0 -0
  116. {ok-script-0.0.50 → ok-script-0.0.52}/ok/ocr/OCR.py +0 -0
  117. {ok-script-0.0.50 → ok-script-0.0.52}/ok/ocr/__init__.py +0 -0
  118. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  119. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  120. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  121. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  122. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  123. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  124. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  125. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  126. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  127. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Media/__init__.py +0 -0
  128. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  129. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Security/__init__.py +0 -0
  130. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  131. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  132. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/Windows/__init__.py +0 -0
  133. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/__init__.py +0 -0
  134. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/delegate.py +0 -0
  135. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/export.py +0 -0
  136. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/idldsl.py +0 -0
  137. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/inspectable.py +0 -0
  138. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/roapi.py +0 -0
  139. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/types.py +0 -0
  140. {ok-script-0.0.50 → ok-script-0.0.52}/ok/rotypes/winstring.py +0 -0
  141. {ok-script-0.0.50 → ok-script-0.0.52}/ok/save/BlackBarProcessor.py +0 -0
  142. {ok-script-0.0.50 → ok-script-0.0.52}/ok/save/PostProcessor.py +0 -0
  143. {ok-script-0.0.50 → ok-script-0.0.52}/ok/save/SaveByInterval.py +0 -0
  144. {ok-script-0.0.50 → ok-script-0.0.52}/ok/save/SaveByKeyPress.py +0 -0
  145. {ok-script-0.0.50 → ok-script-0.0.52}/ok/save/SaveMethodBase.py +0 -0
  146. {ok-script-0.0.50 → ok-script-0.0.52}/ok/save/__init__.py +0 -0
  147. {ok-script-0.0.50 → ok-script-0.0.52}/ok/scene/FeatureScene.py +0 -0
  148. {ok-script-0.0.50 → ok-script-0.0.52}/ok/scene/Scene.py +0 -0
  149. {ok-script-0.0.50 → ok-script-0.0.52}/ok/scene/__init__.py +0 -0
  150. {ok-script-0.0.50 → ok-script-0.0.52}/ok/stats/StreamStats.py +0 -0
  151. {ok-script-0.0.50 → ok-script-0.0.52}/ok/stats/__init__.py +0 -0
  152. {ok-script-0.0.50 → ok-script-0.0.52}/ok/task/BaseTask.py +0 -0
  153. {ok-script-0.0.50 → ok-script-0.0.52}/ok/task/ExecutorOperation.py +0 -0
  154. {ok-script-0.0.50 → ok-script-0.0.52}/ok/task/OneTimeTask.py +0 -0
  155. {ok-script-0.0.50 → ok-script-0.0.52}/ok/task/TaskExecutor.py +0 -0
  156. {ok-script-0.0.50 → ok-script-0.0.52}/ok/task/TriggerTask.py +0 -0
  157. {ok-script-0.0.50 → ok-script-0.0.52}/ok/task/__init__.py +0 -0
  158. {ok-script-0.0.50 → ok-script-0.0.52}/ok/update/__init__.py +0 -0
  159. {ok-script-0.0.50 → ok-script-0.0.52}/ok/update/gen_md5.py +0 -0
  160. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/__init__.py +0 -0
  161. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/exit_event.py +0 -0
  162. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/json.py +0 -0
  163. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/list.py +0 -0
  164. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/path.py +0 -0
  165. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/thread.py +0 -0
  166. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/win32_process.py +0 -0
  167. {ok-script-0.0.50 → ok-script-0.0.52}/ok/util/yaml.py +0 -0
  168. {ok-script-0.0.50 → ok-script-0.0.52}/ok_script.egg-info/dependency_links.txt +0 -0
  169. {ok-script-0.0.50 → ok-script-0.0.52}/ok_script.egg-info/requires.txt +0 -0
  170. {ok-script-0.0.50 → ok-script-0.0.52}/ok_script.egg-info/top_level.txt +0 -0
  171. {ok-script-0.0.50 → ok-script-0.0.52}/setup.cfg +0 -0
  172. {ok-script-0.0.50 → ok-script-0.0.52}/tests/__init__.py +0 -0
  173. {ok-script-0.0.50 → ok-script-0.0.52}/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.50
3
+ Version: 0.0.52
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
@@ -1,5 +1,9 @@
1
1
  import numpy as np
2
2
 
3
+ from ok.logging.Logger import get_logger
4
+
5
+ logger = get_logger(__name__)
6
+
3
7
 
4
8
  class CaptureException(Exception):
5
9
  pass
@@ -21,13 +25,19 @@ class BaseCaptureMethod:
21
25
  @property
22
26
  def width(self):
23
27
  if self._size[0] == 0:
24
- self.get_frame()
28
+ try:
29
+ self.get_frame()
30
+ except Exception as e:
31
+ logger.error('get frame error')
25
32
  return self._size[0]
26
33
 
27
34
  @property
28
35
  def height(self):
29
36
  if self._size[1] == 0:
30
- self.get_frame()
37
+ try:
38
+ self.get_frame()
39
+ except Exception as e:
40
+ logger.error('get frame error')
31
41
  return self._size[1]
32
42
 
33
43
  def get_frame(self) -> np.ndarray | None:
@@ -35,8 +45,8 @@ class BaseCaptureMethod:
35
45
  frame = self.do_get_frame()
36
46
  if frame is not None:
37
47
  self._size = (frame.shape[1], frame.shape[0])
38
- if frame.shape[2] == 4:
39
- frame = frame[:, :, :3]
48
+ if frame.shape[2] == 4:
49
+ frame = frame[:, :, :3]
40
50
  return frame
41
51
  except Exception as e:
42
52
  raise CaptureException() from e
@@ -17,8 +17,9 @@ def calculate_color_percentage(image, color_ranges, box=None):
17
17
  # Check if the ROI is within the image bounds
18
18
  if box is not None:
19
19
  if (box.x >= 0 and box.y >= 0 and
20
- box.x + box.width <= image.shape[1] and # image.shape[1] is the width of the image
21
- box.y + box.height <= image.shape[0]): # image.shape[0] is the height of the image
20
+ box.x + box.width <= image.shape[1] and # image.shape[1] is the width of the image
21
+ box.y + box.height <= image.shape[
22
+ 0]) and box.width > 0 and box.height > 0: # image.shape[0] is the height of the image
22
23
 
23
24
  # Extract the region of interest (ROI) using slicing
24
25
 
@@ -8,6 +8,7 @@ from qfluentwidgets import FluentTranslator, qconfig, Theme
8
8
 
9
9
  import ok
10
10
  import ok.gui.resources
11
+ from ok.gui.Communicate import communicate
11
12
  from ok.gui.MainWindow import MainWindow
12
13
  from ok.gui.MessageWindow import MessageWindow
13
14
  from ok.gui.i18n.path import i18n_path
@@ -30,11 +31,10 @@ class App:
30
31
  QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
31
32
 
32
33
  self.app = QApplication(sys.argv)
34
+ communicate.quit.connect(self.app.quit)
33
35
  self.app.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings)
34
36
  qconfig.theme = Theme.AUTO
35
37
 
36
- self.updater = Updater(self.config, exit_event)
37
-
38
38
  self.about = self.config.get('about')
39
39
  self.title = self.config.get('gui_title')
40
40
  self.version = self.config.get('version')
@@ -58,6 +58,8 @@ class App:
58
58
  else:
59
59
  logger.debug(f"No translation available for {self.locale}, falling back to English/default. {full_path}")
60
60
 
61
+ self.updater = Updater(self.config, exit_event)
62
+
61
63
  def center_window(self, window):
62
64
  screen = self.app.primaryScreen()
63
65
  size = screen.size()
@@ -108,5 +110,6 @@ class App:
108
110
  def exec(self):
109
111
  sys.exit(self.app.exec())
110
112
 
111
- def quit(self):
112
- self.app.quit()
113
+ @staticmethod
114
+ def quit():
115
+ communicate.quit.emit()
@@ -20,8 +20,9 @@ class Communicate(QObject):
20
20
  config_validation: Signal = Signal(str)
21
21
  tab = Signal(str)
22
22
  capture_error = Signal()
23
- check_update = Signal()
24
- download_update = Signal(float, str, str, bool)
23
+ check_update = Signal(str)
24
+ download_update = Signal(float, str, bool, str)
25
+ quit = Signal()
25
26
 
26
27
  def emit_draw_box(self, key: str = None, boxes=None, color=None, frame=None):
27
28
  self.draw_box.emit(key, boxes, color, frame)
@@ -0,0 +1,157 @@
1
+ from PySide6.QtCore import Qt
2
+ from PySide6.QtWidgets import QHBoxLayout, QLabel
3
+ from qfluentwidgets import PushButton, InfoBar, InfoBarPosition, MessageBox
4
+
5
+ import ok.gui
6
+ from ok.capture.windows.dump import dump_threads
7
+ from ok.gui.Communicate import communicate
8
+ from ok.gui.about.VersionCard import VersionCard
9
+ from ok.gui.widget.Tab import Tab
10
+ from ok.logging.Logger import get_logger
11
+
12
+ logger = get_logger(__name__)
13
+
14
+
15
+ class AboutTab(Tab):
16
+ def __init__(self, icon, title, version, about):
17
+ super().__init__()
18
+ self.version_card = VersionCard(icon, title, version, self)
19
+ # Create a QTextEdit instance
20
+ self.addWidget(self.version_card)
21
+ if ok.gui.app.updater.enabled():
22
+ self.download_latest_button = PushButton(self.tr('Download'))
23
+ self.download_latest_button.clicked.connect(self.download_latest)
24
+
25
+ self.latest_hbox = QHBoxLayout()
26
+ self.addLayout(self.latest_hbox)
27
+ self.latest_label = QLabel()
28
+ self.latest_label.setWordWrap(True)
29
+ self.latest_hbox.addWidget(self.latest_label, stretch=1)
30
+ self.latest_hbox.addWidget(self.download_latest_button, stretch=0)
31
+
32
+ self.download_stable_button = PushButton(self.tr('Download'))
33
+ self.download_stable_button.resize(self.download_stable_button.sizeHint())
34
+ self.download_stable_button.clicked.connect(self.download_stable)
35
+ self.stable_hbox = QHBoxLayout()
36
+ self.stable_label = QLabel()
37
+ self.stable_label.setWordWrap(True)
38
+ self.addLayout(self.stable_hbox)
39
+ self.stable_hbox.addWidget(self.stable_label, stretch=1)
40
+ self.stable_hbox.addWidget(self.download_stable_button, stretch=0)
41
+
42
+ communicate.download_update.connect(self.download_update)
43
+
44
+ self.update_update_buttons(0)
45
+ about_label = QLabel()
46
+ about_label.setText(about)
47
+ about_label.setWordWrap(True)
48
+ about_label.setOpenExternalLinks(True)
49
+
50
+ # Set the layout on the widget
51
+ self.addWidget(about_label)
52
+ if ok.gui.ok.debug:
53
+ dump_button = PushButton(self.tr("Dump Threads(HotKey:Ctrl+Alt+D)"))
54
+ dump_button.clicked.connect(dump_threads)
55
+ self.addWidget(dump_button)
56
+
57
+ def update_update_buttons(self, percent, progress=""):
58
+ if ok.gui.app.updater.latest_release:
59
+ self.latest_label.setText(self.get_version_text(ok.gui.app.updater.latest_release))
60
+ self.download_latest_button.show()
61
+ self.latest_label.show()
62
+ else:
63
+ self.latest_label.hide()
64
+ self.download_latest_button.hide()
65
+ if ok.gui.app.updater.stable_release:
66
+ self.stable_label.setText(self.get_version_text(ok.gui.app.updater.stable_release))
67
+ self.stable_label.show()
68
+ self.download_stable_button.show()
69
+ else:
70
+ self.stable_label.hide()
71
+ self.download_stable_button.hide()
72
+
73
+ if ok.gui.app.updater.downloading:
74
+ self.download_latest_button.setDisabled(True)
75
+ self.download_stable_button.setDisabled(True)
76
+ else:
77
+ self.download_latest_button.setDisabled(False)
78
+ self.download_stable_button.setDisabled(False)
79
+
80
+ if ok.gui.app.updater.to_update:
81
+ if ok.gui.app.updater.to_update.get('release') == ok.gui.app.updater.latest_release:
82
+ self.download_latest_button.setText(self.tr('Update'))
83
+ else:
84
+ self.download_stable_button.setText(self.tr('Update'))
85
+ else:
86
+ self.download_latest_button.setText(self.tr('Download'))
87
+ self.download_stable_button.setText(self.tr('Download'))
88
+
89
+ def get_version_text(self, release):
90
+ text = "<h3>{title}: {version} ({size})</h3>"
91
+ if release.get('prerelease'):
92
+ title = self.tr('Beta Version')
93
+ else:
94
+ title = self.tr('Release Version')
95
+ text = text.format(title=title, version=release.get('version'), size=release.get('readable_size'))
96
+ text += "<p>{date}</p>".format(date=release.get('date'))
97
+ text += "<p>{notes}</p>".format(notes=text_to_html_paragraphs(release.get('notes')))
98
+ return text
99
+
100
+ def do_update(self):
101
+ ok.gui.app.updater.async_run(lambda: ok.gui.app.updater.update())
102
+
103
+ def download_update(self, percent, progress, done, error):
104
+ message = ""
105
+ if done:
106
+ if error:
107
+ title = self.tr('Download Error:')
108
+ message = error
109
+ InfoBar.error(
110
+ title=title,
111
+ content=message,
112
+ orient=Qt.Horizontal,
113
+ isClosable=True,
114
+ position=InfoBarPosition.TOP,
115
+ duration=5000, # won't disappear automatically
116
+ parent=self
117
+ )
118
+ else:
119
+ self.show_update_dialog()
120
+
121
+ self.update_update_buttons(percent, progress)
122
+
123
+ def show_update_dialog(self):
124
+ title = self.tr('Update Now')
125
+ content = self.tr(
126
+ "Are you sure you want to update to {version}?".format(
127
+ version=ok.gui.app.updater.to_update.get(
128
+ 'version'))) + '\n\n' + ok.gui.app.updater.to_update.get(
129
+ 'notes')
130
+
131
+ w = MessageBox(title, content, self.window())
132
+ w.setContentCopyable(True)
133
+ if w.exec():
134
+ logger.info("user click update")
135
+ self.do_update()
136
+
137
+ def download_latest(self):
138
+ if ok.gui.app.updater.to_update and ok.gui.app.updater.to_update.get(
139
+ 'release') == ok.gui.app.updater.latest_release:
140
+ self.show_update_dialog()
141
+ else:
142
+ ok.gui.app.updater.async_run(lambda: ok.gui.app.updater.download(ok.gui.app.updater.latest_release))
143
+
144
+ def download_stable(self):
145
+ if ok.gui.app.updater.to_update and ok.gui.app.updater.to_update.get(
146
+ 'release') == ok.gui.app.updater.stable_release:
147
+ self.show_update_dialog()
148
+ else:
149
+ ok.gui.app.updater.async_run(lambda: ok.gui.app.updater.download(ok.gui.app.updater.stable_release))
150
+
151
+
152
+ def text_to_html_paragraphs(text):
153
+ # Split the text into lines
154
+ lines = text.split('\n')
155
+
156
+ # Wrap each line in a <p> tag and join them
157
+ return ''.join(f'<p>{line}</p>' for line in lines)
@@ -0,0 +1,22 @@
1
+ from PySide6.QtCore import Qt
2
+ from PySide6.QtWidgets import QApplication
3
+ from qfluentwidgets import TextEdit
4
+
5
+
6
+ class VersionCard(TextEdit):
7
+ """ Sample card """
8
+
9
+ def __init__(self, parent=None):
10
+ super().__init__(parent)
11
+ self.anchor = None
12
+
13
+ def mousePressEvent(self, e):
14
+ self.anchor = self.anchorAt(e.pos())
15
+ if self.anchor:
16
+ QApplication.setOverrideCursor(Qt.PointingHandCursor)
17
+
18
+ def mouseReleaseEvent(self, e):
19
+ if self.anchor:
20
+ QDesktopServices.openUrl(QUrl(self.anchor))
21
+ QApplication.setOverrideCursor(Qt.ArrowCursor)
22
+ self.anchor = None
@@ -0,0 +1,72 @@
1
+ from PySide6.QtCore import Qt
2
+ from PySide6.QtWidgets import QLabel
3
+ from qfluentwidgets import SettingCard, PushButton, ProgressBar, InfoBar, InfoBarPosition
4
+
5
+ import ok
6
+ from ok.gui.Communicate import communicate
7
+
8
+
9
+ class VersionCard(SettingCard):
10
+ """ Sample card """
11
+
12
+ def __init__(self, icon, title, version, parent=None):
13
+ super().__init__(icon, title, version)
14
+ self.downloading_text = QLabel()
15
+ self.hBoxLayout.addWidget(self.downloading_text)
16
+ self.hBoxLayout.addSpacing(16)
17
+
18
+ self.download_bar = ProgressBar(self)
19
+ self.download_bar.setFixedWidth(80)
20
+ self.download_bar.setFixedHeight(6)
21
+ self.hBoxLayout.addWidget(self.download_bar)
22
+ self.hBoxLayout.addSpacing(16)
23
+
24
+ self.check_update_button = PushButton(self.tr("Check for updates"))
25
+ self.check_update_button.clicked.connect(self.check_update)
26
+ self.hBoxLayout.addWidget(self.check_update_button)
27
+ self.hBoxLayout.addSpacing(16)
28
+ self.update_buttons(0, "")
29
+ communicate.check_update.connect(self.update_update)
30
+ communicate.download_update.connect(self.download_update)
31
+
32
+ def download_update(self, percent, progress, done, error):
33
+ self.update_buttons(percent, progress)
34
+
35
+ def update_buttons(self, percent, progress):
36
+ if ok.gui.app.updater.downloading:
37
+ self.downloading_text.show()
38
+ self.downloading_text.setText(
39
+ self.tr('Downloading {progress} {percent}%').format(progress=progress, percent=format(percent, '.1f')))
40
+ self.download_bar.show()
41
+ self.download_bar.setValue(percent)
42
+ else:
43
+ self.downloading_text.hide()
44
+ self.download_bar.hide()
45
+
46
+ def update_update(self, error):
47
+ title = self.tr('Info')
48
+ if ok.gui.app.updater.latest_release or ok.gui.app.updater.stable_release:
49
+ bar = InfoBar.info
50
+ message = self.tr('Found new version!')
51
+ elif error:
52
+ bar = InfoBar.error
53
+ title = self.tr('Check for update error!')
54
+ message = error
55
+ else:
56
+ bar = InfoBar.info
57
+ message = self.tr("This is the newest version!")
58
+ bar(
59
+ title=title,
60
+ content=message,
61
+ orient=Qt.Horizontal,
62
+ isClosable=True,
63
+ position=InfoBarPosition.TOP,
64
+ duration=5000, # won't disappear automatically
65
+ parent=self
66
+ )
67
+ self.check_update_button.setEnabled(True)
68
+
69
+ def check_update(self):
70
+ ok.gui.app.updater.async_run(lambda: ok.gui.app.updater.check_for_updates())
71
+ self.check_update_button.setText(self.tr("Checking for updates"))
72
+ self.check_update_button.setEnabled(False)