mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-16 03:55:41 +00:00
Use plugins dir when installing from plugins.txt
This commit is contained in:
@ -65,6 +65,29 @@ def handle_pip_error(error, path: str) -> list:
|
|||||||
raise ValidationError(errors[0])
|
raise ValidationError(errors[0])
|
||||||
|
|
||||||
|
|
||||||
|
def check_plugins_path(packagename: str) -> bool:
|
||||||
|
"""Determine if the package is installed in the plugins directory."""
|
||||||
|
# Remove version information
|
||||||
|
for c in '<>=! ':
|
||||||
|
packagename = packagename.split(c)[0]
|
||||||
|
|
||||||
|
plugin_dir = get_plugin_dir()
|
||||||
|
|
||||||
|
if not plugin_dir:
|
||||||
|
return False
|
||||||
|
|
||||||
|
plugin_dir_path = pathlib.Path(plugin_dir)
|
||||||
|
|
||||||
|
if not plugin_dir_path.exists():
|
||||||
|
return False
|
||||||
|
|
||||||
|
result = pip_command('freeze', '--path', plugin_dir_path.absolute())
|
||||||
|
output = result.decode('utf-8').split('\n')
|
||||||
|
|
||||||
|
# Check if the package is installed in the plugins directory
|
||||||
|
return any(re.match(f'^{packagename}==', line.strip()) for line in output)
|
||||||
|
|
||||||
|
|
||||||
def check_package_path(packagename: str):
|
def check_package_path(packagename: str):
|
||||||
"""Determine the install path of a particular package.
|
"""Determine the install path of a particular package.
|
||||||
|
|
||||||
@ -100,6 +123,31 @@ def check_package_path(packagename: str):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def plugins_dir():
|
||||||
|
"""Return the path to the InvenTree custom plugins director.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
pathlib.Path: Path to the custom plugins directory
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValidationError: If the plugins directory is not specified, or does not exist
|
||||||
|
"""
|
||||||
|
pd = get_plugin_dir()
|
||||||
|
|
||||||
|
if not pd:
|
||||||
|
raise ValidationError(_('Plugins directory not specified'))
|
||||||
|
|
||||||
|
pd = pathlib.Path(pd)
|
||||||
|
|
||||||
|
if not pd.exists():
|
||||||
|
try:
|
||||||
|
pd.mkdir(parents=True, exist_ok=True)
|
||||||
|
except Exception:
|
||||||
|
raise ValidationError(_('Failed to create plugin directory'))
|
||||||
|
|
||||||
|
return pd.absolute()
|
||||||
|
|
||||||
|
|
||||||
def install_plugins_file():
|
def install_plugins_file():
|
||||||
"""Install plugins from the plugins file."""
|
"""Install plugins from the plugins file."""
|
||||||
logger.info('Installing plugins from plugins file')
|
logger.info('Installing plugins from plugins file')
|
||||||
@ -110,8 +158,12 @@ def install_plugins_file():
|
|||||||
logger.warning('Plugin file %s does not exist', str(pf))
|
logger.warning('Plugin file %s does not exist', str(pf))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
plugin_dir = plugins_dir()
|
||||||
|
|
||||||
|
cmd = ['install', '-U', '--target', str(plugin_dir), '-r', str(pf)]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pip_command('install', '-r', str(pf))
|
pip_command(*cmd)
|
||||||
except subprocess.CalledProcessError as error:
|
except subprocess.CalledProcessError as error:
|
||||||
output = error.output.decode('utf-8')
|
output = error.output.decode('utf-8')
|
||||||
logger.exception('Plugin file installation failed: %s', str(output))
|
logger.exception('Plugin file installation failed: %s', str(output))
|
||||||
@ -212,21 +264,10 @@ def install_plugin(url=None, packagename=None, user=None, version=None):
|
|||||||
if not in_venv:
|
if not in_venv:
|
||||||
logger.warning('InvenTree is not running in a virtual environment')
|
logger.warning('InvenTree is not running in a virtual environment')
|
||||||
|
|
||||||
plugin_dir = get_plugin_dir()
|
plugin_dir = plugins_dir()
|
||||||
|
|
||||||
if not plugin_dir:
|
|
||||||
raise ValidationError(_('Plugins directory not specified'))
|
|
||||||
|
|
||||||
plugin_dir_path = pathlib.Path(plugin_dir)
|
|
||||||
|
|
||||||
if not plugin_dir_path.exists():
|
|
||||||
try:
|
|
||||||
plugin_dir_path.mkdir(parents=True, exist_ok=True)
|
|
||||||
except Exception:
|
|
||||||
raise ValidationError(_('Failed to create plugin directory'))
|
|
||||||
|
|
||||||
# build up the command
|
# build up the command
|
||||||
install_name = ['install', '-U', '--target', plugin_dir_path.absolute()]
|
install_name = ['install', '-U', '--target', str(plugin_dir)]
|
||||||
|
|
||||||
full_pkg = ''
|
full_pkg = ''
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class PluginConfig(InvenTree.models.MetadataMixin, models.Model):
|
|||||||
"""Nice name for printing."""
|
"""Nice name for printing."""
|
||||||
name = f'{self.name} - {self.key}'
|
name = f'{self.name} - {self.key}'
|
||||||
if not self.active:
|
if not self.active:
|
||||||
name += '(not active)'
|
name += ' (not active)'
|
||||||
return name
|
return name
|
||||||
|
|
||||||
# extra attributes from the registry
|
# extra attributes from the registry
|
||||||
|
@ -365,31 +365,32 @@ class PluginsRegistry:
|
|||||||
collected_plugins = []
|
collected_plugins = []
|
||||||
|
|
||||||
# Collect plugins from paths
|
# Collect plugins from paths
|
||||||
for plugin in self.plugin_dirs():
|
for plugin_dir in self.plugin_dirs():
|
||||||
logger.debug("Loading plugins from directory '%s'", plugin)
|
logger.debug("Loading plugins from directory '%s'", plugin_dir)
|
||||||
|
|
||||||
parent_path = None
|
parent_path = None
|
||||||
parent_obj = Path(plugin)
|
parent_obj = Path(plugin_dir)
|
||||||
|
|
||||||
# If a "path" is provided, some special handling is required
|
# If a "path" is provided, some special handling is required
|
||||||
if parent_obj.name is not plugin and len(parent_obj.parts) > 1:
|
if parent_obj.name is not plugin_dir and len(parent_obj.parts) > 1:
|
||||||
# Ensure PosixPath object is converted to a string, before passing to get_plugins
|
# Ensure PosixPath object is converted to a string, before passing to get_plugins
|
||||||
parent_path = str(parent_obj.parent)
|
parent_path = str(parent_obj.parent)
|
||||||
plugin = parent_obj.name
|
plugin_dir = parent_obj.name
|
||||||
|
|
||||||
# Gather Modules
|
# Gather Modules
|
||||||
if parent_path:
|
if parent_path:
|
||||||
# On python 3.12 use new loader method
|
# On python 3.12 use new loader method
|
||||||
if sys.version_info < (3, 12):
|
if sys.version_info < (3, 12):
|
||||||
raw_module = _load_source(
|
raw_module = _load_source(
|
||||||
plugin, str(parent_obj.joinpath('__init__.py'))
|
plugin_dir, str(parent_obj.joinpath('__init__.py'))
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raw_module = SourceFileLoader(
|
raw_module = SourceFileLoader(
|
||||||
plugin, str(parent_obj.joinpath('__init__.py'))
|
plugin_dir, str(parent_obj.joinpath('__init__.py'))
|
||||||
).load_module()
|
).load_module()
|
||||||
else:
|
else:
|
||||||
raw_module = importlib.import_module(plugin)
|
raw_module = importlib.import_module(plugin_dir)
|
||||||
|
|
||||||
modules = get_plugins(raw_module, InvenTreePlugin, path=parent_path)
|
modules = get_plugins(raw_module, InvenTreePlugin, path=parent_path)
|
||||||
|
|
||||||
for item in modules or []:
|
for item in modules or []:
|
||||||
@ -404,11 +405,11 @@ class PluginsRegistry:
|
|||||||
# Collect plugins from setup entry points
|
# Collect plugins from setup entry points
|
||||||
for entry in get_entrypoints():
|
for entry in get_entrypoints():
|
||||||
try:
|
try:
|
||||||
plugin = entry.load()
|
plugin_dir = entry.load()
|
||||||
plugin.is_package = True
|
plugin_dir.is_package = True
|
||||||
plugin.package_name = getattr(entry.dist, 'name', None)
|
plugin_dir.package_name = getattr(entry.dist, 'name', None)
|
||||||
plugin._get_package_metadata()
|
plugin_dir._get_package_metadata()
|
||||||
collected_plugins.append(plugin)
|
collected_plugins.append(plugin_dir)
|
||||||
except Exception as error: # pragma: no cover
|
except Exception as error: # pragma: no cover
|
||||||
handle_error(error, do_raise=False, log_name='discovery')
|
handle_error(error, do_raise=False, log_name='discovery')
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user