File: scummvm_common.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 (169 lines) | stat: -rw-r--r-- 6,896 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/python3
# encoding=utf-8
#
# Copyright © 2015-2016 Simon McVittie <smcv@debian.org>
# Copyright © 2015-2016 Alexandre Detiste <alexandre@detiste.be>
# SPDX-License-Identifier: GPL-2.0-or-later

import configparser
import logging
import os
import subprocess

from ..build import (PackagingTask)
from ..game import (GameData)
from ..paths import DATADIR
from ..util import (mkdir_p)

logger = logging.getLogger(__name__)

def install_data(from_, to):
    subprocess.check_call(['cp', '--reflink=auto', from_, to])

class ScummvmGameData(GameData):
    def __init__(self, shortname, data):
        super(ScummvmGameData, self).__init__(shortname, data)

        self.wikibase = 'http://wiki.scummvm.org/index.php/'
        assert self.wiki

        if 'gameid' in self.data:
            self.gameid = self.data['gameid']
            assert self.gameid != shortname, 'extraneous gameid for ' + shortname
            self.aliases.add(self.gameid)
        else:
            self.gameid = shortname

        if self.engine is None:
            self.engine = 'scummvm'
        if self.genre is None:
            self.genre = 'Adventure'

    def _populate_package(self, package, d):
        super(ScummvmGameData, self)._populate_package(package, d)
        package.gameid = d.get('gameid')

    def construct_task(self, **kwargs):
        return ScummvmTask(self, **kwargs)

class ScummvmTask(PackagingTask):
    def iter_extra_paths(self, packages):
        super(ScummvmTask, self).iter_extra_paths(packages)

        gameids = set()
        for p in packages:
            gameid = p.gameid or self.game.gameid
            if gameid == 'agi-fanmade':
                continue
            gameids.add(gameid.split('-')[0])
        if not gameids:
            return

        # http://wiki.scummvm.org/index.php/User_Manual/Configuring_ScummVM
        # https://github.com/scummvm/scummvm/pull/656
        config_home = os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
        for rcfile in (os.path.join(config_home, 'scummvm/scummvm.ini'),
                       os.path.expanduser('~/.scummvmrc'),
                       os.path.join(config_home, 'residualvm/residualvm.ini'),
                       os.path.expanduser('~/.residualvmrc')):
            if os.path.isfile(rcfile):
                config = configparser.ConfigParser(strict=False)
                config.read(rcfile, encoding='utf-8')
                for section in config.sections():
                    for gameid in gameids:
                        if section.split('-')[0] == gameid:
                            if 'path' not in config[section]:
                                # invalid .scummvmrc
                                continue
                            path = config[section]['path']
                            if os.path.isdir(path):
                                yield path

    def fill_extra_files(self, per_package_state):
        super().fill_extra_files(per_package_state)
        package = per_package_state.package
        destdir = per_package_state.destdir

        if package.type not in ('demo', 'full') and not package.gameid:
            return

        icon = package.name
        for from_ in (self.locate_steam_icon(package),
                      os.path.join(DATADIR, package.name + '.png'),
                      os.path.join(DATADIR, self.game.shortname + '.png'),
                      os.path.join('/usr/share/pixmaps', icon + '.png'),
                      os.path.join(DATADIR,
                          self.game.shortname.strip('1234567890') + '.png')):
            if from_ and os.path.exists(from_):
                pixdir = os.path.join(destdir, 'usr/share/pixmaps')
                mkdir_p(pixdir)
                install_data(from_, os.path.join(pixdir, '%s.png' % icon))
                break
        else:
            icon = 'scummvm'

        from_ = os.path.splitext(from_)[0] + '.svgz'
        if os.path.exists(from_):
            svgdir = os.path.join(destdir, 'usr/share/icons/hicolor/scalable/apps')
            mkdir_p(svgdir)
            install_data(from_, os.path.join(svgdir, '%s.svgz' % icon))

        appdir = os.path.join(destdir, 'usr/share/applications')
        mkdir_p(appdir)

        desktop = configparser.RawConfigParser()
        desktop.optionxform = lambda option: option
        desktop['Desktop Entry'] = {}
        entry = desktop['Desktop Entry']
        entry['Name'] = package.longname or self.game.longname
        entry['GenericName'] = self.game.genre + ' Game'
        entry['TryExec'] = 'scummvm'
        entry['Icon'] = icon
        entry['Terminal'] = 'false'
        entry['Type'] = 'Application'
        entry['Categories'] = 'Game;%sGame;' % self.game.genre.replace(' ','')
        gameid = package.gameid or self.game.gameid
        install_to = self.packaging.substitute(package.install_to,
                                               package.name)
        if len(package.langs) == 1:
            entry['Exec'] = 'scummvm -p %s %s' % (
                    os.path.join('/', install_to), gameid)
            per_package_state.lintian_overrides.add(
                'desktop-command-not-in-package {} '
                '[usr/share/applications/{}.desktop]'.format(
                    'scummvm', package.name,
                )
            )
        else:
            pgm = package.name[0:len(package.name)-len('-data')]
            entry['Exec'] = pgm
            bindir = self.packaging.substitute(self.packaging.BINDIR, package.name)
            bindir = os.path.join(destdir, bindir.strip('/'))
            assert bindir.startswith(destdir + '/'), (bindir, destdir)
            mkdir_p(bindir)
            path = os.path.join(bindir, pgm)
            if 'en' not in package.langs:
                package.langs.append('en')
            with open(path, 'w') as f:
                f.write('#!/bin/sh\n')
                f.write('GAME_LANG=$(\n')
                f.write("echo $LANGUAGE $LANG en | tr ': ' '\\n' | cut -c1-2 | while read lang\n")
                f.write('do\n')
                for lang in package.langs:
                    f.write('[ "$lang" = "%s" ] && echo $lang && break\n' % lang)
                f.write('done\n')
                f.write(')\n')
                f.write('if [ "$GAME_LANG" = "en" ]; then\n')
                f.write('  exec scummvm -p %s %s\n' % (
                    os.path.join('/', install_to), gameid))
                f.write('else\n')
                f.write('  exec scummvm -q $GAME_LANG -p %s %s\n' % (
                    os.path.join('/', install_to), gameid))
                f.write('fi\n')
            os.chmod(path, 0o755)

        with open(os.path.join(appdir, '%s.desktop' % package.name),
                  'w', encoding='utf-8') as output:
             desktop.write(output, space_around_delimiters=False)

GAME_DATA_SUBCLASS = ScummvmGameData