ok-script 0.0.49__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.
- {ok-script-0.0.49 → ok-script-0.0.52}/PKG-INFO +2 -1
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/BaseCaptureMethod.py +14 -4
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/adb/DeviceManager.py +3 -4
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/color/Color.py +3 -2
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/App.py +11 -4
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/Communicate.py +3 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/MainWindow.py +3 -3
- ok-script-0.0.52/ok/gui/about/AboutTab.py +157 -0
- ok-script-0.0.52/ok/gui/about/HttpTextEdit.py +22 -0
- ok-script-0.0.52/ok/gui/about/VersionCard.py +72 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/resources.py +530 -465
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/start/SelectCaptureListView.py +5 -7
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/LabelAndDropDown.py +3 -0
- ok-script-0.0.52/ok/gui/widget/EmptyCard.py +14 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/Tab.py +7 -3
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/task/TaskExecutor.py +8 -2
- ok-script-0.0.52/ok/update/GithubMultiDownloader.py +176 -0
- ok-script-0.0.52/ok/update/Updater.py +364 -0
- ok-script-0.0.52/ok/update/gen_md5.py +23 -0
- ok-script-0.0.52/ok/util/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/util/path.py +46 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok_script.egg-info/PKG-INFO +2 -1
- {ok-script-0.0.49 → ok-script-0.0.52}/ok_script.egg-info/SOURCES.txt +10 -1
- {ok-script-0.0.49 → ok-script-0.0.52}/ok_script.egg-info/requires.txt +1 -0
- ok-script-0.0.52/ok_script.egg-info/top_level.txt +2 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/setup.py +3 -2
- ok-script-0.0.52/tests/__init__.py +3 -0
- ok-script-0.0.52/tests/test_updater.py +25 -0
- ok-script-0.0.49/ok/gui/about/AboutTab.py +0 -24
- ok-script-0.0.49/ok_script.egg-info/top_level.txt +0 -1
- {ok-script-0.0.49 → ok-script-0.0.52}/README.md +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/OK.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/HwndWindow.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/adb/ADBCaptureMethod.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/adb/WindowsCaptureFactory.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/adb/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/adb/bin/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/adb/targets.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/adb/vbox.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/BaseWindowsCaptureMethod.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/BitBltCaptureMethod.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/DesktopDuplicationCaptureMethod.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/d3d11.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/dump.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/utils.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/capture/windows/window.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/color/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/config/Config.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/config/InfoDict.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/config/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/feature/Box.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/feature/Feature.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/feature/FeatureSet.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/feature/FindFeature.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/feature/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/MessageWindow.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/TabTitles.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/about/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/common/OKIcon.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/common/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/common/config.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/common/style_sheet.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/debug/AspectRatioWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/debug/DebugTab.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/debug/FrameWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/debug/InfoWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/debug/LoggerWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/debug/Screenshot.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/debug/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/i18n/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/i18n/path.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/i18n/update.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/icon/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/icon/icon.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/overlay/OverlayWindow.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/overlay/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/qss/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/settings/SettingTab.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/settings/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/start/SelectHwndWindow.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/start/StartCard.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/start/StartTab.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/start/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/ConfigItemFactory.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/ConfigLabelAndWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/LabelAndDoubleSpinBox.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/LabelAndLineEdit.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/LabelAndList.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/LabelAndSpinBox.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/LabelAndSwitchButton.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/LabelAndWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/ModifyListDialog.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/ModifyListItem.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/StartButton.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/TaskCard.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/TaskOpButton.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/TooltipTableWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/TriggerTaskTab.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/tasks/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/util/Alert.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/util/InitWorker.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/util/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/Card.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/FramelessDialog.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/ListTableWidgetItem.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/StatusBar.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/TabWidget.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/YesNonWidgetItem.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/gui/widget/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/interaction/ADBInteraction.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/interaction/BaseInteraction.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/interaction/Win32Interaction.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/interaction/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/logging/Logger.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/logging/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/ocr/OCR.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/ocr/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Media/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Security/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/Storage/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/Windows/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/delegate.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/export.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/idldsl.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/inspectable.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/roapi.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/types.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/rotypes/winstring.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/save/BlackBarProcessor.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/save/PostProcessor.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/save/SaveByInterval.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/save/SaveByKeyPress.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/save/SaveMethodBase.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/save/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/scene/FeatureScene.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/scene/Scene.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/scene/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/stats/StreamStats.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/stats/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/task/BaseTask.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/task/ExecutorOperation.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/task/OneTimeTask.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/task/TriggerTask.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/task/__init__.py +0 -0
- {ok-script-0.0.49/ok/util → ok-script-0.0.52/ok/update}/__init__.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/util/exit_event.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/util/json.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/util/list.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/util/thread.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/util/win32_process.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok/util/yaml.py +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/ok_script.egg-info/dependency_links.txt +0 -0
- {ok-script-0.0.49 → ok-script-0.0.52}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ok-script
|
|
3
|
-
Version: 0.0.
|
|
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
|
|
@@ -21,6 +21,7 @@ Requires-Dist: PySide6-Fluent-Widgets>=1.5.6
|
|
|
21
21
|
Requires-Dist: psutil>=5.9.8
|
|
22
22
|
Requires-Dist: opencv-python>=4.9.0.80
|
|
23
23
|
Requires-Dist: ok-d3dshot>=0.1.5
|
|
24
|
+
Requires-Dist: py7zr>=0.21.0
|
|
24
25
|
|
|
25
26
|
# ok-script
|
|
26
27
|
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import threading
|
|
2
2
|
|
|
3
3
|
import win32gui
|
|
4
|
-
from adbutils import AdbError
|
|
5
4
|
|
|
6
5
|
from ok.capture.HwndWindow import HwndWindow, find_hwnd_by_title_and_exe
|
|
7
6
|
from ok.capture.adb.ADBCaptureMethod import ADBCaptureMethod, do_screencap
|
|
8
7
|
from ok.capture.adb.WindowsCaptureFactory import update_capture_method
|
|
9
|
-
from ok.capture.adb.vbox import installed_emulator
|
|
10
8
|
from ok.capture.windows.window import get_window_bounds
|
|
11
9
|
from ok.config.Config import Config
|
|
12
10
|
from ok.gui.Communicate import communicate
|
|
@@ -36,8 +34,7 @@ class DeviceManager:
|
|
|
36
34
|
"DeviceManager")
|
|
37
35
|
self.thread = None
|
|
38
36
|
self.capture_method = None
|
|
39
|
-
self.
|
|
40
|
-
self.start()
|
|
37
|
+
self.refresh()
|
|
41
38
|
|
|
42
39
|
def refresh(self):
|
|
43
40
|
if self.thread is None or not self.thread.is_alive():
|
|
@@ -121,6 +118,7 @@ class DeviceManager:
|
|
|
121
118
|
return
|
|
122
119
|
if not fast:
|
|
123
120
|
self.connect_all()
|
|
121
|
+
from ok.capture.adb.vbox import installed_emulator
|
|
124
122
|
installed_emulators = [] if fast else installed_emulator()
|
|
125
123
|
for device in self.adb.list():
|
|
126
124
|
logger.debug(f'adb.list() {device}')
|
|
@@ -295,6 +293,7 @@ class DeviceManager:
|
|
|
295
293
|
def shell(self, *args, **kwargs):
|
|
296
294
|
device = self.device
|
|
297
295
|
if device is not None:
|
|
296
|
+
from adbutils import AdbError
|
|
298
297
|
try:
|
|
299
298
|
return device.shell(*args, **kwargs)
|
|
300
299
|
except AdbError as 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
|
-
|
|
21
|
-
|
|
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,11 +8,13 @@ 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
|
|
14
15
|
from ok.gui.overlay.OverlayWindow import OverlayWindow
|
|
15
16
|
from ok.logging.Logger import get_logger
|
|
17
|
+
from ok.update.Updater import Updater
|
|
16
18
|
|
|
17
19
|
logger = get_logger(__name__)
|
|
18
20
|
|
|
@@ -29,6 +31,7 @@ class App:
|
|
|
29
31
|
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
|
|
30
32
|
|
|
31
33
|
self.app = QApplication(sys.argv)
|
|
34
|
+
communicate.quit.connect(self.app.quit)
|
|
32
35
|
self.app.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings)
|
|
33
36
|
qconfig.theme = Theme.AUTO
|
|
34
37
|
|
|
@@ -55,6 +58,8 @@ class App:
|
|
|
55
58
|
else:
|
|
56
59
|
logger.debug(f"No translation available for {self.locale}, falling back to English/default. {full_path}")
|
|
57
60
|
|
|
61
|
+
self.updater = Updater(self.config, exit_event)
|
|
62
|
+
|
|
58
63
|
def center_window(self, window):
|
|
59
64
|
screen = self.app.primaryScreen()
|
|
60
65
|
size = screen.size()
|
|
@@ -75,8 +80,9 @@ class App:
|
|
|
75
80
|
self.show_message_window(title, content)
|
|
76
81
|
|
|
77
82
|
def show_main_window(self):
|
|
78
|
-
self.main_window = MainWindow(self.icon, self.
|
|
79
|
-
|
|
83
|
+
self.main_window = MainWindow(self.icon, self.title, self.version, self.overlay, self.about,
|
|
84
|
+
exit_event=self.exit_event)
|
|
85
|
+
# Set the window title here
|
|
80
86
|
self.main_window.setWindowIcon(self.icon)
|
|
81
87
|
if self.overlay and ok.gui.device_manager.hwnd is not None:
|
|
82
88
|
self.overlay_window = OverlayWindow(ok.gui.device_manager.hwnd)
|
|
@@ -104,5 +110,6 @@ class App:
|
|
|
104
110
|
def exec(self):
|
|
105
111
|
sys.exit(self.app.exec())
|
|
106
112
|
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
@staticmethod
|
|
114
|
+
def quit():
|
|
115
|
+
communicate.quit.emit()
|
|
@@ -20,6 +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(str)
|
|
24
|
+
download_update = Signal(float, str, bool, str)
|
|
25
|
+
quit = Signal()
|
|
23
26
|
|
|
24
27
|
def emit_draw_box(self, key: str = None, boxes=None, color=None, frame=None):
|
|
25
28
|
self.draw_box.emit(key, boxes, color, frame)
|
|
@@ -20,7 +20,7 @@ class Communicate(QObject):
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class MainWindow(MSFluentWindow):
|
|
23
|
-
def __init__(self, icon, debug=False, about=None, exit_event=None):
|
|
23
|
+
def __init__(self, icon, title, version, debug=False, about=None, exit_event=None):
|
|
24
24
|
super().__init__()
|
|
25
25
|
self.exit_event = exit_event
|
|
26
26
|
self.start_tab = StartTab()
|
|
@@ -42,11 +42,11 @@ class MainWindow(MSFluentWindow):
|
|
|
42
42
|
# self.addSubInterface(debug_tab, FluentIcon.COMMAND_PROMPT, self.tr('Debug'))
|
|
43
43
|
# ... Add other tabs similarly
|
|
44
44
|
if about:
|
|
45
|
-
about_tab = AboutTab(about)
|
|
45
|
+
about_tab = AboutTab(icon, title, version, about)
|
|
46
46
|
self.addSubInterface(about_tab, FluentIcon.QUESTION, self.tr('About'),
|
|
47
47
|
position=NavigationItemPosition.BOTTOM)
|
|
48
48
|
# Styling the tabs and content if needed, for example:
|
|
49
|
-
self.setWindowTitle(
|
|
49
|
+
self.setWindowTitle(f'{title} {version}')
|
|
50
50
|
|
|
51
51
|
communicate.executor_paused.connect(self.executor_paused)
|
|
52
52
|
communicate.tab.connect(self.navigate_tab)
|
|
@@ -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)
|