Insert Python dictionary into another dictionary, to generate .plist file?

409 views Asked by At

I'm trying to generate a .plist file with plistlib library, available in macOS Python 2.7.

The following code works:

#!/usr/bin/env python

from plistlib import writePlist

patches = [
    {
        'Arch': 'x86_64',
        'Base': 'early'
    },
    {
        'Arch': 'x86_64',
        'Base': 'late'
    }
]

result = [
    {
        'Arch': 'x86_64',
        'BundlePath': 'Alpha.kext'
    },
    {
        'Arch': 'x86_64',
        'BundlePath': 'Beta.kext'
    }
]
for i in patches:
    result.append(dict(i))

settings = {
    'Kernel': {
        'Add': result
    }
}
writePlist(settings, 'config.plist')

And produces a config.plist file with the content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Kernel</key>
    <dict>
        <key>Add</key>
        <array>
            <dict>
                <key>Arch</key>
                <string>x86_64</string>
                <key>BundlePath</key>
                <string>Alpha.kext</string>
            </dict>
            <dict>
                <key>Arch</key>
                <string>x86_64</string>
                <key>BundlePath</key>
                <string>Beta.kext</string>
            </dict>
            <dict>
                <key>Arch</key>
                <string>x86_64</string>
                <key>Base</key>
                <string>early</string>
            </dict>
            <dict>
                <key>Arch</key>
                <string>x86_64</string>
                <key>Base</key>
                <string>late</string>
            </dict>
        </array>
    </dict>
</dict>
</plist>

However, my config.plist requires to have the patches dictionaries inside another dictionary:

            <dict>
                <dict>
                    <key>Arch</key>
                    <string>x86_64</string>
                    <key>Base</key>
                    <string>early</string>

The correct config file must look like (see lines 21 and 22 in an editor):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Kernel</key>
    <dict>
        <key>Add</key>
        <array>
            <dict>
                <key>Arch</key>
                <string>x86_64</string>
                <key>BundlePath</key>
                <string>Alpha.kext</string>
            </dict>
            <dict>
                <key>Arch</key>
                <string>x86_64</string>
                <key>BundlePath</key>
                <string>Beta.kext</string>
            </dict>
            <dict>
                <dict>
                    <key>Arch</key>
                    <string>x86_64</string>
                    <key>Base</key>
                    <string>early</string>
                </dict>
                <dict>
                    <key>Arch</key>
                    <string>x86_64</string>
                    <key>Base</key>
                    <string>late</string>
                </dict>
            </dict>
        </array>
    </dict>
</dict>
</plist>

How can I edit my setup.py file to produce the proper dictionary inside dictionary output? In case you wander why I split the code, is because this is a very simplified format, the actual code quite more complex. Therefore, I need a solution within the above code design. Thank you for your help.

1

There are 1 answers

0
ogdenkev On BEST ANSWER

The desired output does not look correct. Your "dictionary of dictionary" does not have a key with it. I suspect it should be something like

<dict>
    <key>Patches</key>
    <array>
        <dict>
            <key>Arch</key>
            ...
        </dict>
        <dict>
            <key>Arch</key>
            ...
        </dict>
    </array>
</dict>

If so, here is how you could do that, using the key of "Patches".

patches = [
    {
        'Arch': 'x86_64',
        'Base': 'early'
    },
    {
        'Arch': 'x86_64',
        'Base': 'late'
    }
]

result = [
    {
        'Arch': 'x86_64',
        'BundlePath': 'Alpha.kext'
    },
    {
        'Arch': 'x86_64',
        'BundlePath': 'Beta.kext'
    }
]
result.append({"Patches": patches})

settings = {
    'Kernel': {
        'Add': result
    }
}
writePlist(settings, 'config.plist')

Output

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Kernel</key>
        <dict>
                <key>Add</key>
                <array>
                        <dict>
                                <key>Arch</key>
                                <string>x86_64</string>
                                <key>BundlePath</key>
                                <string>Alpha.kext</string>
                        </dict>
                        <dict>
                                <key>Arch</key>
                                <string>x86_64</string>
                                <key>BundlePath</key>
                                <string>Beta.kext</string>
                        </dict>
                        <dict>
                                <key>Patches</key>
                                <array>
                                        <dict>
                                                <key>Arch</key>
                                                <string>x86_64</string>
                                                <key>Base</key>
                                                <string>early</string>
                                        </dict>
                                        <dict>
                                                <key>Arch</key>
                                                <string>x86_64</string>
                                                <key>Base</key>
                                                <string>late</string>
                                        </dict>
                                </array>
                        </dict>
                </array>
        </dict>
</dict>
</plist>