mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-07 01:15:33 +00:00
This fixes the uninstallation of shared keyboards if the `additional-keyboards` settings doesn't exist yet. Closes #9879.
99 lines
3.6 KiB
Python
99 lines
3.6 KiB
Python
#!/usr/bin/python3
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
from gi.repository import Gio # needs to come before gi.overrides.GLib!
|
|
from gi.overrides.GLib import Variant
|
|
|
|
class GSettings():
|
|
def __init__(self, schema_id):
|
|
"""
|
|
Wrapper around Gio Settings that deals with running under sudo
|
|
"""
|
|
self.schema_id = schema_id
|
|
if os.environ.get('SUDO_USER'):
|
|
self.is_sudo = True
|
|
logging.debug('Running with sudo. Real user: %s', os.environ.get('SUDO_USER'))
|
|
else:
|
|
self.schema = Gio.Settings.new(self.schema_id)
|
|
self.is_sudo = False
|
|
logging.debug('Running as regular user')
|
|
|
|
def _convert_variant_to_array(self, variant):
|
|
if variant is None:
|
|
return []
|
|
|
|
if variant.get_type_string() == 'as':
|
|
return variant.get_strv()
|
|
|
|
assert variant.get_type_string() == 'a(ss)'
|
|
|
|
values = []
|
|
# Process variant of type "a(ss)" (array of tuples with two strings)
|
|
nChildren = variant.n_children()
|
|
for i in range(nChildren):
|
|
# Process variant of type "(ss)" (tuple with two strings)
|
|
val = variant.get_child_value(i)
|
|
typeVariant = val.get_child_value(0)
|
|
idVariant = val.get_child_value(1)
|
|
values.append((typeVariant.get_string(), idVariant.get_string()))
|
|
return values
|
|
|
|
def _convert_array_to_variant(self, array, type):
|
|
if len(array) == 0:
|
|
return Variant(type, None)
|
|
|
|
if type == 'as':
|
|
return Variant('as', array)
|
|
|
|
assert type == 'a(ss)'
|
|
|
|
children = []
|
|
for (type, id) in array:
|
|
typeVariant = Variant.new_string(type)
|
|
idVariant = Variant.new_string(id)
|
|
child = Variant.new_tuple(typeVariant, idVariant)
|
|
children.append(child)
|
|
return Variant.new_array(None, children)
|
|
|
|
def get(self, key):
|
|
if self.is_sudo:
|
|
args = ['sudo', '-H', '-u', os.environ.get('SUDO_USER'),
|
|
f"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/{os.environ.get('SUDO_UID')}/bus",
|
|
'gsettings', 'get', self.schema_id, key]
|
|
if sys.version_info.major <= 3 and sys.version_info.minor < 7:
|
|
# capture_output got added in Python 3.7
|
|
try:
|
|
output = subprocess.check_output(args)
|
|
value = eval(output)
|
|
except subprocess.CalledProcessError:
|
|
value = None
|
|
logging.warning('Could not convert to sources')
|
|
else:
|
|
process = subprocess.run(args, capture_output=True)
|
|
if process.returncode == 0:
|
|
output = process.stdout
|
|
if output.decode('utf-8').startswith('['):
|
|
value = eval(output)
|
|
return value
|
|
|
|
logging.debug('Could not convert to sources')
|
|
return None
|
|
else:
|
|
variant = self.schema.get_value(key)
|
|
value = self._convert_variant_to_array(variant)
|
|
return value
|
|
|
|
def set(self, key, value, type) -> None:
|
|
if self.is_sudo:
|
|
variant = str(value)
|
|
subprocess.run(
|
|
['sudo', '-H', '-u', os.environ.get('SUDO_USER'),
|
|
f"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/{os.environ.get('SUDO_UID')}/bus",
|
|
'gsettings', 'set', self.schema_id, key, variant])
|
|
else:
|
|
variant = self._convert_array_to_variant(value, type)
|
|
self.schema.set_value(key, variant)
|
|
self.schema.sync()
|