Skip to content

Commit 31e6824

Browse files
committed
IMPROVEMENT: Refractor program settings methods out of backend_filesystem.py
1 parent 24c4079 commit 31e6824

File tree

2 files changed

+221
-192
lines changed

2 files changed

+221
-192
lines changed

MethodicConfigurator/backend_filesystem.py

Lines changed: 4 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,26 @@
1111
from os import path as os_path
1212
from os import getcwd as os_getcwd
1313
from os import listdir as os_listdir
14-
from os import makedirs as os_makedirs
1514
from os import rename as os_rename
1615
from os import walk as os_walk
17-
from os import sep as os_sep
1816

1917
from shutil import copy2 as shutil_copy2
2018
from shutil import copytree as shutil_copytree
2119

2220
from re import compile as re_compile
23-
from re import match as re_match
24-
from re import escape as re_escape
25-
from re import sub as re_sub
2621

2722
# from sys import exit as sys_exit
2823
from logging import debug as logging_debug
2924
from logging import info as logging_info
3025
from logging import warning as logging_warning
3126
from logging import error as logging_error
3227

33-
from json import load as json_load
34-
from json import dump as json_dump
35-
36-
from platform import system as platform_system
37-
3828
from typing import Dict
3929
from typing import List
4030
from typing import Tuple
4131

4232
from zipfile import ZipFile
4333

44-
from platformdirs import site_config_dir
45-
from platformdirs import user_config_dir
46-
4734
from MethodicConfigurator.annotate_params import BASE_URL, PARAM_DEFINITION_XML_FILE, Par
4835
from MethodicConfigurator.annotate_params import get_xml_data
4936
from MethodicConfigurator.annotate_params import create_doc_dict
@@ -53,6 +40,7 @@
5340

5441
from MethodicConfigurator.backend_filesystem_vehicle_components import VehicleComponents
5542
from MethodicConfigurator.backend_filesystem_configuration_steps import ConfigurationSteps
43+
from MethodicConfigurator.backend_filesystem_program_settings import ProgramSettings
5644

5745
from MethodicConfigurator.middleware_template_overview import TemplateOverview
5846

