Skip to content

Commit ca2dddc

Browse files
committed
PICARD-1861: Use pathlib.Path for plugins paths
1 parent 5705a5a commit ca2dddc

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

picard/plugin3/manager.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# Picard, the next-generation MusicBrainz tagger
44
#
5-
# Copyright (C) 2024 Philipp Wolfer
5+
# Copyright (C) 2024-2025 Philipp Wolfer
66
#
77
# This program is free software; you can redistribute it and/or
88
# modify it under the terms of the GNU General Public License
@@ -19,6 +19,7 @@
1919
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2020

2121
import os
22+
from pathlib import Path
2223
from typing import List
2324

2425
from picard import (
@@ -31,8 +32,8 @@
3132
class PluginManager:
3233
"""Installs, loads and updates plugins from multiple plugin directories."""
3334

34-
_primary_plugin_dir: str = None
35-
_plugin_dirs: List[str] = []
35+
_primary_plugin_dir: Path = None
36+
_plugin_dirs: List[Path] = []
3637
_plugins: List[Plugin] = []
3738

3839
def __init__(self, tagger):
@@ -42,9 +43,12 @@ def __init__(self, tagger):
4243

4344
def add_directory(self, dir_path: str, primary: bool = False) -> None:
4445
log.debug('Registering plugin directory %s', dir_path)
45-
dir_path = os.path.normpath(dir_path)
46+
dir_path = Path(os.path.normpath(dir_path))
4647

47-
for entry in os.scandir(dir_path):
48+
if not dir_path.exists():
49+
os.makedirs(dir_path)
50+
51+
for entry in dir_path.iterdir():
4852
if entry.is_dir():
4953
plugin = self._load_plugin(dir_path, entry.name)
5054
if plugin:
@@ -64,7 +68,7 @@ def init_plugins(self):
6468
except Exception as ex:
6569
log.error('Failed initializing plugin %s from %s', plugin.name, plugin.local_path, exc_info=ex)
6670

67-
def _load_plugin(self, plugin_dir: str, plugin_name: str):
71+
def _load_plugin(self, plugin_dir: Path, plugin_name: str):
6872
plugin = Plugin(plugin_dir, plugin_name)
6973
try:
7074
plugin.read_manifest()
@@ -79,7 +83,7 @@ def _load_plugin(self, plugin_dir: str, plugin_name: str):
7983
plugin.local_path,
8084
)
8185
except Exception as ex:
82-
log.warning('Could not read plugin manifest from %r', os.path.join(plugin_dir, plugin_name), exc_info=ex)
86+
log.warning('Could not read plugin manifest from %r', plugin_dir.joinpath(plugin_name), exc_info=ex)
8387
return None
8488

8589

picard/plugin3/plugin.py

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Picard, the next-generation MusicBrainz tagger
44
#
55
# Copyright (C) 2024 Laurent Monin
6-
# Copyright (C) 2024 Philipp Wolfer
6+
# Copyright (C) 2024-2025 Philipp Wolfer
77
#
88
# This program is free software; you can redistribute it and/or
99
# modify it under the terms of the GNU General Public License
@@ -20,7 +20,7 @@
2020
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2121

2222
import importlib.util
23-
import os
23+
from pathlib import Path
2424
import sys
2525

2626
from picard.plugin3.api import PluginApi
@@ -41,7 +41,7 @@ class PluginSourceSyncError(Exception):
4141
class PluginSource:
4242
"""Abstract class for plugin sources"""
4343

44-
def sync(self, target_directory: str):
44+
def sync(self, target_directory: Path):
4545
raise NotImplementedError
4646

4747

@@ -54,15 +54,15 @@ def __init__(self, url: str, ref: str = None):
5454
self.url = url
5555
self.ref = ref or 'main'
5656

57-
def sync(self, target_directory: str):
58-
if os.path.isdir(target_directory):
57+
def sync(self, target_directory: Path):
58+
if target_directory.is_dir():
5959
print(f'{target_directory} exists, fetch changes')
60-
repo = pygit2.Repository(target_directory)
60+
repo = pygit2.Repository(target_directory.absolute())
6161
for remote in repo.remotes:
6262
remote.fetch(callbacks=GitRemoteCallbacks())
6363
else:
6464
print(f'Cloning {self.url} to {target_directory}')
65-
repo = pygit2.clone_repository(self.url, target_directory, callbacks=GitRemoteCallbacks())
65+
repo = pygit2.clone_repository(self.url, target_directory.absolute(), callbacks=GitRemoteCallbacks())
6666
print(list(repo.references))
6767
print(list(repo.branches))
6868
print(list(repo.remotes))
@@ -81,27 +81,24 @@ def sync(self, target_directory: str):
8181
class PluginSourceLocal(PluginSource):
8282
"""Plugin is stored in a local directory, but is not a git repo"""
8383

84-
def sync(self, target_directory: str):
84+
def sync(self, target_directory: Path):
8585
# TODO: copy tree to plugin directory (?)
8686
pass
8787

8888

8989
class Plugin:
90-
local_path: str = None
90+
local_path: Path = None
9191
remote_url: str = None
9292
ref = None
9393
name: str = None
9494
module_name: str = None
9595
manifest: PluginManifest = None
9696
_module = None
9797

98-
def __init__(self, plugins_dir: str, plugin_name: str):
99-
if not os.path.exists(plugins_dir):
100-
os.makedirs(plugins_dir)
101-
self.plugins_dir = plugins_dir
98+
def __init__(self, plugins_dir: Path, plugin_name: str):
10299
self.name = plugin_name
103100
self.module_name = f'picard.plugins.{self.name}'
104-
self.local_path = os.path.join(self.plugins_dir, self.name)
101+
self.local_path = plugins_dir.joinpath(self.name)
105102

106103
def sync(self, plugin_source: PluginSource = None):
107104
"""Sync plugin source"""
@@ -113,13 +110,13 @@ def sync(self, plugin_source: PluginSource = None):
113110

114111
def read_manifest(self):
115112
"""Reads metadata for the plugin from the plugin's MANIFEST.toml"""
116-
manifest_path = os.path.join(self.local_path, 'MANIFEST.toml')
113+
manifest_path = self.local_path.joinpath('MANIFEST.toml')
117114
with open(manifest_path, 'rb') as manifest_file:
118115
self.manifest = PluginManifest(self.name, manifest_file)
119116

120117
def load_module(self):
121118
"""Load corresponding module from source path"""
122-
module_file = os.path.join(self.local_path, '__init__.py')
119+
module_file = self.local_path.joinpath('__init__.py')
123120
spec = importlib.util.spec_from_file_location(self.module_name, module_file)
124121
module = importlib.util.module_from_spec(spec)
125122
sys.modules[self.module_name] = module

0 commit comments

Comments
 (0)