Pamhyr2/src/config.py

387 lines
11 KiB
Python

# config.py -- Pamhyr configuration manager
# Copyright (C) 2023-2024 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import os
import pickle
import logging
from platformdirs import user_cache_dir
from SQL import SQL
from Model.Stricklers.Stricklers import Stricklers
from Model.Stricklers.StricklersList import StricklersList
from Solver.Solvers import solver_type_list
config_dir = user_cache_dir("pamhyr")
config_file = "config.sqlite3"
logger = logging.getLogger()
class Config(SQL):
def __init__(self):
self._version = '0.0.4'
self.filename = Config.filename()
self.set_default_value()
logging.info(f"Configuration file : {self.filename}")
super(Config, self).__init__(filename=self.filename)
def _create(self):
# Info (meta data)
self.execute(
"CREATE TABLE info(key TEXT NOT NULL UNIQUE, value TEXT NOT NULL)")
self.execute(f"INSERT INTO info VALUES ('version', '{self._version}')")
# Key / Value (data)
self.execute(
"CREATE TABLE data(key TEXT NOT NULL UNIQUE, value TEXT NOT NULL)")
# Solver
self.execute("""
CREATE TABLE solver(
type TEXT NOT NULL,
name TEXT NOT NULL UNIQUE,
description TEXT NOT NULL,
path_input TEXT NOT NULL,
path_solver TEXT NOT NULL,
path_output TEXT NOT NULL,
cmd_input TEXT NOT NULL,
cmd_solver TEXT NOT NULL,
cmd_output TEXT NOT NULL
)
""")
# Stricklers
self.execute("""
CREATE TABLE stricklers(
name TEXT NOT NULL UNIQUE,
comment TEXT NOT NULL,
minor REAL NOT NULL,
medium REAL NOT NULL
)
""")
self.commit()
def _update(self):
version = self.execute(
f"SELECT value FROM info WHERE key='version'")[0]
if version != self._version:
logger.info(
"Configuration file update from " +
f"{version} to {self._version}..."
)
major, minor, release = version.strip().split(".")
if major == minor == "0":
if int(release) < 2:
# Add default solver
posix = os.name == 'posix'
ext = "" if posix else ".exe"
self.execute(f"""
INSERT INTO solver VALUES (
'mage8',
'default-mage',
'Default Pamhyr2 mage 8 version',
'', '', '',
'',
'@install_dir/mage/mage{ext} @args @input',
''
)
""")
if int(release) < 3:
self.execute(
"INSERT OR IGNORE INTO data " +
"VALUES ('last_study', '')"
)
self.execute(
"INSERT OR IGNORE INTO data " +
"VALUES ('close_correctly', 'True')"
)
if int(release) < 4:
self.execute(
"INSERT OR IGNORE INTO data " +
"VALUES ('last_solver_name', '')"
)
self.execute(
f"UPDATE info SET value='{self._version}' " +
"WHERE key='version'"
)
self.commit()
def _load_solver(self):
self._solvers = []
solvers = self.execute(
"SELECT * FROM solver",
fetch_one=False
)
for solver in solvers:
solver_type = solver[0]
ctor = solver_type_list[solver_type]
new = ctor(solver[1])
new._description = solver[2]
new._path_input = solver[3]
new._path_solver = solver[4]
new._path_output = solver[5]
new._cmd_input = solver[6]
new._cmd_solver = solver[7]
new._cmd_output = solver[8]
self._solvers.append(new)
def _load_stricklers(self):
self.stricklers = StricklersList()
id = 0
stricklers = self.execute(
"SELECT * FROM stricklers",
fetch_one=False
)
for strickler in stricklers:
new = Stricklers()
new._name = strickler[0]
new._comment = strickler[1]
new._minor = float(strickler[2])
new._medium = float(strickler[3])
self.stricklers.insert(id, new)
id += 1
def _load(self):
# Backup
v = self.execute("SELECT value FROM data WHERE key='backup_enable'")
self.backup_enable = v[0] == "True"
# v = self.execute("SELECT value FROM data WHERE key='backup_path'")
# self.backup_path = v[0]
v = self.execute("SELECT value FROM data WHERE key='backup_frequence'")
self.backup_frequence = v[0]
# v = self.execute("SELECT value FROM data WHERE key='backup_max'")
# self.backup_max = int(v[0])
# Editor
v = self.execute("SELECT value FROM data WHERE key='editor'")
self.editor = v[0]
# Languages
v = self.execute("SELECT value FROM data WHERE key='lang'")
self.lang = v[0]
# Last study
v = self.execute("SELECT value FROM data WHERE key='last_study'")
self.last_study = v[0]
v = self.execute("SELECT value FROM data WHERE key='close_correctly'")
self.close_correctly = v[0] == "True"
# Last Solver
v = self.execute("SELECT value FROM data WHERE key='last_solver_name'")
self.last_solver_name = v[0]
# Debug
v = self.execute("SELECT value FROM data WHERE key='debug'")
self.debug = v[0] == "True"
self._load_solver()
self._load_stricklers()
def _save_solver(self):
self.execute(f"DELETE FROM solver")
for solver in self.solvers:
self.execute(f"""
INSERT INTO solver VALUES (
'{solver._type}',
'{self._db_format(solver._name)}',
'{self._db_format(solver._description)}',
'{self._db_format(solver._path_input)}',
'{self._db_format(solver._path_solver)}',
'{self._db_format(solver._path_output)}',
'{self._db_format(solver._cmd_input)}',
'{self._db_format(solver._cmd_solver)}',
'{self._db_format(solver._cmd_output)}'
)
""",
commit=True)
def _save_stricklers(self):
self.execute(f"DELETE FROM stricklers")
for stricklers in self.stricklers.stricklers:
self.execute(f"""
INSERT INTO stricklers VALUES (
'{self._db_format(stricklers._name)}',
'{self._db_format(stricklers._comment)}',
'{stricklers._minor}',
'{stricklers._medium}'
)
""")
self.commit()
def _save(self):
data = {
"backup_enable": self.backup_enable,
# "backup_path": self.backup_path,
"backup_frequence": self.backup_frequence,
# "backup_max": self.backup_max,
"editor": self.editor,
"lang": self.lang,
"last_study": self.last_study,
"close_correctly": self.close_correctly,
"debug": self.debug,
"last_solver_name": self.last_solver_name,
}
for key in data:
self.execute(
f"INSERT OR IGNORE INTO data VALUES " +
f" ('{key}', '{self._db_format(data[key])}')"
)
self.execute(
f"UPDATE data SET " +
f"value='{self._db_format(data[key])}' " +
f"WHERE key='{key}'"
)
self.commit()
self._save_solver()
self._save_stricklers()
def set_default_value(self):
# Solvers
self._solvers = []
posix = os.name == 'posix'
ext = "" if posix else ".exe"
ctor = solver_type_list["mage8"]
new = ctor("default-mage")
new._description = "Default Pamhyr2 mage 8 version"
new._cmd_solver = f""""@install_dir/mage8/mage{ext}" @args @input"""
self._solvers.append(new)
# Backup
self.backup_enable = True
# self.backup_path = ""
self.backup_frequence = "00:05:00"
# self.backup_max = 10
# Editor
self.editor = "editor @file"
# Languages
self.lang = ""
# Stricklers
self.stricklers = StricklersList()
# Last study
self.last_study = ""
self.close_correctly = False
# Last Solver
self.last_solver_name = ""
# Debug
self.debug = False
def set_close_correctly(self):
self.close_correctly = True
self.execute(
f"UPDATE data SET value='True' WHERE key='close_correctly'")
self.commit()
def set_last_study(self, filename):
if filename is None:
return
self.last_study = filename
self.close_correctly = False
self.execute(
"UPDATE data SET " +
f"value='{self._db_format(self.last_study)}' " +
"WHERE key='last_study'"
)
self.execute(
f"UPDATE data SET value='{self.close_correctly}' " +
"WHERE key='close_correctly'"
)
self.commit()
def update_last_solver_used(self, solver_name):
self.last_solver_name = solver_name
self.execute(
"UPDATE data SET " +
f"value='{self._db_format(self.last_solver_name)}' " +
"WHERE key='last_solver_name'"
)
@classmethod
def filename(cls):
file = ""
if os.name == 'posix':
ndir = config_dir
else:
ndir = config_dir
ndir = ndir.replace("/", "\\")
os.makedirs(ndir, exist_ok=True)
file = os.path.join(ndir, config_file)
return file
@classmethod
def languages(cls):
return {
"System": "",
"English": "en",
"French": "fr",
}
@property
def solvers(self):
return self._solvers.copy()
@solvers.setter
def solvers(self, solvers):
self._solvers = solvers
def save(self):
self._save()
@classmethod
def load(cls):
return cls()