13 Commits
Author SHA1 Message Date
Oliver Hamlet a564f230be Update wrapper version to 3.1.0
Although the LOOT API update includes breaking changes, none of them are
exposed by the Python wrapper, so this is just a minor update.
2018-04-15 13:16:49 +01:00
Oliver Hamlet 27c8f58494 Update pybind11 to v2.2.2 2018-04-15 13:16:49 +01:00
Oliver Hamlet 179125f006 Expose GameType::tes5vr and GameType::fo4vr 2018-04-15 13:16:49 +01:00
Oliver Hamlet 671ca81beb Update to LOOT API v0.13.1 2018-04-15 13:16:49 +01:00
Oliver Hamlet 7faa360790 Update outdated usage example 2017-12-30 15:29:21 +00:00
Oliver Hamlet 0c9d014174 Remove default value for create_game_handle's game_path argument
The LOOT API incorrectly allows it, it causes a runtime exception.
2017-12-30 15:29:03 +00:00
Oliver Hamlet a8e2b11280 Allow initialise_locale() to be called with no args
Use a blank string as the default argument, as it's the most commonly desired value.
2017-12-30 15:27:48 +00:00
Oliver Hamlet 1275a11be7 Expose load_current_load_order_state() via GameInterface 2017-11-04 17:27:15 +00:00
Oliver Hamlet 5357858069 Update documentation 2017-11-04 13:52:19 +00:00
Oliver Hamlet 04088ac8f4 Update wrapper version to 3.0.0 2017-11-04 12:29:27 +00:00
Oliver Hamlet 7098671ad5 Update to LOOT API v0.12.0
Significant changes include:

- The logging interface has changed, a callback can now be set
  instead of an output file and verbosity, giving clients more
  control.
