Merge branch 'master' of git://git.assembla.com/fpdboz.git

This commit is contained in:
Gerko de Roo 2010-08-01 13:29:08 +02:00
commit 0c3c8a3805
22 changed files with 510 additions and 949 deletions

View File

@ -1,3 +1,34 @@
free-poker-tools (0.20.902-1) unstable; urgency=low
* New snapshot release; .901 was broken for FTP
-- Mika Bostrom <bostik@iki.fi> Sat, 24 Jul 2010 09:05:57 +0300
free-poker-tools (0.20.901-1) unstable; urgency=low
* Snapshot release before oncoming 0.21
-- Mika Bostrom <bostik@iki.fi> Thu, 22 Jul 2010 23:32:47 +0300
free-poker-tools (0.20.1-1) unstable; urgency=low
* 0.20.1 release
-- Mika Bostrom <bostik@iki.fi> Thu, 22 Jul 2010 08:47:39 +0300
free-poker-tools (0.20-2) unstable; urgency=low
* Fix executable script shebangs: there is no /usr/bin/python2 (nor
/usr/bin/python3) symlink on Debian or Ubuntu
-- Mika Bostrom <bostik+fpdb@bostik.iki.fi> Thu, 08 Jul 2010 21:29:40 +0300
free-poker-tools (0.20-1) unstable; urgency=low
* 0.20 release
-- Mika Bostrom <bostik+fpdb@bostik.iki.fi> Thu, 08 Jul 2010 11:25:36 +0300
free-poker-tools (0.20~git20100630) unstable; urgency=low free-poker-tools (0.20~git20100630) unstable; urgency=low
* Snapshot release * Snapshot release

View File

