33 Commits
Author SHA1 Message Date
Mikaël Capelle d38019a994 Move to VCPKG. (#7) 2025-05-29 11:03:34 +02:00
Mikaël Capelle af4c65d941 Bump dependencies and fix formatting. (#9) 2025-05-27 08:00:57 +02:00
Mikaël Capelle e510e1c3ed Update translations. (#8) 2024-07-21 16:43:51 +02:00
Mikaël Capelle f1b92a0f61 Install poetry in CI. (#6)
* Install poetry in CI.
* Force platform to Windows for pyright.
2024-06-09 14:20:10 +02:00
Mikaël Capelle 7f93d4f77b Update following uibase change for game features. (#5) 2024-06-09 12:26:22 +02:00
Mikaël Capelle 0f4f666c71 Change plugin requirement to use PyPi version. 2024-05-20 10:28:19 +02:00
Mikaël Capelle a0ca112ed0 Bump stubs. 2022-05-05 13:15:52 +02:00
Mikaël Capelle 7ef97f047c Merge pull request #4 from ModOrganizer2/update-cmake-common-qt6
Update cmake common qt6
2022-04-28 17:54:50 +02:00
Mikaël Capelle aff1cbb944 Fixes for Qt6. 2022-04-22 13:18:04 +02:00
Mikaël Capelle 6492f84eac Minor fixes. 2022-04-19 23:33:35 +02:00
Mikaël Capelle 7b3dc82f46 Update following cmake_common changes.
# Conflicts:
#	CMakeLists.txt
2022-04-19 22:03:11 +02:00
Jeremy Rimpo 76faacba19 Merge remote-tracking branch 'origin/master' into qt6 2022-04-17 20:17:40 -05:00
Mikaël Capelle 0c8d7261fd Merge pull request #3 from Holt59/update-interpreter
Update interpreter to fix issues with case-sensitive comparisons.
2022-02-05 14:33:38 +01:00
Mikaël Capelle 3cf15300fb Update interpreter to fix issues with case-sensitive comparisons. 2022-02-05 14:31:39 +01:00
Jeremy Rimpo 3bfd181704 Installer image improvements
- Expand size of options / image row
- Resize image with correct aspect ratio
- Add maximize button to titlebar
2021-12-26 01:23:16 -06:00
Jeremy Rimpo bffeb8c05f More PyQt6 enum fixes 2021-12-26 01:16:42 -06:00
Jeremy Rimpo f7a9c95d5b Fix issues with PyQt6 2021-12-25 20:54:10 -06:00
Jeremy Rimpo 793ab6273b Reformat the translations 2021-12-09 19:39:50 -06:00
Jeremy Rimpo 7e5ec2d11a Fix pylupdate parsing 2021-12-06 23:50:35 -06:00
Jeremy Rimpo ca343602ec PyQt6 Compatibility 2021-12-06 05:25:26 -06:00
Jeremy Rimpo e2202073dc Changes to compile with Qt6 + Boost 1.77 2021-12-05 03:42:40 -06:00
Mikaël Capelle fb91a1d2b6 Merge pull request #2 from Holt59/fix-optional-plugins
Fix not-selected plugins
2021-03-13 13:49:42 +01:00
Mikaël Capelle 9f71ac1517 Move not-selected plugins to 'optional'. 2021-03-13 13:48:45 +01:00
Mikaël Capelle 775d764950 Fix translations. 2021-02-06 19:28:26 +01:00
Mikaël Capelle 538a0f73e9 Make placeholder text not-translatable. 2021-02-03 18:35:19 +01:00
Mikaël Capelle ecefc5eb8a Fix FOMOD/OMOD detection. 2020-11-27 20:30:06 +01:00
Mikaël Capelle b9653b8322 Merge pull request #1 from ModOrganizer2/cmake-common
Add CMakeLists for MO2 build.
2020-11-25 17:51:27 +01:00
Mikaël Capelle b39be8c295 Add CMakeLists for MO2 build. 2020-11-23 10:56:59 +01:00
Mikaël Capelle 28deb0ce25 Fix release script. 2020-11-23 09:15:55 +01:00
Mikaël Capelle 1cf557a33c Bump version to 1.0.2. 2020-11-17 22:08:58 +01:00
Mikaël Capelle 753871d62a Fix getPluginStatus. 2020-11-17 22:05:56 +01:00
Mikaël Capelle 8b49e0d3cd Do not move non-enabled ESPs to optional. 2020-11-17 19:38:22 +01:00
Mikaël Capelle 52e20cf676 Update mobase stubs in setup.cfg. 2020-11-15 21:53:05 +01:00
27 changed files with 1078 additions and 590 deletions
+6
View File
@@ -0,0 +1,6 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.py text eol=crlf
+39
View File
@@ -0,0 +1,39 @@
name: Build Installer Wizard Plugin
on:
push:
branches: [master]
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
runs-on: windows-2022
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Set environmental variables
shell: bash
run: |
echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> $GITHUB_ENV
- uses: actions/checkout@v4
- name: Configure Installer Wizard Plugin build
shell: pwsh
run: |
cmake --preset vs2022-windows "-DCMAKE_INSTALL_PREFIX=install" "-DVCPKG_MANIFEST_FEATURES=standalone"
- name: Build Installer Wizard Plugin
run: cmake --build vsbuild --config RelWithDebInfo
- name: Install Installer Wizard Plugin
run: cmake --install vsbuild --config RelWithDebInfo
- name: Upload Installer Wizard Plugin artifact
uses: actions/upload-artifact@master
with:
name: installer_wizard
path: ./install/bin/plugins
+20 -12
View File
@@ -8,17 +8,25 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: [3.8]
python-version: [3.12]
steps:
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Test with tox
run: tox -e py38-lint
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- uses: abatilo/actions-poetry@v2
- name: Install package
run: poetry install
# generate UI file for linting
- name: Generate UI files
shell: pwsh
run: |
Get-ChildItem -Recurse -File -Include "*.ui" | ForEach-Object {
poetry run pyuic6 $_ -o ([io.path]::ChangeExtension($_.FullName, "py"))
}
- name: Lint
run: poetry run poe lint
+6
View File
@@ -7,8 +7,14 @@ src/ui/*.py
**/.mypy_cache
.tox
.vscode
venv
# MO2 build files:
vsbuild
mob.log
# Generated files:
lib
src/lib
installer_wizard
installer_wizard-*.zip
+25
View File
@@ -0,0 +1,25 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-toml
- id: check-merge-conflict
- id: mixed-line-ending
args: [--fix=lf]
- id: check-case-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.7 # must match pyproject.toml
hooks:
- id: ruff
args: [--extend-select, I, --fix]
- id: ruff-format
ci:
autofix_commit_msg: "[pre-commit.ci] Auto fixes from pre-commit.com hooks."
autofix_prs: true
autoupdate_commit_msg: "[pre-commit.ci] Pre-commit autoupdate."
autoupdate_schedule: quarterly
submodules: false
+7
View File
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.16)
project(installer_wizard LANGUAGES NONE)
find_package(mo2-cmake CONFIG REQUIRED)
add_subdirectory(src)
+17
View File
@@ -0,0 +1,17 @@
{
"configurePresets": [
{
"binaryDir": "${sourceDir}/vsbuild",
"toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"generator": "Visual Studio 17 2022",
"name": "vs2022-windows"
}
],
"buildPresets": [
{
"name": "vs2022-windows",
"configurePreset": "vs2022-windows"
}
],
"version": 4
}
-163
View File
@@ -1,163 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS><TS version="2.0">
<context>
<name>WizardInstallerComplete</name>
<message>
<location filename="src/ui/wizardinstallercomplete.py" line="151"/>
<source>Form</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallercomplete.py" line="152"/>
<source>The installer script has finished. The following sub-packages and plugins will be installed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallercomplete.py" line="153"/>
<source>Sub-Packages:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallercomplete.py" line="154"/>
<source>Plugins:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallercomplete.py" line="155"/>
<source>INI Tweaks:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallercomplete.py" line="156"/>
<source>Notes:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>WizardInstallerDialog</name>
<message>
<location filename="src/ui/wizardinstallerdialog.py" line="75"/>
<source>BAIN Wizard Installer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerdialog.py" line="76"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerdialog.py" line="77"/>
<source>Manual</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerdialog.py" line="78"/>
<source>Script</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerdialog.py" line="79"/>
<source>Back</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerdialog.py" line="80"/>
<source>Next</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerdialog.py" line="81"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>WizardInstallerError</name>
<message>
<location filename="src/ui/wizardinstallererror.py" line="52"/>
<source>Form</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallererror.py" line="54"/>
<source>TextLabel</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>WizardInstallerPage</name>
<message>
<location filename="src/ui/wizardinstallerpage.py" line="91"/>
<source>Form</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerpage.py" line="92"/>
<source>TextLabel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerpage.py" line="93"/>
<source>Options:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerpage.py" line="94"/>
<source>Description:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>WizardInstallerRequires</name>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="113"/>
<source>Form</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="114"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Warning:&lt;/span&gt; The following version requirements are not met for using this installer.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="115"/>
<source>Requirements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="116"/>
<source>Graphics Extender</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="117"/>
<source>Wrye Bash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="118"/>
<source>Need</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="119"/>
<source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="122"/>
<source>N/A</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="121"/>
<source>Have</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="src/ui/wizardinstallerrequires.py" line="123"/>
<source>Script Extender</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>
+2 -1
View File
@@ -6,7 +6,8 @@ $target = ".\installer_wizard\"
Remove-Item -Recurse -Force -ErrorAction Ignore $target
New-Item -Path $target -Type Directory | Out-Null
Copy-Item -Recurse -Path .\src\* -Exclude "*.ui", "__pycache__" -Destination .\installer_wizard
Copy-Item -Recurse -Path .\src\* -Exclude "*.ui" -Destination $target
Get-ChildItem -Recurse $target -Include "__pycache__" | Remove-Item -Recurse -Force
Copy-Item .\installer_wizard_en.ts, .\README.md, .\LICENSE $target
# Find the version:
+1 -1
View File
@@ -1,5 +1,5 @@
# Install the lib:
pip install --target=.\src\lib --upgrade git+https://github.com/Holt59/bain-wizard-interpreter | Out-Null
pip install --target=.\src\lib --upgrade -r .\plugin-requirements.txt | Out-Null
# Convert ui files:
Get-ChildItem -Recurse -File -Include "*.ui" | ForEach-Object {
+1
View File
@@ -0,0 +1 @@
bain-wizard-interpreter==1.0.4
Generated
+294
View File
@@ -0,0 +1,294 @@
# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
[[package]]
name = "antlr4-python3-runtime"
version = "4.13.1"
description = "ANTLR 4.13.1 runtime for Python 3"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "antlr4-python3-runtime-4.13.1.tar.gz", hash = "sha256:3cd282f5ea7cfb841537fe01f143350fdb1c0b1ce7981443a2fa8513fddb6d1a"},
{file = "antlr4_python3_runtime-4.13.1-py3-none-any.whl", hash = "sha256:78ec57aad12c97ac039ca27403ad61cb98aaec8a3f9bb8144f889aa0fa28b943"},
]
[[package]]
name = "bain-wizard-interpreter"
version = "1.0.4"
description = "BAIN Wizard Interpreter based on wizparse."
optional = false
python-versions = "<4.0,>=3.11.1"
groups = ["main"]
files = [
{file = "bain_wizard_interpreter-1.0.4-py3-none-any.whl", hash = "sha256:c6a084349caa6fd80d8fbf222869fb63df8ede337edbb8774dff557ae2a981bc"},
{file = "bain_wizard_interpreter-1.0.4.tar.gz", hash = "sha256:4ebd36112690775bab6c921c90422c9e5432901ca90860f36c5ba0153bb82079"},
]
[package.dependencies]
antlr4-python3-runtime = ">=4.13.1,<5.0.0"
chardet = ">=5.2.0,<6.0.0"
[[package]]
name = "chardet"
version = "5.2.0"
description = "Universal encoding detector for Python 3"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
{file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
]
[[package]]
name = "mobase-stubs"
version = "2.5.2"
description = "PEP561 stub files for the mobase Python API."
optional = false
python-versions = "<4.0,>=3.12"
groups = ["dev"]
files = [
{file = "mobase_stubs-2.5.2-py3-none-any.whl", hash = "sha256:6a2c1c95494e7dc0d0f51d4f8f178423c0d9904f823f3c44845315bff304b948"},
{file = "mobase_stubs-2.5.2.tar.gz", hash = "sha256:70c15579828df3bce01746e51fee07176390cdc386facea2b156ea04b3de055c"},
]
[[package]]
name = "nodeenv"
version = "1.9.0"
description = "Node.js virtual environment builder"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
groups = ["dev"]
files = [
{file = "nodeenv-1.9.0-py2.py3-none-any.whl", hash = "sha256:508ecec98f9f3330b636d4448c0f1a56fc68017c68f1e7857ebc52acf0eb879a"},
{file = "nodeenv-1.9.0.tar.gz", hash = "sha256:07f144e90dae547bf0d4ee8da0ee42664a42a04e02ed68e06324348dafe4bdb1"},
]
[[package]]
name = "pastel"
version = "0.2.1"
description = "Bring colors to your terminal."
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
groups = ["dev"]
files = [
{file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"},
{file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"},
]
[[package]]
name = "poethepoet"
version = "0.34.0"
description = "A task runner that works well with poetry."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "poethepoet-0.34.0-py3-none-any.whl", hash = "sha256:c472d6f0fdb341b48d346f4ccd49779840c15b30dfd6bc6347a80d6274b5e34e"},
{file = "poethepoet-0.34.0.tar.gz", hash = "sha256:86203acce555bbfe45cb6ccac61ba8b16a5784264484195874da457ddabf5850"},
]
[package.dependencies]
pastel = ">=0.2.1,<0.3.0"
pyyaml = ">=6.0.2,<7.0"
[package.extras]
poetry-plugin = ["poetry (>=1.2.0,<3.0.0) ; python_version < \"4.0\""]
[[package]]
name = "pyqt6"
version = "6.7.1"
description = "Python bindings for the Qt cross platform application toolkit"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "PyQt6-6.7.1-1-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7f397f4b38b23b5588eb2c0933510deb953d96b1f0323a916c4839c2a66ccccc"},
{file = "PyQt6-6.7.1-1-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2f202b7941aa74e5c7e1463a6f27d9131dbc1e6cabe85571d7364f5b3de7397"},
{file = "PyQt6-6.7.1-cp38-abi3-macosx_11_0_universal2.whl", hash = "sha256:f053378e3aef6248fa612c8afddda17f942fb63f9fe8a9aeb2a6b6b4cbb0eba9"},
{file = "PyQt6-6.7.1-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0adb7914c732ad1dee46d9cec838a98cb2b11bc38cc3b7b36fbd8701ae64bf47"},
{file = "PyQt6-6.7.1-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2d771fa0981514cb1ee937633dfa64f14caa902707d9afffab66677f3a73e3da"},
{file = "PyQt6-6.7.1-cp38-abi3-win_amd64.whl", hash = "sha256:fa3954698233fe286a8afc477b84d8517f0788eb46b74da69d3ccc0170d3714c"},
{file = "PyQt6-6.7.1.tar.gz", hash = "sha256:3672a82ccd3a62e99ab200a13903421e2928e399fda25ced98d140313ad59cb9"},
]
[package.dependencies]
PyQt6-Qt6 = ">=6.7.0,<6.8.0"
PyQt6-sip = ">=13.8,<14"
[[package]]
name = "pyqt6-qt6"
version = "6.7.1"
description = "The subset of a Qt installation needed by PyQt6."
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "PyQt6_Qt6-6.7.1-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:29622b5dd38740b4b6962e0c88d082d08fa10b64542ef5d911b04214aad70150"},
{file = "PyQt6_Qt6-6.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fbcfe66a57199c6a26542b8b9b2f2ee59d974db36293de335a1251f24c4fe917"},
{file = "PyQt6_Qt6-6.7.1-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:9fbab2a96d72d77d16021e259ef86a1a3c87adb0e7eebcc92df0d39f3fdf7e27"},
{file = "PyQt6_Qt6-6.7.1-py3-none-win_amd64.whl", hash = "sha256:590a2f30d15892b5259e6a17ecc0a755675b1b49f553d964e195e90094b44120"},
]
[[package]]
name = "pyqt6-sip"
version = "13.10.2"
description = "The sip module support for PyQt6"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "pyqt6_sip-13.10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8132ec1cbbecc69d23dcff23916ec07218f1a9bbbc243bf6f1df967117ce303e"},
{file = "pyqt6_sip-13.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07f77e89d93747dda71b60c3490b00d754451729fbcbcec840e42084bf061655"},
{file = "pyqt6_sip-13.10.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4ffa71ddff6ef031d52cd4f88b8bba08b3516313c023c7e5825cf4a0ba598712"},
{file = "pyqt6_sip-13.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:e907394795e61f1174134465c889177f584336a98d7a10beade2437bf5942244"},
{file = "pyqt6_sip-13.10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1a6c2f168773af9e6c7ef5e52907f16297d4efd346e4c958eda54ea9135be18e"},
{file = "pyqt6_sip-13.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1d3cc9015a1bd8c8d3e86a009591e897d4d46b0c514aede7d2970a2208749cd"},
{file = "pyqt6_sip-13.10.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ddd578a8d975bfb5fef83751829bf09a97a1355fa1de098e4fb4d1b74ee872fc"},
{file = "pyqt6_sip-13.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:061d4a2eb60a603d8be7db6c7f27eb29d9cea97a09aa4533edc1662091ce4f03"},
{file = "pyqt6_sip-13.10.2-cp311-cp311-win_arm64.whl", hash = "sha256:45ac06f0380b7aa4fcffd89f9e8c00d1b575dc700c603446a9774fda2dcfc0de"},
{file = "pyqt6_sip-13.10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:83e6a56d3e715f748557460600ec342cbd77af89ec89c4f2a68b185fa14ea46c"},
{file = "pyqt6_sip-13.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ccf197f8fa410e076936bee28ad9abadb450931d5be5625446fd20e0d8b27a6"},
{file = "pyqt6_sip-13.10.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:37af463dcce39285e686d49523d376994d8a2508b9acccb7616c4b117c9c4ed7"},
{file = "pyqt6_sip-13.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:c7b34a495b92790c70eae690d9e816b53d3b625b45eeed6ae2c0fe24075a237e"},
{file = "pyqt6_sip-13.10.2-cp312-cp312-win_arm64.whl", hash = "sha256:c80cc059d772c632f5319632f183e7578cd0976b9498682833035b18a3483e92"},
{file = "pyqt6_sip-13.10.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8b5d06a0eac36038fa8734657d99b5fe92263ae7a0cd0a67be6acfe220a063e1"},
{file = "pyqt6_sip-13.10.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad376a6078da37b049fdf9d6637d71b52727e65c4496a80b753ddc8d27526aca"},
{file = "pyqt6_sip-13.10.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3dde8024d055f496eba7d44061c5a1ba4eb72fc95e5a9d7a0dbc908317e0888b"},
{file = "pyqt6_sip-13.10.2-cp313-cp313-win_amd64.whl", hash = "sha256:0b097eb58b4df936c4a2a88a2f367c8bb5c20ff049a45a7917ad75d698e3b277"},
{file = "pyqt6_sip-13.10.2-cp313-cp313-win_arm64.whl", hash = "sha256:cc6a1dfdf324efaac6e7b890a608385205e652845c62130de919fd73a6326244"},
{file = "pyqt6_sip-13.10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38b5823dca93377f8a4efac3cbfaa1d20229aa5b640c31cf6ebbe5c586333808"},
{file = "pyqt6_sip-13.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5506b9a795098df3b023cc7d0a37f93d3224a9c040c43804d4bc06e0b2b742b0"},
{file = "pyqt6_sip-13.10.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e455a181d45a28ee8d18d42243d4f470d269e6ccdee60f2546e6e71218e05bb4"},
{file = "pyqt6_sip-13.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:9c67ed66e21b11e04ffabe0d93bc21df22e0a5d7e2e10ebc8c1d77d2f5042991"},
{file = "pyqt6_sip-13.10.2.tar.gz", hash = "sha256:464ad156bf526500ce6bd05cac7a82280af6309974d816739b4a9a627156fafe"},
]
[[package]]
name = "pyright"
version = "1.1.401"
description = "Command line wrapper for pyright"
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
{file = "pyright-1.1.401-py3-none-any.whl", hash = "sha256:6fde30492ba5b0d7667c16ecaf6c699fab8d7a1263f6a18549e0b00bf7724c06"},
{file = "pyright-1.1.401.tar.gz", hash = "sha256:788a82b6611fa5e34a326a921d86d898768cddf59edde8e93e56087d277cc6f1"},
]
[package.dependencies]
nodeenv = ">=1.6.0"
typing-extensions = ">=4.1"
[package.extras]
all = ["nodejs-wheel-binaries", "twine (>=3.4.1)"]
dev = ["twine (>=3.4.1)"]
nodejs = ["nodejs-wheel-binaries"]
[[package]]
name = "pyyaml"
version = "6.0.2"
description = "YAML parser and emitter for Python"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
{file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
{file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
{file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
{file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
{file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
{file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
{file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
{file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
{file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
{file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
{file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
{file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
{file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
{file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
{file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
]
[[package]]
name = "ruff"
version = "0.11.11"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
{file = "ruff-0.11.11-py3-none-linux_armv6l.whl", hash = "sha256:9924e5ae54125ed8958a4f7de320dab7380f6e9fa3195e3dc3b137c6842a0092"},
{file = "ruff-0.11.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c8a93276393d91e952f790148eb226658dd275cddfde96c6ca304873f11d2ae4"},
{file = "ruff-0.11.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6e333dbe2e6ae84cdedefa943dfd6434753ad321764fd937eef9d6b62022bcd"},
{file = "ruff-0.11.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7885d9a5e4c77b24e8c88aba8c80be9255fa22ab326019dac2356cff42089fc6"},
{file = "ruff-0.11.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1b5ab797fcc09121ed82e9b12b6f27e34859e4227080a42d090881be888755d4"},
{file = "ruff-0.11.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e231ff3132c1119ece836487a02785f099a43992b95c2f62847d29bace3c75ac"},
{file = "ruff-0.11.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a97c9babe1d4081037a90289986925726b802d180cca784ac8da2bbbc335f709"},
{file = "ruff-0.11.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8c4ddcbe8a19f59f57fd814b8b117d4fcea9bee7c0492e6cf5fdc22cfa563c8"},
{file = "ruff-0.11.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6224076c344a7694c6fbbb70d4f2a7b730f6d47d2a9dc1e7f9d9bb583faf390b"},
{file = "ruff-0.11.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:882821fcdf7ae8db7a951df1903d9cb032bbe838852e5fc3c2b6c3ab54e39875"},
{file = "ruff-0.11.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:dcec2d50756463d9df075a26a85a6affbc1b0148873da3997286caf1ce03cae1"},
{file = "ruff-0.11.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99c28505ecbaeb6594701a74e395b187ee083ee26478c1a795d35084d53ebd81"},
{file = "ruff-0.11.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9263f9e5aa4ff1dec765e99810f1cc53f0c868c5329b69f13845f699fe74f639"},
{file = "ruff-0.11.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:64ac6f885e3ecb2fdbb71de2701d4e34526651f1e8503af8fb30d4915a3fe345"},
{file = "ruff-0.11.11-py3-none-win32.whl", hash = "sha256:1adcb9a18802268aaa891ffb67b1c94cd70578f126637118e8099b8e4adcf112"},
{file = "ruff-0.11.11-py3-none-win_amd64.whl", hash = "sha256:748b4bb245f11e91a04a4ff0f96e386711df0a30412b9fe0c74d5bdc0e4a531f"},
{file = "ruff-0.11.11-py3-none-win_arm64.whl", hash = "sha256:6c51f136c0364ab1b774767aa8b86331bd8e9d414e2d107db7a2189f35ea1f7b"},
{file = "ruff-0.11.11.tar.gz", hash = "sha256:7774173cc7c1980e6bf67569ebb7085989a78a103922fb83ef3dfe230cd0687d"},
]
[[package]]
name = "typing-extensions"
version = "4.13.2"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"},
{file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"},
]
[metadata]
lock-version = "2.1"
python-versions = "^3.12"
content-hash = "32e576ced1cd9fd1078bf3656ed1726be6e76a63e31498a891a463e5c2078e60"
+65
View File
@@ -0,0 +1,65 @@
[project]
name = "installer-wizard"
version = "1.0.3"
description = ""
authors = [{ name = "Mikaël Capelle", email = "capelle.mikael@gmail.com" }]
license = "MIT"
readme = "README.md"
dynamic = ["dependencies"]
[tool.poetry]
package-mode = false
[tool.poetry.dependencies]
python = "^3.12"
pyqt6 = "6.7.1"
bain-wizard-interpreter = "1.0.4"
[tool.poetry.group.dev.dependencies]
pyright = "^1.1.401"
ruff = "^0.11.11"
poethepoet = "^0.34.0"
mobase-stubs = {version = "2.5.2", allow-prereleases = true}
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poe.tasks]
format-imports = "ruff check --select I . --fix"
format-ruff = "ruff format ."
format.sequence = ["format-imports", "format-ruff"]
lint-ruff = "ruff check ."
lint-ruff-format = "ruff format --check ."
lint-pyright = "pyright ."
lint.sequence = ["lint-ruff", "lint-ruff-format", "lint-pyright"]
lint.ignore_fail = "return_non_zero"
[tool.ruff]
target-version = "py312"
[tool.ruff.lint]
extend-select = ["B", "Q", "I"]
[tool.ruff.lint.isort.sections]
mobase = ["mobase"]
wizard = ["wizard"]
[tool.ruff.lint.isort]
required-imports = ["from __future__ import annotations"]
section-order = [
"future",
"standard-library",
"third-party",
"first-party",
"wizard",
"mobase",
"local-folder",
]
[tool.pyright]
exclude = ["lib", "venv", "src/ui"]
typeCheckingMode = "strict"
reportMissingTypeStubs = true
reportMissingModuleSource = false
pythonPlatform = "Windows"
-7
View File
@@ -1,7 +0,0 @@
black
PyQt5
mypy
flake8
flake8-black
mobase-stubs
git+https://github.com/Holt59/bain-wizard-interpreter
-45
View File
@@ -1,45 +0,0 @@
[flake8]
# Use black line length:
max-line-length = 88
extend-ignore =
# See https://github.com/PyCQA/pycodestyle/issues/373
E203,
exclude = lib,ui
[mypy]
warn_return_any = True
warn_unused_configs = True
namespace_packages = True
[mypy-antlr4.*]
ignore_missing_imports = True
[mypy-.ui.*]
ignore_missing_imports = True
[mypy-src.ui.*]
ignore_missing_imports = True
[mypy-wizard.antlr4.*]
ignore_errors = True
[mypy-pytest]
ignore_missing_imports = True
[tox:tox]
skipsdist = true
envlist = py38-lint
[testenv:py38-lint]
skip_install = true
deps =
black
mypy
flake8
flake8-black
mobase-stubs
git+https://github.com/Holt59/bain-wizard-interpreter
commands =
black src --check --diff --exclude "lib" --exclude "ui"
flake8 src
mypy src
+4
View File
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.16)
add_custom_target(installer_wizard ALL)
mo2_configure_python(installer_wizard MODULE)
+2 -2
View File
@@ -1,10 +1,10 @@
# -*- encoding: utf-8 -*-
"""
This file is the entry point of the module and must contain a createPlugin()
or createPlugins() function.
"""
from __future__ import annotations
import os
import site
+236 -171
View File
File diff suppressed because it is too large Load Diff
+99 -108
View File
@@ -1,28 +1,25 @@
# -*- encoding: utf-8 -*-
from __future__ import annotations
import re
import os
import re
import sys
from collections import defaultdict
from pathlib import Path
from typing import Dict, Optional, List, Union
from typing import Dict, List, Optional, Sequence, Union, cast
# MO2 ships with PyQt5, so you can use it in your plugins:
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtWidgets
import mobase
from PyQt6 import QtWidgets
from PyQt6.QtWidgets import QApplication
from wizard.runner import WizardRunnerState
import mobase
from .dialog import WizardInstallerDialog
from .runner import make_interpreter
from .utils import make_ini_tweaks, merge_ini_tweaks
class WizardInstaller(mobase.IPluginInstallerSimple):
"""
This is the actual plugin. MO2 has two types of installer plugin, this one is
"simple", i.e., it will work directly on the file-tree contained in the archive.
@@ -30,22 +27,19 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
it is valid (for this installer) and then modify it if required before extraction.
"""
# Regex used to parse settings:
# regex used to parse settings
RE_DESCRIPTION = re.compile(r"select([0-9]+)-description")
RE_OPTION = re.compile(r"select([0-9]+)-option([0-9]+)")
_organizer: mobase.IOrganizer
# List of selected options:
# list of selected options
_installerOptions: Dict[str, List[str]]
_installerUsed: bool
def __init__(self):
super().__init__()
# Method for IPlugin - I will not details these here since those are quite
# self-explanatory and are common to all plugins:
def init(self, organizer: mobase.IOrganizer):
self._organizer = organizer
return True
@@ -53,14 +47,17 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
def name(self):
return "BAIN Wizard Installer"
def localizedName(self) -> str:
return self.tr("BAIN Wizard Installer")
def author(self):
return "Holt59"
def description(self):
return self._tr("Installer for BAIN archive containing wizard scripts.")
return self.tr("Installer for BAIN archive containing wizard scripts.")
def version(self):
return mobase.VersionInfo(1, 0, 1)
return mobase.VersionInfo(1, 0, 2)
def isActive(self):
return self._organizer.pluginSetting(self.name(), "enabled")
@@ -78,28 +75,31 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
"prefer OMOD installer over this one when possible",
False,
),
# Above FOMOD:
# above FOMOD?
mobase.PluginSetting("priority", "priority of this installer", 120),
]
# Method for IPluginInstallerSimple:
# method for IPluginInstallerSimple
def priority(self):
return self._organizer.pluginSetting(self.name(), "priority")
def priority(self) -> int:
return cast(int, self._organizer.pluginSetting(self.name(), "priority"))
def isManualInstaller(self) -> bool:
return False
def onInstallationStart(
self, archive: str, reinstallation: bool, mod: Optional[mobase.IModInterface]
self,
archive: str,
reinstallation: bool,
current_mod: Optional[mobase.IModInterface],
):
self._installerUsed = False
self._installerOptions = {}
if mod:
settings = mod.pluginSettings(self.name())
if current_mod:
settings = current_mod.pluginSettings(self.name())
# First extract the description:
# first extract the description
descriptions: Dict[int, str] = {}
options: Dict[int, Dict[int, str]] = defaultdict(dict)
for setting, value in settings.items():
@@ -121,23 +121,27 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
self._installerOptions[desc].append(options[kdesc][index])
def onInstallationEnd(
self, result: mobase.InstallResult, mod: Optional[mobase.IModInterface]
self, result: mobase.InstallResult, new_mod: Optional[mobase.IModInterface]
):
if result != mobase.InstallResult.SUCCESS or not self._installerUsed or not mod:
if (
result != mobase.InstallResult.SUCCESS
or not self._installerUsed
or not new_mod
):
return
mod.clearPluginSettings(self.name())
new_mod.clearPluginSettings(self.name())
for i, desc in enumerate(self._installerOptions):
mod.setPluginSetting(self.name(), f"select{i}-description", desc)
new_mod.setPluginSetting(self.name(), f"select{i}-description", desc)
for iopt, opt in enumerate(self._installerOptions[desc]):
mod.setPluginSetting(self.name(), f"select{i}-option{iopt}", opt)
new_mod.setPluginSetting(self.name(), f"select{i}-option{iopt}", opt)
def _hasFomodInstaller(self) -> bool:
# Do not consider the NCC installer.
return bool(self._organizer.pluginSetting("Fomod Installer", "enabled"))
# do not consider the NCC installer
return self._organizer.isPluginEnabled("Fomod Installer")
def _hasOmodInstaller(self) -> bool:
return bool(self._organizer.pluginSetting("Omod Installer", "enabled"))
return self._organizer.isPluginEnabled("Omod Installer")
def _getWizardArchiveBase(
self, tree: mobase.IFileTree, data_name: str, checker: mobase.ModDataChecker
@@ -159,16 +163,16 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
if entry:
return tree
if len(tree) == 1 and isinstance(tree[0], mobase.IFileTree):
return self._getWizardArchiveBase(tree[0], data_name, checker)
if len(tree) == 1 and isinstance((root := tree[0]), mobase.IFileTree):
return self._getWizardArchiveBase(root, data_name, checker)
return None
def _getEntriesToExtract(
self,
tree: mobase.IFileTree,
extensions: List[str] = ["png", "jpg", "jpeg", "gif", "bmp", "ini"],
) -> List[mobase.FileTreeEntry]:
extensions: Sequence[str] = ["png", "jpg", "jpeg", "gif", "bmp", "ini"],
) -> list[mobase.FileTreeEntry]:
"""
Retrieve all the entries to extract from the given tree.
@@ -179,7 +183,7 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
Returns:
A list of entries corresponding to files with the given extensions.
"""
entries = []
entries: list[mobase.FileTreeEntry] = []
def fn(path: str, entry: mobase.FileTreeEntry):
if entry.isFile() and entry.hasSuffix(extensions):
@@ -202,21 +206,19 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
True if the file-tree can be installed, false otherwise.
"""
# Retrieve the name of the "data" folder:
# retrieve the name of the "data" folder
data_name = self._organizer.managedGame().dataDirectory().dirName()
# Retrieve the mod-data-checker:
checker: mobase.ModDataChecker = self._organizer.managedGame().feature(
mobase.ModDataChecker # type: ignore
)
# retrieve the mod-data-checker
checker = self._organizer.gameFeatures().gameFeature(mobase.ModDataChecker)
# Retrieve the base:
# retrieve the base
base = self._getWizardArchiveBase(tree, data_name, checker)
if not base:
return False
# Check FOMOD:
# check FOMOD for priority
fomod = base.exists("fomod/ModuleConfig.xml")
if (
fomod
@@ -232,9 +234,9 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
def install(
self,
name: mobase.GuessedString,
otree: mobase.IFileTree,
tree: mobase.IFileTree,
version: str,
modId: int,
nexus_id: int,
) -> Union[mobase.InstallResult, mobase.IFileTree]:
"""
Perform the actual installation.
@@ -242,9 +244,9 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
Args:
name: The "name" of the mod. This can be updated to change the name of the
mod.
otree: The original archive tree.
tree: The original archive tree.
version: The original version of the mod.
modId: The original ID of the mod.
nexus_id: The original ID of the mod.
Returns: We either return the modified file-tree (if the installation was
successful), or a InstallResult otherwise.
@@ -254,16 +256,14 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
of the mod, in case those were updated by the installer.
"""
# Retrieve the name of the "data" folder:
# retrieve the name of the "data" folder
data_name = self._organizer.managedGame().dataDirectory().dirName()
# Retrieve the mod-data-checker:
checker: mobase.ModDataChecker = self._organizer.managedGame().feature(
mobase.ModDataChecker # type: ignore
)
# retrieve the mod-data-checker
checker = self._organizer.gameFeatures().gameFeature(mobase.ModDataChecker)
# Retrive the "base" folder:
base = self._getWizardArchiveBase(otree, data_name, checker)
# retrieve the "base" folder
base = self._getWizardArchiveBase(tree, data_name, checker)
if not base or not checker:
return mobase.InstallResult.NOT_ATTEMPTED
@@ -271,9 +271,9 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
if wizard is None:
return mobase.InstallResult.NOT_ATTEMPTED
to_extract = self._getEntriesToExtract(otree)
to_extract = self._getEntriesToExtract(tree)
# Extract the script:
# extract the script
paths = self._manager().extractFiles([wizard] + to_extract, silent=False)
if len(paths) != len(to_extract) + 1:
return mobase.InstallResult.FAILED
@@ -289,29 +289,30 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
name,
{
Path(entry.path()): Path(path)
for entry, path in zip(to_extract, paths[1:])
for entry, path in zip(to_extract, paths[1:], strict=True)
if not path.endswith(".ini")
},
self._installerOptions,
self._parentWidget(),
)
dialog.scriptButtonClicked.connect(lambda: os.startfile(script)) # type: ignore
dialog.scriptButtonClicked.connect( # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
lambda: os.startfile(script)
)
# Note: Unlike the official installer, we do not have a "silent" setting,
# but it is really simple to add it.
if dialog.exec() == QtWidgets.QDialog.Accepted:
# We update the name with the user specified one:
# unlike the official installer, we do not have a "silent" setting, but it is
# really simple to add it
if dialog.exec() == QtWidgets.QDialog.DialogCode.Accepted:
# we update the name with the user specified one
name.update(dialog.name(), mobase.GuessQuality.USER)
# Create the tree with all the sub-packages:
tree = otree.createOrphanTree()
# create the tree with all the sub-packages
new_tree = tree.createOrphanTree()
for subpackage in dialog.subpackages():
entry = base.find(subpackage)
# Should never happens since we fetch the subpackage for the archive:
# should never happens since we fetch the subpackage for the archive
if not entry or not isinstance(entry, mobase.IFileTree):
print(
f"SubPackage {subpackage} not found in the archive.",
@@ -319,57 +320,48 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
)
continue
tree.merge(entry)
new_tree.merge(entry)
# Move all non-selected plugins to "optional":
optionals: List[mobase.FileTreeEntry] = []
for entry in tree:
if entry.isFile() and (
entry.hasSuffix(["esl", "esp", "esm"])
and entry.name() not in dialog.plugins()
):
optionals.append(entry)
# Do not keep empty optional folder:
if optionals:
optional = tree.addDirectory("optional")
for entry in optionals:
optional.insert(entry)
# Handle renames:
# handle renames
for original, new in dialog.renames().items():
# Entry should be at the root:
entry = tree.find(original)
# entry should be at the root
entry = new_tree.find(original)
if not entry:
print(f"Plugin {original} not found, cannot rename.")
continue
tree.move(entry, new)
new_tree.move(entry, new)
# move not selected plugins to optional
for plugin, enabled in dialog.plugins().items():
if not enabled:
entry = new_tree.find(plugin)
if not entry:
continue # silently fail since the plugin should be disabled
new_tree.addDirectory("optional").insert(entry)
# TODO: INI Tweaks:
alltweaks = dialog.tweaks()
for filename, tweaks in alltweaks.items():
# Find the original file (if any):
o_entry = tree.find(filename)
# find the original file (if any)
o_entry = new_tree.find(filename)
o_filename: Optional[str] = None
if o_entry:
# Find the filepath from the list of extracted files:
# find the filepath from the list of extracted files
index = to_extract.index(o_entry)
# +1 because the first one is the script.
# +1 because the first one is the script
o_filename = paths[index + 1]
# If the file existed before, we keep the new one at the same
# place:
# if the file existed before, we keep the new one at the same place
if o_entry or Path(filename).parts[0].lower() == "ini tweaks":
entry = tree.addFile(filename, replace_if_exists=True)
entry = new_tree.addFile(filename, replace_if_exists=True)
# Otherwise we create it in INI Tweaks
# otherwise we create it in INI Tweaks
else:
entry = tree.addFile(
entry = new_tree.addFile(
os.path.join("INI Tweaks", filename), replace_if_exists=True
)
@@ -383,24 +375,23 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
with open(filepath, "w") as fp:
fp.write(data)
# Mark stuff for saving:
# mark stuff for saving
self._installerUsed = True
self._installerOptions = dict(dialog.selectedOptions())
# Return the tree:
return tree
return new_tree
# If user requested a manual installation, we update the name (to keep it
# in the manual installation dialog) and just notify the installation manager:
# if user requested a manual installation, we update the name (to keep it
# in the manual installation dialog) and just notify the installation manager
elif dialog.isManualRequested():
name.update(dialog.name(), mobase.GuessQuality.USER)
return mobase.InstallResult.MANUAL_REQUESTED
# If user canceled, we simply notify the installation manager:
# if user canceled, we simply notify the installation manager
else:
return mobase.InstallResult.CANCELED
def _tr(self, str):
# We need this to translate string in Python. Check the common documentation
# for more details:
return QApplication.translate("WizardInstaller", str)
def tr(self, value: str) -> str:
# we need this to translate string in Python. Check the common documentation
# for more details
return QApplication.translate("WizardInstaller", value)
+156
View File
@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>WizardInstaller</name>
<message>
<location filename="installer.py" line="52" />
<source>BAIN Wizard Installer</source>
<translation type="unfinished" />
</message>
<message>
<location filename="installer.py" line="58" />
<source>Installer for BAIN archive containing wizard scripts.</source>
<translation type="unfinished" />
</message>
</context>
<context>
<name>WizardInstallerComplete</name>
<message>
<location filename="ui\wizardinstallercomplete.ui" line="0" />
<source>The installer script has finished. The following sub-packages and plugins will be installed.</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallercomplete.ui" line="0" />
<source>Sub-Packages:</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallercomplete.ui" line="0" />
<source>Plugins:</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallercomplete.ui" line="0" />
<source>INI Tweaks:</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallercomplete.ui" line="0" />
<source>Notes:</source>
<translation type="unfinished" />
</message>
</context>
<context>
<name>WizardInstallerDialog</name>
<message>
<location filename="ui\wizardinstallerdialog.ui" line="0" />
<location filename="dialog.py" line="688" />
<source>Next</source>
<translation type="unfinished" />
</message>
<message>
<location filename="dialog.py" line="690" />
<source>Install anyway</source>
<translation type="unfinished" />
</message>
<message>
<location filename="dialog.py" line="694" />
<source>Install</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerdialog.ui" line="0" />
<source>BAIN Wizard Installer</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerdialog.ui" line="0" />
<source>Name</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerdialog.ui" line="0" />
<source>Manual</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerdialog.ui" line="0" />
<source>Script</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerdialog.ui" line="0" />
<source>Back</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerdialog.ui" line="0" />
<source>Cancel</source>
<translation type="unfinished" />
</message>
</context>
<context>
<name>WizardInstallerPage</name>
<message>
<location filename="ui\wizardinstallerpage.ui" line="0" />
<source>Options:</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerpage.ui" line="0" />
<source>Description:</source>
<translation type="unfinished" />
</message>
</context>
<context>
<name>WizardInstallerRequires</name>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=" font-weight:600;"&gt;Warning:&lt;/span&gt; The following version requirements are not met for using this installer.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>Requirements</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>Graphics Extender</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>Wrye Bash</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>Need</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>Game</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>N/A</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>Have</source>
<translation type="unfinished" />
</message>
<message>
<location filename="ui\wizardinstallerrequires.ui" line="0" />
<source>Script Extender</source>
<translation type="unfinished" />
</message>
</context>
</TS>

Some files were not shown because too many files have changed in this diff Show More