Skip to content

Commit

Permalink
feature: add profile's rules checks based on execution environment
Browse files Browse the repository at this point in the history
  • Loading branch information
Guts committed Apr 5, 2024
1 parent 998e757 commit 5ab62ad
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 2 deletions.
74 changes: 72 additions & 2 deletions qgis_deployment_toolbelt/jobs/job_profiles_synchronizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@
from pathlib import Path
from shutil import copy2, copytree

# 3rd party
from python_rule_engine import RuleEngine

# package
from qgis_deployment_toolbelt.jobs.generic_job import GenericJob
from qgis_deployment_toolbelt.profiles.qdt_profile import QdtProfile
from qgis_deployment_toolbelt.utils.computer_environment import environment_dict

# #############################################################################
# ########## Globals ###############
Expand Down Expand Up @@ -88,13 +92,79 @@ def run(self) -> None:
f"{', '.join(self.PROFILES_NAMES_DOWNLOADED)}"
)

# filter out profiles that do not match the rules
profiles_matched, profiles_unmatched = self.filter_profiles_on_rules(
li_downloaded_profiles=profiles_folders
)
if not len(profiles_matched):
logger.warning(
"None of the downloaded profiles meet the deployment requirements."
)
return

logger.info(
f"Of the {len(profiles_folders)} profiles downloaded, "
f"{len(profiles_unmatched)} do not meet the conditions for deployment."
)

# copy profiles to the QGIS 3
self.sync_installed_profiles_from_downloaded_profiles(
downloaded_profiles=profiles_folders
downloaded_profiles=profiles_matched
)

logger.debug(f"Job {self.ID} ran successfully.")

def filter_profiles_on_rules(
self, li_downloaded_profiles: Iterable[QdtProfile]
) -> tuple[list[QdtProfile], list[QdtProfile]]:
"""Evaluate profile regarding to its deployment rules.
Args:
li_downloaded_profiles (Iterable[QdtProfile]): input list of QDT profiles
Returns:
tuple[list[QdtProfile], list[QdtProfile]]: tuple of profiles that matched
and those which did not match their deployment rules
"""
li_profiles_matched = []
li_profiles_unmatched = []

context_object = {"environment": environment_dict()}
for profile in li_downloaded_profiles:
if profile.rules is None:
logger.debug(f"No rules to apply to {profile.name}")
li_profiles_matched.append(profile)
continue

logger.debug(
f"Checking that profile '{profile.name}' matches deployment conditions."
f"{len(profile.rules)} rules found."
)
try:
engine = RuleEngine(rules=profile.rules)
results = engine.evaluate(obj=context_object)
if len(results) == len(profile.rules):
logger.debug(
f"Profile '{profile.name}' matches {len(profile.rules)} "
"deployment rule(s)."
)
li_profiles_matched.append(profile)
else:
logger.info(
f"Profile '{profile.name}' does not match the deployment "
f"conditions: {len(results)}/{len(profile.rules)} rule(s) "
"matched."
)
li_profiles_unmatched.append(profile)

except Exception as err:
logger.error(
f"Error occurred parsing rules of profile '{profile.name}'. "
f"Trace: {err}"
)

return li_profiles_matched, li_profiles_unmatched

def compare_downloaded_with_installed_profiles(
self, li_downloaded_profiles: Iterable[QdtProfile]
) -> tuple[list[QdtProfile], list[QdtProfile], list[QdtProfile]]:
Expand Down Expand Up @@ -158,7 +228,7 @@ def compare_downloaded_with_installed_profiles(
return li_profiles_outdated, li_profiles_different, li_profiles_equal

def sync_installed_profiles_from_downloaded_profiles(
self, downloaded_profiles: tuple[QdtProfile]
self, downloaded_profiles: Iterable[QdtProfile]
) -> None:
"""Copy downloaded profiles to QGIS profiles folder. If the QGIS profiles folder
doesn't exist, it will be created and every downloaded profile will be
Expand Down
48 changes: 48 additions & 0 deletions qgis_deployment_toolbelt/utils/computer_environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#! python3 # noqa: E265

"""
Base of QDT jobs.
Author: Julien Moura (https://github.com/guts)
"""


# #############################################################################
# ########## Libraries #############
# ##################################

# Standard library
import logging
import platform
from sys import platform as opersys

# #############################################################################
# ########## Globals ###############
# ##################################

# logs
logger = logging.getLogger(__name__)


# #############################################################################
# ########## Functions #############
# ##################################


def environment_dict() -> dict:
"""Returns a dictionary containing some environment information (computer, network,
platform) that can be used in QDT various places: rules...
Returns:
dict: _description_
"""
return {
"computer_network_name": platform.node(),
"operating_system_code": opersys,
"processor_architecture": platform.machine(),
# custom Linux
"linux_distribution_name": f"{platform.freedesktop_os_release().get('NAME')}",
"linux_distribution_version": f"{platform.freedesktop_os_release().get('VERSION_ID')}",
# custom Windows
"windows_edition": platform.win32_edition(),
}

0 comments on commit 5ab62ad

Please sign in to comment.