Merge branch 'master' of git://git.assembla.com/fpdboz.git
This commit is contained in:
commit
793244fb6b
|
@ -33,6 +33,7 @@ psycopg2 ... http://www.stickpeople.com/projects/python/win-psycopg/psycopg2-2.2
|
||||||
(py)pokereval v138 ... http://sourceforge.net/projects/fpdb/files/fpdb/pypoker-eval-win32/pokereval-138.win32.exe/download
|
(py)pokereval v138 ... http://sourceforge.net/projects/fpdb/files/fpdb/pypoker-eval-win32/pokereval-138.win32.exe/download
|
||||||
(Note: There are no official windows builds, this installer is built from source. A walkthrough is in the same directory as this walkthrough.
|
(Note: There are no official windows builds, this installer is built from source. A walkthrough is in the same directory as this walkthrough.
|
||||||
|
|
||||||
|
|
||||||
1.2/ MySQL
|
1.2/ MySQL
|
||||||
|
|
||||||
Install the following file:
|
Install the following file:
|
||||||
|
@ -67,6 +68,26 @@ with this line:
|
||||||
1.3.4/ Save and exit
|
1.3.4/ Save and exit
|
||||||
|
|
||||||
|
|
||||||
|
1.4/ Patch py2exe to stop popup runtime error message
|
||||||
|
|
||||||
|
see http://www.py2exe.org/index.cgi/StderrLog for technical info.
|
||||||
|
|
||||||
|
1.4.1/
|
||||||
|
|
||||||
|
dos> write C:\Python26\Lib\site-packages\py2exe\boot_common.py
|
||||||
|
|
||||||
|
replace:
|
||||||
|
atexit.register(alert, 0,
|
||||||
|
"See the logfile '%s' for details" % fname,
|
||||||
|
"Errors occurred")
|
||||||
|
with:
|
||||||
|
#atexit.register(alert, 0,
|
||||||
|
# "See the logfile '%s' for details" % fname,
|
||||||
|
# "Errors occurred")
|
||||||
|
|
||||||
|
1.4.2/ save and exit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Step 2 Setup GTK
|
Step 2 Setup GTK
|
||||||
-----------------
|
-----------------
|
||||||
|
|
|
@ -2169,7 +2169,7 @@ class Database:
|
||||||
dup = True
|
dup = True
|
||||||
return dup
|
return dup
|
||||||
|
|
||||||
def getGameTypeId(self, siteid, game):
|
def getGameTypeId(self, siteid, game, printdata = False):
|
||||||
c = self.get_cursor()
|
c = self.get_cursor()
|
||||||
#FIXME: Fixed for NL at the moment
|
#FIXME: Fixed for NL at the moment
|
||||||
c.execute(self.sql.query['getGametypeNL'], (siteid, game['type'], game['category'], game['limitType'], game['currency'],
|
c.execute(self.sql.query['getGametypeNL'], (siteid, game['type'], game['category'], game['limitType'], game['currency'],
|
||||||
|
@ -2181,14 +2181,22 @@ class Database:
|
||||||
hilo = "s"
|
hilo = "s"
|
||||||
elif game['category'] in ['razz','27_3draw','badugi', '27_1draw']:
|
elif game['category'] in ['razz','27_3draw','badugi', '27_1draw']:
|
||||||
hilo = "l"
|
hilo = "l"
|
||||||
|
#FIXME: recognise currency
|
||||||
|
#TODO: this wont work for non-standard structures
|
||||||
tmp = self.insertGameTypes( (siteid, game['currency'], game['type'], game['base'], game['category'], game['limitType'], hilo,
|
tmp = self.insertGameTypes( (siteid, game['currency'], game['type'], game['base'], game['category'], game['limitType'], hilo,
|
||||||
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100),
|
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100),
|
||||||
int(Decimal(game['bb'])*100), int(Decimal(game['bb'])*200)) ) #TODO: this wont work for non-standard structures
|
int(Decimal(game['bb'])*100), int(Decimal(game['bb'])*200)), printdata = printdata)
|
||||||
#FIXME: recognise currency
|
|
||||||
return tmp[0]
|
return tmp[0]
|
||||||
|
|
||||||
|
|
||||||
def insertGameTypes(self, row):
|
def insertGameTypes(self, row, printdata = False):
|
||||||
|
if printdata:
|
||||||
|
print _("######## Gametype ##########")
|
||||||
|
import pprint
|
||||||
|
pp = pprint.PrettyPrinter(indent=4)
|
||||||
|
pp.pprint(row)
|
||||||
|
print _("###### End Gametype ########")
|
||||||
|
|
||||||
c = self.get_cursor()
|
c = self.get_cursor()
|
||||||
c.execute( self.sql.query['insertGameTypes'], row )
|
c.execute( self.sql.query['insertGameTypes'], row )
|
||||||
return [self.get_last_insert_id(c)]
|
return [self.get_last_insert_id(c)]
|
||||||
|
|
|
@ -40,7 +40,6 @@ class DerivedStats():
|
||||||
self.handsplayers[player[1]]['winnings'] = 0
|
self.handsplayers[player[1]]['winnings'] = 0
|
||||||
self.handsplayers[player[1]]['rake'] = 0
|
self.handsplayers[player[1]]['rake'] = 0
|
||||||
self.handsplayers[player[1]]['totalProfit'] = 0
|
self.handsplayers[player[1]]['totalProfit'] = 0
|
||||||
self.handsplayers[player[1]]['street4Seen'] = False
|
|
||||||
self.handsplayers[player[1]]['street4Aggr'] = False
|
self.handsplayers[player[1]]['street4Aggr'] = False
|
||||||
self.handsplayers[player[1]]['wonWhenSeenStreet1'] = 0.0
|
self.handsplayers[player[1]]['wonWhenSeenStreet1'] = 0.0
|
||||||
self.handsplayers[player[1]]['sawShowdown'] = False
|
self.handsplayers[player[1]]['sawShowdown'] = False
|
||||||
|
@ -58,6 +57,11 @@ class DerivedStats():
|
||||||
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
|
self.handsplayers[player[1]]['tourneyTypeId'] = None
|
||||||
|
self.handsplayers[player[1]]['street1Seen'] = False
|
||||||
|
self.handsplayers[player[1]]['street2Seen'] = False
|
||||||
|
self.handsplayers[player[1]]['street3Seen'] = False
|
||||||
|
self.handsplayers[player[1]]['street4Seen'] = False
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -152,10 +156,11 @@ class DerivedStats():
|
||||||
else:
|
else:
|
||||||
self.handsplayers[player[1]]['tourneysPlayersIds'] = None
|
self.handsplayers[player[1]]['tourneysPlayersIds'] = None
|
||||||
|
|
||||||
|
#### seen now processed in playersAtStreetX()
|
||||||
# XXX: enumerate(list, start=x) is python 2.6 syntax; 'start'
|
# XXX: enumerate(list, start=x) is python 2.6 syntax; 'start'
|
||||||
#for i, street in enumerate(hand.actionStreets[2:], start=1):
|
#for i, street in enumerate(hand.actionStreets[2:], start=1):
|
||||||
for i, street in enumerate(hand.actionStreets[2:]):
|
#for i, street in enumerate(hand.actionStreets[2:]):
|
||||||
self.seen(self.hand, i+1)
|
# self.seen(self.hand, i+1)
|
||||||
|
|
||||||
for i, street in enumerate(hand.actionStreets[1:]):
|
for i, street in enumerate(hand.actionStreets[1:]):
|
||||||
self.aggr(self.hand, i)
|
self.aggr(self.hand, i)
|
||||||
|
@ -298,6 +303,7 @@ class DerivedStats():
|
||||||
|
|
||||||
# FIXME?? - This isn't couting people that are all in - at least showdown needs to reflect this
|
# FIXME?? - This isn't couting people that are all in - at least showdown needs to reflect this
|
||||||
# ... new code below hopefully fixes this
|
# ... new code below hopefully fixes this
|
||||||
|
# partly fixed, allins are now set as seeing streets because they never do a fold action
|
||||||
|
|
||||||
self.hands['playersAtStreet1'] = 0
|
self.hands['playersAtStreet1'] = 0
|
||||||
self.hands['playersAtStreet2'] = 0
|
self.hands['playersAtStreet2'] = 0
|
||||||
|
@ -324,18 +330,58 @@ class DerivedStats():
|
||||||
# actionStreets[1] is 'DEAL', 'THIRD', 'PREFLOP', so any player dealt cards
|
# actionStreets[1] is 'DEAL', 'THIRD', 'PREFLOP', so any player dealt cards
|
||||||
# must act on this street if dealt cards. Almost certainly broken for the 'all-in blind' case
|
# must act on this street if dealt cards. Almost certainly broken for the 'all-in blind' case
|
||||||
# and right now i don't care - CG
|
# and right now i don't care - CG
|
||||||
|
|
||||||
p_in = set([x[0] for x in hand.actions[hand.actionStreets[1]]])
|
p_in = set([x[0] for x in hand.actions[hand.actionStreets[1]]])
|
||||||
|
|
||||||
|
#
|
||||||
|
# discover who folded on each street and remove them from p_in
|
||||||
|
#
|
||||||
|
# i values as follows 0=BLINDSANTES 1=PREFLOP 2=FLOP 3=TURN 4=RIVER
|
||||||
|
# (for flop games)
|
||||||
|
#
|
||||||
|
# At the beginning of the loop p_in contains the players with cards
|
||||||
|
# at the start of that street.
|
||||||
|
# p_in is reduced each street to become a list of players still-in
|
||||||
|
# e.g. when i=1 (preflop) all players who folded during preflop
|
||||||
|
# are found by pfba() and eliminated from p_in.
|
||||||
|
# Therefore at the end of the loop, p_in contains players remaining
|
||||||
|
# at the end of the action on that street, and can therefore be set
|
||||||
|
# as the value for the number of players who saw the next street
|
||||||
|
#
|
||||||
|
# note that i is 1 in advance of the actual street numbers in the db
|
||||||
|
#
|
||||||
|
# if p_in reduces to 1 player, we must bomb-out immediately
|
||||||
|
# because the hand is over, this will ensure playersAtStreetx
|
||||||
|
# is accurate.
|
||||||
|
#
|
||||||
|
|
||||||
for (i, street) in enumerate(hand.actionStreets):
|
for (i, street) in enumerate(hand.actionStreets):
|
||||||
|
if (i-1) in (1,2,3,4):
|
||||||
|
# p_in stores players with cards at start of this street,
|
||||||
|
# so can set streetxSeen & playersAtStreetx with this information
|
||||||
|
# This hard-coded for i-1 =1,2,3,4 because those are the only columns
|
||||||
|
# in the db! this code section also replaces seen() - more info log 66
|
||||||
|
# nb i=2=flop=street1Seen, hence i-1 term needed
|
||||||
|
self.hands['playersAtStreet%d' % (i-1)] = len(p_in)
|
||||||
|
for player_with_cards in p_in:
|
||||||
|
self.handsplayers[player_with_cards]['street%sSeen' % (i-1)] = True
|
||||||
|
#
|
||||||
|
# find out who folded, and eliminate them from p_in
|
||||||
|
#
|
||||||
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',))
|
||||||
self.hands['playersAtStreet%d' % (i-1)] = len(p_in)
|
#
|
||||||
|
# if everyone folded, we are done, so exit this method immediately
|
||||||
self.hands['playersAtShowdown'] = len(p_in)
|
#
|
||||||
|
if len(p_in) == 1: return None
|
||||||
|
|
||||||
if self.hands['playersAtShowdown'] > 1:
|
#
|
||||||
for player in p_in:
|
# The remaining players in p_in reached showdown (including all-ins
|
||||||
self.handsplayers[player]['sawShowdown'] = True
|
# because they never did a "fold" action in pfba() above)
|
||||||
|
#
|
||||||
|
self.hands['playersAtShowdown'] = len(p_in)
|
||||||
|
for showdown_player in p_in:
|
||||||
|
self.handsplayers[showdown_player]['sawShowdown'] = True
|
||||||
|
|
||||||
def streetXRaises(self, hand):
|
def streetXRaises(self, hand):
|
||||||
# self.actions[street] is a list of all actions in a tuple, contining the action as the second element
|
# self.actions[street] is a list of all actions in a tuple, contining the action as the second element
|
||||||
|
@ -447,17 +493,6 @@ class DerivedStats():
|
||||||
self.handsplayers[pname]['street%dCheckCallRaiseChance' % (i+1)] = True
|
self.handsplayers[pname]['street%dCheckCallRaiseChance' % (i+1)] = True
|
||||||
self.handsplayers[pname]['street%dCheckCallRaiseDone' % (i+1)] = act!='folds'
|
self.handsplayers[pname]['street%dCheckCallRaiseDone' % (i+1)] = act!='folds'
|
||||||
|
|
||||||
def seen(self, hand, i):
|
|
||||||
pas = set()
|
|
||||||
for act in hand.actions[hand.actionStreets[i+1]]:
|
|
||||||
pas.add(act[0])
|
|
||||||
|
|
||||||
for player in hand.players:
|
|
||||||
if player[1] in pas:
|
|
||||||
self.handsplayers[player[1]]['street%sSeen' % i] = True
|
|
||||||
else:
|
|
||||||
self.handsplayers[player[1]]['street%sSeen' % i] = False
|
|
||||||
|
|
||||||
def aggr(self, hand, i):
|
def aggr(self, hand, i):
|
||||||
aggrers = set()
|
aggrers = set()
|
||||||
others = set()
|
others = set()
|
||||||
|
|
|
@ -76,8 +76,8 @@ class Fulltilt(HandHistoryConverter):
|
||||||
(\s\((?P<TURBO>Turbo)\))?)|(?P<UNREADABLE_INFO>.+))
|
(\s\((?P<TURBO>Turbo)\))?)|(?P<UNREADABLE_INFO>.+))
|
||||||
''' % substitutions, re.VERBOSE)
|
''' % substitutions, re.VERBOSE)
|
||||||
re_Button = re.compile('^The button is in seat #(?P<BUTTON>\d+)', re.MULTILINE)
|
re_Button = re.compile('^The button is in seat #(?P<BUTTON>\d+)', re.MULTILINE)
|
||||||
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) \([%(LS)s](?P<CASH>[,.0-9]+)\)$' % substitutions, re.MULTILINE)
|
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) \([%(LS)s]?(?P<CASH>[%(NUM)s]+)\)(?P<SITOUT>, is sitting out)?$' % substitutions, re.MULTILINE)
|
||||||
re_TourneysPlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) \([%(LS)s]?(?P<CASH>[,.0-9]+)\)(, is sitting out)?$' % substitutions, re.MULTILINE)
|
re_SummarySitout = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) is sitting out?$' % substitutions, re.MULTILINE)
|
||||||
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
||||||
|
|
||||||
#static regex for tourney purpose
|
#static regex for tourney purpose
|
||||||
|
@ -150,7 +150,7 @@ class Fulltilt(HandHistoryConverter):
|
||||||
self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
|
self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
|
||||||
self.re_Action = re.compile(r"^%(PLAYERS)s(?P<ATYPE> bets| checks| raises to| completes it to| calls| folds)( [%(LS)s]?(?P<BET>[%(NUM)s]+))?" % self.substitutions, re.MULTILINE)
|
self.re_Action = re.compile(r"^%(PLAYERS)s(?P<ATYPE> bets| checks| raises to| completes it to| calls| folds)( [%(LS)s]?(?P<BET>[%(NUM)s]+))?" % self.substitutions, re.MULTILINE)
|
||||||
self.re_ShowdownAction = re.compile(r"^%s shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
self.re_ShowdownAction = re.compile(r"^%s shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
||||||
self.re_CollectPot = re.compile(r"^Seat (?P<SEAT>[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P<POT>[%(NUM)s]+)\)(, mucked| with.*)" % self.substitutions, re.MULTILINE)
|
self.re_CollectPot = re.compile(r"^Seat (?P<SEAT>[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P<POT>[%(NUM)s]+)\)(, mucked| with.*)?" % self.substitutions, re.MULTILINE)
|
||||||
self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE)
|
self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE)
|
||||||
self.re_ShownCards = re.compile(r"^Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(?P<ACT>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
self.re_ShownCards = re.compile(r"^Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(?P<ACT>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
||||||
|
|
||||||
|
@ -298,13 +298,24 @@ class Fulltilt(HandHistoryConverter):
|
||||||
# Split hand text for FTP, as the regex matches the player names incorrectly
|
# Split hand text for FTP, as the regex matches the player names incorrectly
|
||||||
# in the summary section
|
# in the summary section
|
||||||
pre, post = hand.handText.split('SUMMARY')
|
pre, post = hand.handText.split('SUMMARY')
|
||||||
if hand.gametype['type'] == "ring" :
|
m = self.re_PlayerInfo.finditer(pre)
|
||||||
m = self.re_PlayerInfo.finditer(pre)
|
plist = {}
|
||||||
else: #if hand.gametype['type'] == "tour"
|
|
||||||
m = self.re_TourneysPlayerInfo.finditer(pre)
|
|
||||||
|
|
||||||
|
# Get list of players in header.
|
||||||
for a in m:
|
for a in m:
|
||||||
hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
|
plist[a.group('PNAME')] = [int(a.group('SEAT')), a.group('CASH')]
|
||||||
|
|
||||||
|
if hand.gametype['type'] == "ring" :
|
||||||
|
# Remove any listed as sitting out in the summary as start of hand info unreliable
|
||||||
|
n = self.re_SummarySitout.finditer(post)
|
||||||
|
for b in n:
|
||||||
|
del plist[b.group('PNAME')]
|
||||||
|
print "DEBUG: Deleting '%s' from player dict" %(b.group('PNAME'))
|
||||||
|
|
||||||
|
# Add remaining players
|
||||||
|
for a in plist:
|
||||||
|
seat, stack = plist[a]
|
||||||
|
hand.addPlayer(seat, a, stack)
|
||||||
|
|
||||||
|
|
||||||
def markStreets(self, hand):
|
def markStreets(self, hand):
|
||||||
|
@ -367,7 +378,11 @@ class Fulltilt(HandHistoryConverter):
|
||||||
logging.warning(_("No bringin found, handid =%s") % hand.handid)
|
logging.warning(_("No bringin found, handid =%s") % hand.handid)
|
||||||
|
|
||||||
def readButton(self, hand):
|
def readButton(self, hand):
|
||||||
hand.buttonpos = int(self.re_Button.search(hand.handText).group('BUTTON'))
|
try:
|
||||||
|
hand.buttonpos = int(self.re_Button.search(hand.handText).group('BUTTON'))
|
||||||
|
except AttributeError, e:
|
||||||
|
# FTP has no indication that a hand is cancelled.
|
||||||
|
raise FpdbParseError(_("FTP: readButton: Failed to detect button (hand #%s cancelled?)") % hand.handid)
|
||||||
|
|
||||||
def readHeroCards(self, hand):
|
def readHeroCards(self, hand):
|
||||||
# streets PREFLOP, PREDRAW, and THIRD are special cases beacause
|
# streets PREFLOP, PREDRAW, and THIRD are special cases beacause
|
||||||
|
|
|
@ -59,7 +59,6 @@ class GuiAutoImport (threading.Thread):
|
||||||
|
|
||||||
self.importer = fpdb_import.Importer(self, self.settings, self.config, self.sql)
|
self.importer = fpdb_import.Importer(self, self.settings, self.config, self.sql)
|
||||||
self.importer.setCallHud(True)
|
self.importer.setCallHud(True)
|
||||||
self.importer.setMinPrint(settings['minPrint'])
|
|
||||||
self.importer.setQuiet(False)
|
self.importer.setQuiet(False)
|
||||||
self.importer.setFailOnError(False)
|
self.importer.setFailOnError(False)
|
||||||
self.importer.setHandCount(0)
|
self.importer.setHandCount(0)
|
||||||
|
@ -338,14 +337,11 @@ if __name__== "__main__":
|
||||||
|
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui")
|
parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui")
|
||||||
parser.add_option("-m", "--minPrint", "--status", dest="minPrint", default="0", type="int",
|
|
||||||
help=_("How often to print a one-line status report (0 (default) means never)"))
|
|
||||||
(options, argv) = parser.parse_args()
|
(options, argv) = parser.parse_args()
|
||||||
|
|
||||||
config = Configuration.Config()
|
config = Configuration.Config()
|
||||||
|
|
||||||
settings = {}
|
settings = {}
|
||||||
settings['minPrint'] = options.minPrint
|
|
||||||
if os.name == 'nt': settings['os'] = 'windows'
|
if os.name == 'nt': settings['os'] = 'windows'
|
||||||
else: settings['os'] = 'linuxmac'
|
else: settings['os'] = 'linuxmac'
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,6 @@ class GuiBulkImport():
|
||||||
|
|
||||||
# get the import settings from the gui and save in the importer
|
# get the import settings from the gui and save in the importer
|
||||||
self.importer.setHandCount(int(self.spin_hands.get_text()))
|
self.importer.setHandCount(int(self.spin_hands.get_text()))
|
||||||
self.importer.setMinPrint(int(self.spin_hands.get_text()))
|
|
||||||
self.importer.setQuiet(self.chk_st_st.get_active())
|
self.importer.setQuiet(self.chk_st_st.get_active())
|
||||||
self.importer.setFailOnError(self.chk_fail.get_active())
|
self.importer.setFailOnError(self.chk_fail.get_active())
|
||||||
self.importer.setThreads(int(self.spin_threads.get_text()))
|
self.importer.setThreads(int(self.spin_threads.get_text()))
|
||||||
|
@ -344,8 +343,6 @@ def main(argv=None):
|
||||||
help=_("Conversion filter (*Full Tilt Poker, PokerStars, Everleaf, Absolute)"))
|
help=_("Conversion filter (*Full Tilt Poker, PokerStars, Everleaf, Absolute)"))
|
||||||
parser.add_option("-x", "--failOnError", action="store_true", default=False,
|
parser.add_option("-x", "--failOnError", action="store_true", default=False,
|
||||||
help=_("If this option is passed it quits when it encounters any error"))
|
help=_("If this option is passed it quits when it encounters any error"))
|
||||||
parser.add_option("-m", "--minPrint", "--status", dest="minPrint", default="0", type="int",
|
|
||||||
help=_("How often to print a one-line status report (0 (default) means never)"))
|
|
||||||
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
||||||
help=_("Print some useful one liners"))
|
help=_("Print some useful one liners"))
|
||||||
parser.add_option("-s", "--starsarchive", action="store_true", dest="starsArchive", default=False,
|
parser.add_option("-s", "--starsarchive", action="store_true", dest="starsArchive", default=False,
|
||||||
|
@ -369,7 +366,6 @@ def main(argv=None):
|
||||||
config = Configuration.Config()
|
config = Configuration.Config()
|
||||||
|
|
||||||
settings = {}
|
settings = {}
|
||||||
settings['minPrint'] = options.minPrint
|
|
||||||
if os.name == 'nt': settings['os'] = 'windows'
|
if os.name == 'nt': settings['os'] = 'windows'
|
||||||
else: settings['os'] = 'linuxmac'
|
else: settings['os'] = 'linuxmac'
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,9 @@ class GuiGraphViewer (threading.Thread):
|
||||||
self.graphBox.add(self.canvas)
|
self.graphBox.add(self.canvas)
|
||||||
self.canvas.show()
|
self.canvas.show()
|
||||||
self.canvas.draw()
|
self.canvas.draw()
|
||||||
|
|
||||||
|
#TODO: Do something useful like alert user
|
||||||
|
#print "No hands returned by graph query"
|
||||||
else:
|
else:
|
||||||
self.ax.set_title(_("Profit graph for ring games"+names),fontsize=12)
|
self.ax.set_title(_("Profit graph for ring games"+names),fontsize=12)
|
||||||
|
|
||||||
|
@ -337,10 +340,7 @@ class GuiGraphViewer (threading.Thread):
|
||||||
if len(winnings) == 0:
|
if len(winnings) == 0:
|
||||||
return (None, None, None)
|
return (None, None, None)
|
||||||
|
|
||||||
#Insert a 0th entry into winnings so graph starts 'zerod'
|
green = map(lambda x:float(x[1]), winnings)
|
||||||
winnings.insert(0, (0,0,0))
|
|
||||||
|
|
||||||
green = map(lambda x: float(x[1]), winnings)
|
|
||||||
blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings)
|
blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings)
|
||||||
red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings)
|
red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings)
|
||||||
greenline = cumsum(green)
|
greenline = cumsum(green)
|
||||||
|
|
|
@ -58,7 +58,7 @@ onlinehelp = {'Game':_('Type of Game'),
|
||||||
'Saw_F':_('% Saw Flop vs hands dealt'),
|
'Saw_F':_('% Saw Flop vs hands dealt'),
|
||||||
'SawSD':_('Saw Show Down / River'),
|
'SawSD':_('Saw Show Down / River'),
|
||||||
'WtSDwsF':_('Went To Show Down When Saw Flop'),
|
'WtSDwsF':_('Went To Show Down When Saw Flop'),
|
||||||
'W$SD':_('Amount Won when Show Down seen'),
|
'W$SD':_('% Won some money at showdown'),
|
||||||
'FlAFq':_('Flop Aggression\n% Bet or Raise after seeing Flop'),
|
'FlAFq':_('Flop Aggression\n% Bet or Raise after seeing Flop'),
|
||||||
'TuAFq':_('Turn Aggression\n% Bet or Raise after seeing Turn'),
|
'TuAFq':_('Turn Aggression\n% Bet or Raise after seeing Turn'),
|
||||||
'RvAFq':_('River Aggression\n% Bet or Raise after seeing River'),
|
'RvAFq':_('River Aggression\n% Bet or Raise after seeing River'),
|
||||||
|
|
|
@ -226,7 +226,7 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
|
|
||||||
self.holecards[street][player] = [open, closed]
|
self.holecards[street][player] = [open, closed]
|
||||||
|
|
||||||
def prepInsert(self, db):
|
def prepInsert(self, db, printtest = False):
|
||||||
#####
|
#####
|
||||||
# Players, Gametypes, TourneyTypes are all shared functions that are needed for additional tables
|
# Players, Gametypes, TourneyTypes are all shared functions that are needed for additional tables
|
||||||
# These functions are intended for prep insert eventually
|
# These functions are intended for prep insert eventually
|
||||||
|
@ -235,7 +235,19 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
self.dbid_pids = db.getSqlPlayerIDs([p[1] for p in self.players], self.siteId)
|
self.dbid_pids = db.getSqlPlayerIDs([p[1] for p in self.players], self.siteId)
|
||||||
|
|
||||||
#Gametypes
|
#Gametypes
|
||||||
self.dbid_gt = db.getGameTypeId(self.siteId, self.gametype)
|
hilo = "h"
|
||||||
|
if self.gametype['category'] in ['studhilo', 'omahahilo']:
|
||||||
|
hilo = "s"
|
||||||
|
elif self.gametype['category'] in ['razz','27_3draw','badugi', '27_1draw']:
|
||||||
|
hilo = "l"
|
||||||
|
|
||||||
|
self.gametyperow = (self.siteId, self.gametype['currency'], self.gametype['type'], self.gametype['base'],
|
||||||
|
self.gametype['category'], self.gametype['limitType'], hilo,
|
||||||
|
int(Decimal(self.gametype['sb'])*100), int(Decimal(self.gametype['bb'])*100),
|
||||||
|
int(Decimal(self.gametype['bb'])*100), int(Decimal(self.gametype['bb'])*200))
|
||||||
|
# Note: the above data is calculated in db.getGameTypeId
|
||||||
|
# Only being calculated above so we can grab the testdata
|
||||||
|
self.dbid_gt = db.getGameTypeId(self.siteId, self.gametype, printdata = printtest)
|
||||||
|
|
||||||
if self.tourNo!=None:
|
if self.tourNo!=None:
|
||||||
self.tourneyTypeId = db.createTourneyType(self)
|
self.tourneyTypeId = db.createTourneyType(self)
|
||||||
|
@ -500,7 +512,6 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
|
||||||
# Player in the big blind posts
|
# Player in the big blind posts
|
||||||
# - this is a call of 1 sb and a raise to 1 bb
|
# - this is a call of 1 sb and a raise to 1 bb
|
||||||
#
|
#
|
||||||
|
|
||||||
log.debug("addBlind: %s posts %s, %s" % (player, blindtype, amount))
|
log.debug("addBlind: %s posts %s, %s" % (player, blindtype, amount))
|
||||||
if player is not None:
|
if player is not None:
|
||||||
amount = re.sub(u',', u'', amount) #some sites have commas
|
amount = re.sub(u',', u'', amount) #some sites have commas
|
||||||
|
@ -520,9 +531,16 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
|
||||||
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
|
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
|
||||||
self.pot.addCommonMoney(player, Decimal(self.sb))
|
self.pot.addCommonMoney(player, Decimal(self.sb))
|
||||||
|
|
||||||
self.bets['PREFLOP'][player].append(Decimal(amount))
|
street = 'BLAH'
|
||||||
|
|
||||||
|
if self.gametype['base'] == 'hold':
|
||||||
|
street = 'PREFLOP'
|
||||||
|
elif self.gametype['base'] == 'draw':
|
||||||
|
street = 'DEAL'
|
||||||
|
|
||||||
|
self.bets[street][player].append(Decimal(amount))
|
||||||
self.pot.addMoney(player, Decimal(amount))
|
self.pot.addMoney(player, Decimal(amount))
|
||||||
self.lastBet['PREFLOP'] = Decimal(amount)
|
self.lastBet[street] = Decimal(amount)
|
||||||
self.posted = self.posted + [[player,blindtype]]
|
self.posted = self.posted + [[player,blindtype]]
|
||||||
|
|
||||||
|
|
||||||
|
@ -1142,34 +1160,6 @@ class DrawHand(Hand):
|
||||||
elif builtFrom == "DB":
|
elif builtFrom == "DB":
|
||||||
self.select("dummy") # Will need a handId
|
self.select("dummy") # Will need a handId
|
||||||
|
|
||||||
# Draw games (at least Badugi has blinds - override default Holdem addBlind
|
|
||||||
def addBlind(self, player, blindtype, amount):
|
|
||||||
# if player is None, it's a missing small blind.
|
|
||||||
# The situation we need to cover are:
|
|
||||||
# Player in small blind posts
|
|
||||||
# - this is a bet of 1 sb, as yet uncalled.
|
|
||||||
# Player in the big blind posts
|
|
||||||
# - this is a call of 1 sb and a raise to 1 bb
|
|
||||||
#
|
|
||||||
|
|
||||||
log.debug("addBlind: %s posts %s, %s" % (player, blindtype, amount))
|
|
||||||
if player is not None:
|
|
||||||
self.bets['DEAL'][player].append(Decimal(amount))
|
|
||||||
self.stacks[player] -= Decimal(amount)
|
|
||||||
#print "DEBUG %s posts, stack %s" % (player, self.stacks[player])
|
|
||||||
act = (player, blindtype, Decimal(amount), self.stacks[player]==0)
|
|
||||||
self.actions['BLINDSANTES'].append(act)
|
|
||||||
self.pot.addMoney(player, Decimal(amount))
|
|
||||||
if blindtype == 'big blind':
|
|
||||||
self.lastBet['DEAL'] = Decimal(amount)
|
|
||||||
elif blindtype == 'both':
|
|
||||||
# extra small blind is 'dead'
|
|
||||||
amount = Decimal(amount)/3
|
|
||||||
amount += amount
|
|
||||||
self.lastBet['DEAL'] = Decimal(amount)
|
|
||||||
self.posted = self.posted + [[player,blindtype]]
|
|
||||||
#print "DEBUG: self.posted: %s" %(self.posted)
|
|
||||||
|
|
||||||
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
if player == self.hero: # we have hero's cards just update shown/mucked
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
if shown: self.shown.add(player)
|
if shown: self.shown.add(player)
|
||||||
|
|
|
@ -56,6 +56,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
'10.00': ('2.00', '5.00'), '10': ('2.00', '5.00'),
|
'10.00': ('2.00', '5.00'), '10': ('2.00', '5.00'),
|
||||||
'20.00': ('5.00', '10.00'), '20': ('5.00', '10.00'),
|
'20.00': ('5.00', '10.00'), '20': ('5.00', '10.00'),
|
||||||
'30.00': ('10.00', '15.00'), '30': ('10.00', '15.00'),
|
'30.00': ('10.00', '15.00'), '30': ('10.00', '15.00'),
|
||||||
|
'40.00': ('10.00', '20.00'), '40': ('10.00', '20.00'),
|
||||||
'60.00': ('15.00', '30.00'), '60': ('15.00', '30.00'),
|
'60.00': ('15.00', '30.00'), '60': ('15.00', '30.00'),
|
||||||
'80.00': ('20.00', '40.00'), '80': ('20.00', '40.00'),
|
'80.00': ('20.00', '40.00'), '80': ('20.00', '40.00'),
|
||||||
'100.00': ('25.00', '50.00'), '100': ('25.00', '50.00'),
|
'100.00': ('25.00', '50.00'), '100': ('25.00', '50.00'),
|
||||||
|
|
333
pyfpdb/RushNotesAux.py
Normal file
333
pyfpdb/RushNotesAux.py
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""RushNotesAux.py
|
||||||
|
|
||||||
|
EXPERIMENTAL - USE WITH CARE
|
||||||
|
|
||||||
|
Auxilliary process to push HUD data into the FullTilt player notes XML
|
||||||
|
This will allow a rudimentary "HUD" in rush games
|
||||||
|
|
||||||
|
The existing notes file will be altered by this function
|
||||||
|
"""
|
||||||
|
# Copyright 2010, "Gimick" of the FPDB project fpdb.sourceforge.net
|
||||||
|
#
|
||||||
|
#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.
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
##########for each hand processed, attempts to create update for player notes in FullTilt
|
||||||
|
##########based upon the AW howto notes written by Ray E. Barker (nutomatic) at fpdb.sourceforge.net
|
||||||
|
##########Huge thanks to Ray for his guidance and encouragement to create this !!
|
||||||
|
|
||||||
|
#
|
||||||
|
#debugmode will write logfiles for the __init__ and update_data methods
|
||||||
|
# writes into ./pyfpdb/~Rushdebug.*
|
||||||
|
#
|
||||||
|
debugmode = False
|
||||||
|
|
||||||
|
# Standard Library modules
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from xml.dom import minidom
|
||||||
|
from datetime import datetime
|
||||||
|
from time import *
|
||||||
|
|
||||||
|
# FreePokerDatabase modules
|
||||||
|
from Mucked import Aux_Window
|
||||||
|
from Mucked import Seat_Window
|
||||||
|
from Mucked import Aux_Seats
|
||||||
|
import Stats
|
||||||
|
import Card
|
||||||
|
|
||||||
|
#
|
||||||
|
# overload minidom methods to fix bug where \n is parsed as " ".
|
||||||
|
# described here: http://bugs.python.org/issue7139
|
||||||
|
#
|
||||||
|
|
||||||
|
def _write_data(writer, data, isAttrib=False):
|
||||||
|
"Writes datachars to writer."
|
||||||
|
if isAttrib:
|
||||||
|
data = data.replace("\r", "
").replace("\n", "
")
|
||||||
|
data = data.replace("\t", "	")
|
||||||
|
writer.write(data)
|
||||||
|
minidom._write_data = _write_data
|
||||||
|
|
||||||
|
def writexml(self, writer, indent="", addindent="", newl=""):
|
||||||
|
# indent = current indentation
|
||||||
|
# addindent = indentation to add to higher levels
|
||||||
|
# newl = newline string
|
||||||
|
writer.write(indent+"<" + self.tagName)
|
||||||
|
|
||||||
|
attrs = self._get_attributes()
|
||||||
|
a_names = attrs.keys()
|
||||||
|
a_names.sort()
|
||||||
|
|
||||||
|
for a_name in a_names:
|
||||||
|
writer.write(" %s=\"" % a_name)
|
||||||
|
_write_data(writer, attrs[a_name].value, isAttrib=True)
|
||||||
|
writer.write("\"")
|
||||||
|
if self.childNodes:
|
||||||
|
writer.write(">%s"%(newl))
|
||||||
|
for node in self.childNodes:
|
||||||
|
node.writexml(writer,indent+addindent,addindent,newl)
|
||||||
|
writer.write("%s</%s>%s" % (indent,self.tagName,newl))
|
||||||
|
else:
|
||||||
|
writer.write("/>%s"%(newl))
|
||||||
|
# For an introduction to overriding instance methods, see
|
||||||
|
# http://irrepupavel.com/documents/python/instancemethod/
|
||||||
|
instancemethod = type(minidom.Element.writexml)
|
||||||
|
minidom.Element.writexml = instancemethod(
|
||||||
|
writexml, None, minidom.Element)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RushNotes(Aux_Window):
|
||||||
|
|
||||||
|
def __init__(self, hud, config, params):
|
||||||
|
|
||||||
|
self.hud = hud
|
||||||
|
self.config = config
|
||||||
|
|
||||||
|
#
|
||||||
|
# following line makes all the site params magically available (thanks Ray!)
|
||||||
|
#
|
||||||
|
site_params_dict = self.hud.config.get_site_parameters(self.hud.site)
|
||||||
|
|
||||||
|
heroname = site_params_dict['screen_name']
|
||||||
|
sitename = site_params_dict['site_name']
|
||||||
|
notepath = site_params_dict['site_path'] # this is a temporary hijack of site-path
|
||||||
|
self.heroid = self.hud.db_connection.get_player_id(self.config, sitename, heroname)
|
||||||
|
self.notefile = notepath + "/" + heroname + ".xml"
|
||||||
|
self.rushtables = ("Mach 10", "Lightning", "Celerity", "Flash", "Zoom")
|
||||||
|
|
||||||
|
if not os.path.isfile(self.notefile):
|
||||||
|
self.active = False
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.active = True
|
||||||
|
|
||||||
|
#
|
||||||
|
# read in existing notefile and backup with date/time in name
|
||||||
|
# todo change to not use dom
|
||||||
|
#
|
||||||
|
now = datetime.now()
|
||||||
|
notefilebackup = self.notefile + ".backup." + now.strftime("%Y%m%d%H%M%S")
|
||||||
|
xmlnotefile = minidom.parse(self.notefile)
|
||||||
|
outputfile = open(notefilebackup, 'w')
|
||||||
|
xmlnotefile.writexml(outputfile)
|
||||||
|
outputfile.close()
|
||||||
|
xmlnotefile.unlink
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create a fresh queue file with skeleton XML
|
||||||
|
#
|
||||||
|
self.queuefile = self.notefile + ".queue"
|
||||||
|
queuedom = minidom.Document()
|
||||||
|
|
||||||
|
pld=queuedom.createElement("PLAYERDATA")
|
||||||
|
queuedom.appendChild(pld)
|
||||||
|
|
||||||
|
nts=queuedom.createElement("NOTES")
|
||||||
|
pld.appendChild(nts)
|
||||||
|
|
||||||
|
nte = queuedom.createElement("NOTE")
|
||||||
|
nte = queuedom.createTextNode("\n")
|
||||||
|
nts.insertBefore(nte,None)
|
||||||
|
|
||||||
|
outputfile = open(self.queuefile, 'w')
|
||||||
|
queuedom.writexml(outputfile)
|
||||||
|
outputfile.close()
|
||||||
|
queuedom.unlink
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
#initialise logfiles
|
||||||
|
debugfile=open("~Rushdebug.init", "w")
|
||||||
|
debugfile.write("conf="+str(config)+"\n")
|
||||||
|
debugfile.write("spdi="+str(site_params_dict)+"\n")
|
||||||
|
debugfile.write("para="+str(params)+"\n")
|
||||||
|
debugfile.write("hero="+heroname+" "+str(self.heroid)+"\n")
|
||||||
|
debugfile.write("back="+notefilebackup+"\n")
|
||||||
|
debugfile.write("queu="+self.queuefile+"\n")
|
||||||
|
debugfile.close()
|
||||||
|
|
||||||
|
open("~Rushdebug.data", "w").close()
|
||||||
|
|
||||||
|
|
||||||
|
def update_data(self, new_hand_id, db_connection):
|
||||||
|
#this method called once for every hand processed
|
||||||
|
# self.hud.stat_dict contains the stats information for this hand
|
||||||
|
|
||||||
|
if not self.active:
|
||||||
|
return
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
debugfile=open("~Rushdebug.data", "a")
|
||||||
|
debugfile.write(new_hand_id+"\n")
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+ " update_data begins"+ "\n")
|
||||||
|
debugfile.write("hero="+str(self.heroid)+"\n")
|
||||||
|
#debugfile.write(str(self.hud.stat_dict)+"\n")
|
||||||
|
debugfile.write("table="+self.hud.table.name+"\n")
|
||||||
|
debugfile.write("players="+str(self.hud.stat_dict.keys())+"\n")
|
||||||
|
debugfile.write("db="+str(db_connection)+"\n")
|
||||||
|
|
||||||
|
if self.hud.table.name not in self.rushtables:
|
||||||
|
return
|
||||||
|
#
|
||||||
|
# Grab a list of player id's
|
||||||
|
#
|
||||||
|
handplayers = self.hud.stat_dict.keys()
|
||||||
|
|
||||||
|
#
|
||||||
|
# build a dictionary of stats text for each player in the hand (excluding the hero)
|
||||||
|
# xmlqueuedict contains {playername : stats text}
|
||||||
|
#
|
||||||
|
xmlqueuedict = {}
|
||||||
|
for playerid in handplayers:
|
||||||
|
# ignore hero, no notes available for hero at Full Tilt
|
||||||
|
if playerid == self.heroid: continue
|
||||||
|
|
||||||
|
playername=unicode(str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'playername')[1]))
|
||||||
|
# Use index[3] which is a short description
|
||||||
|
n=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'n')[3] + " ")
|
||||||
|
vpip=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'vpip')[3] + " ")
|
||||||
|
pfr=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'pfr')[3] + " ")
|
||||||
|
three_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'three_B')[3] + " ")
|
||||||
|
cbet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'cbet')[3] + " ")
|
||||||
|
fbbsteal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'f_BB_steal')[3] + " ")
|
||||||
|
|
||||||
|
steal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'steal')[3] + " ")
|
||||||
|
ffreq1=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'ffreq1')[3] + " ")
|
||||||
|
agg_freq=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'agg_freq')[3] + " ")
|
||||||
|
BBper100=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'BBper100')[3])
|
||||||
|
if BBper100[6] == "-": BBper100=BBper100[0:6] + "(" + BBper100[7:] + ")"
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# grab villain known starting hands
|
||||||
|
# only those where they VPIP'd, so limp in the BB will not be shown
|
||||||
|
# sort by hand strength. Output will show position too,
|
||||||
|
# so KK.1 is KK from late posn etc.
|
||||||
|
# ignore non-rush hands (check against known rushtablenames)
|
||||||
|
# cards decoding is hard-coded for holdem, so that's tuff atm
|
||||||
|
# three categories of known hands are shown:
|
||||||
|
# agression preflop hands
|
||||||
|
# non-aggression preflop hands
|
||||||
|
# bigblind called to defend hands
|
||||||
|
#
|
||||||
|
# This isn't perfect, but it isn't too bad a starting point
|
||||||
|
#
|
||||||
|
|
||||||
|
PFcall="PFcall"
|
||||||
|
PFaggr="PFaggr"
|
||||||
|
PFdefend="PFdefend"
|
||||||
|
|
||||||
|
c = db_connection.get_cursor()
|
||||||
|
c.execute(("SELECT handId, position, startCards, street0Aggr, tableName " +
|
||||||
|
"FROM hands, handsPlayers " +
|
||||||
|
"WHERE handsplayers.handId = hands.id " +
|
||||||
|
"AND street0VPI = 1 " +
|
||||||
|
"AND startCards > 0 " +
|
||||||
|
"AND playerId = %d " +
|
||||||
|
"ORDER BY startCards DESC " +
|
||||||
|
";")
|
||||||
|
% int(playerid))
|
||||||
|
|
||||||
|
for (qid, qposition, qstartcards, qstreet0Aggr, qtablename) in c.fetchall():
|
||||||
|
if (debugmode):
|
||||||
|
debugfile.write("pid, hid, pos, cards, aggr, table player"+
|
||||||
|
str(playerid)+"/"+str(qid)+"/"+str(qposition)+"/"+
|
||||||
|
str(qstartcards)+"/"+str(qstreet0Aggr)+"/"+
|
||||||
|
str(qtablename)+"/"+str(playername)+
|
||||||
|
"\n")
|
||||||
|
|
||||||
|
humancards = Card.decodeStartHandValue("holdem", qstartcards)
|
||||||
|
|
||||||
|
if qtablename not in self.rushtables:
|
||||||
|
pass
|
||||||
|
elif qposition == "B" and qstreet0Aggr == False:
|
||||||
|
PFdefend=PFdefend+"/"+humancards
|
||||||
|
elif qstreet0Aggr == True:
|
||||||
|
PFaggr=PFaggr+"/"+humancards+"."+qposition
|
||||||
|
else:
|
||||||
|
PFcall=PFcall+"/"+humancards+"."+qposition
|
||||||
|
c.close
|
||||||
|
|
||||||
|
#
|
||||||
|
# build up final text package (top/tail with ~fpdb~ ~ends~
|
||||||
|
# for later search/replace by Merge module
|
||||||
|
#
|
||||||
|
xmlqueuedict[playername] = ("~fpdb~" + "\n" +
|
||||||
|
n + vpip + pfr + three_B + fbbsteal + "\n" +
|
||||||
|
steal + cbet + ffreq1 + "\n" +
|
||||||
|
agg_freq + BBper100 + "\n" +
|
||||||
|
PFcall+"\n"+PFaggr+"\n"+PFdefend +"\n"
|
||||||
|
"~ends~")
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+" villain data has been processed" + "\n")
|
||||||
|
debugfile.write(str(xmlqueuedict)+"\n")
|
||||||
|
|
||||||
|
#
|
||||||
|
# delaying processing of xml until now. Grab current queuefile contents and
|
||||||
|
# read each existing NOTE element in turn, if matched to a player in xmlqueuedict
|
||||||
|
# update their text in the xml and delete the dictionary item
|
||||||
|
#
|
||||||
|
xmlnotefile = minidom.parse(self.queuefile)
|
||||||
|
notelist = xmlnotefile.getElementsByTagName('NOTE')
|
||||||
|
|
||||||
|
for noteentry in notelist: #for each note in turn
|
||||||
|
noteplayer = noteentry.getAttribute("PlayerId") #extract the playername from xml
|
||||||
|
if noteplayer in xmlqueuedict: # does that player exist in the queue?
|
||||||
|
noteentry.setAttribute("Text",xmlqueuedict[noteplayer])
|
||||||
|
del xmlqueuedict[noteplayer] #remove from list, does not need to be added later on
|
||||||
|
|
||||||
|
#
|
||||||
|
#create entries for new players (those remaining in the dictionary)
|
||||||
|
#
|
||||||
|
if len(xmlqueuedict) > 0:
|
||||||
|
playerdata=xmlnotefile.lastChild #move to the PLAYERDATA node (assume last one in the list)
|
||||||
|
notesnode=playerdata.childNodes[0] #Find NOTES node
|
||||||
|
|
||||||
|
for newplayer in xmlqueuedict:
|
||||||
|
newentry = xmlnotefile.createElement("NOTE")
|
||||||
|
newentry.setAttribute("PlayerId", newplayer)
|
||||||
|
newentry.setAttribute("Text", xmlqueuedict[newplayer])
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
newentry = xmlnotefile.createTextNode("\n")
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+" xml pre-processing complete"+ "\n")
|
||||||
|
|
||||||
|
#
|
||||||
|
# OverWrite existing xml file with updated DOM and cleanup
|
||||||
|
#
|
||||||
|
updatednotes = open(self.queuefile, 'w')
|
||||||
|
xmlnotefile.writexml(updatednotes)
|
||||||
|
updatednotes.close()
|
||||||
|
|
||||||
|
xmlnotefile.unlink
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+" dom written, process finished"+ "\n")
|
||||||
|
debugfile.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
183
pyfpdb/RushNotesMerge.py
Executable file
183
pyfpdb/RushNotesMerge.py
Executable file
|
@ -0,0 +1,183 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""RushNotesMerge.py
|
||||||
|
|
||||||
|
EXPERIMENTAL - USE WITH CARE
|
||||||
|
|
||||||
|
Merge .queue file with hero's note to generate fresh .merge file
|
||||||
|
|
||||||
|
normal usage
|
||||||
|
$> ./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/heroname.xml"
|
||||||
|
|
||||||
|
The generated file can then replace heroname.xml (if all is well).
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Copyright 2010, "Gimick" of the FPDB project fpdb.sourceforge.net
|
||||||
|
#
|
||||||
|
#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.
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Standard Library modules
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from xml.dom import minidom
|
||||||
|
|
||||||
|
#
|
||||||
|
# overload minidom methods to fix bug where \n is parsed as " ".
|
||||||
|
# described here: http://bugs.python.org/issue7139
|
||||||
|
#
|
||||||
|
|
||||||
|
def _write_data(writer, data, isAttrib=False):
|
||||||
|
"Writes datachars to writer."
|
||||||
|
if isAttrib:
|
||||||
|
data = data.replace("\r", "
").replace("\n", "
")
|
||||||
|
data = data.replace("\t", "	")
|
||||||
|
writer.write(data)
|
||||||
|
minidom._write_data = _write_data
|
||||||
|
|
||||||
|
def writexml(self, writer, indent="", addindent="", newl=""):
|
||||||
|
# indent = current indentation
|
||||||
|
# addindent = indentation to add to higher levels
|
||||||
|
# newl = newline string
|
||||||
|
writer.write(indent+"<" + self.tagName)
|
||||||
|
|
||||||
|
attrs = self._get_attributes()
|
||||||
|
a_names = attrs.keys()
|
||||||
|
a_names.sort()
|
||||||
|
|
||||||
|
for a_name in a_names:
|
||||||
|
writer.write(" %s=\"" % a_name)
|
||||||
|
_write_data(writer, attrs[a_name].value, isAttrib=True)
|
||||||
|
writer.write("\"")
|
||||||
|
if self.childNodes:
|
||||||
|
writer.write(">%s"%(newl))
|
||||||
|
for node in self.childNodes:
|
||||||
|
node.writexml(writer,indent+addindent,addindent,newl)
|
||||||
|
writer.write("%s</%s>%s" % (indent,self.tagName,newl))
|
||||||
|
else:
|
||||||
|
writer.write("/>%s"%(newl))
|
||||||
|
# For an introduction to overriding instance methods, see
|
||||||
|
# http://irrepupavel.com/documents/python/instancemethod/
|
||||||
|
instancemethod = type(minidom.Element.writexml)
|
||||||
|
minidom.Element.writexml = instancemethod(
|
||||||
|
writexml, None, minidom.Element)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
statqueue=0
|
||||||
|
statupdated=0
|
||||||
|
statadded=0
|
||||||
|
|
||||||
|
def cleannote(textin):
|
||||||
|
if textin.find("~fpdb~") == -1: return textin
|
||||||
|
if textin.find("~ends~") == -1: return textin
|
||||||
|
if textin.find("~fpdb~") > textin.find("~ends~"): return textin
|
||||||
|
return textin[0:textin.find("~fpdb~")] + textin[textin.find("~ends~")+6:]
|
||||||
|
# get out now if parameter not passed
|
||||||
|
try:
|
||||||
|
sys.argv[1] <> ""
|
||||||
|
except:
|
||||||
|
print "A parameter is required, quitting now"
|
||||||
|
print "normal usage is something like:"
|
||||||
|
print '$> ./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myhero.xml"'
|
||||||
|
quit()
|
||||||
|
|
||||||
|
if not os.path.isfile(sys.argv[1]):
|
||||||
|
print "Hero notes file not found, quitting"
|
||||||
|
print "normal usage is something like:"
|
||||||
|
print '$> ./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myhero.xml"'
|
||||||
|
quit()
|
||||||
|
|
||||||
|
if not os.path.isfile((sys.argv[1]+".queue")):
|
||||||
|
print "Nothing found to merge, quitting"
|
||||||
|
print "Did the HUD not get started during the last session?"
|
||||||
|
print "Has the HUD been stopped and started without merging?"
|
||||||
|
quit()
|
||||||
|
|
||||||
|
print "***************************************************************"
|
||||||
|
print "IMPORTANT: *** Before running this merge: ***"
|
||||||
|
print "Closedown the FullTiltClient and wait for it to completely stop"
|
||||||
|
print "If FullTiltClient was running, run the merge again once it"
|
||||||
|
print "has stopped completely"
|
||||||
|
print "***************************************************************"
|
||||||
|
print
|
||||||
|
print "read from: ", sys.argv[1]
|
||||||
|
print "merge with: ", sys.argv[1]+".queue"
|
||||||
|
|
||||||
|
#read queue and turn into a dict
|
||||||
|
queuedict = {}
|
||||||
|
xmlqueue = minidom.parse(sys.argv[1]+".queue")
|
||||||
|
notelist = xmlqueue.getElementsByTagName('NOTE')
|
||||||
|
|
||||||
|
for noteentry in notelist:
|
||||||
|
noteplayer = noteentry.getAttribute("PlayerId")
|
||||||
|
notetext = noteentry.getAttribute("Text")
|
||||||
|
queuedict[noteplayer] = notetext
|
||||||
|
statqueue = statqueue + 1
|
||||||
|
|
||||||
|
#read existing player note file
|
||||||
|
|
||||||
|
xmlnotefile = minidom.parse(sys.argv[1])
|
||||||
|
notelist = xmlnotefile.getElementsByTagName('NOTE')
|
||||||
|
|
||||||
|
#
|
||||||
|
#for existing players, empty out existing fpdbtext and refill
|
||||||
|
#
|
||||||
|
for noteentry in notelist:
|
||||||
|
noteplayer = noteentry.getAttribute("PlayerId")
|
||||||
|
if noteplayer in queuedict:
|
||||||
|
existingnote = noteentry.getAttribute("Text")
|
||||||
|
newnote=cleannote(existingnote)
|
||||||
|
newnote = newnote + queuedict[noteplayer]
|
||||||
|
noteentry.setAttribute("Text",newnote)
|
||||||
|
statupdated = statupdated + 1
|
||||||
|
del queuedict[noteplayer]
|
||||||
|
|
||||||
|
#
|
||||||
|
#create entries for new players (those remaining in the dictionary)
|
||||||
|
#
|
||||||
|
if len(queuedict) > 0:
|
||||||
|
playerdata=xmlnotefile.lastChild #move to the PLAYERDATA node (assume last one in the list)
|
||||||
|
notesnode=playerdata.childNodes[1] #Find NOTES node
|
||||||
|
|
||||||
|
for newplayer in queuedict:
|
||||||
|
newentry = xmlnotefile.createElement("NOTE")
|
||||||
|
newentry.setAttribute("PlayerId", newplayer)
|
||||||
|
newentry.setAttribute("Text", queuedict[newplayer])
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
newentry = xmlnotefile.createTextNode("\n")
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
statadded=statadded+1
|
||||||
|
|
||||||
|
#print xmlnotefile.toprettyxml()
|
||||||
|
|
||||||
|
mergednotes = open(sys.argv[1]+".merged", 'w')
|
||||||
|
xmlnotefile.writexml(mergednotes)
|
||||||
|
mergednotes.close()
|
||||||
|
|
||||||
|
xmlnotefile.unlink
|
||||||
|
|
||||||
|
print "Merged file has been written to: ", sys.argv[1]+".merged"
|
||||||
|
print ""
|
||||||
|
print "number in queue: ", statqueue
|
||||||
|
print "existing players updated: ", statupdated
|
||||||
|
print "new players added: ", statadded
|
||||||
|
print "\n"
|
||||||
|
print "Use a viewer to check the contents of the merge file."
|
||||||
|
print "If you are happy, carry out the following steps:"
|
||||||
|
print "1 Rename or delete the existing notes file (normally <heroname>.xml"
|
||||||
|
print "2 Rename the .merged file to become the new notes file"
|
194
pyfpdb/RushNotesReadMe.txt
Normal file
194
pyfpdb/RushNotesReadMe.txt
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
aux to write fpdb data to player notes on Full Tilt
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
by Gimick 30th Dec 2010
|
||||||
|
|
||||||
|
RushNotesAux - auxillary processed attached to the full tilt hud
|
||||||
|
builds up fpdb notes "queue" for each villain met while the autoimport is running
|
||||||
|
uses HUD aggregation stats to do this
|
||||||
|
|
||||||
|
RushNotesMerge - stand alone process to merge the existing ftp notes, together with queue
|
||||||
|
produced by Aux.
|
||||||
|
the output file can then be renamed to become the new ftp notes file
|
||||||
|
|
||||||
|
Important info:
|
||||||
|
The Merge process can only be run when ftp client is shutdown
|
||||||
|
- otherwise ftp overwrites the xml on exit.
|
||||||
|
|
||||||
|
Restarting the autoimport will empty the notes"queue" so avoid restarting
|
||||||
|
autoimport until the previous notes "queue" has been merged. You will
|
||||||
|
lose all the queued notes, but these will be regenerated the next time
|
||||||
|
the villian is at your table, so it isn't the end of the world.
|
||||||
|
|
||||||
|
Existing ftp notes _SHOULD_ be preserved, but this isn't guaranteed,
|
||||||
|
you have been warned!
|
||||||
|
|
||||||
|
Existing colour codings should be preserved,
|
||||||
|
this process does not change or set colourcodings.
|
||||||
|
|
||||||
|
Copies of the live ftp notes file should be preserved everytime
|
||||||
|
RushNotesAux (i.e. the HUD is started)
|
||||||
|
|
||||||
|
The AW is hard-coded with just the table names of Micro Rush Poker,
|
||||||
|
and should ignore all other hands.
|
||||||
|
|
||||||
|
What might not work?
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
This isn't tested with Windows, and probably won't work, feedback welcome.
|
||||||
|
Hasn't been tested for co-existance with other sites, feedback welcome.
|
||||||
|
Whenever FTP change their notes file format, this will all break rather spectacularly,
|
||||||
|
you have been warned!
|
||||||
|
|
||||||
|
Getting started:
|
||||||
|
---------------
|
||||||
|
|
||||||
|
1. Set the Hero aggregation to alltime. hero_stat_range="A"
|
||||||
|
This overcomes a sqlite "bug" which has nothing to do with auxillary windows
|
||||||
|
not doing this will slow processing down to about 1 hand per minute.
|
||||||
|
|
||||||
|
2. Set the site_path to be the folder containing the FTP notes xml file
|
||||||
|
(on wine this is normally site_path="/home/blah/.wine/Program Files/Full Tilt Poker/")
|
||||||
|
|
||||||
|
|
||||||
|
Wire-up the aux process:
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
<aw class="RushNotes" module="RushNotesAux" name="Rush1"> </aw>
|
||||||
|
<game aux="Rush1" cols="3" db="fpdb" game_name="holdem" rows="3">
|
||||||
|
|
||||||
|
or whatever works for you.
|
||||||
|
|
||||||
|
|
||||||
|
Play some poker
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Start Autoimport, and rearrange the on-screen stats out of the way
|
||||||
|
(the full HUD must run, killing the HUD kills the AW updates)
|
||||||
|
|
||||||
|
Play whatever you want
|
||||||
|
|
||||||
|
Stop the autoimport
|
||||||
|
|
||||||
|
Exit the Full tilt poker client (ensure it has fully stopped with ps -A)
|
||||||
|
|
||||||
|
execute the following:
|
||||||
|
|
||||||
|
./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myname.xml"
|
||||||
|
|
||||||
|
A revised notes file (blah.merge) should automagically appear in the full tilt root directory.
|
||||||
|
If you are happy with it, replace the existing (myname.xml file)
|
||||||
|
|
||||||
|
|
||||||
|
Since the updates aren't real time, it would be ok to play the rush
|
||||||
|
session with fpdb inactive, but before quitting any of the tables,
|
||||||
|
start the HUD and wait for it to catch-up processing all the hands played.
|
||||||
|
|
||||||
|
|
||||||
|
Summary
|
||||||
|
-------
|
||||||
|
|
||||||
|
This is very rough and ready, but it does what I set-out to achieve.
|
||||||
|
|
||||||
|
All feedback welcome, and if this is useful as a basis for general notes
|
||||||
|
processing in future, then thats great.
|
||||||
|
|
||||||
|
As I find bugs and make improvements, I will push to git.
|
||||||
|
|
||||||
|
|
||||||
|
Much more information below:
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Background
|
||||||
|
----------
|
||||||
|
|
||||||
|
When playing rush poker, some sort of rudimentary HUD would answer simple questions
|
||||||
|
like "is this allin overbet being made by a nit, or a maniac". Although some
|
||||||
|
notes may have been made previously, some statistics would help to backup the decision.
|
||||||
|
|
||||||
|
Currently fpdb cannot support rush because the HUD is always 1 hand or more
|
||||||
|
behind the current action.
|
||||||
|
|
||||||
|
The only way to do this at the moment is to switch to GuiPlayerStats and make a quick
|
||||||
|
enquiry by player name. However, this effectively times you out of all other
|
||||||
|
action if multitabling.
|
||||||
|
|
||||||
|
Full Tilt situation
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Full Tilt notes are stored in xml format ("hero.xml"). Previously these could
|
||||||
|
be updated while the game was in progress, however, FullTilt now cache the
|
||||||
|
notes and write them out when the application exits. This makes it impossible
|
||||||
|
to use the notes as a real-time HUD, and therefore real-time huds are now
|
||||||
|
forced to screen-scrape or poke around in the client memory.
|
||||||
|
|
||||||
|
Accepting this a limitation, this implementation updates the notes only once
|
||||||
|
the FullTilt client has been closed. Obviously, the villain HUD stats are only
|
||||||
|
as at the end of the last session, however, it is hoped this is significantly
|
||||||
|
better than having nothing at all. As the hero's hand history increases, the
|
||||||
|
notes should progressively mature in accuracy.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
--------
|
||||||
|
|
||||||
|
Note that this implementation was written purely to be "good enough" to work
|
||||||
|
for the author, and is not intended as package or production quality. It
|
||||||
|
is contributed as a starting point for others, or for experimental use.
|
||||||
|
|
||||||
|
Thanks to Ray Barker who gave a great deal of help throughout.
|
||||||
|
|
||||||
|
|
||||||
|
The implementation
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
RushNotesAux is an fpdb auxilliary process, and is called for every hand
|
||||||
|
processed by autoimport. Each villain has a note prepared based on the current
|
||||||
|
fpdb data, and this note (in XML format) is stored in a queue file.
|
||||||
|
|
||||||
|
Auxilliary windows were chosen because
|
||||||
|
a) the author has limited fpdb and programming skill
|
||||||
|
b) the auxillary windows handler is well documented and supported
|
||||||
|
c) any code created has access to the full range of stats with little or no extra work
|
||||||
|
d) runs within the HUD, so the aggregation parameters are already available
|
||||||
|
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The notes are only regenerated if a hand is played against the villain. The
|
||||||
|
process does not "bulk load" notes based upon all the player stats in FPDB.
|
||||||
|
|
||||||
|
It is hoped that due to the relatively large hand volume and relatively small
|
||||||
|
player pools, this limitation will be largely overcome after a few sessions
|
||||||
|
although there will obviously be a number of players with no fpdb note.
|
||||||
|
|
||||||
|
The aggregation parameters used for the notes are based upon the HUD parameters.
|
||||||
|
(with the exception of the hand-ranges, which uses its' own criteria (see source)
|
||||||
|
|
||||||
|
Stopping and starting the HUD will erase the previously created notes queue file.
|
||||||
|
|
||||||
|
The HUD must run, so the individual player popups need to be manually relocated.
|
||||||
|
|
||||||
|
Although hard-coded for micro RUSH tablenames, the auxilliary window could
|
||||||
|
probably happily update notes of all cash and tournament players.
|
||||||
|
|
||||||
|
Process overview
|
||||||
|
----------------
|
||||||
|
|
||||||
|
1/ The HUD process is started.
|
||||||
|
1.1/ when the first hand is received, h fresh holding file is created, and
|
||||||
|
a copy of the current live xml note file is created as a security backup.
|
||||||
|
2/ For every hand played, the auxillary window is called
|
||||||
|
3/ Based upon the players in the hand, fpdb will be interrogated
|
||||||
|
and key stats are formatted in xml-style and written out to a holding file.
|
||||||
|
4/ At the end of the session, the HUD is stopped and the poker client closed
|
||||||
|
|
||||||
|
5/ The user can then review the contents of the holding file.
|
||||||
|
6/ A process is begun to "merge" the holding file into the existing player notes
|
||||||
|
7/ A new "merged" file is created. The process attempts to preserve any
|
||||||
|
existing notes, but this cannot be guaranteed.
|
||||||
|
8/ The user can review this merged file, and if they are happy,
|
||||||
|
they replace the existing note file.
|
||||||
|
9/ Note that this process never updates the live notes file in situ, but
|
||||||
|
there is a risk that something goes wrong, and that existing notes could be destroyed.
|
||||||
|
|
|
@ -62,6 +62,43 @@ class FpdbError:
|
||||||
idx = f.find('regression')
|
idx = f.find('regression')
|
||||||
print "(%3d) : %s" %(self.histogram[f], f[idx:])
|
print "(%3d) : %s" %(self.histogram[f], f[idx:])
|
||||||
|
|
||||||
|
def compare_gametypes_file(filename, importer, errors):
|
||||||
|
hashfilename = filename + '.gt'
|
||||||
|
|
||||||
|
in_fh = codecs.open(hashfilename, 'r', 'utf8')
|
||||||
|
whole_file = in_fh.read()
|
||||||
|
in_fh.close()
|
||||||
|
|
||||||
|
testhash = eval(whole_file)
|
||||||
|
|
||||||
|
hhc = importer.getCachedHHC()
|
||||||
|
handlist = hhc.getProcessedHands()
|
||||||
|
|
||||||
|
lookup = {
|
||||||
|
0:'siteId',
|
||||||
|
1:'currency',
|
||||||
|
2:'type',
|
||||||
|
3:'base',
|
||||||
|
4:'game',
|
||||||
|
5:'limit',
|
||||||
|
6:'hilo',
|
||||||
|
7:'Small Blind',
|
||||||
|
8:'Big Blind',
|
||||||
|
9:'Small Bet',
|
||||||
|
10:'Big Bet',
|
||||||
|
}
|
||||||
|
|
||||||
|
for hand in handlist:
|
||||||
|
ghash = hand.gametyperow
|
||||||
|
for i in range(len(ghash)):
|
||||||
|
print "DEBUG: about to compare: '%s' and '%s'" %(ghash[i], testhash[i])
|
||||||
|
if ghash[i] == testhash[i]:
|
||||||
|
# The stats match - continue
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
errors.error_report(filename, hand, lookup[i], ghash, testhash, None)
|
||||||
|
pass
|
||||||
|
|
||||||
def compare_handsplayers_file(filename, importer, errors):
|
def compare_handsplayers_file(filename, importer, errors):
|
||||||
hashfilename = filename + '.hp'
|
hashfilename = filename + '.hp'
|
||||||
|
|
||||||
|
@ -142,6 +179,8 @@ def compare(leaf, importer, errors, site):
|
||||||
compare_handsplayers_file(filename, importer, errors)
|
compare_handsplayers_file(filename, importer, errors)
|
||||||
if os.path.isfile(filename + '.hands'):
|
if os.path.isfile(filename + '.hands'):
|
||||||
compare_hands_file(filename, importer, errors)
|
compare_hands_file(filename, importer, errors)
|
||||||
|
if os.path.isfile(filename + '.gt'):
|
||||||
|
compare_gametypes_file(filename, importer, errors)
|
||||||
|
|
||||||
importer.clearFileList()
|
importer.clearFileList()
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,6 @@ class Importer:
|
||||||
self.cacheSessions = self.config.get_import_parameters().get("cacheSessions")
|
self.cacheSessions = self.config.get_import_parameters().get("cacheSessions")
|
||||||
|
|
||||||
# CONFIGURATION OPTIONS
|
# CONFIGURATION OPTIONS
|
||||||
self.settings.setdefault("minPrint", 30)
|
|
||||||
self.settings.setdefault("handCount", 0)
|
self.settings.setdefault("handCount", 0)
|
||||||
#self.settings.setdefault("allowHudcacheRebuild", True) # NOT USED NOW
|
#self.settings.setdefault("allowHudcacheRebuild", True) # NOT USED NOW
|
||||||
#self.settings.setdefault("forceThreads", 2) # NOT USED NOW
|
#self.settings.setdefault("forceThreads", 2) # NOT USED NOW
|
||||||
|
@ -115,9 +114,6 @@ class Importer:
|
||||||
def setCacheSessions(self, value):
|
def setCacheSessions(self, value):
|
||||||
self.cacheSessions = value
|
self.cacheSessions = value
|
||||||
|
|
||||||
def setMinPrint(self, value):
|
|
||||||
self.settings['minPrint'] = int(value)
|
|
||||||
|
|
||||||
def setHandCount(self, value):
|
def setHandCount(self, value):
|
||||||
self.settings['handCount'] = int(value)
|
self.settings['handCount'] = int(value)
|
||||||
|
|
||||||
|
@ -477,7 +473,7 @@ class Importer:
|
||||||
|
|
||||||
for hand in handlist:
|
for hand in handlist:
|
||||||
if hand is not None:
|
if hand is not None:
|
||||||
hand.prepInsert(self.database)
|
hand.prepInsert(self.database, printtest = self.settings['testData'])
|
||||||
try:
|
try:
|
||||||
hand.insert(self.database, printtest = self.settings['testData'])
|
hand.insert(self.database, printtest = self.settings['testData'])
|
||||||
except Exceptions.FpdbHandDuplicate:
|
except Exceptions.FpdbHandDuplicate:
|
||||||
|
|
|
@ -167,7 +167,7 @@
|
||||||
'street3CheckCallRaiseChance': False,
|
'street3CheckCallRaiseChance': False,
|
||||||
'street3CheckCallRaiseDone': False,
|
'street3CheckCallRaiseDone': False,
|
||||||
'street3Raises': 0,
|
'street3Raises': 0,
|
||||||
'street3Seen': False,
|
'street3Seen': True,
|
||||||
'street4Aggr': False,
|
'street4Aggr': False,
|
||||||
'street4Bets': 0,
|
'street4Bets': 0,
|
||||||
'street4CBChance': False,
|
'street4CBChance': False,
|
||||||
|
@ -184,7 +184,7 @@
|
||||||
'wonAtSD': 1.0,
|
'wonAtSD': 1.0,
|
||||||
'wonWhenSeenStreet1': 1.0,
|
'wonWhenSeenStreet1': 1.0,
|
||||||
'wonWhenSeenStreet2': 1.0,
|
'wonWhenSeenStreet2': 1.0,
|
||||||
'wonWhenSeenStreet3': 0.0,
|
'wonWhenSeenStreet3': 1.0,
|
||||||
'wonWhenSeenStreet4': 0.0},
|
'wonWhenSeenStreet4': 0.0},
|
||||||
u'Player2': { 'card1': 0,
|
u'Player2': { 'card1': 0,
|
||||||
'card2': 0,
|
'card2': 0,
|
||||||
|
@ -355,7 +355,7 @@
|
||||||
'street3CheckCallRaiseChance': False,
|
'street3CheckCallRaiseChance': False,
|
||||||
'street3CheckCallRaiseDone': False,
|
'street3CheckCallRaiseDone': False,
|
||||||
'street3Raises': 0,
|
'street3Raises': 0,
|
||||||
'street3Seen': False,
|
'street3Seen': True,
|
||||||
'street4Aggr': False,
|
'street4Aggr': False,
|
||||||
'street4Bets': 0,
|
'street4Bets': 0,
|
||||||
'street4CBChance': False,
|
'street4CBChance': False,
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,27 @@
|
||||||
|
FullTiltPoker Game #25314791161: Table Squaw Tea (6 max) - $150/$300 - Limit 2-7 Triple Draw - 8:19:00 ET - 2010/11/06
|
||||||
|
|
||||||
|
Seat 1: Hero ($5,208), is sitting out
|
||||||
|
Seat 2: Player1 ($6,795.50), is sitting out
|
||||||
|
Seat 3: Player2 ($4,368)
|
||||||
|
Seat 5: Player3 ($3,625)
|
||||||
|
Seat 6: Player4 ($12,705)
|
||||||
|
Player4 posts the small blind of $75
|
||||||
|
Player2 posts the big blind of $150
|
||||||
|
The button is in seat #5
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Player3 folds
|
||||||
|
Player4 has 15 seconds left to act
|
||||||
|
Player4 folds
|
||||||
|
Uncalled bet of $75 returned to Player2
|
||||||
|
Player2 mucks
|
||||||
|
Player2 wins the pot ($150)
|
||||||
|
*** SUMMARY ***
|
||||||
|
Duration 24s
|
||||||
|
Total pot $150 | Rake $0
|
||||||
|
Seat 1: Hero is sitting out
|
||||||
|
Seat 2: Player1 is sitting out
|
||||||
|
Seat 3: Player2 (big blind) collected ($150)
|
||||||
|
Seat 5: Player3 (button) didn't bet (folded)
|
||||||
|
Seat 6: Player4 (small blind) folded before the draw
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
'importTime': None,
|
'importTime': None,
|
||||||
'maxSeats': 6,
|
'maxSeats': 6,
|
||||||
'playersAtShowdown': 2,
|
'playersAtShowdown': 2,
|
||||||
'playersAtStreet-1': 5,
|
|
||||||
'playersAtStreet0': 2,
|
|
||||||
'playersAtStreet1': 2,
|
'playersAtStreet1': 2,
|
||||||
'playersAtStreet2': 2,
|
'playersAtStreet2': 2,
|
||||||
'playersAtStreet3': 2,
|
'playersAtStreet3': 2,
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
FullTiltPoker Game #25585334444: Table Rocky Cliff (6 max) - $250/$500 - Limit 2-7 Triple Draw - 18:08:00 ET - 2010/11/15
|
||||||
|
|
||||||
|
Seat 2: Player5 ($1,201)
|
||||||
|
Seat 3: Player6 ($4,108.50)
|
||||||
|
Seat 4: Player4 ($13,124.50)
|
||||||
|
Seat 5: Player3 ($5,245)
|
||||||
|
Seat 6: Hero ($5,000)
|
||||||
|
Player4 posts the small blind of $125
|
||||||
|
Player3 posts the big blind of $250
|
||||||
|
The button is in seat #3
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Player5 has 15 seconds left to act
|
||||||
|
Player5 raises to $500
|
||||||
|
Player6 folds
|
||||||
|
Player4 folds
|
||||||
|
Player3 folds
|
||||||
|
Uncalled bet of $250 returned to Player5
|
||||||
|
Player5 mucks
|
||||||
|
Player5 wins the pot ($625)
|
||||||
|
*** SUMMARY ***
|
||||||
|
Duration 18s
|
||||||
|
Total pot $625 | Rake $0
|
||||||
|
Seat 2: Player5 collected ($625)
|
||||||
|
Seat 3: Player6 (button) didn't bet (folded)
|
||||||
|
Seat 4: Player4 (small blind) folded before the draw
|
||||||
|
Seat 5: Player3 (big blind) folded before the draw
|
||||||
|
Seat 6: Hero is sitting out
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
(1, 'USD', 'ring', 'draw', '27_3draw', 'fl', 'l', 12500, 25000, 25000, 50000)
|
|
@ -0,0 +1,32 @@
|
||||||
|
{ 'boardcard1': 0,
|
||||||
|
'boardcard2': 0,
|
||||||
|
'boardcard3': 0,
|
||||||
|
'boardcard4': 0,
|
||||||
|
'boardcard5': 0,
|
||||||
|
'gametypeId': 1,
|
||||||
|
'importTime': None,
|
||||||
|
'maxSeats': 6,
|
||||||
|
'playersAtShowdown': 1,
|
||||||
|
'playersAtStreet-1': 4,
|
||||||
|
'playersAtStreet0': 1,
|
||||||
|
'playersAtStreet1': 1,
|
||||||
|
'playersAtStreet2': 1,
|
||||||
|
'playersAtStreet3': 1,
|
||||||
|
'playersAtStreet4': 0,
|
||||||
|
'playersVpi': 1,
|
||||||
|
'seats': 4,
|
||||||
|
'showdownPot': 0,
|
||||||
|
'siteHandNo': u'25585334444',
|
||||||
|
'startTime': datetime.datetime(2010, 11, 15, 23, 8, tzinfo=pytz.utc),
|
||||||
|
'street0Raises': 1,
|
||||||
|
'street1Pot': 0,
|
||||||
|
'street1Raises': 0,
|
||||||
|
'street2Pot': 0,
|
||||||
|
'street2Raises': 0,
|
||||||
|
'street3Pot': 0,
|
||||||
|
'street3Raises': 0,
|
||||||
|
'street4Pot': 0,
|
||||||
|
'street4Raises': 0,
|
||||||
|
'tableName': u'Rocky Cliff',
|
||||||
|
'texture': None,
|
||||||
|
'tourneyId': None}
|
|
@ -0,0 +1,376 @@
|
||||||
|
{ u'Player3': { 'card1': 0,
|
||||||
|
'card2': 0,
|
||||||
|
'card3': 0,
|
||||||
|
'card4': 0,
|
||||||
|
'card5': 0,
|
||||||
|
'card6': 0,
|
||||||
|
'card7': 0,
|
||||||
|
'foldBbToStealChance': True,
|
||||||
|
'foldSbToStealChance': False,
|
||||||
|
'foldToOtherRaisedStreet0': False,
|
||||||
|
'foldToOtherRaisedStreet1': False,
|
||||||
|
'foldToOtherRaisedStreet2': False,
|
||||||
|
'foldToOtherRaisedStreet3': False,
|
||||||
|
'foldToOtherRaisedStreet4': False,
|
||||||
|
'foldToStreet1CBChance': False,
|
||||||
|
'foldToStreet1CBDone': False,
|
||||||
|
'foldToStreet2CBChance': False,
|
||||||
|
'foldToStreet2CBDone': False,
|
||||||
|
'foldToStreet3CBChance': False,
|
||||||
|
'foldToStreet3CBDone': False,
|
||||||
|
'foldToStreet4CBChance': False,
|
||||||
|
'foldToStreet4CBDone': False,
|
||||||
|
'foldedBbToSteal': True,
|
||||||
|
'foldedSbToSteal': False,
|
||||||
|
'other3BStreet0': False,
|
||||||
|
'other4BStreet0': False,
|
||||||
|
'otherRaisedStreet0': False,
|
||||||
|
'otherRaisedStreet1': False,
|
||||||
|
'otherRaisedStreet2': False,
|
||||||
|
'otherRaisedStreet3': False,
|
||||||
|
'otherRaisedStreet4': False,
|
||||||
|
'position': 'B',
|
||||||
|
'raiseFirstInChance': False,
|
||||||
|
'raisedFirstIn': False,
|
||||||
|
'rake': 0,
|
||||||
|
'sawShowdown': False,
|
||||||
|
'seatNo': 5,
|
||||||
|
'sitout': False,
|
||||||
|
'startCards': 0,
|
||||||
|
'startCash': 524500,
|
||||||
|
'street0Aggr': False,
|
||||||
|
'street0Bets': 0,
|
||||||
|
'street0Calls': 0,
|
||||||
|
'street0Raises': 0,
|
||||||
|
'street0VPI': False,
|
||||||
|
'street0_3BChance': True,
|
||||||
|
'street0_3BDone': False,
|
||||||
|
'street0_4BChance': False,
|
||||||
|
'street0_4BDone': False,
|
||||||
|
'street1Aggr': False,
|
||||||
|
'street1Bets': 0,
|
||||||
|
'street1CBChance': False,
|
||||||
|
'street1CBDone': False,
|
||||||
|
'street1Calls': 0,
|
||||||
|
'street1CheckCallRaiseChance': False,
|
||||||
|
'street1CheckCallRaiseDone': False,
|
||||||
|
'street1Raises': 0,
|
||||||
|
'street1Seen': False,
|
||||||
|
'street2Aggr': False,
|
||||||
|
'street2Bets': 0,
|
||||||
|
'street2CBChance': False,
|
||||||
|
'street2CBDone': False,
|
||||||
|
'street2Calls': 0,
|
||||||
|
'street2CheckCallRaiseChance': False,
|
||||||
|
'street2CheckCallRaiseDone': False,
|
||||||
|
'street2Raises': 0,
|
||||||
|
'street2Seen': False,
|
||||||
|
'street3Aggr': False,
|
||||||
|
'street3Bets': 0,
|
||||||
|
'street3CBChance': False,
|
||||||
|
'street3CBDone': False,
|
||||||
|
'street3Calls': 0,
|
||||||
|
'street3CheckCallRaiseChance': False,
|
||||||
|
'street3CheckCallRaiseDone': False,
|
||||||
|
'street3Raises': 0,
|
||||||
|
'street3Seen': False,
|
||||||
|
'street4Aggr': False,
|
||||||
|
'street4Bets': 0,
|
||||||
|
'street4CBChance': False,
|
||||||
|
'street4CBDone': False,
|
||||||
|
'street4Calls': 0,
|
||||||
|
'street4CheckCallRaiseChance': False,
|
||||||
|
'street4CheckCallRaiseDone': False,
|
||||||
|
'street4Raises': 0,
|
||||||
|
'street4Seen': False,
|
||||||
|
'totalProfit': -25000,
|
||||||
|
'tourneyTypeId': None,
|
||||||
|
'tourneysPlayersIds': None,
|
||||||
|
'winnings': 0,
|
||||||
|
'wonAtSD': 0.0,
|
||||||
|
'wonWhenSeenStreet1': 0.0,
|
||||||
|
'wonWhenSeenStreet2': 0.0,
|
||||||
|
'wonWhenSeenStreet3': 0.0,
|
||||||
|
'wonWhenSeenStreet4': 0.0},
|
||||||
|
u'Player4': { 'card1': 0,
|
||||||
|
'card2': 0,
|
||||||
|
'card3': 0,
|
||||||
|
'card4': 0,
|
||||||
|
'card5': 0,
|
||||||
|
'card6': 0,
|
||||||
|
'card7': 0,
|
||||||
|
'foldBbToStealChance': False,
|
||||||
|
'foldSbToStealChance': True,
|
||||||
|
'foldToOtherRaisedStreet0': False,
|
||||||
|
'foldToOtherRaisedStreet1': False,
|
||||||
|
'foldToOtherRaisedStreet2': False,
|
||||||
|
'foldToOtherRaisedStreet3': False,
|
||||||
|
'foldToOtherRaisedStreet4': False,
|
||||||
|
'foldToStreet1CBChance': False,
|
||||||
|
'foldToStreet1CBDone': False,
|
||||||
|
'foldToStreet2CBChance': False,
|
||||||
|
'foldToStreet2CBDone': False,
|
||||||
|
'foldToStreet3CBChance': False,
|
||||||
|
'foldToStreet3CBDone': False,
|
||||||
|
'foldToStreet4CBChance': False,
|
||||||
|
'foldToStreet4CBDone': False,
|
||||||
|
'foldedBbToSteal': False,
|
||||||
|
'foldedSbToSteal': True,
|
||||||
|
'other3BStreet0': False,
|
||||||
|
'other4BStreet0': False,
|
||||||
|
'otherRaisedStreet0': False,
|
||||||
|
'otherRaisedStreet1': False,
|
||||||
|
'otherRaisedStreet2': False,
|
||||||
|
'otherRaisedStreet3': False,
|
||||||
|
'otherRaisedStreet4': False,
|
||||||
|
'position': 'S',
|
||||||
|
'raiseFirstInChance': False,
|
||||||
|
'raisedFirstIn': False,
|
||||||
|
'rake': 0,
|
||||||
|
'sawShowdown': False,
|
||||||
|
'seatNo': 4,
|
||||||
|
'sitout': False,
|
||||||
|
'startCards': 0,
|
||||||
|
'startCash': 1312450,
|
||||||
|
'street0Aggr': False,
|
||||||
|
'street0Bets': 0,
|
||||||
|
'street0Calls': 0,
|
||||||
|
'street0Raises': 0,
|
||||||
|
'street0VPI': False,
|
||||||
|
'street0_3BChance': True,
|
||||||
|
'street0_3BDone': False,
|
||||||
|
'street0_4BChance': False,
|
||||||
|
'street0_4BDone': False,
|
||||||
|
'street1Aggr': False,
|
||||||
|
'street1Bets': 0,
|
||||||
|
'street1CBChance': False,
|
||||||
|
'street1CBDone': False,
|
||||||
|
'street1Calls': 0,
|
||||||
|
'street1CheckCallRaiseChance': False,
|
||||||
|
'street1CheckCallRaiseDone': False,
|
||||||
|
'street1Raises': 0,
|
||||||
|
'street1Seen': False,
|
||||||
|
'street2Aggr': False,
|
||||||
|
'street2Bets': 0,
|
||||||
|
'street2CBChance': False,
|
||||||
|
'street2CBDone': False,
|
||||||
|
'street2Calls': 0,
|
||||||
|
'street2CheckCallRaiseChance': False,
|
||||||
|
'street2CheckCallRaiseDone': False,
|
||||||
|
'street2Raises': 0,
|
||||||
|
'street2Seen': False,
|
||||||
|
'street3Aggr': False,
|
||||||
|
'street3Bets': 0,
|
||||||
|
'street3CBChance': False,
|
||||||
|
'street3CBDone': False,
|
||||||
|
'street3Calls': 0,
|
||||||
|
'street3CheckCallRaiseChance': False,
|
||||||
|
'street3CheckCallRaiseDone': False,
|
||||||
|
'street3Raises': 0,
|
||||||
|
'street3Seen': False,
|
||||||
|
'street4Aggr': False,
|
||||||
|
'street4Bets': 0,
|
||||||
|
'street4CBChance': False,
|
||||||
|
'street4CBDone': False,
|
||||||
|
'street4Calls': 0,
|
||||||
|
'street4CheckCallRaiseChance': False,
|
||||||
|
'street4CheckCallRaiseDone': False,
|
||||||
|
'street4Raises': 0,
|
||||||
|
'street4Seen': False,
|
||||||
|
'totalProfit': -12500,
|
||||||
|
'tourneyTypeId': None,
|
||||||
|
'tourneysPlayersIds': None,
|
||||||
|
'winnings': 0,
|
||||||
|
'wonAtSD': 0.0,
|
||||||
|
'wonWhenSeenStreet1': 0.0,
|
||||||
|
'wonWhenSeenStreet2': 0.0,
|
||||||
|
'wonWhenSeenStreet3': 0.0,
|
||||||
|
'wonWhenSeenStreet4': 0.0},
|
||||||
|
u'Player5': { 'card1': 0,
|
||||||
|
'card2': 0,
|
||||||
|
'card3': 0,
|
||||||
|
'card4': 0,
|
||||||
|
'card5': 0,
|
||||||
|
'card6': 0,
|
||||||
|
'card7': 0,
|
||||||
|
'foldBbToStealChance': False,
|
||||||
|
'foldSbToStealChance': False,
|
||||||
|
'foldToOtherRaisedStreet0': False,
|
||||||
|
'foldToOtherRaisedStreet1': False,
|
||||||
|
'foldToOtherRaisedStreet2': False,
|
||||||
|
'foldToOtherRaisedStreet3': False,
|
||||||
|
'foldToOtherRaisedStreet4': False,
|
||||||
|
'foldToStreet1CBChance': False,
|
||||||
|
'foldToStreet1CBDone': False,
|
||||||
|
'foldToStreet2CBChance': False,
|
||||||
|
'foldToStreet2CBDone': False,
|
||||||
|
'foldToStreet3CBChance': False,
|
||||||
|
'foldToStreet3CBDone': False,
|
||||||
|
'foldToStreet4CBChance': False,
|
||||||
|
'foldToStreet4CBDone': False,
|
||||||
|
'foldedBbToSteal': False,
|
||||||
|
'foldedSbToSteal': False,
|
||||||
|
'other3BStreet0': False,
|
||||||
|
'other4BStreet0': False,
|
||||||
|
'otherRaisedStreet0': False,
|
||||||
|
'otherRaisedStreet1': False,
|
||||||
|
'otherRaisedStreet2': False,
|
||||||
|
'otherRaisedStreet3': False,
|
||||||
|
'otherRaisedStreet4': False,
|
||||||
|
'position': 1,
|
||||||
|
'raiseFirstInChance': True,
|
||||||
|
'raisedFirstIn': True,
|
||||||
|
'rake': 0,
|
||||||
|
'sawShowdown': False,
|
||||||
|
'seatNo': 2,
|
||||||
|
'sitout': False,
|
||||||
|
'startCards': 0,
|
||||||
|
'startCash': 120100,
|
||||||
|
'street0Aggr': True,
|
||||||
|
'street0Bets': 0,
|
||||||
|
'street0Calls': 0,
|
||||||
|
'street0Raises': 0,
|
||||||
|
'street0VPI': True,
|
||||||
|
'street0_3BChance': False,
|
||||||
|
'street0_3BDone': False,
|
||||||
|
'street0_4BChance': False,
|
||||||
|
'street0_4BDone': False,
|
||||||
|
'street1Aggr': False,
|
||||||
|
'street1Bets': 0,
|
||||||
|
'street1CBChance': False,
|
||||||
|
'street1CBDone': False,
|
||||||
|
'street1Calls': 0,
|
||||||
|
'street1CheckCallRaiseChance': False,
|
||||||
|
'street1CheckCallRaiseDone': False,
|
||||||
|
'street1Raises': 0,
|
||||||
|
'street1Seen': False,
|
||||||
|
'street2Aggr': False,
|
||||||
|
'street2Bets': 0,
|
||||||
|
'street2CBChance': False,
|
||||||
|
'street2CBDone': False,
|
||||||
|
'street2Calls': 0,
|
||||||
|
'street2CheckCallRaiseChance': False,
|
||||||
|
'street2CheckCallRaiseDone': False,
|
||||||
|
'street2Raises': 0,
|
||||||
|
'street2Seen': False,
|
||||||
|
'street3Aggr': False,
|
||||||
|
'street3Bets': 0,
|
||||||
|
'street3CBChance': False,
|
||||||
|
'street3CBDone': False,
|
||||||
|
'street3Calls': 0,
|
||||||
|
'street3CheckCallRaiseChance': False,
|
||||||
|
'street3CheckCallRaiseDone': False,
|
||||||
|
'street3Raises': 0,
|
||||||
|
'street3Seen': False,
|
||||||
|
'street4Aggr': False,
|
||||||
|
'street4Bets': 0,
|
||||||
|
'street4CBChance': False,
|
||||||
|
'street4CBDone': False,
|
||||||
|
'street4Calls': 0,
|
||||||
|
'street4CheckCallRaiseChance': False,
|
||||||
|
'street4CheckCallRaiseDone': False,
|
||||||
|
'street4Raises': 0,
|
||||||
|
'street4Seen': False,
|
||||||
|
'totalProfit': -25000,
|
||||||
|
'tourneyTypeId': None,
|
||||||
|
'tourneysPlayersIds': None,
|
||||||
|
'winnings': 0,
|
||||||
|
'wonAtSD': 0.0,
|
||||||
|
'wonWhenSeenStreet1': 0.0,
|
||||||
|
'wonWhenSeenStreet2': 0.0,
|
||||||
|
'wonWhenSeenStreet3': 0.0,
|
||||||
|
'wonWhenSeenStreet4': 0.0},
|
||||||
|
u'Player6': { 'card1': 0,
|
||||||
|
'card2': 0,
|
||||||
|
'card3': 0,
|
||||||
|
'card4': 0,
|
||||||
|
'card5': 0,
|
||||||
|
'card6': 0,
|
||||||
|
'card7': 0,
|
||||||
|
'foldBbToStealChance': False,
|
||||||
|
'foldSbToStealChance': False,
|
||||||
|
'foldToOtherRaisedStreet0': False,
|
||||||
|
'foldToOtherRaisedStreet1': False,
|
||||||
|
'foldToOtherRaisedStreet2': False,
|
||||||
|
'foldToOtherRaisedStreet3': False,
|
||||||
|
'foldToOtherRaisedStreet4': False,
|
||||||
|
'foldToStreet1CBChance': False,
|
||||||
|
'foldToStreet1CBDone': False,
|
||||||
|
'foldToStreet2CBChance': False,
|
||||||
|
'foldToStreet2CBDone': False,
|
||||||
|
'foldToStreet3CBChance': False,
|
||||||
|
'foldToStreet3CBDone': False,
|
||||||
|
'foldToStreet4CBChance': False,
|
||||||
|
'foldToStreet4CBDone': False,
|
||||||
|
'foldedBbToSteal': False,
|
||||||
|
'foldedSbToSteal': False,
|
||||||
|
'other3BStreet0': False,
|
||||||
|
'other4BStreet0': False,
|
||||||
|
'otherRaisedStreet0': False,
|
||||||
|
'otherRaisedStreet1': False,
|
||||||
|
'otherRaisedStreet2': False,
|
||||||
|
'otherRaisedStreet3': False,
|
||||||
|
'otherRaisedStreet4': False,
|
||||||
|
'position': 0,
|
||||||
|
'raiseFirstInChance': False,
|
||||||
|
'raisedFirstIn': False,
|
||||||
|
'rake': 0,
|
||||||
|
'sawShowdown': False,
|
||||||
|
'seatNo': 3,
|
||||||
|
'sitout': False,
|
||||||
|
'startCards': 0,
|
||||||
|
'startCash': 410850,
|
||||||
|
'street0Aggr': False,
|
||||||
|
'street0Bets': 0,
|
||||||
|
'street0Calls': 0,
|
||||||
|
'street0Raises': 0,
|
||||||
|
'street0VPI': False,
|
||||||
|
'street0_3BChance': True,
|
||||||
|
'street0_3BDone': False,
|
||||||
|
'street0_4BChance': False,
|
||||||
|
'street0_4BDone': False,
|
||||||
|
'street1Aggr': False,
|
||||||
|
'street1Bets': 0,
|
||||||
|
'street1CBChance': False,
|
||||||
|
'street1CBDone': False,
|
||||||
|
'street1Calls': 0,
|
||||||
|
'street1CheckCallRaiseChance': False,
|
||||||
|
'street1CheckCallRaiseDone': False,
|
||||||
|
'street1Raises': 0,
|
||||||
|
'street1Seen': False,
|
||||||
|
'street2Aggr': False,
|
||||||
|
'street2Bets': 0,
|
||||||
|
'street2CBChance': False,
|
||||||
|
'street2CBDone': False,
|
||||||
|
'street2Calls': 0,
|
||||||
|
'street2CheckCallRaiseChance': False,
|
||||||
|
'street2CheckCallRaiseDone': False,
|
||||||
|
'street2Raises': 0,
|
||||||
|
'street2Seen': False,
|
||||||
|
'street3Aggr': False,
|
||||||
|
'street3Bets': 0,
|
||||||
|
'street3CBChance': False,
|
||||||
|
'street3CBDone': False,
|
||||||
|
'street3Calls': 0,
|
||||||
|
'street3CheckCallRaiseChance': False,
|
||||||
|
'street3CheckCallRaiseDone': False,
|
||||||
|
'street3Raises': 0,
|
||||||
|
'street3Seen': False,
|
||||||
|
'street4Aggr': False,
|
||||||
|
'street4Bets': 0,
|
||||||
|
'street4CBChance': False,
|
||||||
|
'street4CBDone': False,
|
||||||
|
'street4Calls': 0,
|
||||||
|
'street4CheckCallRaiseChance': False,
|
||||||
|
'street4CheckCallRaiseDone': False,
|
||||||
|
'street4Raises': 0,
|
||||||
|
'street4Seen': False,
|
||||||
|
'totalProfit': 0,
|
||||||
|
'tourneyTypeId': None,
|
||||||
|
'tourneysPlayersIds': None,
|
||||||
|
'winnings': 0,
|
||||||
|
'wonAtSD': 0.0,
|
||||||
|
'wonWhenSeenStreet1': 0.0,
|
||||||
|
'wonWhenSeenStreet2': 0.0,
|
||||||
|
'wonWhenSeenStreet3': 0.0,
|
||||||
|
'wonWhenSeenStreet4': 0.0}}
|
|
@ -6,12 +6,10 @@
|
||||||
'gametypeId': 7,
|
'gametypeId': 7,
|
||||||
'importTime': None,
|
'importTime': None,
|
||||||
'maxSeats': 6,
|
'maxSeats': 6,
|
||||||
'playersAtShowdown': 1,
|
'playersAtShowdown': 0,
|
||||||
'playersAtStreet-1': 6,
|
'playersAtStreet1': 0,
|
||||||
'playersAtStreet0': 1,
|
'playersAtStreet2': 0,
|
||||||
'playersAtStreet1': 1,
|
'playersAtStreet3': 0,
|
||||||
'playersAtStreet2': 1,
|
|
||||||
'playersAtStreet3': 1,
|
|
||||||
'playersAtStreet4': 0,
|
'playersAtStreet4': 0,
|
||||||
'playersVpi': 1,
|
'playersVpi': 1,
|
||||||
'seats': 6,
|
'seats': 6,
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
'importTime': None,
|
'importTime': None,
|
||||||
'maxSeats': 9,
|
'maxSeats': 9,
|
||||||
'playersAtShowdown': 0,
|
'playersAtShowdown': 0,
|
||||||
'playersAtStreet-1': 8,
|
|
||||||
'playersAtStreet0': 0,
|
|
||||||
'playersAtStreet1': 0,
|
'playersAtStreet1': 0,
|
||||||
'playersAtStreet2': 0,
|
'playersAtStreet2': 0,
|
||||||
'playersAtStreet3': 0,
|
'playersAtStreet3': 0,
|
||||||
|
|
|
@ -7,11 +7,9 @@
|
||||||
'importTime': None,
|
'importTime': None,
|
||||||
'maxSeats': 6,
|
'maxSeats': 6,
|
||||||
'playersAtShowdown': 2,
|
'playersAtShowdown': 2,
|
||||||
'playersAtStreet-1': 6,
|
'playersAtStreet1': 4,
|
||||||
'playersAtStreet0': 4,
|
|
||||||
'playersAtStreet1': 3,
|
|
||||||
'playersAtStreet2': 3,
|
'playersAtStreet2': 3,
|
||||||
'playersAtStreet3': 2,
|
'playersAtStreet3': 3,
|
||||||
'playersAtStreet4': 0,
|
'playersAtStreet4': 0,
|
||||||
'playersVpi': 3,
|
'playersVpi': 3,
|
||||||
'seats': 6,
|
'seats': 6,
|
||||||
|
|
|
@ -6,13 +6,11 @@
|
||||||
'gametypeId': 5,
|
'gametypeId': 5,
|
||||||
'importTime': None,
|
'importTime': None,
|
||||||
'maxSeats': 8,
|
'maxSeats': 8,
|
||||||
'playersAtShowdown': 1,
|
'playersAtShowdown': 0,
|
||||||
'playersAtStreet-1': 7,
|
|
||||||
'playersAtStreet0': 3,
|
|
||||||
'playersAtStreet1': 3,
|
'playersAtStreet1': 3,
|
||||||
'playersAtStreet2': 2,
|
'playersAtStreet2': 3,
|
||||||
'playersAtStreet3': 1,
|
'playersAtStreet3': 2,
|
||||||
'playersAtStreet4': 1,
|
'playersAtStreet4': 0,
|
||||||
'playersVpi': 3,
|
'playersVpi': 3,
|
||||||
'seats': 7,
|
'seats': 7,
|
||||||
'showdownPot': 0,
|
'showdownPot': 0,
|
||||||
|
|
|
@ -6,15 +6,13 @@
|
||||||
'gametypeId': 1,
|
'gametypeId': 1,
|
||||||
'importTime': None,
|
'importTime': None,
|
||||||
'maxSeats': 8,
|
'maxSeats': 8,
|
||||||
'playersAtShowdown': 1,
|
'playersAtShowdown': 0,
|
||||||
'playersAtStreet-1': 7,
|
'playersAtStreet1': 3,
|
||||||
'playersAtStreet0': 3,
|
'playersAtStreet2': 2,
|
||||||
'playersAtStreet1': 2,
|
'playersAtStreet3': 0,
|
||||||
'playersAtStreet2': 1,
|
'playersAtStreet4': 0,
|
||||||
'playersAtStreet3': 1,
|
|
||||||
'playersAtStreet4': 1,
|
|
||||||
'playersVpi': 2,
|
'playersVpi': 2,
|
||||||
'seats': 8,
|
'seats': 7,
|
||||||
'showdownPot': 0,
|
'showdownPot': 0,
|
||||||
'siteHandNo': u'26190500040',
|
'siteHandNo': u'26190500040',
|
||||||
'startTime': datetime.datetime(2010, 12, 7, 9, 19, tzinfo=pytz.utc),
|
'startTime': datetime.datetime(2010, 12, 7, 9, 19, tzinfo=pytz.utc),
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#Copyright 2009-2010 Carl Gherardi
|
|
||||||
#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 BetfairToFpdb
|
|
||||||
from Hand import *
|
|
||||||
import py
|
|
||||||
|
|
||||||
import Configuration
|
|
||||||
import Database
|
|
||||||
import SQL
|
|
||||||
import fpdb_import
|
|
||||||
|
|
||||||
config = Configuration.Config(file = "HUD_config.test.xml")
|
|
||||||
db = Database.Database(config)
|
|
||||||
sql = SQL.Sql(db_server = 'sqlite')
|
|
||||||
|
|
||||||
settings = {}
|
|
||||||
settings.update(config.get_db_parameters())
|
|
||||||
settings.update(config.get_import_parameters())
|
|
||||||
settings.update(config.get_default_paths())
|
|
||||||
|
|
||||||
def testFlopImport():
|
|
||||||
db.recreate_tables()
|
|
||||||
importer = fpdb_import.Importer(False, settings, config)
|
|
||||||
importer.setDropIndexes("don't drop")
|
|
||||||
importer.setFailOnError(True)
|
|
||||||
importer.setThreads(-1)
|
|
||||||
importer.addBulkImportImportFileOrDir(
|
|
||||||
"""regression-test-files/cash/Betfair/Flop/PLO-6max-USD-0.05-0.10-200909.All.in.river.splitpot.txt""", site="Betfair")
|
|
||||||
importer.setCallHud(False)
|
|
||||||
(stored, dups, partial, errs, ttime) = importer.runImport()
|
|
||||||
importer.clearFileList()
|
|
||||||
|
|
||||||
# Should actually do some testing here
|
|
||||||
assert 1 == 1
|
|
Loading…
Reference in New Issue
Block a user