mirror of
https://github.com/loot/libloot-python.git
synced 2026-07-27 14:14:13 -07:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01a8567ed8 | ||
|
|
7ccfe6d7f4 | ||
|
|
2106ab4f01 |
@@ -1,88 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
# Don't run this workflow when a tag is pushed.
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
MSVC_CONFIG: RelWithDebInfo
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
runs-on: windows-2025
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [Win32, x64]
|
||||
python-version: [3.7]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get Python architecture
|
||||
id: get-python-architecture
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ matrix.platform }}" == "Win32" ]]
|
||||
then
|
||||
PLATFORM=x86
|
||||
else
|
||||
PLATFORM=x64
|
||||
fi
|
||||
echo "architecture=$PLATFORM" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: ${{ steps.get-python-architecture.outputs.architecture }}
|
||||
|
||||
- name: Get descriptive version
|
||||
id: get-version
|
||||
shell: bash
|
||||
run: |
|
||||
GIT_DESCRIBE=$(git describe --tags --long --abbrev=7)
|
||||
DESC_REF=${GIT_DESCRIBE}_${GITHUB_REF#refs/*/}
|
||||
SAFE_DESC_REF=${DESC_REF//[\/<>\"|]/_}
|
||||
echo "version=$SAFE_DESC_REF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run CMake
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G "Visual Studio 17 2022" -A ${{ matrix.platform }} -DCPACK_PACKAGE_VERSION="${{ steps.get-version.outputs.version }}-python${{ matrix.python-version }}"
|
||||
cmake --build . --config ${{ env.MSVC_CONFIG }}
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd build
|
||||
ctest -C ${{ env.MSVC_CONFIG }}
|
||||
|
||||
- name: Build archive
|
||||
id: build-archive
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
cpack -C ${{ env.MSVC_CONFIG }}
|
||||
|
||||
VERSION="${{ steps.get-version.outputs.version }}-python${{ matrix.python-version }}"
|
||||
if [[ "${{ matrix.platform }}" == "Win32" ]]
|
||||
then
|
||||
PLATFORM=win32
|
||||
else
|
||||
PLATFORM=win64
|
||||
fi
|
||||
|
||||
echo "filename=libloot-python-${VERSION}-${PLATFORM}.zip" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.build-archive.outputs.filename }}
|
||||
path: build/package/${{ steps.build-archive.outputs.filename }}
|
||||
if: github.event_name == 'push'
|
||||
@@ -1,92 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: '*'
|
||||
|
||||
env:
|
||||
MSVC_CONFIG: RelWithDebInfo
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
runs-on: ubuntu-18.04
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
git_tag: ${{ steps.get-git-tag.outputs.name }}
|
||||
|
||||
steps:
|
||||
- name: Get Git tag
|
||||
id: get-git-tag
|
||||
run: echo "name=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.get-git-tag.outputs.name }}
|
||||
release_name: libloot-python v${{ steps.get-git-tag.outputs.name }}
|
||||
body: |
|
||||
Requires Windows 7 or later and the [MSVC 2022 x86 redistributable](https://aka.ms/vs/17/release/vc_redist.x86.exe), and [7-Zip](http://www.7-zip.org/) to extract the archive.
|
||||
|
||||
windows:
|
||||
runs-on: windows-2025
|
||||
needs: create_release
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [Win32, x64]
|
||||
python-version: [3.7]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Get descriptive version
|
||||
id: get-version
|
||||
shell: bash
|
||||
run: |
|
||||
GIT_DESCRIBE=$(git describe --tags --long --abbrev=7)
|
||||
DESC_REF=${GIT_DESCRIBE}_${GITHUB_REF#refs/*/}
|
||||
SAFE_DESC_REF=${DESC_REF//[\/<>\"|]/_}
|
||||
echo "version=$SAFE_DESC_REF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run CMake
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G "Visual Studio 17 2022" -A ${{ matrix.platform }} -DCPACK_PACKAGE_VERSION="${{ steps.get-version.outputs.version }}-python${{ matrix.python-version }}"
|
||||
cmake --build . --config ${{ env.MSVC_CONFIG }}
|
||||
|
||||
- name: Build archive
|
||||
id: build-archive
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
cpack -C ${{ env.MSVC_CONFIG }}
|
||||
|
||||
VERSION="${{ steps.get-version.outputs.version }}-python${{ matrix.python-version }}"
|
||||
if [[ "${{ matrix.platform }}" == "Win32" ]]
|
||||
then
|
||||
PLATFORM=win32
|
||||
else
|
||||
PLATFORM=win64
|
||||
fi
|
||||
|
||||
echo "filename=libloot-python-${VERSION}-${PLATFORM}.zip" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload Archive
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
asset_path: build/package/${{ steps.build-archive.outputs.filename }}
|
||||
asset_name: ${{ steps.build-archive.outputs.filename }}
|
||||
asset_content_type: application/x-7z-compressed
|
||||
+39
-15
@@ -1,5 +1,5 @@
|
||||
|
||||
cmake_minimum_required (VERSION 3.4)
|
||||
cmake_minimum_required (VERSION 3.1)
|
||||
project (libloot-python)
|
||||
include(ExternalProject)
|
||||
|
||||
@@ -40,7 +40,7 @@ configure_file("${CMAKE_SOURCE_DIR}/python/setup.py" "${CMAKE_BINARY_DIR}/genera
|
||||
# pybind11
|
||||
#######################################
|
||||
|
||||
set(PYBIND11_VERSION "2.9.2")
|
||||
set(PYBIND11_VERSION "2.4.2")
|
||||
set(PYBIND11_URL "https://github.com/pybind/pybind11/archive/v${PYBIND11_VERSION}.tar.gz")
|
||||
set(PYBIND11_DOWNLOAD_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-${PYBIND11_VERSION}.tar.gz")
|
||||
set(PYBIND11_EXTRACTED_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-${PYBIND11_VERSION}")
|
||||
@@ -84,6 +84,20 @@ link_directories(${LIBLOOT_EXTRACTED_PATH})
|
||||
set(LIBLOOT_STATIC_LIBRARY "${CMAKE_STATIC_LIBRARY_PREFIX}loot${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
set(LIBLOOT_SHARED_LIBRARY "${CMAKE_SHARED_LIBRARY_PREFIX}loot${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
|
||||
#######################################
|
||||
# testing-plugins
|
||||
#######################################
|
||||
|
||||
# This is a bit messy because the testing-plugins aren't actually required to
|
||||
# build libloot-python, but having them as a dependency is the easiest way to
|
||||
# manage downloading and moving them to the expected location.
|
||||
ExternalProject_Add(testing-plugins
|
||||
PREFIX "external"
|
||||
URL "https://github.com/Ortham/testing-plugins/archive/1.4.1.tar.gz"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
#######################################
|
||||
# Python Module
|
||||
#######################################
|
||||
@@ -96,7 +110,7 @@ pybind11_add_module(libloot-python "${CMAKE_SOURCE_DIR}/src/main.cpp"
|
||||
# conventions (no lib, no -python).
|
||||
set_target_properties(libloot-python PROPERTIES OUTPUT_NAME loot)
|
||||
|
||||
add_dependencies(libloot-python libloot)
|
||||
add_dependencies(libloot-python libloot testing-plugins)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
target_link_libraries(libloot-python PRIVATE ${LIBLOOT_STATIC_LIBRARY})
|
||||
@@ -116,6 +130,13 @@ add_custom_command(TARGET libloot-python POST_BUILD
|
||||
"${LIBLOOT_EXTRACTED_PATH}/${LIBLOOT_SHARED_LIBRARY}"
|
||||
"$<TARGET_FILE_DIR:libloot-python>/${LIBLOOT_SHARED_LIBRARY}")
|
||||
|
||||
# Copy testing plugins
|
||||
ExternalProject_Get_Property(testing-plugins SOURCE_DIR)
|
||||
add_custom_command(TARGET libloot-python POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${SOURCE_DIR}
|
||||
$<TARGET_FILE_DIR:libloot-python>)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_test(NAME python
|
||||
@@ -156,22 +177,25 @@ ENDIF ()
|
||||
# Get version info using Git if available
|
||||
find_package(Git)
|
||||
|
||||
IF (NOT DEFINED CPACK_PACKAGE_VERSION)
|
||||
IF (GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --long --always --abbrev=7
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE_STRING
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
IF (GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --long --always
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE_STRING
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REPLACE "/" "-" GIT_DESCRIBE_STRING ${GIT_DESCRIBE_STRING})
|
||||
ELSE()
|
||||
SET (GIT_DESCRIBE_STRING "unknown-version")
|
||||
ENDIF ()
|
||||
IF (DEFINED ENV{APPVEYOR_REPO_BRANCH})
|
||||
set(GIT_DESCRIBE_STRING "${GIT_DESCRIBE_STRING}_$ENV{APPVEYOR_REPO_BRANCH}")
|
||||
ELSEIF (DEFINED ENV{TRAVIS_BRANCH})
|
||||
set(GIT_DESCRIBE_STRING "${GIT_DESCRIBE_STRING}_$ENV{TRAVIS_BRANCH}")
|
||||
ENDIF()
|
||||
|
||||
set(CPACK_PACKAGE_VERSION "${GIT_DESCRIBE_STRING}-python$ENV{PYTHON_VERSION}")
|
||||
ENDIF()
|
||||
string(REPLACE "/" "-" GIT_DESCRIBE_STRING ${GIT_DESCRIBE_STRING})
|
||||
ELSE()
|
||||
SET (GIT_DESCRIBE_STRING "unknown-version")
|
||||
ENDIF ()
|
||||
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
set(CPACK_PACKAGE_VERSION "${GIT_DESCRIBE_STRING}-python$ENV{PYTHON_VERSION}")
|
||||
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package")
|
||||
|
||||
include(CPack)
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
libloot-python
|
||||
==============
|
||||
|
||||
**This repository is no longer maintained. A more complete and up to date Python wrapper can be found in the [libloot repository](https://github.com/loot/libloot/tree/aaacebefa053a6b7504bf61a73d2783a5436ca25/python).**
|
||||
|
||||

|
||||
[](https://ci.appveyor.com/project/LOOT/libloot-python/branch/master)
|
||||
[](http://loot-api-python.readthedocs.io/)
|
||||
|
||||
A Python module that wraps libloot, generated by [pybind11](https://github.com/pybind/pybind11). Not everything in the API is exposed: coverage can be extended on request (or by pull request).
|
||||
|
||||
## Downloads
|
||||
|
||||
Releases are hosted on [GitHub](https://github.com/loot/libloot-python/releases).
|
||||
|
||||
Snapshot builds are available as artifacts from [GitHub Actions runs](https://github.com/loot/libloot-python/actions), though they are only kept for 90 days and can only be downloaded when logged into a GitHub account. The snapshot build archives are named like so:
|
||||
Snapshot builds are available on [Bintray](https://bintray.com/loot/snapshots/libloot-python). The snapshot build archives are named like so:
|
||||
|
||||
```
|
||||
libloot-python-<short revision ID>-python<python version>-win<architecture>.zip
|
||||
```
|
||||
|
||||
For example `libloot-python-94de368-python3.7-win32.zip` was built using the revision with shortened commit ID `94de368`.
|
||||
For example `libloot-python-94de368-python2.7-win32.zip` was built using the revision with shortened commit ID `94de368`.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
os: Visual Studio 2017
|
||||
|
||||
version: "{build}-{branch}"
|
||||
|
||||
configuration: RelWithDebInfo
|
||||
|
||||
platform:
|
||||
- Win32
|
||||
- x64
|
||||
|
||||
environment:
|
||||
bintray_auth_token:
|
||||
secure: PgsEA6TjHVf718zMnK7J/fT1hUAVNKBeWhpYgYaeCyeZk37VT4Ics6j7+B7ElLEr
|
||||
github_auth_token:
|
||||
secure: yDqT5l/e5MntbW99V6+MHlfFgNv+UIogFfeyUVqtFk5lFRB/dAraLLwKCLl6y+DH
|
||||
|
||||
matrix:
|
||||
- PYTHON_VERSION: 2.7
|
||||
- PYTHON_VERSION: 3.7
|
||||
|
||||
install:
|
||||
- ps: (New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/Ortham/ci-scripts/2.0.0/delete_old_bintray_versions.py', "$env:APPVEYOR_BUILD_FOLDER\delete_old_bintray_versions.py")
|
||||
- ps: (New-Object Net.WebClient).DownloadFile('https://github.com/WrinklyNinja/testing-plugins/archive/1.4.1.zip', "$PWD/1.4.1.zip")
|
||||
- 7z x 1.4.1.zip
|
||||
- mv testing-plugins-1.4.1 testing-plugins
|
||||
|
||||
before_build:
|
||||
- ps: $env:PYTHON_DIRECTORY_VERSION=$env:PYTHON_VERSION.Replace(".", "")
|
||||
- cd %APPVEYOR_BUILD_FOLDER%
|
||||
- ps: mkdir build
|
||||
- cd build
|
||||
- ps: |
|
||||
if ($env:PLATFORM -eq 'Win32') {
|
||||
cmake .. -G "Visual Studio 15 2017" -DPYTHON_EXECUTABLE="C:\Python${env:PYTHON_DIRECTORY_VERSION}\python.exe"
|
||||
} else {
|
||||
cmake .. -G "Visual Studio 15 2017" -A x64 -DPYTHON_EXECUTABLE="C:\Python${env:PYTHON_DIRECTORY_VERSION}-x64\python.exe"
|
||||
}
|
||||
|
||||
build:
|
||||
verbosity: minimal
|
||||
project: 'c:\projects\libloot-python\build\libloot-python.sln'
|
||||
|
||||
test_script:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\build
|
||||
- ctest -C %CONFIGURATION%
|
||||
|
||||
after_test:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\build
|
||||
- cpack -C %CONFIGURATION%
|
||||
- ps: $env:GIT_DESCRIBE = ((git describe --tags --long --always) | Out-String) -replace "`n|`r", ""
|
||||
- ps: $env:PACKAGE_VERSION = $env:GIT_DESCRIBE + "_" + ($env:APPVEYOR_REPO_BRANCH.replace("/", "-"))
|
||||
- ps: $env:ARCHITECTURE = $env:PLATFORM.substring($env:PLATFORM.length - 2)
|
||||
|
||||
artifacts:
|
||||
- path: build\package\libloot-python-$(PACKAGE_VERSION)-python$(PYTHON_VERSION)-win$(ARCHITECTURE).zip
|
||||
name: libloot-python
|
||||
|
||||
deploy:
|
||||
- provider: BinTray
|
||||
username: wrinklyninja
|
||||
api_key:
|
||||
secure: PgsEA6TjHVf718zMnK7J/fT1hUAVNKBeWhpYgYaeCyeZk37VT4Ics6j7+B7ElLEr
|
||||
subject: loot
|
||||
repo: snapshots
|
||||
package: libloot-python
|
||||
version: $(PACKAGE_VERSION)
|
||||
publish: true
|
||||
artifact: libloot-python
|
||||
|
||||
- provider: GitHub
|
||||
tag: $(APPVEYOR_REPO_TAG_NAME)
|
||||
release: libloot-python v$(APPVEYOR_REPO_TAG_NAME)
|
||||
description: |
|
||||
Requires Windows 7 or later and the [MSVC 2017 x86 redistributable](https://download.visualstudio.microsoft.com/download/pr/749aa419-f9e4-4578-a417-a43786af205e/d59197078cc425377be301faba7dd87a/vc_redist.x86.exe), and [7-Zip](http://www.7-zip.org/) to extract the archive.
|
||||
auth_token:
|
||||
secure: yDqT5l/e5MntbW99V6+MHlfFgNv+UIogFfeyUVqtFk5lFRB/dAraLLwKCLl6y+DH
|
||||
artifact: libloot-python
|
||||
draft: false
|
||||
on:
|
||||
appveyor_repo_tag: true
|
||||
|
||||
on_success:
|
||||
- ps: python "$env:APPVEYOR_BUILD_FOLDER\delete_old_bintray_versions.py" -g loot/libloot-python -b loot/snapshots/libloot-python -u wrinklyninja -k $env:bintray_auth_token -t $env:github_auth_token -n 30
|
||||
+1
-1
@@ -3,7 +3,7 @@ libloot-python
|
||||
|
||||
This archive contains a build of the libloot-python wrapper module and its corresponding 32-bit Windows build of libloot.
|
||||
|
||||
The DLL requires the [MSVC 2022 x86 redistributable](https://aka.ms/vs/17/release/vc_redist.x86.exe)
|
||||
The DLL requires the [MSVC 2017 x86 redistributable](https://download.visualstudio.microsoft.com/download/pr/749aa419-f9e4-4578-a417-a43786af205e/d59197078cc425377be301faba7dd87a/vc_redist.x86.exe)
|
||||
to be installed.
|
||||
|
||||
See the [online documentation](http://loot-api-python.readthedocs.org/) for more information.
|
||||
|
||||
+4
-2
@@ -22,7 +22,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('../build/Release'))
|
||||
sys.path.insert(0, os.path.abspath('../build/RelWithDebInfo'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
@@ -34,6 +34,7 @@ sys.path.insert(0, os.path.abspath('../build/Release'))
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
]
|
||||
|
||||
@@ -346,5 +347,6 @@ texinfo_documents = [
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {
|
||||
'loot_api': ('http://loot.readthedocs.io/en/0.14.7/', None),
|
||||
'loot': ('https://loot.readthedocs.io/en/0.15.0/', None),
|
||||
'python': ('https://docs.python.org/3', None)
|
||||
}
|
||||
|
||||
+7
-191
@@ -5,188 +5,13 @@ API Reference
|
||||
As this API is just a wrapper for libloot's C++ API, its documentation is linked
|
||||
to for all non-Python-specific information.
|
||||
|
||||
Enumerations
|
||||
============
|
||||
|
||||
The wrapped enumeration types below are classes in Python, but the distinction
|
||||
The wrapped enumeration types are classes in Python, but the distinction
|
||||
makes no difference in practice, so they're grouped here for semantics. All
|
||||
values are unsigned integer constants.
|
||||
their values are unsigned integer constants.
|
||||
|
||||
.. py:class:: loot.GameType
|
||||
|
||||
Wraps :cpp:type:`loot::GameType` to expose libloot's game codes.
|
||||
|
||||
.. py:attribute:: fo3
|
||||
.. py:attribute:: fo4
|
||||
.. py:attribute:: fonv
|
||||
.. py:attribute:: tes4
|
||||
.. py:attribute:: tes5
|
||||
.. py:attribute:: tes5se
|
||||
|
||||
.. py:class:: loot.LogLevel
|
||||
|
||||
Wraps :cpp:type:`loot::LogLevel` to expose libloot's log level codes.
|
||||
|
||||
.. py:attribute:: trace
|
||||
.. py:attribute:: debug
|
||||
.. py:attribute:: info
|
||||
.. py:attribute:: warning
|
||||
.. py:attribute:: error
|
||||
.. py:attribute:: fatal
|
||||
|
||||
.. py:class:: loot.MessageType
|
||||
|
||||
Wraps :cpp:type:`loot::MessageType` to expose libloot's message type
|
||||
codes.
|
||||
|
||||
.. py:attribute:: error
|
||||
.. py:attribute:: say
|
||||
.. py:attribute:: warn
|
||||
|
||||
.. py:class:: loot.PluginCleanliness
|
||||
|
||||
Codes used to indicate the cleanliness of a plugin according to the
|
||||
information contained within the loaded masterlist/userlist.
|
||||
|
||||
.. py:attribute:: clean
|
||||
|
||||
Indicates that the plugin is clean.
|
||||
|
||||
.. py:attribute:: dirty
|
||||
|
||||
Indicates that the plugin is dirty.
|
||||
|
||||
.. py:attribute:: do_not_clean
|
||||
|
||||
Indicates that the plugin contains dirty edits, but that they are part of
|
||||
the plugin’s intended functionality and should not be removed.
|
||||
|
||||
.. py:attribute:: unknown
|
||||
|
||||
Indicates that no data is available on whether the plugin is dirty or not.
|
||||
|
||||
Public-Field Data Structures
|
||||
============================
|
||||
|
||||
Classes with public fields and no member functions.
|
||||
|
||||
.. py:class:: loot.MasterlistInfo
|
||||
|
||||
Wraps :cpp:class:`loot::MasterlistInfo`.
|
||||
|
||||
.. py:attribute:: revision_id
|
||||
|
||||
A Unicode string containing a Git commit's SHA-1 checksum.
|
||||
|
||||
.. py:attribute:: revision_date
|
||||
|
||||
A Unicode string containing the date of the commit given by :py:attr:`revision_id`, in ISO 8601 format (YYYY-MM-DD).
|
||||
|
||||
.. py:attribute:: is_modified
|
||||
|
||||
A boolean that is true if the masterlist has been modified from its state
|
||||
at the commit given by :py:attr:`revision_id`.
|
||||
|
||||
.. py:class:: loot.SimpleMessage
|
||||
|
||||
Wraps :cpp:class:`loot::SimpleMessage`.
|
||||
|
||||
.. py:attribute:: type
|
||||
|
||||
A :py:class:`loot.MessageType` giving the message type.
|
||||
|
||||
.. py:attribute:: language
|
||||
|
||||
A Unicode string giving the message text language.
|
||||
|
||||
.. py:attribute:: text
|
||||
|
||||
A Unicode string containing the message text.
|
||||
|
||||
.. py:attribute:: condition
|
||||
|
||||
A Unicode string containing the message condition.
|
||||
|
||||
.. py:class:: loot.PluginTags
|
||||
|
||||
Wraps :cpp:class:`loot::PluginTags`.
|
||||
|
||||
.. py:attribute:: added
|
||||
|
||||
A set of Unicode strings giving Bash Tags suggested for addition.
|
||||
|
||||
.. py:attribute:: removed
|
||||
|
||||
A set of Unicode strings giving Bash Tags suggested for removal.
|
||||
|
||||
.. py:attribute:: userlist_modified
|
||||
|
||||
A boolean that is true if the suggestions contain metadata obtained from a loaded userlist.
|
||||
|
||||
|
||||
Functions
|
||||
=========
|
||||
|
||||
.. py:function:: loot.set_logging_callback(callback) -> NoneType
|
||||
|
||||
Set the callback function that is called when logging. Wraps
|
||||
:cpp:func:`loot::SetLoggingCallback`.
|
||||
|
||||
.. py:function:: loot.is_compatible(int, int, int) -> bool
|
||||
|
||||
Checks for API compatibility. Wraps :cpp:func:`loot::IsCompatible`.
|
||||
|
||||
.. py:function:: loot.create_game_handle(game : loot.GameType, game_path : unicode, [game_local_path : unicode = u'']) -> loot.GameInterface
|
||||
|
||||
Initialise a new game handle. Wraps :cpp:func:`loot::CreateGameHandle`.
|
||||
|
||||
Classes
|
||||
=======
|
||||
|
||||
.. py:class:: loot.GameInterface
|
||||
|
||||
Wraps :cpp:class:`loot::GameInterface`.
|
||||
|
||||
.. py:function:: loot.get_database() -> loot.DatabaseInterface
|
||||
|
||||
Get a database handle. Wraps :cpp:func:`loot::GetDatabase`.
|
||||
|
||||
.. py:function:: loot.load_current_load_order_state() -> NoneType
|
||||
|
||||
Load the current load order state, discarding any previously held state.
|
||||
Wraps :cpp:func:`loot::LoadCurrentLoadOrderState`.
|
||||
|
||||
.. py:class:: loot.DatabaseInterface
|
||||
|
||||
Wraps :cpp:class:`loot::DatabaseInterface`.
|
||||
|
||||
.. py:method:: get_masterlist_revision(loot.DatabaseInterface, unicode, bool) -> loot.MasterlistInfo
|
||||
|
||||
Gets the give masterlist’s source control revision. Wraps :cpp:func:`GetMasterlistRevision`.
|
||||
|
||||
.. py:method:: get_plugin_metadata(loot.DatabaseInterface, plugin : unicode, [includeUserMetadata : bool = True, [evaluateConditions : bool = False]]) -> loot.PluginMetadata
|
||||
|
||||
Get all a plugin’s loaded metadata. Wraps :cpp:func:`GetPluginMetadata`.
|
||||
|
||||
.. py:method:: get_plugin_cleanliness(loot.DatabaseInterface, plugin : unicode, [evaluateConditions : bool = False]) -> loot.PluginCleanliness
|
||||
|
||||
Determines the database’s knowledge of a plugin’s cleanliness. Outputs whether the plugin should be cleaned or not, or if no data is available.
|
||||
|
||||
.. py:method:: get_plugin_tags(loot.DatabaseInterface, plugin : unicode, [evaluateConditions : bool = False]) -> loot.PluginTags
|
||||
|
||||
Outputs the Bash Tags suggested for addition and removal by the database for the given plugin.
|
||||
|
||||
.. py:method:: load_lists(loot.DatabaseInterface, masterlist_path : unicode, [userlist_path : unicode = u'']) -> NoneType
|
||||
|
||||
Loads the masterlist and userlist from the paths specified. Wraps :cpp:func:`LoadLists`.
|
||||
|
||||
.. py:method:: update_masterlist(loot.DatabaseInterface, unicode, unicode, unicode) -> bool
|
||||
|
||||
Updates the given masterlist using the given Git repository details. Wraps :cpp:func:`UpdateMasterlist`.
|
||||
|
||||
.. py:method:: write_minimal_list(loot.DatabaseInterface, unicode, bool) -> NoneType
|
||||
|
||||
Writes a minimal metadata file containing only Bash Tag suggestions and/or cleanliness info from the loaded metadata. Wraps :cpp:func:`WriteMinimalList`.
|
||||
.. automodule:: loot
|
||||
:members:
|
||||
:exclude-members: Version, WrapperVersion
|
||||
|
||||
.. py:class:: loot.Version
|
||||
|
||||
@@ -208,7 +33,7 @@ Classes
|
||||
|
||||
A Unicode string containing the SHA-1 of the Git revision that the wrapped C++ API was built from.
|
||||
|
||||
.. py:staticmethod:: string() -> unicode
|
||||
.. py:staticmethod:: string() -> str
|
||||
|
||||
Returns the API version as a string of the form ``major.minor.patch``
|
||||
|
||||
@@ -232,15 +57,6 @@ Classes
|
||||
|
||||
A Unicode string containing the SHA-1 of the Git revision that the wrapped C++ API was built from.
|
||||
|
||||
.. py:staticmethod:: string() -> unicode
|
||||
.. py:staticmethod:: string() -> str
|
||||
|
||||
Returns the API version as a string of the form ``major.minor.patch``
|
||||
|
||||
.. py:class:: loot.PluginMetadata
|
||||
|
||||
Wraps :cpp:class:`loot::PluginMetadata`.
|
||||
|
||||
.. py:method:: get_simple_messages(loot.PluginMetadata, unicode) -> list<loot.SimpleMessage>
|
||||
|
||||
Get the plugin’s messages as SimpleMessage objects for the given language.
|
||||
Wraps :cpp:func:`GetPluginMessages`.
|
||||
|
||||
+2
-2
@@ -10,13 +10,13 @@ Build archives contain two binaries:
|
||||
* ``loot.*.pyd`` is the Python wrapper
|
||||
* ``loot.dll`` is the C++ library DLL that the Python wrapper was built against.
|
||||
|
||||
The C++ DLL requires the `Visual C++ 2022 Redistributable (x86)`_
|
||||
The C++ DLL requires the `Visual C++ 2017 Redistributable (x86)`_
|
||||
to be installed.
|
||||
|
||||
To use the wrapper, copy both files to wherever you want to import them from
|
||||
(they must be in the same folder), and you're done!
|
||||
|
||||
.. _Visual C++ 2022 Redistributable (x86): https://aka.ms/vs/17/release/vc_redist.x86.exe
|
||||
.. _Visual C++ 2017 Redistributable (x86): https://download.visualstudio.microsoft.com/download/pr/749aa419-f9e4-4578-a417-a43786af205e/d59197078cc425377be301faba7dd87a/vc_redist.x86.exe
|
||||
|
||||
Using the wrapper
|
||||
=================
|
||||
|
||||
+2
-1
@@ -79,10 +79,11 @@ setup(
|
||||
distclass=BinaryDistribution,
|
||||
classifiers=[
|
||||
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: C++'
|
||||
'Operating System :: Microsoft :: Windows',
|
||||
'Intended Audience :: Developers',
|
||||
],
|
||||
python_requires='>=3.7',
|
||||
python_requires='>=2.7',
|
||||
)
|
||||
|
||||
+137
-52
@@ -58,10 +58,21 @@ bool UpdateMasterlist(std::shared_ptr<DatabaseInterface> db, std::string masterl
|
||||
MasterlistInfo GetMasterlistRevision(std::shared_ptr<DatabaseInterface> db, std::string masterlistPath, bool getShortId) {
|
||||
return db->GetMasterlistRevision(u8path(masterlistPath), getShortId);
|
||||
}
|
||||
|
||||
void SetLoggingCallback(std::function<void(LogLevel, const char*)> callback) {
|
||||
callback = [callback](LogLevel level, const char* message) {
|
||||
pybind11::gil_scoped_acquire acquire;
|
||||
callback(level, message);
|
||||
};
|
||||
loot::SetLoggingCallback(callback);
|
||||
}
|
||||
}
|
||||
|
||||
void bindEnums(pybind11::module& module) {
|
||||
enum_<GameType>(module, "GameType")
|
||||
pybind11::options options;
|
||||
options.disable_function_signatures();
|
||||
|
||||
enum_<GameType>(module, "GameType", "Wraps :cpp:enum:`loot::GameType` to expose libloot's game codes.")
|
||||
.value("tes4", GameType::tes4)
|
||||
.value("tes5", GameType::tes5)
|
||||
.value("tes5se", GameType::tes5se)
|
||||
@@ -71,7 +82,7 @@ void bindEnums(pybind11::module& module) {
|
||||
.value("fo4", GameType::fo4)
|
||||
.value("fo4vr", GameType::fo4vr);
|
||||
|
||||
enum_<LogLevel>(module, "LogLevel")
|
||||
enum_<LogLevel>(module, "LogLevel", "Wraps :cpp:enum:`loot::LogLevel` to expose libloot's log level codes.")
|
||||
.value("trace", LogLevel::trace)
|
||||
.value("debug", LogLevel::debug)
|
||||
.value("info", LogLevel::info)
|
||||
@@ -79,75 +90,140 @@ void bindEnums(pybind11::module& module) {
|
||||
.value("error", LogLevel::error)
|
||||
.value("fatal", LogLevel::fatal);
|
||||
|
||||
enum_<MessageType>(module, "MessageType")
|
||||
enum_<MessageType>(module, "MessageType", "Wraps :cpp:enum:`loot::MessageType` to expose libloot's message type codes.")
|
||||
.value("say", MessageType::say)
|
||||
.value("warn", MessageType::warn)
|
||||
.value("error", MessageType::error);
|
||||
|
||||
enum_<PluginCleanliness>(module, "PluginCleanliness")
|
||||
.value("clean", PluginCleanliness::clean)
|
||||
.value("dirty", PluginCleanliness::dirty)
|
||||
.value("do_not_clean", PluginCleanliness::do_not_clean)
|
||||
.value("unknown", PluginCleanliness::unknown);
|
||||
enum_<PluginCleanliness>(module, "PluginCleanliness", "Codes used to indicate the cleanliness of a plugin according to the information contained within the loaded masterlist / userlist.")
|
||||
.value("clean", PluginCleanliness::clean, "Indicates that the plugin is clean.")
|
||||
.value("dirty", PluginCleanliness::dirty, "Indicates that the plugin is dirty.")
|
||||
.value("do_not_clean", PluginCleanliness::do_not_clean, "Indicates that the plugin contains dirty edits, but that they are part of the plugin's intended functionality and should not be removed.")
|
||||
.value("unknown", PluginCleanliness::unknown, "Indicates that no data is available on whether the plugin is dirty or not.");
|
||||
}
|
||||
|
||||
void bindMetadataClasses(pybind11::module& module) {
|
||||
class_<MasterlistInfo>(module, "MasterlistInfo")
|
||||
.def_readwrite("revision_id", &MasterlistInfo::revision_id)
|
||||
.def_readwrite("revision_date", &MasterlistInfo::revision_date)
|
||||
.def_readwrite("is_modified", &MasterlistInfo::is_modified);
|
||||
class_<MasterlistInfo>(module, "MasterlistInfo", "Wraps :cpp:class:`loot::MasterlistInfo`.")
|
||||
.def_readwrite("revision_id", &MasterlistInfo::revision_id, "A Unicode string containing a Git commit's SHA-1 checksum.")
|
||||
.def_readwrite("revision_date", &MasterlistInfo::revision_date, "A Unicode string containing the date of the commit given by :py:attr:`~loot.MasterlistInfo.revision_id`, in ISO 8601 format (YYYY-MM-DD).")
|
||||
.def_readwrite("is_modified", &MasterlistInfo::is_modified, "A boolean that is true if the masterlist has been modified from its state at the commit given by :py:attr:`~loot.MasterlistInfo.revision_id`.");
|
||||
|
||||
class_<SimpleMessage>(module, "SimpleMessage")
|
||||
.def_readwrite("type", &SimpleMessage::type)
|
||||
.def_readwrite("language", &SimpleMessage::language)
|
||||
.def_readwrite("text", &SimpleMessage::text)
|
||||
.def_readwrite("condition", &SimpleMessage::condition);
|
||||
class_<SimpleMessage>(module, "SimpleMessage", "Wraps :cpp:class:`loot::SimpleMessage`.")
|
||||
.def_readwrite("type", &SimpleMessage::type, "A :py:class:`loot.MessageType` giving the message type.")
|
||||
.def_readwrite("language", &SimpleMessage::language, "A Unicode string giving the message text language.")
|
||||
.def_readwrite("text", &SimpleMessage::text, "A Unicode string containing the message text.")
|
||||
.def_readwrite("condition", &SimpleMessage::condition, "A Unicode string containing the message condition.");
|
||||
|
||||
class_<PluginTags>(module, "PluginTags")
|
||||
.def_readwrite("added", &PluginTags::added)
|
||||
.def_readwrite("removed", &PluginTags::removed)
|
||||
.def_readwrite("userlist_modified", &PluginTags::userlist_modified);
|
||||
.def_readwrite("added", &PluginTags::added, "A set of Unicode strings giving Bash Tags suggested for addition.")
|
||||
.def_readwrite("removed", &PluginTags::removed, "A set of Unicode strings giving Bash Tags suggested for removal.")
|
||||
.def_readwrite("userlist_modified", &PluginTags::userlist_modified, "A boolean that is true if the suggestions contain metadata obtained from a loaded userlist.");
|
||||
|
||||
class_<PluginMetadata>(module, "PluginMetadata")
|
||||
.def("get_simple_messages", &PluginMetadata::GetSimpleMessages);
|
||||
class_<PluginMetadata>(module, "PluginMetadata", "Wraps :cpp:class:`loot::PluginMetadata`.")
|
||||
.def("get_simple_messages",
|
||||
&PluginMetadata::GetSimpleMessages,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Get the plugin's messages as SimpleMessage objects for the given language. Wraps :cpp:func:`GetSimpleMessages`.");
|
||||
}
|
||||
|
||||
void bindVersionClasses(pybind11::module& module) {
|
||||
class_<LootVersion>(module, "Version")
|
||||
.def_readonly_static("major", &LootVersion::major)
|
||||
.def_readonly_static("minor", &LootVersion::minor)
|
||||
.def_readonly_static("patch", &LootVersion::patch)
|
||||
.def_readonly_static("revision", &LootVersion::revision)
|
||||
.def_static("string", LootVersion::GetVersionString);
|
||||
// FIXME: For some reason the static properties have their docstrings ignored.
|
||||
class_<LootVersion>(module, "Version", "Wraps :cpp:class:`loot::LootVersion`.")
|
||||
.def_readonly_static("major", &LootVersion::major, "An unsigned integer giving the major version number. Read-only.")
|
||||
.def_readonly_static("minor", &LootVersion::minor, "An unsigned integer giving the minor version number. Read-only.")
|
||||
.def_readonly_static("patch", &LootVersion::patch, "An unsigned integer giving the patch version number. Read-only.")
|
||||
.def_readonly_static("revision", &LootVersion::revision, "A Unicode string containing the Git commit hash that the wrapped libloot was built from.")
|
||||
.def_static("string",
|
||||
LootVersion::GetVersionString,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Returns the libloot version as a string of the form ``major.minor.patch``.");
|
||||
|
||||
class_<WrapperVersion>(module, "WrapperVersion")
|
||||
.def_readonly_static("major", &WrapperVersion::major)
|
||||
.def_readonly_static("minor", &WrapperVersion::minor)
|
||||
.def_readonly_static("patch", &WrapperVersion::patch)
|
||||
.def_readonly_static("revision", &WrapperVersion::revision)
|
||||
.def_static("string", WrapperVersion::string);
|
||||
class_<WrapperVersion>(module, "WrapperVersion", "Provides information about the version of libloot-python that is being run.")
|
||||
.def_readonly_static("major", &WrapperVersion::major, "An unsigned integer giving the major version number. Read-only.")
|
||||
.def_readonly_static("minor", &WrapperVersion::minor, "An unsigned integer giving the minor version number. Read-only.")
|
||||
.def_readonly_static("patch", &WrapperVersion::patch, "An unsigned integer giving the patch version number. Read-only.")
|
||||
.def_readonly_static("revision", &WrapperVersion::revision, "A Unicode string containing the Git commit hash that the Python module was built from.")
|
||||
.def_static("string",
|
||||
WrapperVersion::string,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Returns the module version as a string of the form ``major.minor.patch``.");
|
||||
}
|
||||
|
||||
void bindInterfaceClasses(pybind11::module& module) {
|
||||
class_<GameInterface, std::shared_ptr<GameInterface>>(module, "GameInterface")
|
||||
.def("load_current_load_order_state", &GameInterface::LoadCurrentLoadOrderState)
|
||||
.def("get_database", &GameInterface::GetDatabase);
|
||||
class_<GameInterface, std::shared_ptr<GameInterface>>(module, "GameInterface", "Wraps :cpp:class:`loot::GameInterface`.")
|
||||
.def("load_current_load_order_state",
|
||||
&GameInterface::LoadCurrentLoadOrderState,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Load the current load order state, discarding any previously held state. Wraps :cpp:func:`LoadCurrentLoadOrderState`.")
|
||||
.def("get_database",
|
||||
&GameInterface::GetDatabase,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Get a database handle. Wraps :cpp:func:`GetDatabase`.")
|
||||
.def("load_plugins",
|
||||
&GameInterface::LoadPlugins,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Load the given plugins. Wraps :cpp:func:`LoadPlugins`.")
|
||||
.def("get_plugin",
|
||||
&GameInterface::GetPlugin,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Get the given loaded plugin. Wraps :cpp:func:`GetPlugin`.");
|
||||
|
||||
class_<DatabaseInterface, std::shared_ptr<DatabaseInterface>>(module, "DatabaseInterface")
|
||||
.def("load_lists", &py::LoadLists, arg("masterlist_path"), arg("userlist_path") = "")
|
||||
.def("update_masterlist", &py::UpdateMasterlist)
|
||||
.def("get_masterlist_revision", &py::GetMasterlistRevision)
|
||||
.def("get_plugin_metadata", &DatabaseInterface::GetPluginMetadata,
|
||||
class_<DatabaseInterface, std::shared_ptr<DatabaseInterface>>(module, "DatabaseInterface", "Wraps :cpp:class:`loot::DatabaseInterface`.")
|
||||
.def("load_lists",
|
||||
&py::LoadLists,
|
||||
arg("masterlist_path"),
|
||||
arg("userlist_path") = "",
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Loads the masterlist and userlist from the paths specified. Wraps :cpp:func:`LoadLists`.")
|
||||
.def("update_masterlist",
|
||||
&py::UpdateMasterlist,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Updates the given masterlist using the given Git repository details. Wraps :cpp:func:`UpdateMasterlist`.")
|
||||
.def("get_masterlist_revision",
|
||||
&py::GetMasterlistRevision,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Gets the give masterlist's source control revision. Wraps :cpp:func:`GetMasterlistRevision`.")
|
||||
.def("get_plugin_metadata",
|
||||
&DatabaseInterface::GetPluginMetadata,
|
||||
arg("plugin"),
|
||||
arg("includeUserMetadata") = true,
|
||||
arg("evaluateConditions") = false)
|
||||
.def("get_plugin_tags", &GetPluginTags,
|
||||
arg("evaluateConditions") = false,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Get all a plugin's loaded metadata. Wraps :cpp:func:`GetPluginMetadata`.")
|
||||
.def("get_plugin_tags",
|
||||
&GetPluginTags,
|
||||
arg("plugin"),
|
||||
arg("evaluateConditions") = false)
|
||||
.def("get_plugin_cleanliness", &GetPluginCleanliness,
|
||||
arg("evaluateConditions") = false,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Outputs the Bash Tags suggested for addition and removal by the database for the given plugin.")
|
||||
.def("get_plugin_cleanliness",
|
||||
&GetPluginCleanliness,
|
||||
arg("plugin"),
|
||||
arg("evaluateConditions") = false)
|
||||
.def("write_minimal_list", &py::WriteMinimalList);
|
||||
arg("evaluateConditions") = false,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Determines the database's knowledge of a plugin's cleanliness. Outputs whether the plugin should be cleaned or not, or if no data is available.")
|
||||
.def("write_minimal_list",
|
||||
&py::WriteMinimalList,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Writes a minimal metadata file containing only Bash Tag suggestions and/or cleanliness info from the loaded metadata. Wraps :cpp:func:`WriteMinimalList`.");
|
||||
|
||||
class_<PluginInterface, std::shared_ptr<PluginInterface>>(module, "PluginInterface")
|
||||
.def_property_readonly("name",
|
||||
&PluginInterface::GetName,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"The plugin's name. Read-only. Wraps :cpp:func:`GetName`.")
|
||||
.def("is_master",
|
||||
&PluginInterface::IsMaster,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Check if the plugin is a master. Wraps :cpp:func:`IsMaster`.")
|
||||
.def("is_light_master",
|
||||
&PluginInterface::IsLightMaster,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Check if the plugin is a light master. Wraps :cpp:func:`IsLightMaster`.")
|
||||
.def("is_valid_as_light_master",
|
||||
&PluginInterface::IsValidAsLightMaster,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Check if the plugin contains only records with FormIDs that are valid in a light master. Wraps :cpp:func:`IsValidAsLightMaster`.");
|
||||
}
|
||||
|
||||
void bindClasses(pybind11::module& module) {
|
||||
@@ -157,7 +233,10 @@ void bindClasses(pybind11::module& module) {
|
||||
}
|
||||
|
||||
void bindFunctions(pybind11::module& module) {
|
||||
module.def("set_logging_callback", &SetLoggingCallback);
|
||||
module.def("set_logging_callback",
|
||||
&py::SetLoggingCallback,
|
||||
arg("callback"),
|
||||
"Set the callback function that is called when logging. Wraps :cpp:func:`loot::SetLoggingCallback`.");
|
||||
|
||||
// Need to clear the stored logging callback when exiting, or Python will
|
||||
// hang because the callback pointer is still stored by libloot.
|
||||
@@ -166,12 +245,18 @@ void bindFunctions(pybind11::module& module) {
|
||||
SetLoggingCallback(nullptr);
|
||||
}));
|
||||
|
||||
module.def("is_compatible", &IsCompatible);
|
||||
module.def("is_compatible",
|
||||
&IsCompatible,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Checks for API compatibility. Wraps :cpp:func:`loot::IsCompatible`.");
|
||||
|
||||
module.def("create_game_handle", &py::CreateGameHandle,
|
||||
module.def("create_game_handle",
|
||||
&py::CreateGameHandle,
|
||||
arg("game"),
|
||||
arg("game_path"),
|
||||
arg("game_local_path") = "");
|
||||
arg("game_local_path") = "",
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>(),
|
||||
"Initialise a new game handle. Wraps :cpp:func:`loot::CreateGameHandle`.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+62
-8
@@ -20,29 +20,28 @@ from loot import is_compatible
|
||||
from loot import set_logging_callback
|
||||
|
||||
def logging_callback(level, message):
|
||||
pass
|
||||
print(level, message)
|
||||
|
||||
set_logging_callback(logging_callback)
|
||||
|
||||
class GameFixture(unittest.TestCase):
|
||||
game_path = os.path.join(u'.', u'Oblivion')
|
||||
local_path = os.path.join(u'.', u'local')
|
||||
master_filename = u'Oblivion.esm'
|
||||
|
||||
def setUp(self):
|
||||
data_path = os.path.join(self.game_path, 'Data')
|
||||
master_file = os.path.join(data_path, 'Oblivion.esm')
|
||||
|
||||
if not os.path.exists(data_path):
|
||||
os.makedirs(data_path)
|
||||
open(master_file, 'a').close()
|
||||
open(self.master_file_path(), 'a').close()
|
||||
|
||||
if not os.path.exists(self.local_path):
|
||||
os.makedirs(self.local_path)
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.game_path)
|
||||
os.remove(self.master_file_path())
|
||||
shutil.rmtree(self.local_path)
|
||||
|
||||
def master_file_path(self):
|
||||
return os.path.join(self.game_path, 'Data', self.master_filename)
|
||||
|
||||
class TestLootApi(GameFixture):
|
||||
def test_is_compatible(self):
|
||||
self.assertFalse(is_compatible(0, 9, 0))
|
||||
@@ -68,6 +67,61 @@ class TestLootApi(GameFixture):
|
||||
db = game.get_database()
|
||||
self.assertNotEqual(db, None)
|
||||
|
||||
class TestGameInterface(GameFixture):
|
||||
def setUp(self):
|
||||
super(TestGameInterface, self).setUp()
|
||||
|
||||
self.game = create_game_handle(GameType.tes4, self.game_path, self.local_path)
|
||||
|
||||
def test_load_plugins(self):
|
||||
self.game.load_plugins([u'Blank.esm'], True)
|
||||
self.game.load_plugins([u'Blank.esm'], False)
|
||||
|
||||
def test_get_plugin(self):
|
||||
self.game.load_plugins([u'Blank.esm'], True)
|
||||
plugin = self.game.get_plugin(u'Blank.esm')
|
||||
|
||||
self.assertNotEqual(plugin, None)
|
||||
|
||||
class TestPluginInterface(GameFixture):
|
||||
game_path = os.path.join(u'.', u'SkyrimSE')
|
||||
master_filename = u'Skyrim.esm'
|
||||
|
||||
def setUp(self):
|
||||
super(TestPluginInterface, self).setUp()
|
||||
|
||||
self.game = create_game_handle(GameType.tes5se, self.game_path, self.local_path)
|
||||
self.game.load_plugins([u'Blank.esm', u'Blank.esl'], False)
|
||||
|
||||
def test_name(self):
|
||||
plugin = self.game.get_plugin(u'Blank.esm')
|
||||
|
||||
self.assertNotEqual(plugin, None)
|
||||
self.assertEqual(plugin.name, u'Blank.esm')
|
||||
|
||||
def test_is_master(self):
|
||||
plugin = self.game.get_plugin(u'Blank.esm')
|
||||
|
||||
self.assertNotEqual(plugin, None)
|
||||
self.assertTrue(plugin.is_master())
|
||||
|
||||
def test_is_light_master(self):
|
||||
plugin = self.game.get_plugin(u'Blank.esm')
|
||||
|
||||
self.assertNotEqual(plugin, None)
|
||||
self.assertFalse(plugin.is_light_master())
|
||||
|
||||
plugin = self.game.get_plugin(u'Blank.esl')
|
||||
|
||||
self.assertNotEqual(plugin, None)
|
||||
self.assertTrue(plugin.is_light_master())
|
||||
|
||||
def test_is_valid_as_light_master(self):
|
||||
plugin = self.game.get_plugin(u'Blank.esm')
|
||||
|
||||
self.assertNotEqual(plugin, None)
|
||||
self.assertTrue(plugin.is_valid_as_light_master())
|
||||
|
||||
class TestDatabaseInterface(GameFixture):
|
||||
masterlist_path = os.path.join(os.path.dirname(__file__), u'masterlist.yaml')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user