-
Notifications
You must be signed in to change notification settings - Fork 0
/
childsplay.py
executable file
·309 lines (271 loc) · 11.5 KB
/
childsplay.py
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2010 Stas Zykiewicz <[email protected]>
#
# seniorplay
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 3 of the GNU General Public License
# as published by the Free Software Foundation. A copy of this license should
# be included in the file GPL-3.
#
# 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 Library 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
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import sys, os, shlex, glob,shutil
from SPBasePaths import SHARELIBDATADIR
if len(sys.argv) > 2:
if sys.argv[1] == '--plainversion':
from SPVersion import version
print(version)
if os.path.exists('/data/userdata/.schoolsplay.rc/tmp'):# btp production only
shutil.rmtree('/data/userdata/.schoolsplay.rc/tmp',True)
sys.exit(0)
# construct proper restart command if we need to restart
prog = "python %s " % os.path.join(os.getcwd(), " ".join(sys.argv))
print(sys.argv)
import subprocess
#import gc
#gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS)
# first parse commandline options
from SPOptionParser import OParser
# if this doesn't bail out the options are correct and we continue with schoolsplay
op = OParser()
# this will return a class object with the options as attributes
CMD_Options = op.get_options()
######## Here we add options for debugging #####
### Must be removed or at least discussed before release #####
#CMD_Options.loglevel = 'debug'
import SPLogging
SPLogging.set_level(CMD_Options.loglevel)
SPLogging.start()
#create logger, configuration of logger was done above
import logging
CPmodule_logger = logging.getLogger("childsplay.childsplay")
CPmodule_logger.debug("Created schoolsplay loggers")
import utils
BTPPID = None
BTPSTART = None
try:
BTPPID = CMD_Options.kill_btp
BTPSTART = CMD_Options.restart_btp
except AttributeError:
CPmodule_logger.info("No kill_btp or restart_btp option given")
else:
if BTPPID and BTPSTART:
CPmodule_logger.warning("Found BTP pid, killing BTP with pid: %s" % BTPPID)
subprocess.Popen("kill -9 %s" % BTPPID, shell=True)
utils._remove_lock()
BTPSTART = 'cd .. && ' + BTPSTART
else:
CPmodule_logger.info("No pid for BTP")
try:
import sqlalchemy as sqla
except ImportError:
CPmodule_logger.exception("No sqlalchemy package found")
sys.exit(1)
else:
if sqla.__version__ < '0.5.8':
CPmodule_logger.error("Found sqlalchemy version %s" % sqla.__version__)
CPmodule_logger.error("Your version of sqlalchemy is to old, please upgrade to version >= 0.6")
sys.exit(1)
CPmodule_logger.debug("using sqlalchemy %s" % sqla.__version__)
import sqlalchemy.orm as sqlorm
import time
import datetime
#CPmodule_logger.info("IMPORTANT READ THE FOLLOWING LINES")
#CPmodule_logger.info("For debugging purposes we run with some cmdline options hardcoded.")
#CPmodule_logger.info("These must be removed before releasing this to the real world")
#CPmodule_logger.info("Look at the top of this module for these options")
from SPConstants import *
sys.path.insert(0, BASEDIR)
sys.path.insert(0, os.path.join(BASEDIR, 'lib'))
if CMD_Options.loglevel == 'debug':
CPmodule_logger.debug("Paths defined in SPConstants:")
for v in ['ACTIVITYDATADIR', 'ALPHABETDIR', 'BASEDIR',\
'DBASEPATH', 'HOMEDIR', 'HOMEIMAGES', 'HOME_DIR_NAME',\
'LOCALEDIR', 'LOCKFILE']:
CPmodule_logger.debug("%s > %s" % (v, eval(v)))
# Rudimentary language check, when it fails it sets the cmdline option to C
# which is available on every proper GNU/Linux system. We don't have yet a dbase
# connection at this stage so we just check if the locale is properly formed.
# We don't care about windows of course that system locale handling sucks anyway.
loc = CMD_Options.lang
if loc.find('_') == -1 or loc.upper().find('utf8') == -1:
pass
# Make sure we have xml files in a writeable place
name = 'childsplay'
p = os.path.join(HOMEDIR, name)
if not os.path.exists(p):
os.makedirs(p)
orgxmlfiles = glob.glob(os.path.join(THEMESPATH, name, '*.xml'))
existingxmlfiles = os.listdir(p)
for f in XML_FILES_WE_MUST_HAVE:
if f not in existingxmlfiles and os.path.exists(os.path.join(THEMESPATH, name, f)):
src = os.path.join(THEMESPATH, name, f)
CPmodule_logger.debug("Copying %s to %s" % (src, p))
shutil.copy(src, p)
## We also want to have the default photo albums in a writable location
#p = os.path.join(HOMEDIR, 'braintrainer', 'DefaultAlbums')
#if not os.path.exists(p):
# os.makedirs(p)
#orgalbums = [a for a in glob.glob(os.path.join(ACTDATADIR, 'PhotoalbumData', '*_Album_*')) if os.path.isdir(a)]
#existingxmlfiles = os.listdir(p)
#for f in orgalbums:
# if os.path.basename(f) not in existingxmlfiles and os.path.exists(f):
# shutil.copytree(f, os.path.join(p, os.path.basename(f)))
# for childsplay we must make sure we have a content dbase in sqlite3 format present.
# if we want to use an sqlite content dbase we must make sure the default one is in the proper location.
p = os.path.join(HOMEDIR, CMD_Options.theme, CONTENTDBASE)
if not os.path.exists(p):
if os.path.exists(CONTENTDBASE):
shutil.copy(CONTENTDBASE, p)
else:
shutil.copy(os.path.join(SHARELIBDATADIR, CONTENTDBASE), p)
import pygame
## set a bigger buffer, seems that on win XP in conjuction with certain hardware
## the playback of sound is scrambled with the "normal" 1024 buffer.
### XXXX this still sucks, signed or unsigned that's the question :-(
pygame.mixer.pre_init(22050, -16, 2, 2048)
pygame.init()
# this will return the tuple (lang,rtl=bool)
LANG = utils.set_locale(lang=CMD_Options.lang)
# display a splash for 3 seconds
start_splash = time.time()
screen = pygame.display.set_mode((700, 200), pygame.NOFRAME)
background = pygame.Surface(screen.get_size())
p = os.path.join(SHARELIBDATADIR, 'SPData/themes/childsplay/cp-btp-splash.png')
backgroundimage = utils.load_image(p)
background.blit(backgroundimage, (0, 0))
screen.blit(background, (0, 0))
pygame.display.update()
if CMD_Options.checklog:
try:
import SPlogCheck
except (ImportError, utils.SPError):
sys.exit(1)
except utils.MyError:
sys.exit(1)
sys.exit(0)
if not utils._set_lock():
sys.exit(1)
import SPMainCore
from SPgdm import GDMEscapeKeyException
# start the maincore, we only return here on an exit
CPmodule_logger.debug("Start logging")
CPmodule_logger.debug("commandline options: %s" % CMD_Options)
CPmodule_logger.debug("SPMainCore running from: %s" % SPMainCore)
from SPDataManagerCreateDbase import DbaseMaker
DEBUG = False
try:
#This will setup the dbases and ORMS
dbm = DbaseMaker(CMD_Options.theme, debug_sql=DEBUG)
except (AttributeError, sqla.exceptions.SQLAlchemyError, utils.MyError) as info:
CPmodule_logger.exception("Failed to start the DBase, %s" % info)
raise utils.MyError(info)
mainscreen = None
abort = 0
tellcore_error = False
while not abort:
restartme = False
try:
if not tellcore_error:
# query for a session id
try:
orm = dbm.get_all_orms()['stats_session']
content_engine, user_engine = dbm.get_engines()
session = sqlorm.sessionmaker(bind=user_engine)()
except Exception as info:
CPmodule_logger.exception("Failed to get orm for stats_session: %s" % info)
abort = True
break
orm = orm(datetime=datetime.datetime.now())
session.add(orm)
session.commit()
orm = dbm.get_all_orms()['stats_session']
result = session.query(orm).all()[-1]
session_id = result.ID
session.close()
# there's no support for other resolutions then 800x600
mcgui = SPMainCore.MainCoreGui(resolution=(800, 600),
options=CMD_Options, dbmaker = dbm,
mainscr=mainscreen, error=tellcore_error,
session_id=session_id, start_splash=start_splash,
language=LANG)
mainscreen = mcgui.get_mainscreen()
mcgui.start()
except SPMainCore.MainEscapeKeyException:
CPmodule_logger.info("User hits exit/escape...")
tellcore_error = False
if CMD_Options.no_login or CMD_Options.user:
# we have no login screen or the user was passed as a cmdline option so we exit
#sys.exit(0)
abort = True
CPmodule_logger.info("nologin screen, clean exit")
elif CMD_Options.theme == 'childsplay':
CPmodule_logger.info("Theme is childsplay, clean exit")
abort = True
else:
CPmodule_logger.info("restarting core.")
restartme = True
except GDMEscapeKeyException:
CPmodule_logger.info("login screen, clean exit")
tellcore_error = False
break
except utils.RestartMeException:
CPmodule_logger.info("GIT pull occurred, need to restart myself.")
restartme = True
abort = True
tellcore_error = False
except (SystemExit, utils.StopmeException) as status:
if str(status) == '0':
CPmodule_logger.info("systemexit, clean exit")
abort = True
else:
CPmodule_logger.info("systemexit, not a clean exit")
CPmodule_logger.info("restarting core.")
tellcore_error = True
mcgui.call_foreign_observers()
except utils.SPError as info:
CPmodule_logger.error("Unrecoverable error, not a clean exit")
CPmodule_logger.info("restarting core.")
tellcore_error = True
mcgui.call_foreign_observers()
except Exception as status:
CPmodule_logger.exception("unhandled exception in toplevel, traceback follows:")
CPmodule_logger.info("restarting core.")
tellcore_error = True
mcgui.call_foreign_observers()
try:
mcgui.activity.stop_timer()
except Exception as info:
CPmodule_logger.warning("Failed to stop activity timers")
CPmodule_logger.info("Seniorplay stopped.")
#from SPWidgets import Dialog
#
#try:
# import SPlogCheck
#except (ImportError, utils.SPError):
# text = _("Failed to parse the logfile, please contact the developers.\nMessage was: %s" % info)
# dlg = Dialog(text, buttons=[_('OK')], title=_('Warning !'))
# dlg.run()
#except utils.MyError, info:
# text = "%s" % info
# #dlg.run()
CPmodule_logger.debug("quiting pygame and waiting 0.5 seconds.")
pygame.quit()
time.sleep(0.5)
#if sys.platform == "linux2":
# CPmodule_logger.info("Removing pyc files")
# subprocess.Popen('find . -name "*.pyc" -exec rm {} \;',shell=True )
# BT+ specific stuff
if (CMD_Options.theme == 'braintrainer' and restartme) or (BTPPID and BTPSTART):
restartme = False
CPmodule_logger.info("respawing with :%s" % BTPSTART)
pid = subprocess.Popen(BTPSTART, shell=True).pid
CPmodule_logger.debug("launched Control Panel with pid %s" % pid)
sys.exit()