1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

Start implementing flake8 compliance.

So far for the a* files.
This commit is contained in:
Shlomi Fish 2017-04-16 19:03:50 +03:00
parent be0de4a2b5
commit 82a7284824
4 changed files with 490 additions and 374 deletions

View file

@ -1,25 +1,25 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
##---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
## #
## Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2009 Skomoroh # Copyright (C) 2005-2009 Skomoroh
## #
## This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version. # (at your option) any later version.
## #
## This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details. # GNU General Public License for more details.
## #
## You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
## #
##---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
# imports # imports
@ -32,6 +32,7 @@ from pysollib.mfxutil import SubclassResponsibility
# * # *
# ************************************************************************ # ************************************************************************
class AbstractCard: class AbstractCard:
# A playing card. # A playing card.
# #
@ -77,13 +78,14 @@ class AbstractCard:
def __str__(self): def __str__(self):
# Return a string for debug print statements. # Return a string for debug print statements.
return "Card(%d, %d, %d, %d)" % (self.id, self.deck, self.suit, self.rank) return "Card(%d, %d, %d, %d)" % \
(self.id, self.deck, self.suit, self.rank)
def isHidden(self): def isHidden(self):
return self.hide_stack is not None return self.hide_stack is not None
def moveTo(self, x, y): def moveTo(self, x, y):
##print 'moveTo', x, y # print 'moveTo', x, y
# Move the card to absolute position (x, y). # Move the card to absolute position (x, y).
dx, dy = 0, 0 dx, dy = 0, 0
if self.game.app.opt.randomize_place: if self.game.app.opt.randomize_place:
@ -97,7 +99,7 @@ class AbstractCard:
if dx or dy: if dx or dy:
self.x = self.x + dx self.x = self.x + dx
self.y = self.y + dy self.y = self.y + dy
##print "moveBy:", self.id, dx, dy, self.item.coords() # print "moveBy:", self.id, dx, dy, self.item.coords()
self.item.move(dx, dy) self.item.move(dx, dy)
def tkraise(self, unhide=1): def tkraise(self, unhide=1):
@ -106,7 +108,6 @@ class AbstractCard:
self.unhide() self.unhide()
self.item.tkraise() self.item.tkraise()
# #
# abstract methods # abstract methods
# #
@ -131,10 +132,8 @@ class AbstractCard:
def updateCardBackground(self, image): def updateCardBackground(self, image):
raise SubclassResponsibility raise SubclassResponsibility
def close(self): def close(self):
pass pass
def unclose(self): def unclose(self):
pass pass

View file