@@ -79,7 +67,7 @@ def is_within_tolerance(x: float, y: float, atol: float = 1e-08, rtol: float = 1
7967
return abs(x - y) <= atol + (rtol * abs(y))
8068

8169

82-
class LocalFilesystem(VehicleComponents, ConfigurationSteps): # pylint: disable=too-many-public-methods
70+
class LocalFilesystem(VehicleComponents, ConfigurationSteps, ProgramSettings): # pylint: disable=too-many-public-methods
8371
"""
8472
A class to manage local filesystem operations for the ArduPilot methodic configurator.
8573
@@ -98,6 +86,7 @@ def __init__(self, vehicle_dir: str, vehicle_type: str, fw_version: str, allow_e
9886
self.file_parameters = None
9987
VehicleComponents.__init__(self)
10088
ConfigurationSteps.__init__(self, vehicle_dir, vehicle_type)
89+
ProgramSettings.__init__(self)
10190
self.fw_version = fw_version
10291
self.allow_editing_template_files = allow_editing_template_files
10392
if vehicle_dir is not None:
@@ -394,16 +383,6 @@ def zip_files(self, files_to_zip: List[Tuple[bool, str]]):
394383

395384
logging_info("Intermediate parameter files and summary files zipped to %s", zip_file_path)
396385

397-
@staticmethod
398-
def application_icon_filepath():
399-
script_dir = os_path.dirname(os_path.abspath(__file__))
400-
return os_path.join(script_dir, 'ArduPilot_icon.png')
401-
402-
@staticmethod
403-
def application_logo_filepath():
404-
script_dir = os_path.dirname(os_path.abspath(__file__))
405-
return os_path.join(script_dir, 'ArduPilot_logo.png')
406-
407386
def vehicle_image_filepath(self):
408387
return os_path.join(self.vehicle_dir, 'vehicle.jpg')
409388

@@ -418,19 +397,6 @@ def new_vehicle_dir(base_dir: str, new_dir: str):
418397
def directory_exists(directory: str) -> bool:
419398
return os_path.exists(directory)
420399

421-
def create_new_vehicle_dir(self, new_vehicle_dir: str):
422-
# Check if the new vehicle directory already exists
423-
if os_path.exists(new_vehicle_dir):
424-
return "Directory already exists, choose a different one"
425-
426-
try:
427-
# Create the new vehicle directory
428-
os_makedirs(new_vehicle_dir, exist_ok=True)
429-
except OSError as e:
430-
logging_error("Error creating new vehicle directory: %s", e)
431-
return str(e)
432-
return ""
433-
434400
def copy_template_files_to_new_vehicle_dir(self, template_dir: str, new_vehicle_dir: str):
435401
# Copy the template files to the new vehicle directory
436402
for item in os_listdir(template_dir):
@@ -445,26 +411,6 @@ def copy_template_files_to_new_vehicle_dir(self, template_dir: str, new_vehicle_
445411
def getcwd():
446412
return os_getcwd()
447413

448-
@staticmethod
449-
def valid_directory_name(dir_name: str):
450-
"""
451-
Check if a given directory name contains only alphanumeric characters, underscores, hyphens,
452-
and the OS directory separator.
453-
454-
This function is designed to ensure that the directory name does not contain characters that are
455-
invalid for directory names in many operating systems. It does not guarantee that the name
456-
is valid in all contexts or operating systems, as directory name validity can vary.
457-
458-
Parameters:
459-
- dir_name (str): The directory name to check.
460-
461-
Returns:
462-
- bool: True if the directory name matches the allowed pattern, False otherwise.
463-
"""
464-
# Include os.sep in the pattern
465-
pattern = r'^[\w' + re_escape(os_sep) + '-]+$'
466-
return re_match(pattern, dir_name) is not None
467-
468414
def tempcal_imu_result_param_tuple(self):
469415
tempcal_imu_result_param_filename = "03_imu_temperature_calibration_results.param"
470416
return [tempcal_imu_result_param_filename, os_path.join(self.vehicle_dir, tempcal_imu_result_param_filename)]
@@ -480,139 +426,6 @@ def copy_fc_values_to_file(self, selected_file: str, params: Dict[str, float]):
480426
logging_warning("Parameter %s not found in the current parameter file", param)
481427
return ret
482428

483-
@staticmethod
484-
def __user_config_dir():
485-
user_config_directory = user_config_dir(".ardupilot_methodic_configurator", False, roaming=True, ensure_exists=True)
486-
487-
if not os_path.exists(user_config_directory):
488-
raise FileNotFoundError(f"The user configuration directory '{user_config_directory}' does not exist.")
489-
if not os_path.isdir(user_config_directory):
490-
raise NotADirectoryError(f"The path '{user_config_directory}' is not a directory.")
491-
492-
return user_config_directory
493-
494-
@staticmethod
495-
def __site_config_dir():
496-
site_config_directory = site_config_dir(".ardupilot_methodic_configurator", False, version=None, multipath=False,
497-
ensure_exists=True)
498-
499-
if not os_path.exists(site_config_directory):
500-
raise FileNotFoundError(f"The site configuration directory '{site_config_directory}' does not exist.")
501-
if not os_path.isdir(site_config_directory):
502-
raise NotADirectoryError(f"The path '{site_config_directory}' is not a directory.")
503-
504-
return site_config_directory
505-
506-
@staticmethod
507-
def __get_settings_as_dict():
508-
settings_path = os_path.join(LocalFilesystem.__user_config_dir(), "settings.json")
509-
510-
settings = {}
511-
512-
try:
513-
with open(settings_path, "r", encoding='utf-8') as settings_file:
514-
settings = json_load(settings_file)
515-
except FileNotFoundError:
516-
# If the file does not exist, it will be created later
517-
pass
518-
519-
if "Format version" not in settings:
520-
settings["Format version"] = 1
521-
522-
if "directory_selection" not in settings:
523-
settings["directory_selection"] = {}
524-
return settings
525-
526-
@staticmethod
527-
def __set_settings_from_dict(settings):
528-
settings_path = os_path.join(LocalFilesystem.__user_config_dir(), "settings.json")
529-
530-
with open(settings_path, "w", encoding='utf-8') as settings_file:
531-
json_dump(settings, settings_file, indent=4)
532-
533-
@staticmethod
534-
def __get_settings_config():
535-
settings = LocalFilesystem.__get_settings_as_dict()
536-
537-
# Regular expression pattern to match single backslashes
538-
pattern = r"(?<!\\)\\(?!\\)|(?<!/)/(?!/)"
539-
540-
# Replacement string
541-
if platform_system() == 'Windows':
542-
replacement = r"\\"
543-
else:
544-
replacement = r"/"
545-
return settings, pattern, replacement
546-
547-
@staticmethod
548-
def store_recently_used_template_dirs(template_dir: str, new_base_dir: str):
549-
settings, pattern, replacement = LocalFilesystem.__get_settings_config()
550-
551-
# Update the settings with the new values
552-
settings["directory_selection"].update({
553-
"template_dir": re_sub(pattern, replacement, template_dir),
554-
"new_base_dir": re_sub(pattern, replacement, new_base_dir)
555-
})
556-
557-
LocalFilesystem.__set_settings_from_dict(settings)
558-
559-
@staticmethod
560-
def store_template_dir(relative_template_dir: str):
561-
settings, pattern, replacement = LocalFilesystem.__get_settings_config()
562-
563-
template_dir = os_path.join(LocalFilesystem.get_templates_base_dir(), relative_template_dir)
564-
565-
# Update the settings with the new values
566-
settings["directory_selection"].update({
567-
"template_dir": re_sub(pattern, replacement, template_dir)
568-
})
569-
570-
LocalFilesystem.__set_settings_from_dict(settings)
571-
572-
@staticmethod
573-
def store_recently_used_vehicle_dir(vehicle_dir: str):
574-
settings, pattern, replacement = LocalFilesystem.__get_settings_config()
575-
576-
# Update the settings with the new values
577-
settings["directory_selection"].update({
578-
"vehicle_dir": re_sub(pattern, replacement, vehicle_dir)
579-
})
580-
581-
LocalFilesystem.__set_settings_from_dict(settings)
582-
583-
584-
@staticmethod
585-
def get_templates_base_dir():
586-
current_dir = os_path.dirname(os_path.abspath(__file__))
587-
if platform_system() == 'Windows':
588-
current_dir = current_dir.replace("\\_internal", "")
589-
elif "site-packages" not in current_dir:
590-
current_dir = current_dir.replace("/MethodicConfigurator", "")
591-
program_dir = current_dir
592-
593-
if platform_system() == 'Windows':
594-
site_directory = LocalFilesystem.__site_config_dir()
595-
else:
596-
site_directory = program_dir
597-
return os_path.join(site_directory, "vehicle_templates")
598-
599-
@staticmethod
600-
def get_recently_used_dirs():
601-
template_default_dir = os_path.join(LocalFilesystem.get_templates_base_dir(),
602-
"ArduCopter", "diatone_taycan_mxc", "4.5.3-params")
603-
604-
settings_directory = LocalFilesystem.__user_config_dir()
605-
vehicles_default_dir = os_path.join(settings_directory, "vehicles")
606-
if not os_path.exists(vehicles_default_dir):
607-
os_makedirs(vehicles_default_dir, exist_ok=True)
608-
609-
settings = LocalFilesystem.__get_settings_as_dict()
610-
template_dir = settings["directory_selection"].get("template_dir", template_default_dir)
611-
new_base_dir = settings["directory_selection"].get("new_base_dir", vehicles_default_dir)
612-
vehicle_dir = settings["directory_selection"].get("vehicle_dir", vehicles_default_dir)
613-
614-
return template_dir, new_base_dir, vehicle_dir
615-
616429
def write_last_uploaded_filename(self, current_file: str):
617430
try:
618431
with open(os_path.join(self.vehicle_dir, 'last_uploaded_filename.txt'), 'w', encoding='utf-8') as file:
@@ -679,7 +492,6 @@ def get_eval_variables(self):
679492

680493
def copy_fc_params_values_to_template_created_vehicle_files(self, fc_parameters: Dict[str, 'Par']):
681494
eval_variables = self.get_eval_variables()
682-
eval_variables['fc_parameters'] = fc_parameters
683495
for param_filename, param_dict in self.file_parameters.items():
684496
for param_name, param in param_dict.items():
685497
if param_name in fc_parameters:
@@ -712,7 +524,7 @@ def get_vehicle_components_overviews():
712524
"""
713525
vehicle_components_dict = {}
714526
file_to_find = VehicleComponents().vehicle_components_json_filename
715-
template_default_dir = LocalFilesystem.get_templates_base_dir()
527+
template_default_dir = ProgramSettings.get_templates_base_dir()
716528
for root, _dirs, files in os_walk(template_default_dir):
717529
if file_to_find in files:
718530
relative_path = os_path.relpath(root, template_default_dir)

0 commit comments

Comments
 (0)