kajongg.py 6.64 KB
Newer Older
1
#!/usr/bin/env python
2
3
4
# -*- coding: utf-8 -*-

"""
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
5
Copyright (C) 2008-2014 Wolfgang Rohdewald <wolfgang@rohdewald.de>
6

7
Kajongg is free software you can redistribute it and/or modify
8
9
10
11
12
13
14
15
16
17
18
it under the terms of the GNU General Public License as published by
the Free Software Foundation either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21
"""

22
23
# pylint: disable=wrong-import-position

24
# keyboardinterrupt should simply terminate
25
26
27
28
# import signal
# signal.signal(signal.SIGINT, signal.SIG_DFL)
import sys
import logging
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
29

30
from qt import QObject, usingQt4
31
from kde import ki18n, KApplication, KCmdLineArgs, KCmdLineOptions, KGlobal
32
from about import About
33

34
from common import Options, SingleshotOptions, Internal, Debug, unicodeString
35
from util import kprint
36

37
38
# do not import modules using twisted before our reactor is running

Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
39
40
def initRulesets():
    """exits if user only wanted to see available rulesets"""
41
    import predefined  # pylint: disable=unused-variable
42
    if Options.showRulesets or Options.rulesetName:
43
        from rule import Ruleset
44
        rulesets = dict((x.name, x) for x in Ruleset.selectableRulesets())
45
        if Options.showRulesets:
46
47
            for name in rulesets:
                kprint(name)
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
48
            Internal.db.close()
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
49
            sys.exit(0)
50
51
        elif Options.rulesetName in rulesets:
            # we have an exact match
52
            Options.ruleset = rulesets[Options.rulesetName]
53
        else:
54
            matches = list(x for x in rulesets if Options.rulesetName in x)
55
56
57
58
            if len(matches) != 1:
                if len(matches) == 0:
                    msg = 'Ruleset %s is unknown' % Options.rulesetName
                else:
59
60
61
                    msg = 'Ruleset %s is ambiguous: %s' % (
                        Options.rulesetName,
                        ', '.join(matches))
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
62
                Internal.db.close()
63
                raise SystemExit(msg)
64
            Options.ruleset = rulesets[matches[0]]
65

66

67
68
def defineOptions():
    """this is the KDE way. Compare with kajonggserver.py"""
69
    options = KCmdLineOptions()
70
71
72
    options.add(
        "playopen",
        ki18n("all robots play with visible concealed tiles"))
73
    options.add("demo", ki18n("start with demo mode"))
74
    options.add("host <HOST>", ki18n("login to HOST"))
75
76
    options.add("table <TABLE>", ki18n("start new TABLE"))
    options.add("join <TABLE>", ki18n("join TABLE "))
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
77
    options.add("ruleset <RULESET>", ki18n("use ruleset without asking"))
78
79
80
    options.add(
        "rounds <ROUNDS>",
        ki18n("play one ROUNDS rounds per game. Only for debugging!"))
81
    options.add("player <PLAYER>", ki18n("prefer PLAYER for next login"))
82
83
84
    options.add(
        "ai <AI>",
        ki18n("use AI variant for human player in demo mode"))
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
85
    options.add("csv <CSV>", ki18n("write statistics to CSV"))
86
    options.add("rulesets", ki18n("show all available rulesets"))
87
    options.add("game <seed(/(firsthand)(..(lasthand))>",
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
                ki18n("for testing purposes: Initializes the random generator"), "0")
    options.add(
        "nogui",
        ki18n("show no graphical user interface. Intended only for testing"))
    options.add(
        "nokde",
        ki18n("Do not use KDE bindings. Intended only for testing"))
    options.add(
        "qt5",
        ki18n("Force using Qt5. Currently Qt4 is used by default"))
    options.add(
        "socket <SOCKET>",
        ki18n("use a dedicated server listening on SOCKET. Intended only for testing"))
    options.add(
        "port <PORT>",
        ki18n("use a dedicated server listening on PORT. Intended only for testing"))
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
104
    options.add("debug <OPTIONS>", ki18n(Debug.help()))
105
106
    return options

107

108
109
def parseOptions():
    """parse command line options and save the values"""
110
    args = KCmdLineArgs.parsedArgs()
111
112
    Internal.app = APP
    Options.playOpen |= args.isSet('playopen')
113
    Options.showRulesets |= args.isSet('rulesets')
114
    Options.rulesetName = str(args.getOption('ruleset'))
115
116
    if args.isSet('host'):
        Options.host = str(args.getOption('host'))
117
    if args.isSet('player'):
118
        Options.player = unicodeString(args.getOption('player'))
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
119
    if args.isSet('rounds'):
120
        Options.rounds = int(args.getOption('rounds'))
121
    if args.isSet('ai'):
122
        Options.AI = str(args.getOption('ai'))
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
123
    if args.isSet('csv'):
124
        Options.csv = str(args.getOption('csv'))
125
    if args.isSet('socket'):
126
        Options.socket = str(args.getOption('socket'))
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
127
128
    if args.isSet('port'):
        Options.port = str(args.getOption('port'))
129
    SingleshotOptions.game = str(args.getOption('game'))
130
    Options.gui |= args.isSet('gui')
131
132
133
134
    if args.isSet('table'):
        SingleshotOptions.table = int(args.getOption('table'))
    if args.isSet('join'):
        SingleshotOptions.join = int(args.getOption('join'))
135
    Options.demo |= args.isSet('demo')
136
    Options.demo |= not Options.gui
137
    Internal.autoPlay = Options.demo
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
138
139
    msg = Debug.setOptions(str(args.getOption('debug')))
    if msg:
140
141
        Internal.logger.debug(msg)
        logging.shutdown()
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
142
        sys.exit(2)
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
143
144
145
146
    from query import initDb
    if not initDb():
        raise SystemExit('Cannot initialize database')
    initRulesets()
147
148
    Options.fixed = True  # may not be changed anymore

149

Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
150
class EvHandler(QObject):
151

Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
152
    """an application wide event handler"""
153

Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
154
155
    def eventFilter(self, receiver, event):
        """will be called for all events"""
156
157
        from log import EventData
        EventData(receiver, event)
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
158
159
        return QObject.eventFilter(self, receiver, event)

160
if __name__ == "__main__":
161
    from util import gitHead
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
162

163
    ABOUT = About()
164
    KCmdLineArgs.init(sys.argv, ABOUT.about)
165
    KCmdLineArgs.addCmdLineOptions(defineOptions())
166
    if usingQt4:
167
        KApplication.setGraphicsSystem('raster')
168
169
    APP = KApplication()
    parseOptions()
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
170

171
172
173
    if Debug.neutral:
        KGlobal.locale().setLanguage('en_US')

Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
174
175
176
177
    if Debug.events:
        EVHANDLER = EvHandler()
        APP.installEventFilter(EVHANDLER)

178
179
    from config import SetupPreferences
    SetupPreferences()
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
180

181
    if Options.csv:
182
        if gitHead() == 'current':
183
            Internal.logger.debug(
184
                'You cannot write to %s with changes uncommitted to git',
185
                Options.csv)
186
            sys.exit(2)
187
188
    from mainwindow import MainWindow
    MainWindow()
Wolfgang Rohdewald's avatar
Wolfgang Rohdewald committed
189
    Internal.app.exec_()