From a10d6d6286990d2efa6997bed891cbf9d245c826 Mon Sep 17 00:00:00 2001 From: Mika Bostrom Date: Mon, 6 Dec 2010 17:31:50 +0200 Subject: [PATCH 01/23] Update changelog to 0.21-rc1 --- packaging/debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packaging/debian/changelog b/packaging/debian/changelog index c09713a3..8ebf2bcd 100644 --- a/packaging/debian/changelog +++ b/packaging/debian/changelog @@ -1,3 +1,9 @@ +free-poker-tools (0.21~rc1) unstable; urgency=low + + * First 0.21 release candidate + + -- Mika Bostrom Mon, 06 Dec 2010 17:30:54 +0200 + free-poker-tools (0.20.906-1) unstable; urgency=low * New snapshot From dd95c8626f1ba0c9a59bf51436aaf01b3815990c Mon Sep 17 00:00:00 2001 From: Eric Blade Date: Sat, 18 Dec 2010 14:58:43 -0500 Subject: [PATCH 02/23] license change --- pyfpdb/TournamentTracker.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/pyfpdb/TournamentTracker.py b/pyfpdb/TournamentTracker.py index 455626ec..3c8c1276 100644 --- a/pyfpdb/TournamentTracker.py +++ b/pyfpdb/TournamentTracker.py @@ -3,23 +3,21 @@ """TourneyTracker.py Based on HUD_main .. who knows if we want to actually use this or not """ -# Copyright 2008-2010, Eric Blade -# -# 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 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Copyright (c) 2009-2010 Eric Blade, and the FPDB team. + +#This program is free software: you can redistribute it and/or modify +#it under the terms of the GNU Affero General Public License as published by +#the Free Software Foundation, version 3 of the License. +# +#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 Affero General Public License +#along with this program. If not, see . +#In the "official" distribution you can find the license in agpl-3.0.txt. -######################################################################## import L10n _ = L10n.get_translation() From 31b068c3dc42bc291c5e419a9fff71d658fd08a4 Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 12:09:40 +0800 Subject: [PATCH 03/23] Regression: FTP Table with "'" in Table name --- .../Draw/3-Draw-Limit-USD-150-300-201012.txt | Bin 0 -> 3192 bytes .../3-Draw-Limit-USD-150-300-201012.txt.hands | 32 ++ .../3-Draw-Limit-USD-150-300-201012.txt.hp | 470 ++++++++++++++++++ 3 files changed, 502 insertions(+) create mode 100644 pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt create mode 100644 pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hands create mode 100644 pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hp diff --git a/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt b/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt new file mode 100644 index 0000000000000000000000000000000000000000..5a6ebd86d475faa9156a1caca783d8dfd6292fb6 GIT binary patch literal 3192 zcmd^BTTc@~6h6-;{)bH<0gMK^+jc2$go;S;Mr(*^c<2pj>@DpIn)ut*?>lG5Zaag8 z;G5aZ?9A?*`*+TqUq6rKs|@i((v$(-8CLIQB44C0Gpt`pTSiz%vLUflB+ zIGN(zghm6I{*mMOl1~Y=2TE^qBrkE^c*Xe6|GSuD%-lbfC(?kvZIw_0E$tp+|6MIF zVZRNXs`6aQpesS+Wtv!NPW1F7KV8D<6z5a#bmB=!a+)$|YARy~s|Xg-Yjd?d!#tMH z*iR6rY(;~z$FrRCtbx-$p2X9m;?Y!c8tM@Tb+39fj3d31fTjvL)m+ZP8&haJhsLxe zlWRrBTw`x&BU)%%5C11}g?STRtEh#=IMAXHuMVi`mk=LA6rFH?X$9JXcpr%NTMd1#^b07Cd>4_XoAFtX^nJ z7hht`m!6f30ntp&`nk`@$K?d&6}>|LhtHQan^w;g%~#ND2z}-%eWB~}_o5W~{_ekb z>s-}5T-AX(cVQ#rPgJS2p{2$3!|L~Tt@qXufuZ_6@z%cPc&knz4lL|!Rp-B3e0SrVr}{S42KEge5x8Aq##aQLI8;v(p20Gq_E), + 'street0Raises': 3, + 'street1Pot': 0, + 'street1Raises': 1, + 'street2Pot': 0, + 'street2Raises': 2, + 'street3Pot': 0, + 'street3Raises': 0, + 'street4Pot': 0, + 'street4Raises': 0, + 'tableName': u"David's Draw", + 'texture': None, + 'tourneyId': None} diff --git a/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hp b/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hp new file mode 100644 index 00000000..583521f6 --- /dev/null +++ b/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hp @@ -0,0 +1,470 @@ +{ u'Hero': { 'card1': 0, + 'card2': 0, + 'card3': 0, + 'card4': 0, + 'card5': 0, + 'card6': 0, + 'card7': 0, + 'foldBbToStealChance': False, + 'foldSbToStealChance': False, + 'foldToOtherRaisedStreet0': False, + 'foldToOtherRaisedStreet1': False, + 'foldToOtherRaisedStreet2': False, + 'foldToOtherRaisedStreet3': False, + 'foldToOtherRaisedStreet4': False, + 'foldToStreet1CBChance': False, + 'foldToStreet1CBDone': False, + 'foldToStreet2CBChance': False, + 'foldToStreet2CBDone': False, + 'foldToStreet3CBChance': False, + 'foldToStreet3CBDone': False, + 'foldToStreet4CBChance': False, + 'foldToStreet4CBDone': False, + 'foldedBbToSteal': False, + 'foldedSbToSteal': False, + 'other3BStreet0': False, + 'other4BStreet0': False, + 'otherRaisedStreet0': False, + 'otherRaisedStreet1': False, + 'otherRaisedStreet2': False, + 'otherRaisedStreet3': False, + 'otherRaisedStreet4': False, + 'position': 'S', + 'raiseFirstInChance': False, + 'raisedFirstIn': False, + 'rake': 0, + 'sawShowdown': False, + 'seatNo': 2, + 'sitout': False, + 'startCards': 0, + 'startCash': 174700, + 'street0Aggr': False, + 'street0Bets': 0, + 'street0Calls': 0, + 'street0Raises': 0, + 'street0VPI': False, + 'street0_3BChance': False, + 'street0_3BDone': False, + 'street0_4BChance': True, + 'street0_4BDone': False, + 'street1Aggr': False, + 'street1Bets': 0, + 'street1CBChance': False, + 'street1CBDone': False, + 'street1Calls': 0, + 'street1CheckCallRaiseChance': False, + 'street1CheckCallRaiseDone': False, + 'street1Raises': 0, + 'street1Seen': False, + 'street2Aggr': False, + 'street2Bets': 0, + 'street2CBChance': False, + 'street2CBDone': False, + 'street2Calls': 0, + 'street2CheckCallRaiseChance': False, + 'street2CheckCallRaiseDone': False, + 'street2Raises': 0, + 'street2Seen': False, + 'street3Aggr': False, + 'street3Bets': 0, + 'street3CBChance': False, + 'street3CBDone': False, + 'street3Calls': 0, + 'street3CheckCallRaiseChance': False, + 'street3CheckCallRaiseDone': False, + 'street3Raises': 0, + 'street3Seen': False, + 'street4Aggr': False, + 'street4Bets': 0, + 'street4CBChance': False, + 'street4CBDone': False, + 'street4Calls': 0, + 'street4CheckCallRaiseChance': False, + 'street4CheckCallRaiseDone': False, + 'street4Raises': 0, + 'street4Seen': False, + 'totalProfit': -7500, + 'tourneyTypeId': None, + 'tourneysPlayersIds': None, + 'winnings': 0, + 'wonAtSD': 0.0, + 'wonWhenSeenStreet1': 0.0, + 'wonWhenSeenStreet2': 0.0, + 'wonWhenSeenStreet3': 0.0, + 'wonWhenSeenStreet4': 0.0}, + u'Player1': { 'card1': 0, + 'card2': 0, + 'card3': 0, + 'card4': 0, + 'card5': 0, + 'card6': 0, + 'card7': 0, + 'foldBbToStealChance': False, + 'foldSbToStealChance': False, + 'foldToOtherRaisedStreet0': False, + 'foldToOtherRaisedStreet1': False, + 'foldToOtherRaisedStreet2': False, + 'foldToOtherRaisedStreet3': False, + 'foldToOtherRaisedStreet4': False, + 'foldToStreet1CBChance': False, + 'foldToStreet1CBDone': False, + 'foldToStreet2CBChance': False, + 'foldToStreet2CBDone': False, + 'foldToStreet3CBChance': False, + 'foldToStreet3CBDone': False, + 'foldToStreet4CBChance': False, + 'foldToStreet4CBDone': False, + 'foldedBbToSteal': False, + 'foldedSbToSteal': False, + 'other3BStreet0': False, + 'other4BStreet0': False, + 'otherRaisedStreet0': False, + 'otherRaisedStreet1': False, + 'otherRaisedStreet2': False, + 'otherRaisedStreet3': False, + 'otherRaisedStreet4': False, + 'position': 0, + 'raiseFirstInChance': False, + 'raisedFirstIn': False, + 'rake': 0, + 'sawShowdown': False, + 'seatNo': 1, + 'sitout': False, + 'startCards': 0, + 'startCash': 641100, + 'street0Aggr': False, + 'street0Bets': 0, + 'street0Calls': 0, + 'street0Raises': 0, + 'street0VPI': False, + 'street0_3BChance': False, + 'street0_3BDone': False, + 'street0_4BChance': True, + 'street0_4BDone': False, + 'street1Aggr': False, + 'street1Bets': 0, + 'street1CBChance': False, + 'street1CBDone': False, + 'street1Calls': 0, + 'street1CheckCallRaiseChance': False, + 'street1CheckCallRaiseDone': False, + 'street1Raises': 0, + 'street1Seen': False, + 'street2Aggr': False, + 'street2Bets': 0, + 'street2CBChance': False, + 'street2CBDone': False, + 'street2Calls': 0, + 'street2CheckCallRaiseChance': False, + 'street2CheckCallRaiseDone': False, + 'street2Raises': 0, + 'street2Seen': False, + 'street3Aggr': False, + 'street3Bets': 0, + 'street3CBChance': False, + 'street3CBDone': False, + 'street3Calls': 0, + 'street3CheckCallRaiseChance': False, + 'street3CheckCallRaiseDone': False, + 'street3Raises': 0, + 'street3Seen': False, + 'street4Aggr': False, + 'street4Bets': 0, + 'street4CBChance': False, + 'street4CBDone': False, + 'street4Calls': 0, + 'street4CheckCallRaiseChance': False, + 'street4CheckCallRaiseDone': False, + 'street4Raises': 0, + 'street4Seen': False, + 'totalProfit': 0, + 'tourneyTypeId': None, + 'tourneysPlayersIds': None, + 'winnings': 0, + 'wonAtSD': 0.0, + 'wonWhenSeenStreet1': 0.0, + 'wonWhenSeenStreet2': 0.0, + 'wonWhenSeenStreet3': 0.0, + 'wonWhenSeenStreet4': 0.0}, + u'Player4': { 'card1': 0, + 'card2': 0, + 'card3': 0, + 'card4': 0, + 'card5': 0, + 'card6': 0, + 'card7': 0, + 'foldBbToStealChance': False, + 'foldSbToStealChance': False, + 'foldToOtherRaisedStreet0': False, + 'foldToOtherRaisedStreet1': False, + 'foldToOtherRaisedStreet2': False, + 'foldToOtherRaisedStreet3': False, + 'foldToOtherRaisedStreet4': False, + 'foldToStreet1CBChance': False, + 'foldToStreet1CBDone': False, + 'foldToStreet2CBChance': False, + 'foldToStreet2CBDone': False, + 'foldToStreet3CBChance': False, + 'foldToStreet3CBDone': False, + 'foldToStreet4CBChance': False, + 'foldToStreet4CBDone': False, + 'foldedBbToSteal': False, + 'foldedSbToSteal': False, + 'other3BStreet0': False, + 'other4BStreet0': False, + 'otherRaisedStreet0': False, + 'otherRaisedStreet1': False, + 'otherRaisedStreet2': False, + 'otherRaisedStreet3': False, + 'otherRaisedStreet4': False, + 'position': 'B', + 'raiseFirstInChance': False, + 'raisedFirstIn': False, + 'rake': 0, + 'sawShowdown': False, + 'seatNo': 4, + 'sitout': False, + 'startCards': 0, + 'startCash': 988300, + 'street0Aggr': False, + 'street0Bets': 0, + 'street0Calls': 0, + 'street0Raises': 0, + 'street0VPI': False, + 'street0_3BChance': False, + 'street0_3BDone': False, + 'street0_4BChance': True, + 'street0_4BDone': False, + 'street1Aggr': False, + 'street1Bets': 0, + 'street1CBChance': False, + 'street1CBDone': False, + 'street1Calls': 0, + 'street1CheckCallRaiseChance': False, + 'street1CheckCallRaiseDone': False, + 'street1Raises': 0, + 'street1Seen': False, + 'street2Aggr': False, + 'street2Bets': 0, + 'street2CBChance': False, + 'street2CBDone': False, + 'street2Calls': 0, + 'street2CheckCallRaiseChance': False, + 'street2CheckCallRaiseDone': False, + 'street2Raises': 0, + 'street2Seen': False, + 'street3Aggr': False, + 'street3Bets': 0, + 'street3CBChance': False, + 'street3CBDone': False, + 'street3Calls': 0, + 'street3CheckCallRaiseChance': False, + 'street3CheckCallRaiseDone': False, + 'street3Raises': 0, + 'street3Seen': False, + 'street4Aggr': False, + 'street4Bets': 0, + 'street4CBChance': False, + 'street4CBDone': False, + 'street4Calls': 0, + 'street4CheckCallRaiseChance': False, + 'street4CheckCallRaiseDone': False, + 'street4Raises': 0, + 'street4Seen': False, + 'totalProfit': -15000, + 'tourneyTypeId': None, + 'tourneysPlayersIds': None, + 'winnings': 0, + 'wonAtSD': 0.0, + 'wonWhenSeenStreet1': 0.0, + 'wonWhenSeenStreet2': 0.0, + 'wonWhenSeenStreet3': 0.0, + 'wonWhenSeenStreet4': 0.0}, + u'Player5': { 'card1': 0, + 'card2': 0, + 'card3': 0, + 'card4': 0, + 'card5': 0, + 'card6': 0, + 'card7': 0, + 'foldBbToStealChance': False, + 'foldSbToStealChance': False, + 'foldToOtherRaisedStreet0': False, + 'foldToOtherRaisedStreet1': False, + 'foldToOtherRaisedStreet2': False, + 'foldToOtherRaisedStreet3': False, + 'foldToOtherRaisedStreet4': False, + 'foldToStreet1CBChance': False, + 'foldToStreet1CBDone': False, + 'foldToStreet2CBChance': False, + 'foldToStreet2CBDone': False, + 'foldToStreet3CBChance': False, + 'foldToStreet3CBDone': False, + 'foldToStreet4CBChance': False, + 'foldToStreet4CBDone': False, + 'foldedBbToSteal': False, + 'foldedSbToSteal': False, + 'other3BStreet0': False, + 'other4BStreet0': False, + 'otherRaisedStreet0': False, + 'otherRaisedStreet1': False, + 'otherRaisedStreet2': True, + 'otherRaisedStreet3': False, + 'otherRaisedStreet4': False, + 'position': 2, + 'raiseFirstInChance': True, + 'raisedFirstIn': True, + 'rake': 0, + 'sawShowdown': True, + 'seatNo': 5, + 'sitout': False, + 'startCards': 0, + 'startCash': 424700, + 'street0Aggr': True, + 'street0Bets': 0, + 'street0Calls': 0, + 'street0Raises': 0, + 'street0VPI': True, + 'street0_3BChance': False, + 'street0_3BDone': False, + 'street0_4BChance': True, + 'street0_4BDone': True, + 'street1Aggr': True, + 'street1Bets': 1, + 'street1CBChance': True, + 'street1CBDone': True, + 'street1Calls': 0, + 'street1CheckCallRaiseChance': False, + 'street1CheckCallRaiseDone': False, + 'street1Raises': 0, + 'street1Seen': True, + 'street2Aggr': True, + 'street2Bets': 1, + 'street2CBChance': True, + 'street2CBDone': True, + 'street2Calls': 1, + 'street2CheckCallRaiseChance': False, + 'street2CheckCallRaiseDone': False, + 'street2Raises': 0, + 'street2Seen': True, + 'street3Aggr': False, + 'street3Bets': 0, + 'street3CBChance': False, + 'street3CBDone': False, + 'street3Calls': 0, + 'street3CheckCallRaiseChance': False, + 'street3CheckCallRaiseDone': False, + 'street3Raises': 0, + 'street3Seen': True, + 'street4Aggr': False, + 'street4Bets': 0, + 'street4CBChance': False, + 'street4CBDone': False, + 'street4Calls': 0, + 'street4CheckCallRaiseChance': False, + 'street4CheckCallRaiseDone': False, + 'street4Raises': 0, + 'street4Seen': False, + 'totalProfit': -135000, + 'tourneyTypeId': None, + 'tourneysPlayersIds': None, + 'winnings': 0, + 'wonAtSD': 0.0, + 'wonWhenSeenStreet1': 0.0, + 'wonWhenSeenStreet2': 0.0, + 'wonWhenSeenStreet3': 0.0, + 'wonWhenSeenStreet4': 0.0}, + u'Player6': { 'card1': 0, + 'card2': 0, + 'card3': 0, + 'card4': 0, + 'card5': 0, + 'card6': 0, + 'card7': 0, + 'foldBbToStealChance': False, + 'foldSbToStealChance': False, + 'foldToOtherRaisedStreet0': False, + 'foldToOtherRaisedStreet1': False, + 'foldToOtherRaisedStreet2': False, + 'foldToOtherRaisedStreet3': False, + 'foldToOtherRaisedStreet4': False, + 'foldToStreet1CBChance': False, + 'foldToStreet1CBDone': False, + 'foldToStreet2CBChance': False, + 'foldToStreet2CBDone': False, + 'foldToStreet3CBChance': False, + 'foldToStreet3CBDone': False, + 'foldToStreet4CBChance': False, + 'foldToStreet4CBDone': False, + 'foldedBbToSteal': False, + 'foldedSbToSteal': False, + 'other3BStreet0': False, + 'other4BStreet0': False, + 'otherRaisedStreet0': False, + 'otherRaisedStreet1': True, + 'otherRaisedStreet2': True, + 'otherRaisedStreet3': False, + 'otherRaisedStreet4': False, + 'position': 1, + 'raiseFirstInChance': False, + 'raisedFirstIn': False, + 'rake': 300, + 'sawShowdown': True, + 'seatNo': 6, + 'sitout': False, + 'startCards': 0, + 'startCash': 368600, + 'street0Aggr': True, + 'street0Bets': 0, + 'street0Calls': 1, + 'street0Raises': 0, + 'street0VPI': True, + 'street0_3BChance': True, + 'street0_3BDone': True, + 'street0_4BChance': False, + 'street0_4BDone': False, + 'street1Aggr': False, + 'street1Bets': 0, + 'street1CBChance': False, + 'street1CBDone': False, + 'street1Calls': 1, + 'street1CheckCallRaiseChance': False, + 'street1CheckCallRaiseDone': False, + 'street1Raises': 0, + 'street1Seen': True, + 'street2Aggr': True, + 'street2Bets': 0, + 'street2CBChance': False, + 'street2CBDone': False, + 'street2Calls': 0, + 'street2CheckCallRaiseChance': False, + 'street2CheckCallRaiseDone': False, + 'street2Raises': 0, + 'street2Seen': True, + 'street3Aggr': False, + 'street3Bets': 0, + 'street3CBChance': True, + 'street3CBDone': False, + 'street3Calls': 0, + 'street3CheckCallRaiseChance': False, + 'street3CheckCallRaiseDone': False, + 'street3Raises': 0, + 'street3Seen': True, + 'street4Aggr': False, + 'street4Bets': 0, + 'street4CBChance': False, + 'street4CBDone': False, + 'street4Calls': 0, + 'street4CheckCallRaiseChance': False, + 'street4CheckCallRaiseDone': False, + 'street4Raises': 0, + 'street4Seen': False, + 'totalProfit': 157200, + 'tourneyTypeId': None, + 'tourneysPlayersIds': None, + 'winnings': 292200, + 'wonAtSD': 1.0, + 'wonWhenSeenStreet1': 1.0, + 'wonWhenSeenStreet2': 1.0, + 'wonWhenSeenStreet3': 1.0, + 'wonWhenSeenStreet4': 0.0}} From 69a67f5c831c4af34d9e0a68a603236df09d38fe Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 12:29:20 +0800 Subject: [PATCH 04/23] FTP: Make apostrophe a valid tablename character --- pyfpdb/FulltiltToFpdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 487cb12d..44cc9fbe 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -37,7 +37,7 @@ class Fulltilt(HandHistoryConverter): substitutions = { 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes 'LS' : u"\$|\u20AC|\xe2\x82\xac|", # legal currency symbols - Euro(cp1252, utf-8) - 'TAB' : u"-\u2013\s\da-zA-Z" + 'TAB' : u"-\u2013'\s\da-zA-Z" } # Static regexes From 02b39285811ea7c38bb50982f4602ab9702de184 Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 12:40:45 +0800 Subject: [PATCH 05/23] Fix .hands file: s//pytz.utc/ --- .../cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hands | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hands b/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hands index 1849b499..438c0b92 100644 --- a/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hands +++ b/pyfpdb/regression-test-files/cash/FTP/Draw/3-Draw-Limit-USD-150-300-201012.txt.hands @@ -17,7 +17,7 @@ 'seats': 5, 'showdownPot': 0, 'siteHandNo': u'25325990000', - 'startTime': datetime.datetime(2010, 12, 20, 15, 0, tzinfo=), + 'startTime': datetime.datetime(2010, 12, 20, 15, 0, tzinfo=pytz.utc), 'street0Raises': 3, 'street1Pot': 0, 'street1Raises': 1, From d97be04066458dd6845a3d48bcca36b846a34dcd Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 13:18:05 +0800 Subject: [PATCH 06/23] FTP: Change the way the number format is dealt with Rather than define [.,0-9] multiple times thoughout the regexes, add it to the substitutions section. Passes existing regression suite. --- pyfpdb/FulltiltToFpdb.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 44cc9fbe..1ea80f4d 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -37,7 +37,8 @@ class Fulltilt(HandHistoryConverter): substitutions = { 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes 'LS' : u"\$|\u20AC|\xe2\x82\xac|", # legal currency symbols - Euro(cp1252, utf-8) - 'TAB' : u"-\u2013'\s\da-zA-Z" + 'TAB' : u"-\u2013'\s\da-zA-Z", # legal characters for tablename + 'NUM' : u".,\d", # legal characters in number format } # Static regexes @@ -45,10 +46,10 @@ class Fulltilt(HandHistoryConverter): (?:(?P.+)\s\((?P\d+)\),\s)? .+ -\s(?P[%(LS)s]|)? - (?P[.0-9]+)/ - [%(LS)s]?(?P[.0-9]+)\s - (Ante\s\$?(?P[.0-9]+)\s)?-\s - [%(LS)s]?(?P[.0-9]+\sCap\s)? + (?P[%(NUM)s]+)/ + [%(LS)s]?(?P[%(NUM)s]+)\s + (Ante\s\$?(?P[%(NUM)s]+)\s)?-\s + [%(LS)s]?(?P[%(NUM)s]+\sCap\s)? (?P(No\sLimit|Pot\sLimit|Limit))?\s (?P(Hold\'em|Omaha\sHi|Omaha\sH/L|7\sCard\sStud|Stud\sH/L|Razz|Stud\sHi|2-7\sTriple\sDraw|5\sCard\sDraw|Badugi)) ''' % substitutions, re.VERBOSE) @@ -60,7 +61,7 @@ class Fulltilt(HandHistoryConverter): (?PPlay\sChip\s|PC)? (?P[%(TAB)s]+)\s (\((?P.+)\)\s)?-\s - [%(LS)s]?(?P[.0-9]+)/[%(LS)s]?(?P[.0-9]+)\s(Ante\s[%(LS)s]?(?P[.0-9]+)\s)?-\s + [%(LS)s]?(?P[%(NUM)s]+)/[%(LS)s]?(?P[%(NUM)s]+)\s(Ante\s[%(LS)s]?(?P[.0-9]+)\s)?-\s [%(LS)s]?(?P[.0-9]+\sCap\s)? (?P[-\da-zA-Z\/\'\s]+)\s-\s (?P.*$) @@ -140,16 +141,16 @@ class Fulltilt(HandHistoryConverter): self.substitutions['PLAYERS'] = player_re logging.debug("player_re: " + player_re) - self.re_PostSB = re.compile(r"^%(PLAYERS)s posts the small blind of [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_PostDead = re.compile(r"^%(PLAYERS)s posts a dead small blind of [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_PostBB = re.compile(r"^%(PLAYERS)s posts (the big blind of )?[%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_Antes = re.compile(r"^%(PLAYERS)s antes [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_BringIn = re.compile(r"^%(PLAYERS)s brings in for [%(LS)s]?(?P[.0-9]+)" % self.substitutions, re.MULTILINE) - self.re_PostBoth = re.compile(r"^%(PLAYERS)s posts small \& big blinds \[[%(LS)s]? (?P[.0-9]+)" % self.substitutions, re.MULTILINE) + self.re_PostSB = re.compile(r"^%(PLAYERS)s posts the small blind of [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_PostDead = re.compile(r"^%(PLAYERS)s posts a dead small blind of [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_PostBB = re.compile(r"^%(PLAYERS)s posts (the big blind of )?[%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_Antes = re.compile(r"^%(PLAYERS)s antes [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_BringIn = re.compile(r"^%(PLAYERS)s brings in for [%(LS)s]?(?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) + self.re_PostBoth = re.compile(r"^%(PLAYERS)s posts small \& big blinds \[[%(LS)s]? (?P[%(NUM)s]+)" % self.substitutions, re.MULTILINE) self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P.+?)\])?( \[(?P.+?)\])" % player_re, re.MULTILINE) - self.re_Action = re.compile(r"^%(PLAYERS)s(?P bets| checks| raises to| completes it to| calls| folds)( [%(LS)s]?(?P[.,\d]+))?" % self.substitutions, re.MULTILINE) + self.re_Action = re.compile(r"^%(PLAYERS)s(?P bets| checks| raises to| completes it to| calls| folds)( [%(LS)s]?(?P[%(NUM)s]+))?" % self.substitutions, re.MULTILINE) self.re_ShowdownAction = re.compile(r"^%s shows \[(?P.*)\]" % player_re, re.MULTILINE) - self.re_CollectPot = re.compile(r"^Seat (?P[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P[.,\d]+)\)(, mucked| with.*)" % self.substitutions, re.MULTILINE) + self.re_CollectPot = re.compile(r"^Seat (?P[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P[%(NUM)s]+)\)(, mucked| with.*)" % self.substitutions, re.MULTILINE) self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE) self.re_ShownCards = re.compile(r"^Seat (?P[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(?Pshowed|mucked) \[(?P.*)\].*" % player_re, re.MULTILINE) From 0b02b05f6768735d2577c042dfdc98e071c479fd Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 14:00:09 +0800 Subject: [PATCH 07/23] HHC, Party: Move clearMoneyString into HHC Make clearMoneyString available to all parsers and fix all calls within Party --- pyfpdb/HandHistoryConverter.py | 5 +++++ pyfpdb/PartyPokerToFpdb.py | 20 ++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index 62383beb..34760664 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -675,6 +675,11 @@ or None if we fail to get the info """ # PokerStars: WCOOP 2nd Chance 02: $1,050 NLHE - Tournament 307521826 Table 1 - Blinds $30/$60 return "%s.+Table (\d+)" % (tournament, ) + @staticmethod + def clearMoneyString(money): + "Renders 'numbers' like '1 200' and '2,000'" + return money.replace(' ', '').replace(',', '') + def getTableTitleRe(config, sitename, *args, **kwargs): "Returns string to search in windows titles for current site" return getSiteHhc(config, sitename).getTableTitleRe(*args, **kwargs) diff --git a/pyfpdb/PartyPokerToFpdb.py b/pyfpdb/PartyPokerToFpdb.py index a9321c63..c1f33295 100755 --- a/pyfpdb/PartyPokerToFpdb.py +++ b/pyfpdb/PartyPokerToFpdb.py @@ -240,8 +240,8 @@ class PartyPoker(HandHistoryConverter): info['sb'] = "%.2f" % (sb) info['currency'] = self.currencies[mg['CURRENCY']] else: - info['sb'] = clearMoneyString(mg['SB']) - info['bb'] = clearMoneyString(mg['BB']) + info['sb'] = self.clearMoneyString(mg['SB']) + info['bb'] = self.clearMoneyString(mg['BB']) info['currency'] = 'T$' return info @@ -361,10 +361,10 @@ class PartyPoker(HandHistoryConverter): if a.group('CASH') > '0': #record max known stack for use with players with unknown stack maxKnownStack = max(a.group('CASH'),maxKnownStack) - hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), clearMoneyString(a.group('CASH'))) + hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), self.clearMoneyString(a.group('CASH'))) else: #zero stacked players are added later - zeroStackPlayers.append([int(a.group('SEAT')), a.group('PNAME'), clearMoneyString(a.group('CASH'))]) + zeroStackPlayers.append([int(a.group('SEAT')), a.group('PNAME'), self.clearMoneyString(a.group('CASH'))]) if hand.gametype['type'] == 'ring': #finds first vacant seat after an exact seat def findFirstEmptySeat(startSeat): @@ -384,7 +384,7 @@ class PartyPoker(HandHistoryConverter): #if a zero stacked player is just joined the table in this very hand then set his stack to maxKnownStack for p in zeroStackPlayers: if p[1] in match_JoiningPlayers: - p[2] = clearMoneyString(maxKnownStack) + p[2] = self.clearMoneyString(maxKnownStack) hand.addPlayer(p[0],p[1],p[2]) seatedPlayers = list([(f[1]) for f in hand.players]) @@ -401,7 +401,7 @@ class PartyPoker(HandHistoryConverter): occupiedSeats = list([(f[0]) for f in hand.players]) occupiedSeats.sort() newPlayerSeat = findFirstEmptySeat(previousBBPosterSeat) - hand.addPlayer(newPlayerSeat,player,clearMoneyString(maxKnownStack)) + hand.addPlayer(newPlayerSeat,player,self.clearMoneyString(maxKnownStack)) def markStreets(self, hand): m = re.search( @@ -491,7 +491,7 @@ class PartyPoker(HandHistoryConverter): for action in m: acts = action.groupdict() playerName = action.group('PNAME') - amount = clearMoneyString(action.group('BET')) if action.group('BET') else None + amount = self.clearMoneyString(action.group('BET')) if action.group('BET') else None actionType = action.group('ATYPE') if actionType == 'is all-In': @@ -530,7 +530,7 @@ class PartyPoker(HandHistoryConverter): def readCollectPot(self,hand): for m in self.re_CollectPot.finditer(hand.handText): - hand.addCollectPot(player=m.group('PNAME'),pot=clearMoneyString(m.group('POT'))) + hand.addCollectPot(player=m.group('PNAME'),pot=self.clearMoneyString(m.group('POT'))) def readShownCards(self,hand): for m in self.re_ShownCards.finditer(hand.handText): @@ -554,10 +554,6 @@ class PartyPoker(HandHistoryConverter): else: return table_name -def clearMoneyString(money): - "Renders 'numbers' like '1 200' and '2,000'" - return money.replace(' ', '').replace(',', '') - def renderCards(string): "Splits strings like ' Js, 4d '" cards = string.strip().split(' ') From c979c172d872ee573a282713435dfa6468f37108 Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 14:25:58 +0800 Subject: [PATCH 08/23] FTP: Make FTP use clearMoneyString() FTP Summary files have a slightly different format than those written my the client. Also convert all tourney string munging to clearMoneyString --- pyfpdb/FulltiltToFpdb.py | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 1ea80f4d..955b55b9 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -207,8 +207,8 @@ class Fulltilt(HandHistoryConverter): info['limitType'] = 'cn' else: info['limitType'] = limits[mg['LIMIT']] - info['sb'] = mg['SB'] - info['bb'] = mg['BB'] + info['sb'] = self.clearMoneyString(mg['SB']) + info['bb'] = self.clearMoneyString(mg['BB']) if mg['GAME'] is not None: (info['base'], info['category']) = games[mg['GAME']] if mg['CURRENCY'] is not None: @@ -340,15 +340,15 @@ class Fulltilt(HandHistoryConverter): def readBlinds(self, hand): try: m = self.re_PostSB.search(hand.handText) - hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB')) + hand.addBlind(m.group('PNAME'), 'small blind', self.clearMoneyString(m.group('SB'))) except: # no small blind hand.addBlind(None, None, None) for a in self.re_PostDead.finditer(hand.handText): - hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB')) + hand.addBlind(a.group('PNAME'), 'secondsb', self.clearMoneyString(a.group('SB'))) for a in self.re_PostBB.finditer(hand.handText): - hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB')) + hand.addBlind(a.group('PNAME'), 'big blind', self.clearMoneyString(a.group('BB'))) for a in self.re_PostBoth.finditer(hand.handText): - hand.addBlind(a.group('PNAME'), 'small & big blinds', a.group('SBBB')) + hand.addBlind(a.group('PNAME'), 'small & big blinds', self.clearMoneyString(a.group('SBBB'))) def readAntes(self, hand): logging.debug(_("reading antes")) @@ -529,10 +529,10 @@ class Fulltilt(HandHistoryConverter): # Additional info can be stored in the tourney object if mg['BUYIN'] is not None: - tourney.buyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.buyin = 100*Decimal(self.clearMoneyString(mg['BUYIN'])) tourney.fee = 0 if mg['FEE'] is not None: - tourney.fee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + tourney.fee = 100*Decimal(self.clearMoneyString(mg['FEE'])) if mg['TOURNAMENT_NAME'] is not None: # Tournament Name can have a trailing space at the end (depending on the tournament description) tourney.tourneyName = mg['TOURNAMENT_NAME'].rstrip() @@ -576,25 +576,25 @@ class Fulltilt(HandHistoryConverter): mg = m.groupdict() if tourney.isMatrix : if mg['BUYIN'] is not None: - tourney.subTourneyBuyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.subTourneyBuyin = 100*Decimal(self.clearMoneyString(mg['BUYIN'])) tourney.subTourneyFee = 0 if mg['FEE'] is not None: - tourney.subTourneyFee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + tourney.subTourneyFee = 100*Decimal(self.clearMoneyString(mg['FEE'])) else : if mg['BUYIN'] is not None: if tourney.buyin is None: - tourney.buyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.buyin = 100*Decimal(clearMoneyString(mg['BUYIN'])) else : - if 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) != tourney.buyin: + if 100*Decimal(clearMoneyString(mg['BUYIN'])) != tourney.buyin: log.error(_("Conflict between buyins read in topline (%s) and in BuyIn field (%s)") % (tourney.buyin, 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN']))) ) - tourney.subTourneyBuyin = 100*Decimal(re.sub(u',', u'', "%s" % mg['BUYIN'])) + tourney.subTourneyBuyin = 100*Decimal(clearMoneyString(mg['BUYIN'])) if mg['FEE'] is not None: if tourney.fee is None: - tourney.fee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + tourney.fee = 100*Decimal(clearMoneyString(mg['FEE'])) else : - if 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) != tourney.fee: - log.error(_("Conflict between fees read in topline (%s) and in BuyIn field (%s)") % (tourney.fee, 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE']))) ) - tourney.subTourneyFee = 100*Decimal(re.sub(u',', u'', "%s" % mg['FEE'])) + if 100*Decimal(clearMoneyString(mg['FEE'])) != tourney.fee: + log.error(_("Conflict between fees read in topline (%s) and in BuyIn field (%s)") % (tourney.fee, 100*Decimal(clearMoneyString(mg['FEE']))) ) + tourney.subTourneyFee = 100*Decimal(clearMoneyString(mg['FEE'])) if tourney.buyin is None: log.info(_("Unable to affect a buyin to this tournament : assume it's a freeroll")) @@ -663,10 +663,10 @@ class Fulltilt(HandHistoryConverter): tourney.koCounts.update( { tourney.hero : Decimal(mg['COUNT_KO']) } ) # Deal with money amounts - tourney.koBounty = 100*Decimal(re.sub(u',', u'', "%s" % tourney.koBounty)) - tourney.prizepool = 100*Decimal(re.sub(u',', u'', "%s" % tourney.prizepool)) - tourney.rebuyCost = 100*Decimal(re.sub(u',', u'', "%s" % tourney.rebuyCost)) - tourney.addOnCost = 100*Decimal(re.sub(u',', u'', "%s" % tourney.addOnCost)) + tourney.koBounty = 100*Decimal(clearMoneyString(tourney.koBounty)) + tourney.prizepool = 100*Decimal(clearMoneyString(tourney.prizepool)) + tourney.rebuyCost = 100*Decimal(clearMoneyString(tourney.rebuyCost)) + tourney.addOnCost = 100*Decimal(clearMoneyString(tourney.addOnCost)) # Calculate payin amounts and update winnings -- not possible to take into account nb of rebuys, addons or Knockouts for other players than hero on FTP for p in tourney.players : @@ -692,7 +692,7 @@ class Fulltilt(HandHistoryConverter): rank = Decimal(a.group('RANK')) if a.group('WINNING') is not None: - winnings = 100*Decimal(re.sub(u',', u'', "%s" % a.group('WINNING'))) + winnings = 100*Decimal(clearMoneyString(a.group('WINNING'))) else: winnings = "0" From e705188dd2adf61565c77060ec62b9bc312e6433 Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 14:32:32 +0800 Subject: [PATCH 09/23] HUD_Config.text.xml: Add MySQL option --- pyfpdb/HUD_config.test.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyfpdb/HUD_config.test.xml b/pyfpdb/HUD_config.test.xml index cfad09c5..7ce84651 100644 --- a/pyfpdb/HUD_config.test.xml +++ b/pyfpdb/HUD_config.test.xml @@ -581,6 +581,7 @@ Left-Drag to Move" + From b39637866c6e03effd8768edc1a3ec747159900e Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 15:21:43 +0800 Subject: [PATCH 10/23] Database: Fix MySQL crasher Tablename with an odd .fr character caused the insert in Hands to fail Resolves: http://sourceforge.net/apps/mantisbt/fpdb/view.php?id=60 --- pyfpdb/Database.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 943479cd..89d3d630 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -1699,6 +1699,10 @@ class Database: pp = pprint.PrettyPrinter(indent=4) pp.pprint(p) print _("###### End Hands ########") + + # Tablename can have odd charachers + p['tableName'] = Charset.to_db_utf8(p['tableName']) + #stores into table hands: q = self.sql.query['store_hand'] From 8339ad1da67b0de6402c40cbc3d8bf33cee77650 Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 20 Dec 2010 15:57:15 +0800 Subject: [PATCH 11/23] Winamax: Reduce size of tourney hids The max size of a MySQL unsigned bigint is 9223372036854775808 Winamax hand.handid was a lot larger than that. Reduce the size if the nummber is 19 digits long. --- pyfpdb/WinamaxToFpdb.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyfpdb/WinamaxToFpdb.py b/pyfpdb/WinamaxToFpdb.py index 47721515..c6b49c4c 100644 --- a/pyfpdb/WinamaxToFpdb.py +++ b/pyfpdb/WinamaxToFpdb.py @@ -222,6 +222,8 @@ class Winamax(HandHistoryConverter): if key == 'HID1': # Need to remove non-alphanumerics for MySQL hand.handid = "1%.9d%s%s"%(int(info['HID2']),info['HID1'],info['HID3']) + if len (hand.handid) > 19: + hand.handid = "%s" % info['HID1'] if key == 'TOURNO': hand.tourNo = info[key] if key == 'TABLE': From 6d3e21756db88ecf73f86cda918130f7fcb2ce07 Mon Sep 17 00:00:00 2001 From: "chaz@pokeit.co" Date: Mon, 20 Dec 2010 07:02:00 -0500 Subject: [PATCH 12/23] * Commented out BB won in sessionsCache for the time being. Will add it back in once I resolve the errors. --- pyfpdb/Database.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 89d3d630..ac33cfc9 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -2094,7 +2094,7 @@ class Database: if (game['type']=='ring'): line[0] = 1 # count ring hands if (game['type']=='tour'): line[1] = 1 # count tour hands if (game['type']=='ring'): line[2] = pdata[p]['totalProfit'] #sum of profit - if (game['type']=='ring'): line[3] = float(Decimal(pdata[p]['totalProfit'])/Decimal(bigBet)) #sum of big bets won + if (game['type']=='ring'): line[3] = 0 #float(Decimal(pdata[p]['totalProfit'])/Decimal(bigBet)) #sum of big bets won line[4] = startTime inserts.append(line) From 797c126318b0658aa936343cb312ae93392f1a17 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 22 Dec 2010 11:26:58 +0800 Subject: [PATCH 13/23] Database: Disable alchemy pools Want to use DBAPIs connection.row_factory so we can select() directly into a dict --- pyfpdb/Database.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 89d3d630..ec6b299e 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -60,11 +60,14 @@ import Configuration # Other library modules try: import sqlalchemy.pool as pool - use_pool = True + #use_pool = True + # Forcing to False so we can use connection.row_factory + use_pool = False except ImportError: log.info(_("Not using sqlalchemy connection pool.")) use_pool = False + try: from numpy import var use_numpy = True @@ -446,7 +449,8 @@ class Database: self.db_path = database log.info(_("Connecting to SQLite: %(database)s") % {'database':self.db_path}) if os.path.exists(database) or create: - self.connection = sqlite3.connect(self.db_path, detect_types=sqlite3.PARSE_DECLTYPES ) + self.connection = sqlite3.connect(self.db_path, detect_types=sqlite3.PARSE_DECLTYPES) + self.connection.row_factory = sqlite3.Row self.__connected = True sqlite3.register_converter("bool", lambda x: bool(int(x))) sqlite3.register_adapter(bool, lambda x: "1" if x else "0") From a9c0593eb56f97b7aa7d4c8a75b7c4646cfe2adc Mon Sep 17 00:00:00 2001 From: Mika Bostrom Date: Wed, 22 Dec 2010 06:02:02 +0200 Subject: [PATCH 14/23] Demote postgres/mysql to suggestions For most users we only need to depend on sqlite bindings anyway. --- packaging/debian/control | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packaging/debian/control b/packaging/debian/control index c510e1c8..945b741e 100644 --- a/packaging/debian/control +++ b/packaging/debian/control @@ -11,9 +11,8 @@ Section: games Priority: extra Depends: ${python:Depends}, python-gtk2, python-matplotlib, python-support, python-xlib, - mysql-server | postgresql | python-pysqlite2, - python-psycopg2 | python-mysqldb -Suggests: wine + python-pysqlite2 +Suggests: wine, postgresql | mysql-server, python-psycopg2 | python-mysqldb Description: free poker database with HUD FPDB is a statistics tool for online poker. It supports most sites and several games. Most prominent feature is its heads-up display From 10fc52e96fc99ed70fd16db6f2133ecab02157d8 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 22 Dec 2010 12:13:58 +0800 Subject: [PATCH 15/23] Hand: First pass at select() for Hand --- pyfpdb/Hand.py | 164 ++++++++++++++++++++++++++----------------------- 1 file changed, 87 insertions(+), 77 deletions(-) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 10f15f57..28dc6bc5 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -289,99 +289,109 @@ db: a connected Database object""" hp.seatno, round(hp.winnings / 100.0,2) as winnings, p.name, - round(hp.startcash / 100.0,2) as chips, - hp.card1,hp.card2, + round(hp.startCash / 100.0,2) as chips, + hp.card1,hp.card2,hp.card3,hp.card4, hp.position FROM HandsPlayers as hp, Players as p WHERE hp.handId = %s - and p.id = hp.playerid + and p.id = hp.playerId """ q = q.replace('%s', db.sql.query['placeholder']) # PlayerStacks c.execute(q, (handId,)) - for (seat, winnings, name, chips, card1,card2, position) in c.fetchall(): - print "DEBUG: seat: '%s'\tname: '%s'\tchips: '%s'" % (seat, name, chips) + for (seat, winnings, name, chips, card1, card2, card3, card4, position) in c.fetchall(): self.addPlayer(seat,name,str(chips)) - #if card1 and card2: - # self.addHoleCards(map(Card.valueSuitFromCard, (card1,card2)), name, dealt=True) - #if winnings > 0: - # self.addCollectPot(name, winnings) - #if position == 'B': - # self.buttonpos = seat + cardlist = map(Card.valueSuitFromCard, [card1, card2, card3, card4]) + cardlist = [card1, card2, card3, card4] + self.addHoleCards('PREFLOP', name, closed=cardlist, shown=False, mucked=False, dealt=True) + if winnings > 0: + self.addCollectPot(name, str(winnings)) + if position == 'B': + self.buttonpos = seat - # HandInfo : HID, TABLE - # BUTTON - why is this treated specially in Hand? - # answer: it is written out in hand histories - # still, I think we should record all the active seat positions in a seat_order array - #c.execute("""SELECT - # h.sitehandno as hid, - # h.tablename as table, - # h.startTime as startTime - # FROM - # Hands as h - # WHERE h.id = %(handid)s - # """, {'handid':handid}) - #res = c.fetchone() - #h.handid = res[0] - #h.tablename = res[1] - #h.startTime = res[2] # automatically a datetime + # HandInfo + q = """SELECT * + FROM Hands + WHERE id = %s + """ + q = q.replace('%s', db.sql.query['placeholder']) + c.execute(q, (handId,)) + + # NOTE: This relies on row_factory = sqlite3.Row (set in connect() params) + # Need to find MySQL and Postgres equivalents + # MySQL maybe: cursorclass=MySQLdb.cursors.DictCursor + res = c.fetchone() + self.tablename = res['tableName'] + self.startTime = res['startTime'] # automatically a datetime + #res['tourneyId'] + #gametypeId + #res['importTime'] # Don't really care about this + #res['seats'] + self.maxseats = res['maxSeats'] + #res['rush'] + cards = map(Card.valueSuitFromCard, [res['boardcard1'], res['boardcard2'], res['boardcard3'], res['boardcard4'], res['boardcard5']]) + if cards[0]: + self.setCommunityCards('FLOP', cards[0:3]) + if cards[3]: + self.setCommunityCards('TURN', [cards[3]]) + if cards[4]: + self.setCommunityCards('RIVER', [cards[4]]) + # playersVpi | playersAtStreet1 | playersAtStreet2 | playersAtStreet3 | + # playersAtStreet4 | playersAtShowdown | street0Raises | street1Raises | + # street2Raises | street3Raises | street4Raises | street1Pot | street2Pot | + # street3Pot | street4Pot | showdownPot | comment | commentTs | texture - #cards = map(Card.valueSuitFromCard, res[11:16] ) - #if cards[0]: - # h.setCommunityCards('FLOP', cards[0:3]) - #if cards[3]: - # h.setCommunityCards('TURN', [cards[3]]) - #if cards[4]: - # h.setCommunityCards('RIVER', [cards[4]]) - #[Card.valueSuitFromCard(x) for x in cards] - - - # actions - #c.execute("""SELECT - # (ha.street,ha.actionno) as actnum, - # p.name, - # ha.street, - # ha.action, - # ha.allin, - # round(ha.amount / 100.0,2) - # FROM - # handsplayers as hp, - # handsactions as ha, - # players as p - # WHERE - # hp.handid = %(handid)s - # and ha.handsplayerid = hp.id - # and p.id = hp.playerid - # ORDER BY - # ha.street,ha.actionno - # """, {'handid':handid}) - #res = c.fetchall() - #for (actnum,player, streetnum, act, allin, amount) in res: - # act=act.strip() - # street = h.allStreets[streetnum+1] - # if act==u'blind': - # h.addBlind(player, 'big blind', amount) - # # TODO: The type of blind is not recorded in the DB. - # # TODO: preflop street name anomalies in Hand - # elif act==u'fold': - # h.addFold(street,player) - # elif act==u'call': - # h.addCall(street,player,amount) - # elif act==u'bet': - # h.addBet(street,player,amount) - # elif act==u'check': - # h.addCheck(street,player) - # elif act==u'unbet': - # pass - # else: - # print act, player, streetnum, allin, amount - # # TODO : other actions + # Actions + q = """SELECT + ha.actionNo, + p.name, + ha.street, + ha.actionId, + ha.allIn, + round(ha.amount / 100.0,2) as bet + FROM + HandsActions as ha, + HandsPlayers as hp, + Players as p, + Hands as h + WHERE + h.id = %s + and ha.handsPlayerId = hp.id + and hp.playerId = p.id + AND h.id = hp.handId + ORDER BY + ha.id ASC +; """ + q = q.replace('%s', db.sql.query['placeholder']) + c.execute(q, (handId,)) + for row in c.fetchall(): + name = row['name'] + street = row['street'] + act = row['actionId'] + # allin True/False if row['allIn'] == 0 + bet = row['bet'] + print "DEBUG: name: '%s' street: '%s' act: '%s' bet: '%s'" %(name, street, act, bet) + street = self.allStreets[int(street)+1] + if act == 2: # Small Blind + self.addBlind(name, 'small blind', str(bet)) + elif act == 4: # Big Blind + self.addBlind(name, 'big blind', str(bet)) + elif act == 6: # Call + self.addCall(street, name, str(bet)) + elif act == 8: # Bet + self.addBet(street, name, str(bet)) + elif act == 10: # Fold + self.addFold(street, name) + elif act == 11: # Check + self.addCheck(street, name) + else: + print "DEBUG: unknown action: '%s'" % act #hhc.readShowdownActions(self) #hc.readShownCards(self) From f31d0cbfc8f9d11e45e564b8d840dc0a10b2296c Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 22 Dec 2010 13:03:45 +0800 Subject: [PATCH 16/23] Replayer: Switch over to Hand.select() --- pyfpdb/GuiReplayer.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyfpdb/GuiReplayer.py b/pyfpdb/GuiReplayer.py index ba5a985e..c91d0410 100644 --- a/pyfpdb/GuiReplayer.py +++ b/pyfpdb/GuiReplayer.py @@ -249,7 +249,7 @@ class GuiReplayer: be replaced by a function to select a hand from the db in the not so distant future. This code has been shamelessly stolen from Carl """ - if True: + if False: settings = {} settings.update(self.conf.get_db_parameters()) settings.update(self.conf.get_import_parameters()) @@ -276,7 +276,7 @@ class GuiReplayer: # for the Hand.__init__ ####### Shift this section in Database.py for all to use ###### - handid = 40 + handid = 2 q = self.sql.query['get_gameinfo_from_hid'] q = q.replace('%s', self.sql.query['placeholder']) @@ -295,6 +295,7 @@ class GuiReplayer: print "DEBUG: Create stud hand here" elif gametype['base'] == 'draw': print "DEBUG: Create draw hand here" + return h def temp(self): pass From 9cff165c3c0ad7fc64049bcb3d44c3995ebcb49f Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 22 Dec 2010 13:04:20 +0800 Subject: [PATCH 17/23] Hand: select() updates Fix SQL for seat order Fix startTime formating Add lots of commented out debug --- pyfpdb/Hand.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 28dc6bc5..28b67416 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -298,15 +298,20 @@ db: a connected Database object""" WHERE hp.handId = %s and p.id = hp.playerId + ORDER BY + hp.seatno """ q = q.replace('%s', db.sql.query['placeholder']) # PlayerStacks c.execute(q, (handId,)) for (seat, winnings, name, chips, card1, card2, card3, card4, position) in c.fetchall(): + #print "DEBUG: addPlayer(%s, %s, %s)" %(seat,name,str(chips)) self.addPlayer(seat,name,str(chips)) + #print "DEBUG: card1: %s" % card1 cardlist = map(Card.valueSuitFromCard, [card1, card2, card3, card4]) cardlist = [card1, card2, card3, card4] + #print "DEUBG: cardlist: '%s'" % cardlist self.addHoleCards('PREFLOP', name, closed=cardlist, shown=False, mucked=False, dealt=True) if winnings > 0: self.addCollectPot(name, str(winnings)) @@ -327,7 +332,8 @@ db: a connected Database object""" # MySQL maybe: cursorclass=MySQLdb.cursors.DictCursor res = c.fetchone() self.tablename = res['tableName'] - self.startTime = res['startTime'] # automatically a datetime + self.handid = res['siteHandNo'] + self.startTime = datetime.datetime.strptime(res['startTime'], "%Y-%m-%d %H:%M:%S+00:00") #res['tourneyId'] #gametypeId #res['importTime'] # Don't really care about this @@ -335,6 +341,8 @@ db: a connected Database object""" self.maxseats = res['maxSeats'] #res['rush'] cards = map(Card.valueSuitFromCard, [res['boardcard1'], res['boardcard2'], res['boardcard3'], res['boardcard4'], res['boardcard5']]) + #print "DEBUG: res['boardcard1']: %s" % res['boardcard1'] + #print "DEBUG: cards: %s" % cards if cards[0]: self.setCommunityCards('FLOP', cards[0:3]) if cards[3]: @@ -376,9 +384,10 @@ db: a connected Database object""" act = row['actionId'] # allin True/False if row['allIn'] == 0 bet = row['bet'] - print "DEBUG: name: '%s' street: '%s' act: '%s' bet: '%s'" %(name, street, act, bet) street = self.allStreets[int(street)+1] + #print "DEBUG: name: '%s' street: '%s' act: '%s' bet: '%s'" %(name, street, act, bet) if act == 2: # Small Blind + print "DEBUG: addBlind(%s, 'small blind', %s" %(name, str(bet)) self.addBlind(name, 'small blind', str(bet)) elif act == 4: # Big Blind self.addBlind(name, 'big blind', str(bet)) @@ -393,6 +402,9 @@ db: a connected Database object""" else: print "DEBUG: unknown action: '%s'" % act + #print self + #self.writeHand() + #hhc.readShowdownActions(self) #hc.readShownCards(self) #h.totalPot() From d94f7a68a231abc13af1e34de6cd147dbef7bf71 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 22 Dec 2010 13:08:41 +0800 Subject: [PATCH 18/23] Hand: Fix for stack print in writeHand --- pyfpdb/Hand.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 28b67416..68c87425 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -403,7 +403,7 @@ db: a connected Database object""" print "DEBUG: unknown action: '%s'" % act #print self - #self.writeHand() + self.writeHand() #hhc.readShowdownActions(self) #hc.readShownCards(self) @@ -1002,7 +1002,7 @@ class HoldemOmahaHand(Hand): log.debug(self.actions['PREFLOP']) for player in [x for x in self.players if x[1] in players_who_act_preflop]: #Only print stacks of players who do something preflop - print >>fh, ("Seat %s: %s ($%s in chips) " %(player[0], player[1], player[2])) + print >>fh, ("Seat %s: %s ($%.2f in chips) " %(player[0], player[1], float(player[2]))) if self.actions['BLINDSANTES']: for act in self.actions['BLINDSANTES']: From 2382152cb83c589b5f288cf855aec8a564aa7f8f Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 22 Dec 2010 13:20:43 +0800 Subject: [PATCH 19/23] Hand: select() update - Fix holecards for holdem --- pyfpdb/Hand.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 68c87425..f61f0765 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -309,10 +309,16 @@ db: a connected Database object""" #print "DEBUG: addPlayer(%s, %s, %s)" %(seat,name,str(chips)) self.addPlayer(seat,name,str(chips)) #print "DEBUG: card1: %s" % card1 - cardlist = map(Card.valueSuitFromCard, [card1, card2, card3, card4]) - cardlist = [card1, card2, card3, card4] + # map() should work, but is returning integers... FIXME later + #cardlist = map(Card.valueSuitFromCard, [card1, card2, card3, card4]) + cardlist = [Card.valueSuitFromCard(card1), Card.valueSuitFromCard(card2), Card.valueSuitFromCard(card3), Card.valueSuitFromCard(card4)] #print "DEUBG: cardlist: '%s'" % cardlist - self.addHoleCards('PREFLOP', name, closed=cardlist, shown=False, mucked=False, dealt=True) + if cardlist[0] == '': + pass + elif self.gametype['category'] == 'holdem': + self.addHoleCards('PREFLOP', name, closed=cardlist[0:2], shown=False, mucked=False, dealt=True) + elif self.gametype['category'] == 'omaha': + self.addHoleCards('PREFLOP', name, closed=cardlist, shown=False, mucked=False, dealt=True) if winnings > 0: self.addCollectPot(name, str(winnings)) if position == 'B': From 6487691b695ba127e41e98137e451b4cded0c8e4 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 22 Dec 2010 13:26:41 +0800 Subject: [PATCH 20/23] Hand: Add pot calculations to select() --- pyfpdb/Hand.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index f61f0765..405a56e5 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -408,13 +408,12 @@ db: a connected Database object""" else: print "DEBUG: unknown action: '%s'" % act - #print self + self.totalPot() + self.rake = self.totalpot - self.totalcollected self.writeHand() #hhc.readShowdownActions(self) #hc.readShownCards(self) - #h.totalPot() - #h.rake = h.totalpot - h.totalcollected def addPlayer(self, seat, name, chips): From fc836ea9022cdbb5edfb1318e3b83fbd58a1f706 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 23 Dec 2010 12:40:22 +0800 Subject: [PATCH 21/23] Replayer: Move table hash creation into a class Add several other classes too --- pyfpdb/GuiReplayer.py | 77 +++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/pyfpdb/GuiReplayer.py b/pyfpdb/GuiReplayer.py index c91d0410..86646cf2 100644 --- a/pyfpdb/GuiReplayer.py +++ b/pyfpdb/GuiReplayer.py @@ -100,7 +100,10 @@ class GuiReplayer: self.replayBox.pack_start(self.area) + gobject.timeout_add(1000,self.draw_action) + self.MyHand = self.importhand() + self.table = Table(self.area, self.MyHand).table self.maxseats=self.MyHand.maxseats @@ -109,21 +112,6 @@ class GuiReplayer: elif self.MyHand.gametype['currency']=="EUR": self.currency="€" - - self.table={} #create table with positions, player names, status (live/folded), stacks and chips on table - for i in range(0,self.maxseats): # radius: 200, center: 250,250 - x= int (round(250+200*math.cos(2*i*math.pi/self.maxseats))) - y= int (round(250+200*math.sin(2*i*math.pi/self.maxseats))) - try: - self.table[i]={"name":self.MyHand.players[i][1],"stack":Decimal(self.MyHand.players[i][2]),"x":x,"y":y,"chips":0,"status":"live"} #save coordinates of each player - try: - self.table[i]['holecards']=self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][1]+' '+self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][2] - print "holecards: ",self.table[i]['holecards'] - except: - self.table[i]['holecards']='' - except IndexError: #if seat is empty - print "seat ",i+1," out of ",self.maxseats," empty" - self.actions=[] #create list with all actions if isinstance(self.MyHand, HoldemOmahaHand): @@ -133,7 +121,6 @@ class GuiReplayer: self.action_number=0 self.action_level=0 self.pot=0 - gobject.timeout_add(1000,self.draw_action) def area_expose(self, area, event): @@ -276,7 +263,7 @@ class GuiReplayer: # for the Hand.__init__ ####### Shift this section in Database.py for all to use ###### - handid = 2 + handid = 1 q = self.sql.query['get_gameinfo_from_hid'] q = q.replace('%s', self.sql.query['placeholder']) @@ -300,6 +287,62 @@ class GuiReplayer: def temp(self): pass +class Table: + def __init__(self, darea, hand): + self.darea = darea + self.hand = hand + #self.pixmap = gtk.gdk.Pixmap(darea, width, height, depth=-1) + + self.table = {} + for i in range(0, hand.maxseats): # radius: 200, center: 250,250 + x= int (round(250+200*math.cos(2*i*math.pi/hand.maxseats))) + y= int (round(250+200*math.sin(2*i*math.pi/hand.maxseats))) + try: + self.table[i]={"name":self.hand.players[i][1],"stack":Decimal(self.hand.players[i][2]),"x":x,"y":y,"chips":0,"status":"live"} #save coordinates of each player + try: + self.table[i]['holecards']=self.hand.holecards["PREFLOP"][self.hand.players[i][1]][1]+' '+self.hand.holecards["PREFLOP"][self.hand.players[i][1]][2] + print "holecards: ",self.table[i]['holecards'] + except: + self.table[i]['holecards']='' + except IndexError: #if seat is empty + print "seat ",i+1," out of ", hand.maxseats," empty" + + print "DEBUG: table: %s" % self.table + + def draw(self): + draw_players() + draw_pot() + draw_community_cards() + +class Player: + def __init__(self, name, stack, position): + self.active = True + self.stack = stack + self.position = position + self.name = name + x = 0 + y = 0 + + def draw(self): + draw_name() + draw_stack() + draw_cards() + +class Pot: + def __init__(self, hand): + self.total = 0.0 + + def draw(self): + pass + +class CommunityCards: + def __init__(self, hand): + self.pixbuf = self.gen_pixbuf_from_file(PATH_TO_THE_FILE) + + def draw(self): + pass + + def main(argv=None): """main can also be called in the python interpreter, by supplying the command line as the argument.""" if argv is None: From 18ccea9a6751dffda914bf5dbc7b2bc67231796d Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 23 Dec 2010 14:18:27 +0800 Subject: [PATCH 22/23] fpdb_import: Correct mainline print --- pyfpdb/fpdb_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 15043503..ba1251ac 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -624,4 +624,4 @@ class ProgressBar: if __name__ == "__main__": - print _("CLI for fpdb_import is now available as CliFpdb.py") + print _("CLI for importing hands is GuiBulkImport.py") From 54264bb2631bd4bff73909c2054fe646458f50b7 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 23 Dec 2010 15:26:28 +0800 Subject: [PATCH 23/23] Replayer: Refactor player code into its own class --- pyfpdb/GuiReplayer.py | 52 +++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/pyfpdb/GuiReplayer.py b/pyfpdb/GuiReplayer.py index 86646cf2..720a17c4 100644 --- a/pyfpdb/GuiReplayer.py +++ b/pyfpdb/GuiReplayer.py @@ -31,6 +31,9 @@ import gtk import math import gobject +import pprint +pp = pprint.PrettyPrinter(indent=4) + class GuiReplayer: def __init__(self, config, querylist, mainwin, options = None, debug=True): @@ -105,8 +108,6 @@ class GuiReplayer: self.MyHand = self.importhand() self.table = Table(self.area, self.MyHand).table - self.maxseats=self.MyHand.maxseats - if self.MyHand.gametype['currency']=="USD": #TODO: check if there are others .. self.currency="$" elif self.MyHand.gametype['currency']=="EUR": @@ -291,23 +292,18 @@ class Table: def __init__(self, darea, hand): self.darea = darea self.hand = hand + self.players = [] #self.pixmap = gtk.gdk.Pixmap(darea, width, height, depth=-1) + # tmp var while refactoring self.table = {} - for i in range(0, hand.maxseats): # radius: 200, center: 250,250 - x= int (round(250+200*math.cos(2*i*math.pi/hand.maxseats))) - y= int (round(250+200*math.sin(2*i*math.pi/hand.maxseats))) - try: - self.table[i]={"name":self.hand.players[i][1],"stack":Decimal(self.hand.players[i][2]),"x":x,"y":y,"chips":0,"status":"live"} #save coordinates of each player - try: - self.table[i]['holecards']=self.hand.holecards["PREFLOP"][self.hand.players[i][1]][1]+' '+self.hand.holecards["PREFLOP"][self.hand.players[i][1]][2] - print "holecards: ",self.table[i]['holecards'] - except: - self.table[i]['holecards']='' - except IndexError: #if seat is empty - print "seat ",i+1," out of ", hand.maxseats," empty" + i = 0 + for seat, name, chips in hand.players: + self.players.append(Player(hand, name, chips, seat)) + self.table[i] = self.players[i].get_hash() + i += 1 - print "DEBUG: table: %s" % self.table + pp.pprint(self.table) def draw(self): draw_players() @@ -315,13 +311,25 @@ class Table: draw_community_cards() class Player: - def __init__(self, name, stack, position): - self.active = True - self.stack = stack - self.position = position - self.name = name - x = 0 - y = 0 + def __init__(self, hand, name, stack, seat): + self.status = 'live' + self.stack = Decimal(stack) + self.chips = 0 + self.seat = seat + self.name = name + self.holecards = hand.join_holecards(name) + self.x = int (round(250+200*math.cos(2*self.seat*math.pi/hand.maxseats))) + self.y = int (round(250+200*math.sin(2*self.seat*math.pi/hand.maxseats))) + + def get_hash(self): + return { 'chips': 0, + 'holecards': self.holecards, + 'name': self.name, + 'stack': self.stack, + 'status': self.status, + 'x': self.x, + 'y': self.y, + } def draw(self): draw_name()