@ -1,32 +1,32 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
##---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
## #
## Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2009 Skomoroh # Copyright (C) 2005-2009 Skomoroh
## #
## This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version. # (at your option) any later version.
## #
## This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details. # GNU General Public License for more details.
## #
## You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
## #
##---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
# imports # imports
import os, locale import os
import locale
# PySol imports # PySol imports
from pysollib.mfxutil import SubclassResponsibility
from pysollib.mfxutil import Struct, openURL from pysollib.mfxutil import Struct, openURL
from pysollib.mfxutil import print_err from pysollib.mfxutil import print_err
from pysollib.pysolrandom import constructRandom from pysollib.pysolrandom import constructRandom
@ -44,7 +44,7 @@ from pysollib.pysoltk import ProgressionDialog
from pysollib.pysoltk import GameInfoDialog from pysollib.pysoltk import GameInfoDialog
# toolkit imports # toolkit imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.pysoltk import MfxMessageDialog, MfxSimpleEntry from pysollib.pysoltk import MfxMessageDialog, MfxSimpleEntry
from pysollib.pysoltk import MfxExceptionDialog from pysollib.pysoltk import MfxExceptionDialog
from pysollib.pysoltk import PlayerOptionsDialog from pysollib.pysoltk import PlayerOptionsDialog
@ -69,25 +69,25 @@ class PysolMenubar(PysolMenubarTk):
self.game = None self.game = None
# enabled/disabled - this is set by updateMenuState() # enabled/disabled - this is set by updateMenuState()
self.menustate = Struct( self.menustate = Struct(
save = 0, save=0,
save_as = 0, save_as=0,
hold_and_quit = 0, hold_and_quit=0,
undo = 0, undo=0,
redo = 0, redo=0,
restart = 0, restart=0,
deal = 0, deal=0,
hint = 0, hint=0,
autofaceup = 0, autofaceup=0,
autodrop = 0, autodrop=0,
shuffle = 0, shuffle=0,
autodeal = 0, autodeal=0,
quickplay = 0, quickplay=0,
demo = 0, demo=0,
highlight_piles = 0, highlight_piles=0,
find_card = 0, find_card=0,
rules = 0, rules=0,
pause = 0, pause=0,
custom_game = 0, custom_game=0,
) )
PysolMenubarTk.__init__(self, app, top, progress) PysolMenubarTk.__init__(self, app, top, progress)
@ -109,7 +109,6 @@ class PysolMenubar(PysolMenubarTk):
assert self.game is not None assert self.game is not None
return self.game.changed(*args, **kw) return self.game.changed(*args, **kw)
# #
# menu updates # menu updates
# #
@ -146,7 +145,7 @@ class PysolMenubar(PysolMenubarTk):
if game.getHintClass() is not None: if game.getHintClass() is not None:
if opt.hint: if opt.hint:
ms.hint = 1 ms.hint = 1
###if not game.demo: # if not already running # if not game.demo: # if not already running
ms.demo = 1 ms.demo = 1
autostacks = game.getAutoStacks() autostacks = game.getAutoStacks()
if autostacks[0]: if autostacks[0]:
@ -229,15 +228,16 @@ class PysolMenubar(PysolMenubarTk):
self._clearMenuState() self._clearMenuState()
self._updateMenus() self._updateMenus()
# #
# File menu # File menu
# #
def mNewGame(self, *args): def mNewGame(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.changed(): if self.changed():
if not self.game.areYouSure(_("New game")): return if not self.game.areYouSure(_("New game")):
return
if self.game.nextGameFlags(self.game.id) == 0: if self.game.nextGameFlags(self.game.id) == 0:
self.game.endGame() self.game.endGame()
self.game.newGame() self.game.newGame()
@ -246,7 +246,8 @@ class PysolMenubar(PysolMenubarTk):
self.game.quitGame(self.game.id) self.game.quitGame(self.game.id)
def _mSelectGame(self, id, random=None, force=False): def _mSelectGame(self, id, random=None, force=False):
if self._cancelDrag(): return if self._cancelDrag():
return
if not force and self.game.id == id: if not force and self.game.id == id:
return return
if self.changed(): if self.changed():
@ -263,10 +264,10 @@ class PysolMenubar(PysolMenubarTk):
id = self.game.id id = self.game.id
if not self.app.getGameInfo(id): if not self.app.getGameInfo(id):
raise ValueError raise ValueError
except (ValueError, TypeError), ex: except (ValueError, TypeError):
d = MfxMessageDialog(self.top, title=_("Invalid game number"), MfxMessageDialog(self.top, title=_("Invalid game number"),
text=_("Invalid game number\n") + str(seed), text=_("Invalid game number\n") + str(seed),
bitmap="error") bitmap="error")
return return
f = self.game.nextGameFlags(id, random) f = self.game.nextGameFlags(id, random)
if f & 17 == 0: if f & 17 == 0:
@ -280,36 +281,42 @@ class PysolMenubar(PysolMenubarTk):
self.game.quitGame(id, random=random) self.game.quitGame(id, random=random)
def mNewGameWithNextId(self, *args): def mNewGameWithNextId(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.changed(): if self.changed():
if not self.game.areYouSure(_("Select next game number")): return if not self.game.areYouSure(_("Select next game number")):
return
r = self.game.random r = self.game.random
seed = r.increaseSeed(r.initial_seed) seed = r.increaseSeed(r.initial_seed)
seed = r.str(seed) seed = r.str(seed)
self._mNewGameBySeed(seed, self.game.random.ORIGIN_NEXT_GAME) self._mNewGameBySeed(seed, self.game.random.ORIGIN_NEXT_GAME)
def mSelectGameById(self, *args): def mSelectGameById(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
id, f = None, self.game.getGameNumber(format=0) return
f = self.game.getGameNumber(format=0)
d = MfxSimpleEntry(self.top, _("Select new game number"), d = MfxSimpleEntry(self.top, _("Select new game number"),
_("\n\nEnter new game number"), f, _("\n\nEnter new game number"), f,
strings=(_("&OK"), _("&Next number"), _("&Cancel")), strings=(_("&OK"), _("&Next number"), _("&Cancel")),
default=0, e_width=25) default=0, e_width=25)
if d.status != 0: return if d.status != 0:
if d.button == 2: return return
if d.button == 2:
return
if d.button == 1: if d.button == 1:
self.mNewGameWithNextId() self.mNewGameWithNextId()
return return
if self.changed(): if self.changed():
if not self.game.areYouSure(_("Select new game number")): return if not self.game.areYouSure(_("Select new game number")):
return
self._mNewGameBySeed(d.value, self.game.random.ORIGIN_SELECTED) self._mNewGameBySeed(d.value, self.game.random.ORIGIN_SELECTED)
def mSelectRandomGame(self, type='all'): def mSelectRandomGame(self, type='all'):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.changed(): if self.changed():
if not self.game.areYouSure(_("Select random game")): return if not self.game.areYouSure(_("Select random game")):
return
game_id = None game_id = None
games = [] games = []
for g in self.app.gdb.getGamesIdSortedById(): for g in self.app.gdb.getGamesIdSortedById():
@ -336,13 +343,15 @@ class PysolMenubar(PysolMenubarTk):
self.game.quitGame(game_id) self.game.quitGame(game_id)
def _mSelectNextGameFromList(self, gl, step): def _mSelectNextGameFromList(self, gl, step):
if self._cancelDrag(): return if self._cancelDrag():
return
id = self.game.id id = self.game.id
gl = list(gl) gl = list(gl)
if len(gl) < 2 or not id in gl: if len(gl) < 2 or (id not in gl):
return return
if self.changed(): if self.changed():
if not self.game.areYouSure(_("Select next game")): return if not self.game.areYouSure(_("Select next game")):
return
index = (gl.index(id) + step) % len(gl) index = (gl.index(id) + step) % len(gl)
self.game.endGame() self.game.endGame()
self.game.quitGame(gl[index]) self.game.quitGame(gl[index])
@ -357,10 +366,12 @@ class PysolMenubar(PysolMenubarTk):
self._mSelectNextGameFromList(self.app.gdb.getGamesIdSortedByName(), 1) self._mSelectNextGameFromList(self.app.gdb.getGamesIdSortedByName(), 1)
def mSelectPrevGameByName(self, *args): def mSelectPrevGameByName(self, *args):
self._mSelectNextGameFromList(self.app.gdb.getGamesIdSortedByName(), -1) self._mSelectNextGameFromList(
self.app.gdb.getGamesIdSortedByName(), -1)
def mSave(self, *args): def mSave(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
if self.menustate.save_as: if self.menustate.save_as:
if self.game.filename: if self.game.filename:
self.game.saveGame(self.game.filename) self.game.saveGame(self.game.filename)
@ -368,37 +379,42 @@ class PysolMenubar(PysolMenubarTk):
self.mSaveAs() self.mSaveAs()
def mHoldAndQuit(self, *args): def mHoldAndQuit(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
self.game.endGame(holdgame=1) self.game.endGame(holdgame=1)
self.game.quitGame(holdgame=1) self.game.quitGame(holdgame=1)
def mQuit(self, *args): def mQuit(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.changed(): if self.changed():
if not self.game.areYouSure(_("Quit ") + TITLE): return if not self.game.areYouSure(_("Quit ") + TITLE):
return
self.game.endGame() self.game.endGame()
self.game.quitGame() self.game.quitGame()
# #
# Edit menu # Edit menu
# #
def mUndo(self, *args): def mUndo(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.menustate.undo: if self.menustate.undo:
self.game.playSample("undo") self.game.playSample("undo")
self.game.undo() self.game.undo()
def mRedo(self, *args): def mRedo(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.menustate.redo: if self.menustate.redo:
self.game.playSample("redo") self.game.playSample("redo")
self.game.redo() self.game.redo()
self.game.checkForWin() self.game.checkForWin()
def mRedoAll(self, *args): def mRedoAll(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.menustate.redo: if self.menustate.redo:
self.app.top.busyUpdate() self.app.top.busyUpdate()
self.game.playSample("redo", loop=1) self.game.playSample("redo", loop=1)
@ -409,23 +425,32 @@ class PysolMenubar(PysolMenubarTk):
self.game.stopSamples() self.game.stopSamples()
def mSetBookmark(self, n, confirm=1): def mSetBookmark(self, n, confirm=1):
if self._cancelDrag(): return if self._cancelDrag():
if not self.app.opt.bookmarks: return return
if not (0 <= n <= 8): return if not self.app.opt.bookmarks:
return
if not (0 <= n <= 8):
return
self.game.setBookmark(n, confirm=confirm) self.game.setBookmark(n, confirm=confirm)
self.game.updateMenus() self.game.updateMenus()
def mGotoBookmark(self, n, confirm=-1): def mGotoBookmark(self, n, confirm=-1):
if self._cancelDrag(): return if self._cancelDrag():
if not self.app.opt.bookmarks: return return
if not (0 <= n <= 8): return if not self.app.opt.bookmarks:
return
if not (0 <= n <= 8):
return
self.game.gotoBookmark(n, confirm=confirm) self.game.gotoBookmark(n, confirm=confirm)
self.game.updateMenus() self.game.updateMenus()
def mClearBookmarks(self, *args): def mClearBookmarks(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
if not self.app.opt.bookmarks: return return
if not self.game.gsaveinfo.bookmarks: return if not self.app.opt.bookmarks:
return
if not self.game.gsaveinfo.bookmarks:
return
if not self.game.areYouSure(_("Clear bookmarks"), if not self.game.areYouSure(_("Clear bookmarks"),
_("Clear all bookmarks ?")): _("Clear all bookmarks ?")):
return return
@ -433,7 +458,8 @@ class PysolMenubar(PysolMenubarTk):
self.game.updateMenus() self.game.updateMenus()
def mRestart(self, *args): def mRestart(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.game.moves.index == 0: if self.game.moves.index == 0:
return return
if self.changed(restart=1): if self.changed(restart=1):
@ -442,27 +468,30 @@ class PysolMenubar(PysolMenubarTk):
return return
self.game.restartGame() self.game.restartGame()
# #
# Game menu # Game menu
# #
def mDeal(self, *args): def mDeal(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
self.game.dealCards() self.game.dealCards()
def mDrop(self, *args): def mDrop(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
##self.game.autoPlay(autofaceup=-1, autodrop=1) return
# self.game.autoPlay(autofaceup=-1, autodrop=1)
self.game.autoDrop(autofaceup=-1) self.game.autoDrop(autofaceup=-1)
def mDrop1(self, *args): def mDrop1(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
##self.game.autoPlay(autofaceup=1, autodrop=1) return
# self.game.autoPlay(autofaceup=1, autodrop=1)
self.game.autoDrop(autofaceup=1) self.game.autoDrop(autofaceup=1)
def mShuffle(self, *args): def mShuffle(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.menustate.shuffle: if self.menustate.shuffle:
if self.game.canShuffle(): if self.game.canShuffle():
self.game._mahjonggShuffle() self.game._mahjonggShuffle()
@ -476,7 +505,8 @@ class PysolMenubar(PysolMenubarTk):
create_solver_dialog(self.game.top, self.app) create_solver_dialog(self.game.top, self.app)
def mEditGameComment(self, *args): def mEditGameComment(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
game, gi = self.game, self.game.gameinfo game, gi = self.game, self.game.gameinfo
t = " " + game.getGameNumber(format=1) t = " " + game.getGameNumber(format=1)
cc = _("Comments for %s:\n\n") % (gi.name + t) cc = _("Comments for %s:\n\n") % (gi.name + t)
@ -497,16 +527,18 @@ class PysolMenubar(PysolMenubarTk):
try: try:
fd = open(fn, 'a') fd = open(fn, 'a')
fd.write(text.encode(enc, 'replace')) fd.write(text.encode(enc, 'replace'))
except Exception, err: except Exception as err:
d = MfxExceptionDialog(self.top, err, d = MfxExceptionDialog(
text=_("Error while writing to file")) self.top, err,
text=_("Error while writing to file"))
else: else:
if fd: fd.close() if fd:
d = MfxMessageDialog(self.top, title=TITLE+_(" Info"), bitmap="info", fd.close()
text=_("Comments were appended to\n\n") + fn) d = MfxMessageDialog(
self.top, title=TITLE+_(" Info"), bitmap="info",
text=_("Comments were appended to\n\n") + fn)
self._setCommentMenu(bool(game.gsaveinfo.comment)) self._setCommentMenu(bool(game.gsaveinfo.comment))
# #
# Game menu - statistics # Game menu - statistics
# #
@ -524,15 +556,17 @@ class PysolMenubar(PysolMenubarTk):
file = open(filename, "a") file = open(filename, "a")
a = FileStatsFormatter(self.app, file) a = FileStatsFormatter(self.app, file)
write_method(a, player) write_method(a, player)
except EnvironmentError, ex: except EnvironmentError as ex:
if file: file.close() if file:
d = MfxExceptionDialog(self.top, ex, file.close()
text=_("Error while writing to file")) MfxExceptionDialog(self.top, ex,
text=_("Error while writing to file"))
else: else:
if file: file.close() if file:
d = MfxMessageDialog(self.top, title=TITLE+_(" Info"), bitmap="info", file.close()
text=text + _(" were appended to\n\n") + filename) MfxMessageDialog(
self.top, title=TITLE+_(" Info"), bitmap="info",
text=text + _(" were appended to\n\n") + filename)
def mPlayerStats(self, *args, **kw): def mPlayerStats(self, *args, **kw):
mode = kw.get("mode", 101) mode = kw.get("mode", 101)
@ -556,7 +590,8 @@ class PysolMenubar(PysolMenubarTk):
d = Status_StatsDialog(self.top, game=self.game) d = Status_StatsDialog(self.top, game=self.game)
elif mode == 101: elif mode == 101:
header = p1 + _("Statistics for ") + n header = p1 + _("Statistics for ") + n
d = SingleGame_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) d = SingleGame_StatsDialog(
self.top, header, self.app, player, gameid=self.game.id)
gameid = d.selected_game gameid = d.selected_game
elif mode == 102: elif mode == 102:
header = p1 + _("Statistics") + p2 header = p1 + _("Statistics") + p2
@ -570,13 +605,15 @@ class PysolMenubar(PysolMenubarTk):
d = SessionLog_StatsDialog(self.top, header, self.app, player) d = SessionLog_StatsDialog(self.top, header, self.app, player)
elif mode == 105: elif mode == 105:
header = p1 + TOP_TITLE + _(" for ") + n header = p1 + TOP_TITLE + _(" for ") + n
d = Top_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) d = Top_StatsDialog(
self.top, header, self.app, player, gameid=self.game.id)
elif mode == 106: elif mode == 106:
header = _("Game Info") header = _("Game Info")
d = GameInfoDialog(self.top, header, self.app) d = GameInfoDialog(self.top, header, self.app)
elif mode == 107: elif mode == 107:
header = _("Statistics progression") header = _("Statistics progression")
d = ProgressionDialog(self.top, header, self.app, player, gameid=self.game.id) d = ProgressionDialog(
self.top, header, self.app, player, gameid=self.game.id)
elif mode == 202: elif mode == 202:
# print stats to file # print stats to file
write_method = FileStatsFormatter.writeStats write_method = FileStatsFormatter.writeStats
@ -591,18 +628,25 @@ class PysolMenubar(PysolMenubarTk):
self._mStatsSave(player, "log", write_method) self._mStatsSave(player, "log", write_method)
elif mode == 301: elif mode == 301:
# reset all player stats # reset all player stats
if self.game.areYouSure(_("Reset all statistics"), if self.game.areYouSure(
_("Reset ALL statistics and logs for player\n%s ?") % p0, _("Reset all statistics"),
confirm=1, default=1): _("Reset ALL statistics and logs for player\n%s ?") % p0,
confirm=1, default=1
):
self.app.stats.resetStats(player, 0) self.app.stats.resetStats(player, 0)
self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) self.game.updateStatus(stats=self.app.stats.getStats(
self.app.opt.player, self.game.id))
elif mode == 302: elif mode == 302:
# reset player stats for current game # reset player stats for current game
if self.game.areYouSure(_("Reset game statistics"), if self.game.areYouSure(
_('Reset statistics and logs for player\n%s\nand game\n%s ?') % (p0, n), _("Reset game statistics"),
confirm=1, default=1): _('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.app.stats.resetStats(player, self.game.id)
self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) self.game.updateStatus(stats=self.app.stats.getStats(
self.app.opt.player, self.game.id))
elif mode == 401: elif mode == 401:
# start a new game with a gameid # start a new game with a gameid
if gameid and gameid != self.game.id: if gameid and gameid != self.game.id:
@ -610,7 +654,7 @@ class PysolMenubar(PysolMenubarTk):
self.game.quitGame(gameid) self.game.quitGame(gameid)
elif mode == 402: elif mode == 402:
# start a new game with a gameid / gamenumber # start a new game with a gameid / gamenumber
## TODO # TODO
pass pass
else: else:
print_err("stats problem: %s %s %s" % (mode, demo, player)) print_err("stats problem: %s %s %s" % (mode, demo, player))
@ -619,67 +663,76 @@ class PysolMenubar(PysolMenubarTk):
break break
mode = d.button mode = d.button
# #
# Assist menu # Assist menu
# #
def mHint(self, *args): def mHint(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.app.opt.hint: if self.app.opt.hint:
if self.game.showHint(0, self.app.opt.timeouts['hint']): if self.game.showHint(0, self.app.opt.timeouts['hint']):
self.game.stats.hints += 1 self.game.stats.hints += 1
def mHint1(self, *args): def mHint1(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.app.opt.hint: if self.app.opt.hint:
if self.game.showHint(1, self.app.opt.timeouts['hint']): if self.game.showHint(1, self.app.opt.timeouts['hint']):
self.game.stats.hints += 1 self.game.stats.hints += 1
def mHighlightPiles(self, *args): def mHighlightPiles(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.app.opt.highlight_piles: if self.app.opt.highlight_piles:
if self.game.highlightPiles(self.app.opt.timeouts['highlight_piles']): if self.game.highlightPiles(
self.app.opt.timeouts['highlight_piles']
):
self.game.stats.highlight_piles += 1 self.game.stats.highlight_piles += 1
def mDemo(self, *args): def mDemo(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
if self.game.getHintClass() is not None: if self.game.getHintClass() is not None:
self._mDemo(mixed=0) self._mDemo(mixed=0)
def mMixedDemo(self, *args): def mMixedDemo(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
self._mDemo(mixed=1) self._mDemo(mixed=1)
def _mDemo(self, mixed): def _mDemo(self, mixed):
if self.changed(): if self.changed():
# only ask if there have been no demo moves or hints yet # only ask if there have been no demo moves or hints yet
if self.game.stats.demo_moves == 0 and self.game.stats.hints == 0: if self.game.stats.demo_moves == 0 and self.game.stats.hints == 0:
if not self.game.areYouSure(_("Play demo")): return if not self.game.areYouSure(_("Play demo")):
##self.app.demo_counter = 0 return
# self.app.demo_counter = 0
self.game.startDemo(mixed=mixed) self.game.startDemo(mixed=mixed)
# #
# Options menu # Options menu
# #
def mOptPlayerOptions(self, *args): def mOptPlayerOptions(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
d = PlayerOptionsDialog(self.top, _("Set player options"), self.app) d = PlayerOptionsDialog(self.top, _("Set player options"), self.app)
if d.status == 0 and d.button == 0: if d.status == 0 and d.button == 0:
self.app.opt.confirm = bool(d.confirm) self.app.opt.confirm = bool(d.confirm)
self.app.opt.update_player_stats = bool(d.update_stats) self.app.opt.update_player_stats = bool(d.update_stats)
self.app.opt.win_animation = bool(d.win_animation) self.app.opt.win_animation = bool(d.win_animation)
##n = string.strip(d.player) # n = string.strip(d.player)
n = d.player[:30].strip() n = d.player[:30].strip()
if 0 < len(n) <= 30: if 0 < len(n) <= 30:
self.app.opt.player = n self.app.opt.player = n
self.game.updateStatus(player=self.app.opt.player) self.game.updateStatus(player=self.app.opt.player)
self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) self.game.updateStatus(stats=self.app.stats.getStats(
self.app.opt.player, self.game.id))
def mOptColors(self, *args): def mOptColors(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
d = ColorsDialog(self.top, _("Set colors"), self.app) d = ColorsDialog(self.top, _("Set colors"), self.app)
text_color = self.app.opt.colors['text'] text_color = self.app.opt.colors['text']
if d.status == 0 and d.button == 0: if d.status == 0 and d.button == 0:
@ -696,7 +749,8 @@ class PysolMenubar(PysolMenubarTk):
self.app.setTile(self.app.tabletile_index, force=True) self.app.setTile(self.app.tabletile_index, force=True)
def mOptFonts(self, *args): def mOptFonts(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
d = FontsDialog(self.top, _("Set fonts"), self.app) d = FontsDialog(self.top, _("Set fonts"), self.app)
if d.status == 0 and d.button == 0: if d.status == 0 and d.button == 0:
self.app.opt.fonts.update(d.fonts) self.app.opt.fonts.update(d.fonts)
@ -705,50 +759,59 @@ class PysolMenubar(PysolMenubarTk):
self.game.quitGame(bookmark=1) self.game.quitGame(bookmark=1)
def mOptTimeouts(self, *args): def mOptTimeouts(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
d = TimeoutsDialog(self.top, _("Set timeouts"), self.app) d = TimeoutsDialog(self.top, _("Set timeouts"), self.app)
if d.status == 0 and d.button == 0: if d.status == 0 and d.button == 0:
self.app.opt.timeouts['demo'] = d.demo_timeout self.app.opt.timeouts['demo'] = d.demo_timeout
self.app.opt.timeouts['hint'] = d.hint_timeout self.app.opt.timeouts['hint'] = d.hint_timeout
self.app.opt.timeouts['raise_card'] = d.raise_card_timeout self.app.opt.timeouts['raise_card'] = d.raise_card_timeout
self.app.opt.timeouts['highlight_piles'] = d.highlight_piles_timeout self.app.opt.timeouts['highlight_piles'] = \
self.app.opt.timeouts['highlight_cards'] = d.highlight_cards_timeout d.highlight_piles_timeout
self.app.opt.timeouts['highlight_samerank'] = d.highlight_samerank_timeout self.app.opt.timeouts['highlight_cards'] = \
d.highlight_cards_timeout
self.app.opt.timeouts['highlight_samerank'] = \
d.highlight_samerank_timeout
# #
# Help menu # Help menu
# #
def mHelp(self, *args): def mHelp(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
help_html(self.app, "index.html", "html") help_html(self.app, "index.html", "html")
def mHelpHowToPlay(self, *args): def mHelpHowToPlay(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
help_html(self.app, "howtoplay.html", "html") help_html(self.app, "howtoplay.html", "html")
def mHelpRules(self, *args): def mHelpRules(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
if not self.menustate.rules: if not self.menustate.rules:
return return
dir = os.path.join("html", "rules") dir = os.path.join("html", "rules")
## FIXME: plugins # FIXME: plugins
help_html(self.app, self.app.getGameRulesFilename(self.game.id), dir) help_html(self.app, self.app.getGameRulesFilename(self.game.id), dir)
def mHelpLicense(self, *args): def mHelpLicense(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
help_html(self.app, "license.html", "html") help_html(self.app, "license.html", "html")
def mHelpNews(self, *args): def mHelpNews(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
help_html(self.app, "news.html", "html") help_html(self.app, "news.html", "html")
def mHelpWebSite(self, *args): def mHelpWebSite(self, *args):
openURL(PACKAGE_URL) openURL(PACKAGE_URL)
def mHelpAbout(self, *args): def mHelpAbout(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
help_about(self.app) help_about(self.app)
# #
@ -756,7 +819,8 @@ class PysolMenubar(PysolMenubarTk):
# #
def mScreenshot(self, *args): def mScreenshot(self, *args):
if self._cancelDrag(): return if self._cancelDrag():
return
f = os.path.join(self.app.dn.config, "screenshots") f = os.path.join(self.app.dn.config, "screenshots")
if not os.path.isdir(f): if not os.path.isdir(f):
return return
@ -772,17 +836,19 @@ class PysolMenubar(PysolMenubarTk):
self.top.screenshot(fn) self.top.screenshot(fn)
def mPlayNextMusic(self, *args): def mPlayNextMusic(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
if self.app.audio and self.app.opt.sound_music_volume > 0: if self.app.audio and self.app.opt.sound_music_volume > 0:
self.app.audio.playNextMusic() self.app.audio.playNextMusic()
if 1 and DEBUG: if 1 and DEBUG:
index = self.app.audio.getMusicInfo() index = self.app.audio.getMusicInfo()
music = self.app.music_manager.get(index) music = self.app.music_manager.get(index)
if music: if music:
print "playing music:", music.filename print("playing music:", music.filename)
def mIconify(self, *args): def mIconify(self, *args):
if self._cancelDrag(break_pause=False): return if self._cancelDrag(break_pause=False):
return
self.top.wm_iconify() self.top.wm_iconify()
@ -870,4 +936,3 @@ class PysolToolbar(PysolToolbarTk):
if not self._busy(): if not self._busy():
self.menubar.mOptPlayerOptions() self.menubar.mOptPlayerOptions()
return 1 return 1

View file

@ -1,29 +1,30 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
##---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
## #
## Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2009 Skomoroh # Copyright (C) 2005-2009 Skomoroh
## #
## This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version. # (at your option) any later version.
## #
## This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details. # GNU General Public License for more details.
## #
## You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
## #
##---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
# imports # imports
import os, re import os
import re
import traceback import traceback
# PySol imports # PySol imports
@ -47,7 +48,7 @@ from pysollib.settings import DEBUG
from pysollib.winsystems import TkSettings from pysollib.winsystems import TkSettings
# Toolkit imports # Toolkit imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.pysoltk import wm_withdraw, loadImage from pysollib.pysoltk import wm_withdraw, loadImage
from pysollib.pysoltk import MfxDialog, MfxMessageDialog, MfxExceptionDialog from pysollib.pysoltk import MfxDialog, MfxMessageDialog, MfxExceptionDialog
from pysollib.pysoltk import TclError, MfxScrolledCanvas from pysollib.pysoltk import TclError, MfxScrolledCanvas
@ -67,13 +68,14 @@ from pysollib.help import help_about, destroy_help_html
# * Statistics # * Statistics
# ************************************************************************ # ************************************************************************
class _GameStatResult: class _GameStatResult:
def __init__(self): def __init__(self):
self.min = 0 self.min = 0
self.max = 0 self.max = 0
self.top = [] self.top = []
self.num = 0 self.num = 0
self.total = 0 # sum of all values self.total = 0 # sum of all values
self.average = 0 self.average = 0
def update(self, gameid, value, game_number, game_start_time): def update(self, gameid, value, game_number, game_start_time):
@ -115,7 +117,7 @@ class GameStat:
self.gameid = id self.gameid = id
# #
self.num_total = 0 self.num_total = 0
#self.num_not_won = 0 # self.num_not_won = 0
self.num_lost = 0 self.num_lost = 0
self.num_won = 0 self.num_won = 0
self.num_perfect = 0 self.num_perfect = 0
@ -143,17 +145,17 @@ class GameStat:
return return
elif status == 1: elif status == 1:
self.num_won += 1 self.num_won += 1
else: # status == 2 else: # status == 2
self.num_perfect += 1 self.num_perfect += 1
score = game.getGameScore() score = game.getGameScore()
##print 'GameScore:', score # print 'GameScore:', score
score_p = None score_p = None
if score is not None: if score is not None:
score_p = self.score_result.update( score_p = self.score_result.update(
game.id, score, game_number, game_start_time) game.id, score, game_number, game_start_time)
score = game.getGameScoreCasino() score = game.getGameScoreCasino()
##print 'GameScoreCasino:', score # print 'GameScoreCasino:', score
score_casino_p = None score_casino_p = None
if score is not None: if score is not None:
score_casino_p = self.score_casino_result.update( score_casino_p = self.score_casino_result.update(
@ -202,11 +204,15 @@ class Statistics:
return return
if gameid == 0: if gameid == 0:
# remove all games # remove all games
try: del self.games_stats[player] try:
except KeyError: pass del self.games_stats[player]
except KeyError:
pass
else: else:
try: del self.games_stats[player][gameid] try:
except KeyError: pass del self.games_stats[player][gameid]
except KeyError:
pass
def __resetPrevGames(self, player, games, gameid): def __resetPrevGames(self, player, games, gameid):
if player not in games: if player not in games:
@ -281,10 +287,10 @@ class Statistics:
all_games_stat.update(game, status) all_games_stat.update(game, status)
return game_stat.update(game, status) return game_stat.update(game, status)
## def __setstate__(self, state): # for backward compatible # def __setstate__(self, state): # for backward compatible
## if 'gameid' not in state: # if 'gameid' not in state:
## self.gameid = None # self.gameid = None
## self.__dict__.update(state) # self.__dict__.update(state)
# ************************************************************************ # ************************************************************************
@ -342,12 +348,12 @@ class Application:
self.images = None self.images = None
self.subsampled_images = None self.subsampled_images = None
self.gimages = Struct( # global images self.gimages = Struct( # global images
demo = [], # demo logos demo=[], # demo logos
pause = [], # pause logos pause=[], # pause logos
logos = [], logos=[],
redeal = [], redeal=[],
) )
#self.progress_bg = None # self.progress_bg = None
self.progress_images = [] self.progress_images = []
self.cardset_manager = CardsetManager() self.cardset_manager = CardsetManager()
self.cardset = None # current cardset self.cardset = None # current cardset
@ -358,28 +364,28 @@ class Application:
self.music_manager = MusicManager() self.music_manager = MusicManager()
self.music_playlist = [] self.music_playlist = []
self.intro = Struct( self.intro = Struct(
progress = None, # progress bar progress=None, # progress bar
) )
# directory names # directory names
config = os.path.normpath(getprefdir(PACKAGE)) config = os.path.normpath(getprefdir(PACKAGE))
self.dn = Struct( self.dn = Struct(
config = config, config=config,
plugins = os.path.join(config, "plugins"), plugins=os.path.join(config, "plugins"),
savegames = os.path.join(config, "savegames"), savegames=os.path.join(config, "savegames"),
maint = os.path.join(config, "maint"), # debug maint=os.path.join(config, "maint"), # debug
) )
for k, v in self.dn.__dict__.items(): for k, v in self.dn.__dict__.items():
## if os.name == "nt": # if os.name == "nt":
## v = os.path.normcase(v) # v = os.path.normcase(v)
v = os.path.normpath(v) v = os.path.normpath(v)
self.dn.__dict__[k] = v self.dn.__dict__[k] = v
# file names # file names
self.fn = Struct( self.fn = Struct(
opt = os.path.join(self.dn.config, "options.dat"), opt=os.path.join(self.dn.config, "options.dat"),
opt_cfg = os.path.join(self.dn.config, "options.cfg"), opt_cfg=os.path.join(self.dn.config, "options.cfg"),
stats = os.path.join(self.dn.config, "statistics.dat"), stats=os.path.join(self.dn.config, "statistics.dat"),
holdgame = os.path.join(self.dn.config, "holdgame.dat"), holdgame=os.path.join(self.dn.config, "holdgame.dat"),
comments = os.path.join(self.dn.config, "comments.dat"), comments=os.path.join(self.dn.config, "comments.dat"),
) )
for k, v in self.dn.__dict__.items(): for k, v in self.dn.__dict__.items():
if os.name == "nt": if os.name == "nt":
@ -397,22 +403,21 @@ class Application:
self.opt.player = player self.opt.player = player
# misc # misc
self.nextgame = Struct( self.nextgame = Struct(
id = 0, # start this game id=0, # start this game
random = None, # use this random generator random=None, # use this random generator
loadedgame = None, # data for loaded game loadedgame=None, # data for loaded game
startdemo = 0, # start demo ? startdemo=0, # start demo ?
cardset = None, # use this cardset cardset=None, # use this cardset
holdgame = 0, # hold this game on exit ? holdgame=0, # hold this game on exit ?
bookmark = None, # goto this bookmark (load new cardset) bookmark=None, # goto this bookmark (load new cardset)
) )
self.commandline = Struct( self.commandline = Struct(
loadgame = None, # load a game ? loadgame=None, # load a game ?
game = None, game=None,
gameid = None, gameid=None,
) )
self.demo_counter = 0 self.demo_counter = 0
# the PySol mainloop # the PySol mainloop
def mainloop(self): def mainloop(self):
# copy startup options # copy startup options
@ -455,7 +460,8 @@ class Application:
if not self.nextgame.loadedgame: if not self.nextgame.loadedgame:
if self.commandline.loadgame: if self.commandline.loadgame:
try: try:
self.nextgame.loadedgame = tmpgame._loadGame(self.commandline.loadgame, self) self.nextgame.loadedgame = tmpgame._loadGame(
self.commandline.loadgame, self)
self.nextgame.loadedgame.gstats.holded = 0 self.nextgame.loadedgame.gstats.holded = 0
except: except:
traceback.print_exc() traceback.print_exc()
@ -467,7 +473,8 @@ class Application:
else: else:
self.nextgame.id, self.nextgame.random = gameid, None self.nextgame.id, self.nextgame.random = gameid, None
elif self.commandline.gameid is not None: elif self.commandline.gameid is not None:
self.nextgame.id, self.nextgame.random = self.commandline.gameid, None self.nextgame.id, self.nextgame.random = \
self.commandline.gameid, None
self.opt.game_holded = 0 self.opt.game_holded = 0
tmpgame.destruct() tmpgame.destruct()
destruct(tmpgame) destruct(tmpgame)
@ -476,7 +483,8 @@ class Application:
# widgets # widgets
# #
# create the menubar # create the menubar
if self.intro.progress: self.intro.progress.update(step=1) if self.intro.progress:
self.intro.progress.update(step=1)
self.menubar = PysolMenubar(self, self.top, self.menubar = PysolMenubar(self, self.top,
progress=self.intro.progress) progress=self.intro.progress)
# create the statusbar(s) # create the statusbar(s)
@ -506,7 +514,8 @@ class Application:
for w, v in self.opt.toolbar_vars.items(): for w, v in self.opt.toolbar_vars.items():
self.toolbar.config(w, v) self.toolbar.config(w, v)
# #
if self.intro.progress: self.intro.progress.update(step=1) if self.intro.progress:
self.intro.progress.update(step=1)
# #
try: try:
# this is the mainloop # this is the mainloop
@ -547,7 +556,9 @@ class Application:
break break
# load new cardset # load new cardset
if self.nextgame.cardset is not self.cardset: if self.nextgame.cardset is not self.cardset:
self.loadCardset(self.nextgame.cardset, id=self.nextgame.id, update=7+256) self.loadCardset(
self.nextgame.cardset, id=self.nextgame.id,
update=7+256)
else: else:
self.requestCompatibleCardsetType(self.nextgame.id) self.requestCompatibleCardsetType(self.nextgame.id)
finally: finally:
@ -560,27 +571,30 @@ class Application:
# update options # update options
self.opt.last_gameid = id self.opt.last_gameid = id
# save options # save options
try: self.saveOptions() try:
self.saveOptions()
except: except:
traceback.print_exc() traceback.print_exc()
pass pass
# save statistics # save statistics
try: self.saveStatistics() try:
self.saveStatistics()
except: except:
traceback.print_exc() traceback.print_exc()
pass pass
# save comments # save comments
try: self.saveComments() try:
self.saveComments()
except: except:
traceback.print_exc() traceback.print_exc()
pass pass
# shut down audio # shut down audio
try: self.audio.destroy() try:
self.audio.destroy()
except: except:
traceback.print_exc() traceback.print_exc()
pass pass
def runGame(self, id, random=None): def runGame(self, id, random=None):
self.top.connectApp(self) self.top.connectApp(self)
# create game instance # create game instance
@ -602,7 +616,7 @@ class Application:
self.game.create(self) self.game.create(self)
# connect with game # connect with game
self.menubar.connectGame(self.game) self.menubar.connectGame(self.game)
if self.toolbar: ##~ if self.toolbar: # ~
self.toolbar.connectGame(self.game) self.toolbar.connectGame(self.game)
self.game.updateStatus(player=self.opt.player) self.game.updateStatus(player=self.opt.player)
# update "Recent games" menubar entry # update "Recent games" menubar entry
@ -654,7 +668,6 @@ class Application:
self.game.busy = 0 self.game.busy = 0
self.top.mainloop() self.top.mainloop()
# free game # free game
def freeGame(self): def freeGame(self):
# disconnect from game # disconnect from game
@ -670,7 +683,6 @@ class Application:
self.game = None self.game = None
self.top.connectApp(None) self.top.connectApp(None)
# #
# UI support # UI support
# #
@ -678,8 +690,8 @@ class Application:
def wm_save_state(self): def wm_save_state(self):
if self.top: if self.top:
s = self.top.wm_state() s = self.top.wm_state()
##print "wm_save_state", s # print "wm_save_state", s
if s == "zoomed": # Windows only if s == "zoomed": # Windows only
self.opt.wm_maximized = True self.opt.wm_maximized = True
elif s == "normal": elif s == "normal":
self.opt.wm_maximized = False self.opt.wm_maximized = False
@ -719,7 +731,7 @@ class Application:
(_('&OK'), 'ok'), (_('&OK'), 'ok'),
(_('&Cancel'), 'cancel'), (_('&Cancel'), 'cancel'),
(_('&New game'), 'new'), (_('&New game'), 'new'),
): ):
fn = self.dataloader.findImage(f, dir) fn = self.dataloader.findImage(f, dir)
im = loadImage(fn) im = loadImage(fn)
MfxDialog.button_img[n] = im MfxDialog.button_img[n] = im
@ -727,7 +739,7 @@ class Application:
def loadImages2(self): def loadImages2(self):
# load canvas images # load canvas images
dir = "images" dir = "images"
##for f in ("noredeal", "redeal",): # for f in ("noredeal", "redeal",):
for f in ("stopsign", "redeal",): for f in ("stopsign", "redeal",):
self.gimages.redeal.append(self.dataloader.findImage(f, dir)) self.gimages.redeal.append(self.dataloader.findImage(f, dir))
dir = os.path.join("images", "demo") dir = os.path.join("images", "demo")
@ -736,9 +748,9 @@ class Application:
dir = os.path.join("images", "pause") dir = os.path.join("images", "pause")
for f in ("pause01", "pause02", "pause03",): for f in ("pause01", "pause02", "pause03",):
self.gimages.pause.append(self.dataloader.findImage(f, dir)) self.gimages.pause.append(self.dataloader.findImage(f, dir))
##dir = os.path.join("images", "stats") # dir = os.path.join("images", "stats")
##for f in ("barchart",): # for f in ("barchart",):
## self.gimages.stats.append(self.dataloader.findImage(f, dir)) # self.gimages.stats.append(self.dataloader.findImage(f, dir))
def loadImages3(self): def loadImages3(self):
# load treeview images # load treeview images
@ -768,7 +780,7 @@ class Application:
def _getImagesDir(self, *dirs, **kwargs): def _getImagesDir(self, *dirs, **kwargs):
check = kwargs.get('check', True) check = kwargs.get('check', True)
dirs = [str(d) for d in dirs] # XXX: don't use unicode dirs = [str(d) for d in dirs] # XXX: don't use unicode
d = os.path.join(self.dataloader.dir, 'images', *dirs) d = os.path.join(self.dataloader.dir, 'images', *dirs)
if check: if check:
if os.path.exists(d): if os.path.exists(d):
return d return d
@ -805,7 +817,6 @@ class Application:
def getFont(self, name): def getFont(self, name):
return self.opt.fonts.get(name) return self.opt.fonts.get(name)
# #
# cardset # cardset
# #
@ -836,10 +847,10 @@ class Application:
self.opt.cardset[gi.category] = (cs.name, cs.backname) self.opt.cardset[gi.category] = (cs.name, cs.backname)
if update & 8: if update & 8:
self.opt.cardset[(1, gi.id)] = (cs.name, cs.backname) self.opt.cardset[(1, gi.id)] = (cs.name, cs.backname)
#from pprint import pprint; pprint(self.opt.cardset) # from pprint import pprint; pprint(self.opt.cardset)
def loadCardset(self, cs, id=0, update=7, progress=None): def loadCardset(self, cs, id=0, update=7, progress=None):
##print 'loadCardset', cs.ident # print 'loadCardset', cs.ident
r = 0 r = 0
if cs is None or cs.error: if cs is None or cs.error:
return 0 return 0
@ -852,7 +863,7 @@ class Application:
# value: (Cardset.ident, Images, SubsampledImages) # value: (Cardset.ident, Images, SubsampledImages)
c = self.cardsets_cache.get(cs.type) c = self.cardsets_cache.get(cs.type)
if c and c[0] == cs.ident: if c and c[0] == cs.ident:
#print 'load from cache', c # print 'load from cache', c
self.images, self.subsampled_images = c[1], c[2] self.images, self.subsampled_images = c[1], c[2]
self.updateCardset(id, update=update) self.updateCardset(id, update=update)
if self.menubar is not None: if self.menubar is not None:
@ -877,32 +888,35 @@ class Application:
if self.opt.save_cardsets: if self.opt.save_cardsets:
c = self.cardsets_cache.get(cs.type) c = self.cardsets_cache.get(cs.type)
if c: if c:
##c[1].destruct() # c[1].destruct()
destruct(c[1]) destruct(c[1])
self.cardsets_cache[cs.type] = (cs.ident, images, simages) self.cardsets_cache[cs.type] = (cs.ident, images, simages)
elif self.images is not None: elif self.images is not None:
##self.images.destruct() # self.images.destruct()
destruct(self.images) destruct(self.images)
# #
if self.cardset and self.cardset.ident != cs.ident and \ if self.cardset:
self.cardset.type == cs.type: if self.cardset.ident != cs.ident:
self.opt.games_geometry = {} # clear saved games geometry if self.cardset.type == cs.type:
# clear saved games geometry
self.opt.games_geometry = {}
# update # update
self.images = images self.images = images
self.subsampled_images = simages self.subsampled_images = simages
self.updateCardset(id, update=update) self.updateCardset(id, update=update)
r = 1 r = 1
except (Exception, TclError, UnpicklingError), ex: except (Exception, TclError, UnpicklingError) as ex:
traceback.print_exc() traceback.print_exc()
cs.error = 1 cs.error = 1
# restore settings # restore settings
self.nextgame.cardset = self.cardset self.nextgame.cardset = self.cardset
if self.cardset: if self.cardset:
self.cardset_manager.setSelected(self.cardset.index) self.cardset_manager.setSelected(self.cardset.index)
##images.destruct() # images.destruct()
destruct(images) destruct(images)
d = MfxExceptionDialog(self.top, ex, title=CARDSET+_(" load error"), MfxExceptionDialog(
text=_("Error while loading ")+CARDSET) self.top, ex, title=CARDSET+_(" load error"),
text=_("Error while loading ")+CARDSET)
self.intro.progress = progress self.intro.progress = progress
if r and self.menubar is not None: if r and self.menubar is not None:
self.menubar.updateBackgroundImagesMenu() self.menubar.updateBackgroundImagesMenu()
@ -917,7 +931,7 @@ class Application:
if gc == GI.GC_FRENCH: if gc == GI.GC_FRENCH:
t0 = "French" t0 = "French"
if cs_type not in (CSI.TYPE_FRENCH, if cs_type not in (CSI.TYPE_FRENCH,
##CSI.TYPE_TAROCK, # CSI.TYPE_TAROCK,
): ):
t1 = t0 t1 = t0
elif gc == GI.GC_HANAFUDA: elif gc == GI.GC_HANAFUDA:
@ -996,15 +1010,16 @@ class Application:
return 1 return 1
# #
t = self.checkCompatibleCardsetType(gi, self.cardset) t = self.checkCompatibleCardsetType(gi, self.cardset)
d = MfxMessageDialog(self.top, title=_("Incompatible ")+CARDSET, MfxMessageDialog(
bitmap="warning", self.top, title=_("Incompatible ")+CARDSET,
text=_('''The currently selected %s %s bitmap="warning",
text=_('''The currently selected %s %s
is not compatible with the game is not compatible with the game
%s %s
Please select a %s type %s. Please select a %s type %s.
''') % (CARDSET, self.cardset.name, gi.name, t[0], CARDSET), ''') % (CARDSET, self.cardset.name, gi.name, t[0], CARDSET),
strings=(_("&OK"),), default=0) strings=(_("&OK"),), default=0)
cs = self.__selectCardsetDialog(t) cs = self.__selectCardsetDialog(t)
if cs is None: if cs is None:
return -1 return -1
@ -1023,7 +1038,7 @@ Please select a %s type %s.
if (self.opt.scale_x, self.opt.scale_y, if (self.opt.scale_x, self.opt.scale_y,
self.opt.auto_scale, self.opt.preserve_aspect_ratio) != \ self.opt.auto_scale, self.opt.preserve_aspect_ratio) != \
d.scale_values or \ d.scale_values or \
(cs.CARD_XOFFSET, cs.CARD_YOFFSET) != d.cardset_values: (cs.CARD_XOFFSET, cs.CARD_YOFFSET) != d.cardset_values:
changed = True changed = True
if d.key == self.cardset.index and not changed: if d.key == self.cardset.index and not changed:
return None return None
@ -1046,7 +1061,6 @@ Please select a %s type %s.
self.cardset.index) self.cardset.index)
return cs return cs
# #
# load & save options, statistics and comments # load & save options, statistics and comments
# #
@ -1070,7 +1084,7 @@ Please select a %s type %s.
return return
stats = unpickle(self.fn.stats) stats = unpickle(self.fn.stats)
if stats: if stats:
##print "loaded:", stats.__dict__ # print "loaded:", stats.__dict__
self.stats.__dict__.update(stats.__dict__) self.stats.__dict__.update(stats.__dict__)
# start a new session # start a new session
self.stats.session_games = {} self.stats.session_games = {}
@ -1082,7 +1096,7 @@ Please select a %s type %s.
return return
comments = unpickle(self.fn.comments) comments = unpickle(self.fn.comments)
if comments: if comments:
##print "loaded:", comments.__dict__ # print "loaded:", comments.__dict__
self.comments.__dict__.update(comments.__dict__) self.comments.__dict__.update(comments.__dict__)
def __saveObject(self, obj, fn): def __saveObject(self, obj, fn):
@ -1099,7 +1113,6 @@ Please select a %s type %s.
def saveComments(self): def saveComments(self):
self.__saveObject(self.comments, self.fn.comments) self.__saveObject(self.comments, self.fn.comments)
# #
# access games database # access games database
# #
@ -1118,94 +1131,100 @@ Please select a %s type %s.
## ##
def getGamesIdSortedByPlayed(self, player=''): def getGamesIdSortedByPlayed(self, player=''):
if player == '': player = self.opt.player if player == '':
def _cmp(a, b): player = self.opt.player
def _key(a):
wa, la, ta, ma = self.stats.getFullStats(player, a) wa, la, ta, ma = self.stats.getFullStats(player, a)
wb, lb, tb, mb = self.stats.getFullStats(player, b) return wa+la
return cmp(wb+lb, wa+la) # reverse
games = list(self.gdb.getGamesIdSortedByName()) games = list(self.gdb.getGamesIdSortedByName())
games.sort(_cmp) games.sort(key=_key)
return games return games[::-1]
def getGamesIdSortedByWon(self, player=''): def getGamesIdSortedByWon(self, player=''):
if player == '': player = self.opt.player if player == '':
def _cmp(a, b): player = self.opt.player
def _key(a):
wa, la, ta, ma = self.stats.getFullStats(player, a) wa, la, ta, ma = self.stats.getFullStats(player, a)
wb, lb, tb, mb = self.stats.getFullStats(player, b) return wa
return cmp(wb, wa) # reverse
games = list(self.gdb.getGamesIdSortedByName()) games = list(self.gdb.getGamesIdSortedByName())
games.sort(_cmp) games.sort(key=_key)
return games return games[::-1]
def getGamesIdSortedByLost(self, player=''): def getGamesIdSortedByLost(self, player=''):
if player == '': player = self.opt.player if player == '':
def _cmp(a, b): player = self.opt.player
def _key(a):
wa, la, ta, ma = self.stats.getFullStats(player, a) wa, la, ta, ma = self.stats.getFullStats(player, a)
wb, lb, tb, mb = self.stats.getFullStats(player, b) return la
return cmp(lb, la) # reverse
games = list(self.gdb.getGamesIdSortedByName()) games = list(self.gdb.getGamesIdSortedByName())
games.sort(_cmp) games.sort(key=_key)
return games return games[::-1]
def getGamesIdSortedByPercent(self, player=''): def getGamesIdSortedByPercent(self, player=''):
if player == '': player = self.opt.player if player == '':
def _cmp(a, b): player = self.opt.player
def _key(a):
wa, la, ta, ma = self.stats.getFullStats(player, a) wa, la, ta, ma = self.stats.getFullStats(player, a)
wb, lb, tb, mb = self.stats.getFullStats(player, b) return float(wa)/(1 if wa+la == 0 else wa+la)
if wa+la == 0 or wb+lb == 0:
return cmp(wb+lb, wa+la) # reverse
return cmp(float(wb)/(wb+lb),
float(wa)/(wa+la)) # reverse
games = list(self.gdb.getGamesIdSortedByName()) games = list(self.gdb.getGamesIdSortedByName())
games.sort(_cmp) games.sort(key=_key)
return games return games[::-1]
def getGamesIdSortedByPlayingTime(self, player=''): def getGamesIdSortedByPlayingTime(self, player=''):
if player == '': player = self.opt.player if player == '':
def _cmp(a, b): player = self.opt.player
def _key(a):
wa, la, ta, ma = self.stats.getFullStats(player, a) wa, la, ta, ma = self.stats.getFullStats(player, a)
wb, lb, tb, mb = self.stats.getFullStats(player, b) return ta
return cmp(tb, ta) # reverse
games = list(self.gdb.getGamesIdSortedByName()) games = list(self.gdb.getGamesIdSortedByName())
games.sort(_cmp) games.sort(key=_key)
return games return games[::-1]
def getGamesIdSortedByMoves(self, player=''): def getGamesIdSortedByMoves(self, player=''):
if player == '': player = self.opt.player if player == '':
def _cmp(a, b): player = self.opt.player
wa, la, ta, ma = self.stats.getFullStats(player, a)
wb, lb, tb, mb = self.stats.getFullStats(player, b)
return cmp(mb, ma) # reverse
games = list(self.gdb.getGamesIdSortedByName())
games.sort(_cmp)
return games
def _key(a):
wa, la, ta, ma = self.stats.getFullStats(player, a)
return ma
games = list(self.gdb.getGamesIdSortedByName())
games.sort(key=_key)
return games[::-1]
def getGameInfo(self, id): def getGameInfo(self, id):
return self.gdb.get(id) return self.gdb.get(id)
def getGameClass(self, id): def getGameClass(self, id):
gi = self.gdb.get(id) gi = self.gdb.get(id)
if gi is None: return None if gi is None:
return None
return gi.gameclass return gi.gameclass
def getGameTitleName(self, id): def getGameTitleName(self, id):
gi = self.gdb.get(id) gi = self.gdb.get(id)
if gi is None: return None if gi is None:
return None
return gi.name return gi.name
def getGameMenuitemName(self, id): def getGameMenuitemName(self, id):
gi = self.gdb.get(id) gi = self.gdb.get(id)
if gi is None: return None if gi is None:
return None
return gi.short_name return gi.short_name
def getGameRulesFilename(self, id): def getGameRulesFilename(self, id):
gi = self.gdb.get(id) gi = self.gdb.get(id)
if gi is None: return None if gi is None:
return None
if gi.rules_filename is not None: if gi.rules_filename is not None:
return gi.rules_filename return gi.rules_filename
n = gi.en_name # english name n = gi.en_name # english name
##n = re.sub(r"[\[\(].*$", "", n) # n = re.sub(r"[\[\(].*$", "", n)
n = latin1_to_ascii(n) n = latin1_to_ascii(n)
n = re.sub(r"[^\w]", "", n) n = re.sub(r"[^\w]", "", n)
n = n.lower() + ".html" n = n.lower() + ".html"
@ -1216,14 +1235,15 @@ Please select a %s type %s.
return n return n
def getGameSaveName(self, id): def getGameSaveName(self, id):
if os.path.supports_unicode_filenames: # new in python 2.3 if os.path.supports_unicode_filenames: # new in python 2.3
return self.getGameTitleName(id) return self.getGameTitleName(id)
gi = self.gdb.get(id) gi = self.gdb.get(id)
n = gi.en_name # english name n = gi.en_name # english name
if not n: return None if not n:
## m = re.search(r"^(.*)([\[\(](\w+).*[\]\)])\s*$", n) return None
## if m: # m = re.search(r"^(.*)([\[\(](\w+).*[\]\)])\s*$", n)
## n = m.group(1) + "_" + m.group(2).lower() # if m:
# n = m.group(1) + "_" + m.group(2).lower()
n = latin1_to_ascii(n) n = latin1_to_ascii(n)
n = n.lower() n = n.lower()
n = re.sub(r"[\s]", "_", n) n = re.sub(r"[\s]", "_", n)
@ -1266,12 +1286,11 @@ Please select a %s type %s.
if m and os.path.isfile(n): if m and os.path.isfile(n):
try: try:
loadGame(m.group(1), n) loadGame(m.group(1), n)
except Exception, ex: except Exception as ex:
if DEBUG: if DEBUG:
traceback.print_exc() traceback.print_exc()
print_err(_("error loading plugin %s: %s") % (n, ex)) print_err(_("error loading plugin %s: %s") % (n, ex))
# #
# init cardsets # init cardsets
# #
@ -1283,13 +1302,14 @@ Please select a %s type %s.
f = open(filename, "r") f = open(filename, "r")
lines = f.readlines() lines = f.readlines()
finally: finally:
if f: f.close() if f:
f.close()
lines = [l.strip() for l in lines] lines = [l.strip() for l in lines]
if not lines[0].startswith("PySol"): if not lines[0].startswith("PySol"):
return None return None
config = CardsetConfig() config = CardsetConfig()
if not self._parseCardsetConfig(config, lines): if not self._parseCardsetConfig(config, lines):
##print filename, 'invalid config' # print filename, 'invalid config'
return None return None
if config.CARDD > self.top.winfo_screendepth(): if config.CARDD > self.top.winfo_screendepth():
return None return None
@ -1315,7 +1335,8 @@ Please select a %s type %s.
fields = [f.strip() for f in line[0].split(';')] fields = [f.strip() for f in line[0].split(';')]
if len(fields) >= 2: if len(fields) >= 2:
m = re.search(r"^(\d+)$", fields[1]) m = re.search(r"^(\d+)$", fields[1])
if m: cs.version = int(m.group(1)) if m:
cs.version = int(m.group(1))
if cs.version >= 3: if cs.version >= 3:
if len(fields) < 5: if len(fields) < 5:
perr(1, msg='number of fields') perr(1, msg='number of fields')
@ -1371,8 +1392,10 @@ Please select a %s type %s.
if not m: if not m:
perr(3, msg='invalid format') perr(3, msg='invalid format')
return 0 return 0
cs.CARDW, cs.CARDH, cs.CARDD = int(m.group(1)), int(m.group(2)), int(m.group(3)) cs.CARDW, cs.CARDH, cs.CARDD = \
# line[3]: CARD_UP_YOFFSET, CARD_DOWN_YOFFSET, SHADOW_XOFFSET, SHADOW_YOFFSET int(m.group(1)), int(m.group(2)), int(m.group(3))
# line[3]: CARD_UP_YOFFSET, CARD_DOWN_YOFFSET,
# SHADOW_XOFFSET, SHADOW_YOFFSET
m = re.search(r"^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", line[3]) m = re.search(r"^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", line[3])
if not m: if not m:
perr(4, msg='invalid format') perr(4, msg='invalid format')
@ -1396,7 +1419,7 @@ Please select a %s type %s.
# set offsets from options.cfg # set offsets from options.cfg
if cs.ident in self.opt.offsets: if cs.ident in self.opt.offsets:
cs.CARD_XOFFSET, cs.CARD_YOFFSET = self.opt.offsets[cs.ident] cs.CARD_XOFFSET, cs.CARD_YOFFSET = self.opt.offsets[cs.ident]
##if cs.type != 1: print cs.type, cs.name # if cs.type != 1: print cs.type, cs.name
return 1 return 1
def initCardsets(self): def initCardsets(self):
@ -1405,7 +1428,7 @@ Please select a %s type %s.
dirs = manager.getSearchDirs(self, ("cardsets", ""), "PYSOL_CARDSETS") dirs = manager.getSearchDirs(self, ("cardsets", ""), "PYSOL_CARDSETS")
if DEBUG: if DEBUG:
dirs = dirs + manager.getSearchDirs(self, "cardsets-*") dirs = dirs + manager.getSearchDirs(self, "cardsets-*")
##print dirs # print dirs
found, t = [], {} found, t = [], {}
for dir in dirs: for dir in dirs:
dir = dir.strip() dir = dir.strip()
@ -1416,40 +1439,42 @@ Please select a %s type %s.
names = os.listdir(dir) names = os.listdir(dir)
names.sort() names.sort()
for name in names: for name in names:
if not name.startswith('cardset-'): continue if not name.startswith('cardset-'):
continue
d = os.path.join(dir, name) d = os.path.join(dir, name)
if not os.path.isdir(d): continue if not os.path.isdir(d):
continue
f1 = os.path.join(d, "config.txt") f1 = os.path.join(d, "config.txt")
f2 = os.path.join(d, "COPYRIGHT") f2 = os.path.join(d, "COPYRIGHT")
if os.path.isfile(f1) and os.path.isfile(f2): if os.path.isfile(f1) and os.path.isfile(f2):
try: try:
cs = self._readCardsetConfig(d, f1) cs = self._readCardsetConfig(d, f1)
if cs: if cs:
##from pprint import pprint # from pprint import pprint
##print cs.name # print cs.name
##pprint(cs.__dict__) # pprint(cs.__dict__)
back = cs.backnames[cs.backindex] back = cs.backnames[cs.backindex]
f1 = os.path.join(d, back) f1 = os.path.join(d, back)
f2 = os.path.join(d, "shade" + cs.ext) f2 = os.path.join(d, "shade" + cs.ext)
if (cs.ext in IMAGE_EXTENSIONS and if (cs.ext in IMAGE_EXTENSIONS and
os.path.isfile(f1) and os.path.isfile(f2)): os.path.isfile(f1) and
os.path.isfile(f2)):
found.append(cs) found.append(cs)
#print '+', cs.name # print '+', cs.name
else: else:
print_err('fail _readCardsetConfig: %s %s' print_err('fail _readCardsetConfig: %s %s'
% (d, f1)) % (d, f1))
pass pass
except Exception, err: except Exception as err:
##traceback.print_exc() # traceback.print_exc()
pass pass
except EnvironmentError, ex: except EnvironmentError as ex:
pass pass
# register cardsets # register cardsets
for obj in found: for obj in found:
if not manager.getByName(obj.name): if not manager.getByName(obj.name):
manager.register(obj) manager.register(obj)
##print obj.index, obj.name # print obj.index, obj.name
# #
# init tiles # init tiles
@ -1458,12 +1483,13 @@ Please select a %s type %s.
def initTiles(self): def initTiles(self):
manager = self.tabletile_manager manager = self.tabletile_manager
# find all available tiles # find all available tiles
dirs = manager.getSearchDirs(self, dirs = manager.getSearchDirs(
("tiles-*", self,
os.path.join("tiles", "stretch"), ("tiles-*",
os.path.join("tiles", "save-aspect")), os.path.join("tiles", "stretch"),
"PYSOL_TILES") os.path.join("tiles", "save-aspect")),
##print dirs "PYSOL_TILES")
# print dirs
s = "((\\" + ")|(\\".join(IMAGE_EXTENSIONS) + "))$" s = "((\\" + ")|(\\".join(IMAGE_EXTENSIONS) + "))$"
ext_re = re.compile(s, re.I | re.U) ext_re = re.compile(s, re.I | re.U)
found, t = [], {} found, t = [], {}
@ -1486,14 +1512,14 @@ Please select a %s type %s.
if os.path.split(dir)[-1] == 'save-aspect': if os.path.split(dir)[-1] == 'save-aspect':
tile.stretch = 1 tile.stretch = 1
tile.save_aspect = 1 tile.save_aspect = 1
#n = re.sub("[-_]", " ", n) # n = re.sub("[-_]", " ", n)
n = n.replace('_', ' ') n = n.replace('_', ' ')
tile.name = n tile.name = n
key = n.lower() key = n.lower()
if key not in t: if key not in t:
t[key] = 1 t[key] = 1
found.append((n, tile)) found.append((n, tile))
except EnvironmentError, ex: except EnvironmentError as ex:
pass pass
# register tiles # register tiles
found.sort() found.sort()
@ -1502,7 +1528,6 @@ Please select a %s type %s.
if not manager.getByName(obj.name): if not manager.getByName(obj.name):
manager.register(obj) manager.register(obj)
# #
# init samples / music # init samples / music
# #
@ -1534,7 +1559,7 @@ Please select a %s type %s.
if key not in t: if key not in t:
t[key] = 1 t[key] = 1
found.append((n, obj)) found.append((n, obj))
except EnvironmentError, ex: except EnvironmentError as ex:
pass pass
# register songs # register songs
found.sort() found.sort()
@ -1545,22 +1570,19 @@ Please select a %s type %s.
manager.register(obj) manager.register(obj)
return found return found
def initSamples(self): def initSamples(self):
manager = self.sample_manager manager = self.sample_manager
# find all available samples # find all available samples
dirs = manager.getSearchDirs(self, ("sound", os.path.join("sound", "extra"))) dirs = manager.getSearchDirs(
##print dirs self, ("sound", os.path.join("sound", "extra")))
# print dirs
ext_re = re.compile(r"\.((wav))$", re.I) ext_re = re.compile(r"\.((wav))$", re.I)
self.initResource(manager, dirs, ext_re, Sample) self.initResource(manager, dirs, ext_re, Sample)
def initMusic(self): def initMusic(self):
manager = self.music_manager manager = self.music_manager
# find all available music songs # find all available music songs
dirs = manager.getSearchDirs(self, "music-*", "PYSOL_MUSIC") dirs = manager.getSearchDirs(self, "music-*", "PYSOL_MUSIC")
##print dirs # print dirs
ext_re = re.compile(self.audio.EXTENSIONS) ext_re = re.compile(self.audio.EXTENSIONS)
self.initResource(manager, dirs, ext_re, Music) self.initResource(manager, dirs, ext_re, Music)

30
tests/style/py-flake8.t Normal file
View file

@ -0,0 +1,30 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 1;
use Test::Differences qw( eq_or_diff );
use String::ShellQuote qw/ shell_quote /;
# my $cmd = shell_quote( 'flake8', '.' );
my $cmd = shell_quote( 'flake8', glob('./pysollib/a*.py') );
# TEST
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );
__END__
=head1 COPYRIGHT AND LICENSE
This file is part of Freecell Solver. It is subject to the license terms in
the COPYING.txt file found in the top-level directory of this distribution
and at http://fc-solve.shlomifish.org/docs/distro/COPYING.html . No part of
Freecell Solver, including this file, may be copied, modified, propagated,
or distributed except according to the terms contained in the COPYING file.
Copyright (c) 2016 Shlomi Fish
=cut