Create module for high-level xfconf ops

master
dece 4 years ago
parent cce38c94c6
commit 5310496238

@ -1,61 +1,74 @@
from ctypes import byref, cdll, c_char_p, c_void_p, POINTER import argparse
import json
class Xfconf: from xfconf import Xfconf
"""Xfconf library interface."""
def __init__(self, libxfconf="libxfconf-0.so.2", DEFAULT_FILE_PATH = "xion.json"
libglib="libglib-2.0.so.0"):
self.lib = cdll.LoadLibrary(libxfconf)
self.glib = cdll.LoadLibrary(libglib) def main():
self.set_foreign_functions() argparser = argparse.ArgumentParser()
argparser.add_argument("--xq-path", type=str,
def set_foreign_functions(self): help="Optional path to xion-query")
self._ff_init = self.lib.xfconf_init argparser.add_argument("-e", "--export", type=str, nargs=2,
self._ff_shutdown = self.lib.xfconf_shutdown metavar=("channel", "root"),
self._ff_list_channels = self.lib.xfconf_list_channels help="Channel and root to export")
self._ff_list_channels.restype = POINTER(c_void_p) argparser.add_argument("-f", "--file", type=str,
self._ff_channel_get = self.lib.xfconf_channel_get help="JSON file for import/export")
self._ff_channel_get.argtypes = (c_char_p,) args = argparser.parse_args()
self._ff_channel_get.restype = c_void_p
self._ff_channel_get_properties = self.lib.xfconf_channel_get_properties xion = Xion(xq=args.xq_path)
self._ff_channel_get_properties.argtypes = (c_void_p, c_char_p) if args.export:
self._ff_channel_get_properties.restype = c_void_p channel, root = args.export
tree = xion.build_tree(channel, root)
def init(self): if tree is None:
err = c_void_p() print("Failed to build config tree.")
if not self._ff_init(byref(err)): return
raise XfconfError("xfconf_init: error") if args.file:
output_path = args.file
def shutdown(self): else:
self._ff_shutdown() print(f"No output file, using {DEFAULT_FILE_PATH}.")
output_path = DEFAULT_FILE_PATH
def list_channels(self): xion.export_tree(tree, output_path)
channels = self._ff_list_channels()
i = 0
while channels[i] is not None: class Xion:
yield c_char_p(channels[i]).value.decode()
i += 1 def __init__(self, xq=None):
self.glib.g_strfreev(channels) self.xfconf = Xfconf(xq=xq)
def get_channel(self, name): def build_tree(self, channel, root="/"):
return self._ff_channel_get(name.encode()) """Return a dict of configs in this channel, filtering on root.
def list_properties(self, channel, base=None): Return None on error.
table = self._ff_channel_get_properties(channel, None) """
print(table) props = self.xfconf.get_property_list(channel, root=root)
self.glib.g_hash_table_destroy(table) if props is None:
print(f"Failed to get property list for channel {channel}.")
return None
tree = {}
class XfconfError(Exception): for prop_name in props:
pass prop = self.xfconf.get_property(channel, prop_name)
if prop is None:
print(f"Failed to get property {prop_name}.")
xfconf = Xfconf() return None
xfconf.init() if isinstance(prop, list):
for channel_name in xfconf.list_channels(): leaf = [Xion._build_prop_leaf(p) for p in prop]
print(channel_name) else:
channel = xfconf.get_channel("xfce4-keyboard-shortcuts") leaf = Xion._build_prop_leaf(prop)
xfconf.list_properties(channel) tree[prop_name] = leaf
xfconf.shutdown() return tree
def export_tree(self, tree, output_path):
"""Export a config tree as a sorted JSON file."""
with open(output_path, "wt") as output_file:
json.dump(tree, output_file, indent=2, sort_keys=True)
@staticmethod
def _build_prop_leaf(prop):
return {"type": prop.gtype, "value": str(prop.value)}
if __name__ == "__main__":
main()

Loading…
Cancel
Save