mirror of
https://github.com/ModOrganizer2/pystubs-generation.git
synced 2026-07-27 14:07:13 -07:00
Compare commits
66
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49a77592f9 | ||
|
|
6fe9b1d569 | ||
|
|
dd80b67a0a | ||
|
|
8789b59f23 | ||
|
|
72c652daaa | ||
|
|
80a365f19a | ||
|
|
1b8d6840e2 | ||
|
|
d7c1ecd6f2 | ||
|
|
6a76dda9d7 | ||
|
|
0c807ad974 | ||
|
|
a3542ca1c4 | ||
|
|
d6760273a2 | ||
|
|
ece93e7cb3 | ||
|
|
4fa50f89a4 | ||
|
|
962a3c2c1f | ||
|
|
7c2581eb0c | ||
|
|
336d80a5c6 | ||
|
|
a1f5ef3a45 | ||
|
|
be6a6761f7 | ||
|
|
52f835dc75 | ||
|
|
9ee5222bbc | ||
|
|
4655e1f3eb | ||
|
|
c4a6e2266d | ||
|
|
966a84a59a | ||
|
|
3a5c16af21 | ||
|
|
3eb1daa053 | ||
|
|
0eca0f7644 | ||
|
|
7467a2b11c | ||
|
|
eb420fcd79 | ||
|
|
156b827389 | ||
|
|
104e8612d8 | ||
|
|
4f24d363ec | ||
|
|
2e4fd7c1a8 | ||
|
|
ee3faa0c87 | ||
|
|
c5ee7f8a43 | ||
|
|
33b7222b13 | ||
|
|
e083e0832e | ||
|
|
478af17c58 | ||
|
|
6ca51655aa | ||
|
|
0ec04f4e9e | ||
|
|
d43d067c84 | ||
|
|
06e0fe1cca | ||
|
|
c57280578d | ||
|
|
178b1d111d | ||
|
|
a5b374f3f3 | ||
|
|
14fa117b2d | ||
|
|
6cab2a555b | ||
|
|
b555debad7 | ||
|
|
4f9e212b93 | ||
|
|
1388c1113a | ||
|
|
15dae1d2bc | ||
|
|
0aa1e2d24f | ||
|
|
df29edf5a5 | ||
|
|
15d43de37e | ||
|
|
7b9c6ab32c | ||
|
|
318a4acfb1 | ||
|
|
820bc3e0fe | ||
|
|
c980dd024b | ||
|
|
c7d8442398 | ||
|
|
ae09efbab3 | ||
|
|
a203ee8215 | ||
|
|
9fa09d1b88 | ||
|
|
4d40644aa5 | ||
|
|
fa0facabe8 | ||
|
|
02be57db1d | ||
|
|
233c8f51e8 |
@@ -1,34 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
# Standard drop-in approach that should work for most people.
|
||||
- uses: ammaraskar/sphinx-action@master
|
||||
env:
|
||||
PYTHONPATH: .
|
||||
with:
|
||||
pre-build-command: "apt-get update -y && apt-get install -y libgl1-mesa-glx && cp stubs/2.3.0/mobase.pyi docs/mobase.py"
|
||||
docs-folder: "docs/"
|
||||
|
||||
- name: Install SSH Client 🔑
|
||||
uses: webfactory/ssh-agent@v0.2.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@3.6.1
|
||||
with:
|
||||
SSH: true
|
||||
REPOSITORY_NAME: ModOrganizer2/python-plugins-doc
|
||||
BRANCH: master
|
||||
FOLDER: docs/build/html
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Build Documentation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.12
|
||||
- uses: abatilo/actions-poetry@v2
|
||||
- name: Install
|
||||
run: poetry install
|
||||
- name: Install libgl1
|
||||
run: sudo apt install -y libgl1 libegl1 libglib2.0-0 libxkbcommon0 libdbus-1-3
|
||||
- name: Copy stubs
|
||||
run: |
|
||||
mkdir -p docs/src
|
||||
cp -r stubs/2.5.2/mobase-stubs docs/src/mobase
|
||||
- name: Build
|
||||
run: poetry run sphinx-build -b html docs/source docs/build
|
||||
env:
|
||||
PYTHONPATH: docs
|
||||
- if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
name: Deploy Documentation
|
||||
uses: JamesIves/github-pages-deploy-action@v4
|
||||
with:
|
||||
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
||||
repository-name: ModOrganizer2/python-plugins-doc
|
||||
branch: master
|
||||
folder: docs/build
|
||||
@@ -0,0 +1,20 @@
|
||||
name: Check Linting
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
checks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.12
|
||||
- uses: abatilo/actions-poetry@v2
|
||||
- name: Install
|
||||
run: |
|
||||
poetry install
|
||||
- name: Lint
|
||||
run: |
|
||||
poetry run poe lint
|
||||
@@ -1,18 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
# Standard drop-in approach that should work for most people.
|
||||
- uses: ammaraskar/sphinx-action@master
|
||||
env:
|
||||
PYTHONPATH: .
|
||||
with:
|
||||
pre-build-command: "apt-get update -y && apt-get install -y libgl1-mesa-glx && cp stubs/2.3.0/mobase.pyi docs/mobase.py"
|
||||
docs-folder: "docs/"
|
||||
@@ -1,40 +1,57 @@
|
||||
# This workflows will upload a Python Package using Twine when a release is created
|
||||
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
|
||||
|
||||
name: Upload Python Package
|
||||
name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
push:
|
||||
tags: ["*"]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
||||
build:
|
||||
name: Build distribution 📦
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Replace string
|
||||
uses: frabert/replace-string-action@v1.1
|
||||
id: version
|
||||
with:
|
||||
string: ${{ github.ref_name }}
|
||||
pattern: "v?([0-9][.][0-9][.][0-9]).*"
|
||||
replace-with: "$1"
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.12
|
||||
- uses: abatilo/actions-poetry@v2
|
||||
- name: Build
|
||||
run: |
|
||||
cd stubs/setup
|
||||
mkdir mobase-stubs
|
||||
cp -r ../${{ steps.version.outputs.replaced }}/mobase-stubs/* mobase-stubs/
|
||||
sed -i 's/__version__ = ".*"/__version__ = "${{ github.ref_name }}"/' mobase-stubs/__init__.pyi
|
||||
TAG=${{ github.ref_name }}
|
||||
poetry version ${TAG#v}
|
||||
poetry build
|
||||
- name: Store the distribution packages
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: stubs/setup/dist/
|
||||
|
||||
publish-to-pypi:
|
||||
name: Publish Python 🐍 distribution 📦 to PyPI
|
||||
needs:
|
||||
- build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Replace string
|
||||
uses: frabert/replace-string-action@v1.1
|
||||
id: version
|
||||
with:
|
||||
string: ${{ github.event.release.tag_name }}
|
||||
pattern: "v?([0-9][.][0-9][.][0-9]).*"
|
||||
replace-with: "$1"
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel twine
|
||||
- name: Build and publish
|
||||
env:
|
||||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||
run: |
|
||||
cd stubs/setup
|
||||
cp ../${{ steps.version.outputs.replaced }}/mobase.pyi mobase-stubs/__init__.pyi
|
||||
python setup.py sdist bdist_wheel
|
||||
twine upload dist/*
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: python-package-distributions
|
||||
path: dist/
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
||||
+2
-1
@@ -2,9 +2,10 @@
|
||||
.mypy_cache
|
||||
__pycache__
|
||||
.vscode
|
||||
**/*.egg-info
|
||||
|
||||
# The 'bin/' directory:
|
||||
bin
|
||||
docs/build
|
||||
docs/mobase.py
|
||||
docs/source/api
|
||||
docs/source/api
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Mod Organizer 2 - Python stubs generation
|
||||
|
||||
This little project can be used to generate python stubs (`.pyi` file) for the MO2 python
|
||||
This project can be used to generate python stubs (`.pyi` file) for the MO2 python
|
||||
interface `mobase`.
|
||||
|
||||
## Using the stubs
|
||||
@@ -16,119 +16,103 @@ MO2.
|
||||
You can install stubs for a specific version of MO2:
|
||||
|
||||
```bash
|
||||
pip install mobase-stubs==2.3.2.*
|
||||
```
|
||||
|
||||
If you want development stubs, you can install them this way:
|
||||
```bash
|
||||
# Clone this repository:
|
||||
git clone https://github.com/ModOrganizer2/pystubs-generation.git
|
||||
|
||||
# Install the stubs:
|
||||
cd pystubs-generation/stubs/setup
|
||||
pip install .
|
||||
pip install mobase-stubs==2.5.*
|
||||
```
|
||||
|
||||
Some words of warning:
|
||||
|
||||
- The stubs are as correct as possible, but some errors are expected.
|
||||
- If you see a `InterfaceNotImplemented` class anywhere in the stubs, it means that a proper interface is
|
||||
currently not available.
|
||||
- Some classes are said (in the stubs) to inherit `QWidget` or `QObject`. This is true on the C++ side but NOT
|
||||
on the python side. The inheritance is only added to help with auto-completion since these classes also
|
||||
override `__getattr__` to dispatch to the underlying `QWidget` or `QObject`. Some things might not work as
|
||||
expected with these class (e.g., `isintance(myObject, QObject)` will return `False`), which is why a
|
||||
`_object()` and `_widget()` method is also provided.
|
||||
- Some classes are said (in the stubs) to inherit `QWidget` or `QObject`. This is true
|
||||
on the C++ side but NOT on the python side. The inheritance is only added to help with
|
||||
auto-completion since these classes also override `__getattr__` to dispatch to the
|
||||
underlying `QWidget` or `QObject`. Some things might not work as expected with these
|
||||
class (e.g., `isinstance(myObject, QObject)` will return `False`), which is why a
|
||||
`_object()` and `_widget()` method is also provided.
|
||||
|
||||
## Generating the stubs
|
||||
|
||||
The stubs are generated using python by parsing the `mobase` module.
|
||||
You need the version of python that matches your current MO2 installation: e.g., if you have a `python38.dll` in
|
||||
your MO2 installation path, then you need **python 3.8**.
|
||||
You need the version of python that matches your current MO2 installation: e.g., if you
|
||||
have a `python310.dll` in your MO2 installation path, then you need **Python 3.10**.
|
||||
|
||||
To generate the stubs, you can run:
|
||||
|
||||
```
|
||||
# Change the output folder to whatever you want:
|
||||
python main.py -c configs\config-2.3.yml -o stubs\setup\mobase-stubs\__init__.pyi ${MO2_INSTALL_PATH}
|
||||
```bash
|
||||
# install the package
|
||||
poetry install
|
||||
|
||||
# change the output folder to whatever you want
|
||||
mo2-stubs-generator -c configs/config-2.4.yml -o mobase-stubs ${MO2_INSTALL_PATH}
|
||||
```
|
||||
|
||||
Where `${MO2_INSTALL_PATH}` is the path to your MO2 installation (the one containing `ModOrganizer.exe`).
|
||||
Where `${MO2_INSTALL_PATH}` is the path to your MO2 installation (the one
|
||||
containing `ModOrganizer.exe`).
|
||||
|
||||
The latest stubs are kept under `stubs/setup/mobase-stubs/__init__.pyi`, and when a new version is released,
|
||||
the stubs are backed-up under `stubs/x.y.z/mobase.pyi`.
|
||||
The stubs are generated under `stubs/setup/mobase-stubs` by default, you
|
||||
can change the output file by using the `-o` option.
|
||||
The stubs under `stubs/setup/mobase-stubs` should not be committed as these are
|
||||
generated from the version stubs under `stubs/${VERSION}/mobase-stubs`.
|
||||
|
||||
A few options are available for `mo2-stubs-generator`:
|
||||
|
||||
If you do not specify a `-o` option, output will go to `stdout`, so you should redirect.
|
||||
Warning and "critical" messages are printed to `stderr`.
|
||||
|
||||
A few options are available for `main.py`:
|
||||
|
||||
```
|
||||
usage: Stubs generator for the MO2 python interface [-h] [-o OUTPUT] [-v] [-c CONFIG] INSTALL_DIR
|
||||
```bash
|
||||
$ mo2-stubs-generator --help
|
||||
usage: stubs generator for the MO2 python interface [-h] [-o OUTPUT] [-v] [-c CONFIG] INSTALL_DIR
|
||||
|
||||
positional arguments:
|
||||
INSTALL_DIR installation directory of Mod Organizer 2
|
||||
|
||||
optional arguments:
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-o OUTPUT, --output OUTPUT
|
||||
output file (output to stdout if not specified)
|
||||
output folder (default stubs/setup/mobase-stubs)
|
||||
-v, --verbose verbose mode (all logs go to stderr)
|
||||
-c CONFIG, --config CONFIG
|
||||
configuration file
|
||||
```
|
||||
|
||||
The stubs generator will try hard to find a valid stubs for all classes and methods of `mobase`.
|
||||
A lot of information is available through the `-v` options. Without it, only conversions or fixes
|
||||
considered "strange" will be outputed.
|
||||
For instance, here is the output with the current `config-2.3.yml` file:
|
||||
|
||||
```
|
||||
WARNING: Replacing IOrganizer::FileInfo with FileInfo.
|
||||
WARNING: Replacing IOrganizer::FileInfo with FileInfo.
|
||||
WARNING: Replacing IPluginInstaller::EInstallResult with InstallResult.
|
||||
WARNING: Replacing IPluginInstaller::EInstallResult with InstallResult.
|
||||
```
|
||||
|
||||
As you can see, only a few types were manually fixed (specified in `config-2.3.yml`).
|
||||
The stubs generator will try hard to find a valid stubs for all classes
|
||||
and methods of `mobase`.
|
||||
A lot of information is available through the `-v` options. Without it,
|
||||
only conversions or fixes considered "strange" will be shown.
|
||||
|
||||
## Configuration file
|
||||
|
||||
The configuration file contains information for the stubs that cannot be deduced by `main` (or are too
|
||||
complex to deduce), and the documentation for everything.
|
||||
The configuration file contains information for the stubs that cannot be
|
||||
deduced by `main` (or are too complex to deduce), and the documentation for everything.
|
||||
|
||||
## Uploading the stubs to pypi
|
||||
|
||||
The upload of the stubs to https://pypi.org/project/mobase-stubs/ has to be done manually. Here
|
||||
are the steps:
|
||||
The upload of the stubs to [https://pypi.org/project/mobase-stubs/](https://pypi.org/project/mobase-stubs/)
|
||||
should be done automatically when a new Github tag is pushed.
|
||||
|
||||
1. Check the version of the stubs:
|
||||
- The version is specified in the configuration file. If you need to modify the stubs of the
|
||||
current version, you need to add a `.postX` after the version since PyPi does not allow
|
||||
re-upload of the same release.
|
||||
2. Generate the stubs using the procedure above. You should generate the stubs under `stubs/setup/mobase-stubs/__init__.pyi`.
|
||||
3. If necessary, update the dependencies in `setup.py` (`PyQt5-stubs` version and python version).
|
||||
4. Go to `stubs/setup` and run:
|
||||
## Extras — Using `mobase` in a Python interpreter
|
||||
|
||||
It is possible to start a (i)python interpreter with `mobase` imported by running
|
||||
|
||||
```bash
|
||||
python setup.py sdist bdist_wheel
|
||||
twine upload dist/*
|
||||
python -i -m mo2.stubs.generator.loader ${MO2_INSTALL_PATH}
|
||||
```
|
||||
|
||||
You need to set the environment variables `TWINE_USERNAME` and `TWINE_PASSWORD` to appropriate values
|
||||
before running `twine upload`.
|
||||
You can also import `mobase` in your code using the following (after installing
|
||||
this package):
|
||||
|
||||
## Extras — Starts a python interpreter with `mobase`
|
||||
```python
|
||||
from mo2.stubs.generator import load_mobase
|
||||
|
||||
It is possible to start a (i)python interpret with `mobase` imported by running:
|
||||
mobase = load_mobase(MO2_INSTALL_PATH)
|
||||
|
||||
```
|
||||
python -im generator.loader ${MO2_INSTALL_PATH}
|
||||
# the above will probably not give you type-completion in your IDE or typing, so
|
||||
# you can use the following (if the stubs are installed)
|
||||
load_mobase(MO2_INSTALL_PATH)
|
||||
import mobase
|
||||
import mobase.widgets
|
||||
```
|
||||
|
||||
This has no real usage except for MO2 developers since most classes from the `mobase` module cannot be instantiated.
|
||||
**Note:** Most classes in `mobase` cannot be instantiated, so this is mostly intended
|
||||
for MO2 developers.
|
||||
|
||||
# License
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -138,4 +122,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
See [LICENSE](LICENSE).
|
||||
See [LICENSE](LICENSE).
|
||||
|
||||
+200
-78
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = source
|
||||
BUILDDIR = build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
@@ -1,35 +0,0 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=source
|
||||
set BUILDDIR=build
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
@@ -1,4 +0,0 @@
|
||||
sphinx-rtd-theme
|
||||
sphinx-autodoc-typehints
|
||||
sphinx-automodapi
|
||||
PyQt5
|
||||
+7
-11
@@ -10,21 +10,13 @@
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../stubs/2.3rc1/"))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = "MO2 Python Plugin API"
|
||||
copyright = "2020, Holt59"
|
||||
copyright = "2023, Holt59"
|
||||
author = "Holt59"
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = "2.3rc1"
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
@@ -35,8 +27,9 @@ extensions = [
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx_autodoc_typehints",
|
||||
"sphinx.ext.napoleon",
|
||||
"autoapi.extension",
|
||||
# "sphinx.ext.autosummary",
|
||||
"sphinx_automodapi.automodapi",
|
||||
# "sphinx_automodapi.automodapi",
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
@@ -47,6 +40,9 @@ templates_path = ["_templates"]
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = []
|
||||
|
||||
autoapi_dirs = ["../src"]
|
||||
autoapi_member_order = "groupwise"
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
@@ -69,5 +65,5 @@ html_favicon = "mo2.ico"
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ["_static"]
|
||||
# html_static_path = ["_static"]
|
||||
html_extra_path = [".nojekyll"]
|
||||
|
||||
@@ -18,7 +18,6 @@ This documentation is dedicated to writting MO2 **Python** plugins.
|
||||
plugin-types
|
||||
writing-plugins
|
||||
faq
|
||||
mobase
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
``mobase`` API
|
||||
==============
|
||||
|
||||
.. currentmodule:: mobase
|
||||
|
||||
.. automodapi:: mobase
|
||||
:no-inheritance-diagram:
|
||||
:no-heading:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
@@ -1,7 +0,0 @@
|
||||
mobase
|
||||
======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
mobase
|
||||
@@ -64,10 +64,8 @@ These plugins (shall eventually) implement all the game specific features and fu
|
||||
able to add support for further games.
|
||||
The plugin is also responsible to help MO determine if (and where) the game is installed in the first place.
|
||||
Since supporting a game properly requires extensions in many places of the UI.
|
||||
To allow this without creating one huge plugin interface that involves every aspect of MO, game plugins
|
||||
expose a *feature list*.
|
||||
The list of possible features can be found in the "game_features" project and each feature can itself be
|
||||
considered a plugin interface.
|
||||
To allow this without creating one huge plugin interface that involves every aspect of MO,
|
||||
game plugins can register only the features they need to MO2 using :meth:`registerFeature<mobase.IGameFeatures.registerFeature>`
|
||||
|
||||
As an example for a game feature take BSA invalidation: If the game requires BSA invalidation it will implement
|
||||
this feature.
|
||||
@@ -147,4 +145,4 @@ File Mappings
|
||||
|
||||
This interface allows plugins to add virtual file (or directory) links to the virtual file system in addition to the
|
||||
mod files.
|
||||
Profile-local save games, ini-files and load-orders are all implemented this way in MO2.
|
||||
Profile-local save games, ini-files and load-orders are all implemented this way in MO2.
|
||||
|
||||
+82
-25
@@ -15,7 +15,7 @@ This guide assumes that:
|
||||
`Python extension <https://marketplace.visualstudio.com/items?itemName=ms-python.python>`_.
|
||||
- You have Python installed: https://www.python.org/downloads/.
|
||||
|
||||
- It is recommended but not mandatory to use the Python version that is used by MO2.
|
||||
- You must use the Python version that used by MO2.
|
||||
You can check the ``pythonXX.dll`` in the MO2 installation folder to find the Python version used by MO2 (``python38.dll`` means Python 3.8).
|
||||
- You obviously need a valid MO2 installation: https://github.com/modorganizer2/modorganizer/releases
|
||||
|
||||
@@ -28,8 +28,8 @@ Preparation
|
||||
-----------
|
||||
|
||||
**Note:** This part is optional but highly recommended if you want a proper environment to work with.
|
||||
Everything here is written to be as simple as possible but you can of course adapt it to your preferences: use a python virtual
|
||||
environment, use workspace settings instead of global ones, etc.
|
||||
Everything here is written to be as simple as possible but you can of course adapt it to your preferences:
|
||||
use a python virtual environment, use workspace settings instead of global ones, etc.
|
||||
|
||||
1. Get the ``mobase`` stubs
|
||||
...........................
|
||||
@@ -39,11 +39,14 @@ as ``flake8`` or ``mypy``.
|
||||
Instead, we provide `stubs <https://stackoverflow.com/questions/59051631/what-is-the-use-of-stub-files-pyi-in-python>`_
|
||||
which can be used for auto-completion or type-checking.
|
||||
|
||||
The stubs for ``mobase`` are available at https://github.com/ModOrganizer2/pystubs-generation/tree/master/stubs.
|
||||
You want to download the ``mobase.pyi`` file in the folder corresponding to your MO2 version and put it under ``$MO2DIR/plugins/data``.
|
||||
You can install the stubs for ``mobase`` using ``pip``:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install mobase-stubs
|
||||
|
||||
This will install the stubs for ``mobase`` but also for PyQt5, which is heavily used by MO2.
|
||||
|
||||
**Note:** It is possible to put the stubs in a different location, but we are going to use ``$MO2DIR/plugins/data`` for PyQt5,
|
||||
so we might as well use it for the stubs.
|
||||
|
||||
2. Configure Visual Studio Code for ``mobase``
|
||||
..............................................
|
||||
@@ -57,32 +60,86 @@ Open ``settings.json`` (Ctrl+Shift+P, then "Open Settings (JSON)"), and add the
|
||||
"python.linting.enabled": true,
|
||||
"python.linting.mypyEnabled": true,
|
||||
"python.linting.flake8Enabled": true,
|
||||
"python.autoComplete.extraPaths": [
|
||||
"$MO2DIR\\plugins\\data",
|
||||
]
|
||||
|
||||
3. Configure ``mypy`` to find the ``mobase`` stubs
|
||||
..................................................
|
||||
3. [Optional] Configure ``black`` to auto-format your source files
|
||||
..................................................................
|
||||
|
||||
There are multiply way to configure ``mypy``:
|
||||
This step is optional for your own plugin but recent MO2 plugins use ``black``
|
||||
to get consistent formatting.
|
||||
|
||||
1. You can create a ``mypy.ini`` file somewhere containing:
|
||||
You can install ``black`` with ``pip``:
|
||||
|
||||
.. code-block:: ini
|
||||
.. code::
|
||||
|
||||
[mypy]
|
||||
mypy_path = $MO2DIR\plugins\data
|
||||
pip install black flake8-black
|
||||
|
||||
And then add the following to ``settings.json`` (with the correct path):
|
||||
To configure Visual Studio Code to auto-format your code with ``black`` when saving, open ``settings.json``
|
||||
(Ctrl+Shift+P, then "Open Settings (JSON)"), and add the following entries:
|
||||
|
||||
.. code-block:: json-object
|
||||
|
||||
"python.linting.mypyArgs": [
|
||||
"--config-file=path-to-mypy.ini",
|
||||
]
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"python.formatting.provider": "black",
|
||||
|
||||
2. You can set the ``MYPYPATH`` environment variable to ``$MO2DIR\plugins\data`` (this requires
|
||||
restarting VS code).
|
||||
|
||||
4. [Optional] Automatically reload plugins during development
|
||||
.............................................................
|
||||
|
||||
This section is optional and requires you to already have written a "working"
|
||||
plugin (a plugin that MO2 can load).
|
||||
|
||||
Since MO2 2.4 alpha 6, a new command has been added to ``ModOrganizer.exe`` to
|
||||
reload plugins during execution.
|
||||
If your plugin is named "My Plugin", you can use the following command to reload
|
||||
it while MO2 is running:
|
||||
|
||||
.. code::
|
||||
|
||||
$MO2DIR\ModOrganizer.exe reload-plugin "My Plugin"
|
||||
|
||||
If you are using Visual Studio Code, you can send this command to MO2 automatically
|
||||
after saving files from your project.
|
||||
|
||||
1. Create a "reload plugin" task in Visual Studio Code (Ctrl+Shift+P then
|
||||
``Tasks: Configure task`` or open ``.vscode/tasks.json``) using the following
|
||||
snippet (replace the name and directory as needed):
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// .vscode/tasks.json
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "reload plugin",
|
||||
"type": "shell",
|
||||
"command": "$MO2DIR/ModOrganizer.exe",
|
||||
"args": [
|
||||
"reload-plugin", "My Plugin"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
2. Install the `Trigger Task on Save <https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.triggertaskonsave>`_
|
||||
extension from Visual Studio Code marketplace.
|
||||
|
||||
3. Add the following to your Visual Studio Code settings (``.vscode/settings.json``)
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
// .vscode/settings.json
|
||||
{
|
||||
"triggerTaskOnSave.on": true,
|
||||
"triggerTaskOnSave.tasks": {
|
||||
"reload plugin": [
|
||||
"*.py"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Testing the setup
|
||||
-----------------
|
||||
@@ -128,8 +185,8 @@ If your setup is valid, here is what you should have.
|
||||
|
||||
.. image:: images/check-setup-3.png
|
||||
|
||||
If everything is as above, you can delete the test file and move on to writting
|
||||
If everything is as above, you can delete the test file and move on to writing
|
||||
your own plugin!
|
||||
|
||||
|
||||
.. |error-window| image:: images/error-window.png
|
||||
.. |error-window| image:: images/error-window.png
|
||||
|
||||
@@ -226,6 +226,8 @@ These plugins are not as well documented as the ones in the repository above.
|
||||
plugins and should mostly be investigated if you want to add a game to it.
|
||||
- `FNIS Tool <https://github.com/ModOrganizer2/modorganizer-fnistool>`_ [``IPluginTool``]:
|
||||
Plugin to integrate FNIS into MO2.
|
||||
- `Installer Wizard <https://github.com/ModOrganizer2/modorganizer-installer_wizard>`_ [``IPluginInstaller``]:
|
||||
Installer for BAIN archives containing wizard scripts.
|
||||
- `Preview DDS <https://github.com/ModOrganizer2/modorganizer-preview_dds>`_ [``IPluginPreview``]:
|
||||
Plugin to preview DDS files. Quite complex due to the use
|
||||
of OpenGL for display.
|
||||
@@ -243,7 +245,7 @@ These plugins are not as well documented as the ones in the repository above.
|
||||
Unofficial Plugins
|
||||
..................
|
||||
|
||||
These plugins have been created by developpers for MO2 and are usually distributed on Nexus.
|
||||
These plugins have been created by developers for MO2 and are usually distributed on Nexus.
|
||||
|
||||
- `Merge Plugins Hide <https://github.com/deorder/mo2-plugins>`_ [``IPluginTool``]:
|
||||
Hide / unhide plugins that were merged using ``Merge Plugins`` or ``zMerge``.
|
||||
@@ -254,4 +256,67 @@ These plugins have been created by developpers for MO2 and are usually distribut
|
||||
- `Sync Mod Order <https://github.com/deorder/mo2-plugins>`_ [``IPluginTool``]:
|
||||
Synchronize mod order from current profile to another while keeping the (enabled/disabled) state intact.
|
||||
|
||||
*Feel free to open an issue or a pull-request if you want to add your own plugin to the list.*
|
||||
*Feel free to open an issue or a pull-request if you want to add your own plugin to the list.*
|
||||
|
||||
Internationalization
|
||||
--------------------
|
||||
|
||||
If you plan to distribute your plugin, it is often a good idea to provide translations for it.
|
||||
|
||||
Adding translation code
|
||||
.......................
|
||||
|
||||
Mod Organizer uses Qt translation system, so you need to adapt your plugin code to provide
|
||||
translation strings.
|
||||
To do this, you need two things:
|
||||
|
||||
1. In every class containing strings you need to translate, you must add a ``__tr`` function
|
||||
that takes a ``str`` input and call `QApplication.translate` on it (see example below).
|
||||
2. You need to wrap all translatable strings in a call to ``self.__str("My String")`` (see
|
||||
example below).
|
||||
|
||||
.. code:: python
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
class MyPlugin(...):
|
||||
|
||||
def localizedName(self) -> str:
|
||||
# Use self.__tr to wrap string you want translatable.
|
||||
return self.__tr("My Plugin Name")
|
||||
|
||||
def __tr(self, txt: str) -> str:
|
||||
# The first argument must EXACTLY match the class name:
|
||||
return QApplication.translate("MyPlugin", txt)
|
||||
|
||||
Generating Qt translation files
|
||||
...............................
|
||||
|
||||
Once your code is updated, you need to generate the Qt translation file ``.ts``.
|
||||
You can use ``PyQt5.lupdate_main`` for this:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
PyQt5.lupdate_main mysourcefile.py -ts mysourcefile.ts
|
||||
|
||||
You should generate a single translation file for your whole plugin even if it contains
|
||||
multiple files by passing all Python file and Qt UI (``.ui``) file to the command above.
|
||||
|
||||
Translating
|
||||
...........
|
||||
|
||||
Now that you have the original ``.ts`` file, you need to translate it in order to obtain
|
||||
translation files for other languages.
|
||||
To do so, you can use online services such as `Transifex <https://www.transifex.com>`_ or
|
||||
simply Qt Linguistic tools.
|
||||
|
||||
Distributing translations
|
||||
.........................
|
||||
|
||||
Once you have obtained translation files for another language, e.g. French, you need to
|
||||
compile it into a ``.qm`` file and then ship it.
|
||||
|
||||
- If you are using a single Python file plugin ``myplugin.py``, the name of the compiled
|
||||
translation must be ``myplugin_fr.qm``.
|
||||
- If you are shipping a module ``mymoduleplugin``, the name of the compiled translation
|
||||
must be ``mymoduleplugin``.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user