Skip to content

Commit cae3919

Browse files
authored
First round of QA testing fixes (#171)
* Added sonarcloud.properties * Remove duplicate DeleteDC & allow errors to show May fix #167 * Rename CaptureMethodInterface to CaptureMethodBase * Added autofix script and faster linting * Disable device probing for now. Fixes #169 * Updated settings widget text and workaround to fix #170 * Bump AUTOSPLIT_VERSION * Next Image even if it's not possible to split Fixes #168 * Fix build
1 parent 2c6cd9c commit cae3919

19 files changed

+128
-105
lines changed

.github/workflows/lint-and-build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
- run: scripts/install.ps1
4646
shell: pwsh
4747
- name: Analysing the code with Pyright
48-
run: pyright --warnings
48+
run: pyright src/ --warnings
4949
Pylint:
5050
runs-on: windows-latest
5151
strategy:
@@ -64,7 +64,7 @@ jobs:
6464
- run: scripts/install.ps1
6565
shell: pwsh
6666
- name: Analysing the code with Pylint
67-
run: pylint --reports=y --output-format=colorized src/
67+
run: pylint src/ --reports=y --output-format=colorized
6868
Flake8:
6969
runs-on: windows-latest
7070
strategy:
@@ -83,7 +83,7 @@ jobs:
8383
- run: scripts/install.ps1
8484
shell: pwsh
8585
- name: Analysing the code with Flake8
86-
run: flake8
86+
run: flake8 src/ typings/
8787
Bandit:
8888
runs-on: windows-latest
8989
steps:
@@ -98,7 +98,7 @@ jobs:
9898
- run: scripts/install.ps1
9999
shell: pwsh
100100
- name: Analysing the code with Bandit
101-
run: bandit -n 1 --severity-level medium --recursive src
101+
run: bandit src/ -n 1 --severity-level medium --recursive
102102
Build:
103103
runs-on: windows-latest
104104
strategy:

.sonarcloud.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sonar.python.version=3.9, 3.10

.vscode/extensions.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
"ms-python.vscode-pylance",
1010
"ms-vscode.powershell",
1111
"pkief.material-icon-theme",
12+
"redhat.vscode-xml",
1213
"redhat.vscode-yaml",
1314
"shardulm94.trailing-spaces",
14-
"sonarsource.sonarlint-vscode"
15+
"sonarsource.sonarlint-vscode",
1516
],
1617
"unwantedRecommendations": [
1718
// Must disable in this workspace //
@@ -36,5 +37,5 @@
3637
"johnstoncode.svn-scm",
3738
// Prefer using VSCode itself as a text editor
3839
"vscodevim.vim",
39-
]
40+
],
4041
}

.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,6 @@
106106
"powershell.codeFormatting.useCorrectCasing": true,
107107
"powershell.codeFormatting.whitespaceBetweenParameters": true,
108108
"powershell.integratedConsole.showOnStartup": false,
109+
"xml.codeLens.enabled": true,
110+
"xml.format.spaceBeforeEmptyCloseTag": false,
109111
}

res/design.ui

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@
1010
<height>424</height>
1111
</rect>
1212
</property>
13-
<property name="sizePolicy">
14-
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
15-
<horstretch>0</horstretch>
16-
<verstretch>0</verstretch>
17-
</sizepolicy>
18-
</property>
1913
<property name="minimumSize">
2014
<size>
2115
<width>777</width>

