Commit 06d878a9 authored by Roman Alifanov's avatar Roman Alifanov

init `file` backend

parent c3784816
......@@ -159,3 +159,59 @@
gtype: boolean
backend: gsettings
key: org.gnome.desktop.interface.enable-animations
- name: "ThemeSwitcher"
weight: 25
sections:
- name: Themes
type: classic
weight: 0
settings:
- name: KV Light Theme
type: entry
gtype: string
backend: file
key: KV_LIGHT_THEME
help: Select the Kvantum light theme
default: KvLibadwaita
params:
file_path: "~/.config/ximper-unified-theme-switcher/themes"
- name: KV Dark Theme
type: entry
gtype: string
backend: file
key: KV_DARK_THEME
help: Select the Kvantum dark theme
default: KvLibadwaitaDark
params:
file_path: "~/.config/ximper-unified-theme-switcher/themes"
- name: GTK3 Light Theme
type: entry
gtype: string
backend: file
key: GTK3_LIGHT_THEME
help: Select the GTK3 light theme
default: adw-gtk3
params:
file_path: "~/.config/ximper-unified-theme-switcher/themes"
- name: GTK3 Dark Theme
type: entry
gtype: string
backend: file
key: GTK3_DARK_THEME
help: Select the GTK3 dark theme
default: adw-gtk3-dark
params:
file_path: "~/.config/ximper-unified-theme-switcher/themes"
- name: Current Theme
type: choice
gtype: string
backend: file
key: CURRENT_THEME
help: Define the current theme preference
default: "prefer-dark"
map:
Prefer Dark: prefer-dark
Prefer Light: prefer-light
Default: default
params:
file_path: "~/.config/ximper-unified-theme-switcher/themes"
......@@ -8,9 +8,10 @@ from .widgets import WidgetFactory
class Setting:
def __init__(self, setting_data):
self.name = setting_data['name']
self.backend = setting_data.get('backend')
self.params = setting_data.get('params', {})
self.type = setting_data['type']
self.help = setting_data.get('help', "")
self.backend = setting_data.get('backend')
self.key = setting_data.get('key')
self.default = setting_data.get('default')
self.gtype = setting_data.get('gtype', [])
......@@ -80,7 +81,8 @@ class Setting:
backend.set_value(self.key, value, self.gtype)
def _get_backend(self):
backend = backend_factory.get_backend(self.backend)
backend = backend_factory.get_backend(self.backend, self.params)
if not backend:
print(f"Бекенд {self.backend} не зарегистрирован.")
return backend
......
from gi.repository import Gio, GLib
import json
import yaml
import os
from configparser import ConfigParser
class Backend:
def __init__(self, params=None):
# Параметры, передаваемые при инициализации
self.params = params or {}
def get_value(self, key, gtype):
raise NotImplementedError("Метод get_value должен быть реализован")
......@@ -46,15 +55,161 @@ class GSettingsBackend(Backend):
except Exception as e:
print(f"[ERROR] Ошибка при установке значения {schema_key}: {e}")
class FileBackend(Backend):
def __init__(self, params=None):
super().__init__(params)
self.file_path = os.path.expanduser(self.params.get('file_path'))
self.encoding = self.params.get('encoding', 'utf-8')
self.file_type = self._get_file_type()
def _get_file_type(self):
_, ext = os.path.splitext(self.file_path)
ext = ext.lower()
if ext == '.json':
return 'json'
elif ext == '.yaml' or ext == '.yml':
return 'yaml'
elif ext == '.ini':
return 'ini'
elif ext == '.sh' or ext == '.conf':
return 'text'
else:
return 'text'
def _read_file(self):
try:
with open(self.file_path, 'r', encoding=self.encoding) as file:
if self.file_type == 'json':
return json.load(file)
elif self.file_type == 'yaml':
return yaml.safe_load(file)
elif self.file_type == 'ini':
config = ConfigParser()
config.read_file(file)
return config
elif self.file_type == 'text':
return self._parse_text_config(file)
else:
raise ValueError(f"Unsupported file type: {self.file_type}")
except Exception as e:
print(f"[ERROR] Ошибка при чтении файла {self.file_path}: {e}")
return None
def _write_file(self, data):
try:
with open(self.file_path, 'w', encoding=self.encoding) as file:
if self.file_type == 'json':
json.dump(data, file, indent=4)
elif self.file_type == 'yaml':
yaml.dump(data, file, default_flow_style=False)
elif self.file_type == 'ini':
config = ConfigParser()
for section, values in data.items():
config[section] = values
config.write(file)
elif self.file_type == 'text':
self._write_text_config(file, data)
else:
raise ValueError(f"Unsupported file type: {self.file_type}")
except Exception as e:
print(f"[ERROR] Ошибка при записи в файл {self.file_path}: {e}")
def _parse_text_config(self, file):
config = {}
for line in file:
line = line.strip()
if not line or line.startswith('#'):
continue
if '=' in line:
key, value = line.split('=', 1)
config[key.strip()] = value.strip()
return config
def _write_text_config(self, file, data):
existing_lines = []
with open(self.file_path, 'r', encoding=self.encoding) as file_read:
existing_lines = file_read.readlines()
existing_style = self._detect_text_style(existing_lines)
for key, value in data.items():
if existing_style == 'space_around':
file.write(f"{key} = {value}\n")
elif existing_style == 'no_space':
file.write(f"{key}={value}\n")
else:
file.write(f"{key} = {value}\n")
def _detect_text_style(self, lines):
style = None
for line in lines:
line = line.strip()
if '=' in line:
if line.startswith(' ') and line.endswith(' '):
style = 'space_around'
break
elif line.find('=') == len(line.split('=')[0]):
style = 'no_space'
break
return style or 'space_around'
def get_value(self, key, gtype):
data = self._read_file()
if data is None:
return None
if self.file_type == 'json' or self.file_type == 'yaml':
return data.get(key, None)
elif self.file_type == 'ini':
section, key_name = key.split('.', 1)
if section in data:
return data[section].get(key_name, None)
elif self.file_type == 'text':
return data.get(key, None)
return None
def get_range(self, key, gtype):
data = self._read_file()
if data is None:
return None
if self.file_type == 'json' or self.file_type == 'yaml':
if isinstance(data.get(key), list):
return (min(data[key]), max(data[key]))
elif self.file_type == 'ini':
pass
return None
def set_value(self, key, value, gtype):
data = self._read_file()
if data is None:
return
if self.file_type == 'json' or self.file_type == 'yaml':
data[key] = value
elif self.file_type == 'ini':
section, key_name = key.split('.', 1)
if section not in data:
data[section] = {}
data[section][key_name] = value
elif self.file_type == 'text':
data[key] = value
self._write_file(data)
class BackendFactory:
def __init__(self):
self.backends = {
'gsettings': GSettingsBackend(),
'gsettings': GSettingsBackend,
'file': FileBackend,
}
def get_backend(self, name):
return self.backends.get(name)
def get_backend(self, backend_name, params=None):
backend_class = self.backends.get(backend_name)
if backend_class:
# Передаем параметры в конструктор бэкенда, если они есть
return backend_class(params) if params else backend_class()
return None
backend_factory = BackendFactory()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment