File: compile_yaml.py

package info (click to toggle)
game-data-packager 73
  • links: PTS, VCS
  • area: contrib
  • in suites: bookworm
  • size: 23,420 kB
  • sloc: python: 11,086; sh: 609; makefile: 59
file content (138 lines) | stat: -rwxr-xr-x 5,098 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/python3
# encoding=utf-8
#
# Copyright © 2015 Simon McVittie <smcv@debian.org>
# SPDX-License-Identifier: GPL-2.0-or-later

import json
import os
import sys

from game_data_packager.util import load_yaml

srcdir = os.path.dirname(
    os.path.dirname(
        os.path.abspath(__file__)
    )
)

def main(f, out):
    data = load_yaml(open(f, encoding='utf-8'))
    game = os.path.basename(f)[5:].split('.')[0]

    with open(
        os.path.join(srcdir, 'data', 'wikipedia.csv'),
        'r', encoding='utf8',
    ) as csv:
        for line in csv.readlines():
            shortname, url = line.strip().split(';', 1)
            if shortname == game:
                data['wikipedia'] = url
                break

    v = data.pop('files', None)
    offload = os.path.splitext(out)[0] + '.files'
    if v is not None:
        json.dump(v, open(offload + '.tmp', 'w', encoding='utf-8'), sort_keys=True)
        os.rename(offload + '.tmp', offload)
    elif os.path.isfile(offload):
        os.remove(offload)

    groups = data.pop('groups', None)
    offload = os.path.splitext(out)[0] + '.groups'

    if groups is not None:
        with open(offload + '.tmp', 'w', encoding='utf-8') as writer:
            writer.write('# Generated file, do not edit.\n')
            writer.write(
                '# Edit %s.yaml and put it next to vfs.zip instead.\n' %
                os.path.basename(game)
            )

            assert isinstance(groups, dict)
            # The group data starts with a list of groups. This is necessary
            # so we can know whether a group member, encountered later on in
            # the data, is a group or a file.
            for group_name, group_data in sorted(groups.items()):
                if isinstance(group_data, dict):
                    if group_data.get('ignorable'):
                        continue

                writer.write('*%s\n' % group_name)

            for group_name, group_data in sorted(groups.items()):
                if isinstance(group_data, dict):
                    if group_data.get('ignorable'):
                        continue

                    writer.write('[%s]\n' % group_name)
                    attrs = {}
                    members = group_data['group_members']
                    for k, v in group_data.items():
                        if k != 'group_members':
                            attrs[k] = v
                    if attrs:
                        json.dump(attrs, writer, sort_keys=True)
                        writer.write('\n')
                elif isinstance(group_data, (str, list)):
                    writer.write('[%s]\n' % group_name)
                    members = group_data
                else:
                    raise AssertionError('group %r should be dict, str or list' % group_name)

                has_members = False

                if isinstance(members, str):
                    for line in members.splitlines():
                        assert not line.startswith('[')
                        assert not line.startswith('{')
                        line = line.strip()
                        if (line and
                                not line.startswith('#') and
                                not line.startswith('.')):
                            has_members = True
                            writer.write(' '.join(line.split()))
                            writer.write('\n')
                elif isinstance(members, list):
                    for m in members:
                        has_members = True
                        writer.write('? ? %s\n' % m)
                else:
                    raise AssertionError('group %r members should be str or list' % group_name)

                # an empty group is no use, and would break the assumption
                # that we can use f.group_members to detect groups
                assert has_members

        os.rename(offload + '.tmp', offload)
    elif os.path.isfile(offload):
        os.remove(offload)

    for k in ('sha1sums', 'sha256sums', 'size_and_md5'):
        v = data.pop(k, None)
        offload = os.path.splitext(out)[0] + '.' + k

        if v is not None:
            with open(offload + '.tmp', 'w', encoding='utf-8') as writer:
                writer.write('# Generated file, do not edit.\n')
                writer.write(
                    '# Edit %s.yaml and put it next to vfs.zip instead.\n' %
                    game)

                for line in v.splitlines():
                    stripped = line.strip()
                    if (stripped == '' or
                            stripped.startswith('#') or
                            stripped.startswith('.')):
                        continue
                    writer.write(line)
                    writer.write('\n')
            os.rename(offload + '.tmp', offload)
        elif os.path.isfile(offload):
            os.remove(offload)

    json.dump(data, open(out + '.tmp', 'w', encoding='utf-8'), sort_keys=True)
    os.rename(out + '.tmp', out)

if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2])