res/settings.ui

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<ui version="4.0">
3-
<class>DialogSettings</class>
4-
<widget class="QDialog" name="DialogSettings">
3+
<class>SettingsWidget</class>
4+
<widget class="QWidget" name="SettingsWidget">
55
<property name="geometry">
66
<rect>
77
<x>0</x>
@@ -10,12 +10,6 @@
1010
<height>661</height>
1111
</rect>
1212
</property>
13-
<property name="sizePolicy">
14-
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
15-
<horstretch>0</horstretch>
16-
<verstretch>0</verstretch>
17-
</sizepolicy>
18-
</property>
1913
<property name="minimumSize">
2014
<size>
2115
<width>291</width>
@@ -40,12 +34,6 @@
4034
<iconset>
4135
<normaloff>:/resources/icon.ico</normaloff>:/resources/icon.ico</iconset>
4236
</property>
43-
<property name="sizeGripEnabled">
44-
<bool>false</bool>
45-
</property>
46-
<property name="modal">
47-
<bool>false</bool>
48-
</property>
4937
<widget class="QGroupBox" name="capture_settings_groupbox">
5038
<property name="geometry">
5139
<rect>
@@ -352,7 +340,7 @@ It is highly recommended to NOT use pHash if you use masked images. It is very i
352340
<property name="geometry">
353341
<rect>
354342
<x>6</x>
355-
<y>193</y>
343+
<y>190</y>
356344
<width>261</width>
357345
<height>61</height>
358346
</rect>
@@ -364,7 +352,10 @@ It is highly recommended to NOT use pHash if you use masked images. It is very i
364352
</font>
365353
</property>
366354
<property name="text">
367-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Custom image settings and flags are set in the &lt;br&gt;&lt;/br&gt; image file name. These will override the default &lt;br&gt;&lt;/br&gt; values. View the &lt;a href=&quot;https://github.com/{GITHUB_REPOSITORY}#readme&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;README&lt;/span&gt;&lt;/a&gt; for full details on all &lt;br&gt;&lt;/br&gt; available custom image settings.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
355+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Image settings and flags can be set per image through the image file name. These will override the default values. View the &lt;a href=&quot;https://github.com/{GITHUB_REPOSITORY}#readme&quot;&gt;&lt;span style=&quot;text-decoration: underline; color:#0000ff;&quot;&gt;README&lt;/span&gt;&lt;/a&gt; for full details on all available custom image settings.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
356+
</property>
357+
<property name="wordWrap">
358+
<bool>true</bool>
368359
</property>
369360
</widget>
370361
<widget class="QLabel" name="default_delay_time_label">
@@ -399,6 +390,34 @@ It is highly recommended to NOT use pHash if you use masked images. It is very i
399390
<number>999999999</number>
400391
</property>
401392
</widget>
393+
<widget class="QCommandLinkButton" name="readme_link_button">
394+
<property name="geometry">
395+
<rect>
396+
<x>140</x>
397+
<y>210</y>
398+
<width>71</width>
399+
<height>31</height>
400+
</rect>
401+
</property>
402+
<property name="font">
403+
<font>
404+
<pointsize>8</pointsize>
405+
<bold>true</bold>
406+
</font>
407+
</property>
408+
<property name="text">
409+
<string>README</string>
410+
</property>
411+
<property name="iconSize">
412+
<size>
413+
<width>0</width>
414+
<height>0</height>
415+
</size>
416+
</property>
417+
<property name="description">
418+
<string>This is a workaround because custom_image_settings_info_label simply will not open links with a left click no matter what we tried.</string>
419+
</property>
420+
</widget>
402421
<widget class="QCheckBox" name="enable_auto_reset_image_checkbox">
403422
<property name="geometry">
404423
<rect>
@@ -714,11 +733,11 @@ reset image</string>
714733
</widget>
715734
</widget>
716735
<tabstops>
717-
<tabstop>set_split_hotkey_button</tabstop>
718-
<tabstop>set_reset_hotkey_button</tabstop>
719-
<tabstop>set_undo_split_hotkey_button</tabstop>
720-
<tabstop>set_skip_split_hotkey_button</tabstop>
721-
<tabstop>set_pause_hotkey_button</tabstop>
736+
<tabstop>split_input</tabstop>
737+
<tabstop>reset_input</tabstop>
738+
<tabstop>undo_split_input</tabstop>
739+
<tabstop>skip_split_input</tabstop>
740+
<tabstop>pause_input</tabstop>
722741
<tabstop>fps_limit_spinbox</tabstop>
723742
<tabstop>live_capture_region_checkbox</tabstop>
724743
<tabstop>capture_method_combobox</tabstop>

res/update_checker.ui

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@
1313
<height>133</height>
1414
</rect>
1515
</property>
16-
<property name="sizePolicy">
17-
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
18-
<horstretch>0</horstretch>
19-
<verstretch>0</verstretch>
20-
</sizepolicy>
21-
</property>
2216
<property name="minimumSize">
2317
<size>
2418
<width>313</width>

scripts/lint.ps1

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ $originalDirectory = $pwd
22
Set-Location "$PSScriptRoot/.."
33
$exitCodes = 0
44

