mirror of
https://github.com/loot/libloot-python.git
synced 2026-07-27 14:14:13 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88cbaa58af | ||
|
|
900d5132ce | ||
|
|
929d3ac659 | ||
|
|
ddc40b70e9 | ||
|
|
43ba191ac5 | ||
|
|
64293324c3 | ||
|
|
5a9179be1b | ||
|
|
6f6b2269cf | ||
|
|
024ab1f1e5 | ||
|
|
a7d26204a1 | ||
|
|
8247ef9f62 | ||
|
|
dcf9b8b96b | ||
|
|
263322a75c | ||
|
|
b52cd9bd6b | ||
|
|
580bf87802 | ||
|
|
c144f7a66c | ||
|
|
ffd62f9e0c | ||
|
|
937a36a5ae | ||
|
|
915c002ca6 | ||
|
|
c19a9be579 | ||
|
|
b393507657 | ||
|
|
d356ac2445 | ||
|
|
fe4c3ab6b5 | ||
|
|
b17b531073 | ||
|
|
06a6d9ceb6 | ||
|
|
a35abab104 | ||
|
|
646a8d02e0 | ||
|
|
cab63886d3 | ||
|
|
8a61701855 | ||
|
|
8c75e83374 | ||
|
|
5450709ebe | ||
|
|
3a9ff95de2 | ||
|
|
1298fce6fd | ||
|
|
21242f359d | ||
|
|
6579eb5178 | ||
|
|
61a74b6984 | ||
|
|
66f84d4848 | ||
|
|
5f5c0e3949 | ||
|
|
ab926c8755 | ||
|
|
35475b292f | ||
|
|
51e2e4e4fa | ||
|
|
c17437a579 | ||
|
|
49204621c5 | ||
|
|
3098ffa692 | ||
|
|
392a090823 | ||
|
|
e98b43a4b1 | ||
|
|
a957ece62b |
@@ -0,0 +1,88 @@
|
||||
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'
|
||||
@@ -0,0 +1,92 @@
|
||||
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
|
||||
@@ -50,3 +50,5 @@ $RECYCLE.BIN/
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
.vscode/
|
||||
|
||||
+66
-66
@@ -1,15 +1,23 @@
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
project (loot_api_python)
|
||||
cmake_minimum_required (VERSION 3.4)
|
||||
project (libloot-python)
|
||||
include(ExternalProject)
|
||||
|
||||
set(EXTERNAL_PROJECTS_PATH "${CMAKE_BINARY_DIR}/external/src")
|
||||
make_directory(${EXTERNAL_PROJECTS_PATH})
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
##############################
|
||||
# Get Build Revision
|
||||
##############################
|
||||
|
||||
set(LIBLOOT_PY_VERSION_MAJOR 4)
|
||||
set(LIBLOOT_PY_VERSION_MINOR 0)
|
||||
set(LIBLOOT_PY_VERSION_PATCH 2)
|
||||
|
||||
find_package(Git)
|
||||
|
||||
IF (GIT_FOUND)
|
||||
@@ -21,16 +29,18 @@ ELSE()
|
||||
SET (GIT_COMMIT_STRING "unknown")
|
||||
ENDIF ()
|
||||
|
||||
message(STATUS "libloot-python version: ${LIBLOOT_PY_VERSION_MAJOR}.${LIBLOOT_PY_VERSION_MINOR}.${LIBLOOT_PY_VERSION_PATCH}")
|
||||
message(STATUS "Git revision: ${GIT_COMMIT_STRING}")
|
||||
|
||||
# Write to file.
|
||||
configure_file("${CMAKE_SOURCE_DIR}/src/wrapper_version.cpp.in" "${CMAKE_BINARY_DIR}/generated/wrapper_version.cpp" @ONLY)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/python/setup.py" "${CMAKE_BINARY_DIR}/generated/setup.py" @ONLY)
|
||||
|
||||
#######################################
|
||||
# pybind11
|
||||
#######################################
|
||||
|
||||
set(PYBIND11_VERSION "2.1.1")
|
||||
set(PYBIND11_VERSION "2.9.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}")
|
||||
@@ -46,55 +56,52 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xfz ${PYBIND11_DOWNLOAD_PATH}
|
||||
add_subdirectory(${PYBIND11_EXTRACTED_PATH})
|
||||
|
||||
#######################################
|
||||
# LOOT API
|
||||
# libloot
|
||||
#######################################
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
set(LOOT_API_URL "https://github.com/loot/loot-api/releases/download/0.13.2/loot_api-0.13.2-0-g5956e60_dev-win32.7z")
|
||||
if (NOT "${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64")
|
||||
set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.15.0/libloot-0.15.0-0-g629fdab_master-win32.7z")
|
||||
else()
|
||||
set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.15.0/libloot-0.15.0-0-g629fdab_master-win64.7z")
|
||||
endif()
|
||||
else()
|
||||
set(LOOT_API_URL "https://github.com/loot/loot-api/releases/download/0.13.2/loot-api.tar.xz")
|
||||
set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.15.0/libloot.tar.xz")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(loot-api-c++
|
||||
ExternalProject_Add(libloot
|
||||
PREFIX "external"
|
||||
URL ${LOOT_API_URL}
|
||||
URL ${LIBLOOT_URL}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
ExternalProject_Get_Property(loot-api-c++ SOURCE_DIR)
|
||||
set(LOOT_API_EXTRACTED_PATH ${SOURCE_DIR})
|
||||
ExternalProject_Get_Property(libloot SOURCE_DIR)
|
||||
set(LIBLOOT_EXTRACTED_PATH ${SOURCE_DIR})
|
||||
|
||||
include_directories("${CMAKE_SOURCE_DIR}/src"
|
||||
"${LOOT_API_EXTRACTED_PATH}/include")
|
||||
link_directories(${LOOT_API_EXTRACTED_PATH})
|
||||
set(LOOT_API_STATIC_LIBRARY "${CMAKE_STATIC_LIBRARY_PREFIX}loot_api${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
set(LOOT_API_SHARED_LIBRARY "${CMAKE_SHARED_LIBRARY_PREFIX}loot_api${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
|
||||
#######################################
|
||||
# Test Masterlist
|
||||
#######################################
|
||||
|
||||
ExternalProject_Add(test-masterlist
|
||||
PREFIX "external"
|
||||
URL "https://github.com/loot/oblivion/archive/09286601739c11a3a3e4552c6ddbdcaeffd1a8d3.zip"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
"${LIBLOOT_EXTRACTED_PATH}/include")
|
||||
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}")
|
||||
|
||||
#######################################
|
||||
# Python Module
|
||||
#######################################
|
||||
|
||||
pybind11_add_module(loot_api "${CMAKE_SOURCE_DIR}/src/main.cpp"
|
||||
pybind11_add_module(libloot-python "${CMAKE_SOURCE_DIR}/src/main.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/convenience.cpp"
|
||||
"${CMAKE_BINARY_DIR}/generated/wrapper_version.cpp")
|
||||
|
||||
add_dependencies(loot_api loot-api-c++ test-masterlist)
|
||||
# Set the target output name to loot to follow common Python library naming
|
||||
# conventions (no lib, no -python).
|
||||
set_target_properties(libloot-python PROPERTIES OUTPUT_NAME loot)
|
||||
|
||||
add_dependencies(libloot-python libloot)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
target_link_libraries(loot_api PRIVATE ${LOOT_API_STATIC_LIBRARY})
|
||||
target_link_libraries(libloot-python PRIVATE ${LIBLOOT_STATIC_LIBRARY})
|
||||
else()
|
||||
target_link_libraries(loot_api PRIVATE ${LOOT_API_SHARED_LIBRARY})
|
||||
target_link_libraries(libloot-python PRIVATE ${LIBLOOT_SHARED_LIBRARY})
|
||||
endif()
|
||||
|
||||
########################################
|
||||
@@ -103,44 +110,43 @@ endif()
|
||||
|
||||
find_package(PythonInterp REQUIRED)
|
||||
|
||||
# Copy the API binary to the build directory.
|
||||
add_custom_command(TARGET loot_api POST_BUILD
|
||||
# Copy the libloot binary to the build directory.
|
||||
add_custom_command(TARGET libloot-python POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${LOOT_API_EXTRACTED_PATH}/${LOOT_API_SHARED_LIBRARY}"
|
||||
"$<TARGET_FILE_DIR:loot_api>/${LOOT_API_SHARED_LIBRARY}")
|
||||
"${LIBLOOT_EXTRACTED_PATH}/${LIBLOOT_SHARED_LIBRARY}"
|
||||
"$<TARGET_FILE_DIR:libloot-python>/${LIBLOOT_SHARED_LIBRARY}")
|
||||
|
||||
# Copy the test masterlist to the build directory.
|
||||
ExternalProject_Get_Property(test-masterlist SOURCE_DIR)
|
||||
add_custom_command(TARGET loot_api POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${SOURCE_DIR}/masterlist.yaml"
|
||||
"$<TARGET_FILE_DIR:loot_api>/masterlist.yaml")
|
||||
enable_testing()
|
||||
|
||||
# Also copy the test Python script to the build directory.
|
||||
add_custom_command(TARGET loot_api POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CMAKE_SOURCE_DIR}/src/test.py"
|
||||
"$<TARGET_FILE_DIR:loot_api>/test.py")
|
||||
add_test(NAME python
|
||||
WORKING_DIRECTORY $<TARGET_FILE_DIR:libloot-python>
|
||||
COMMAND "${PYTHON_EXECUTABLE}" ${CMAKE_SOURCE_DIR}/test/test.py)
|
||||
|
||||
########################################
|
||||
# Install
|
||||
########################################
|
||||
|
||||
install(TARGETS loot_api
|
||||
DESTINATION "."
|
||||
install(TARGETS libloot-python
|
||||
DESTINATION "loot"
|
||||
CONFIGURATIONS Release RelWithDebInfo)
|
||||
|
||||
install(FILES "${LOOT_API_EXTRACTED_PATH}/${LOOT_API_SHARED_LIBRARY}"
|
||||
"${CMAKE_SOURCE_DIR}/docs/README.md"
|
||||
install(FILES "${LIBLOOT_EXTRACTED_PATH}/${LIBLOOT_SHARED_LIBRARY}"
|
||||
"${CMAKE_SOURCE_DIR}/python/loot/__init__.py"
|
||||
DESTINATION "loot"
|
||||
CONFIGURATIONS Release RelWithDebInfo)
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/docs/README.md"
|
||||
"${CMAKE_BINARY_DIR}/generated/setup.py"
|
||||
"${CMAKE_SOURCE_DIR}/LICENSE"
|
||||
DESTINATION "."
|
||||
CONFIGURATIONS Release RelWithDebInfo)
|
||||
|
||||
IF (MSVC)
|
||||
install(FILES $<TARGET_PDB_FILE:loot_api>
|
||||
DESTINATION .
|
||||
install(FILES $<TARGET_PDB_FILE:libloot-python>
|
||||
DESTINATION "loot"
|
||||
OPTIONAL
|
||||
CONFIGURATIONS RelWithDebInfo
|
||||
RENAME loot_api_python.pdb)
|
||||
RENAME libloot-python.pdb)
|
||||
ENDIF ()
|
||||
|
||||
########################################
|
||||
@@ -150,28 +156,22 @@ ENDIF ()
|
||||
# Get version info using Git if available
|
||||
find_package(Git)
|
||||
|
||||
IF (GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --long --always
|
||||
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 (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()
|
||||
ELSE()
|
||||
string(REPLACE "/" "-" GIT_DESCRIBE_STRING ${GIT_DESCRIBE_STRING})
|
||||
ELSE()
|
||||
SET (GIT_DESCRIBE_STRING "unknown-version")
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
set(CPACK_GENERATOR "7Z")
|
||||
else()
|
||||
set(CPACK_GENERATOR "TXZ")
|
||||
endif()
|
||||
set(CPACK_PACKAGE_VERSION "${GIT_DESCRIBE_STRING}-python$ENV{PYTHON_VERSION}")
|
||||
ENDIF()
|
||||
|
||||
set(CPACK_PACKAGE_VERSION ${GIT_DESCRIBE_STRING})
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package")
|
||||
|
||||
include(CPack)
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
LOOT API Python Module
|
||||
=======================
|
||||
libloot-python
|
||||
==============
|
||||
|
||||
[](https://ci.appveyor.com/project/WrinklyNinja/loot-api-python)
|
||||
[](https://travis-ci.org/loot/loot-api-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).**
|
||||
|
||||

|
||||
[](http://loot-api-python.readthedocs.io/)
|
||||
|
||||
A Python module that wraps the LOOT API, 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).
|
||||
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
|
||||
|
||||
Snapshot builds are available on [Bintray](https://bintray.com/wrinklyninja/loot/loot-api-python). The snapshot build archives are named like so:
|
||||
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:
|
||||
|
||||
```
|
||||
loot_api_python-<short revision ID>-win32.7z
|
||||
libloot-python-<short revision ID>-python<python version>-win<architecture>.zip
|
||||
```
|
||||
|
||||
For example `loot_api_python-94de368-win32.7z` was built using the revision with shortened commit ID `94de368`.
|
||||
For example `libloot-python-94de368-python3.7-win32.zip` was built using the revision with shortened commit ID `94de368`.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -23,6 +26,6 @@ The documentation can be found online at [Read The Docs](http://loot-api-python.
|
||||
|
||||
## Build Instructions
|
||||
|
||||
The module's build system uses [CMake](https://cmake.org/) and requires [Python](https://www.python.org) (tested with 2.7). Make sure they're installed, then run CMake, and build the generated solution file.
|
||||
The module's build system uses [CMake](https://cmake.org/) and requires [Python](https://www.python.org). Make sure they're installed, then run CMake, and build the generated solution file.
|
||||
|
||||
Only Windows support has been tested, though Linux builds should also be possible.
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
os: Visual Studio 2015
|
||||
|
||||
version: "{build}-{branch}"
|
||||
|
||||
configuration: RelWithDebInfo
|
||||
|
||||
environment:
|
||||
bintray_auth_token:
|
||||
secure: fBQJmUDK/EgEUWjjbo6bWcitczeFTJZT4OZ3ZZ4FoUT6soBsTWPQJnr8YEVMFhGP
|
||||
|
||||
install:
|
||||
- ps: (New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/WrinklyNinja/ci-scripts/1.1.0/delete_old_bintray_versions.py', "$env:APPVEYOR_BUILD_FOLDER\delete_old_bintray_versions.py")
|
||||
|
||||
before_build:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%
|
||||
- ps: mkdir build
|
||||
- cd build
|
||||
- cmake .. -G "Visual Studio 14 2015"
|
||||
|
||||
build:
|
||||
verbosity: minimal
|
||||
project: 'c:\projects\loot-api-python\build\loot_api_python.sln'
|
||||
|
||||
test_script:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\build\%CONFIGURATION%
|
||||
- python -m unittest test
|
||||
|
||||
after_test:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\build
|
||||
- cpack -C %CONFIGURATION%
|
||||
# AppVeyor checks out a specific commit, but that means the archive script
|
||||
# can't tell which branch it's on, so rename the 7z archives.
|
||||
- ps: $env:GIT_DESCRIBE = ((git describe --tags --long --always) | Out-String) -replace "`n|`r", ""
|
||||
|
||||
artifacts:
|
||||
- path: build\package\loot_api_python-$(GIT_DESCRIBE)_$(APPVEYOR_REPO_BRANCH)-win32.7z
|
||||
name: loot_api_python
|
||||
|
||||
deploy:
|
||||
- provider: BinTray
|
||||
username: wrinklyninja
|
||||
api_key:
|
||||
secure: fBQJmUDK/EgEUWjjbo6bWcitczeFTJZT4OZ3ZZ4FoUT6soBsTWPQJnr8YEVMFhGP
|
||||
subject: wrinklyninja
|
||||
repo: loot
|
||||
package: loot-api-python
|
||||
version: $(GIT_DESCRIBE)_$(APPVEYOR_REPO_BRANCH)
|
||||
publish: true
|
||||
artifact: loot_api_python
|
||||
|
||||
- provider: GitHub
|
||||
tag: $(APPVEYOR_REPO_TAG_NAME)
|
||||
release: LOOT API Python Module v$(APPVEYOR_REPO_TAG_NAME)
|
||||
description: |
|
||||
Requires Windows 7 or later and the [MSVC 2015 x86 redistributable](https://download.microsoft.com/download/6/A/A/6AA4EDFF-645B-48C5-81CC-ED5963AEAD48/vc_redist.x86.exe), and [7-Zip](http://www.7-zip.org/) to extract the archive.
|
||||
auth_token:
|
||||
secure: V1GojGQfrAiQtUWtNNXfm3samiH+1yNF5UYhkn8B8mbif20IGTGWNlBS9E4S0SUC
|
||||
artifact: loot_api_python
|
||||
draft: false
|
||||
on:
|
||||
appveyor_repo_tag: true
|
||||
|
||||
on_success:
|
||||
- ps: python "$env:APPVEYOR_BUILD_FOLDER\delete_old_bintray_versions.py" -o loot -g loot-api-python -u wrinklyninja -b loot -p loot-api-python -t $env:bintray_auth_token -n 30
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
LOOT API Python Wrapper
|
||||
=======================
|
||||
libloot-python
|
||||
==============
|
||||
|
||||
This archive contains a build of the LOOT API Python wrapper module and its corresponding 32-bit Windows build of the LOOT API.
|
||||
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 2015 x86 redistributable](https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe)
|
||||
The DLL requires the [MSVC 2022 x86 redistributable](https://aka.ms/vs/17/release/vc_redist.x86.exe)
|
||||
to be installed.
|
||||
|
||||
See the [online documentation](http://loot-api-python.readthedocs.org/) for more information.
|
||||
The library source code is available [on GitHub](https://github.com/loot/loot-api-python).
|
||||
The library source code is available [on GitHub](https://github.com/loot/libloot-python).
|
||||
|
||||
---
|
||||
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# LOOT API Python Module documentation build configuration file, created by
|
||||
# libloot-python documentation build configuration file, created by
|
||||
# sphinx-quickstart on Mon Aug 15 07:11:32 2016.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
@@ -54,8 +54,8 @@ source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'LOOT API Python Module'
|
||||
copyright = u'2016, WrinklyNinja'
|
||||
project = u'libloot-python'
|
||||
copyright = u'2019, WrinklyNinja'
|
||||
author = u'WrinklyNinja'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
@@ -139,7 +139,7 @@ html_theme = 'sphinx_rtd_theme'
|
||||
# The name for this set of Sphinx documents.
|
||||
# "<project> v<release> documentation" by default.
|
||||
#
|
||||
# html_title = u'LOOT API Python Module v;atest'
|
||||
# html_title = u'libloot-python v;atest'
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#
|
||||
@@ -265,7 +265,7 @@ latex_elements = {
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'LOOTAPIPythonModule.tex', u'LOOT API Python Module Documentation',
|
||||
(master_doc, 'libloot-python.tex', u'libloot-python Documentation',
|
||||
u'WrinklyNinja', 'manual'),
|
||||
]
|
||||
|
||||
@@ -307,7 +307,7 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'lootapipythonmodule', u'LOOT API Python Module Documentation',
|
||||
(master_doc, 'libloot-python', u'libloot-python Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
@@ -322,8 +322,8 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'LOOTAPIPythonModule', u'LOOT API Python Module Documentation',
|
||||
author, 'LOOTAPIPythonModule', 'One line description of project.',
|
||||
(master_doc, 'libloot-python', u'libloot-python Documentation',
|
||||
author, 'libloot-python', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
@@ -346,5 +346,5 @@ texinfo_documents = [
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {
|
||||
'loot_api': ('http://loot.readthedocs.io/en/0.10.2/', None),
|
||||
'loot_api': ('http://loot.readthedocs.io/en/0.14.7/', None),
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
.. LOOT API Python Module documentation master file, created by
|
||||
.. libloot-python documentation master file, created by
|
||||
sphinx-quickstart on Mon Aug 15 07:11:32 2016.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
LOOT API Python Module
|
||||
======================
|
||||
libloot-python
|
||||
==============
|
||||
|
||||
Contents:
|
||||
|
||||
|
||||
+32
-39
@@ -2,8 +2,8 @@
|
||||
API Reference
|
||||
*************
|
||||
|
||||
As this API is just a wrapper for LOOT's C++ API, its documentation is linked to
|
||||
for all non-Python-specific information.
|
||||
As this API is just a wrapper for libloot's C++ API, its documentation is linked
|
||||
to for all non-Python-specific information.
|
||||
|
||||
Enumerations
|
||||
============
|
||||
@@ -12,9 +12,9 @@ The wrapped enumeration types below 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.
|
||||
|
||||
.. py:class:: loot_api.GameType
|
||||
.. py:class:: loot.GameType
|
||||
|
||||
Wraps :cpp:type:`loot::GameType` to expose the LOOT API's game codes.
|
||||
Wraps :cpp:type:`loot::GameType` to expose libloot's game codes.
|
||||
|
||||
.. py:attribute:: fo3
|
||||
.. py:attribute:: fo4
|
||||
@@ -23,9 +23,9 @@ values are unsigned integer constants.
|
||||
.. py:attribute:: tes5
|
||||
.. py:attribute:: tes5se
|
||||
|
||||
.. py:class:: loot_api.LogLevel
|
||||
.. py:class:: loot.LogLevel
|
||||
|
||||
Wraps :cpp:type:`loot::LogLevel` to expose the LOOT API's log level codes.
|
||||
Wraps :cpp:type:`loot::LogLevel` to expose libloot's log level codes.
|
||||
|
||||
.. py:attribute:: trace
|
||||
.. py:attribute:: debug
|
||||
@@ -34,16 +34,16 @@ values are unsigned integer constants.
|
||||
.. py:attribute:: error
|
||||
.. py:attribute:: fatal
|
||||
|
||||
.. py:class:: loot_api.MessageType
|
||||
.. py:class:: loot.MessageType
|
||||
|
||||
Wraps :cpp:type:`loot::MessageType` to expose the LOOT API's message type
|
||||
Wraps :cpp:type:`loot::MessageType` to expose libloot's message type
|
||||
codes.
|
||||
|
||||
.. py:attribute:: error
|
||||
.. py:attribute:: say
|
||||
.. py:attribute:: warn
|
||||
|
||||
.. py:class:: loot_api.PluginCleanliness
|
||||
.. py:class:: loot.PluginCleanliness
|
||||
|
||||
Codes used to indicate the cleanliness of a plugin according to the
|
||||
information contained within the loaded masterlist/userlist.
|
||||
@@ -70,7 +70,7 @@ Public-Field Data Structures
|
||||
|
||||
Classes with public fields and no member functions.
|
||||
|
||||
.. py:class:: loot_api.MasterlistInfo
|
||||
.. py:class:: loot.MasterlistInfo
|
||||
|
||||
Wraps :cpp:class:`loot::MasterlistInfo`.
|
||||
|
||||
@@ -87,13 +87,13 @@ Classes with public fields and no member functions.
|
||||
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_api.SimpleMessage
|
||||
.. py:class:: loot.SimpleMessage
|
||||
|
||||
Wraps :cpp:class:`loot::SimpleMessage`.
|
||||
|
||||
.. py:attribute:: type
|
||||
|
||||
A :py:class:`loot_api.MessageType` giving the message type.
|
||||
A :py:class:`loot.MessageType` giving the message type.
|
||||
|
||||
.. py:attribute:: language
|
||||
|
||||
@@ -107,7 +107,7 @@ Classes with public fields and no member functions.
|
||||
|
||||
A Unicode string containing the message condition.
|
||||
|
||||
.. py:class:: loot_api.PluginTags
|
||||
.. py:class:: loot.PluginTags
|
||||
|
||||
Wraps :cpp:class:`loot::PluginTags`.
|
||||
|
||||
@@ -127,74 +127,68 @@ Classes with public fields and no member functions.
|
||||
Functions
|
||||
=========
|
||||
|
||||
.. py:function:: loot_api.set_logging_callback(callback) -> NoneType
|
||||
.. 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_api.is_compatible(int, int, int) -> bool
|
||||
.. py:function:: loot.is_compatible(int, int, int) -> bool
|
||||
|
||||
Checks for API compatibility. Wraps :cpp:func:`loot::IsCompatible`.
|
||||
|
||||
.. py:function:: loot_api.InitialiseLocale(unicode = u'') -> NoneType
|
||||
|
||||
Initialise the current global locale using the given ID. A blank value means
|
||||
that the system default locale will be initialised. Wraps
|
||||
:cpp:func:`loot::InitialiseLocale`.
|
||||
|
||||
.. py:function:: loot_api.create_game_handle(game : loot_api.GameType, game_path : unicode, [game_local_path : unicode = u'']) -> loot_api.GameInterface
|
||||
.. 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_api.GameInterface
|
||||
.. py:class:: loot.GameInterface
|
||||
|
||||
Wraps :cpp:class:`loot::GameInterface`.
|
||||
|
||||
.. py:function:: loot_api.get_database() -> loot_api.DatabaseInterface
|
||||
.. py:function:: loot.get_database() -> loot.DatabaseInterface
|
||||
|
||||
Get a database handle. Wraps :cpp:func:`loot::GetDatabase`.
|
||||
|
||||
.. py:function:: loot_api.load_current_load_order_state() -> NoneType
|
||||
.. 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_api.DatabaseInterface
|
||||
.. py:class:: loot.DatabaseInterface
|
||||
|
||||
Wraps :cpp:class:`loot::DatabaseInterface`.
|
||||
|
||||
.. py:method:: get_masterlist_revision(loot_api.DatabaseInterface, unicode, bool) -> loot_api.MasterlistInfo
|
||||
.. 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_api.DatabaseInterface, plugin : unicode, [includeUserMetadata : bool = True, [evaluateConditions : bool = False]]) -> loot_api.PluginMetadata
|
||||
.. 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_api.DatabaseInterface, plugin : unicode, [evaluateConditions : bool = False]) -> loot_api.PluginCleanliness
|
||||
.. 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_api.DatabaseInterface, plugin : unicode, [evaluateConditions : bool = False]) -> loot_api.PluginTags
|
||||
.. 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_api.DatabaseInterface, masterlist_path : unicode, [userlist_path : unicode = u'']) -> NoneType
|
||||
.. 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_api.DatabaseInterface, unicode, unicode, unicode) -> bool
|
||||
.. 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_api.DatabaseInterface, unicode, bool) -> NoneType
|
||||
.. 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`.
|
||||
|
||||
.. py:class:: loot_api.Version
|
||||
.. py:class:: loot.Version
|
||||
|
||||
Wraps :cpp:class:`loot::LootVersion`.
|
||||
|
||||
@@ -218,10 +212,9 @@ Classes
|
||||
|
||||
Returns the API version as a string of the form ``major.minor.patch``
|
||||
|
||||
.. py:class:: loot_api.WrapperVersion
|
||||
.. py:class:: loot.WrapperVersion
|
||||
|
||||
Provides information about the version of the LOOT API Python wrapper that is
|
||||
being run.
|
||||
Provides information about the version of libloot-python that is being run.
|
||||
|
||||
.. py:attribute:: major
|
||||
|
||||
@@ -243,11 +236,11 @@ Classes
|
||||
|
||||
Returns the API version as a string of the form ``major.minor.patch``
|
||||
|
||||
.. py:class:: loot_api.PluginMetadata
|
||||
.. py:class:: loot.PluginMetadata
|
||||
|
||||
Wraps :cpp:class:`loot::PluginMetadata`.
|
||||
|
||||
.. py:method:: get_simple_messages(loot_api.PluginMetadata, unicode) -> list<loot_api.SimpleMessage>
|
||||
.. 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`.
|
||||
|
||||
+9
-10
@@ -7,16 +7,16 @@ Installing the wrapper
|
||||
|
||||
Build archives contain two binaries:
|
||||
|
||||
* ``loot_api.pyd`` is the Python wrapper
|
||||
* ``loot_api.dll`` is the C++ API DLL that the Python wrapper was built against.
|
||||
* ``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++ 2015 Redistributable (x86)`_
|
||||
The C++ DLL requires the `Visual C++ 2022 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++ 2015 Redistributable (x86): https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe
|
||||
.. _Visual C++ 2022 Redistributable (x86): https://aka.ms/vs/17/release/vc_redist.x86.exe
|
||||
|
||||
Using the wrapper
|
||||
=================
|
||||
@@ -27,10 +27,10 @@ Checking Compatibility
|
||||
To check if the module loaded is compatible with the version of the API that you
|
||||
developed against::
|
||||
|
||||
>>> import loot_api
|
||||
>>> loot_api.is_compatible(0,12,0)
|
||||
>>> import loot
|
||||
>>> loot.is_compatible(0,14,0)
|
||||
True
|
||||
>>> loot_api.is_compatible(0,9,0)
|
||||
>>> loot.is_compatible(0,9,0)
|
||||
False
|
||||
|
||||
Getting a Plugin's Bash Tag Suggestions
|
||||
@@ -38,9 +38,8 @@ Getting a Plugin's Bash Tag Suggestions
|
||||
|
||||
To get a plugin's Bash Tag suggestions from a ``masterlist.yaml`` metadata file::
|
||||
|
||||
>>> import loot_api
|
||||
>>> loot_api.initialise_locale()
|
||||
>>> db = loot_api.create_game_handle(loot_api.GameType.tes4, 'C:\\path\\to\\oblivion\\directory')
|
||||
>>> import loot
|
||||
>>> db = loot.create_game_handle(loot.GameType.tes4, 'C:\\path\\to\\oblivion\\directory')
|
||||
>>> db.load_lists('masterlist.yaml')
|
||||
>>> tags = db.get_plugin_tags(u'Unofficial Oblivion Patch.esp')
|
||||
>>> tags.added
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from .loot import *
|
||||
@@ -0,0 +1,88 @@
|
||||
import itertools
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
|
||||
from setuptools import Distribution, find_packages, setup
|
||||
|
||||
try: # python 3
|
||||
import winreg
|
||||
from urllib.request import urlretrieve
|
||||
except ImportError: # python 2
|
||||
import _winreg as winreg
|
||||
from urllib import urlretrieve
|
||||
|
||||
|
||||
MSVC_MIN_VERSION = (14, 0, 24215)
|
||||
|
||||
|
||||
class BinaryDistribution(Distribution):
|
||||
def has_ext_modules(foo):
|
||||
return True
|
||||
|
||||
|
||||
def is_msvc_redist_installed(major, minor, build):
|
||||
if platform.machine().endswith("64"): # check if os is 64bit
|
||||
sub_key = "SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x64"
|
||||
else:
|
||||
sub_key = "SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x86"
|
||||
try:
|
||||
key_handle = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, sub_key)
|
||||
runtime_installed = winreg.QueryValueEx(key_handle, "Installed")[0]
|
||||
installed_major = winreg.QueryValueEx(key_handle, "Major")[0]
|
||||
installed_minor = winreg.QueryValueEx(key_handle, "Minor")[0]
|
||||
installed_build = winreg.QueryValueEx(key_handle, "Bld")[0]
|
||||
return (
|
||||
runtime_installed != 0
|
||||
and installed_major >= major
|
||||
and installed_minor >= minor
|
||||
and installed_build >= build
|
||||
)
|
||||
except WindowsError as exc:
|
||||
return False
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
def install_msvc_redist():
|
||||
url = (
|
||||
"https://download.microsoft.com/download/6/A/A/"
|
||||
"6AA4EDFF-645B-48C5-81CC-ED5963AEAD48/vc_redist.x86.exe"
|
||||
)
|
||||
dl_dir = tempfile.mkdtemp()
|
||||
dl_file = os.path.join(dl_dir, "vc_redist.exe")
|
||||
urlretrieve(url, dl_file)
|
||||
subprocess.call([dl_file, "/quiet"])
|
||||
# trying to remove the temp folder triggers
|
||||
# an error during py2 pip install
|
||||
|
||||
|
||||
if not is_msvc_redist_installed(*MSVC_MIN_VERSION):
|
||||
install_msvc_redist()
|
||||
|
||||
# The version string is substituted in by CMake.
|
||||
setup(
|
||||
name="libloot-python",
|
||||
version="@LIBLOOT_PY_VERSION_MAJOR@.@LIBLOOT_PY_VERSION_MINOR@.@LIBLOOT_PY_VERSION_PATCH@",
|
||||
description="A Python module that wraps libloot.",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/loot/libloot-python",
|
||||
packages=find_packages(),
|
||||
include_package_data=True,
|
||||
package_data={"loot": ["loot*.pyd", "loot.dll"]},
|
||||
distclass=BinaryDistribution,
|
||||
classifiers=[
|
||||
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: C++'
|
||||
'Operating System :: Microsoft :: Windows',
|
||||
'Intended Audience :: Developers',
|
||||
],
|
||||
python_requires='>=3.7',
|
||||
)
|
||||
+21
-12
@@ -31,21 +31,25 @@ PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std:
|
||||
PluginTags tags;
|
||||
|
||||
auto metadata = db->GetPluginMetadata(plugin, false, evaluateConditions);
|
||||
for (const auto &tag : metadata.GetTags()) {
|
||||
if (metadata.has_value()) {
|
||||
for (const auto &tag : metadata.value().GetTags()) {
|
||||
if (tag.IsAddition())
|
||||
tags.added.insert(tag.GetName());
|
||||
else
|
||||
tags.removed.insert(tag.GetName());
|
||||
}
|
||||
}
|
||||
|
||||
metadata = db->GetPluginUserMetadata(plugin, evaluateConditions);
|
||||
tags.userlist_modified = !metadata.GetTags().empty();
|
||||
for (const auto &tag : metadata.GetTags()) {
|
||||
if (metadata.has_value()) {
|
||||
tags.userlist_modified = !metadata.value().GetTags().empty();
|
||||
for (const auto &tag : metadata.value().GetTags()) {
|
||||
if (tag.IsAddition())
|
||||
tags.added.insert(tag.GetName());
|
||||
else
|
||||
tags.removed.insert(tag.GetName());
|
||||
}
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
@@ -53,22 +57,27 @@ PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std:
|
||||
PluginCleanliness GetPluginCleanliness(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin, bool evaluateConditions) {
|
||||
auto metadata = db->GetPluginMetadata(plugin, true, evaluateConditions);
|
||||
|
||||
if (metadata.GetDirtyInfo().empty()) {
|
||||
if (metadata.GetCleanInfo().empty()) {
|
||||
return PluginCleanliness::unknown;
|
||||
} else {
|
||||
return PluginCleanliness::clean;
|
||||
}
|
||||
} else if (!metadata.GetCleanInfo().empty()) {
|
||||
if (!metadata.has_value()) {
|
||||
return PluginCleanliness::unknown;
|
||||
}
|
||||
|
||||
for (const auto& info : metadata.GetDirtyInfo()) {
|
||||
auto dirtyInfo = metadata.value().GetDirtyInfo();
|
||||
auto cleanInfo = metadata.value().GetCleanInfo();
|
||||
|
||||
if (dirtyInfo.empty() == cleanInfo.empty()) {
|
||||
return PluginCleanliness::unknown;
|
||||
}
|
||||
|
||||
if (!cleanInfo.empty()) {
|
||||
return PluginCleanliness::clean;
|
||||
}
|
||||
|
||||
for (const auto& info : dirtyInfo) {
|
||||
if (info.ChooseInfo("en").GetText().find("Do not clean") != std::string::npos) {
|
||||
return PluginCleanliness::do_not_clean;
|
||||
}
|
||||
}
|
||||
|
||||
return PluginCleanliness::unknown;
|
||||
return PluginCleanliness::dirty;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -22,8 +22,8 @@ along with LOOT. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOOT_API_PYTHON_CONVENIENCE
|
||||
#define LOOT_API_PYTHON_CONVENIENCE
|
||||
#ifndef LIBLOOT_PYTHON_CONVENIENCE
|
||||
#define LIBLOOT_PYTHON_CONVENIENCE
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
+39
-12
@@ -34,8 +34,32 @@ using pybind11::arg;
|
||||
using pybind11::enum_;
|
||||
using pybind11::class_;
|
||||
using pybind11::metaclass;
|
||||
using std::filesystem::path;
|
||||
using std::filesystem::u8path;
|
||||
|
||||
namespace loot {
|
||||
namespace py {
|
||||
std::shared_ptr<GameInterface> CreateGameHandle(GameType gameType, std::string gamePath, std::string gameLocalPath) {
|
||||
return CreateGameHandle(gameType, u8path(gamePath), u8path(gameLocalPath));
|
||||
}
|
||||
|
||||
void LoadLists(std::shared_ptr<DatabaseInterface> db, std::string masterlistPath, std::string userlistPath) {
|
||||
return db->LoadLists(u8path(masterlistPath), u8path(userlistPath));
|
||||
}
|
||||
|
||||
void WriteMinimalList(std::shared_ptr<DatabaseInterface> db, std::string outputFile, bool overwrite) {
|
||||
return db->WriteMinimalList(u8path(outputFile), overwrite);
|
||||
}
|
||||
|
||||
bool UpdateMasterlist(std::shared_ptr<DatabaseInterface> db, std::string masterlistPath, std::string remoteUrl, std::string remoteBranch) {
|
||||
return db->UpdateMasterlist(u8path(masterlistPath), remoteUrl, remoteBranch);
|
||||
}
|
||||
|
||||
MasterlistInfo GetMasterlistRevision(std::shared_ptr<DatabaseInterface> db, std::string masterlistPath, bool getShortId) {
|
||||
return db->GetMasterlistRevision(u8path(masterlistPath), getShortId);
|
||||
}
|
||||
}
|
||||
|
||||
void bindEnums(pybind11::module& module) {
|
||||
enum_<GameType>(module, "GameType")
|
||||
.value("tes4", GameType::tes4)
|
||||
@@ -94,7 +118,7 @@ void bindVersionClasses(pybind11::module& module) {
|
||||
.def_readonly_static("minor", &LootVersion::minor)
|
||||
.def_readonly_static("patch", &LootVersion::patch)
|
||||
.def_readonly_static("revision", &LootVersion::revision)
|
||||
.def_static("string", LootVersion::string);
|
||||
.def_static("string", LootVersion::GetVersionString);
|
||||
|
||||
class_<WrapperVersion>(module, "WrapperVersion")
|
||||
.def_readonly_static("major", &WrapperVersion::major)
|
||||
@@ -110,9 +134,9 @@ void bindInterfaceClasses(pybind11::module& module) {
|
||||
.def("get_database", &GameInterface::GetDatabase);
|
||||
|
||||
class_<DatabaseInterface, std::shared_ptr<DatabaseInterface>>(module, "DatabaseInterface")
|
||||
.def("load_lists", &DatabaseInterface::LoadLists, arg("masterlist_path"), arg("userlist_path") = "")
|
||||
.def("update_masterlist", &DatabaseInterface::UpdateMasterlist)
|
||||
.def("get_masterlist_revision", &DatabaseInterface::GetMasterlistRevision)
|
||||
.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,
|
||||
arg("plugin"),
|
||||
arg("includeUserMetadata") = true,
|
||||
@@ -123,7 +147,7 @@ void bindInterfaceClasses(pybind11::module& module) {
|
||||
.def("get_plugin_cleanliness", &GetPluginCleanliness,
|
||||
arg("plugin"),
|
||||
arg("evaluateConditions") = false)
|
||||
.def("write_minimal_list", &DatabaseInterface::WriteMinimalList);
|
||||
.def("write_minimal_list", &py::WriteMinimalList);
|
||||
}
|
||||
|
||||
void bindClasses(pybind11::module& module) {
|
||||
@@ -135,23 +159,26 @@ void bindClasses(pybind11::module& module) {
|
||||
void bindFunctions(pybind11::module& module) {
|
||||
module.def("set_logging_callback", &SetLoggingCallback);
|
||||
|
||||
// Need to clear the stored logging callback when exiting, or Python will
|
||||
// hang because the callback pointer is still stored by libloot.
|
||||
auto atexit = pybind11::module::import("atexit");
|
||||
atexit.attr("register")(pybind11::cpp_function([]() {
|
||||
SetLoggingCallback(nullptr);
|
||||
}));
|
||||
|
||||
module.def("is_compatible", &IsCompatible);
|
||||
|
||||
module.def("initialise_locale", &InitialiseLocale, arg("id") = "");
|
||||
|
||||
module.def("create_game_handle", &CreateGameHandle,
|
||||
module.def("create_game_handle", &py::CreateGameHandle,
|
||||
arg("game"),
|
||||
arg("game_path"),
|
||||
arg("game_local_path") = "");
|
||||
}
|
||||
}
|
||||
|
||||
PYBIND11_PLUGIN(loot_api) {
|
||||
pybind11::module module("loot_api", "A Python module that wraps the LOOT API, generated by pybind11.");
|
||||
PYBIND11_MODULE(loot, module) {
|
||||
module.doc() = "A Python module that wraps libloot, generated by pybind11.";
|
||||
|
||||
loot::bindEnums(module);
|
||||
loot::bindClasses(module);
|
||||
loot::bindFunctions(module);
|
||||
|
||||
return module.ptr();
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
along with LOOT. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LOOT_PLUGIN_CLEANLINESS
|
||||
#define LOOT_PLUGIN_CLEANLINESS
|
||||
#ifndef LIBLOOT_PYTHON_PLUGIN_CLEANLINESS
|
||||
#define LIBLOOT_PYTHON_PLUGIN_CLEANLINESS
|
||||
|
||||
/**
|
||||
* The namespace used by the LOOT API.
|
||||
* The namespace used by libloot.
|
||||
*/
|
||||
namespace loot {
|
||||
/**
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@
|
||||
along with LOOT. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LOOT_PLUGIN_TAGS
|
||||
#define LOOT_PLUGIN_TAGS
|
||||
#ifndef LIBLOOT_PYTHON_PLUGIN_TAGS
|
||||
#define LIBLOOT_PYTHON_PLUGIN_TAGS
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
#include "wrapper_version.h"
|
||||
|
||||
namespace loot {
|
||||
const unsigned int WrapperVersion::major = 3;
|
||||
const unsigned int WrapperVersion::minor = 1;
|
||||
const unsigned int WrapperVersion::patch = 1;
|
||||
const unsigned int WrapperVersion::major = @LIBLOOT_PY_VERSION_MAJOR@;
|
||||
const unsigned int WrapperVersion::minor = @LIBLOOT_PY_VERSION_MINOR@;
|
||||
const unsigned int WrapperVersion::patch = @LIBLOOT_PY_VERSION_PATCH@;
|
||||
const std::string WrapperVersion::revision = "@GIT_COMMIT_STRING@";
|
||||
|
||||
std::string WrapperVersion::string() {
|
||||
|
||||
@@ -22,8 +22,8 @@ along with LOOT. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOOT_API_PYTHON_WRAPPER_VERSION
|
||||
#define LOOT_API_PYTHON_WRAPPER_VERSION
|
||||
#ifndef LIBLOOT_PYTHON_WRAPPER_VERSION
|
||||
#define LIBLOOT_PYTHON_WRAPPER_VERSION
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user