1#!/usr/local/bin/python3.8
2
3from gi.repository import GLib
4import xml.dom.minidom
5
6import os, sys
7sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8
9from caribou.settings import caribou_settings
10
11class SchemasMaker:
12    def __init__(self, settings, domain):
13        self.settings = settings
14        self.domain = domain
15
16    def create_schemas(self, output):
17        doc = xml.dom.minidom.Document()
18        schemafile =  doc.createElement('schemalist')
19        schema = doc.createElement('schema')
20        schema.setAttribute("id", self.settings.schema_id)
21        schema.setAttribute("gettext-domain", self.domain)
22        schemafile.appendChild(schema)
23        self._create_schema(self.settings, doc, schema)
24
25        fp = open(output, 'w')
26        self._pretty_xml(fp, schemafile)
27        fp.close()
28
29    def _attribs(self, e):
30        if not list(e.attributes.items()):
31            return ""
32        return ' ' + ' '.join(['%s="%s"' % (k, v) \
33                                   for k, v in list(e.attributes.items())])
34
35    def _pretty_xml(self, fp, e, indent=0):
36        if not e.childNodes or \
37                (len(e.childNodes) == 1 and \
38                     e.firstChild.nodeType == e.TEXT_NODE):
39            fp.write('%s%s\n' % (' '*indent*2, e.toxml().strip()))
40        else:
41            fp.write('%s<%s%s>\n' % (' '*indent*2, e.tagName, self._attribs(e)))
42            for c in e.childNodes:
43                self._pretty_xml(fp, c, indent + 1)
44            fp.write('%s</%s>\n' % (' '*indent*2, e.tagName))
45
46    def _append_children_element_value_pairs(self, doc, element, pairs):
47        for e, t in pairs:
48            el = doc.createElement(e)
49            te = doc.createTextNode(str(t))
50            el.appendChild(te)
51            element.appendChild(el)
52
53    def _create_schema(self, setting, doc, schemalist):
54        if hasattr(setting, 'path'):
55            schemalist.setAttribute("path", setting.path)
56        if hasattr(setting, 'gsettings_key'):
57            key = doc.createElement('key')
58            key.setAttribute('name', setting.gsettings_key)
59            key.setAttribute('type', setting.variant_type)
60            schemalist.appendChild(key)
61            # pygobject >= 3.3.3 and up expose g_variant_print as
62            # "print_". Older pygobjects expose it as "print", which
63            # we need to use through getattr as "print" is a keyword.
64            #
65            # Try the new name first, fall back to the old one if unavailable.
66            #
67            # Once we depend on pygobject >= 3.4 we can just call
68            # setting.gvariant.print_(False) directly.
69            printfunc = getattr(setting.gvariant, 'print_', None)
70            if printfunc is None:
71                printfunc = getattr(setting.gvariant, 'print')
72            self._append_children_element_value_pairs(
73                doc, key, [('default', printfunc(False)),
74                           ('_summary', setting.short_desc),
75                           ('_description', setting.long_desc)])
76
77        for s in setting:
78            self._create_schema(s, doc, schemalist)
79
80if __name__ == "__main__":
81    from caribou.settings import AllSettings
82    from locale import setlocale, LC_ALL
83    import argparse
84
85    parser = argparse.ArgumentParser(description='make_schema')
86
87    parser.add_argument('settings_object', type=str,
88                        help='Settings object')
89    parser.add_argument('-o', '--output', type=str, required=True,
90                        help='Output file name')
91    parser.add_argument('-d', '--domain', type=str, default='caribou',
92                        help='Translation domain')
93
94    args = parser.parse_args()
95
96    # prevent _summary and _description from being translated
97    setlocale(LC_ALL, "C")
98
99    modulename, settings_obj = args.settings_object.rsplit('.', 1)
100
101    module = __import__(modulename, locals(), globals(), [settings_obj])
102    settings = getattr(module, settings_obj)
103
104    maker = SchemasMaker(settings, args.domain)
105    maker.create_schemas(args.output)
106