5+
Write-Host "`nRunning autofixes..."
6+
isort src/ typings/
7+
autopep8 src/ typings/ --in-place
8+
59
Write-Host "`nRunning Pyright..."
610
$Env:PYRIGHT_PYTHON_FORCE_VERSION = 'latest'
7-
pyright --warnings
11+
pyright src/ --warnings
812
$exitCodes += $LastExitCode
913
if ($LastExitCode -gt 0) {
1014
Write-Host "`Pyright failed ($LastExitCode)" -ForegroundColor Red
@@ -14,7 +18,7 @@ else {
1418
}
1519

1620
Write-Host "`nRunning Pylint..."
17-
pylint --output-format=colorized src/
21+
pylint src/ --output-format=colorized
1822
$exitCodes += $LastExitCode
1923
if ($LastExitCode -gt 0) {
2024
Write-Host "`Pylint failed ($LastExitCode)" -ForegroundColor Red
@@ -24,7 +28,7 @@ else {
2428
}
2529

2630
Write-Host "`nRunning Flake8..."
27-
flake8
31+
flake8 src/ typings/
2832
$exitCodes += $LastExitCode
2933
if ($LastExitCode -gt 0) {
3034
Write-Host "`Flake8 failed ($LastExitCode)" -ForegroundColor Red
@@ -34,7 +38,7 @@ else {
3438
}
3539

3640
Write-Host "`nRunning Bandit..."
37-
bandit -f custom --silent --recursive src
41+
bandit src/ -f custom --silent --recursive
3842
# $exitCodes += $LastExitCode # Returns 1 on low
3943
if ($LastExitCode -gt 0) {
4044
Write-Host "`Bandit warning ($LastExitCode)" -ForegroundColor Yellow

scripts/requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ flake8-pyi>=22.8.1 # flake8 5 support
1919
flake8-quotes
2020
flake8-simplify
2121
pep8-naming
22-
pylint>=2.13.9 # Respect ignore configuration options with --recursive=y
22+
pylint>=2.13.9,<3.0.0 # Respect ignore configuration options with --recursive=y # 3.0 still in pre-release
2323
pyright
2424
#
2525
# Run `./scripts/designer.ps1` to quickly open the bundled PyQt Designer.

scripts/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
numpy>=1.23 # Updated types
1414
opencv-python-headless>=4.5.4,<4.6 # https://github.com/pyinstaller/pyinstaller/issues/6889
1515
PyQt6>=6.2.1 # Python 3.10 support
16-
git+https://github.com/Avasam/imagehash.git@patch-2#egg=ImageHash # Contains type information + setup as package not module
16+
git+https://github.com/JohannesBuchner/imagehash.git#egg=ImageHash # Contains type information + setup as package not module
1717
keyboard
1818
packaging
1919
Pillow

src/AutoSplit.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import os
77
import signal
88
import sys
9-
from collections.abc import Callable
109
from time import time
1110
from types import FunctionType
1211

@@ -21,7 +20,7 @@
2120
import user_profile
2221
from AutoControlledWorker import AutoControlledWorker
2322
from AutoSplitImage import COMPARISON_RESIZE, START_KEYWORD, AutoSplitImage, ImageType
24-
from capture_method import CaptureMethodEnum, CaptureMethodInterface
23+
from capture_method import CaptureMethodBase, CaptureMethodEnum
2524
from gen import about, design, settings, update_checker
2625
from hotkeys import HOTKEYS, after_setting_hotkey, send_command
2726
from menu_bar import (about_qt, about_qt_for_python, check_for_updates, get_default_settings_from_ui, open_about,
@@ -64,15 +63,7 @@ class AutoSplit(QMainWindow, design.Ui_MainWindow):
6463
AboutWidget: about.Ui_AboutAutoSplitWidget | None = None
6564
UpdateCheckerWidget: update_checker.Ui_UpdateChecker | None = None
6665
CheckForUpdatesThread: QtCore.QThread | None = None
67-
SettingsWidget: settings.Ui_DialogSettings | None = None
68-
69-
# hotkeys need to be initialized to be passed as thread arguments in hotkeys.py
70-
# and for type safety in both hotkeys.py and settings_file.py
71-
split_hotkey: Callable[[], None] | None = None
72-
reset_hotkey: Callable[[], None] | None = None
73-
skip_split_hotkey: Callable[[], None] | None = None
74-
undo_split_hotkey: Callable[[], None] | None = None
75-
pause_hotkey: Callable[[], None] | None = None
66+
SettingsWidget: settings.Ui_SettingsWidget | None = None
7667

7768
# Initialize a few attributes
7869
hwnd = 0
@@ -82,7 +73,7 @@ class AutoSplit(QMainWindow, design.Ui_MainWindow):
8273
split_image_number = 0
8374
split_images_and_loop_number: list[tuple[AutoSplitImage, int]] = []
8475
split_groups: list[list[int]] = []
85-
capture_method = CaptureMethodInterface()
76+
capture_method = CaptureMethodBase()
8677

8778
# Last loaded settings empty and last successful loaded settings file path to None until we try to load them
8879
last_loaded_settings = DEFAULT_PROFILE
@@ -123,6 +114,10 @@ def __init__(self, parent: QWidget | None = None): # pylint: disable=too-many-s
123114
self.width_spinbox.setFrame(False)
124115
self.height_spinbox.setFrame(False)
125116

117+
# Hotkeys need to be initialized to be passed as thread arguments in hotkeys.py
118+
for hotkey in HOTKEYS:
119+
setattr(self, f"{hotkey}_hotkey", None)
120+
126121
# Get default values defined in SettingsDialog
127122
self.settings_dict = get_default_settings_from_ui(self)
128123
user_profile.load_check_for_updates_on_open(self)
@@ -450,7 +445,7 @@ def skip_split(self, navigate_image_only: bool = False):
450445
# or Splitting/skipping when there are no images left
451446
if self.start_auto_splitter_button.text() == START_AUTO_SPLITTER_TEXT \
452447
or "Delayed Split" in self.current_split_image.text() \
453-
or (not self.skip_split_button.isEnabled() and not self.is_auto_controlled) \
448+
or not (self.skip_split_button.isEnabled() or self.is_auto_controlled or navigate_image_only) \
454449
or self.__is_current_split_out_of_range():
455450
return
456451

@@ -795,6 +790,10 @@ def __reset_if_should(self, capture: cv2.Mat | None):
795790
self.reset()
796791
else:
797792
self.table_reset_image_live_label.setText("disabled")
793+
else:
794+
self.table_reset_image_live_label.setText("N/A")
795+
self.table_reset_image_threshold_label.setText("N/A")
796+
self.table_reset_image_highest_label.setText("N/A")
798797

799798
return self.__check_for_reset_state_update_ui()
800799

src/capture_method/BitBltCaptureMethod.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import win32ui
1212
from win32 import win32gui
1313

14-
from capture_method.interface import CaptureMethodInterface
14+
from capture_method.CaptureMethodBase import CaptureMethodBase
1515
from utils import get_window_bounds, is_valid_hwnd
1616

1717
if TYPE_CHECKING:
@@ -21,7 +21,7 @@
2121
PW_RENDERFULLCONTENT = 0x00000002
2222

2323

24-
class BitBltCaptureMethod(CaptureMethodInterface):
24+
class BitBltCaptureMethod(CaptureMethodBase):
2525
_render_full_content = False
2626

2727
def get_frame(self, autosplit: AutoSplit) -> tuple[cv2.Mat | None, bool]:
@@ -57,15 +57,11 @@ def get_frame(self, autosplit: AutoSplit) -> tuple[cv2.Mat | None, bool]:
5757
image.shape = (selection["height"], selection["width"], 4)
5858
except (win32ui.error, pywintypes.error):
5959
return None, False
60-
# We already obtained the image, so we can ignore errors during cleanup
61-
try:
62-
dc_object.DeleteDC()
63-
dc_object.DeleteDC()
64-
compatible_dc.DeleteDC()
65-
win32gui.ReleaseDC(hwnd, window_dc)
66-
win32gui.DeleteObject(bitmap.GetHandle())
67-
except win32ui.error:
68-
pass
60+
# Cleanup DC and handle
61+
dc_object.DeleteDC()
62+
compatible_dc.DeleteDC()
63+
win32gui.ReleaseDC(hwnd, window_dc)
64+
win32gui.DeleteObject(bitmap.GetHandle())
6965
return image, False
7066

7167
def recover_window(self, captured_window_title: str, autosplit: AutoSplit):

src/capture_method/interface.py renamed to src/capture_method/CaptureMethodBase.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# pylint: disable=no-self-use,unnecessary-dunder-call
1313

1414

15-
class CaptureMethodInterface():
15+
class CaptureMethodBase():
1616
def __init__(self, autosplit: AutoSplit | None = None):
1717
pass
1818

src/capture_method/VideoCaptureDeviceCaptureMethod.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66
import cv2
77

8-
from capture_method.interface import CaptureMethodInterface
8+
from capture_method.CaptureMethodBase import CaptureMethodBase
99
from error_messages import CREATE_NEW_ISSUE_MESSAGE, exception_traceback
1010
from utils import is_valid_image
1111

1212
if TYPE_CHECKING:
1313
from AutoSplit import AutoSplit
1414

1515

16-
class VideoCaptureDeviceCaptureMethod(CaptureMethodInterface):
16+
class VideoCaptureDeviceCaptureMethod(CaptureMethodBase):
1717
capture_device: cv2.VideoCapture
1818
capture_thread: Thread | None
1919
last_captured_frame: cv2.Mat | None = None

0 commit comments

Comments
 (0)