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

View file

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

View file

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