- DatabaseInterface::EvalLists() has been removed.
- SimpleMessage now has a condition field.
2017-11-04 12:14:26 +00:00
Oliver Hamlet 212f899396 Update to pybind11 v2.2.1 2017-10-17 19:57:42 +01:00
Oliver Hamlet 1e0dbe8dc2 Update to LOOT API v0.11.1 and fix Linux builds 2017-10-17 20:34:45 +01:00
8 changed files with 156 additions and 100 deletions
+10 -4
View File
@@ -30,9 +30,10 @@ configure_file("${CMAKE_SOURCE_DIR}/src/wrapper_version.cpp.in" "${CMAKE_BINARY_
# pybind11 # pybind11
####################################### #######################################
set(PYBIND11_URL "https://github.com/pybind/pybind11/archive/v2.1.1.tar.gz") set(PYBIND11_VERSION "2.2.2")
set(PYBIND11_DOWNLOAD_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-2.1.1.tar.gz") set(PYBIND11_URL "https://github.com/pybind/pybind11/archive/v${PYBIND11_VERSION}.tar.gz")
set(PYBIND11_EXTRACTED_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-2.1.1") set(PYBIND11_DOWNLOAD_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-${PYBIND11_VERSION}.tar.gz")
set(PYBIND11_EXTRACTED_PATH "${EXTERNAL_PROJECTS_PATH}/pybind11-${PYBIND11_VERSION}")
if (NOT EXISTS ${PYBIND11_DOWNLOAD_PATH}) if (NOT EXISTS ${PYBIND11_DOWNLOAD_PATH})
file(DOWNLOAD ${PYBIND11_URL} ${PYBIND11_DOWNLOAD_PATH}) file(DOWNLOAD ${PYBIND11_URL} ${PYBIND11_DOWNLOAD_PATH})
@@ -48,10 +49,15 @@ add_subdirectory(${PYBIND11_EXTRACTED_PATH})
# LOOT API # LOOT API
####################################### #######################################
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
set(LOOT_API_URL "https://github.com/loot/loot-api/releases/download/0.13.1/loot_api-0.13.1-0-g1804e45_dev-win32.7z")
else()
set(LOOT_API_URL "https://github.com/loot/loot-api/releases/download/0.13.1/loot-api.tar.xz")
endif()
ExternalProject_Add(loot-api-c++ ExternalProject_Add(loot-api-c++
PREFIX "external" PREFIX "external"
URL "https://github.com/loot/loot-api/releases/download/0.11.0/loot_api-0.11.0-0-g8864f78_dev-win32.7z" URL ${LOOT_API_URL}
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
INSTALL_COMMAND "") INSTALL_COMMAND "")
+72 -37
View File
@@ -14,8 +14,7 @@ values are unsigned integer constants.
.. py:class:: loot_api.GameType .. py:class:: loot_api.GameType
Wraps :cpp:type:`loot::GameType` to expose the LOOT API's game Wraps :cpp:type:`loot::GameType` to expose the LOOT API's game codes.
codes.
.. py:attribute:: fo3 .. py:attribute:: fo3
.. py:attribute:: fo4 .. py:attribute:: fo4
@@ -24,27 +23,21 @@ values are unsigned integer constants.
.. py:attribute:: tes5 .. py:attribute:: tes5
.. py:attribute:: tes5se .. py:attribute:: tes5se
.. py:class:: loot_api.LanguageCode .. py:class:: loot_api.LogLevel
Wraps :cpp:type:`loot::LanguageCode` to expose the LOOT API's Wraps :cpp:type:`loot::LogLevel` to expose the LOOT API's log level codes.
language codes.
.. py:attribute:: english .. py:attribute:: trace
.. py:attribute:: spanish .. py:attribute:: debug
.. py:attribute:: russian .. py:attribute:: info
.. py:attribute:: french .. py:attribute:: warning
.. py:attribute:: chinese .. py:attribute:: error
.. py:attribute:: polish .. py:attribute:: fatal
.. py:attribute:: brazilian_portuguese
.. py:attribute:: finnish
.. py:attribute:: german
.. py:attribute:: danish
.. py:attribute:: korean
.. py:class:: loot_api.MessageType .. py:class:: loot_api.MessageType
Wraps :cpp:type:`loot::MessageType` to expose the LOOT API's Wraps :cpp:type:`loot::MessageType` to expose the LOOT API's message type
message type codes. codes.
.. py:attribute:: error .. py:attribute:: error
.. py:attribute:: say .. py:attribute:: say
@@ -52,13 +45,26 @@ values are unsigned integer constants.
.. py:class:: loot_api.PluginCleanliness .. py:class:: loot_api.PluginCleanliness
Wraps :cpp:type:`loot::PluginCleanliness` to expose the LOOT API's plugin cleanliness state codes. Codes used to indicate the cleanliness of a plugin according to the
information contained within the loaded masterlist/userlist.
.. py:attribute:: clean .. py:attribute:: clean
Indicates that the plugin is clean.
.. py:attribute:: dirty .. py:attribute:: dirty
Indicates that the plugin is dirty.
.. py:attribute:: do_not_clean .. 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 .. py:attribute:: unknown
Indicates that no data is available on whether the plugin is dirty or not.
Public-Field Data Structures Public-Field Data Structures
============================ ============================
@@ -81,7 +87,7 @@ Classes with public fields and no member functions.
A boolean that is true if the masterlist has been modified from its state A boolean that is true if the masterlist has been modified from its state
at the commit given by :py:attr:`revision_id`. at the commit given by :py:attr:`revision_id`.
.. py:class:: loot_api.Message .. py:class:: loot_api.SimpleMessage
Wraps :cpp:class:`loot::SimpleMessage`. Wraps :cpp:class:`loot::SimpleMessage`.
@@ -91,12 +97,16 @@ Classes with public fields and no member functions.
.. py:attribute:: language .. py:attribute:: language
A :py:class:`loot_api.LanguageCode` giving the message text language. A Unicode string giving the message text language.
.. py:attribute:: text .. py:attribute:: text
A Unicode string containing the message text. A Unicode string containing the message text.
.. py:attribute:: condition
A Unicode string containing the message condition.
.. py:class:: loot_api.PluginTags .. py:class:: loot_api.PluginTags
Wraps :cpp:class:`loot::PluginTags`. Wraps :cpp:class:`loot::PluginTags`.
@@ -117,49 +127,65 @@ Classes with public fields and no member functions.
Functions Functions
========= =========
.. py:function:: loot_api.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_api.is_compatible(int, int, int) -> bool
Checks for API compatibility. Wraps :cpp:func:`loot::IsCompatible`. Checks for API compatibility. Wraps :cpp:func:`loot::IsCompatible`.
.. py:function:: loot_api.create_database(game : loot_api.GameType, [game_path : unicode = u'', [game_local_path : unicode = u'']]) -> loot_api.DatabaseInterface .. py:function:: loot_api.InitialiseLocale(unicode = u'') -> NoneType
Initialise a new database handle. Wraps :cpp:func:`loot::IsCompatible`. 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
Initialise a new game handle. Wraps :cpp:func:`loot::CreateGameHandle`.
Classes Classes
======= =======
.. py:class:: loot_api.GameInterface
Wraps :cpp:class:`loot::GameInterface`.
.. py:function:: loot_api.get_database() -> loot_api.DatabaseInterface
Get a database handle. Wraps :cpp:func:`loot::GetDatabase`.
.. py:function:: loot_api.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_api.DatabaseInterface
Wraps :cpp:class:`loot::DatabaseInterface`. Wraps :cpp:class:`loot::DatabaseInterface`.
.. py:method:: eval_lists(loot_api.DatabaseInterface) -> NoneType
Evaluates all conditions and regular expression metadata entries in the loaded metadata lists. Wraps :cpp:func:`EvalLists`.
.. py:method:: get_masterlist_revision(loot_api.DatabaseInterface, unicode, bool) -> loot_api.MasterlistInfo .. py:method:: get_masterlist_revision(loot_api.DatabaseInterface, unicode, bool) -> loot_api.MasterlistInfo
Gets the give masterlist’s source control revision. Wraps :cpp:func:`GetMasterlistRevision`. Gets the give masterlist’s source control revision. Wraps :cpp:func:`GetMasterlistRevision`.
.. py:method:: get_plugin_cleanliness(loot_api.DatabaseInterface, unicode) -> loot_api.PluginCleanliness .. py:method:: get_plugin_metadata(loot_api.DatabaseInterface, plugin : unicode, [includeUserMetadata : bool = True, [evaluateConditions : bool = False]]) -> loot_api.PluginMetadata
Determines the database’s knowledge of a plugin’s cleanliness. Wraps :cpp:func:`GetPluginCleanliness`. Get all a plugin’s loaded metadata. Wraps :cpp:func:`GetPluginMetadata`.
.. py:method:: get_plugin_messages(loot_api.DatabaseInterface, unicode, loot_api.LanguageCode) -> list<loot_api.Message> .. py:method:: get_plugin_cleanliness(loot_api.DatabaseInterface, plugin : unicode, [evaluateConditions : bool = False]) -> loot_api.PluginCleanliness
Outputs the messages associated with the given plugin in the database. Wraps :cpp:func:`GetPluginMessages`. 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, unicode) -> loot_api.PluginTags .. py:method:: get_plugin_tags(loot_api.DatabaseInterface, plugin : unicode, [evaluateConditions : bool = False]) -> loot_api.PluginTags
Outputs the Bash Tags suggested for addition and removal by the database for the given plugin. Wraps :cpp:func:`GetPluginTags`. 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_api.DatabaseInterface, masterlist_path : unicode, [userlist_path : unicode = u'']) -> NoneType
Loads the masterlist and userlist from the paths specified. Wraps :cpp:func:`LoadLists`. Loads the masterlist and userlist from the paths specified. Wraps :cpp:func:`LoadLists`.
.. py:method:: sort_plugins(loot_api.DatabaseInterface, list<unicode>) -> list<unicode>
Calculates a new load order for all a game’s installed plugins and outputs the sorted order. Wraps :cpp:func:`SortPlugins`.
.. py:method:: update_masterlist(loot_api.DatabaseInterface, unicode, unicode, unicode) -> bool .. py:method:: update_masterlist(loot_api.DatabaseInterface, unicode, unicode, unicode) -> bool
Updates the given masterlist using the given Git repository details. Wraps :cpp:func:`UpdateMasterlist`. Updates the given masterlist using the given Git repository details. Wraps :cpp:func:`UpdateMasterlist`.
@@ -216,3 +242,12 @@ Classes
.. py:staticmethod:: string() -> unicode .. py:staticmethod:: string() -> unicode
Returns the API version as a string of the form ``major.minor.patch`` Returns the API version as a string of the form ``major.minor.patch``
.. py:class:: loot_api.PluginMetadata
Wraps :cpp:class:`loot::PluginMetadata`.
.. py:method:: get_simple_messages(loot_api.PluginMetadata, unicode) -> list<loot_api.SimpleMessage>
Get the plugin’s messages as SimpleMessage objects for the given language.
Wraps :cpp:func:`GetPluginMessages`.
+4 -3
View File
@@ -28,7 +28,7 @@ To check if the module loaded is compatible with the version of the API that you
developed against:: developed against::
>>> import loot_api >>> import loot_api
>>> loot_api.is_compatible(0,10,0) >>> loot_api.is_compatible(0,12,0)
True True
>>> loot_api.is_compatible(0,9,0) >>> loot_api.is_compatible(0,9,0)
False False
@@ -39,8 +39,9 @@ Getting a Plugin's Bash Tag Suggestions
To get a plugin's Bash Tag suggestions from a ``masterlist.yaml`` metadata file:: To get a plugin's Bash Tag suggestions from a ``masterlist.yaml`` metadata file::
>>> import loot_api >>> import loot_api
>>> db = loot_api.create_database(loot_api.GameType.tes4, '', '') >>> loot_api.initialise_locale()
>>> db.load_lists('masterlist.yaml', '') >>> db = loot_api.create_game_handle(loot_api.GameType.tes4, 'C:\\path\\to\\oblivion\\directory')
>>> db.load_lists('masterlist.yaml')
>>> tags = db.get_plugin_tags(u'Unofficial Oblivion Patch.esp') >>> tags = db.get_plugin_tags(u'Unofficial Oblivion Patch.esp')
>>> tags.added >>> tags.added
set([u'Scripts', u'Relations', u'C.Owner', u'Actors.AIPackages', u'Actors.Stats', u'Actors.ACBS', u'C.Music', u'Factions', u'Invent', u'Relev', u'Names', u'C.Light', u'Delev', u'C.Name', u'C.Climate', u'NPC.Class', u'Stats', u'Actors.DeathItem', u'Creatures.Blood', u'Actors.CombatStyle', u'Actors.AIData']) set([u'Scripts', u'Relations', u'C.Owner', u'Actors.AIPackages', u'Actors.Stats', u'Actors.ACBS', u'C.Music', u'Factions', u'Invent', u'Relev', u'Names', u'C.Light', u'Delev', u'C.Name', u'C.Climate', u'NPC.Class', u'Stats', u'Actors.DeathItem', u'Creatures.Blood', u'Actors.CombatStyle', u'Actors.AIData'])
+5 -10
View File
@@ -27,15 +27,10 @@ along with LOOT. If not, see
#include <loot/api.h> #include <loot/api.h>
namespace loot { namespace loot {
std::shared_ptr<DatabaseInterface> CreateDatabase(const GameType game, const std::string & game_path, const std::string & game_local_path) { PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin, bool evaluateConditions) {
auto gameHandle = CreateGameHandle(game, game_path, game_local_path);
return gameHandle->GetDatabase();
}
PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin) {
PluginTags tags; PluginTags tags;
auto metadata = db->GetPluginMetadata(plugin, false, false); auto metadata = db->GetPluginMetadata(plugin, false, evaluateConditions);
for (const auto &tag : metadata.GetTags()) { for (const auto &tag : metadata.GetTags()) {
if (tag.IsAddition()) if (tag.IsAddition())
tags.added.insert(tag.GetName()); tags.added.insert(tag.GetName());
@@ -43,7 +38,7 @@ PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std:
tags.removed.insert(tag.GetName()); tags.removed.insert(tag.GetName());
} }
metadata = db->GetPluginUserMetadata(plugin, false); metadata = db->GetPluginUserMetadata(plugin, evaluateConditions);
tags.userlist_modified = !metadata.GetTags().empty(); tags.userlist_modified = !metadata.GetTags().empty();
for (const auto &tag : metadata.GetTags()) { for (const auto &tag : metadata.GetTags()) {
if (tag.IsAddition()) if (tag.IsAddition())
@@ -55,8 +50,8 @@ PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std:
return tags; return tags;
} }
PluginCleanliness GetPluginCleanliness(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin) { PluginCleanliness GetPluginCleanliness(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin, bool evaluateConditions) {
auto metadata = db->GetPluginMetadata(plugin, true, false); auto metadata = db->GetPluginMetadata(plugin, true, evaluateConditions);
if (metadata.GetDirtyInfo().empty()) { if (metadata.GetDirtyInfo().empty()) {
if (metadata.GetCleanInfo().empty()) { if (metadata.GetCleanInfo().empty()) {
+7 -7
View File
@@ -34,13 +34,13 @@ along with LOOT. If not, see
#include "plugin_tags.h" #include "plugin_tags.h"
namespace loot { namespace loot {
std::shared_ptr<DatabaseInterface> CreateDatabase(const GameType game, PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db,
const std::string& game_path = "", const std::string& plugin,
const std::string& game_local_path = ""); bool evaluateConditions = false);
PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin); PluginCleanliness GetPluginCleanliness(const std::shared_ptr<DatabaseInterface> db,
const std::string& plugin,
PluginCleanliness GetPluginCleanliness(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin); bool evaluateConditions = false);
} }
#endif #endif
+36 -23
View File
@@ -25,6 +25,7 @@
#include <loot/api.h> #include <loot/api.h>
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "convenience.h" #include "convenience.h"
#include "wrapper_version.h" #include "wrapper_version.h"
@@ -40,14 +41,19 @@ void bindEnums(pybind11::module& module) {
.value("tes4", GameType::tes4) .value("tes4", GameType::tes4)
.value("tes5", GameType::tes5) .value("tes5", GameType::tes5)
.value("tes5se", GameType::tes5se) .value("tes5se", GameType::tes5se)
.value("tes5vr", GameType::tes5vr)
.value("fo3", GameType::fo3) .value("fo3", GameType::fo3)
.value("fonv", GameType::fonv) .value("fonv", GameType::fonv)
.value("fo4", GameType::fo4); .value("fo4", GameType::fo4)
.value("fo4vr", GameType::fo4vr);
enum_<LogVerbosity>(module, "LogVerbosity") enum_<LogLevel>(module, "LogLevel")
.value("off", LogVerbosity::off) .value("trace", LogLevel::trace)
.value("trace", LogVerbosity::trace) .value("debug", LogLevel::debug)
.value("warning", LogVerbosity::warning); .value("info", LogLevel::info)
.value("warning", LogLevel::warning)
.value("error", LogLevel::error)
.value("fatal", LogLevel::fatal);
enum_<MessageType>(module, "MessageType") enum_<MessageType>(module, "MessageType")
.value("say", MessageType::say) .value("say", MessageType::say)
@@ -70,7 +76,8 @@ void bindMetadataClasses(pybind11::module& module) {
class_<SimpleMessage>(module, "SimpleMessage") class_<SimpleMessage>(module, "SimpleMessage")
.def_readwrite("type", &SimpleMessage::type) .def_readwrite("type", &SimpleMessage::type)
.def_readwrite("language", &SimpleMessage::language) .def_readwrite("language", &SimpleMessage::language)
.def_readwrite("text", &SimpleMessage::text); .def_readwrite("text", &SimpleMessage::text)
.def_readwrite("condition", &SimpleMessage::condition);
class_<PluginTags>(module, "PluginTags") class_<PluginTags>(module, "PluginTags")
.def_readwrite("added", &PluginTags::added) .def_readwrite("added", &PluginTags::added)
@@ -82,14 +89,14 @@ void bindMetadataClasses(pybind11::module& module) {
} }
void bindVersionClasses(pybind11::module& module) { void bindVersionClasses(pybind11::module& module) {
class_<LootVersion>(module, "Version", metaclass()) class_<LootVersion>(module, "Version")
.def_readonly_static("major", &LootVersion::major) .def_readonly_static("major", &LootVersion::major)
.def_readonly_static("minor", &LootVersion::minor) .def_readonly_static("minor", &LootVersion::minor)
.def_readonly_static("patch", &LootVersion::patch) .def_readonly_static("patch", &LootVersion::patch)
.def_readonly_static("revision", &LootVersion::revision) .def_readonly_static("revision", &LootVersion::revision)
.def_static("string", LootVersion::string); .def_static("string", LootVersion::string);
class_<WrapperVersion>(module, "WrapperVersion", metaclass()) class_<WrapperVersion>(module, "WrapperVersion")
.def_readonly_static("major", &WrapperVersion::major) .def_readonly_static("major", &WrapperVersion::major)
.def_readonly_static("minor", &WrapperVersion::minor) .def_readonly_static("minor", &WrapperVersion::minor)
.def_readonly_static("patch", &WrapperVersion::patch) .def_readonly_static("patch", &WrapperVersion::patch)
@@ -98,17 +105,24 @@ void bindVersionClasses(pybind11::module& module) {
} }
void bindInterfaceClasses(pybind11::module& module) { 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_<DatabaseInterface, std::shared_ptr<DatabaseInterface>>(module, "DatabaseInterface") class_<DatabaseInterface, std::shared_ptr<DatabaseInterface>>(module, "DatabaseInterface")
.def("load_lists", &DatabaseInterface::LoadLists, arg("masterlist_path"), arg("userlist_path") = "") .def("load_lists", &DatabaseInterface::LoadLists, arg("masterlist_path"), arg("userlist_path") = "")
.def("eval_lists", &DatabaseInterface::EvalLists)
.def("update_masterlist", &DatabaseInterface::UpdateMasterlist) .def("update_masterlist", &DatabaseInterface::UpdateMasterlist)
.def("get_masterlist_revision", &DatabaseInterface::GetMasterlistRevision) .def("get_masterlist_revision", &DatabaseInterface::GetMasterlistRevision)
.def("get_plugin_metadata", &DatabaseInterface::GetPluginMetadata, .def("get_plugin_metadata", &DatabaseInterface::GetPluginMetadata,
arg("plugin"), arg("plugin"),
arg("includeUserMetadata") = true, arg("includeUserMetadata") = true,
arg("evaluateConditions") = false) arg("evaluateConditions") = false)
.def("get_plugin_tags", &GetPluginTags) .def("get_plugin_tags", &GetPluginTags,
.def("get_plugin_cleanliness", &GetPluginCleanliness) arg("plugin"),
arg("evaluateConditions") = false)
.def("get_plugin_cleanliness", &GetPluginCleanliness,
arg("plugin"),
arg("evaluateConditions") = false)
.def("write_minimal_list", &DatabaseInterface::WriteMinimalList); .def("write_minimal_list", &DatabaseInterface::WriteMinimalList);
} }
@@ -119,24 +133,23 @@ void bindClasses(pybind11::module& module) {
} }
void bindFunctions(pybind11::module& module) { void bindFunctions(pybind11::module& module) {
module.def("set_logging_verbosity", &SetLoggingVerbosity); module.def("set_logging_callback", &SetLoggingCallback);
module.def("set_log_file", &SetLogFile);
module.def("is_compatible", &IsCompatible); module.def("is_compatible", &IsCompatible);
module.def("initialise_locale", &InitialiseLocale); module.def("initialise_locale", &InitialiseLocale, arg("id") = "");
module.def("create_database", &CreateDatabase, arg("game"), arg("game_path") = "", arg("game_local_path") = ""); module.def("create_game_handle", &CreateGameHandle,
arg("game"),
arg("game_path"),
arg("game_local_path") = "");
} }
} }
PYBIND11_PLUGIN(loot_api) { PYBIND11_MODULE(loot_api, module) {
pybind11::module module("loot_api", "A Python module that wraps the LOOT API, generated by pybind11."); module.doc() = "A Python module that wraps the LOOT API, generated by pybind11.";
loot::bindEnums(module); loot::bindEnums(module);
loot::bindClasses(module); loot::bindClasses(module);
loot::bindFunctions(module); loot::bindFunctions(module);
return module.ptr();
} }
+20 -14
View File
@@ -7,16 +7,18 @@ import unittest
from loot_api import Version from loot_api import Version
from loot_api import WrapperVersion from loot_api import WrapperVersion
from loot_api import GameType from loot_api import GameType
from loot_api import LogVerbosity
from loot_api import SimpleMessage from loot_api import SimpleMessage
from loot_api import MessageType from loot_api import MessageType
from loot_api import create_database from loot_api import create_game_handle
from loot_api import is_compatible from loot_api import is_compatible
from loot_api import set_logging_verbosity from loot_api import set_logging_callback
from loot_api import initialise_locale from loot_api import initialise_locale
set_logging_verbosity(LogVerbosity.off) def logging_callback(level, message):
initialise_locale("") pass
set_logging_callback(logging_callback)
initialise_locale()
class GameFixture(unittest.TestCase): class GameFixture(unittest.TestCase):
game_path = os.path.join(u'.', u'Oblivion') game_path = os.path.join(u'.', u'Oblivion')
@@ -38,25 +40,26 @@ class GameFixture(unittest.TestCase):
class TestLootApi(GameFixture): class TestLootApi(GameFixture):
def test_is_compatible(self): def test_is_compatible(self):
self.assertFalse(is_compatible(0, 9, 0)) self.assertFalse(is_compatible(0, 9, 0))
self.assertTrue(is_compatible(0, 11, 0)) self.assertTrue(is_compatible(0, 13, 0))
def test_version(self): def test_version(self):
self.assertEqual(Version.major, 0) self.assertEqual(Version.major, 0)
self.assertEqual(Version.minor, 11) self.assertEqual(Version.minor, 13)
self.assertEqual(Version.patch, 0) self.assertEqual(Version.patch, 1)
self.assertNotEqual(Version.revision, u'') self.assertNotEqual(Version.revision, u'')
self.assertEqual(Version.string(), "0.11.0") self.assertEqual(Version.string(), "0.13.1")
def test_wrapper_version(self): def test_wrapper_version(self):
self.assertEqual(WrapperVersion.major, 2) self.assertEqual(WrapperVersion.major, 3)
self.assertEqual(WrapperVersion.minor, 0) self.assertEqual(WrapperVersion.minor, 1)
self.assertEqual(WrapperVersion.patch, 0) self.assertEqual(WrapperVersion.patch, 0)
self.assertNotEqual(WrapperVersion.revision, u'') self.assertNotEqual(WrapperVersion.revision, u'')
self.assertNotEqual(WrapperVersion.revision, Version.revision) self.assertNotEqual(WrapperVersion.revision, Version.revision)
self.assertEqual(WrapperVersion.string(), "2.0.0") self.assertEqual(WrapperVersion.string(), "3.1.0")
def test_create_db(self): def test_create_db(self):
db = create_database(GameType.tes4, self.game_path, self.local_path) game = create_game_handle(GameType.tes4, self.game_path, self.local_path)
db = game.get_database()
self.assertNotEqual(db, None) self.assertNotEqual(db, None)
class TestDatabaseInterface(GameFixture): class TestDatabaseInterface(GameFixture):
@@ -65,7 +68,10 @@ class TestDatabaseInterface(GameFixture):
def setUp(self): def setUp(self):
super(TestDatabaseInterface, self).setUp() super(TestDatabaseInterface, self).setUp()
self.db = create_database(GameType.tes4, self.game_path, self.local_path) game = create_game_handle(GameType.tes4, self.game_path, self.local_path)
game.load_current_load_order_state()
self.db = game.get_database()
def test_load_lists(self): def test_load_lists(self):
self.db.load_lists(self.masterlist_path, u'') self.db.load_lists(self.masterlist_path, u'')
+2 -2
View File
@@ -25,8 +25,8 @@
#include "wrapper_version.h" #include "wrapper_version.h"
namespace loot { namespace loot {
const unsigned int WrapperVersion::major = 2; const unsigned int WrapperVersion::major = 3;
const unsigned int WrapperVersion::minor = 0; const unsigned int WrapperVersion::minor = 1;
const unsigned int WrapperVersion::patch = 0; const unsigned int WrapperVersion::patch = 0;
const std::string WrapperVersion::revision = "@GIT_COMMIT_STRING@"; const std::string WrapperVersion::revision = "@GIT_COMMIT_STRING@";