Skip to content

Commit

Permalink
Jobs: make downloaded and installed profiles listing more generic (#336)
Browse files Browse the repository at this point in the history
  • Loading branch information
Guts authored Nov 14, 2023
2 parents aa7cd61 + 6ed1cff commit 6c1b939
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 83 deletions.
4 changes: 2 additions & 2 deletions docs/jobs/profiles_manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ Sample job configurations.
### Profiles states
- `remote`: a profile stored outside the end-user computer, on a git repository, an HTTP server or a LAN drive. Typically: `https://gitlab.com/Oslandia/qgis/profils_qgis_fr_2022.git`.
- `downloaded`: a profile downloaded into teh QDT local working folder. Typically: `~/.cache/qgis-deployment-toolbelt/Oslandia/`.
- `installed`: a profile installed into the QGIS and so accessible to the end-user through the QGIS interface. Typically: `/home/jmo/.local/share/QGIS/QGIS3/profiles/geotribu`
- `downloaded`: a profile downloaded into the QDT local working folder. Typically: `~/.cache/qgis-deployment-toolbelt/Oslandia/`.
- `installed`: a profile's folder located into the QGIS profiles folder and so accessible to the end-user through the QGIS interface. Typically: `~/.local/share/QGIS/QGIS3/profiles/default` or `%APPDATA%/QGIS/QGIS3/profiles/default`

----

Expand Down
62 changes: 54 additions & 8 deletions qgis_deployment_toolbelt/jobs/generic_job.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#! python3 # noqa: E265

"""
Base of job.
Base of QDT jobs.
Author: Julien Moura (https://github.com/guts)
"""
Expand All @@ -15,8 +15,10 @@
import logging
from configparser import ConfigParser
from pathlib import Path
from sys import platform as opersys

# package
from qgis_deployment_toolbelt.constants import OS_CONFIG, get_qdt_working_directory
from qgis_deployment_toolbelt.exceptions import (
JobOptionBadName,
JobOptionBadValue,
Expand All @@ -39,28 +41,72 @@
class GenericJob:
"""Generic base for QDT jobs."""

ID = ""
OPTIONS_SCHEMA = dict[dict]
ID: str = ""
OPTIONS_SCHEMA: dict[dict] = dict(dict())

def __init__(self) -> None:
"""Object instanciation."""
# local QDT folder
self.qdt_working_folder = get_qdt_working_directory()
if not self.qdt_working_folder.exists():
logger.info(
f"QDT downloaded folder not found: {self.qdt_working_folder}. "
"Creating it to properly run the job."
)
self.qdt_working_folder.mkdir(parents=True, exist_ok=True)
logger.debug(f"Working folder: {self.qdt_working_folder}")

# destination profiles folder
self.qgis_profiles_path: Path = Path(OS_CONFIG.get(opersys).profiles_path)
if not self.qgis_profiles_path.exists():
logger.info(
f"Installed QGIS profiles folder not found: {self.qgis_profiles_path}. "
"Creating it to properly run the job."
)
self.qgis_profiles_path.mkdir(parents=True)
logger.debug(f"Installed QGIS profiles folder: {self.qgis_profiles_path}")

def list_downloaded_profiles(self) -> tuple[QdtProfile]:
"""List downloaded QGIS profiles, i.e. a profile's folder located into the QDT
working folder.
Typically: `~/.cache/qgis-deployment-toolbelt/geotribu` or
`%USERPROFILE%/.cache/qgis-deployment-toolbelt/geotribu`).
Returns:
tuple[QdtProfile]: tuple of profiles objects
"""
return self.filter_profiles_folder(start_parent_folder=self.qdt_working_folder)

def list_installed_profiles(self) -> tuple[QdtProfile]:
"""List installed QGIS profiles, i.e. a profile's folder located into the QGIS
profiles path and so accessible to the end-user through the QGIS interface.
Typically: `~/.local/share/QGIS/QGIS3/profiles/geotribu` or
`%APPDATA%/QGIS/QGIS3/profiles/geotribu`).
Returns:
tuple[QdtProfile]: tuple of profiles objects
"""
return self.filter_profiles_folder(start_parent_folder=self.qgis_profiles_path)

def filter_profiles_folder(self) -> tuple[QdtProfile]:
"""Parse downloaded folder to filter on QGIS profiles folders.
def filter_profiles_folder(self, start_parent_folder: Path) -> tuple[QdtProfile]:
"""Parse a folder structure to filter on QGIS profiles folders.
Returns:
tuple[QdtProfile]: tuple of profiles objects
"""
# first, try to get folders containing a profile.json
qgis_profiles_folder = [
QdtProfile.from_json(profile_json_path=f, profile_folder=f.parent)
for f in self.qdt_working_folder.glob("**/profile.json")
for f in start_parent_folder.glob("**/profile.json")
]
if len(qgis_profiles_folder):
logger.debug(
f"{len(qgis_profiles_folder)} profiles found within {self.qdt_working_folder}"
f"{len(qgis_profiles_folder)} profiles found within {start_parent_folder}"
)
return tuple(qgis_profiles_folder)

# if empty, try to identify if a folder is a QGIS profile - but unsure
for d in self.qdt_working_folder.glob("**"):
for d in start_parent_folder.glob("**"):
if (
d.is_dir()
and d.parent.name == "profiles"
Expand Down
1 change: 1 addition & 0 deletions qgis_deployment_toolbelt/jobs/job_environment_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def __init__(self, options: list[dict]) -> None:
options (List[dict]): list of dictionary with environment variables to set
or remove.
"""
super().__init__()
self.options: list[dict] = [self.validate_options(opt) for opt in options]

def run(self) -> None:
Expand Down
16 changes: 1 addition & 15 deletions qgis_deployment_toolbelt/jobs/job_plugins_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from shutil import copy2
from sys import platform as opersys

# package
from qgis_deployment_toolbelt.__about__ import __title_clean__
from qgis_deployment_toolbelt.constants import OS_CONFIG, get_qdt_working_directory
from qgis_deployment_toolbelt.jobs.generic_job import GenericJob
from qgis_deployment_toolbelt.plugins.plugin import QgisPlugin
from qgis_deployment_toolbelt.profiles.qdt_profile import QdtProfile
Expand Down Expand Up @@ -68,26 +66,14 @@ def __init__(self, options: dict) -> None:
:param dict options: job options.
"""
super().__init__()
self.options: dict = self.validate_options(options)

# local QDT folder
self.qdt_working_folder = get_qdt_working_directory()
logger.debug(f"Working folder: {self.qdt_working_folder}")

# where QDT downloads plugins
self.qdt_plugins_folder = self.qdt_working_folder.parent / "plugins"
self.qdt_plugins_folder.mkdir(exist_ok=True, parents=True)
logger.info(f"QDT plugins folder: {self.qdt_plugins_folder}")

# destination profiles folder
self.qgis_profiles_path: Path = Path(OS_CONFIG.get(opersys).profiles_path)
if not self.qgis_profiles_path.exists():
logger.warning(
f"QGIS profiles folder not found: {self.qgis_profiles_path}. "
"Creating it to properly run the job."
)
self.qgis_profiles_path.mkdir(parents=True)

def run(self) -> None:
"""Execute job logic."""
# list plugins through different profiles
Expand Down
15 changes: 1 addition & 14 deletions qgis_deployment_toolbelt/jobs/job_plugins_synchronizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
import logging
from pathlib import Path
from shutil import unpack_archive
from sys import platform as opersys

# package
from qgis_deployment_toolbelt.constants import OS_CONFIG, get_qdt_working_directory
from qgis_deployment_toolbelt.jobs.generic_job import GenericJob
from qgis_deployment_toolbelt.plugins.plugin import QgisPlugin
from qgis_deployment_toolbelt.profiles.qdt_profile import QdtProfile
Expand Down Expand Up @@ -71,25 +69,14 @@ def __init__(self, options: dict) -> None:
:param dict options: job options.
"""
super().__init__()
self.options: dict = self.validate_options(options)

# local QDT folder
self.qdt_working_folder = get_qdt_working_directory()
logger.debug(f"Working folder: {self.qdt_working_folder}")

# where QDT downloads plugins
self.qdt_plugins_folder = self.qdt_working_folder.parent / "plugins"
self.qdt_plugins_folder.mkdir(exist_ok=True, parents=True)
logger.info(f"QDT plugins folder: {self.qdt_plugins_folder}")

# destination profiles folder
self.qgis_profiles_path: Path = Path(OS_CONFIG.get(opersys).profiles_path)
if not self.qgis_profiles_path.exists():
logger.warning(
f"QGIS profiles folder not found: {self.qgis_profiles_path}. "
"Creating it to properly run the job."
)
self.qgis_profiles_path.mkdir(parents=True)
logger.debug(
"Using plugins listed into profile.json files found into profiles "
f"already installed under the QGIS3 user data: {self.qgis_profiles_path.resolve()}"
Expand Down
29 changes: 2 additions & 27 deletions qgis_deployment_toolbelt/jobs/job_profiles_synchronizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
from collections.abc import Iterable
from pathlib import Path
from shutil import copy2, copytree
from sys import platform as opersys

# package
from qgis_deployment_toolbelt.constants import OS_CONFIG, get_qdt_working_directory
from qgis_deployment_toolbelt.jobs.generic_job import GenericJob
from qgis_deployment_toolbelt.profiles import LocalGitHandler, RemoteGitHandler
from qgis_deployment_toolbelt.profiles.qdt_profile import QdtProfile
Expand Down Expand Up @@ -102,32 +100,9 @@ def __init__(self, options: dict) -> None:
options (List[dict]): list of dictionary with environment variables to set
or remove.
"""
super().__init__()
self.options: dict = self.validate_options(options)

# local QDT folder
self.qdt_working_folder = get_qdt_working_directory()
logger.debug(f"Working folder: {self.qdt_working_folder}")

# profile folder
self.qgis_profiles_path: Path = Path(OS_CONFIG.get(opersys).profiles_path)
if not self.qgis_profiles_path.exists():
logger.warning(
f"QGIS profiles folder not found: {self.qgis_profiles_path}. "
"Creating it to properly run the job."
)
self.qgis_profiles_path.mkdir(exist_ok=True, parents=True)

# list installed profiles
self.PROFILES_NAMES_INSTALLED = [
d.name
for d in self.qgis_profiles_path.iterdir()
if d.is_dir() and not d.name.startswith(".")
]

# prepare local destination
if not self.qdt_working_folder.exists():
self.qdt_working_folder.mkdir(parents=True, exist_ok=True)

def run(self) -> None:
"""Execute job logic."""
# download or refresh
Expand Down Expand Up @@ -157,7 +132,7 @@ def run(self) -> None:
raise NotImplementedError

# check of there are some profiles folders within the downloaded folder
profiles_folders = self.filter_profiles_folder()
profiles_folders = self.list_downloaded_profiles()
if profiles_folders is None:
logger.error("No QGIS profile found in the downloaded folder.")
return
Expand Down
7 changes: 3 additions & 4 deletions qgis_deployment_toolbelt/jobs/job_shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

# package
from qgis_deployment_toolbelt.__about__ import __title__, __version__
from qgis_deployment_toolbelt.constants import OS_CONFIG, get_qdt_working_directory
from qgis_deployment_toolbelt.constants import OS_CONFIG
from qgis_deployment_toolbelt.jobs.generic_job import GenericJob
from qgis_deployment_toolbelt.profiles.qdt_profile import QdtProfile
from qgis_deployment_toolbelt.shortcuts import ApplicationShortcut
Expand Down Expand Up @@ -111,17 +111,16 @@ def __init__(self, options: dict) -> None:
:param dict options: profiles source (remote, can be a local network) and
destination (local).
"""
super().__init__()
self.options: dict = self.validate_options(options)

# profile folder
self.os_config = OS_CONFIG.get(opersys)
self.qdt_working_folder = get_qdt_working_directory()
self.qgis_profiles_path: Path = Path(self.os_config.profiles_path)

def run(self) -> None:
"""Execute job logic."""
# check of there are some profiles folders within the downloaded folder
downloaded_profiles = self.filter_profiles_folder()
downloaded_profiles = self.list_downloaded_profiles()
if downloaded_profiles is None:
logger.error("No QGIS profile found in the downloaded folder.")
return
Expand Down
15 changes: 2 additions & 13 deletions qgis_deployment_toolbelt/jobs/job_splash_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
import logging
from configparser import ConfigParser
from pathlib import Path
from sys import platform as opersys

# package
from qgis_deployment_toolbelt.constants import OS_CONFIG, get_qdt_working_directory
from qgis_deployment_toolbelt.exceptions import SplashScreenBadDimensions
from qgis_deployment_toolbelt.jobs.generic_job import GenericJob
from qgis_deployment_toolbelt.profiles.qdt_profile import QdtProfile
Expand Down Expand Up @@ -69,22 +67,13 @@ def __init__(self, options: dict) -> None:
Args:
options (dict): dictionary of options.
"""
super().__init__()
self.options: dict = self.validate_options(options)

# profile folder
self.qdt_working_folder = get_qdt_working_directory()
self.qgis_profiles_path: Path = Path(OS_CONFIG.get(opersys).profiles_path)
if not self.qgis_profiles_path.exists():
logger.warning(
f"QGIS profiles folder not found: {self.qgis_profiles_path}. "
"Creating it to properly run the job."
)
self.qgis_profiles_path.mkdir(parents=True)

def run(self) -> None:
"""Execute job logic."""
# check of there are some profiles folders within the downloaded folder
downloaded_profiles = self.filter_profiles_folder()
downloaded_profiles = self.list_downloaded_profiles()
if downloaded_profiles is None:
logger.error("No QGIS profile found in the downloaded folder.")
return
Expand Down

0 comments on commit 6c1b939

Please sign in to comment.