Initial commit

Still to do:
* Tidy up the plugin file itself (i.e. remove development comments and logging)
* Make Umbrella-side changes (i.e. add a link to this repo as a build step)
* Add the translation file to the repo (it should be made the first time this is built with Umbrella)
This commit is contained in:
AnyOldName3
2019-12-07 14:31:00 +00:00
commit ed8d56a4eb
7 changed files with 1015 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
root = true
[*.py]
indent_style = space
indent_size = 4
+109
View File
@@ -0,0 +1,109 @@
# Mod Organizer Umbrella stuff
/msbuild.log
/*std*.log
/*build
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
+15
View File
@@ -0,0 +1,15 @@
# Version chosen arbitrarily
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
PROJECT(Form43PluginChecker LANGUAGES NONE)
# Value passed from modorganizer-umbrella
SET(DEPENDENCIES_DIR CACHE PATH "")
LIST(APPEND CMAKE_PREFIX_PATH ${QT_ROOT}/lib/cmake)
# Find Python
FILE(GLOB_RECURSE PYTHON_ROOT ${DEPENDENCIES_DIR}/pyconfig.h.in)
GET_FILENAME_COMPONENT(PYTHON_ROOT ${PYTHON_ROOT} DIRECTORY)
ADD_SUBDIRECTORY(src)
+674
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
# Version chosen arbitrarily
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
# maybe widgets too
FIND_PACKAGE(Qt5LinguistTools)
INCLUDE(PyQt5TranslationMacros.cmake)
PYQT5_CREATE_TRANSLATION(form43checker_translations_qm ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/Form43Checker_en.ts)
add_custom_target(translations ALL DEPENDS ${form43checker_translations_qm})
###############
## Installation
INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/Form43Checker.py
DESTINATION bin/plugins)
+108
View File
@@ -0,0 +1,108 @@
from pathlib import Path
import sys
from PyQt5.QtCore import QCoreApplication, qDebug
if "mobase" not in sys.modules:
import mock_mobase as mobase
class Form43Checker(mobase.IPluginDiagnose):
def __init__(self):
super(Form43Checker, self).__init__()
self.__organizer = None
def init(self, organizer):
self.__organizer = organizer
# Already gets queried whenever a new plugin is added, so that's nice.
#organizer.pluginList().onRefreshed(lambda : self._invalidate())
#organizer.pluginList().onRefreshed(lambda : qDebug("onRefreshed callback triggered"))
return True
def name(self):
return "Form 43 Plugin Checker"
def author(self):
return "AnyOldName3"
def description(self):
return self.__tr("Checks plugins (.ESM/.ESP files) to see if any are Form 43 (Skyrim LE).")
def version(self):
return mobase.VersionInfo(1, 0, 0, mobase.ReleaseType.prealpha)
def isActive(self):
return self.__organizer.managedGame().gameName() == "Skyrim Special Edition"
def settings(self):
return []
def activeProblems(self):
qDebug("Active problems called.")
if self.__scanPlugins():
return [0]
else:
return []
def shortDescription(self, key):
return self.__tr("Form 43 plugin detected")
def fullDescription(self, key):
pluginList = self.__listPlugins()
pluginList = [Path(absolutePath).name for absolutePath in pluginList]
pluginListString = "\n" + ("\n".join(pluginList))
return self.__tr("You have one or more Form 43 plugins. They are:{0}").format(pluginListString)
def hasGuidedFix(self, key):
return False
def startGuidedFix(self, key):
# Maybe we could use xEdit or something to resave the file?
pass
def __tr(self, str):
return QCoreApplication.translate("Form43Checker", str)
def __testFile(self, path):
path = Path(path)
if path.is_file():
with path.open(mode='rb') as file:
file.seek(20)
version = file.read(2)
return version == b"\x2b\x00"
else:
qDebug("I've been told to scan a plugin that doesn't exist.")
return None
def __scanPlugins(self):
if self.__organizer.managedGame().gameName() != "Skyrim Special Edition":
return False
def isPluginFile(name):
extension = Path(name).suffix
extension = extension.lower()
return extension == ".esp" or extension == ".esm"
fileList = self.__organizer.findFiles("", isPluginFile)
for file in fileList:
if self.__testFile(file):
return True
return False
def __listPlugins(self):
def isPluginFile(name):
extension = Path(name).suffix
extension = extension.lower()
return extension == ".esp" or extension == ".esm"
fileList = self.__organizer.findFiles("", isPluginFile)
return [file for file in fileList if self.__testFile(file)]
def createPlugin():
return Form43Checker()
+88
View File
@@ -0,0 +1,88 @@
# This is a modified version of Qt5LinguistToolsMacros.cmake which calls
# pylupdate5 instead of lupdate, allowing Python strings to be extracted,
# too. It still requires the Qt version of the file to be included, but
# only this version of the function needs to be called. You also need to
# have PYTHON_ROOT set to a directory where a working pylupdate5.bat can
# be found. If you aren't using Windows, your platform's equivalent may
# work, too.
#=============================================================================
# Copyright 2005-2011 Kitware, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of Kitware, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
include(CMakeParseArguments)
function(PYQT5_CREATE_TRANSLATION _qm_files)
set(options)
set(oneValueArgs)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(_LUPDATE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
set(_lupdate_files ${_LUPDATE_UNPARSED_ARGUMENTS})
set(_lupdate_options ${_LUPDATE_OPTIONS})
set(_my_sources)
set(_my_tsfiles)
foreach(_file ${_lupdate_files})
get_filename_component(_ext ${_file} EXT)
get_filename_component(_abs_FILE ${_file} ABSOLUTE)
if(_ext MATCHES "ts")
list(APPEND _my_tsfiles ${_abs_FILE})
else()
list(APPEND _my_sources ${_abs_FILE})
endif()
endforeach()
foreach(_ts_file ${_my_tsfiles})
set(_lst_file_srcs)
if(_my_sources)
# Qt made a file listing all sources and used that as an argument, but pylupdate5 doesn't support that.
# Qt allowed directories to be listed as sources, but pylupdate5 requires their contents to be listed.
get_filename_component(_ts_name ${_ts_file} NAME_WE)
set(_ts_lst_file "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lst_file")
foreach(_lst_file_src ${_my_sources})
if(IS_DIRECTORY ${_lst_file_src})
file(GLOB _directory_contents ${_lst_file_src}/*.py ${_lst_file_src}/*.ui)
list(APPEND _lst_file_srcs ${_directory_contents})
else()
list(APPEND _lst_file_srcs ${_lst_file_src})
endif()
endforeach()
endif()
add_custom_command(OUTPUT ${_ts_file}
COMMAND ${PYTHON_ROOT}/pylupdate5.bat
ARGS ${_lupdate_options} ${_lst_file_srcs} -ts ${_ts_file}
DEPENDS ${_lst_file_srcs} ${_ts_lst_file}
WORKING_DIRECTORY ${PYTHON_ROOT}
VERBATIM)
endforeach()
qt5_add_translation(${_qm_files} ${_my_tsfiles})
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
endfunction()