@ -10,7 +10,7 @@ NEED_PYTHON=2.5
DESCRIPTION="A free/open source tracker/HUD for use with online poker" DESCRIPTION="A free/open source tracker/HUD for use with online poker"
HOMEPAGE="http://fpdb.wiki.sourceforge.net/" HOMEPAGE="http://fpdb.wiki.sourceforge.net/"
SRC_URI="mirror://sourceforge/${PN}/${PV}/${P}.tar.gz" SRC_URI="mirror://sourceforge/${PN}/${PV}/${P}.tar.bz2"
LICENSE="AGPL-3" LICENSE="AGPL-3"
SLOT="0" SLOT="0"
@ -29,7 +29,8 @@ RDEPEND="
dev-python/pygtk dev-python/pygtk
graph? ( dev-python/numpy graph? ( dev-python/numpy
dev-python/matplotlib[gtk] ) dev-python/matplotlib[gtk] )
dev-python/python-xlib" dev-python/python-xlib
dev-python/pytz"
DEPEND="${RDEPEND}" DEPEND="${RDEPEND}"
src_install() { src_install() {
@ -53,9 +54,7 @@ src_install() {
pkg_postinst() { pkg_postinst() {
games_pkg_postinst games_pkg_postinst
echo elog "Note that if you really want to use mysql or postgresql you will have to create"
elog "Note that if you really want to use mysql or postgresql you will have to create" elog "the database and user yourself and enter it into the fpdb config."
elog "the database and user yourself and enter it into the fpdb config."
elog "You can find the instructions on the project's website." elog "You can find the instructions on the project's website."
echo
} }

View File

@ -1,57 +0,0 @@
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# created by Steffen Schaumburg, steffen@schaumburger.info
EAPI="2"
NEED_PYTHON=2.5
#inherit distutils
DESCRIPTION="A database program to track your online poker games"
HOMEPAGE="http://fpdb.sourceforge.net/"
#SRC_URI="mirror://sourceforge/fpdb/${MY_P}.tar.bz2"
LICENSE="AGPL-3"
SLOT="0"
KEYWORDS="~amd64 ~x86"
#note: this should work on other architectures too, please send me your experiences
IUSE="graphing mysql postgres sqlite"
RDEPEND="
mysql? ( virtual/mysql
dev-python/mysql-python )
postgres? ( dev-db/postgresql-server
dev-python/psycopg )
sqlite? ( dev-lang/python[sqlite]
dev-python/numpy )
>=x11-libs/gtk+-2.10
dev-python/pygtk
graphing? ( dev-python/numpy
dev-python/matplotlib[gtk] )
dev-python/python-xlib"
DEPEND="${RDEPEND}"
#src_install() {
# DIRINST="${D}usr/share/games/fpdb/"
# mkdir -p "${DIRINST}"
# cp -R * "${DIRINST}" || die
#
# DIRBIN="${D}usr/games/bin/"
# mkdir -p "${DIRBIN}"
# #echo "pathes"
# #echo "${DIRINST}pyfpdb/fpdb.py"
# #echo "${DIRBIN}fpdb.py"
# #echo
# echo "cd /usr/share/games/fpdb/pyfpdb/ && python fpdb.py" > "${DIRBIN}fpdb" || die
# chmod 755 "${DIRBIN}fpdb" || die
#}
#src_test() {
#}
pkg_postinst() {
elog "Fpdb's dependencies have been installed. Please visit fpdb.sourceforge.net"
elog "and download and unpack the archive.You can then start fpdb by running run_fpdb.py."
elog "Note that if you really want to use mysql or postgresql you will have to create"
elog "the database and user yourself and enter it into the fpdb config."
}

View File

@ -1,59 +0,0 @@
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# created by Steffen Schaumburg, steffen@schaumburger.info
EAPI="2"
NEED_PYTHON=2.5
DESCRIPTION="Fpdb is a free/open source tracker/HUD for use with online poker"
HOMEPAGE="http://fpdb.wiki.sourceforge.net/"
SRC_URI="mirror://sourceforge/${PN}/${PV}/${P}.tar.gz"
LICENSE="AGPL-3"
SLOT="0"
KEYWORDS="~amd64 ~x86"
#note: this should work on other architectures too, please send me your experiences
IUSE="graphing mysql postgres sqlite"
RDEPEND="
mysql? ( virtual/mysql
dev-python/mysql-python )
postgres? ( dev-db/postgresql-server
dev-python/psycopg )
sqlite? ( dev-lang/python[sqlite]
dev-python/numpy )
>=x11-libs/gtk+-2.10
dev-python/pygtk
graphing? ( dev-python/numpy
dev-python/matplotlib[gtk] )
dev-python/python-xlib"
DEPEND="${RDEPEND}"
src_install() {
dodir /usr/share/games/fpdb
exeinto /usr/share/games/fpdb
doexe run_fpdb.py
dosym /usr/share/games/fpdb/run_fpdb.py /usr/bin/fpdb
insinto /usr/share/games/fpdb
doins readme.txt
insinto /usr/share/games/fpdb/files
doins files/*
insinto /usr/share/games/fpdb/gfx
doins gfx/*
insinto /usr/share/games/fpdb/pyfpdb
doins pyfpdb/*
# pyfpdb/regression-test-files dir is missing for now; cp -r ??
}
pkg_postinst() {
elog "Note that if you really want to use mysql or postgresql you will have to create"
elog "the database and user yourself and enter it into the fpdb config."
elog "You can find the instructions on the project's website."
}

View File

@ -0,0 +1,2 @@
To use the ebuild please simply copy it into your local portage tree and rename it to fpdb-version.ebuild, for example fpdb-0.20.1.ebuild or fpdb-0.20.902.ebuild.
Here's a little howto on how to utilise 3rd party ebuilds such as this one: http://www.gentoo-wiki.info/HOWTO_Installing_3rd_Party_Ebuilds

View File

@ -42,10 +42,10 @@ class Absolute(HandHistoryConverter):
#Seat 6 - FETS63 ($0.75 in chips) #Seat 6 - FETS63 ($0.75 in chips)
#Board [10s 5d Kh Qh 8c] #Board [10s 5d Kh Qh 8c]
re_GameInfo = re.compile(ur"^Stage #([0-9]+): (?P<GAME>Holdem|HORSE)(?: \(1 on 1\)|)? ?(?P<LIMIT>No Limit|Pot Limit|Normal|)? ?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/?(?:\$| €|)(?P<BB>[.0-9]+)?", re.MULTILINE) re_GameInfo = re.compile(ur"^Stage #(C?[0-9]+): (?P<GAME>Holdem|HORSE)(?: \(1 on 1\)|)? ?(?P<LIMIT>No Limit|Pot Limit|Normal|)? ?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/?(?:\$| €|)(?P<BB>[.0-9]+)?", re.MULTILINE)
re_HorseGameInfo = re.compile(ur"^Game Type: (?P<LIMIT>Limit) (?P<GAME>Holdem)", re.MULTILINE) re_HorseGameInfo = re.compile(ur"^Game Type: (?P<LIMIT>Limit) (?P<GAME>Holdem)", re.MULTILINE)
# TODO: can set max seats via (1 on 1) to a known 2 .. # TODO: can set max seats via (1 on 1) to a known 2 ..
re_HandInfo = re.compile(ur"^Stage #(?P<HID>[0-9]+): .*(?P<DATETIME>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).*\n(Table: (?P<TABLE>.*) \(Real Money\))?", re.MULTILINE) re_HandInfo = re.compile(ur"^Stage #C?(?P<HID>[0-9]+): .*(?P<DATETIME>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).*\n(Table: (?P<TABLE>.*) \(Real Money\))?", re.MULTILINE)
re_TableFromFilename = re.compile(ur".*IHH([0-9]+) (?P<TABLE>.*) -") # on HORSE STUD games, the table name isn't in the hand info! re_TableFromFilename = re.compile(ur".*IHH([0-9]+) (?P<TABLE>.*) -") # on HORSE STUD games, the table name isn't in the hand info!
re_Button = re.compile(ur"Seat #(?P<BUTTON>[0-9]) is the ?[dead]* dealer$", re.MULTILINE) # TODO: that's not the right way to match for "dead" dealer is it? re_Button = re.compile(ur"Seat #(?P<BUTTON>[0-9]) is the ?[dead]* dealer$", re.MULTILINE) # TODO: that's not the right way to match for "dead" dealer is it?
re_PlayerInfo = re.compile(ur"^Seat (?P<SEAT>[0-9]) - (?P<PNAME>.*) \((?:\$| €|)(?P<CASH>[0-9]*[.0-9]+) in chips\)", re.MULTILINE) re_PlayerInfo = re.compile(ur"^Seat (?P<SEAT>[0-9]) - (?P<PNAME>.*) \((?:\$| €|)(?P<CASH>[0-9]*[.0-9]+) in chips\)", re.MULTILINE)
@ -96,17 +96,18 @@ class Absolute(HandHistoryConverter):
def determineGameType(self, handText): def determineGameType(self, handText):
"""return dict with keys/values: """return dict with keys/values:
'type' in ('ring', 'tour') 'type' in ('ring', 'tour')
'limitType' in ('nl', 'cn', 'pl', 'cp', 'fl') 'limitType' in ('nl', 'cn', 'pl', 'cp', 'fl')
'base' in ('hold', 'stud', 'draw') 'base' in ('hold', 'stud', 'draw')
'category' in ('holdem', 'omahahi', omahahilo', 'razz', 'studhi', 'studhilo', 'fivedraw', '27_1draw', '27_3draw', 'badugi') 'category' in ('holdem', 'omahahi', omahahilo', 'razz', 'studhi', 'studhilo', 'fivedraw', '27_1draw', '27_3draw', 'badugi')
'hilo' in ('h','l','s') 'hilo' in ('h','l','s')
'smallBlind' int? 'smallBlind' int?
'bigBlind' int? 'bigBlind' int?
'smallBet' 'smallBet'
'bigBet' 'bigBet'
'currency' in ('USD', 'EUR', 'T$', <countrycode>) 'currency' in ('USD', 'EUR', 'T$', <countrycode>)
or None if we fail to get the info """
or None if we fail to get the info """
info = {'type':'ring'} info = {'type':'ring'}
m = self.re_GameInfo.search(handText) m = self.re_GameInfo.search(handText)
@ -329,6 +330,9 @@ def validCard(card):
return card return card
if __name__ == "__main__": if __name__ == "__main__":
import Configuration
config = Configuration.Config(None)
parser = OptionParser() parser = OptionParser()
parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="-") parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="-")
parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-") parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-")
@ -345,5 +349,5 @@ if __name__ == "__main__":
LOG_FILENAME = './logging.out' LOG_FILENAME = './logging.out'
logging.basicConfig(filename=LOG_FILENAME,level=options.verbosity) logging.basicConfig(filename=LOG_FILENAME,level=options.verbosity)
e = Absolute(in_path = options.ipath, out_path = options.opath, follow = options.follow, autostart=True, debugging=True) e = Absolute(config, in_path = options.ipath, out_path = options.opath, follow = options.follow, autostart=True)

View File

@ -52,8 +52,13 @@ def get_default_config_path():
if os.name == 'posix': if os.name == 'posix':
config_path = os.path.join(os.path.expanduser("~"), '.fpdb') config_path = os.path.join(os.path.expanduser("~"), '.fpdb')
elif os.name == 'nt': elif os.name == 'nt':
config_path = os.path.join(os.environ["APPDATA"], 'fpdb') config_path = os.path.join(unicode(os.environ[u"APPDATA"], "latin-1"), u"fpdb")
#print u"path after joining in get_default_config_path:",config_path
else: config_path = False else: config_path = False
try: os.mkdir(config_path)
except: pass
return config_path return config_path
def get_exec_path(): def get_exec_path():
@ -110,7 +115,7 @@ def get_logger(file_name, config = "config", fallback = False, log_dir=None, log
(conf_file,copied) = get_config(file_name, fallback = fallback) (conf_file,copied) = get_config(file_name, fallback = fallback)
if log_dir is None: if log_dir is None:
log_dir = os.path.join(get_exec_path(), 'log') log_dir = os.path.join(get_exec_path(), u'log')
#print "\nget_logger: checking log_dir:", log_dir #print "\nget_logger: checking log_dir:", log_dir
check_dir(log_dir) check_dir(log_dir)
if log_file is None: if log_file is None:
@ -147,7 +152,7 @@ def check_dir(path, create = True):
msg = "Creating directory: '%s'" % (path) msg = "Creating directory: '%s'" % (path)
print msg print msg
log.info(msg) log.info(msg)
os.mkdir(path) os.mkdir(path)#, "utf-8"))
else: else:
return False return False
@ -520,9 +525,9 @@ class Config:
self.dir_self = get_exec_path() self.dir_self = get_exec_path()
# self.dir_config = os.path.dirname(self.file) # self.dir_config = os.path.dirname(self.file)
self.dir_config = get_default_config_path() self.dir_config = get_default_config_path()
self.dir_log = os.path.join(self.dir_config, 'log') self.dir_log = os.path.join(self.dir_config, u'log')
self.dir_database = os.path.join(self.dir_config, 'database') self.dir_database = os.path.join(self.dir_config, u'database')
self.log_file = os.path.join(self.dir_log, 'fpdb-log.txt') self.log_file = os.path.join(self.dir_log, u'fpdb-log.txt')
log = get_logger("logging.conf", "config", log_dir=self.dir_log) log = get_logger("logging.conf", "config", log_dir=self.dir_log)
# Parse even if there was no real config file found and we are using the example # Parse even if there was no real config file found and we are using the example

View File

@ -74,7 +74,7 @@ except ImportError:
use_numpy = False use_numpy = False
DB_VERSION = 137 DB_VERSION = 139
# Variance created as sqlite has a bunch of undefined aggregate functions. # Variance created as sqlite has a bunch of undefined aggregate functions.
@ -1651,8 +1651,8 @@ class Database:
pdata[p]['foldToOtherRaisedStreet2'], pdata[p]['foldToOtherRaisedStreet2'],
pdata[p]['foldToOtherRaisedStreet3'], pdata[p]['foldToOtherRaisedStreet3'],
pdata[p]['foldToOtherRaisedStreet4'], pdata[p]['foldToOtherRaisedStreet4'],
pdata[p]['stealAttemptChance'], pdata[p]['raiseFirstInChance'],
pdata[p]['stealAttempted'], pdata[p]['raisedFirstIn'],
pdata[p]['foldBbToStealChance'], pdata[p]['foldBbToStealChance'],
pdata[p]['foldedBbToSteal'], pdata[p]['foldedBbToSteal'],
pdata[p]['foldSbToStealChance'], pdata[p]['foldSbToStealChance'],
@ -1732,8 +1732,8 @@ class Database:
if pdata[p]['foldToOtherRaisedStreet4']: line[21] = 1 if pdata[p]['foldToOtherRaisedStreet4']: line[21] = 1
line[22] = pdata[p]['wonWhenSeenStreet1'] line[22] = pdata[p]['wonWhenSeenStreet1']
line[23] = pdata[p]['wonAtSD'] line[23] = pdata[p]['wonAtSD']
if pdata[p]['stealAttemptChance']: line[24] = 1 if pdata[p]['raiseFirstInChance']: line[24] = 1
if pdata[p]['stealAttempted']: line[25] = 1 if pdata[p]['raisedFirstIn']: line[25] = 1
if pdata[p]['foldBbToStealChance']: line[26] = 1 if pdata[p]['foldBbToStealChance']: line[26] = 1
if pdata[p]['foldedBbToSteal']: line[27] = 1 if pdata[p]['foldedBbToSteal']: line[27] = 1
if pdata[p]['foldSbToStealChance']: line[28] = 1 if pdata[p]['foldSbToStealChance']: line[28] = 1

View File

@ -53,12 +53,13 @@ class DerivedStats():
self.handsplayers[player[1]]['street0_3BDone'] = False self.handsplayers[player[1]]['street0_3BDone'] = False
self.handsplayers[player[1]]['street0_4BChance'] = False self.handsplayers[player[1]]['street0_4BChance'] = False
self.handsplayers[player[1]]['street0_4BDone'] = False self.handsplayers[player[1]]['street0_4BDone'] = False
self.handsplayers[player[1]]['stealAttemptChance'] = False self.handsplayers[player[1]]['raiseFirstInChance'] = False
self.handsplayers[player[1]]['stealAttempted'] = False self.handsplayers[player[1]]['raisedFirstIn'] = False
self.handsplayers[player[1]]['foldBbToStealChance'] = False self.handsplayers[player[1]]['foldBbToStealChance'] = False
self.handsplayers[player[1]]['foldSbToStealChance'] = False self.handsplayers[player[1]]['foldSbToStealChance'] = False
self.handsplayers[player[1]]['foldedSbToSteal'] = False self.handsplayers[player[1]]['foldedSbToSteal'] = False
self.handsplayers[player[1]]['foldedBbToSteal'] = False self.handsplayers[player[1]]['foldedBbToSteal'] = False
self.handsplayers[player[1]]['tourneyTypeId'] = None
for i in range(5): for i in range(5):
self.handsplayers[player[1]]['street%dCalls' % i] = 0 self.handsplayers[player[1]]['street%dCalls' % i] = 0
@ -142,6 +143,7 @@ class DerivedStats():
self.handsplayers[player[1]]['startCash'] = int(100 * Decimal(player[2])) self.handsplayers[player[1]]['startCash'] = int(100 * Decimal(player[2]))
self.handsplayers[player[1]]['sitout'] = False #TODO: implement actual sitout detection self.handsplayers[player[1]]['sitout'] = False #TODO: implement actual sitout detection
if hand.gametype["type"]=="tour": if hand.gametype["type"]=="tour":
self.handsplayers[player[1]]['tourneyTypeId']=hand.tourneyTypeId
self.handsplayers[player[1]]['tourneysPlayersIds'] = hand.tourneysPlayersIds[player[1]] self.handsplayers[player[1]]['tourneysPlayersIds'] = hand.tourneysPlayersIds[player[1]]
else: else:
self.handsplayers[player[1]]['tourneysPlayersIds'] = None self.handsplayers[player[1]]['tourneysPlayersIds'] = None
@ -288,7 +290,9 @@ class DerivedStats():
# print "p_actions:", self.pfba(actions), "p_folds:", self.pfba(actions, l=('folds',)), "alliners:", alliners # print "p_actions:", self.pfba(actions), "p_folds:", self.pfba(actions, l=('folds',)), "alliners:", alliners
# pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners) # pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners)
p_in = set(x[1] for x in hand.players) # hand.players includes people that are sitting out on some sites.
# Those that posted an ante should have been deal cards.
p_in = set([x[0] for x in hand.actions['BLINDSANTES']])
for (i, street) in enumerate(hand.actionStreets): for (i, street) in enumerate(hand.actionStreets):
actions = hand.actions[street] actions = hand.actions[street]
p_in = p_in - self.pfba(actions, l=('folds',)) p_in = p_in - self.pfba(actions, l=('folds',))
@ -313,13 +317,14 @@ class DerivedStats():
self.hands['street%dRaises' % i] = len(filter( lambda action: action[1] in ('raises','bets'), hand.actions[street])) self.hands['street%dRaises' % i] = len(filter( lambda action: action[1] in ('raises','bets'), hand.actions[street]))
def calcSteals(self, hand): def calcSteals(self, hand):
"""Fills stealAttempt(Chance|ed, fold(Bb|Sb)ToSteal(Chance|) """Fills raiseFirstInChance|raisedFirstIn, fold(Bb|Sb)ToSteal(Chance|)
Steal attempt - open raise on positions 1 0 S - i.e. MP3, CO, BU, SB Steal attempt - open raise on positions 1 0 S - i.e. CO, BU, SB
(note: I don't think PT2 counts SB steals in HU hands, maybe we shouldn't?) (note: I don't think PT2 counts SB steals in HU hands, maybe we shouldn't?)
Fold to steal - folding blind after steal attemp wo any other callers or raisers Fold to steal - folding blind after steal attemp wo any other callers or raisers
""" """
steal_attempt = False steal_attempt = False
raised = False
steal_positions = (1, 0, 'S') steal_positions = (1, 0, 'S')
if hand.gametype['base'] == 'stud': if hand.gametype['base'] == 'stud':
steal_positions = (2, 1, 0) steal_positions = (2, 1, 0)
@ -339,11 +344,13 @@ class DerivedStats():
if steal_attempt and act != 'folds': if steal_attempt and act != 'folds':
break break
if posn in steal_positions and not steal_attempt: if not steal_attempt and not raised: # if posn in steal_positions and not steal_attempt:
self.handsplayers[pname]['stealAttemptChance'] = True self.handsplayers[pname]['raiseFirstInChance'] = True
if act in ('bets', 'raises'): if act in ('bets', 'raises'):
self.handsplayers[pname]['stealAttempted'] = True self.handsplayers[pname]['raisedFirstIn'] = True
steal_attempt = True raised = True
if posn in steal_positions:
steal_attempt = True
if act == 'calls': if act == 'calls':
break break

View File

@ -146,13 +146,14 @@ or None if we fail to get the info """
tourno = t.group('TOURNO') tourno = t.group('TOURNO')
hand.tourNo = tourno hand.tourNo = tourno
hand.tablename = t.group('TABLE') hand.tablename = t.group('TABLE')
#TODO we should fetch info including buyincurrency, buyin and fee from URL:
# https://www.poker4ever.com/tourney/%TOURNEY_NUMBER%
# Believe Everleaf time is GMT/UTC, no transation necessary # Believe Everleaf time is GMT/UTC, no transation necessary
# Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET] # Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET]
# or : 2008/11/07 12:38:49 ET # or : 2008/11/07 12:38:49 ET
# Not getting it in my HH files yet, so using # Not getting it in my HH files yet, so using
# 2008/11/10 3:58:52 ET # 2008/11/10 3:58:52 ET
#TODO: Do conversion from GMT to ET
#TODO: Need some date functions to convert to different timezones (Date::Manip for perl rocked for this) #TODO: Need some date functions to convert to different timezones (Date::Manip for perl rocked for this)
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), "%Y/%m/%d - %H:%M:%S") hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), "%Y/%m/%d - %H:%M:%S")
return return

View File

@ -229,12 +229,21 @@ class Filters(threading.Thread):
return self.numHands return self.numHands
#end def getNumHands #end def getNumHands
def getNumTourneys(self):
return self.numTourneys
#end def getNumTourneys
def getSites(self): def getSites(self):
return self.sites return self.sites
#end def getSites #end def getSites
def getTourneyTypes(self):
return self.tourneyTypes
#end def getTourneyTypes
def getGames(self): def getGames(self):
return self.games return self.games
#end def getGames
def getSiteIds(self): def getSiteIds(self):
return self.siteid return self.siteid
@ -316,6 +325,7 @@ class Filters(threading.Thread):
liststore.append(_nt) liststore.append(_nt)
self.__set_hero_name(pname, site) self.__set_hero_name(pname, site)
#end def createPlayerLine
def __set_hero_name(self, w, site): def __set_hero_name(self, w, site):
_name = w.get_text() _name = w.get_text()
@ -338,6 +348,20 @@ class Filters(threading.Thread):
cb.connect('clicked', self.__set_site_select, site) cb.connect('clicked', self.__set_site_select, site)
cb.set_active(True) cb.set_active(True)
hbox.pack_start(cb, False, False, 0) hbox.pack_start(cb, False, False, 0)
#end def createSiteLine
def __set_tourney_type_select(self, w, tourneyType):
#print w.get_active()
self.tourneyTypes[tourneyType] = w.get_active()
log.debug("self.tourney_types[%s] set to %s" %(tourneyType, self.tourneyTypes[tourneyType]))
#end def __set_tourney_type_select
def createTourneyTypeLine(self, hbox, tourneyType):
cb = gtk.CheckButton(str(tourneyType))
cb.connect('clicked', self.__set_tourney_type_select, tourneyType)
hbox.pack_start(cb, False, False, 0)
cb.set_active(True)
#end def createTourneyTypeLine
def createGameLine(self, hbox, game): def createGameLine(self, hbox, game):
cb = gtk.CheckButton(game) cb = gtk.CheckButton(game)
@ -357,6 +381,7 @@ class Filters(threading.Thread):
#print w.get_active() #print w.get_active()
self.sites[site] = w.get_active() self.sites[site] = w.get_active()
log.debug("self.sites[%s] set to %s" %(site, self.sites[site])) log.debug("self.sites[%s] set to %s" %(site, self.sites[site]))
#end def __set_site_select
def __set_game_select(self, w, game): def __set_game_select(self, w, game):
#print w.get_active() #print w.get_active()
@ -505,6 +530,7 @@ class Filters(threading.Thread):
#print "__set_seat_select: seat =", seat, "active =", w.get_active() #print "__set_seat_select: seat =", seat, "active =", w.get_active()
self.seats[seat] = w.get_active() self.seats[seat] = w.get_active()
log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) ) log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) )
#end def __set_seat_select
def __set_group_select(self, w, group): def __set_group_select(self, w, group):
#print "__set_seat_select: seat =", seat, "active =", w.get_active() #print "__set_seat_select: seat =", seat, "active =", w.get_active()
@ -552,6 +578,7 @@ class Filters(threading.Thread):
hbox.pack_start(phands, False, False, 0) hbox.pack_start(phands, False, False, 0)
phands.connect("changed", self.__set_num_hands, site) phands.connect("changed", self.__set_num_hands, site)
top_hbox.pack_start(showb, expand=False, padding=1) top_hbox.pack_start(showb, expand=False, padding=1)
#end def fillPlayerFrame
def fillSitesFrame(self, vbox): def fillSitesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0) top_hbox = gtk.HBox(False, 0)
@ -583,6 +610,33 @@ class Filters(threading.Thread):
# self.siteid[site] = result[0][0] # self.siteid[site] = result[0][0]
#else: #else:
# print "Either 0 or more than one site matched - EEK" # print "Either 0 or more than one site matched - EEK"
#end def fillSitesFrame
def fillTourneyTypesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['tourneyTypesTitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'tourneyTypes')
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['tourneyTypes'] = vbox1
result = self.db.getTourneyTypesIds()
if len(result) >= 1:
for line in result:
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, True, 0)
self.createTourneyTypeLine(hbox, line[0])
else:
print "INFO: No tourney types returned from database"
log.info("No tourney types returned from database")
#end def fillTourneyTypesFrame
def fillGamesFrame(self, vbox): def fillGamesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0) top_hbox = gtk.HBox(False, 0)
@ -859,6 +913,7 @@ class Filters(threading.Thread):
for w in self.mainVBox.get_children(): for w in self.mainVBox.get_children():
w.destroy() w.destroy()
self.make_filter() self.make_filter()
#end def __refresh
def __toggle_box(self, widget, entry): def __toggle_box(self, widget, entry):
if self.boxes[entry].props.visible: if self.boxes[entry].props.visible:

View File

@ -54,7 +54,7 @@ class Fulltilt(HandHistoryConverter):
\$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)\s(Ante\s\$?(?P<ANTE>[.0-9]+)\s)?-\s \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)\s(Ante\s\$?(?P<ANTE>[.0-9]+)\s)?-\s
\$?(?P<CAP>[.0-9]+\sCap\s)? \$?(?P<CAP>[.0-9]+\sCap\s)?
(?P<GAMETYPE>[a-zA-Z\/\'\s]+)\s-\s (?P<GAMETYPE>[a-zA-Z\/\'\s]+)\s-\s
(?P<DATETIME>\d+:\d+:\d+\s\w+\s-\s\d+/\d+/\d+|\d+:\d+\s\w+\s-\s\w+\,\s\w+\s\d+\,\s\d+) (?P<DATETIME>\d+:\d+:\d+\s(?P<TZ1>\w+)\s-\s\d+/\d+/\d+|\d+:\d+\s(?P<TZ2>\w+)\s-\s\w+\,\s\w+\s\d+\,\s\d+)
(?P<PARTIAL>\(partial\))?\n (?P<PARTIAL>\(partial\))?\n
(?:.*?\n(?P<CANCELLED>Hand\s\#(?P=HID)\shas\sbeen\scanceled))? (?:.*?\n(?P<CANCELLED>Hand\s\#(?P=HID)\shas\sbeen\scanceled))?
''', re.VERBOSE|re.DOTALL) ''', re.VERBOSE|re.DOTALL)
@ -202,12 +202,17 @@ class Fulltilt(HandHistoryConverter):
hand.handid = m.group('HID') hand.handid = m.group('HID')
hand.tablename = m.group('TABLE') hand.tablename = m.group('TABLE')
timezone = "ET"
if m.group('TZ1') == "CET" or m.group('TZ2') == "CET":
timezone = "CET"
try: try:
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), "%H:%M:%S ET - %Y/%m/%d") stringformat = "%H:%M:%S " + m.group('TZ1') + " - %Y/%m/%d"
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), stringformat)
except: except:
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), "%H:%M ET - %a, %B %d, %Y") stringformat = "%H:%M " + m.group('TZ2') + " - %a, %B %d, %Y"
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), stringformat)
hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, "ET", "UTC") hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, timezone, "UTC")
if m.group("CANCELLED") or m.group("PARTIAL"): if m.group("CANCELLED") or m.group("PARTIAL"):
raise FpdbParseError(hid=m.group('HID')) raise FpdbParseError(hid=m.group('HID'))

View File

@ -31,7 +31,7 @@ import Filters
import Charset import Charset
import GuiPlayerStats import GuiPlayerStats
colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5 colalias,colshowsumm,colshowposn,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5,6
ranks = {'x':0, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14} ranks = {'x':0, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats): class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
@ -88,33 +88,34 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
# ToDo: store in config # ToDo: store in config
# ToDo: create popup to adjust column config # ToDo: create popup to adjust column config
# columns to display, keys match column name returned by sql, values in tuple are: # columns to display, keys match column name returned by sql, values in tuple are:
# is column displayed, column heading, xalignment, formatting, celltype # is column displayed(summary then position), column heading, xalignment, formatting, celltype
self.columns = [ ["game", True, "Game", 0.0, "%s", "str"] self.columns = [ ["game", True, True, "Game", 0.0, "%s", "str"]
, ["hand", False, "Hand", 0.0, "%s", "str"] # true not allowed for this line , ["hand", False, False, "Hand", 0.0, "%s", "str"] # true not allowed for this line
, ["plposition", False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code) , ["plposition", False, False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code)
, ["pname", False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code) , ["pname", False, False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code)
, ["n", True, "Hds", 1.0, "%1.0f", "str"] , ["n", True, True, "Hds", 1.0, "%1.0f", "str"]
, ["avgseats", False, "Seats", 1.0, "%3.1f", "str"] , ["avgseats", False, False, "Seats", 1.0, "%3.1f", "str"]
, ["vpip", True, "VPIP", 1.0, "%3.1f", "str"] , ["vpip", True, True, "VPIP", 1.0, "%3.1f", "str"]
, ["pfr", True, "PFR", 1.0, "%3.1f", "str"] , ["pfr", True, True, "PFR", 1.0, "%3.1f", "str"]
, ["pf3", True, "PF3", 1.0, "%3.1f", "str"] , ["pf3", True, True, "PF3", 1.0, "%3.1f", "str"]
, ["aggfac", True, "AggFac", 1.0, "%2.2f", "str"] , ["aggfac", True, True, "AggFac", 1.0, "%2.2f", "str"]
, ["aggfrq", True, "AggFreq", 1.0, "%3.1f", "str"] , ["aggfrq", True, True, "AggFreq", 1.0, "%3.1f", "str"]
, ["conbet", True, "ContBet", 1.0, "%3.1f", "str"] , ["conbet", True, True, "ContBet", 1.0, "%3.1f", "str"]
, ["steals", True, "Steals", 1.0, "%3.1f", "str"] , ["rfi", True, True, "RFI", 1.0, "%3.1f", "str"]
, ["saw_f", True, "Saw_F", 1.0, "%3.1f", "str"] , ["steals", True, True, "Steals", 1.0, "%3.1f", "str"]
, ["sawsd", True, "SawSD", 1.0, "%3.1f", "str"] , ["saw_f", True, True, "Saw_F", 1.0, "%3.1f", "str"]
, ["wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f", "str"] , ["sawsd", True, True, "SawSD", 1.0, "%3.1f", "str"]
, ["wmsd", True, "W$SD", 1.0, "%3.1f", "str"] , ["wtsdwsf", True, True, "WtSDwsF", 1.0, "%3.1f", "str"]
, ["flafq", True, "FlAFq", 1.0, "%3.1f", "str"] , ["wmsd", True, True, "W$SD", 1.0, "%3.1f", "str"]
, ["tuafq", True, "TuAFq", 1.0, "%3.1f", "str"] , ["flafq", True, True, "FlAFq", 1.0, "%3.1f", "str"]
, ["rvafq", True, "RvAFq", 1.0, "%3.1f", "str"] , ["tuafq", True, True, "TuAFq", 1.0, "%3.1f", "str"]
, ["pofafq", False, "PoFAFq", 1.0, "%3.1f", "str"] , ["rvafq", True, True, "RvAFq", 1.0, "%3.1f", "str"]
, ["net", True, "Net($)", 1.0, "%6.2f", "cash"] , ["pofafq", False, False, "PoFAFq", 1.0, "%3.1f", "str"]
, ["bbper100", True, "bb/100", 1.0, "%4.2f", "str"] , ["net", True, True, "Net($)", 1.0, "%6.2f", "cash"]
, ["rake", True, "Rake($)", 1.0, "%6.2f", "cash"] , ["bbper100", True, True, "bb/100", 1.0, "%4.2f", "str"]
, ["bb100xr", True, "bbxr/100", 1.0, "%4.2f", "str"] , ["rake", True, True, "Rake($)", 1.0, "%6.2f", "cash"]
, ["variance", True, "Variance", 1.0, "%5.2f", "str"] , ["bb100xr", True, True, "bbxr/100", 1.0, "%4.2f", "str"]
, ["variance", True, True, "Variance", 1.0, "%5.2f", "str"]
] ]
# Detail filters: This holds the data used in the popup window, extra values are # Detail filters: This holds the data used in the popup window, extra values are
@ -149,6 +150,8 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
self.stats_vbox = gtk.VPaned() self.stats_vbox = gtk.VPaned()
self.stats_vbox.show() self.stats_vbox.show()
self.stats_frame.add(self.stats_vbox) self.stats_frame.add(self.stats_vbox)
self.top_pane_height = 0
self.height_inc = None
# self.fillStatsFrame(self.stats_vbox) # self.fillStatsFrame(self.stats_vbox)
#self.main_hbox.pack_start(self.filters.get_vbox()) #self.main_hbox.pack_start(self.filters.get_vbox())
@ -158,7 +161,17 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
self.main_hbox.show() self.main_hbox.show()
# make sure Hand column is not displayed # make sure Hand column is not displayed
[x for x in self.columns if x[0] == 'hand'][0][1] = False [x for x in self.columns if x[0] == 'hand'][0][colshowsumm] = False
[x for x in self.columns if x[0] == 'hand'][0][colshowposn] = False
# if rfi and steal both on for summaries, turn rfi off
if ( [x for x in self.columns if x[0] == 'rfi'][0][colshowsumm]
and [x for x in self.columns if x[0] == 'steals'][0][colshowsumm]):
[x for x in self.columns if x[0] == 'rfi'][0][colshowsumm] = False
# if rfi and steal both on for position breakdowns, turn steals off:
if ( [x for x in self.columns if x[0] == 'rfi'][0][colshowposn]
and [x for x in self.columns if x[0] == 'steals'][0][colshowposn]):
[x for x in self.columns if x[0] == 'steals'][0][colshowposn] = False
self.last_pos = -1 self.last_pos = -1
@ -168,18 +181,33 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
#end def get_vbox #end def get_vbox
def refreshStats(self, widget, data): def refreshStats(self, widget, data):
self.last_pos = self.stats_vbox.get_position() #self.last_pos = self.stats_vbox.get_position()
self.height_inc = None
#old_len = 0
#if self.liststore:
# old_len = len(self.liststore[0])
try: self.stats_vbox.destroy() try: self.stats_vbox.destroy()
except AttributeError: pass except AttributeError: pass
self.liststore = [] self.liststore = []
self.listcols = [] self.listcols = []
#self.stats_vbox = gtk.VBox(False, 0)
self.stats_vbox = gtk.VPaned() self.stats_vbox = gtk.VPaned()
self.stats_vbox.show() self.stats_vbox.show()
self.stats_frame.add(self.stats_vbox) self.stats_frame.add(self.stats_vbox)
self.fillStatsFrame(self.stats_vbox) self.fillStatsFrame(self.stats_vbox)
if self.last_pos > 0:
self.stats_vbox.set_position(self.last_pos) # set height of top pane
# (tried 2 ways, guesstimate using ratio of old to new number of rows and sum of
# heights of parts)
new_len = 0
if self.liststore:
#new_len = len(self.liststore[0])
#print "setting to", self.top_pane_height + self.height_inc
self.stats_vbox.set_position(self.top_pane_height + self.height_inc)
#if self.last_pos > 0:
# if old_len > 0 and new_len > 0 and new_len <= 10:
# self.stats_vbox.set_position(self.last_pos * (new_len+1.9)/(old_len+1.9))
# else:
# self.stats_vbox.set_position(self.last_pos)
#end def refreshStats #end def refreshStats
def fillStatsFrame(self, vbox): def fillStatsFrame(self, vbox):
@ -225,8 +253,8 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
# Scrolled window for summary table # Scrolled window for summary table
swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
swin.show() vbox.pack1(swin) #, resize=True) don't use resize, self.height_inc relies on initial
vbox.pack1(swin) # height of pane being correct for one row
# Display summary table at top of page # Display summary table at top of page
# 3rd parameter passes extra flags, currently includes: # 3rd parameter passes extra flags, currently includes:
@ -236,6 +264,7 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
flags = [False, self.filters.getNumHands(), 0] flags = [False, self.filters.getNumHands(), 0]
self.addGrid(swin, 'playerDetailedStats', flags, playerids self.addGrid(swin, 'playerDetailedStats', flags, playerids
,sitenos, limits, type, seats, groups, dates, games) ,sitenos, limits, type, seats, groups, dates, games)
swin.show()
if 'allplayers' in groups and groups['allplayers']: if 'allplayers' in groups and groups['allplayers']:
# can't currently do this combination so skip detailed table # can't currently do this combination so skip detailed table
@ -249,19 +278,32 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
vbox2.pack_start(heading, expand=False, padding=3) vbox2.pack_start(heading, expand=False, padding=3)
# Scrolled window for detailed table (display by hand) # Scrolled window for detailed table (display by hand)
swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) swin2 = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) swin2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
swin.show() swin2.show()
vbox2.pack_start(swin, expand=True, padding=3) vbox2.pack_start(swin2, expand=True, padding=3)
vbox.pack2(vbox2) vbox.pack2(vbox2)
vbox2.show() vbox2.show()
# Detailed table # Detailed table
flags[0] = True flags[0] = True
flags[2] = 1 flags[2] = 1
self.addGrid(swin, 'playerDetailedStats', flags, playerids self.addGrid(swin2, 'playerDetailedStats', flags, playerids
,sitenos, limits, type, seats, groups, dates, games) ,sitenos, limits, type, seats, groups, dates, games)
if self.height_inc is None:
self.height_inc = 0
# need this to check whether scrollbar is visible:
while gtk.events_pending(): # see http://faq.pygtk.org/index.py?req=index for more hints (3.7)
gtk.main_iteration(False)
hs = swin.get_hscrollbar()
if hs is not None:
#print "hs vis", hs.get_property('visible'), hs.get_property('visible').__class__
if hs.get_property('visible'):
self.height_inc = hs.size_request()[1] + swin.style_get_property('scrollbar-spacing')
#print "hh set to", self.height_inc
self.stats_vbox.set_position(self.top_pane_height + self.height_inc)
self.db.rollback() self.db.rollback()
print "Stats page displayed in %4.2f seconds" % (time() - startTime) print "Stats page displayed in %4.2f seconds" % (time() - startTime)
#end def createStatsTable #end def createStatsTable
@ -350,6 +392,8 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
colnames = [desc[0].lower() for desc in self.cursor.description] colnames = [desc[0].lower() for desc in self.cursor.description]
# pre-fetch some constant values: # pre-fetch some constant values:
colshow = colshowsumm
if groups['posn']: colshow = colshowposn
self.cols_to_show = [x for x in self.columns if x[colshow]] self.cols_to_show = [x for x in self.columns if x[colshow]]
hgametypeid_idx = colnames.index('hgametypeid') hgametypeid_idx = colnames.index('hgametypeid')
@ -445,6 +489,11 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
sqlrow += 1 sqlrow += 1
row += 1 row += 1
vbox.show_all() vbox.show_all()
view.show()
if len(self.liststore) == 1:
#print "view hieght is ", view.get_allocation().height, view.size_request(), view.get_visible_rect().height, view.get_vadjustment().get_value()
self.top_pane_height = view.size_request()[1]
#print "saved ", self.top_pane_height
#end def addGrid #end def addGrid
def refineQuery(self, query, flags, playerids, sitenos, limits, type, seats, groups, dates, games): def refineQuery(self, query, flags, playerids, sitenos, limits, type, seats, groups, dates, games):
@ -455,20 +504,22 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
else: else:
holecards = flags[0] holecards = flags[0]
numhands = flags[1] numhands = flags[1]
colshow = colshowsumm
if groups['posn']: colshow = colshowposn
if 'allplayers' in groups and groups['allplayers']: if 'allplayers' in groups and groups['allplayers']:
nametest = "(hp.playerId)" nametest = "(hp.playerId)"
if holecards or groups['posn']: if holecards or groups['posn']:
pname = "'all players'" pname = "'all players'"
# set flag in self.columns to not show player name column # set flag in self.columns to not show player name column
[x for x in self.columns if x[0] == 'pname'][0][1] = False [x for x in self.columns if x[0] == 'pname'][0][colshow] = False
# can't do this yet (re-write doing more maths in python instead of sql?) # can't do this yet (re-write doing more maths in python instead of sql?)
if numhands: if numhands:
nametest = "(-1)" nametest = "(-1)"
else: else:
pname = "p.name" pname = "p.name"
# set flag in self.columns to show player name column # set flag in self.columns to show player name column
[x for x in self.columns if x[0] == 'pname'][0][1] = True [x for x in self.columns if x[0] == 'pname'][0][colshow] = True
if numhands: if numhands:
having = ' and count(1) > %d ' % (numhands,) having = ' and count(1) > %d ' % (numhands,)
else: else:
@ -480,7 +531,7 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
nametest = "1 = 2" nametest = "1 = 2"
pname = "p.name" pname = "p.name"
# set flag in self.columns to not show player name column # set flag in self.columns to not show player name column
[x for x in self.columns if x[0] == 'pname'][0][1] = False [x for x in self.columns if x[0] == 'pname'][0][colshow] = False
query = query.replace("<player_test>", nametest) query = query.replace("<player_test>", nametest)
query = query.replace("<playerName>", pname) query = query.replace("<playerName>", pname)
query = query.replace("<havingclause>", having) query = query.replace("<havingclause>", having)
@ -603,11 +654,11 @@ class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
#query = query.replace("<position>", "case hp.position when '0' then 'Btn' else hp.position end") #query = query.replace("<position>", "case hp.position when '0' then 'Btn' else hp.position end")
query = query.replace("<position>", "hp.position") query = query.replace("<position>", "hp.position")
# set flag in self.columns to show posn column # set flag in self.columns to show posn column
[x for x in self.columns if x[0] == 'plposition'][0][1] = True [x for x in self.columns if x[0] == 'plposition'][0][colshow] = True
else: else:
query = query.replace("<position>", "gt.base") query = query.replace("<position>", "gt.base")
# unset flag in self.columns to hide posn column # unset flag in self.columns to hide posn column
[x for x in self.columns if x[0] == 'plposition'][0][1] = False [x for x in self.columns if x[0] == 'plposition'][0][colshow] = False
#print "query =\n", query #print "query =\n", query
return(query) return(query)

View File

@ -1,290 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#Copyright 2008-2010 Steffen Schaumburg
#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 <http://www.gnu.org/licenses/>.
#In the "official" distribution you can find the license in agpl-3.0.txt.
import threading
import pygtk
pygtk.require('2.0')
import gtk
import os
import fpdb_import
from Exceptions import *
class GuiTableViewer (threading.Thread):
def hudDivide (self, a, b):
if b==0:
return "n/a"
else:
return str(int((a/float(b))*100))+"%"
#end def hudDivide
def browse_clicked(self, widget, data):
"""runs when user clicks browse on tv tab"""
#print "start of table_viewer.browser_clicked"
current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer",
action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
#dia_chooser.set_current_folder(pathname)
dia_chooser.set_filename(current_path)
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
response = dia_chooser.run()
if response == gtk.RESPONSE_OK:
#print dia_chooser.get_filename(), 'selected'
self.filename_tbuffer.set_text(dia_chooser.get_filename())
elif response == gtk.RESPONSE_CANCEL:
print 'Closed, no files selected'
dia_chooser.destroy()
#end def table_viewer.browse_clicked
def prepare_data(self):
"""prepares the data for display by refresh_clicked, returns a 2D array"""
#print "start of prepare_data"
arr=[]
#first prepare the header row
if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"):
tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST")
tmp+=("FS", "FB")
tmp+=("CB", )
tmp+=("2B", "3B")
tmp+=("AF", "FF", "AT", "FT", "AR", "FR")
tmp+=("WtSD", "W$wsF", "W$SD")
else:
raise FpdbError("reimplement stud")
arr.append(tmp)
#then the data rows
for player in range(len(self.player_names)):
tmp=[]
p_name = Charset.to_gui(self.player_names[player][0])
tmp.append(p_name)
seatCount=len(self.player_names)
if seatCount>=8:
minSeats,maxSeats=7,10
elif seatCount==7:
minSeats,maxSeats=6,10
elif seatCount==6 or seatCount==5:
minSeats,maxSeats=seatCount-1,seatCount+1
elif seatCount==4:
minSeats,maxSeats=4,5
elif seatCount==2 or seatCount==3:
minSeats,maxSeats=seatCount,seatCount
else:
FpdbError("invalid seatCount")
self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats))
rows=self.cursor.fetchall()
row=[]
for field_no in range(len(rows[0])):
row.append(rows[0][field_no])
for row_no in range(len(rows)):
if row_no==0:
pass
else:
for field_no in range(len(rows[row_no])):
if field_no<=3:
pass
else:
#print "in prep data, row_no:",row_no,"field_no:",field_no
row[field_no]+=rows[row_no][field_no]
tmp.append(str(row[6]))#Hands
tmp.append(self.hudDivide(row[7],row[6])) #VPIP
tmp.append(self.hudDivide(row[8],row[6])) #PFR
tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B
tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST
tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS
tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB
tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB
tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B
tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B
tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF
tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF
tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT
tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT
tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR
tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR
tmp.append(self.hudDivide(row[15],row[11])) #WtSD
tmp.append(self.hudDivide(row[28],row[11])) #W$wSF
tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD
arr.append(tmp)
return arr
#end def table_viewer.prepare_data
def refresh_clicked(self, widget, data):
"""runs when user clicks refresh"""
#print "start of table_viewer.refresh_clicked"
arr=self.prepare_data()
try: self.data_table.destroy()
except AttributeError: pass
self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False)
self.main_vbox.pack_start(self.data_table)
self.data_table.show()
for row in range(len(arr)):
for column in range (len(arr[row])):
eventBox=gtk.EventBox()
new_label=gtk.Label(arr[row][column])
if row%2==0: #
bg_col="white"
if column==0 or (column>=5 and column<=10):
bg_col="lightgrey"
else:
bg_col="lightgrey"
if column==0 or (column>=5 and column<=10):
bg_col="grey"
#style = eventBox.get_style()
#style.font.height=8
#eventBox.set_style(style)
eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col))
eventBox.add(new_label)
self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1)
eventBox.show()
new_label.show()
#end def table_viewer.refresh_clicked
def read_names_clicked(self, widget, data):
"""runs when user clicks read names"""
#print "start of table_viewer.read_names_clicked"
self.db.reconnect()
self.cursor=self.db.get_cursor()
#self.hands_id=self.last_read_hand_id
self.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, ))
self.gametype_id=self.cursor.fetchone()[0]
self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, ))
self.category=self.cursor.fetchone()[0]
#print "self.gametype_id", self.gametype_id," category:", self.category, " self.hands_id:", self.hands_id
self.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_ids=self.cursor.fetchall()
#print "self.player_ids:",self.player_ids
self.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_names=self.cursor.fetchall()
#print "self.player_names:",self.player_names
#end def table_viewer.read_names_clicked
def import_clicked(self, widget, data):
"""runs when user clicks import"""
#print "start of table_viewer.import_clicked"
self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
self.importer = fpdb_import.Importer(self, self.settings, self.config)
self.importer.setMinPrint(0)
self.importer.setQuiet(False)
self.importer.setFailOnError(False)
self.importer.setHandCount(0)
self.importer.addImportFile(self.inputFile)
self.importer.runImport()
self.hands_id=self.importer.handsId
#end def table_viewer.import_clicked
def all_clicked(self, widget, data):
"""runs when user clicks all"""
#print "start of table_viewer.all_clicked"
self.import_clicked(widget, data)
self.read_names_clicked(widget, data)
self.refresh_clicked(widget, data)
#end def table_viewer.all_clicked
def get_vbox(self):
"""returns the vbox of this thread"""
return self.main_vbox
#end def get_vbox
def __init__(self, db, settings, config=None, debug=True):
"""Constructor for table_viewer"""
self.debug=debug
#print "start of table_viewer constructor"
self.db = db
self.cursor = db.get_cursor()
self.settings = settings
self.config = config
self.main_vbox = gtk.VBox(False, 0)
self.main_vbox.show()
self.settings_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.settings_hbox, False, True, 0)
self.settings_hbox.show()
self.filename_label = gtk.Label("Path of history file")
self.settings_hbox.pack_start(self.filename_label, False, False)
self.filename_label.show()
self.filename_tbuffer=gtk.TextBuffer()
self.filename_tbuffer.set_text(self.settings['hud-defaultPath'])
self.filename_tview=gtk.TextView(self.filename_tbuffer)
self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5)
self.filename_tview.show()
self.browse_button=gtk.Button("Browse...")
self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked")
self.settings_hbox.pack_start(self.browse_button, False, False)
self.browse_button.show()
self.button_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.button_hbox, False, True, 0)
self.button_hbox.show()
#self.import_button = gtk.Button("Import")
#self.import_button.connect("clicked", self.import_clicked, "Import clicked")
#self.button_hbox.add(self.import_button)
#self.import_button.show()
#self.read_names_button = gtk.Button("Read Names")
#self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked")
#self.button_hbox.add(self.read_names_button)
#self.read_names_button.show()
#self.refresh_button = gtk.Button("Show/Refresh data")
#self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked")
#self.button_hbox.add(self.refresh_button)
#self.refresh_button.show()
self.all_button = gtk.Button("Import&Read&Refresh")
self.all_button.connect("clicked", self.all_clicked, "All clicked")
self.button_hbox.add(self.all_button)
self.all_button.show()
#end of table_viewer.__init__

View File

@ -26,8 +26,11 @@ import codecs
from decimal import Decimal from decimal import Decimal
import operator import operator
from xml.dom.minidom import Node from xml.dom.minidom import Node
import time import time
import datetime import datetime
from pytz import timezone
import pytz
import logging import logging
# logging has been set up in fpdb.py or HUD_main.py, use their settings: # logging has been set up in fpdb.py or HUD_main.py, use their settings:
@ -497,19 +500,68 @@ or None if we fail to get the info """
@staticmethod @staticmethod
def changeTimezone(time, givenTimezone, wantedTimezone): def changeTimezone(time, givenTimezone, wantedTimezone):
if givenTimezone=="ET" and wantedTimezone=="UTC": #print "raw time:",time, "given TZ:", givenTimezone
# approximate rules for ET daylight savings time: if wantedTimezone=="UTC":
if ( time.month == 12 # all of Dec wantedTimezone = pytz.utc
or (time.month == 11 and time.day > 4) # and most of November else:
or time.month < 3 # and all of Jan/Feb raise Error #TODO raise appropriate error
or (time.month == 3 and time.day < 11) ): # and 1st 10 days of March
offset = datetime.timedelta(hours=5) # are EST: assume 5 hour offset (ET without daylight saving) if givenTimezone=="ET":
else: givenTimezone = timezone('US/Eastern')
offset = datetime.timedelta(hours=4) # rest is EDT: assume 4 hour offset (ET with daylight saving) elif givenTimezone=="CET":
# adjust time into UTC: givenTimezone = timezone('Europe/Berlin')
time = time + offset #Note: Daylight Saving Time is standardised across the EU so this should be fine
#print " tz = %s start = %s" % (tz, str(hand.starttime)) elif givenTimezone == 'HST': # Hawaiian Standard Time
return time pass
elif givenTimezone == 'AKT': # Alaska Time
pass
elif givenTimezone == 'PT': # Pacific Time
pass
elif givenTimezone == 'MT': # Mountain Time
pass
elif givenTimezone == 'CT': # Central Time
pass
elif givenTimezone == 'AT': # Atlantic Time
pass
elif givenTimezone == 'NT': # Newfoundland Time
pass
elif givenTimezone == 'ART': # Argentinian Time
pass
elif givenTimezone == 'BRT': # Brasilia Time
pass
elif givenTimezone == 'AKT': # Alaska Time
pass
elif givenTimezone == 'WET': # Western European Time
pass
elif givenTimezone == 'EET': # Eastern European Time
pass
elif givenTimezone == 'MSK': # Moscow Standard Time
pass
elif givenTimezone == 'IST': # India Standard Time
pass
elif givenTimezone == 'CCT': # China Coast Time
pass
elif givenTimezone == 'JST': # Japan Standard Time
pass
elif givenTimezone == 'AWST': # Australian Western Standard Time
givenTimezone = timezone('Australia/West')
elif givenTimezone == 'ACST': # Australian Central Standard Time
givenTimezone = timezone('Australia/Darwin')
elif givenTimezone == 'AEST': # Australian Eastern Standard Time
# Each State on the East Coast has different DSTs.
# Melbournce is out because I don't like AFL, Queensland doesn't have DST
# ACT is full of politicians and Tasmania will never notice.
# Using Sydney.
givenTimezone = timezone('Australia/Sydney')
elif givenTimezone == 'NZT': # New Zealand Time
pass
else:
raise Error #TODO raise appropriate error
localisedTime = givenTimezone.localize(time)
utcTime = localisedTime.astimezone(wantedTimezone)
#print "utcTime:",utcTime
return utcTime
#end @staticmethod def changeTimezone #end @staticmethod def changeTimezone
@staticmethod @staticmethod

View File

@ -72,7 +72,7 @@ class PokerStars(HandHistoryConverter):
(Tournament\s\# # open paren of tournament info (Tournament\s\# # open paren of tournament info
(?P<TOURNO>\d+),\s (?P<TOURNO>\d+),\s
# here's how I plan to use LS # here's how I plan to use LS
(?P<BUYIN>([%(LS)s\+\d\.]+\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?)|Freeroll)\s+)? (?P<BUYIN>(?P<BIAMT>[%(LS)s\d\.]+)\+(?P<BOUNTY>[%(LS)s\d\.]+)?\+(?P<BIRAKE>[%(LS)s\d\.]+)\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)|Freeroll)\s+)?
# close paren of tournament info # close paren of tournament info
(?P<MIXED>HORSE|8\-Game|HOSE)?\s?\(? (?P<MIXED>HORSE|8\-Game|HOSE)?\s?\(?
(?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s (?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s
@ -206,24 +206,20 @@ class PokerStars(HandHistoryConverter):
m = self.re_HandInfo.search(hand.handText,re.DOTALL) m = self.re_HandInfo.search(hand.handText,re.DOTALL)
if m: if m:
info.update(m.groupdict()) info.update(m.groupdict())
# hand.maxseats = int(m2.group(1))
else: else:
pass # throw an exception here, eh? pass # throw an exception here, eh?
m = self.re_GameInfo.search(hand.handText) m = self.re_GameInfo.search(hand.handText)
if m: if m:
info.update(m.groupdict()) info.update(m.groupdict())
# m = self.re_Button.search(hand.handText)
# if m: info.update(m.groupdict())
# TODO : I rather like the idea of just having this dict as hand.info
log.debug("readHandInfo: %s" % info) log.debug("readHandInfo: %s" % info)
for key in info: for key in info:
if key == 'DATETIME': if key == 'DATETIME':
#2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET] # (both dates are parsed so ET date overrides the other) #2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET] # (both dates are parsed so ET date overrides the other)
#2008/08/17 - 01:14:43 (ET) #2008/08/17 - 01:14:43 (ET)
#2008/09/07 06:23:14 ET #2008/09/07 06:23:14 ET
m1 = self.re_DateTime.finditer(info[key]) m1 = self.re_DateTime.finditer(info[key])
# m2 = re.search("(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})[\- ]+(?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)", info[key]) datetimestr = "2000/01/01 00:00:00" # default used if time not found
datetimestr = "2000/01/01 00:00:00" # default used if time not found (stops import crashing, but startTime will be wrong)
for a in m1: for a in m1:
datetimestr = "%s/%s/%s %s:%s:%s" % (a.group('Y'), a.group('M'),a.group('D'),a.group('H'),a.group('MIN'),a.group('S')) datetimestr = "%s/%s/%s %s:%s:%s" % (a.group('Y'), a.group('M'),a.group('D'),a.group('H'),a.group('MIN'),a.group('S'))
#tz = a.group('TZ') # just assume ET?? #tz = a.group('TZ') # just assume ET??
@ -236,12 +232,15 @@ class PokerStars(HandHistoryConverter):
hand.tourNo = info[key] hand.tourNo = info[key]
if key == 'BUYIN': if key == 'BUYIN':
if hand.tourNo!=None: if hand.tourNo!=None:
#print "DEBUG: info['BUYIN']: %s" % info['BUYIN']
#print "DEBUG: info['BIAMT']: %s" % info['BIAMT']
#print "DEBUG: info['BIRAKE']: %s" % info['BIRAKE']
#print "DEBUG: info['BOUNTY']: %s" % info['BOUNTY']
if info[key] == 'Freeroll': if info[key] == 'Freeroll':
hand.buyin = 0 hand.buyin = 0
hand.fee = 0 hand.fee = 0
hand.buyinCurrency = "FREE" hand.buyinCurrency = "FREE"
else: else:
#print "info[key]:",info[key]
if info[key].find("$")!=-1: if info[key].find("$")!=-1:
hand.buyinCurrency="USD" hand.buyinCurrency="USD"
elif info[key].find(u"")!=-1: elif info[key].find(u"")!=-1:
@ -249,13 +248,13 @@ class PokerStars(HandHistoryConverter):
elif info[key].find("FPP")!=-1: elif info[key].find("FPP")!=-1:
hand.buyinCurrency="PSFP" hand.buyinCurrency="PSFP"
else: else:
raise FpdbParseError("failed to detect currency") #FIXME: handle other currencies, FPP, play money #FIXME: handle other currencies, FPP, play money
raise FpdbParseError("failed to detect currency")
if hand.buyinCurrency=="USD" or hand.buyinCurrency=="EUR": if hand.buyinCurrency=="USD" or hand.buyinCurrency=="EUR":
info[key]=info[key][:-4] hand.buyin = int(100*Decimal(info['BIAMT'][1:]))
middle=info[key].find("+") hand.fee = int(100*Decimal(info['BIRAKE'][1:]))
hand.buyin = int(100*Decimal(info[key][1:middle])) # TODO: Bounty is in key 'BOUNTY'
hand.fee = int(100*Decimal(info[key][middle+2:]))
elif hand.buyinCurrency=="PSFP": elif hand.buyinCurrency=="PSFP":
hand.buyin = int(Decimal(info[key][0:-3])) hand.buyin = int(Decimal(info[key][0:-3]))
hand.fee = 0 hand.fee = 0

View File

@ -392,9 +392,9 @@ class Sql:
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id), id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id), siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
currency varchar(4) NOT NULL, currency varchar(4),
buyIn INT NOT NULL, buyIn INT,
fee INT NOT NULL, fee INT,
category varchar(9) NOT NULL, category varchar(9) NOT NULL,
limitType char(2) NOT NULL, limitType char(2) NOT NULL,
buyInChips INT, buyInChips INT,
@ -423,9 +423,9 @@ class Sql:
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id SERIAL, PRIMARY KEY (id), id SERIAL, PRIMARY KEY (id),
siteId INT NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id), siteId INT NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
currency varchar(4) NOT NULL, currency varchar(4),
buyin INT NOT NULL, buyin INT,
fee INT NOT NULL, fee INT,
category varchar(9), category varchar(9),
limitType char(2), limitType char(2),
buyInChips INT, buyInChips INT,
@ -453,9 +453,9 @@ class Sql:
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
siteId INT NOT NULL, siteId INT NOT NULL,
currency VARCHAR(4) NOT NULL, currency VARCHAR(4),
buyin INT NOT NULL, buyin INT,
fee INT NOT NULL, fee INT,
category TEXT, category TEXT,
limitType TEXT, limitType TEXT,
buyInChips INT, buyInChips INT,
@ -598,8 +598,8 @@ class Sql:
foldToOtherRaisedStreet3 BOOLEAN, foldToOtherRaisedStreet3 BOOLEAN,
foldToOtherRaisedStreet4 BOOLEAN, foldToOtherRaisedStreet4 BOOLEAN,
stealAttemptChance BOOLEAN, raiseFirstInChance BOOLEAN,
stealAttempted BOOLEAN, raisedFirstIn BOOLEAN,
foldBbToStealChance BOOLEAN, foldBbToStealChance BOOLEAN,
foldedBbToSteal BOOLEAN, foldedBbToSteal BOOLEAN,
foldSbToStealChance BOOLEAN, foldSbToStealChance BOOLEAN,
@ -714,8 +714,8 @@ class Sql:
foldToOtherRaisedStreet3 BOOLEAN, foldToOtherRaisedStreet3 BOOLEAN,
foldToOtherRaisedStreet4 BOOLEAN, foldToOtherRaisedStreet4 BOOLEAN,
stealAttemptChance BOOLEAN, raiseFirstInChance BOOLEAN,
stealAttempted BOOLEAN, raisedFirstIn BOOLEAN,
foldBbToStealChance BOOLEAN, foldBbToStealChance BOOLEAN,
foldedBbToSteal BOOLEAN, foldedBbToSteal BOOLEAN,
foldSbToStealChance BOOLEAN, foldSbToStealChance BOOLEAN,
@ -829,8 +829,8 @@ class Sql:
foldToOtherRaisedStreet3 INT, foldToOtherRaisedStreet3 INT,
foldToOtherRaisedStreet4 INT, foldToOtherRaisedStreet4 INT,
stealAttemptChance INT, raiseFirstInChance INT,
stealAttempted INT, raisedFirstIn INT,
foldBbToStealChance INT, foldBbToStealChance INT,
foldedBbToSteal INT, foldedBbToSteal INT,
foldSbToStealChance INT, foldSbToStealChance INT,
@ -1025,8 +1025,8 @@ class Sql:
foldToOtherRaisedStreet3 INT, foldToOtherRaisedStreet3 INT,
foldToOtherRaisedStreet4 INT, foldToOtherRaisedStreet4 INT,
stealAttemptChance INT, raiseFirstInChance INT,
stealAttempted INT, raisedFirstIn INT,
foldBbToStealChance INT, foldBbToStealChance INT,
foldedBbToSteal INT, foldedBbToSteal INT,
foldSbToStealChance INT, foldSbToStealChance INT,
@ -1125,8 +1125,8 @@ class Sql:
foldToOtherRaisedStreet3 INT, foldToOtherRaisedStreet3 INT,
foldToOtherRaisedStreet4 INT, foldToOtherRaisedStreet4 INT,
stealAttemptChance INT, raiseFirstInChance INT,
stealAttempted INT, raisedFirstIn INT,
foldBbToStealChance INT, foldBbToStealChance INT,
foldedBbToSteal INT, foldedBbToSteal INT,
foldSbToStealChance INT, foldSbToStealChance INT,
@ -1224,8 +1224,8 @@ class Sql:
foldToOtherRaisedStreet3 INT, foldToOtherRaisedStreet3 INT,
foldToOtherRaisedStreet4 INT, foldToOtherRaisedStreet4 INT,
stealAttemptChance INT, raiseFirstInChance INT,
stealAttempted INT, raisedFirstIn INT,
foldBbToStealChance INT, foldBbToStealChance INT,
foldedBbToSteal INT, foldedBbToSteal INT,
foldSbToStealChance INT, foldSbToStealChance INT,
@ -1364,8 +1364,18 @@ class Sql:
sum(hc.foldToOtherRaisedStreet4) AS f_freq_4, sum(hc.foldToOtherRaisedStreet4) AS f_freq_4,
sum(hc.wonWhenSeenStreet1) AS w_w_s_1, sum(hc.wonWhenSeenStreet1) AS w_w_s_1,
sum(hc.wonAtSD) AS wmsd, sum(hc.wonAtSD) AS wmsd,
sum(hc.stealAttemptChance) AS steal_opp, sum(case hc.position
sum(hc.stealAttempted) AS steal, when 'S' then hc.raiseFirstInChance
when '0' then hc.raiseFirstInChance
when '1' then hc.raiseFirstInChance
else 0
) AS steal_opp,
sum(case hc.position
when 'S' then hc.raisedFirstIn
when '0' then hc.raisedFirstIn
when '1' then hc.raisedFirstIn
else 0
) AS steal,
sum(hc.foldSbToStealChance) AS SBstolen, sum(hc.foldSbToStealChance) AS SBstolen,
sum(hc.foldedSbToSteal) AS SBnotDef, sum(hc.foldedSbToSteal) AS SBnotDef,
sum(hc.foldBbToStealChance) AS BBstolen, sum(hc.foldBbToStealChance) AS BBstolen,
@ -1463,8 +1473,8 @@ class Sql:
sum(hc.foldToOtherRaisedStreet4) AS f_freq_4, sum(hc.foldToOtherRaisedStreet4) AS f_freq_4,
sum(hc.wonWhenSeenStreet1) AS w_w_s_1, sum(hc.wonWhenSeenStreet1) AS w_w_s_1,
sum(hc.wonAtSD) AS wmsd, sum(hc.wonAtSD) AS wmsd,
sum(hc.stealAttemptChance) AS steal_opp, sum(hc.raiseFirstInChance) AS steal_opp,
sum(hc.stealAttempted) AS steal, sum(hc.raisedFirstIn) AS steal,
sum(hc.foldSbToStealChance) AS SBstolen, sum(hc.foldSbToStealChance) AS SBstolen,
sum(hc.foldedSbToSteal) AS SBnotDef, sum(hc.foldedSbToSteal) AS SBnotDef,
sum(hc.foldBbToStealChance) AS BBstolen, sum(hc.foldBbToStealChance) AS BBstolen,
@ -1589,8 +1599,8 @@ class Sql:
cast(hp2.foldToOtherRaisedStreet4 as <signed>integer) AS f_freq_4, cast(hp2.foldToOtherRaisedStreet4 as <signed>integer) AS f_freq_4,
cast(hp2.wonWhenSeenStreet1 as <signed>integer) AS w_w_s_1, cast(hp2.wonWhenSeenStreet1 as <signed>integer) AS w_w_s_1,
cast(hp2.wonAtSD as <signed>integer) AS wmsd, cast(hp2.wonAtSD as <signed>integer) AS wmsd,
cast(hp2.stealAttemptChance as <signed>integer) AS steal_opp, cast(hp2.raiseFirstInChance as <signed>integer) AS steal_opp,
cast(hp2.stealAttempted as <signed>integer) AS steal, cast(hp2.raisedFirstIn as <signed>integer) AS steal,
cast(hp2.foldSbToStealChance as <signed>integer) AS SBstolen, cast(hp2.foldSbToStealChance as <signed>integer) AS SBstolen,
cast(hp2.foldedSbToSteal as <signed>integer) AS SBnotDef, cast(hp2.foldedSbToSteal as <signed>integer) AS SBnotDef,
cast(hp2.foldBbToStealChance as <signed>integer) AS BBstolen, cast(hp2.foldBbToStealChance as <signed>integer) AS BBstolen,
@ -1691,8 +1701,8 @@ class Sql:
cast(hp2.foldToOtherRaisedStreet4 as <signed>integer) AS f_freq_4, cast(hp2.foldToOtherRaisedStreet4 as <signed>integer) AS f_freq_4,
cast(hp2.wonWhenSeenStreet1 as <signed>integer) AS w_w_s_1, cast(hp2.wonWhenSeenStreet1 as <signed>integer) AS w_w_s_1,
cast(hp2.wonAtSD as <signed>integer) AS wmsd, cast(hp2.wonAtSD as <signed>integer) AS wmsd,
cast(hp2.stealAttemptChance as <signed>integer) AS steal_opp, cast(hp2.raiseFirstInChance as <signed>integer) AS steal_opp,
cast(hp2.stealAttempted as <signed>integer) AS steal, cast(hp2.raisedFirstIn as <signed>integer) AS steal,
cast(hp2.foldSbToStealChance as <signed>integer) AS SBstolen, cast(hp2.foldSbToStealChance as <signed>integer) AS SBstolen,
cast(hp2.foldedSbToSteal as <signed>integer) AS SBnotDef, cast(hp2.foldedSbToSteal as <signed>integer) AS SBnotDef,
cast(hp2.foldBbToStealChance as <signed>integer) AS BBstolen, cast(hp2.foldBbToStealChance as <signed>integer) AS BBstolen,
@ -1794,8 +1804,8 @@ class Sql:
cast(hp2.foldToOtherRaisedStreet4 as <signed>integer) AS f_freq_4, cast(hp2.foldToOtherRaisedStreet4 as <signed>integer) AS f_freq_4,
cast(hp2.wonWhenSeenStreet1 as <signed>integer) AS w_w_s_1, cast(hp2.wonWhenSeenStreet1 as <signed>integer) AS w_w_s_1,
cast(hp2.wonAtSD as <signed>integer) AS wmsd, cast(hp2.wonAtSD as <signed>integer) AS wmsd,
cast(hp2.stealAttemptChance as <signed>integer) AS steal_opp, cast(hp2.raiseFirstInChance as <signed>integer) AS steal_opp,
cast(hp2.stealAttempted as <signed>integer) AS steal, cast(hp2.raisedFirstIn as <signed>integer) AS steal,
cast(hp2.foldSbToStealChance as <signed>integer) AS SBstolen, cast(hp2.foldSbToStealChance as <signed>integer) AS SBstolen,
cast(hp2.foldedSbToSteal as <signed>integer) AS SBnotDef, cast(hp2.foldedSbToSteal as <signed>integer) AS SBnotDef,
cast(hp2.foldBbToStealChance as <signed>integer) AS BBstolen, cast(hp2.foldBbToStealChance as <signed>integer) AS BBstolen,
@ -2026,11 +2036,35 @@ class Sql:
,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999 ,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999
else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer)) else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer))
end AS pf3 end AS pf3
,case when sum(cast(hp.stealattemptchance as <signed>integer)) = 0 then -999 ,case when sum(cast(hp.raiseFirstInChance as <signed>integer)) = 0 then -999
else 100.0*sum(cast(hp.stealattempted as <signed>integer))/sum(cast(hp.stealattemptchance as <signed>integer)) else 100.0 * sum(cast(hp.raisedFirstIn as <signed>integer)) /
sum(cast(hp.raiseFirstInChance as <signed>integer))
end AS rfi
,case when sum(case hp.position
when 'S' then cast(hp.raiseFirstInChance as <signed>integer)
when '0' then cast(hp.raiseFirstInChance as <signed>integer)
when '1' then cast(hp.raiseFirstInChance as <signed>integer)
else 0
end
) = 0 then -999
else 100.0 *
sum(case hp.position
when 'S' then cast(hp.raisedFirstIn as <signed>integer)
when '0' then cast(hp.raisedFirstIn as <signed>integer)
when '1' then cast(hp.raisedFirstIn as <signed>integer)
else 0
end
) /
sum(case hp.position
when 'S' then cast(hp.raiseFirstInChance as <signed>integer)
when '0' then cast(hp.raiseFirstInChance as <signed>integer)
when '1' then cast(hp.raiseFirstInChance as <signed>integer)
else 0
end
)
end AS steals end AS steals
,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f ,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f
,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd ,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd
,case when sum(cast(hp.street1Seen as <signed>integer)) = 0 then -999 ,case when sum(cast(hp.street1Seen as <signed>integer)) = 0 then -999
else 100.0*sum(cast(hp.sawShowdown as <signed>integer))/sum(cast(hp.street1Seen as <signed>integer)) else 100.0*sum(cast(hp.sawShowdown as <signed>integer))/sum(cast(hp.street1Seen as <signed>integer))
end AS wtsdwsf end AS wtsdwsf
@ -2123,8 +2157,32 @@ class Sql:
,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999 ,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999
else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer)) else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer))
end AS pf3 end AS pf3
,case when sum(cast(hp.stealattemptchance as <signed>integer)) = 0 then -999 ,case when sum(cast(hp.raiseFirstInChance as <signed>integer)) = 0 then -999
else 100.0*sum(cast(hp.stealattempted as <signed>integer))/sum(cast(hp.stealattemptchance as <signed>integer)) else 100.0 * sum(cast(hp.raisedFirstIn as <signed>integer)) /
sum(cast(hp.raiseFirstInChance as <signed>integer))
end AS rfi
,case when sum(case hp.position
when 'S' then cast(hp.raiseFirstInChance as <signed>integer)
when '0' then cast(hp.raiseFirstInChance as <signed>integer)
when '1' then cast(hp.raiseFirstInChance as <signed>integer)
else 0
end
) = 0 then -999
else 100.0 *
sum(case hp.position
when 'S' then cast(hp.raisedFirstIn as <signed>integer)
when '0' then cast(hp.raisedFirstIn as <signed>integer)
when '1' then cast(hp.raisedFirstIn as <signed>integer)
else 0
end
) /
sum(case hp.position
when 'S' then cast(hp.raiseFirstInChance as <signed>integer)
when '0' then cast(hp.raiseFirstInChance as <signed>integer)
when '1' then cast(hp.raiseFirstInChance as <signed>integer)
else 0
end
)
end AS steals end AS steals
,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f ,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f
,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd ,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd
@ -2221,8 +2279,32 @@ class Sql:
,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999 ,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999
else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer)) else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer))
end AS pf3 end AS pf3
,case when sum(cast(hp.stealattemptchance as <signed>integer)) = 0 then -999 ,case when sum(cast(hp.raiseFirstInChance as <signed>integer)) = 0 then -999
else 100.0*sum(cast(hp.stealattempted as <signed>integer))/sum(cast(hp.stealattemptchance as <signed>integer)) else 100.0 * sum(cast(hp.raisedFirstIn as <signed>integer)) /
sum(cast(hp.raiseFirstInChance as <signed>integer))
end AS rfi
,case when sum(case hp.position
when 'S' then cast(hp.raiseFirstInChance as <signed>integer)
when '0' then cast(hp.raiseFirstInChance as <signed>integer)
when '1' then cast(hp.raiseFirstInChance as <signed>integer)
else 0
end
) = 0 then -999
else 100.0 *
sum(case hp.position
when 'S' then cast(hp.raisedFirstIn as <signed>integer)
when '0' then cast(hp.raisedFirstIn as <signed>integer)
when '1' then cast(hp.raisedFirstIn as <signed>integer)
else 0
end
) /
sum(case hp.position
when 'S' then cast(hp.raiseFirstInChance as <signed>integer)
when '0' then cast(hp.raiseFirstInChance as <signed>integer)
when '1' then cast(hp.raiseFirstInChance as <signed>integer)
else 0
end
)
end AS steals end AS steals
,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f ,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f
,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd ,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd
@ -2380,8 +2462,8 @@ class Sql:
,case when sum(street0_3Bchance) = 0 then '0' ,case when sum(street0_3Bchance) = 0 then '0'
else format(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),1) else format(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),1)
end AS pf3 end AS pf3
,case when sum(stealattemptchance) = 0 then '-' ,case when sum(raiseFirstInChance) = 0 then '-'
else format(100.0*sum(stealattempted)/sum(stealattemptchance),1) else format(100.0*sum(raisedFirstIn)/sum(raiseFirstInChance),1)
end AS steals end AS steals
,format(100.0*sum(street1Seen)/sum(HDs),1) AS saw_f ,format(100.0*sum(street1Seen)/sum(HDs),1) AS saw_f
,format(100.0*sum(sawShowdown)/sum(HDs),1) AS sawsd ,format(100.0*sum(sawShowdown)/sum(HDs),1) AS sawsd
@ -2444,6 +2526,8 @@ class Sql:
) hprof2 ) hprof2
on hprof2.gtId = stats.gtId on hprof2.gtId = stats.gtId
order by stats.category, stats.limittype, stats.bigBlindDesc desc <orderbyseats>""" order by stats.category, stats.limittype, stats.bigBlindDesc desc <orderbyseats>"""
#elif db_server == 'sqlite': #TODO
# self.query['playerStats'] = """ """
else: # assume postgres else: # assume postgres
self.query['playerStats'] = """ self.query['playerStats'] = """
SELECT upper(stats.limitType) || ' ' SELECT upper(stats.limitType) || ' '
@ -2483,8 +2567,8 @@ class Sql:
,case when sum(street0_3Bchance) = 0 then '0' ,case when sum(street0_3Bchance) = 0 then '0'
else to_char(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),'90D0') else to_char(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),'90D0')
end AS pf3 end AS pf3
,case when sum(stealattemptchance) = 0 then '-' ,case when sum(raiseFirstInChance) = 0 then '-'
else to_char(100.0*sum(stealattempted)/sum(stealattemptchance),'90D0') else to_char(100.0*sum(raisedFirstIn)/sum(raiseFirstInChance),'90D0')
end AS steals end AS steals
,to_char(100.0*sum(street1Seen)/sum(HDs),'90D0') AS saw_f ,to_char(100.0*sum(street1Seen)/sum(HDs),'90D0') AS saw_f
,to_char(100.0*sum(sawShowdown)/sum(HDs),'90D0') AS sawsd ,to_char(100.0*sum(sawShowdown)/sum(HDs),'90D0') AS sawsd
@ -2547,8 +2631,6 @@ class Sql:
) hprof2 ) hprof2
on hprof2.gtId = stats.gtId on hprof2.gtId = stats.gtId
order by stats.base, stats.limittype, stats.bigBlindDesc desc <orderbyseats>""" order by stats.base, stats.limittype, stats.bigBlindDesc desc <orderbyseats>"""
#elif db_server == 'sqlite':
# self.query['playerStats'] = """ """
if db_server == 'mysql': if db_server == 'mysql':
self.query['playerStatsByPosition'] = """ self.query['playerStatsByPosition'] = """
@ -2608,8 +2690,8 @@ class Sql:
,case when sum(street0_3Bchance) = 0 then '0' ,case when sum(street0_3Bchance) = 0 then '0'
else format(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),1) else format(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),1)
end AS pf3 end AS pf3
,case when sum(stealattemptchance) = 0 then '-' ,case when sum(raiseFirstInChance) = 0 then '-'
else format(100.0*sum(stealattempted)/sum(stealattemptchance),1) else format(100.0*sum(raisedFirstIn)/sum(raiseFirstInChance),1)
end AS steals end AS steals
,format(100.0*sum(street1Seen)/sum(HDs),1) AS saw_f ,format(100.0*sum(street1Seen)/sum(HDs),1) AS saw_f
,format(100.0*sum(sawShowdown)/sum(HDs),1) AS sawsd ,format(100.0*sum(sawShowdown)/sum(HDs),1) AS sawsd
@ -2742,8 +2824,8 @@ class Sql:
,case when sum(street0_3Bchance) = 0 then '0' ,case when sum(street0_3Bchance) = 0 then '0'
else to_char(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),'90D0') else to_char(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),'90D0')
end AS pf3 end AS pf3
,case when sum(stealattemptchance) = 0 then '-' ,case when sum(raiseFirstInChance) = 0 then '-'
else to_char(100.0*sum(stealattempted)/sum(stealattemptchance),'90D0') else to_char(100.0*sum(raisedFirstIn)/sum(raiseFirstInChance),'90D0')
end AS steals end AS steals
,to_char(round(100.0*sum(street1Seen)/sum(HDs)),'90D0') AS saw_f ,to_char(round(100.0*sum(street1Seen)/sum(HDs)),'90D0') AS saw_f
,to_char(round(100.0*sum(sawShowdown)/sum(HDs)),'90D0') AS sawsd ,to_char(round(100.0*sum(sawShowdown)/sum(HDs)),'90D0') AS sawsd
@ -2922,8 +3004,8 @@ class Sql:
,foldToOtherRaisedStreet2 ,foldToOtherRaisedStreet2
,foldToOtherRaisedStreet3 ,foldToOtherRaisedStreet3
,foldToOtherRaisedStreet4 ,foldToOtherRaisedStreet4
,stealAttemptChance ,raiseFirstInChance
,stealAttempted ,raisedFirstIn
,foldBbToStealChance ,foldBbToStealChance
,foldedBbToSteal ,foldedBbToSteal
,foldSbToStealChance ,foldSbToStealChance
@ -3012,8 +3094,8 @@ class Sql:
,sum(foldToOtherRaisedStreet2) ,sum(foldToOtherRaisedStreet2)
,sum(foldToOtherRaisedStreet3) ,sum(foldToOtherRaisedStreet3)
,sum(foldToOtherRaisedStreet4) ,sum(foldToOtherRaisedStreet4)
,sum(stealAttemptChance) ,sum(raiseFirstInChance)
,sum(stealAttempted) ,sum(raisedFirstIn)
,sum(foldBbToStealChance) ,sum(foldBbToStealChance)
,sum(foldedBbToSteal) ,sum(foldedBbToSteal)
,sum(foldSbToStealChance) ,sum(foldSbToStealChance)
@ -3103,8 +3185,8 @@ class Sql:
,foldToOtherRaisedStreet2 ,foldToOtherRaisedStreet2
,foldToOtherRaisedStreet3 ,foldToOtherRaisedStreet3
,foldToOtherRaisedStreet4 ,foldToOtherRaisedStreet4
,stealAttemptChance ,raiseFirstInChance
,stealAttempted ,raisedFirstIn
,foldBbToStealChance ,foldBbToStealChance
,foldedBbToSteal ,foldedBbToSteal
,foldSbToStealChance ,foldSbToStealChance
@ -3193,8 +3275,8 @@ class Sql:
,sum(CAST(foldToOtherRaisedStreet2 as integer)) ,sum(CAST(foldToOtherRaisedStreet2 as integer))
,sum(CAST(foldToOtherRaisedStreet3 as integer)) ,sum(CAST(foldToOtherRaisedStreet3 as integer))
,sum(CAST(foldToOtherRaisedStreet4 as integer)) ,sum(CAST(foldToOtherRaisedStreet4 as integer))
,sum(CAST(stealAttemptChance as integer)) ,sum(CAST(raisedFirstInChance as integer))
,sum(CAST(stealAttempted as integer)) ,sum(CAST(raisedFirstIn as integer))
,sum(CAST(foldBbToStealChance as integer)) ,sum(CAST(foldBbToStealChance as integer))
,sum(CAST(foldedBbToSteal as integer)) ,sum(CAST(foldedBbToSteal as integer))
,sum(CAST(foldSbToStealChance as integer)) ,sum(CAST(foldSbToStealChance as integer))
@ -3284,8 +3366,8 @@ class Sql:
,foldToOtherRaisedStreet2 ,foldToOtherRaisedStreet2
,foldToOtherRaisedStreet3 ,foldToOtherRaisedStreet3
,foldToOtherRaisedStreet4 ,foldToOtherRaisedStreet4
,stealAttemptChance ,raiseFirstInChance
,stealAttempted ,raisedFirstIn
,foldBbToStealChance ,foldBbToStealChance
,foldedBbToSteal ,foldedBbToSteal
,foldSbToStealChance ,foldSbToStealChance
@ -3374,8 +3456,8 @@ class Sql:
,sum(CAST(foldToOtherRaisedStreet2 as integer)) ,sum(CAST(foldToOtherRaisedStreet2 as integer))
,sum(CAST(foldToOtherRaisedStreet3 as integer)) ,sum(CAST(foldToOtherRaisedStreet3 as integer))
,sum(CAST(foldToOtherRaisedStreet4 as integer)) ,sum(CAST(foldToOtherRaisedStreet4 as integer))
,sum(CAST(stealAttemptChance as integer)) ,sum(CAST(raiseFirstInChance as integer))
,sum(CAST(stealAttempted as integer)) ,sum(CAST(raisedFirstIn as integer))
,sum(CAST(foldBbToStealChance as integer)) ,sum(CAST(foldBbToStealChance as integer))
,sum(CAST(foldedBbToSteal as integer)) ,sum(CAST(foldedBbToSteal as integer))
,sum(CAST(foldSbToStealChance as integer)) ,sum(CAST(foldSbToStealChance as integer))
@ -3465,8 +3547,8 @@ class Sql:
foldToOtherRaisedStreet4, foldToOtherRaisedStreet4,
wonWhenSeenStreet1, wonWhenSeenStreet1,
wonAtSD, wonAtSD,
stealAttemptChance, raiseFirstInChance,
stealAttempted, raisedFirstIn,
foldBbToStealChance, foldBbToStealChance,
foldedBbToSteal, foldedBbToSteal,
foldSbToStealChance, foldSbToStealChance,
@ -3554,8 +3636,8 @@ class Sql:
foldToOtherRaisedStreet4=foldToOtherRaisedStreet4+%s, foldToOtherRaisedStreet4=foldToOtherRaisedStreet4+%s,
wonWhenSeenStreet1=wonWhenSeenStreet1+%s, wonWhenSeenStreet1=wonWhenSeenStreet1+%s,
wonAtSD=wonAtSD+%s, wonAtSD=wonAtSD+%s,
stealAttemptChance=stealAttemptChance+%s, raiseFirstInChance=raiseFirstInChance+%s,
stealAttempted=stealAttempted+%s, raisedFirstIn=raisedFirstIn+%s,
foldBbToStealChance=foldBbToStealChance+%s, foldBbToStealChance=foldBbToStealChance+%s,
foldedBbToSteal=foldedBbToSteal+%s, foldedBbToSteal=foldedBbToSteal+%s,
foldSbToStealChance=foldSbToStealChance+%s, foldSbToStealChance=foldSbToStealChance+%s,
@ -3873,8 +3955,8 @@ class Sql:
foldToOtherRaisedStreet2, foldToOtherRaisedStreet2,
foldToOtherRaisedStreet3, foldToOtherRaisedStreet3,
foldToOtherRaisedStreet4, foldToOtherRaisedStreet4,
stealAttemptChance, raiseFirstInChance,
stealAttempted, raisedFirstIn,
foldBbToStealChance, foldBbToStealChance,
foldedBbToSteal, foldedBbToSteal,
foldSbToStealChance, foldSbToStealChance,

View File

@ -351,6 +351,29 @@ def f_BB_steal(stat_dict, player):
'(0/0)', '(0/0)',
'% folded BB to steal') '% folded BB to steal')
def f_steal(stat_dict, player):
""" Folded blind to steal."""
stat = 0.0
try:
folded_blind = stat_dict[player]['sbnotdef'] + stat_dict[player]['bbnotdef']
blind_stolen = stat_dict[player]['sbstolen'] + stat_dict[player]['bbstolen']
stat = float(folded_blind)/float(blind_stolen)
return (stat,
'%3.1f' % (100*stat) + '%',
'fB=%3.1f' % (100*stat) + '%',
'fB_s=%3.1f' % (100*stat) + '%',
'(%d/%d)' % (folded_blind, blind_stolen),
'% folded blind to steal'
)
except:
return (stat,
'NA',
'fB=NA',
'fB_s=NA',
'(0/0)',
'% folded blind to steal')
def three_B(stat_dict, player): def three_B(stat_dict, player):
""" Three bet preflop/3rd.""" """ Three bet preflop/3rd."""
stat = 0.0 stat = 0.0
@ -777,6 +800,7 @@ if __name__== "__main__":
#print "player = ", player, do_stat(stat_dict, player = player, stat = 'steal') #print "player = ", player, do_stat(stat_dict, player = player, stat = 'steal')
#print "player = ", player, do_stat(stat_dict, player = player, stat = 'f_SB_steal') #print "player = ", player, do_stat(stat_dict, player = player, stat = 'f_SB_steal')
#print "player = ", player, do_stat(stat_dict, player = player, stat = 'f_BB_steal') #print "player = ", player, do_stat(stat_dict, player = player, stat = 'f_BB_steal')
#print "player = ", player, do_stat(stat_dict, player = player, stat = 'f_steal')
#print "player = ", player, do_stat(stat_dict, player = player, stat = 'three_B') #print "player = ", player, do_stat(stat_dict, player = player, stat = 'three_B')
#print "player = ", player, do_stat(stat_dict, player = player, stat = 'WMsF') #print "player = ", player, do_stat(stat_dict, player = player, stat = 'WMsF')
#print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq1') #print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq1')

View File

@ -63,68 +63,12 @@ class TourneyFilters(Filters.Filters):
self.make_filter() self.make_filter()
#end def __init__ #end def __init__
def __calendar_dialog(self, widget, entry): def __refresh(self, widget, entry): #identical with Filters
d = gtk.Window(gtk.WINDOW_TOPLEVEL)
d.set_title('Pick a date')
vb = gtk.VBox()
cal = gtk.Calendar()
vb.pack_start(cal, expand=False, padding=0)
btn = gtk.Button('Done')
btn.connect('clicked', self.__get_date, cal, entry, d)
vb.pack_start(btn, expand=False, padding=4)
d.add(vb)
d.set_position(gtk.WIN_POS_MOUSE)
d.show_all()
#end def __calendar_dialog
def __clear_dates(self, w):
self.start_date.set_text('')
self.end_date.set_text('')
#end def __clear_dates
def __get_dates(self):
# self.day_start gives user's start of day in hours
offset = int(self.day_start * 3600) # calc day_start in seconds
t1 = self.start_date.get_text()
t2 = self.end_date.get_text()
if t1 == '':
t1 = '1970-01-02'
if t2 == '':
t2 = '2020-12-12'
s1 = strptime(t1, "%Y-%m-%d") # make time_struct
s2 = strptime(t2, "%Y-%m-%d")
e1 = mktime(s1) + offset # s1 is localtime, but returned time since epoch is UTC, then add the
e2 = mktime(s2) + offset # s2 is localtime, but returned time since epoch is UTC
e2 = e2 + 24 * 3600 - 1 # date test is inclusive, so add 23h 59m 59s to e2
adj_t1 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e1)) # make adjusted string including time
adj_t2 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e2))
log.info("t1="+t1+" adj_t1="+adj_t1+'.')
return (adj_t1, adj_t2)
#end def __get_dates
def __refresh(self, widget, entry):
for w in self.mainVBox.get_children(): for w in self.mainVBox.get_children():
w.destroy() w.destroy()
self.make_filter() self.make_filter()
#end def __refresh #end def __refresh
def __set_hero_name(self, w, site):
_name = w.get_text()
# get_text() returns a str but we want internal variables to be unicode:
_guiname = unicode(_name)
self.heroes[site] = _guiname
#log.debug("setting heroes[%s]: %s"%(site, self.heroes[site]))
#end def __set_hero_name
def __set_num_tourneys(self, w, val): def __set_num_tourneys(self, w, val):
try: try:
self.numTourneys = int(w.get_text()) self.numTourneys = int(w.get_text())
@ -133,25 +77,7 @@ class TourneyFilters(Filters.Filters):
print "setting numTourneys:", self.numTourneys print "setting numTourneys:", self.numTourneys
#end def __set_num_tourneys #end def __set_num_tourneys
def __set_seat_select(self, w, seat): def __toggle_box(self, widget, entry): #identical with Filters
#print "__set_seat_select: seat =", seat, "active =", w.get_active()
self.seats[seat] = w.get_active()
log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) )
#end def __set_seat_select
def __set_site_select(self, w, site):
#print w.get_active()
self.sites[site] = w.get_active()
log.debug("self.sites[%s] set to %s" %(site, self.sites[site]))
#end def __set_site_select
def __set_tourney_type_select(self, w, tourneyType):
#print w.get_active()
self.tourneyTypes[tourneyType] = w.get_active()
log.debug("self.tourney_types[%s] set to %s" %(tourneyType, self.tourneyTypes[tourneyType]))
#end def __set_tourney_type_select
def __toggle_box(self, widget, entry):
if self.boxes[entry].props.visible: if self.boxes[entry].props.visible:
self.boxes[entry].hide() self.boxes[entry].hide()
widget.set_label("show") widget.set_label("show")
@ -160,259 +86,6 @@ class TourneyFilters(Filters.Filters):
widget.set_label("hide") widget.set_label("hide")
#end def __toggle_box #end def __toggle_box
def createPlayerLine(self, hbox, site, player):
log.debug('add:"%s"' % player)
label = gtk.Label(site +" id:")
hbox.pack_start(label, False, False, 3)
pname = gtk.Entry()
pname.set_text(player)
pname.set_width_chars(20)
hbox.pack_start(pname, False, True, 0)
#pname.connect("changed", self.__set_hero_name, site)
# Added EntryCompletion but maybe comboBoxEntry is more flexible? (e.g. multiple choices)
completion = gtk.EntryCompletion()
pname.set_completion(completion)
liststore = gtk.ListStore(gobject.TYPE_STRING)
completion.set_model(liststore)
completion.set_text_column(0)
names = self.db.get_player_names(self.conf, self.siteid[site]) # (config=self.conf, site_id=None, like_player_name="%")
for n in names: # list of single-element "tuples"
_n = Charset.to_gui(n[0])
_nt = (_n, )
liststore.append(_nt)
self.__set_hero_name(pname, site)
#end def createPlayerLine
def createSiteLine(self, hbox, site):
cb = gtk.CheckButton(site)
cb.connect('clicked', self.__set_site_select, site)
cb.set_active(True)
hbox.pack_start(cb, False, False, 0)
#end def createSiteLine
def createTourneyTypeLine(self, hbox, tourneyType):
cb = gtk.CheckButton(str(tourneyType))
cb.connect('clicked', self.__set_tourney_type_select, tourneyType)
hbox.pack_start(cb, False, False, 0)
cb.set_active(True)
#end def createTourneyTypeLine
def fillDateFrame(self, vbox):
# Hat tip to Mika Bostrom - calendar code comes from PokerStats
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['datestitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'dates')
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['dates'] = vbox1
hbox = gtk.HBox()
vbox1.pack_start(hbox, False, True, 0)
lbl_start = gtk.Label('From:')
btn_start = gtk.Button()
btn_start.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
btn_start.connect('clicked', self.__calendar_dialog, self.start_date)
hbox.pack_start(lbl_start, expand=False, padding=3)
hbox.pack_start(btn_start, expand=False, padding=3)
hbox.pack_start(self.start_date, expand=False, padding=2)
#New row for end date
hbox = gtk.HBox()
vbox1.pack_start(hbox, False, True, 0)
lbl_end = gtk.Label(' To:')
btn_end = gtk.Button()
btn_end.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
btn_end.connect('clicked', self.__calendar_dialog, self.end_date)
btn_clear = gtk.Button(label=' Clear Dates ')
btn_clear.connect('clicked', self.__clear_dates)
hbox.pack_start(lbl_end, expand=False, padding=3)
hbox.pack_start(btn_end, expand=False, padding=3)
hbox.pack_start(self.end_date, expand=False, padding=2)
hbox.pack_start(btn_clear, expand=False, padding=15)
#end def fillDateFrame
def fillPlayerFrame(self, vbox, display):
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['playerstitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="refresh", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__refresh, 'players')
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['players'] = vbox1
for site in self.conf.get_supported_sites():
hBox = gtk.HBox(False, 0)
vbox1.pack_start(hBox, False, True, 0)
player = self.conf.supported_sites[site].screen_name
_pname = Charset.to_gui(player)
self.createPlayerLine(hBox, site, _pname)
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, False, 0)
#cb = gtk.CheckButton(self.filterText['groupsall'])
#cb.connect('clicked', self.__set_group_select, 'allplayers')
#hbox.pack_start(cb, False, False, 0)
#self.sbGroups['allplayers'] = cb
#self.groups['allplayers'] = False
#lbl = gtk.Label('Min # Hands:')
#lbl.set_alignment(xalign=1.0, yalign=0.5)
#hbox.pack_start(lbl, expand=True, padding=3)
#phands = gtk.Entry()
#phands.set_text('0')
#phands.set_width_chars(8)
#hbox.pack_start(phands, False, False, 0)
#phands.connect("changed", self.__set_num_hands, site)
top_hbox.pack_start(showb, expand=False, padding=1)
#end def fillPlayerFrame
def fillSeatsFrame(self, vbox, display):
hbox = gtk.HBox(False, 0)
vbox.pack_start(hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['seatstitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'seats')
hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['seats'] = vbox1
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, True, 0)
lbl_from = gtk.Label(self.filterText['seatsbetween'])
lbl_to = gtk.Label(self.filterText['seatsand'])
adj1 = gtk.Adjustment(value=2, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
sb1 = gtk.SpinButton(adjustment=adj1, climb_rate=0.0, digits=0)
adj2 = gtk.Adjustment(value=10, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
sb2 = gtk.SpinButton(adjustment=adj2, climb_rate=0.0, digits=0)
hbox.pack_start(lbl_from, expand=False, padding=3)
hbox.pack_start(sb1, False, False, 0)
hbox.pack_start(lbl_to, expand=False, padding=3)
hbox.pack_start(sb2, False, False, 0)
self.sbSeats['from'] = sb1
self.sbSeats['to'] = sb2
#end def fillSeatsFrame
def fillSitesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
top_hbox.show()
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['sitestitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'sites')
showb.show()
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
self.boxes['sites'] = vbox1
vbox.pack_start(vbox1, False, False, 0)
for site in self.conf.get_supported_sites():
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, True, 0)
self.createSiteLine(hbox, site)
#end def fillSitesFrame
def fillTourneyTypesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['tourneyTypesTitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'tourneyTypes')
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['tourneyTypes'] = vbox1
result = self.db.getTourneyTypesIds()
if len(result) >= 1:
for line in result:
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, True, 0)
self.createTourneyTypeLine(hbox, line[0])
else:
print "INFO: No tourney types returned from database"
log.info("No tourney types returned from database")
#end def fillTourneyTypesFrame
def getDates(self):
return self.__get_dates()
#end def getDates
def getHeroes(self):
return self.heroes
#end def getHeroes
def getNumTourneys(self):
return self.numTourneys
#end def getNumTourneys
def getSeats(self):
if 'from' in self.sbSeats:
self.seats['from'] = self.sbSeats['from'].get_value_as_int()
if 'to' in self.sbSeats:
self.seats['to'] = self.sbSeats['to'].get_value_as_int()
return self.seats
#end def getSeats
def getSiteIds(self):
return self.siteid
#end def getSiteIds
def getSites(self):
return self.sites
#end def getSites
def getTourneyTypes(self):
return self.tourneyTypes
#end def getTourneyTypes
def get_vbox(self):
"""returns the vbox of this thread"""
return self.mainVBox
#end def get_vbox
def make_filter(self): def make_filter(self):
self.tourneyTypes = {} self.tourneyTypes = {}
#self.tourneys = {} #self.tourneys = {}
@ -526,15 +199,4 @@ class TourneyFilters(Filters.Filters):
# make sure any locks on db are released: # make sure any locks on db are released:
self.db.rollback() self.db.rollback()
#end def make_filter #end def make_filter
def registerButton2Name(self, title):
self.Button2.set_label(title)
self.label['button2'] = title
#end def registerButton2Name
def registerButton2Callback(self, callback):
self.Button2.connect("clicked", callback, "clicked")
self.Button2.set_sensitive(True)
self.callback['button2'] = callback
#end def registerButton2Callback
#end class TourneyFilters #end class TourneyFilters

View File

@ -70,7 +70,7 @@ class Table(Table_Window):
for listing in os.popen('xwininfo -root -tree').readlines(): for listing in os.popen('xwininfo -root -tree').readlines():
if re.search(search_string, listing): if re.search(search_string, listing):
# print listing # print listing
mo = re.match('\s+([\dxabcdef]+) (.+):\s\(\"([a-zA-Z.]+)\".+ (\d+)x(\d+)\+\d+\+\d+ \+(\d+)\+(\d+)', listing) mo = re.match('\s+([\dxabcdef]+) (.+):\s\(\"([a-zA-Z0-9\-.]+)\".+ (\d+)x(\d+)\+\d+\+\d+ \+(\d+)\+(\d+)', listing)
self.number = int( mo.group(1), 0) self.number = int( mo.group(1), 0)
self.width = int( mo.group(4) ) self.width = int( mo.group(4) )
self.height = int( mo.group(5) ) self.height = int( mo.group(5) )

View File

@ -107,7 +107,6 @@ import ImapFetcher
import GuiRingPlayerStats import GuiRingPlayerStats
import GuiTourneyPlayerStats import GuiTourneyPlayerStats
import GuiPositionalStats import GuiPositionalStats
import GuiTableViewer
import GuiAutoImport import GuiAutoImport
import GuiGraphViewer import GuiGraphViewer
import GuiSessionViewer import GuiSessionViewer
@ -117,7 +116,7 @@ import Configuration
import Exceptions import Exceptions
import Stats import Stats
VERSION = "0.20.901" VERSION = "0.20.902 plus git"
class fpdb: class fpdb:
@ -798,7 +797,6 @@ class fpdb:
<menuitem action="tourneyplayerstats"/> <menuitem action="tourneyplayerstats"/>
<menuitem action="posnstats"/> <menuitem action="posnstats"/>
<menuitem action="sessionstats"/> <menuitem action="sessionstats"/>
<menuitem action="tableviewer"/>
</menu> </menu>
<menu action="database"> <menu action="database">
<menuitem action="maintaindbs"/> <menuitem action="maintaindbs"/>
@ -839,7 +837,6 @@ class fpdb:
('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view, mysql only)', '<control>T', 'Tourney Player Stats (tabulated view, mysql only)', self.tab_tourney_player_stats), ('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view, mysql only)', '<control>T', 'Tourney Player Stats (tabulated view, mysql only)', self.tab_tourney_player_stats),
('posnstats', None, 'P_ositional Stats (tabulated view)', '<control>O', 'Positional Stats (tabulated view)', self.tab_positional_stats), ('posnstats', None, 'P_ositional Stats (tabulated view)', '<control>O', 'Positional Stats (tabulated view)', self.tab_positional_stats),
('sessionstats', None, 'Session Stats', None, 'Session Stats', self.tab_session_stats), ('sessionstats', None, 'Session Stats', None, 'Session Stats', self.tab_session_stats),
('tableviewer', None, 'Poker_table Viewer (mostly obselete)', None, 'Poker_table Viewer (mostly obselete)', self.tab_table_viewer),
('database', None, '_Database'), ('database', None, '_Database'),
('maintaindbs', None, '_Maintain Databases', None, 'Maintain Databases', self.dia_maintain_dbs), ('maintaindbs', None, '_Maintain Databases', None, 'Maintain Databases', self.dia_maintain_dbs),
('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables), ('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables),
@ -1068,13 +1065,6 @@ This program is free/libre open source software licensed partially under the AGP
You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt and gpl-3.0.txt in the fpdb installation directory.""") You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt and gpl-3.0.txt in the fpdb installation directory.""")
self.add_and_display_tab(mh_tab, "Help") self.add_and_display_tab(mh_tab, "Help")
def tab_table_viewer(self, widget, data=None):
"""opens a table viewer tab"""
new_tv_thread = GuiTableViewer.GuiTableViewer(self.db, self.settings, self.config)
self.threads.append(new_tv_thread)
tv_tab = new_tv_thread.get_vbox()
self.add_and_display_tab(tv_tab, "Table Viewer")
def tabGraphViewer(self, widget, data=None): def tabGraphViewer(self, widget, data=None):
"""opens a graph viewer tab""" """opens a graph viewer tab"""
new_gv_thread = GuiGraphViewer.GuiGraphViewer(self.sql, self.config, self.window) new_gv_thread = GuiGraphViewer.GuiGraphViewer(self.sql, self.config, self.window)

View File

@ -13,14 +13,12 @@ from distutils.core import setup
setup(name = 'fpdb', setup(name = 'fpdb',
description = 'Free Poker Database', description = 'Free Poker Database',
version = '0.12', version = '0.20',
author = 'FPDB team', author = 'FPDB team',
author_email = 'fpdb-main@lists.sourceforge.net', author_email = 'fpdb-main@lists.sourceforge.net',
packages = ['fpdb'], packages = ['fpdb'],
package_dir = { 'fpdb' : 'pyfpdb' }, package_dir = { 'fpdb' : 'pyfpdb' },
data_files = [ data_files = [
('/usr/share/doc/python-fpdb',
['THANKS.txt']),
('/usr/share/pixmaps', ('/usr/share/pixmaps',
['gfx/fpdb-icon.png', 'gfx/fpdb-icon2.png', ['gfx/fpdb-icon.png', 'gfx/fpdb-icon2.png',
'gfx/fpdb-cards.png' 'gfx/fpdb-cards.png'