def set_theme(app, top, theme): # set theme style = ttk.Style(top) try: style.theme_use(theme) except: print_err(_('invalid theme name: ') + theme) style.theme_use(app.opt.default_tile_theme)
def to_unicode(s): if isinstance(s, unicode): return s try: s = unicode(s, 'utf-8') except UnicodeDecodeError, err: print_err(err) s = unicode(s, 'utf-8', 'ignore')
def perr(line, field=None, msg=''): if not DEBUG: return if field: print_err('_parseCardsetConfig error: line #%d, field #%d %s' % (line, field, msg)) else: print_err('_parseCardsetConfig error: line #%d: %s' % (line, msg))
def to_unicode(s): if isinstance(s, six.text_type): return s try: s = six.text_type(s, 'utf-8') except UnicodeDecodeError as err: print_err(err) s = six.text_type(s, 'utf-8', 'ignore') return s
def initCardsets(self): manager = self.cardset_manager # find all available cardsets dirs = manager.getSearchDirs(self, ("cardsets", ""), "PYSOL_CARDSETS") if DEBUG: dirs += manager.getSearchDirs(self, "cardsets-*") # print dirs found, t = [], {} fnames = {} # (to check for duplicates) for dirname in dirs: dirname = dirname.strip() try: names = [] if dirname and os.path.isdir(dirname) and dirname not in t: t[dirname] = 1 names = os.listdir(dirname) names.sort() for name in names: if not name.startswith('cardset-'): continue d = os.path.join(dirname, name) if not os.path.isdir(d): continue f1 = os.path.join(d, "config.txt") f2 = os.path.join(d, "COPYRIGHT") if os.path.isfile(f1) and os.path.isfile(f2): try: cs = self._readCardsetConfig(d, f1) if cs: # from pprint import pprint # print cs.name # pprint(cs.__dict__) back = cs.backnames[cs.backindex] f1 = os.path.join(d, back) f2 = os.path.join(d, "shade" + cs.ext) if (cs.ext in IMAGE_EXTENSIONS and cs.name not in fnames and os.path.isfile(f1) and os.path.isfile(f2)): found.append(cs) # print '+', cs.name fnames[cs.name] = 1 else: print_err('fail _readCardsetConfig: %s %s' % (d, f1)) pass except Exception: # traceback.print_exc() pass except EnvironmentError: pass # register cardsets for obj in found: if not manager.getByName(obj.name): manager.register(obj)
def loadPlugins(self, dirname): for name in self._my_list_dir(dirname): m = re.search(r"^(.+)\.py$", name) n = os.path.join(dirname, name) if m and os.path.isfile(n): try: loadGame(m.group(1), n) except Exception as ex: if DEBUG: traceback.print_exc() print_err(_("error loading plugin %s: %s") % (n, ex))
def parse_option(argv): prog_name = argv[0] try: optlist, args = getopt.getopt(argv[1:], "g:i:hD:", [ "game=", "gameid=", "french-only", "noplugins", "nosound", "sound-mod=", "help" ]) except getopt.GetoptError, err: print_err( _("%s\ntry %s --help for more information") % (err, prog_name), 0) return None
def set_theme(app, top, theme): # set try: from ttkthemes import themed_style style = themed_style.ThemedStyle(top) except ImportError: style = ttk.Style(top) try: style.theme_use(theme) except Exception: print_err(_('invalid theme name: ') + theme) style.theme_use(app.opt.default_tile_theme)
def parse_option(argv): prog_name = argv[0] try: optlist, args = getopt.getopt(argv[1:], "g:i:hD:", ["game=", "gameid=", "french-only", "noplugins", "nosound", "sound-mod=", "help"]) except getopt.GetoptError, err: print_err(_("%s\ntry %s --help for more information") % (err, prog_name), 0) return None
def initCardsets(self): """Load all valid cardset config.txt files and ignore invalid ones. """ screendepth = self.top.winfo_screendepth() manager = self.cardset_manager # find all available cardsets dirs = manager.getSearchDirs(self, ("cardsets", ""), "PYSOL_CARDSETS") if DEBUG: dirs += manager.getSearchDirs(self, "cardsets-*") found = [] found_names = [] # (to check for duplicates) for dirname in dirs: try: subdirs = [ os.path.join(dirname, subdir) for subdir in os.listdir(dirname) if subdir.startswith('cardset-') ] except EnvironmentError: traceback.print_exc() continue subdirs.sort() for d in subdirs: config_txt_path = os.path.join(d, "config.txt") if not os.path.isfile(config_txt_path): continue try: cs = self._readCardsetConfig(d, config_txt_path) except Exception: traceback.print_exc() cs = None if not cs: print_err('failed to parse cardset file: %s' % config_txt_path) continue back = cs.backnames[cs.backindex] back_im_path = os.path.join(d, back) shade_im_path = os.path.join(d, "shade" + cs.ext) if (cs.name not in found_names and cs.ext in IMAGE_EXTENSIONS and cs.CARDD <= screendepth and os.path.isfile(back_im_path) and os.path.isfile(shade_im_path)): found.append(cs) found_names.append(cs.name) # register cardsets for obj in found: if not manager.getByName(obj.name): manager.register(obj)
def get_font_name(font): # create font name # i.e. "helvetica 12" -> ("helvetica", 12, "roman", "normal") from six.moves.tkinter_font import Font font_name = None try: f = Font(font=font) except: print_err(_('invalid font name: ') + font) if DEBUG: traceback.print_exc() else: fa = f.actual() font_name = (fa['family'], fa['size'], fa['slant'], fa['weight']) return font_name
def get_font_name(font): # create font name # i.e. "helvetica 12" -> ("helvetica", 12, "roman", "normal") from tkFont import Font font_name = None try: f = Font(font=font) except: print_err(_('invalid font name: ') + font) if DEBUG: traceback.print_exc() else: fa = f.actual() font_name = (fa['family'], fa['size'], fa['slant'], fa['weight']) return font_name
def read_cardset_config(dirname, filename): """Parse a cardset config file and produce a Cardset object. This function returns None if any errors occurred. """ with open(filename, "rt") as f: lines_list = f.readlines() lines_list = [line.strip() for line in lines_list] if not lines_list[0].startswith("PySol"): return None config = parse_cardset_config(lines_list) if not config: print_err('invalid cardset: %s' % filename) return None cs = Cardset() cs.dir = dirname cs.update(config.__dict__) return cs
def get_font_name(font): # create font name # i.e. "helvetica 12" -> ("helvetica", 12, "roman", "normal") if (TOOLKIT == 'kivy'): return "helvetica 12" from six.moves.tkinter_font import Font font_name = None try: f = Font(font=font) except Exception: print_err(_('invalid font name: ') + font) if DEBUG: traceback.print_exc() else: fa = f.actual() font_name = (fa['family'], fa['size'], fa['slant'], fa['weight']) return font_name
def __loadCard(self, filename, check_w=1, check_h=1): # print '__loadCard:', filename f = os.path.join(self.cs.dir, filename) if not os.path.exists(f): print_err('card image path %s does not exist' % f) return None try: img = loadImage(file=f) except Exception: return None if TOOLKIT == 'kivy': w = img.texture.size[0] h = img.texture.size[1] else: w, h = img.width(), img.height() if self.CARDW < 0: self.CARDW, self.CARDH = w, h else: if ((check_w and w != self.CARDW) or (check_h and h != self.CARDH)): raise ValueError("Invalid size %dx%d of image %s" % (w, h, f)) return img
def _getOption(self, section, key, t): config = self._config try: if config[section][key] is None: # invalid value return None if t == 'bool': val = config[section].as_bool(key) elif t == 'int': val = config[section].as_int(key) elif t == 'float': val = config[section].as_float(key) elif t == 'list': val = config[section][key] assert isinstance(val, (list, tuple)) else: # str val = config[section][key] except KeyError: val = None except Exception: print_err('load option error: %s: %s' % (section, key)) traceback.print_exc() val = None return val
def mPlayerStats(self, *args, **kw): wasPaused = False if not self.game.pause: self.game.doPause() wasPaused = True mode = kw.get("mode", 101) demo = 0 gameid = None while mode > 0: if mode > 1000: demo = not demo mode = mode % 1000 # d = Struct(status=-1, button=-1) if demo: player = None else: player = self.app.opt.player n = self.game.gameinfo.name # translation keywords transkw = { 'app': TITLE, 'player': player, 'game': n, 'tops': TOP_SIZE } # if mode == 100: d = Status_StatsDialog(self.top, game=self.game) elif mode == 101: header = (_("%(app)s Demo Statistics for %(game)s") if demo else _("Statistics for %(game)s")) % transkw d = SingleGame_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) gameid = d.selected_game elif mode == 102: header = (_("%(app)s Demo Statistics") if demo else _("Statistics for %(player)s")) % transkw d = AllGames_StatsDialog(self.top, header, self.app, player) gameid = d.selected_game elif mode == 103: header = (_("%(app)s Demo Full log") if demo else _("Full log for %(player)s")) % transkw d = FullLog_StatsDialog(self.top, header, self.app, player) elif mode == 104: header = (_("%(app)s Demo Session log") if demo else _("Session log for %(player)s")) % transkw d = SessionLog_StatsDialog(self.top, header, self.app, player) elif mode == 105: # TRANSLATORS: eg. top 10 or top 5 results for a certain game header = (_("%(app)s Demo Top %(tops)d for %(game)s") if demo else _("Top %(tops)d for %(game)s")) % transkw d = Top_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) elif mode == 106: header = _("Game Info") d = GameInfoDialog(self.top, header, self.app) elif mode == 107: header = _("Statistics progression") d = ProgressionDialog(self.top, header, self.app, player, gameid=self.game.id) elif mode == 202: # print stats to file write_method = FileStatsFormatter.writeStats self._mStatsSave(player, "stats", write_method) elif mode == 203: # print full log to file write_method = FileStatsFormatter.writeFullLog self._mStatsSave(player, "log", write_method) elif mode == 204: # print session log to file write_method = FileStatsFormatter.writeSessionLog self._mStatsSave(player, "log", write_method) elif mode == 301: # reset all player stats if self.game.areYouSure( _("Reset all statistics"), _("Reset ALL statistics and logs for player\n" + "%(player)s?") % transkw, confirm=1, default=1): self.app.stats.resetStats(player, 0) self.game.updateStatus(stats=self.app.stats.getStats( self.app.opt.player, self.game.id)) elif mode == 302: # reset player stats for current game if self.game.areYouSure( _("Reset game statistics"), _('Reset statistics and logs for player\n%(player)s\n' 'and game\n%(game)s?') % transkw, confirm=1, default=1): self.app.stats.resetStats(player, self.game.id) self.game.updateStatus(stats=self.app.stats.getStats( self.app.opt.player, self.game.id)) elif mode == 401: # start a new game with a gameid if gameid and gameid != self.game.id: self.game.endGame() self.game.quitGame(gameid) elif mode == 402: # start a new game with a gameid / gamenumber # TODO pass else: print_err("stats problem: %s %s %s" % (mode, demo, player)) pass if d.status != 0: break mode = d.button if self.game.pause: if wasPaused: self.game.doPause()
def load(self, app, progress=None): ext = self.cs.ext[1:] pstep = 0 if progress: pstep = self.cs.ncards + len(self.cs.backnames) + \ self.cs.nbottoms + self.cs.nletters pstep += self.cs.nshadows + 1 # shadows & shade pstep = max(0, (80.0 - progress.percent) / pstep) # load face cards for n in self.cs.getFaceCardNames(): self._card.append(self.__loadCard(n + self.cs.ext)) self._card[-1].filename = n if progress: progress.update(step=pstep) assert len(self._card) == self.cs.ncards # load backgrounds for name in self.cs.backnames: if name: im = self.__loadCard(name) if im: self.__addBack(im, name) else: print_err('in {cs_dir}/config.txt: card back "{fname}" ' 'does not exist'.format(cs_dir=self.cs.dir, fname=name)) if progress: progress.update(step=1) # load bottoms for i in range(self.cs.nbottoms): name = "bottom%02d" % (i + 1) bottom = self.__loadBottom(name, color='black') if bottom is not None: self._bottom_positive.append(bottom) if progress: progress.update(step=pstep) # load negative bottoms name = "bottom%02d-n" % (i + 1) bottom = self.__loadBottom(name, color='white') if bottom is not None: self._bottom_negative.append(bottom) if progress: progress.update(step=pstep) # load letters for rank in range(self.cs.nletters): name = "l%02d" % (rank + 1) self._letter_positive.append(self.__loadBottom(name, color='black')) if progress: progress.update(step=pstep) # load negative letters name = "l%02d-n" % (rank + 1) self._letter_negative.append(self.__loadBottom(name, color='white')) if progress: progress.update(step=pstep) # shadow if not USE_PIL: for i in range(self.cs.nshadows): name = "shadow%02d.%s" % (i, ext) im = self.__loadCard(name, check_w=0, check_h=0) self._shadow.append(im) if i > 0: # skip 0 name = "xshadow%02d.%s" % (i, ext) im = self.__loadCard(name, check_w=0, check_h=0) self._xshadow.append(im) if progress: progress.update(step=pstep) # shade if USE_PIL: self._highlight.append( self._getHighlight(self._card[0], None, '#3896f8')) else: self._highlight.append(self.__loadCard("shade." + ext)) if progress: progress.update(step=pstep) # create missing self._createMissingImages() # self._bottom = self._bottom_positive self._letter = self._letter_positive # return 1
def mPlayerStats(self, *args, **kw): mode = kw.get("mode", 101) demo = 0 gameid = None while mode > 0: if mode > 1000: demo = not demo mode = mode % 1000 # d = Struct(status=-1, button=-1) if demo: player = None p0, p1, p2 = TITLE + _(" Demo"), TITLE + _(" Demo "), "" else: player = self.app.opt.player p0, p1, p2 = player, "", _(" for ") + player n = self.game.gameinfo.name # if mode == 100: d = Status_StatsDialog(self.top, game=self.game) elif mode == 101: header = p1 + _("Statistics for ") + n d = SingleGame_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) gameid = d.selected_game elif mode == 102: header = p1 + _("Statistics") + p2 d = AllGames_StatsDialog(self.top, header, self.app, player) gameid = d.selected_game elif mode == 103: header = p1 + _("Full log") + p2 d = FullLog_StatsDialog(self.top, header, self.app, player) elif mode == 104: header = p1 + _("Session log") + p2 d = SessionLog_StatsDialog(self.top, header, self.app, player) elif mode == 105: header = p1 + TOP_TITLE + _(" for ") + n d = Top_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) elif mode == 106: header = _("Game Info") d = GameInfoDialog(self.top, header, self.app) elif mode == 107: header = _("Statistics progression") d = ProgressionDialog(self.top, header, self.app, player, gameid=self.game.id) elif mode == 202: # print stats to file write_method = FileStatsFormatter.writeStats self._mStatsSave(player, "stats", write_method) elif mode == 203: # print full log to file write_method = FileStatsFormatter.writeFullLog self._mStatsSave(player, "log", write_method) elif mode == 204: # print session log to file write_method = FileStatsFormatter.writeSessionLog self._mStatsSave(player, "log", write_method) elif mode == 301: # reset all player stats if self.game.areYouSure( _("Reset all statistics"), _("Reset ALL statistics and logs for player\n%s ?") % p0, confirm=1, default=1): self.app.stats.resetStats(player, 0) self.game.updateStatus(stats=self.app.stats.getStats( self.app.opt.player, self.game.id)) elif mode == 302: # reset player stats for current game if self.game.areYouSure(_("Reset game statistics"), _('Reset statistics and logs ' + 'for player\n%s\nand game\n%s ?') % (p0, n), confirm=1, default=1): self.app.stats.resetStats(player, self.game.id) self.game.updateStatus(stats=self.app.stats.getStats( self.app.opt.player, self.game.id)) elif mode == 401: # start a new game with a gameid if gameid and gameid != self.game.id: self.game.endGame() self.game.quitGame(gameid) elif mode == 402: # start a new game with a gameid / gamenumber # TODO pass else: print_err("stats problem: %s %s %s" % (mode, demo, player)) pass if d.status != 0: break mode = d.button
def mPlayerStats(self, *args, **kw): mode = kw.get("mode", 101) demo = 0 gameid = None while mode > 0: if mode > 1000: demo = not demo mode = mode % 1000 # d = Struct(status=-1, button=-1) if demo: player = None p0, p1, p2 = TITLE+_(" Demo"), TITLE+_(" Demo "), "" else: player = self.app.opt.player p0, p1, p2 = player, "", _(" for ") + player n = self.game.gameinfo.name # if mode == 100: d = Status_StatsDialog(self.top, game=self.game) elif mode == 101: header = p1 + _("Statistics for ") + n d = SingleGame_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) gameid = d.selected_game elif mode == 102: header = p1 + _("Statistics") + p2 d = AllGames_StatsDialog(self.top, header, self.app, player) gameid = d.selected_game elif mode == 103: header = p1 + _("Full log") + p2 d = FullLog_StatsDialog(self.top, header, self.app, player) elif mode == 104: header = p1 + _("Session log") + p2 d = SessionLog_StatsDialog(self.top, header, self.app, player) elif mode == 105: header = p1 + TOP_TITLE + _(" for ") + n d = Top_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) elif mode == 106: header = _("Game Info") d = GameInfoDialog(self.top, header, self.app) elif mode == 107: header = _("Statistics progression") d = ProgressionDialog(self.top, header, self.app, player, gameid=self.game.id) elif mode == 202: # print stats to file write_method = FileStatsFormatter.writeStats self._mStatsSave(player, "stats", write_method) elif mode == 203: # print full log to file write_method = FileStatsFormatter.writeFullLog self._mStatsSave(player, "log", write_method) elif mode == 204: # print session log to file write_method = FileStatsFormatter.writeSessionLog self._mStatsSave(player, "log", write_method) elif mode == 301: # reset all player stats if self.game.areYouSure(_("Reset all statistics"), _("Reset ALL statistics and logs for player\n%s ?") % p0, confirm=1, default=1): self.app.stats.resetStats(player, 0) self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) elif mode == 302: # reset player stats for current game if self.game.areYouSure(_("Reset game statistics"), _('Reset statistics and logs for player\n%s\nand game\n%s ?') % (p0, n), confirm=1, default=1): self.app.stats.resetStats(player, self.game.id) self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) elif mode == 401: # start a new game with a gameid if gameid and gameid != self.game.id: self.game.endGame() self.game.quitGame(gameid) elif mode == 402: # start a new game with a gameid / gamenumber ## TODO pass else: print_err("stats problem: %s %s %s" % (mode, demo, player)) pass if d.status != 0: break mode = d.button
-g --game=GAMENAME start game GAMENAME -i --gameid=GAMEID --french-only --sound-mod=MOD --nosound disable sound support --noplugins disable load plugins -h --help display this help and exit FILE - file name of a saved game MOD - one of following: pss(default), pygame, oss, win """) % prog_name return None if len(args) > 1: print_err( _("too many files\ntry %s --help for more information") % prog_name, 0) return None filename = args and args[0] or None if filename and not os.path.isfile(filename): print_err( _("invalid file name\ntry %s --help for more information") % prog_name, 0) return None return opts, filename # ************************************************************************ # * # ************************************************************************ def pysol_init(app, args):
def pysol_init(app, args): # init commandline options (undocumented) opts = parse_option(args) if not opts: return 1 sys.exit(1) opts, filename = opts if filename: app.commandline.loadgame = filename app.commandline.deal = opts['deal'] app.commandline.game = opts['game'] if opts['gameid'] is not None: try: app.commandline.gameid = int(opts['gameid']) except ValueError: print_err(_('invalid game id: ') + opts['gameid']) # try to create the config directory for d in ( app.dn.config, app.dn.savegames, os.path.join(app.dn.config, "music"), # os.path.join(app.dn.config, "screenshots"), os.path.join(app.dn.config, "tiles"), os.path.join(app.dn.config, "tiles", "stretch"), os.path.join(app.dn.config, "tiles", "save-aspect"), os.path.join(app.dn.config, "cardsets"), os.path.join(app.dn.config, "plugins"), ): if not os.path.exists(d): try: os.makedirs(d) except Exception: traceback.print_exc() pass # init DataLoader f = os.path.join("html", "license.html") app.dataloader = DataLoader(args[0], f) # init toolkit 1) top = MfxRoot(className=TITLE) app.top = top app.top_bg = top.cget("bg") app.top_cursor = top.cget("cursor") # load options try: app.loadOptions() except Exception: traceback.print_exc() pass # init toolkit 2) init_root_window(top, app) # prepare the progress bar app.loadImages1() if not app.progress_images: app.progress_images = (loadImage(app.gimages.logos[0]), loadImage(app.gimages.logos[1])) app.wm_withdraw() # create the progress bar title = _("Welcome to %s") % TITLE color = app.opt.colors['table'] if app.tabletile_index > 0: color = "#008200" app.intro.progress = PysolProgressBar(app, top, title=title, color=color, images=app.progress_images, norm=2.0) app.intro.progress.update(step=1) # init games database def progressCallback(*args): app.intro.progress.update(step=1) GAME_DB.setCallback(progressCallback) import pysollib.games if not opts['french-only']: import pysollib.games.ultra import pysollib.games.mahjongg import pysollib.games.special pysollib.games.special.no_use() # try to load plugins if not opts["noplugins"]: for dir in (os.path.join(app.dataloader.dir, "games"), os.path.join(app.dataloader.dir, "plugins"), app.dn.plugins): try: app.loadPlugins(dir) except Exception: pass GAME_DB.setCallback(None) # init audio 1) app.audio = None sounds = {'pss': PysolSoundServerModuleClient, 'pygame': PyGameAudioClient, 'oss': OSSAudioClient, 'win': Win32AudioClient} if TOOLKIT == 'kivy': sounds['kivy'] = KivyAudioClient if opts["nosound"] or SOUND_MOD == 'none': app.audio = AbstractAudioClient() elif opts['sound-mod']: c = sounds[opts['sound-mod']] app.audio = c() elif SOUND_MOD == 'auto': snd = [] snd.append(PyGameAudioClient) if TOOLKIT == 'kivy': snd.append(KivyAudioClient) if pysolsoundserver: snd.append(PysolSoundServerModuleClient) snd.append(OSSAudioClient) snd.append(Win32AudioClient) snd.append(AbstractAudioClient) for c in snd: try: app.audio = c() app.audio.startServer() app.audio.connectServer(app) except Exception: pass else: # success break else: c = sounds[SOUND_MOD] app.audio = c() app.audio.startServer() app.audio.connectServer(app) # update sound_mode if isinstance(app.audio, PysolSoundServerModuleClient): app.opt.sound_mode = 1 else: app.opt.sound_mode = 0 # check games if len(app.gdb.getGamesIdSortedByName()) == 0: app.wm_withdraw() app.intro.progress.destroy() d = MfxMessageDialog(top, title=_("%s installation error") % TITLE, text=_(''' No games were found !!! Main data directory is: %s Please check your %s installation. ''') % (app.dataloader.dir, TITLE), bitmap="error", strings=(_("&Quit"),)) return 1 # init cardsets app.initCardsets() cardset = None c = app.opt.cardset.get(0) if c: cardset = app.cardset_manager.getByName(c[0]) if cardset and c[1]: cardset.updateCardback(backname=c[1]) if not cardset: cardset = app.cardset_manager.get(0) if app.cardset_manager.len() == 0 or not cardset: fatal_no_cardsets(app) return 3 # init tiles manager = app.tabletile_manager tile = Tile() tile.color = app.opt.colors['table'] tile.name = "None" tile.filename = None manager.register(tile) app.initTiles() if app.opt.tabletile_name: # and top.winfo_screendepth() > 8: for tile in manager.getAll(): if app.opt.tabletile_name == tile.basename: app.tabletile_index = tile.index break # init samples and music resources app.initSamples() app.initMusic() # init audio 2) if not app.audio.CAN_PLAY_SOUND: app.opt.sound = 0 app.audio.updateSettings() # start up the background music if app.audio.CAN_PLAY_MUSIC: music = app.music_manager.getAll() if music: app.music_playlist = list(music)[:] app.miscrandom.shuffle(app.music_playlist) if 1: for m in app.music_playlist: if m.name.lower() == "bye_for_now": app.music_playlist.remove(m) app.music_playlist.insert(0, m) break app.audio.playContinuousMusic(app.music_playlist) # prepare other images app.loadImages2() app.loadImages3() app.loadImages4() # load cardset progress = app.intro.progress if not app.loadCardset(cardset, progress=progress, update=1): for cardset in app.cardset_manager.getAll(): progress.reset() if app.loadCardset(cardset, progress=progress, update=1): break else: fatal_no_cardsets(app) return 3 # ok return 0
def parse_option(argv): prog_name = argv[0] try: optlist, args = getopt.getopt(argv[1:], "g:i:hD:", ["deal=", "game=", "gameid=", "french-only", "noplugins", "nosound", "sound-mod=", "help"]) except getopt.GetoptError as err: print_err(_("%s\ntry %s --help for more information") % (err, prog_name), 0) return None opts = {"help": False, "deal": None, "game": None, "gameid": None, "french-only": False, "noplugins": False, "nosound": False, "sound-mod": None, } for i in optlist: if i[0] in ("-h", "--help"): opts["help"] = True elif i[0] in ("--deal"): opts["deal"] = i[1] elif i[0] in ("-g", "--game"): opts["game"] = i[1] elif i[0] in ("-i", "--gameid"): opts["gameid"] = i[1] elif i[0] == "--french-only": opts["french-only"] = True elif i[0] == "--noplugins": opts["noplugins"] = True elif i[0] == "--nosound": opts["nosound"] = True elif i[0] == "--sound-mod": assert i[1] in ('pss', 'pygame', 'oss', 'win') opts["sound-mod"] = i[1] if opts["help"]: print(_("""Usage: %s [OPTIONS] [FILE] -g --game=GAMENAME start game GAMENAME -i --gameid=GAMEID --french-only --sound-mod=MOD --nosound disable sound support --noplugins disable load plugins -h --help display this help and exit FILE - file name of a saved game MOD - one of following: pss(default), pygame, oss, win """) % prog_name) return None if len(args) > 1: print_err( _("too many files\ntry %s --help for more information") % prog_name, 0) return None filename = args and args[0] or None if filename and not os.path.isfile(filename): print_err( _("invalid file name\ntry %s --help for more information") % prog_name, 0) return None return opts, filename
-g --game=GAMENAME start game GAMENAME -i --gameid=GAMEID --french-only --sound-mod=MOD --nosound disable sound support --noplugins disable load plugins -h --help display this help and exit FILE - file name of a saved game MOD - one of following: pss(default), pygame, oss, win """) % prog_name return None if len(args) > 1: print_err( _("too many files\ntry %s --help for more information") % prog_name, 0) return None filename = args and args[0] or None if filename and not os.path.isfile(filename): print_err( _("invalid file name\ntry %s --help for more information") % prog_name, 0) return None return opts, filename # ************************************************************************ # * # ************************************************************************
def load(self, filename): # create ConfigObj instance try: config = configobj.ConfigObj(filename, configspec=configspec, encoding=self._config_encoding) except configobj.ParseError: traceback.print_exc() config = configobj.ConfigObj(configspec=configspec, encoding=self._config_encoding) self._config = config # create sections for section in ( 'general', 'sound_samples', 'fonts', 'colors', 'timeouts', 'cardsets', 'games_geometry', 'offsets', ): if section not in config: config[section] = {} # add initial comment if not os.path.exists(filename): config.initial_comment = [ '-*- coding: %s -*-' % self._config_encoding ] return # validation vdt = validate.Validator() res = config.validate(vdt) # from pprint import pprint; pprint(res) if res is not True: for section, data in res.items(): if data is True: continue for key, value in data.items(): if value is False: print_err('config file: validation error: ' 'section: "%s", key: "%s"' % (section, key)) config[section][key] = None # general for key, t in self.GENERAL_OPTIONS: val = self._getOption('general', key, t) if val == 'None': setattr(self, key, None) elif val is not None: setattr(self, key, val) pysollib.settings.TRANSLATE_GAME_NAMES = self.translate_game_names recent_gameid = self._getOption('general', 'recent_gameid', 'list') if recent_gameid is not None: try: self.recent_gameid = [int(i) for i in recent_gameid] except Exception: traceback.print_exc() favorite_gameid = self._getOption('general', 'favorite_gameid', 'list') if favorite_gameid is not None: try: self.favorite_gameid = [int(i) for i in favorite_gameid] except Exception: traceback.print_exc() visible_buttons = self._getOption('general', 'visible_buttons', 'list') if visible_buttons is not None: for key in TOOLBAR_BUTTONS: self.toolbar_vars[key] = (key in visible_buttons) # solver solver_presets = self._getOption('general', 'solver_presets', 'list') if solver_presets is not None: if 'none' not in solver_presets: solver_presets.insert(0, 'none') self.solver_presets = solver_presets # sound_samples for key in self.sound_samples: val = self._getOption('sound_samples', key, 'bool') if val is not None: self.sound_samples[key] = val # fonts for key in self.fonts: if key == 'default': continue val = self._getOption('fonts', key, 'str') if val is not None: try: val[1] = int(val[1]) except Exception: traceback.print_exc() else: val = tuple(val) self.fonts[key] = val # colors for key in self.colors: val = self._getOption('colors', key, 'str') if val is not None: self.colors[key] = val # timeouts for key in self.timeouts: val = self._getOption('timeouts', key, 'float') if val is not None: self.timeouts[key] = val # cardsets for key in self.cardset: val = self._getOption('cardsets', str(key), 'list') if val is not None: try: self.cardset[int(key)] = val except Exception: traceback.print_exc() for key, t in (('scale_cards', 'bool'), ('scale_x', 'float'), ('scale_y', 'float'), ('auto_scale', 'bool'), ('preserve_aspect_ratio', 'bool')): val = self._getOption('cardsets', key, t) if val is not None: setattr(self, key, val) # games_geometry for key, val in config['games_geometry'].items(): try: val = [int(i) for i in val] assert len(val) == 2 self.games_geometry[int(key)] = val except Exception: traceback.print_exc() game_geometry = self._getOption('general', 'game_geometry', 'list') if game_geometry is not None: try: self.game_geometry = tuple(int(i) for i in game_geometry) except Exception: traceback.print_exc() # cards offsets for key, val in config['offsets'].items(): try: val = [int(i) for i in val] assert len(val) == 2 self.offsets[key] = val except Exception: traceback.print_exc()
def load(self, filename): # create ConfigObj instance try: config = configobj.ConfigObj(filename, configspec=configspec, encoding=self._config_encoding) except configobj.ParseError: traceback.print_exc() config = configobj.ConfigObj(configspec=configspec, encoding=self._config_encoding) self._config = config # create sections for section in ( 'general', 'sound_samples', 'fonts', 'colors', 'timeouts', 'cardsets', 'games_geometry', 'offsets', ): if section not in config: config[section] = {} # add initial comment if not os.path.exists(filename): config.initial_comment = ['-*- coding: %s -*-' % self._config_encoding] return # validation vdt = validate.Validator() res = config.validate(vdt) # from pprint import pprint; pprint(res) if res is not True: for section, data in res.items(): if data is True: continue for key, value in data.items(): if value is False: print_err('config file: validation error: ' 'section: "%s", key: "%s"' % (section, key)) config[section][key] = None # general for key, t in self.GENERAL_OPTIONS: val = self._getOption('general', key, t) if val == 'None': setattr(self, key, None) elif val is not None: setattr(self, key, val) pysollib.settings.TRANSLATE_GAME_NAMES = self.translate_game_names recent_gameid = self._getOption('general', 'recent_gameid', 'list') if recent_gameid is not None: try: self.recent_gameid = [int(i) for i in recent_gameid] except Exception: traceback.print_exc() favorite_gameid = self._getOption('general', 'favorite_gameid', 'list') if favorite_gameid is not None: try: self.favorite_gameid = [int(i) for i in favorite_gameid] except Exception: traceback.print_exc() visible_buttons = self._getOption('general', 'visible_buttons', 'list') if visible_buttons is not None: for key in TOOLBAR_BUTTONS: self.toolbar_vars[key] = (key in visible_buttons) # solver solver_presets = self._getOption('general', 'solver_presets', 'list') if solver_presets is not None: if 'none' not in solver_presets: solver_presets.insert(0, 'none') self.solver_presets = solver_presets # sound_samples for key in self.sound_samples: val = self._getOption('sound_samples', key, 'bool') if val is not None: self.sound_samples[key] = val # fonts for key in self.fonts: if key == 'default': continue val = self._getOption('fonts', key, 'str') if val is not None: try: val[1] = int(val[1]) except Exception: traceback.print_exc() else: val = tuple(val) self.fonts[key] = val # colors for key in self.colors: val = self._getOption('colors', key, 'str') if val is not None: self.colors[key] = val # timeouts for key in self.timeouts: val = self._getOption('timeouts', key, 'float') if val is not None: self.timeouts[key] = val # cardsets for key in self.cardset: val = self._getOption('cardsets', str(key), 'list') if val is not None: try: self.cardset[int(key)] = val except Exception: traceback.print_exc() for key, t in (('scale_cards', 'bool'), ('scale_x', 'float'), ('scale_y', 'float'), ('auto_scale', 'bool'), ('preserve_aspect_ratio', 'bool')): val = self._getOption('cardsets', key, t) if val is not None: setattr(self, key, val) # games_geometry for key, val in config['games_geometry'].items(): try: val = [int(i) for i in val] assert len(val) == 2 self.games_geometry[int(key)] = val except Exception: traceback.print_exc() game_geometry = self._getOption('general', 'game_geometry', 'list') if game_geometry is not None: try: self.game_geometry = tuple(int(i) for i in game_geometry) except Exception: traceback.print_exc() # cards offsets for key, val in config['offsets'].items(): try: val = [int(i) for i in val] assert len(val) == 2 self.offsets[key] = val except Exception: traceback.print_exc()
def mainproc(self): # copy startup options self.startup_opt = self.opt.copy() # try to load statistics try: self.loadStatistics() except Exception: traceback.print_exc() pass # startup information if self.getGameClass(self.opt.last_gameid): self.nextgame.id = self.opt.last_gameid # load a holded or saved game tmpgame = self.constructGame(self.gdb.getGamesIdSortedByName()[0]) self._load_held_or_saved_game(tmpgame) if not self.nextgame.loadedgame: if self.commandline.loadgame: try: self.nextgame.loadedgame = tmpgame._loadGame( self.commandline.loadgame, self) self.nextgame.loadedgame.gstats.holded = 0 except Exception: traceback.print_exc() self.nextgame.loadedgame = None elif self.commandline.game is not None: gameid = self.gdb.getGameByName(self.commandline.game) if gameid is None: print_err( _("can't find game: %(game)s") % {'game': self.commandline.game}) sys.exit(-1) else: self.nextgame.id = gameid deal = self.commandline.deal self.nextgame.random = \ None if deal is None else construct_random(deal) elif self.commandline.gameid is not None: self.nextgame.id, self.nextgame.random = \ self.commandline.gameid, None self.opt.game_holded = 0 tmpgame.destruct() destruct(tmpgame) tmpgame = None # # widgets # # create the menubar if self.intro.progress: self.intro.progress.update(step=1) self.menubar = PysolMenubar(self, self.top, progress=self.intro.progress) # create the statusbar(s) self.statusbar = PysolStatusbar(self.top) self.statusbar.show(self.opt.statusbar) self.statusbar.config('gamenumber', self.opt.statusbar_game_number) self.statusbar.config('stuck', self.opt.statusbar_stuck) self.helpbar = HelpStatusbar(self.top) self.helpbar.show(self.opt.helpbar) # create the canvas self.scrolled_canvas = MfxScrolledCanvas(self.top, propagate=True) self.canvas = self.scrolled_canvas.canvas padx, pady = TkSettings.canvas_padding self.scrolled_canvas.grid(row=1, column=1, sticky='nsew', padx=padx, pady=pady) self.top.grid_columnconfigure(1, weight=1) self.top.grid_rowconfigure(1, weight=1) self.setTile(self.tabletile_index, force=True) # create the toolbar dirname = self.getToolbarImagesDir() self.toolbar = PysolToolbar(self.top, self.menubar, dir=dirname, size=self.opt.toolbar_size, relief=self.opt.toolbar_relief, compound=self.opt.toolbar_compound) self.toolbar.show(self.opt.toolbar) if TOOLKIT == 'tk': for w, v in self.opt.toolbar_vars.items(): self.toolbar.config(w, v) # if self.intro.progress: self.intro.progress.update(step=1) # if TOOLKIT == 'kivy': self.gproc = self.gameproc() self.gproc.send(None) return self._main_loop()
def pysol_init(app, args): # init commandline options (undocumented) opts = parse_option(args) if not opts: return 1 sys.exit(1) opts, filename = opts if filename: app.commandline.loadgame = filename app.commandline.game = opts['game'] if opts['gameid'] is not None: try: app.commandline.gameid = int(opts['gameid']) except ValueError: print_err(_('invalid game id: ') + opts['gameid']) # try to create the config directory for d in ( app.dn.config, app.dn.savegames, os.path.join(app.dn.config, "music"), # os.path.join(app.dn.config, "screenshots"), os.path.join(app.dn.config, "tiles"), os.path.join(app.dn.config, "tiles", "stretch"), os.path.join(app.dn.config, "tiles", "save-aspect"), os.path.join(app.dn.config, "cardsets"), os.path.join(app.dn.config, "plugins"), ): if not os.path.exists(d): try: os.makedirs(d) except: traceback.print_exc() pass # init DataLoader f = os.path.join("html-src", "license.html") app.dataloader = DataLoader(args[0], f) # init toolkit 1) top = MfxRoot(className=TITLE) app.top = top app.top_bg = top.cget("bg") app.top_cursor = top.cget("cursor") # load options try: app.loadOptions() except: traceback.print_exc() pass # init toolkit 2) init_root_window(top, app) # prepare the progress bar app.loadImages1() if not app.progress_images: app.progress_images = (loadImage(app.gimages.logos[0]), loadImage(app.gimages.logos[1])) app.wm_withdraw() # create the progress bar title = _("Welcome to %s") % TITLE color = app.opt.colors['table'] if app.tabletile_index > 0: color = "#008200" app.intro.progress = PysolProgressBar(app, top, title=title, color=color, images=app.progress_images, norm=2.0) app.intro.progress.update(step=1) # init games database def progressCallback(*args): app.intro.progress.update(step=1) GAME_DB.setCallback(progressCallback) import pysollib.games if not opts['french-only']: import pysollib.games.ultra import pysollib.games.mahjongg import pysollib.games.special pysollib.games.special.no_use() # try to load plugins if not opts["noplugins"]: for dir in (os.path.join(app.dataloader.dir, "games"), os.path.join(app.dataloader.dir, "plugins"), app.dn.plugins): try: app.loadPlugins(dir) except: pass GAME_DB.setCallback(None) # init audio 1) app.audio = None sounds = { 'pss': PysolSoundServerModuleClient, 'pygame': PyGameAudioClient, 'oss': OSSAudioClient, 'win': Win32AudioClient } if opts["nosound"] or SOUND_MOD == 'none': app.audio = AbstractAudioClient() elif opts['sound-mod']: c = sounds[opts['sound-mod']] app.audio = c() elif SOUND_MOD == 'auto': for c in (PyGameAudioClient, PysolSoundServerModuleClient, OSSAudioClient, Win32AudioClient, AbstractAudioClient): try: app.audio = c() app.audio.startServer() app.audio.connectServer(app) except: pass else: # success break else: c = sounds[SOUND_MOD] app.audio = c() app.audio.startServer() app.audio.connectServer(app) # update sound_mode if isinstance(app.audio, PysolSoundServerModuleClient): app.opt.sound_mode = 1 else: app.opt.sound_mode = 0 # check games if len(app.gdb.getGamesIdSortedByName()) == 0: app.wm_withdraw() app.intro.progress.destroy() d = MfxMessageDialog(top, title=_("%s installation error") % TITLE, text=_(''' No games were found !!! Main data directory is: %s Please check your %s installation. ''') % (app.dataloader.dir, TITLE), bitmap="error", strings=(_("&Quit"), )) return 1 # init cardsets app.initCardsets() cardset = None c = app.opt.cardset.get(0) if c: cardset = app.cardset_manager.getByName(c[0]) if cardset and c[1]: cardset.updateCardback(backname=c[1]) if not cardset: cardset = app.cardset_manager.get(0) if app.cardset_manager.len() == 0 or not cardset: fatal_no_cardsets(app) return 3 # init tiles manager = app.tabletile_manager tile = Tile() tile.color = app.opt.colors['table'] tile.name = "None" tile.filename = None manager.register(tile) app.initTiles() if app.opt.tabletile_name: # and top.winfo_screendepth() > 8: for tile in manager.getAll(): if app.opt.tabletile_name == tile.basename: app.tabletile_index = tile.index break # init samples and music resources app.initSamples() app.initMusic() # init audio 2) if not app.audio.CAN_PLAY_SOUND: app.opt.sound = 0 app.audio.updateSettings() # start up the background music if app.audio.CAN_PLAY_MUSIC: music = app.music_manager.getAll() if music: app.music_playlist = list(music)[:] app.miscrandom.shuffle(app.music_playlist) if 1: for m in app.music_playlist: if m.name.lower() == "bye_for_now": app.music_playlist.remove(m) app.music_playlist.insert(0, m) break app.audio.playContinuousMusic(app.music_playlist) # prepare other images app.loadImages2() app.loadImages3() app.loadImages4() # load cardset progress = app.intro.progress if not app.loadCardset(cardset, progress=progress, update=1): for cardset in app.cardset_manager.getAll(): progress.reset() if app.loadCardset(cardset, progress=progress, update=1): break else: fatal_no_cardsets(app) return 3 # ok return 0
def _perr(line_no, field=None, msg=''): if field: print_err('cannot parse cardset config: line #%d, field #%d: %s' % (line_no, field, msg)) else: print_err('cannot parse cardset config: line #%d: %s' % (line_no, msg))
def parse_option(argv): prog_name = argv[0] try: optlist, args = getopt.getopt(argv[1:], "g:i:hD:", [ "game=", "gameid=", "french-only", "noplugins", "nosound", "sound-mod=", "help" ]) except getopt.GetoptError as err: print_err( _("%s\ntry %s --help for more information") % (err, prog_name), 0) return None opts = { "help": False, "game": None, "gameid": None, "french-only": False, "noplugins": False, "nosound": False, "sound-mod": None, } for i in optlist: if i[0] in ("-h", "--help"): opts["help"] = True elif i[0] in ("-g", "--game"): opts["game"] = i[1] elif i[0] in ("-i", "--gameid"): opts["gameid"] = i[1] elif i[0] == "--french-only": opts["french-only"] = True elif i[0] == "--noplugins": opts["noplugins"] = True elif i[0] == "--nosound": opts["nosound"] = True elif i[0] == "--sound-mod": assert i[1] in ('pss', 'pygame', 'oss', 'win') opts["sound-mod"] = i[1] if opts["help"]: print( _("""Usage: %s [OPTIONS] [FILE] -g --game=GAMENAME start game GAMENAME -i --gameid=GAMEID --french-only --sound-mod=MOD --nosound disable sound support --noplugins disable load plugins -h --help display this help and exit FILE - file name of a saved game MOD - one of following: pss(default), pygame, oss, win """) % prog_name) return None if len(args) > 1: print_err( _("too many files\ntry %s --help for more information") % prog_name, 0) return None filename = args and args[0] or None if filename and not os.path.isfile(filename): print_err( _("invalid file name\ntry %s --help for more information") % prog_name, 0) return None return opts, filename
def mainproc(self): # copy startup options self.startup_opt = self.opt.copy() # try to load statistics try: self.loadStatistics() except Exception: traceback.print_exc() pass # startup information if self.getGameClass(self.opt.last_gameid): self.nextgame.id = self.opt.last_gameid # load a holded or saved game id = self.gdb.getGamesIdSortedByName()[0] tmpgame = self.constructGame(id) if self.opt.game_holded > 0 and not self.nextgame.loadedgame: game = None try: game = tmpgame._loadGame(self.fn.holdgame, self) except Exception: traceback.print_exc() game = None if game: if game.id == self.opt.game_holded and game.gstats.holded: game.gstats.loaded = game.gstats.loaded - 1 game.gstats.holded = 0 self.nextgame.loadedgame = game else: # not a holded game game.destruct() destruct(game) game = None if not self.nextgame.loadedgame: if self.commandline.loadgame: try: self.nextgame.loadedgame = tmpgame._loadGame( self.commandline.loadgame, self) self.nextgame.loadedgame.gstats.holded = 0 except Exception: traceback.print_exc() self.nextgame.loadedgame = None elif self.commandline.game is not None: gameid = self.gdb.getGameByName(self.commandline.game) if gameid is None: print_err(_("can't find game: ") + self.commandline.game) sys.exit(-1) else: self.nextgame.id = gameid deal = self.commandline.deal self.nextgame.random = \ None if deal is None else constructRandom(deal) elif self.commandline.gameid is not None: self.nextgame.id, self.nextgame.random = \ self.commandline.gameid, None self.opt.game_holded = 0 tmpgame.destruct() destruct(tmpgame) tmpgame = None # # widgets # # create the menubar if self.intro.progress: self.intro.progress.update(step=1) self.menubar = PysolMenubar(self, self.top, progress=self.intro.progress) # create the statusbar(s) self.statusbar = PysolStatusbar(self.top) self.statusbar.show(self.opt.statusbar) self.statusbar.config('gamenumber', self.opt.statusbar_game_number) self.statusbar.config('stuck', self.opt.statusbar_stuck) self.helpbar = HelpStatusbar(self.top) self.helpbar.show(self.opt.helpbar) # create the canvas self.scrolled_canvas = MfxScrolledCanvas(self.top, propagate=True) self.canvas = self.scrolled_canvas.canvas padx, pady = TkSettings.canvas_padding self.scrolled_canvas.grid(row=1, column=1, sticky='nsew', padx=padx, pady=pady) self.top.grid_columnconfigure(1, weight=1) self.top.grid_rowconfigure(1, weight=1) self.setTile(self.tabletile_index, force=True) # create the toolbar dir = self.getToolbarImagesDir() self.toolbar = PysolToolbar(self.top, self.menubar, dir=dir, size=self.opt.toolbar_size, relief=self.opt.toolbar_relief, compound=self.opt.toolbar_compound) self.toolbar.show(self.opt.toolbar) if TOOLKIT == 'tk': for w, v in self.opt.toolbar_vars.items(): self.toolbar.config(w, v) # if self.intro.progress: self.intro.progress.update(step=1) # if TOOLKIT == 'kivy': self.gproc = self.gameproc() self.gproc.send(None) try: # this is the mainloop while 1: assert self.cardset is not None id_, random = self.nextgame.id, self.nextgame.random self.nextgame.id, self.nextgame.random = 0, None try: if TOOLKIT == 'kivy': self.gproc.send((id_, random)) logging.info('App: sent for game to start') yield logging.info('App: game proc stopped') else: self.runGame(id_, random) except Exception: # try Klondike if current game fails if id_ == 2: raise # internal error? if DEBUG: raise traceback.print_exc() self.nextgame.id = 2 self.freeGame() continue if self.nextgame.holdgame: assert self.nextgame.id <= 0 try: self.game.gstats.holded = 1 self.game._saveGame(self.fn.holdgame) self.opt.game_holded = self.game.id except Exception: traceback.print_exc() pass self.wm_save_state() # save game geometry geom = (self.canvas.winfo_width(), self.canvas.winfo_height()) if self.opt.save_games_geometry and not self.opt.wm_maximized: self.opt.games_geometry[self.game.id] = geom self.opt.game_geometry = geom self.freeGame() # if self.nextgame.id <= 0: break # load new cardset if self.nextgame.cardset is not self.cardset: self.loadCardset(self.nextgame.cardset, id=self.nextgame.id, update=7 + 256) else: self.requestCompatibleCardsetType(self.nextgame.id) except Exception: traceback.print_exc() pass finally: # hide main window self.wm_withdraw() # destroy_help_html() destroy_find_card_dialog() destroy_solver_dialog() # update options self.opt.last_gameid = id_ # save options try: self.saveOptions() except Exception: traceback.print_exc() pass # save statistics try: self.saveStatistics() except Exception: traceback.print_exc() pass # shut down audio try: self.audio.destroy() except Exception: traceback.print_exc() pass if TOOLKIT == 'kivy': self.top.quit() while True: logging.info('App: mainloop end position') yield