Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
tuneit
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ximper Linux
tuneit
Commits
bad3f058
Commit
bad3f058
authored
Feb 02, 2025
by
Anton Palgunov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into shop
parents
b6663d1d
06d878a9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
234 additions
and
12 deletions
+234
-12
exampleplug.yml
modules/exampleplug.yml
+56
-0
__init__.py
src/settings/__init__.py
+19
-8
backends.py
src/settings/backends.py
+159
-4
No files found.
modules/exampleplug.yml
View file @
bad3f058
...
...
@@ -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"
src/settings/__init__.py
View file @
bad3f058
...
...
@@ -8,18 +8,21 @@ 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'
)
if
len
(
setting_data
.
get
(
'gtype'
))
>
2
:
self
.
gtype
=
setting_data
.
get
(
'gtype'
)[
0
]
else
:
self
.
gtype
=
setting_data
.
get
(
'gtype'
)
self
.
gtype
=
setting_data
.
get
(
'gtype'
,
[])
self
.
map
=
setting_data
.
get
(
'map'
,
self
.
_default_map
())
self
.
data
=
setting_data
.
get
(
'data'
,
{})
if
len
(
self
.
gtype
)
>
2
:
self
.
gtype
=
self
.
gtype
[
0
]
else
:
self
.
gtype
=
self
.
gtype
def
_default_map
(
self
):
if
self
.
type
==
'boolean'
:
# Дефолтная карта для булевых настроек
...
...
@@ -27,7 +30,10 @@ class Setting:
if
self
.
type
==
'choice'
:
# Дефолтная карта для выборов
map
=
{}
range
=
self
.
_get_backend_range
()[
1
]
range
=
self
.
_get_backend_range
()
if
range
is
None
:
return
{}
for
var
in
range
:
print
(
var
)
...
...
@@ -35,7 +41,11 @@ class Setting:
return
map
if
self
.
type
==
'number'
:
map
=
{}
range
=
self
.
_get_backend_range
()[
1
]
range
=
self
.
_get_backend_range
()
if
range
is
None
:
return
{}
map
[
"upper"
]
=
range
[
1
]
map
[
"lower"
]
=
range
[
0
]
...
...
@@ -71,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
...
...
src/settings/backends.py
View file @
bad3f058
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 должен быть реализован"
)
...
...
@@ -31,7 +40,7 @@ class GSettingsBackend(Backend):
print
(
f
"[DEBUG] Получение значения: schema={schema_name}, key={key_name}, gtype={gtype}"
)
try
:
value
=
schema
.
get_range
(
key_name
)
return
value
.
unpack
()
return
value
.
unpack
()
[
1
]
except
Exception
as
e
:
print
(
f
"[ERROR] Ошибка при получении значения {key}: {e}"
)
return
None
...
...
@@ -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
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment