Merge branch 'master' into good
Conflicts: pyfpdb/Configuration.py pyfpdb/HUD_config.xml.example
This commit is contained in:
commit
019440a71b
|
@ -6,7 +6,7 @@ Build-Depends: debhelper, python-support
|
|||
Standards-Version: 3.8.0
|
||||
|
||||
Package: python-fpdb
|
||||
Architecture: any
|
||||
Architecture: all
|
||||
Section: games
|
||||
Priority: extra
|
||||
Depends: ${python:Depends}, python-gtk2, python-matplotlib,
|
||||
|
|
|
@ -26,17 +26,17 @@ def twoStartCards(value1, suit1, value2, suit2):
|
|||
if value1 < 2 or value2 < 2:
|
||||
ret = 0
|
||||
if value1 == value2: # pairs
|
||||
ret = (13 * (value2-2) + (value2-1) )
|
||||
ret = (13 * (value2-2) + (value2-2) )
|
||||
elif suit1 == suit2:
|
||||
if value1 > value2:
|
||||
ret = 13 * (value1-2) + (value2-1)
|
||||
ret = 13 * (value1-2) + (value2-2)
|
||||
else:
|
||||
ret = 13 * (value2-2) + (value1-1)
|
||||
ret = 13 * (value2-2) + (value1-2)
|
||||
else:
|
||||
if value1 > value2:
|
||||
ret = 13 * (value2-2) + (value2-1)
|
||||
ret = 13 * (value2-2) + (value1-2)
|
||||
else:
|
||||
ret = 13 * (value1-2) + (value2-1)
|
||||
ret = 13 * (value1-2) + (value2-2)
|
||||
|
||||
# print "twoStartCards(", value1, suit1, value2, suit2, ")=", ret
|
||||
return ret
|
||||
|
@ -46,7 +46,6 @@ def twoStartCardString(card):
|
|||
into a string like AQo """
|
||||
ret = 'xx'
|
||||
if card > 0:
|
||||
card -= 1
|
||||
s = ('2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A')
|
||||
x = card / 13
|
||||
y = card - 13 * x
|
||||
|
|
|
@ -282,6 +282,19 @@ class HudUI:
|
|||
def __init__(self, node):
|
||||
self.node = node
|
||||
self.label = node.getAttribute('label')
|
||||
#
|
||||
self.aggregate_ring = fix_tf(node.getAttribute('aggregate_ring_game_stats'))
|
||||
self.aggregate_tour = fix_tf(node.getAttribute('aggregate_tourney_stats'))
|
||||
self.hud_style = node.getAttribute('stat_aggregation_range')
|
||||
self.hud_days = node.getAttribute('aggregation_days')
|
||||
self.agg_bb_mult = node.getAttribute('aggregation_level_multiplier')
|
||||
#
|
||||
self.h_aggregate_ring = fix_tf(node.getAttribute('aggregate_hero_ring_game_stats'))
|
||||
self.h_aggregate_tour = fix_tf(node.getAttribute('aggregate_hero_tourney_stats'))
|
||||
self.h_hud_style = node.getAttribute('hero_stat_aggregation_range')
|
||||
self.h_hud_days = node.getAttribute('hero_aggregation_days')
|
||||
self.h_agg_bb_mult = node.getAttribute('hero_aggregation_level_multiplier')
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return " label = %s\n" % self.label
|
||||
|
@ -320,13 +333,21 @@ class Config:
|
|||
pass
|
||||
|
||||
if file == None: # that didn't work either, just die
|
||||
print "No HUD_config_xml found. Exiting"
|
||||
sys.stderr.write("No HUD_config_xml found. Exiting")
|
||||
print "No HUD_config_xml found after looking in current directory and "+self.default_config_path+"\nExiting"
|
||||
sys.stderr.write("No HUD_config_xml found after looking in current directory and "+self.default_config_path+"\nExiting")
|
||||
print "press enter to continue"
|
||||
sys.stdin.readline()
|
||||
sys.exit()
|
||||
|
||||
# Parse even if there was no real config file found and we are using the example
|
||||
# If using the example, we'll edit it later
|
||||
# sc 2009/10/04 Example already copied to main filename, is this ok?
|
||||
log.info("Reading configuration file %s" % file)
|
||||
if os.sep in file:
|
||||
print "\nReading configuration file %s\n" % file
|
||||
else:
|
||||
print "\nReading configuration file %s" % file
|
||||
print "in %s\n" % os.getcwd()
|
||||
try:
|
||||
doc = xml.dom.minidom.parse(file)
|
||||
except:
|
||||
|
@ -418,6 +439,8 @@ class Config:
|
|||
db_pass = df_parms['db-password'])
|
||||
self.save(file=os.path.join(self.default_config_path, "HUD_config.xml"))
|
||||
|
||||
print ""
|
||||
|
||||
def set_hhArchiveBase(self, path):
|
||||
self.imp.node.setAttribute("hhArchiveBase", path)
|
||||
|
||||
|
@ -467,11 +490,15 @@ class Config:
|
|||
|
||||
def find_example_config(self):
|
||||
if os.path.exists('HUD_config.xml.example'): # there is a HUD_config in the cwd
|
||||
file = 'HUD_config.xml.example' # so we use it
|
||||
file = 'HUD_config.xml' # so we use it
|
||||
try:
|
||||
shutil.copyfile(file+'.example', file)
|
||||
except:
|
||||
file = ''
|
||||
print "No HUD_config.xml found, using HUD_config.xml.example.\n", \
|
||||
"A HUD_config.xml will be written. You will probably have to edit it."
|
||||
"A HUD_config.xml has been created. You will probably have to edit it."
|
||||
sys.stderr.write("No HUD_config.xml found, using HUD_config.xml.example.\n" + \
|
||||
"A HUD_config.xml will be written. You will probably have to edit it.")
|
||||
"A HUD_config.xml has been created. You will probably have to edit it.")
|
||||
else:
|
||||
file = None
|
||||
return file
|
||||
|
@ -615,6 +642,7 @@ class Config:
|
|||
# Allow to change the menu appearance
|
||||
def get_hud_ui_parameters(self):
|
||||
hui = {}
|
||||
|
||||
default_text = 'FPDB Menu - Right click\nLeft-Drag to Move'
|
||||
try:
|
||||
hui['label'] = self.ui.label
|
||||
|
@ -622,6 +650,39 @@ class Config:
|
|||
hui['label'] = default_text
|
||||
except:
|
||||
hui['label'] = default_text
|
||||
|
||||
try: hui['aggregate_ring'] = self.ui.aggregate_ring
|
||||
except: hui['aggregate_ring'] = False
|
||||
|
||||
try: hui['aggregate_tour'] = self.ui.aggregate_tour
|
||||
except: hui['aggregate_tour'] = True
|
||||
|
||||
try: hui['hud_style'] = self.ui.hud_style
|
||||
except: hui['hud_style'] = 'A'
|
||||
|
||||
try: hui['hud_days'] = int(self.ui.hud_days)
|
||||
except: hui['hud_days'] = 90
|
||||
|
||||
try: hui['agg_bb_mult'] = self.ui.agg_bb_mult
|
||||
except: hui['agg_bb_mult'] = 1
|
||||
|
||||
# Hero specific
|
||||
|
||||
try: hui['h_aggregate_ring'] = self.ui.h_aggregate_ring
|
||||
except: hui['h_aggregate_ring'] = False
|
||||
|
||||
try: hui['h_aggregate_tour'] = self.ui.h_aggregate_tour
|
||||
except: hui['h_aggregate_tour'] = True
|
||||
|
||||
try: hui['h_hud_style'] = self.ui.h_hud_style
|
||||
except: hui['h_hud_style'] = 'S'
|
||||
|
||||
try: hui['h_hud_days'] = int(self.ui.h_hud_days)
|
||||
except: hui['h_hud_days'] = 30
|
||||
|
||||
try: hui['h_agg_bb_mult'] = self.ui.h_agg_bb_mult
|
||||
except: hui['h_agg_bb_mult'] = 1
|
||||
|
||||
return hui
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,76 +22,6 @@ class DerivedStats():
|
|||
def __init__(self, hand):
|
||||
self.hand = hand
|
||||
|
||||
self.activeSeats = 0
|
||||
self.position = 0
|
||||
self.tourneyTypeId = 0
|
||||
|
||||
self.HDs = 0
|
||||
self.street0VPI = 0
|
||||
self.street0Aggr = 0
|
||||
self.street0_3BChance = 0
|
||||
self.street0_3BDone = 0
|
||||
self.street0_4BChance = 0
|
||||
self.street0_4BDone = 0
|
||||
|
||||
self.street1Seen = 0
|
||||
self.street2Seen = 0
|
||||
self.street3Seen = 0
|
||||
self.street4Seen = 0
|
||||
self.sawShowdown = 0
|
||||
|
||||
self.street1Aggr = 0
|
||||
self.street2Aggr = 0
|
||||
self.street3Aggr = 0
|
||||
self.street4Aggr = 0
|
||||
|
||||
self.otherRaisedStreet1 = 0
|
||||
self.otherRaisedStreet2 = 0
|
||||
self.otherRaisedStreet3 = 0
|
||||
self.otherRaisedStreet4 = 0
|
||||
self.foldToOtherRaisedStreet1 = 0
|
||||
self.foldToOtherRaisedStreet2 = 0
|
||||
self.foldToOtherRaisedStreet3 = 0
|
||||
self.foldToOtherRaisedStreet4 = 0
|
||||
self.wonWhenSeenStreet1 = 0
|
||||
self.wonAtSD = 0
|
||||
|
||||
self.stealAttemptChance = 0
|
||||
self.stealAttempted = 0
|
||||
self.foldBbToStealChance = 0
|
||||
self.foldedBbToSteal = 0
|
||||
self.foldSbToStealChance = 0
|
||||
self.foldedSbToSteal = 0
|
||||
|
||||
self.street1CBChance = 0
|
||||
self.street1CBDone = 0
|
||||
self.street2CBChance = 0
|
||||
self.street2CBDone = 0
|
||||
self.street3CBChance = 0
|
||||
self.street3CBDone = 0
|
||||
self.street4CBChance = 0
|
||||
self.street4CBDone = 0
|
||||
|
||||
self.foldToStreet1CBChance = 0
|
||||
self.foldToStreet1CBDone = 0
|
||||
self.foldToStreet2CBChance = 0
|
||||
self.foldToStreet2CBDone = 0
|
||||
self.foldToStreet3CBChance = 0
|
||||
self.foldToStreet3CBDone = 0
|
||||
self.foldToStreet4CBChance = 0
|
||||
self.foldToStreet4CBDone = 0
|
||||
|
||||
self.totalProfit = 0
|
||||
|
||||
self.street1CheckCallRaiseChance = 0
|
||||
self.street1CheckCallRaiseDone = 0
|
||||
self.street2CheckCallRaiseChance = 0
|
||||
self.street2CheckCallRaiseDone = 0
|
||||
self.street3CheckCallRaiseChance = 0
|
||||
self.street3CheckCallRaiseDone = 0
|
||||
self.street4CheckCallRaiseChance = 0
|
||||
self.street4CheckCallRaiseDone = 0
|
||||
|
||||
self.hands = {}
|
||||
self.handsplayers = {}
|
||||
|
||||
|
@ -106,6 +36,9 @@ class DerivedStats():
|
|||
print "hands =", self.hands
|
||||
print "handsplayers =", self.handsplayers
|
||||
|
||||
def getHands(self):
|
||||
return self.hands
|
||||
|
||||
def assembleHands(self, hand):
|
||||
self.hands['tableName'] = hand.tablename
|
||||
self.hands['siteHandNo'] = hand.handid
|
||||
|
@ -114,36 +47,790 @@ class DerivedStats():
|
|||
self.hands['importTime'] = None
|
||||
self.hands['seats'] = self.countPlayers(hand)
|
||||
self.hands['maxSeats'] = hand.maxseats
|
||||
self.hands['boardcard1'] = None
|
||||
self.hands['boardcard2'] = None
|
||||
self.hands['boardcard3'] = None
|
||||
self.hands['boardcard4'] = None
|
||||
self.hands['boardcard5'] = None
|
||||
self.hands['texture'] = None # No calculation done for this yet.
|
||||
|
||||
boardCard = 1
|
||||
for street in hand.communityStreets:
|
||||
for card in hand.board[street]:
|
||||
self.hands['boardcard%s' % str(boardCard)] = Card.encodeCard(card)
|
||||
boardCard += 1
|
||||
# This (i think...) is correct for both stud and flop games, as hand.board['street'] disappears, and
|
||||
# those values remain default in stud.
|
||||
boardcards = hand.board['FLOP'] + hand.board['TURN'] + hand.board['RIVER'] + [u'0x', u'0x', u'0x', u'0x', u'0x']
|
||||
cards = [Card.encodeCard(c) for c in boardcards[0:5]]
|
||||
self.hands['boardcard1'] = cards[0]
|
||||
self.hands['boardcard2'] = cards[1]
|
||||
self.hands['boardcard3'] = cards[2]
|
||||
self.hands['boardcard4'] = cards[3]
|
||||
self.hands['boardcard5'] = cards[4]
|
||||
|
||||
#print "DEBUG: self.getStreetTotals = (%s, %s, %s, %s, %s)" % hand.getStreetTotals()
|
||||
#FIXME: Pot size still in decimal, needs to be converted to cents
|
||||
(self.hands['street1Pot'],
|
||||
self.hands['street2Pot'],
|
||||
self.hands['street3Pot'],
|
||||
self.hands['street4Pot'],
|
||||
self.hands['showdownPot']) = hand.getStreetTotals()
|
||||
|
||||
self.vpip(hand) # Gives playersVpi (num of players vpip)
|
||||
#print "DEBUG: vpip: %s" %(self.hands['playersVpi'])
|
||||
self.playersAtStreetX(hand) # Gives playersAtStreet1..4 and Showdown
|
||||
#print "DEBUG: playersAtStreet 1:'%s' 2:'%s' 3:'%s' 4:'%s'" %(self.hands['playersAtStreet1'],self.hands['playersAtStreet2'],self.hands['playersAtStreet3'],self.hands['playersAtStreet4'])
|
||||
self.streetXRaises(hand) # Empty function currently
|
||||
|
||||
# comment TEXT,
|
||||
# commentTs DATETIME
|
||||
|
||||
def assembleHandsPlayers(self, hand):
|
||||
self.vpip(self.hand)
|
||||
for i, street in enumerate(hand.actionStreets[1:]):
|
||||
self.aggr(self.hand, i)
|
||||
|
||||
def assembleHudCache(self, hand):
|
||||
# # def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo
|
||||
# # ,winnings, totalWinnings, positions, actionTypes, actionAmounts, antes):
|
||||
# #"""calculates data for the HUD during import. IMPORTANT: if you change this method make
|
||||
# # sure to also change the following storage method and table_viewer.prepare_data if necessary
|
||||
# #"""
|
||||
# #print "generateHudCacheData, len(player_ids)=", len(player_ids)
|
||||
# #setup subarrays of the result dictionary.
|
||||
# street0VPI=[]
|
||||
# street0Aggr=[]
|
||||
# street0_3BChance=[]
|
||||
# street0_3BDone=[]
|
||||
# street1Seen=[]
|
||||
# street2Seen=[]
|
||||
# street3Seen=[]
|
||||
# street4Seen=[]
|
||||
# sawShowdown=[]
|
||||
# street1Aggr=[]
|
||||
# street2Aggr=[]
|
||||
# street3Aggr=[]
|
||||
# street4Aggr=[]
|
||||
# otherRaisedStreet1=[]
|
||||
# otherRaisedStreet2=[]
|
||||
# otherRaisedStreet3=[]
|
||||
# otherRaisedStreet4=[]
|
||||
# foldToOtherRaisedStreet1=[]
|
||||
# foldToOtherRaisedStreet2=[]
|
||||
# foldToOtherRaisedStreet3=[]
|
||||
# foldToOtherRaisedStreet4=[]
|
||||
# wonWhenSeenStreet1=[]
|
||||
#
|
||||
# wonAtSD=[]
|
||||
# stealAttemptChance=[]
|
||||
# stealAttempted=[]
|
||||
# hudDataPositions=[]
|
||||
#
|
||||
# street0Calls=[]
|
||||
# street1Calls=[]
|
||||
# street2Calls=[]
|
||||
# street3Calls=[]
|
||||
# street4Calls=[]
|
||||
# street0Bets=[]
|
||||
# street1Bets=[]
|
||||
# street2Bets=[]
|
||||
# street3Bets=[]
|
||||
# street4Bets=[]
|
||||
# #street0Raises=[]
|
||||
# #street1Raises=[]
|
||||
# #street2Raises=[]
|
||||
# #street3Raises=[]
|
||||
# #street4Raises=[]
|
||||
#
|
||||
# # Summary figures for hand table:
|
||||
# result={}
|
||||
# result['playersVpi']=0
|
||||
# result['playersAtStreet1']=0
|
||||
# result['playersAtStreet2']=0
|
||||
# result['playersAtStreet3']=0
|
||||
# result['playersAtStreet4']=0
|
||||
# result['playersAtShowdown']=0
|
||||
# result['street0Raises']=0
|
||||
# result['street1Raises']=0
|
||||
# result['street2Raises']=0
|
||||
# result['street3Raises']=0
|
||||
# result['street4Raises']=0
|
||||
# result['street1Pot']=0
|
||||
# result['street2Pot']=0
|
||||
# result['street3Pot']=0
|
||||
# result['street4Pot']=0
|
||||
# result['showdownPot']=0
|
||||
#
|
||||
# firstPfRaiseByNo=-1
|
||||
# firstPfRaiserId=-1
|
||||
# firstPfRaiserNo=-1
|
||||
# firstPfCallByNo=-1
|
||||
# firstPfCallerId=-1
|
||||
#
|
||||
# for i, action in enumerate(actionTypeByNo[0]):
|
||||
# if action[1] == "bet":
|
||||
# firstPfRaiseByNo = i
|
||||
# firstPfRaiserId = action[0]
|
||||
# for j, pid in enumerate(player_ids):
|
||||
# if pid == firstPfRaiserId:
|
||||
# firstPfRaiserNo = j
|
||||
# break
|
||||
# break
|
||||
# for i, action in enumerate(actionTypeByNo[0]):
|
||||
# if action[1] == "call":
|
||||
# firstPfCallByNo = i
|
||||
# firstPfCallerId = action[0]
|
||||
# break
|
||||
# firstPlayId = firstPfCallerId
|
||||
# if firstPfRaiseByNo <> -1:
|
||||
# if firstPfRaiseByNo < firstPfCallByNo or firstPfCallByNo == -1:
|
||||
# firstPlayId = firstPfRaiserId
|
||||
#
|
||||
#
|
||||
# cutoffId=-1
|
||||
# buttonId=-1
|
||||
# sbId=-1
|
||||
# bbId=-1
|
||||
# if base=="hold":
|
||||
# for player, pos in enumerate(positions):
|
||||
# if pos == 1:
|
||||
# cutoffId = player_ids[player]
|
||||
# if pos == 0:
|
||||
# buttonId = player_ids[player]
|
||||
# if pos == 'S':
|
||||
# sbId = player_ids[player]
|
||||
# if pos == 'B':
|
||||
# bbId = player_ids[player]
|
||||
#
|
||||
# someoneStole=False
|
||||
#
|
||||
# #run a loop for each player preparing the actual values that will be commited to SQL
|
||||
# for player in xrange(len(player_ids)):
|
||||
# #set default values
|
||||
# myStreet0VPI=False
|
||||
# myStreet0Aggr=False
|
||||
# myStreet0_3BChance=False
|
||||
# myStreet0_3BDone=False
|
||||
# myStreet1Seen=False
|
||||
# myStreet2Seen=False
|
||||
# myStreet3Seen=False
|
||||
# myStreet4Seen=False
|
||||
# mySawShowdown=False
|
||||
# myStreet1Aggr=False
|
||||
# myStreet2Aggr=False
|
||||
# myStreet3Aggr=False
|
||||
# myStreet4Aggr=False
|
||||
# myOtherRaisedStreet1=False
|
||||
# myOtherRaisedStreet2=False
|
||||
# myOtherRaisedStreet3=False
|
||||
# myOtherRaisedStreet4=False
|
||||
# myFoldToOtherRaisedStreet1=False
|
||||
# myFoldToOtherRaisedStreet2=False
|
||||
# myFoldToOtherRaisedStreet3=False
|
||||
# myFoldToOtherRaisedStreet4=False
|
||||
# myWonWhenSeenStreet1=0.0
|
||||
# myWonAtSD=0.0
|
||||
# myStealAttemptChance=False
|
||||
# myStealAttempted=False
|
||||
# myStreet0Calls=0
|
||||
# myStreet1Calls=0
|
||||
# myStreet2Calls=0
|
||||
# myStreet3Calls=0
|
||||
# myStreet4Calls=0
|
||||
# myStreet0Bets=0
|
||||
# myStreet1Bets=0
|
||||
# myStreet2Bets=0
|
||||
# myStreet3Bets=0
|
||||
# myStreet4Bets=0
|
||||
# #myStreet0Raises=0
|
||||
# #myStreet1Raises=0
|
||||
# #myStreet2Raises=0
|
||||
# #myStreet3Raises=0
|
||||
# #myStreet4Raises=0
|
||||
#
|
||||
# #calculate VPIP and PFR
|
||||
# street=0
|
||||
# heroPfRaiseCount=0
|
||||
# for currentAction in action_types[street][player]: # finally individual actions
|
||||
# if currentAction == "bet":
|
||||
# myStreet0Aggr = True
|
||||
# if currentAction == "bet" or currentAction == "call":
|
||||
# myStreet0VPI = True
|
||||
#
|
||||
# if myStreet0VPI:
|
||||
# result['playersVpi'] += 1
|
||||
# myStreet0Calls = action_types[street][player].count('call')
|
||||
# myStreet0Bets = action_types[street][player].count('bet')
|
||||
# # street0Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street0Raises'] += myStreet0Bets
|
||||
#
|
||||
# #PF3BChance and PF3B
|
||||
# pfFold=-1
|
||||
# pfRaise=-1
|
||||
# if firstPfRaiseByNo != -1:
|
||||
# for i, actionType in enumerate(actionTypeByNo[0]):
|
||||
# if actionType[0] == player_ids[player]:
|
||||
# if actionType[1] == "bet" and pfRaise == -1 and i > firstPfRaiseByNo:
|
||||
# pfRaise = i
|
||||
# if actionType[1] == "fold" and pfFold == -1:
|
||||
# pfFold = i
|
||||
# if pfFold == -1 or pfFold > firstPfRaiseByNo:
|
||||
# myStreet0_3BChance = True
|
||||
# if pfRaise > firstPfRaiseByNo:
|
||||
# myStreet0_3BDone = True
|
||||
#
|
||||
# #steal calculations
|
||||
# if base=="hold":
|
||||
# if len(player_ids)>=3: # no point otherwise # was 5, use 3 to match pokertracker definition
|
||||
# if positions[player]==1:
|
||||
# if firstPfRaiserId==player_ids[player] \
|
||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
||||
# myStealAttempted=True
|
||||
# myStealAttemptChance=True
|
||||
# if firstPlayId==cutoffId or firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
||||
# myStealAttemptChance=True
|
||||
# if positions[player]==0:
|
||||
# if firstPfRaiserId==player_ids[player] \
|
||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
||||
# myStealAttempted=True
|
||||
# myStealAttemptChance=True
|
||||
# if firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
||||
# myStealAttemptChance=True
|
||||
# if positions[player]=='S':
|
||||
# if firstPfRaiserId==player_ids[player] \
|
||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
||||
# myStealAttempted=True
|
||||
# myStealAttemptChance=True
|
||||
# if firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
||||
# myStealAttemptChance=True
|
||||
# if positions[player]=='B':
|
||||
# pass
|
||||
#
|
||||
# if myStealAttempted:
|
||||
# someoneStole=True
|
||||
#
|
||||
#
|
||||
# #calculate saw* values
|
||||
# isAllIn = False
|
||||
# if any(i for i in allIns[0][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[1][player])>0 or isAllIn):
|
||||
# myStreet1Seen = True
|
||||
#
|
||||
# if any(i for i in allIns[1][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[2][player])>0 or isAllIn):
|
||||
# myStreet2Seen = True
|
||||
#
|
||||
# if any(i for i in allIns[2][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[3][player])>0 or isAllIn):
|
||||
# myStreet3Seen = True
|
||||
#
|
||||
# #print "base:", base
|
||||
# if base=="hold":
|
||||
# mySawShowdown = True
|
||||
# if any(actiontype == "fold" for actiontype in action_types[3][player]):
|
||||
# mySawShowdown = False
|
||||
# else:
|
||||
# #print "in else"
|
||||
# if any(i for i in allIns[3][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[4][player])>0 or isAllIn):
|
||||
# #print "in if"
|
||||
# myStreet4Seen = True
|
||||
#
|
||||
# mySawShowdown = True
|
||||
# if any(actiontype == "fold" for actiontype in action_types[4][player]):
|
||||
# mySawShowdown = False
|
||||
#
|
||||
# if myStreet1Seen:
|
||||
# result['playersAtStreet1'] += 1
|
||||
# if myStreet2Seen:
|
||||
# result['playersAtStreet2'] += 1
|
||||
# if myStreet3Seen:
|
||||
# result['playersAtStreet3'] += 1
|
||||
# if myStreet4Seen:
|
||||
# result['playersAtStreet4'] += 1
|
||||
# if mySawShowdown:
|
||||
# result['playersAtShowdown'] += 1
|
||||
#
|
||||
# #flop stuff
|
||||
# street=1
|
||||
# if myStreet1Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet1Aggr = True
|
||||
#
|
||||
# myStreet1Calls = action_types[street][player].count('call')
|
||||
# myStreet1Bets = action_types[street][player].count('bet')
|
||||
# # street1Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street1Raises'] += myStreet1Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet1=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet1=True
|
||||
#
|
||||
# #turn stuff - copy of flop with different vars
|
||||
# street=2
|
||||
# if myStreet2Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet2Aggr = True
|
||||
#
|
||||
# myStreet2Calls = action_types[street][player].count('call')
|
||||
# myStreet2Bets = action_types[street][player].count('bet')
|
||||
# # street2Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street2Raises'] += myStreet2Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet2=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet2=True
|
||||
#
|
||||
# #river stuff - copy of flop with different vars
|
||||
# street=3
|
||||
# if myStreet3Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet3Aggr = True
|
||||
#
|
||||
# myStreet3Calls = action_types[street][player].count('call')
|
||||
# myStreet3Bets = action_types[street][player].count('bet')
|
||||
# # street3Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street3Raises'] += myStreet3Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet3=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet3=True
|
||||
#
|
||||
# #stud river stuff - copy of flop with different vars
|
||||
# street=4
|
||||
# if myStreet4Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet4Aggr=True
|
||||
#
|
||||
# myStreet4Calls = action_types[street][player].count('call')
|
||||
# myStreet4Bets = action_types[street][player].count('bet')
|
||||
# # street4Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street4Raises'] += myStreet4Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet4=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet4=True
|
||||
#
|
||||
# if winnings[player] != 0:
|
||||
# if myStreet1Seen:
|
||||
# myWonWhenSeenStreet1 = winnings[player] / float(totalWinnings)
|
||||
# if mySawShowdown:
|
||||
# myWonAtSD=myWonWhenSeenStreet1
|
||||
#
|
||||
# #add each value to the appropriate array
|
||||
# street0VPI.append(myStreet0VPI)
|
||||
# street0Aggr.append(myStreet0Aggr)
|
||||
# street0_3BChance.append(myStreet0_3BChance)
|
||||
# street0_3BDone.append(myStreet0_3BDone)
|
||||
# street1Seen.append(myStreet1Seen)
|
||||
# street2Seen.append(myStreet2Seen)
|
||||
# street3Seen.append(myStreet3Seen)
|
||||
# street4Seen.append(myStreet4Seen)
|
||||
# sawShowdown.append(mySawShowdown)
|
||||
# street1Aggr.append(myStreet1Aggr)
|
||||
# street2Aggr.append(myStreet2Aggr)
|
||||
# street3Aggr.append(myStreet3Aggr)
|
||||
# street4Aggr.append(myStreet4Aggr)
|
||||
# otherRaisedStreet1.append(myOtherRaisedStreet1)
|
||||
# otherRaisedStreet2.append(myOtherRaisedStreet2)
|
||||
# otherRaisedStreet3.append(myOtherRaisedStreet3)
|
||||
# otherRaisedStreet4.append(myOtherRaisedStreet4)
|
||||
# foldToOtherRaisedStreet1.append(myFoldToOtherRaisedStreet1)
|
||||
# foldToOtherRaisedStreet2.append(myFoldToOtherRaisedStreet2)
|
||||
# foldToOtherRaisedStreet3.append(myFoldToOtherRaisedStreet3)
|
||||
# foldToOtherRaisedStreet4.append(myFoldToOtherRaisedStreet4)
|
||||
# wonWhenSeenStreet1.append(myWonWhenSeenStreet1)
|
||||
# wonAtSD.append(myWonAtSD)
|
||||
# stealAttemptChance.append(myStealAttemptChance)
|
||||
# stealAttempted.append(myStealAttempted)
|
||||
# if base=="hold":
|
||||
# pos=positions[player]
|
||||
# if pos=='B':
|
||||
# hudDataPositions.append('B')
|
||||
# elif pos=='S':
|
||||
# hudDataPositions.append('S')
|
||||
# elif pos==0:
|
||||
# hudDataPositions.append('D')
|
||||
# elif pos==1:
|
||||
# hudDataPositions.append('C')
|
||||
# elif pos>=2 and pos<=4:
|
||||
# hudDataPositions.append('M')
|
||||
# elif pos>=5 and pos<=8:
|
||||
# hudDataPositions.append('E')
|
||||
# ### RHH Added this elif to handle being a dead hand before the BB (pos==9)
|
||||
# elif pos==9:
|
||||
# hudDataPositions.append('X')
|
||||
# else:
|
||||
# raise FpdbError("invalid position")
|
||||
# elif base=="stud":
|
||||
# #todo: stud positions and steals
|
||||
# pass
|
||||
#
|
||||
# street0Calls.append(myStreet0Calls)
|
||||
# street1Calls.append(myStreet1Calls)
|
||||
# street2Calls.append(myStreet2Calls)
|
||||
# street3Calls.append(myStreet3Calls)
|
||||
# street4Calls.append(myStreet4Calls)
|
||||
# street0Bets.append(myStreet0Bets)
|
||||
# street1Bets.append(myStreet1Bets)
|
||||
# street2Bets.append(myStreet2Bets)
|
||||
# street3Bets.append(myStreet3Bets)
|
||||
# street4Bets.append(myStreet4Bets)
|
||||
# #street0Raises.append(myStreet0Raises)
|
||||
# #street1Raises.append(myStreet1Raises)
|
||||
# #street2Raises.append(myStreet2Raises)
|
||||
# #street3Raises.append(myStreet3Raises)
|
||||
# #street4Raises.append(myStreet4Raises)
|
||||
#
|
||||
# #add each array to the to-be-returned dictionary
|
||||
# result['street0VPI']=street0VPI
|
||||
# result['street0Aggr']=street0Aggr
|
||||
# result['street0_3BChance']=street0_3BChance
|
||||
# result['street0_3BDone']=street0_3BDone
|
||||
# result['street1Seen']=street1Seen
|
||||
# result['street2Seen']=street2Seen
|
||||
# result['street3Seen']=street3Seen
|
||||
# result['street4Seen']=street4Seen
|
||||
# result['sawShowdown']=sawShowdown
|
||||
#
|
||||
# result['street1Aggr']=street1Aggr
|
||||
# result['otherRaisedStreet1']=otherRaisedStreet1
|
||||
# result['foldToOtherRaisedStreet1']=foldToOtherRaisedStreet1
|
||||
# result['street2Aggr']=street2Aggr
|
||||
# result['otherRaisedStreet2']=otherRaisedStreet2
|
||||
# result['foldToOtherRaisedStreet2']=foldToOtherRaisedStreet2
|
||||
# result['street3Aggr']=street3Aggr
|
||||
# result['otherRaisedStreet3']=otherRaisedStreet3
|
||||
# result['foldToOtherRaisedStreet3']=foldToOtherRaisedStreet3
|
||||
# result['street4Aggr']=street4Aggr
|
||||
# result['otherRaisedStreet4']=otherRaisedStreet4
|
||||
# result['foldToOtherRaisedStreet4']=foldToOtherRaisedStreet4
|
||||
# result['wonWhenSeenStreet1']=wonWhenSeenStreet1
|
||||
# result['wonAtSD']=wonAtSD
|
||||
# result['stealAttemptChance']=stealAttemptChance
|
||||
# result['stealAttempted']=stealAttempted
|
||||
# result['street0Calls']=street0Calls
|
||||
# result['street1Calls']=street1Calls
|
||||
# result['street2Calls']=street2Calls
|
||||
# result['street3Calls']=street3Calls
|
||||
# result['street4Calls']=street4Calls
|
||||
# result['street0Bets']=street0Bets
|
||||
# result['street1Bets']=street1Bets
|
||||
# result['street2Bets']=street2Bets
|
||||
# result['street3Bets']=street3Bets
|
||||
# result['street4Bets']=street4Bets
|
||||
# #result['street0Raises']=street0Raises
|
||||
# #result['street1Raises']=street1Raises
|
||||
# #result['street2Raises']=street2Raises
|
||||
# #result['street3Raises']=street3Raises
|
||||
# #result['street4Raises']=street4Raises
|
||||
#
|
||||
# #now the various steal values
|
||||
# foldBbToStealChance=[]
|
||||
# foldedBbToSteal=[]
|
||||
# foldSbToStealChance=[]
|
||||
# foldedSbToSteal=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myFoldBbToStealChance=False
|
||||
# myFoldedBbToSteal=False
|
||||
# myFoldSbToStealChance=False
|
||||
# myFoldedSbToSteal=False
|
||||
#
|
||||
# if base=="hold":
|
||||
# if someoneStole and (positions[player]=='B' or positions[player]=='S') and firstPfRaiserId!=player_ids[player]:
|
||||
# street=0
|
||||
# for count in xrange(len(action_types[street][player])):#individual actions
|
||||
# if positions[player]=='B':
|
||||
# myFoldBbToStealChance=True
|
||||
# if action_types[street][player][count]=="fold":
|
||||
# myFoldedBbToSteal=True
|
||||
# if positions[player]=='S':
|
||||
# myFoldSbToStealChance=True
|
||||
# if action_types[street][player][count]=="fold":
|
||||
# myFoldedSbToSteal=True
|
||||
#
|
||||
#
|
||||
# foldBbToStealChance.append(myFoldBbToStealChance)
|
||||
# foldedBbToSteal.append(myFoldedBbToSteal)
|
||||
# foldSbToStealChance.append(myFoldSbToStealChance)
|
||||
# foldedSbToSteal.append(myFoldedSbToSteal)
|
||||
# result['foldBbToStealChance']=foldBbToStealChance
|
||||
# result['foldedBbToSteal']=foldedBbToSteal
|
||||
# result['foldSbToStealChance']=foldSbToStealChance
|
||||
# result['foldedSbToSteal']=foldedSbToSteal
|
||||
#
|
||||
# #now CB
|
||||
# street1CBChance=[]
|
||||
# street1CBDone=[]
|
||||
# didStreet1CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet1CBChance=False
|
||||
# myStreet1CBDone=False
|
||||
#
|
||||
# if street0VPI[player]:
|
||||
# myStreet1CBChance=True
|
||||
# if street1Aggr[player]:
|
||||
# myStreet1CBDone=True
|
||||
# didStreet1CB.append(player_ids[player])
|
||||
#
|
||||
# street1CBChance.append(myStreet1CBChance)
|
||||
# street1CBDone.append(myStreet1CBDone)
|
||||
# result['street1CBChance']=street1CBChance
|
||||
# result['street1CBDone']=street1CBDone
|
||||
#
|
||||
# #now 2B
|
||||
# street2CBChance=[]
|
||||
# street2CBDone=[]
|
||||
# didStreet2CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet2CBChance=False
|
||||
# myStreet2CBDone=False
|
||||
#
|
||||
# if street1CBDone[player]:
|
||||
# myStreet2CBChance=True
|
||||
# if street2Aggr[player]:
|
||||
# myStreet2CBDone=True
|
||||
# didStreet2CB.append(player_ids[player])
|
||||
#
|
||||
# street2CBChance.append(myStreet2CBChance)
|
||||
# street2CBDone.append(myStreet2CBDone)
|
||||
# result['street2CBChance']=street2CBChance
|
||||
# result['street2CBDone']=street2CBDone
|
||||
#
|
||||
# #now 3B
|
||||
# street3CBChance=[]
|
||||
# street3CBDone=[]
|
||||
# didStreet3CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet3CBChance=False
|
||||
# myStreet3CBDone=False
|
||||
#
|
||||
# if street2CBDone[player]:
|
||||
# myStreet3CBChance=True
|
||||
# if street3Aggr[player]:
|
||||
# myStreet3CBDone=True
|
||||
# didStreet3CB.append(player_ids[player])
|
||||
#
|
||||
# street3CBChance.append(myStreet3CBChance)
|
||||
# street3CBDone.append(myStreet3CBDone)
|
||||
# result['street3CBChance']=street3CBChance
|
||||
# result['street3CBDone']=street3CBDone
|
||||
#
|
||||
# #and 4B
|
||||
# street4CBChance=[]
|
||||
# street4CBDone=[]
|
||||
# didStreet4CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet4CBChance=False
|
||||
# myStreet4CBDone=False
|
||||
#
|
||||
# if street3CBDone[player]:
|
||||
# myStreet4CBChance=True
|
||||
# if street4Aggr[player]:
|
||||
# myStreet4CBDone=True
|
||||
# didStreet4CB.append(player_ids[player])
|
||||
#
|
||||
# street4CBChance.append(myStreet4CBChance)
|
||||
# street4CBDone.append(myStreet4CBDone)
|
||||
# result['street4CBChance']=street4CBChance
|
||||
# result['street4CBDone']=street4CBDone
|
||||
#
|
||||
#
|
||||
# result['position']=hudDataPositions
|
||||
#
|
||||
# foldToStreet1CBChance=[]
|
||||
# foldToStreet1CBDone=[]
|
||||
# foldToStreet2CBChance=[]
|
||||
# foldToStreet2CBDone=[]
|
||||
# foldToStreet3CBChance=[]
|
||||
# foldToStreet3CBDone=[]
|
||||
# foldToStreet4CBChance=[]
|
||||
# foldToStreet4CBDone=[]
|
||||
#
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myFoldToStreet1CBChance=False
|
||||
# myFoldToStreet1CBDone=False
|
||||
# foldToStreet1CBChance.append(myFoldToStreet1CBChance)
|
||||
# foldToStreet1CBDone.append(myFoldToStreet1CBDone)
|
||||
#
|
||||
# myFoldToStreet2CBChance=False
|
||||
# myFoldToStreet2CBDone=False
|
||||
# foldToStreet2CBChance.append(myFoldToStreet2CBChance)
|
||||
# foldToStreet2CBDone.append(myFoldToStreet2CBDone)
|
||||
#
|
||||
# myFoldToStreet3CBChance=False
|
||||
# myFoldToStreet3CBDone=False
|
||||
# foldToStreet3CBChance.append(myFoldToStreet3CBChance)
|
||||
# foldToStreet3CBDone.append(myFoldToStreet3CBDone)
|
||||
#
|
||||
# myFoldToStreet4CBChance=False
|
||||
# myFoldToStreet4CBDone=False
|
||||
# foldToStreet4CBChance.append(myFoldToStreet4CBChance)
|
||||
# foldToStreet4CBDone.append(myFoldToStreet4CBDone)
|
||||
#
|
||||
# if len(didStreet1CB)>=1:
|
||||
# generateFoldToCB(1, player_ids, didStreet1CB, street1CBDone, foldToStreet1CBChance, foldToStreet1CBDone, actionTypeByNo)
|
||||
#
|
||||
# if len(didStreet2CB)>=1:
|
||||
# generateFoldToCB(2, player_ids, didStreet2CB, street2CBDone, foldToStreet2CBChance, foldToStreet2CBDone, actionTypeByNo)
|
||||
#
|
||||
# if len(didStreet3CB)>=1:
|
||||
# generateFoldToCB(3, player_ids, didStreet3CB, street3CBDone, foldToStreet3CBChance, foldToStreet3CBDone, actionTypeByNo)
|
||||
#
|
||||
# if len(didStreet4CB)>=1:
|
||||
# generateFoldToCB(4, player_ids, didStreet4CB, street4CBDone, foldToStreet4CBChance, foldToStreet4CBDone, actionTypeByNo)
|
||||
#
|
||||
# result['foldToStreet1CBChance']=foldToStreet1CBChance
|
||||
# result['foldToStreet1CBDone']=foldToStreet1CBDone
|
||||
# result['foldToStreet2CBChance']=foldToStreet2CBChance
|
||||
# result['foldToStreet2CBDone']=foldToStreet2CBDone
|
||||
# result['foldToStreet3CBChance']=foldToStreet3CBChance
|
||||
# result['foldToStreet3CBDone']=foldToStreet3CBDone
|
||||
# result['foldToStreet4CBChance']=foldToStreet4CBChance
|
||||
# result['foldToStreet4CBDone']=foldToStreet4CBDone
|
||||
#
|
||||
#
|
||||
# totalProfit=[]
|
||||
#
|
||||
# street1CheckCallRaiseChance=[]
|
||||
# street1CheckCallRaiseDone=[]
|
||||
# street2CheckCallRaiseChance=[]
|
||||
# street2CheckCallRaiseDone=[]
|
||||
# street3CheckCallRaiseChance=[]
|
||||
# street3CheckCallRaiseDone=[]
|
||||
# street4CheckCallRaiseChance=[]
|
||||
# street4CheckCallRaiseDone=[]
|
||||
# #print "b4 totprof calc, len(playerIds)=", len(player_ids)
|
||||
# for pl in xrange(len(player_ids)):
|
||||
# #print "pl=", pl
|
||||
# myTotalProfit=winnings[pl] # still need to deduct other costs
|
||||
# if antes:
|
||||
# myTotalProfit=winnings[pl] - antes[pl]
|
||||
# for i in xrange(len(actionTypes)): #iterate through streets
|
||||
# #for j in xrange(len(actionTypes[i])): #iterate through names (using pl loop above)
|
||||
# for k in xrange(len(actionTypes[i][pl])): #iterate through individual actions of that player on that street
|
||||
# myTotalProfit -= actionAmounts[i][pl][k]
|
||||
#
|
||||
# myStreet1CheckCallRaiseChance=False
|
||||
# myStreet1CheckCallRaiseDone=False
|
||||
# myStreet2CheckCallRaiseChance=False
|
||||
# myStreet2CheckCallRaiseDone=False
|
||||
# myStreet3CheckCallRaiseChance=False
|
||||
# myStreet3CheckCallRaiseDone=False
|
||||
# myStreet4CheckCallRaiseChance=False
|
||||
# myStreet4CheckCallRaiseDone=False
|
||||
#
|
||||
# #print "myTotalProfit=", myTotalProfit
|
||||
# totalProfit.append(myTotalProfit)
|
||||
# #print "totalProfit[]=", totalProfit
|
||||
#
|
||||
# street1CheckCallRaiseChance.append(myStreet1CheckCallRaiseChance)
|
||||
# street1CheckCallRaiseDone.append(myStreet1CheckCallRaiseDone)
|
||||
# street2CheckCallRaiseChance.append(myStreet2CheckCallRaiseChance)
|
||||
# street2CheckCallRaiseDone.append(myStreet2CheckCallRaiseDone)
|
||||
# street3CheckCallRaiseChance.append(myStreet3CheckCallRaiseChance)
|
||||
# street3CheckCallRaiseDone.append(myStreet3CheckCallRaiseDone)
|
||||
# street4CheckCallRaiseChance.append(myStreet4CheckCallRaiseChance)
|
||||
# street4CheckCallRaiseDone.append(myStreet4CheckCallRaiseDone)
|
||||
#
|
||||
# result['totalProfit']=totalProfit
|
||||
# #print "res[totalProfit]=", result['totalProfit']
|
||||
#
|
||||
# result['street1CheckCallRaiseChance']=street1CheckCallRaiseChance
|
||||
# result['street1CheckCallRaiseDone']=street1CheckCallRaiseDone
|
||||
# result['street2CheckCallRaiseChance']=street2CheckCallRaiseChance
|
||||
# result['street2CheckCallRaiseDone']=street2CheckCallRaiseDone
|
||||
# result['street3CheckCallRaiseChance']=street3CheckCallRaiseChance
|
||||
# result['street3CheckCallRaiseDone']=street3CheckCallRaiseDone
|
||||
# result['street4CheckCallRaiseChance']=street4CheckCallRaiseChance
|
||||
# result['street4CheckCallRaiseDone']=street4CheckCallRaiseDone
|
||||
# return result
|
||||
# #end def generateHudCacheData
|
||||
pass
|
||||
|
||||
def vpip(self, hand):
|
||||
vpipers = set()
|
||||
for act in hand.actions[hand.actionStreets[1]]:
|
||||
if act[1] in ('calls','bets', 'raises'):
|
||||
vpipers.add(act[0])
|
||||
|
||||
for player in hand.players:
|
||||
if player[1] in vpipers:
|
||||
self.handsplayers[player[1]]['vpip'] = True
|
||||
else:
|
||||
self.handsplayers[player[1]]['vpip'] = False
|
||||
#for player in hand.players:
|
||||
# print "DEBUG: '%s' '%s' '%s'" %(player, player[1], vpipers)
|
||||
# if player[1] in vpipers:
|
||||
# self.handsplayers[player[1]]['vpip'] = True
|
||||
# else:
|
||||
# self.handsplayers[player[1]]['vpip'] = False
|
||||
self.hands['playersVpi'] = len(vpipers)
|
||||
|
||||
def playersAtStreetX(self, hand):
|
||||
""" playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4/draw1 */"""
|
||||
# self.actions[street] is a list of all actions in a tuple, contining the player name first
|
||||
# [ (player, action, ....), (player2, action, ...) ]
|
||||
# The number of unique players in the list per street gives the value for playersAtStreetXXX
|
||||
|
||||
self.hands['playersAtStreet1'] = 0
|
||||
self.hands['playersAtStreet2'] = 0
|
||||
self.hands['playersAtStreet3'] = 0
|
||||
self.hands['playersAtStreet4'] = 0
|
||||
self.hands['playersAtShowdown'] = 0
|
||||
|
||||
for street in hand.actionStreets:
|
||||
actors = {}
|
||||
for act in hand.actions[street]:
|
||||
actors[act[0]] = 1
|
||||
#print "len(actors.keys(%s)): %s" % ( street, len(actors.keys()))
|
||||
if hand.gametype['base'] in ("hold"):
|
||||
if street in "FLOP": self.hands['playersAtStreet1'] = len(actors.keys())
|
||||
elif street in "TURN": self.hands['playersAtStreet2'] = len(actors.keys())
|
||||
elif street in "RIVER": self.hands['playersAtStreet3'] = len(actors.keys())
|
||||
elif hand.gametype['base'] in ("stud"):
|
||||
if street in "FOURTH": self.hands['playersAtStreet1'] = len(actors.keys())
|
||||
elif street in "FIFTH": self.hands['playersAtStreet2'] = len(actors.keys())
|
||||
elif street in "SIXTH": self.hands['playersAtStreet3'] = len(actors.keys())
|
||||
elif street in "SEVENTH": self.hands['playersAtStreet4'] = len(actors.keys())
|
||||
elif hand.gametype['base'] in ("draw"):
|
||||
if street in "DRAWONE": self.hands['playersAtStreet1'] = len(actors.keys())
|
||||
elif street in "DRAWTWO": self.hands['playersAtStreet2'] = len(actors.keys())
|
||||
elif street in "DRAWTHREE": self.hands['playersAtStreet3'] = len(actors.keys())
|
||||
|
||||
#Need playersAtShowdown
|
||||
|
||||
|
||||
def streetXRaises(self, hand):
|
||||
# self.actions[street] is a list of all actions in a tuple, contining the action as the second element
|
||||
# [ (player, action, ....), (player2, action, ...) ]
|
||||
# No idea what this value is actually supposed to be
|
||||
# In theory its "num small bets paid to see flop/street4, including blind" which makes sense for limit. Not so useful for nl
|
||||
# Leaving empty for the moment,
|
||||
self.hands['street0Raises'] = 0 # /* num small bets paid to see flop/street4, including blind */
|
||||
self.hands['street1Raises'] = 0 # /* num small bets paid to see turn/street5 */
|
||||
self.hands['street2Raises'] = 0 # /* num big bets paid to see river/street6 */
|
||||
self.hands['street3Raises'] = 0 # /* num big bets paid to see sd/street7 */
|
||||
self.hands['street4Raises'] = 0 # /* num big bets paid to see showdown */
|
||||
|
||||
def aggr(self, hand, i):
|
||||
aggrers = set()
|
||||
for act in hand.actions[hand.actionStreets[i]]:
|
||||
|
@ -157,4 +844,4 @@ class DerivedStats():
|
|||
self.handsplayers[player[1]]['street%sAggr' % i] = False
|
||||
|
||||
def countPlayers(self, hand):
|
||||
pass
|
||||
pass
|
||||
|
|
|
@ -17,5 +17,8 @@ class FpdbParseError(FpdbError):
|
|||
class FpdbDatabaseError(FpdbError):
|
||||
pass
|
||||
|
||||
class FpdbMySQLFailedError(FpdbDatabaseError):
|
||||
pass
|
||||
|
||||
class DuplicateError(FpdbError):
|
||||
pass
|
||||
|
|
|
@ -23,6 +23,7 @@ import os
|
|||
import sys
|
||||
from optparse import OptionParser
|
||||
from time import *
|
||||
import gobject
|
||||
#import pokereval
|
||||
|
||||
import Configuration
|
||||
|
@ -31,19 +32,20 @@ import FpdbSQLQueries
|
|||
|
||||
class Filters(threading.Thread):
|
||||
def __init__(self, db, config, qdict, display = {}, debug=True):
|
||||
self.debug=debug
|
||||
# config and qdict are now redundant
|
||||
self.debug = debug
|
||||
#print "start of GraphViewer constructor"
|
||||
self.db=db
|
||||
self.cursor=db.cursor
|
||||
self.sql=qdict
|
||||
self.conf = config
|
||||
self.db = db
|
||||
self.cursor = db.cursor
|
||||
self.sql = db.sql
|
||||
self.conf = db.config
|
||||
self.display = display
|
||||
|
||||
self.sites = {}
|
||||
self.games = {}
|
||||
self.limits = {}
|
||||
self.seats = {}
|
||||
self.groups = {}
|
||||
self.groups = {}
|
||||
self.siteid = {}
|
||||
self.heroes = {}
|
||||
self.boxes = {}
|
||||
|
@ -53,6 +55,7 @@ class Filters(threading.Thread):
|
|||
,'seatsbetween':'Between:', 'seatsand':'And:', 'seatsshow':'Show Number of _Players'
|
||||
,'limitstitle':'Limits:', 'seatstitle':'Number of Players:'
|
||||
,'groupstitle':'Grouping:', 'posnshow':'Show Position Stats:'
|
||||
,'limitsFL':'FL', 'limitsNL':'NL', 'ring':'Ring', 'tour':'Tourney'
|
||||
}
|
||||
|
||||
# For use in date ranges.
|
||||
|
@ -97,6 +100,11 @@ class Filters(threading.Thread):
|
|||
self.cbLimits = {}
|
||||
self.cbNoLimits = None
|
||||
self.cbAllLimits = None
|
||||
self.cbFL = None
|
||||
self.cbNL = None
|
||||
self.rb = {} # radio buttons for ring/tour
|
||||
self.type = None # ring/tour
|
||||
self.types = {} # list of all ring/tour values
|
||||
|
||||
self.fillLimitsFrame(vbox, self.display)
|
||||
limitsFrame.add(vbox)
|
||||
|
@ -189,6 +197,9 @@ class Filters(threading.Thread):
|
|||
ltuple.append(l)
|
||||
return ltuple
|
||||
|
||||
def getType(self):
|
||||
return(self.type)
|
||||
|
||||
def getSeats(self):
|
||||
if 'from' in self.sbSeats:
|
||||
self.seats['from'] = self.sbSeats['from'].get_value_as_int()
|
||||
|
@ -228,7 +239,16 @@ class Filters(threading.Thread):
|
|||
pname.set_width_chars(20)
|
||||
hbox.pack_start(pname, False, True, 0)
|
||||
pname.connect("changed", self.__set_hero_name, site)
|
||||
#TODO: Look at GtkCompletion - to fill out usernames
|
||||
|
||||
# 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) # (config=self.conf, site_id=None, like_player_name="%")
|
||||
for n in names:
|
||||
liststore.append(n)
|
||||
|
||||
self.__set_hero_name(pname, site)
|
||||
|
||||
|
@ -269,21 +289,99 @@ class Filters(threading.Thread):
|
|||
#print w.get_active()
|
||||
self.limits[limit] = w.get_active()
|
||||
print "self.limit[%s] set to %s" %(limit, self.limits[limit])
|
||||
if str(limit).isdigit():
|
||||
if limit.isdigit() or (len(limit) > 2 and limit[-2:] == 'nl'):
|
||||
if self.limits[limit]:
|
||||
if self.cbNoLimits != None:
|
||||
self.cbNoLimits.set_active(False)
|
||||
else:
|
||||
if self.cbAllLimits != None:
|
||||
self.cbAllLimits.set_active(False)
|
||||
if not self.limits[limit]:
|
||||
if limit.isdigit():
|
||||
self.cbFL.set_active(False)
|
||||
else:
|
||||
self.cbNL.set_active(False)
|
||||
elif limit == "all":
|
||||
if self.limits[limit]:
|
||||
for cb in self.cbLimits.values():
|
||||
cb.set_active(True)
|
||||
#for cb in self.cbLimits.values():
|
||||
# cb.set_active(True)
|
||||
if self.cbFL != None:
|
||||
self.cbFL.set_active(True)
|
||||
if self.cbNL != None:
|
||||
self.cbNL.set_active(True)
|
||||
elif limit == "none":
|
||||
if self.limits[limit]:
|
||||
for cb in self.cbLimits.values():
|
||||
cb.set_active(False)
|
||||
self.cbNL.set_active(False)
|
||||
self.cbFL.set_active(False)
|
||||
elif limit == "fl":
|
||||
if not self.limits[limit]:
|
||||
# only toggle all fl limits off if they are all currently on
|
||||
# this stops turning one off from cascading into 'fl' box off
|
||||
# and then all fl limits being turned off
|
||||
all_fl_on = True
|
||||
for cb in self.cbLimits.values():
|
||||
t = cb.get_children()[0].get_text()
|
||||
if t.isdigit():
|
||||
if not cb.get_active():
|
||||
all_fl_on = False
|
||||
found = {'ring':False, 'tour':False}
|
||||
for cb in self.cbLimits.values():
|
||||
#print "cb label: ", cb.children()[0].get_text()
|
||||
t = cb.get_children()[0].get_text()
|
||||
if t.isdigit():
|
||||
if self.limits[limit] or all_fl_on:
|
||||
cb.set_active(self.limits[limit])
|
||||
found[self.types[t]] = True
|
||||
if self.limits[limit]:
|
||||
if not found[self.type]:
|
||||
if self.type == 'ring':
|
||||
if 'tour' in self.rb:
|
||||
self.rb['tour'].set_active(True)
|
||||
elif self.type == 'tour':
|
||||
if 'ring' in self.rb:
|
||||
self.rb['ring'].set_active(True)
|
||||
elif limit == "nl":
|
||||
if not self.limits[limit]:
|
||||
# only toggle all nl limits off if they are all currently on
|
||||
# this stops turning one off from cascading into 'nl' box off
|
||||
# and then all nl limits being turned off
|
||||
all_nl_on = True
|
||||
for cb in self.cbLimits.values():
|
||||
t = cb.get_children()[0].get_text()
|
||||
if "nl" in t and len(t) > 2:
|
||||
if not cb.get_active():
|
||||
all_nl_on = False
|
||||
found = {'ring':False, 'tour':False}
|
||||
for cb in self.cbLimits.values():
|
||||
t = cb.get_children()[0].get_text()
|
||||
if "nl" in t and len(t) > 2:
|
||||
if self.limits[limit] or all_nl_on:
|
||||
cb.set_active(self.limits[limit])
|
||||
found[self.types[t]] = True
|
||||
if self.limits[limit]:
|
||||
if not found[self.type]:
|
||||
if self.type == 'ring':
|
||||
self.rb['tour'].set_active(True)
|
||||
elif self.type == 'tour':
|
||||
self.rb['ring'].set_active(True)
|
||||
elif limit == "ring":
|
||||
print "set", limit, "to", self.limits[limit]
|
||||
if self.limits[limit]:
|
||||
self.type = "ring"
|
||||
for cb in self.cbLimits.values():
|
||||
#print "cb label: ", cb.children()[0].get_text()
|
||||
if self.types[cb.get_children()[0].get_text()] == 'tour':
|
||||
cb.set_active(False)
|
||||
elif limit == "tour":
|
||||
print "set", limit, "to", self.limits[limit]
|
||||
if self.limits[limit]:
|
||||
self.type = "tour"
|
||||
for cb in self.cbLimits.values():
|
||||
#print "cb label: ", cb.children()[0].get_text()
|
||||
if self.types[cb.get_children()[0].get_text()] == 'ring':
|
||||
cb.set_active(False)
|
||||
|
||||
def __set_seat_select(self, w, seat):
|
||||
#print "__set_seat_select: seat =", seat, "active =", w.get_active()
|
||||
|
@ -328,22 +426,23 @@ class Filters(threading.Thread):
|
|||
print "INFO: No games returned from database"
|
||||
|
||||
def fillLimitsFrame(self, vbox, display):
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox.pack_start(hbox, False, False, 0)
|
||||
top_hbox = gtk.HBox(False, 0)
|
||||
vbox.pack_start(top_hbox, False, False, 0)
|
||||
lbl_title = gtk.Label(self.filterText['limitstitle'])
|
||||
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
|
||||
hbox.pack_start(lbl_title, expand=True, padding=3)
|
||||
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, 'limits')
|
||||
hbox.pack_start(showb, expand=False, padding=1)
|
||||
|
||||
vbox1 = gtk.VBox(False, 0)
|
||||
vbox.pack_start(vbox1, False, False, 0)
|
||||
self.boxes['limits'] = vbox1
|
||||
|
||||
self.cursor.execute(self.sql.query['getLimits'])
|
||||
self.cursor.execute(self.sql.query['getLimits2'])
|
||||
# selects limitType, bigBlind
|
||||
result = self.db.cursor.fetchall()
|
||||
fl, nl = False, False
|
||||
if len(result) >= 1:
|
||||
hbox = gtk.HBox(True, 0)
|
||||
vbox1.pack_start(hbox, False, False, 0)
|
||||
|
@ -351,26 +450,72 @@ class Filters(threading.Thread):
|
|||
hbox.pack_start(vbox2, False, False, 0)
|
||||
vbox3 = gtk.VBox(False, 0)
|
||||
hbox.pack_start(vbox3, False, False, 0)
|
||||
found = {'nl':False, 'fl':False, 'ring':False, 'tour':False}
|
||||
for i, line in enumerate(result):
|
||||
if "UseType" in self.display:
|
||||
if line[0] != self.display["UseType"]:
|
||||
continue
|
||||
hbox = gtk.HBox(False, 0)
|
||||
if i <= len(result)/2:
|
||||
vbox2.pack_start(hbox, False, False, 0)
|
||||
else:
|
||||
vbox3.pack_start(hbox, False, False, 0)
|
||||
self.cbLimits[line[0]] = self.createLimitLine(hbox, line[0], line[0])
|
||||
if line[1] == 'fl':
|
||||
name = str(line[2])
|
||||
found['fl'] = True
|
||||
else:
|
||||
name = str(line[2])+line[1]
|
||||
found['nl'] = True
|
||||
self.cbLimits[name] = self.createLimitLine(hbox, name, name)
|
||||
self.types[name] = line[0]
|
||||
found[line[0]] = True # type is ring/tour
|
||||
self.type = line[0] # if only one type, set it now
|
||||
if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2:
|
||||
hbox = gtk.HBox(True, 0)
|
||||
vbox1.pack_start(hbox, False, False, 0)
|
||||
vbox2 = gtk.VBox(False, 0)
|
||||
hbox.pack_start(vbox2, False, False, 0)
|
||||
vbox3 = gtk.VBox(False, 0)
|
||||
hbox.pack_start(vbox3, False, False, 0)
|
||||
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox1.pack_start(hbox, False, True, 0)
|
||||
vbox2.pack_start(hbox, False, False, 0)
|
||||
self.cbAllLimits = self.createLimitLine(hbox, 'all', self.filterText['limitsall'])
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox1.pack_start(hbox, False, True, 0)
|
||||
vbox2.pack_start(hbox, False, False, 0)
|
||||
self.cbNoLimits = self.createLimitLine(hbox, 'none', self.filterText['limitsnone'])
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox1.pack_start(hbox, False, True, 0)
|
||||
cb = self.createLimitLine(hbox, 'show', self.filterText['limitsshow'])
|
||||
|
||||
dest = vbox3 # for ring/tour buttons
|
||||
if "LimitType" in display and display["LimitType"] == True and found['nl'] and found['fl']:
|
||||
#if found['fl']:
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox3.pack_start(hbox, False, False, 0)
|
||||
self.cbFL = self.createLimitLine(hbox, 'fl', self.filterText['limitsFL'])
|
||||
#if found['nl']:
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox3.pack_start(hbox, False, False, 0)
|
||||
self.cbNL = self.createLimitLine(hbox, 'nl', self.filterText['limitsNL'])
|
||||
dest = vbox2 # for ring/tour buttons
|
||||
else:
|
||||
print "INFO: No games returned from database"
|
||||
|
||||
if "Type" in display and display["Type"] == True and found['ring'] and found['tour']:
|
||||
rb1 = gtk.RadioButton(None, self.filterText['ring'])
|
||||
rb1.connect('clicked', self.__set_limit_select, 'ring')
|
||||
rb2 = gtk.RadioButton(rb1, self.filterText['tour'])
|
||||
rb2.connect('clicked', self.__set_limit_select, 'tour')
|
||||
top_hbox.pack_start(rb1, False, False, 0) # (child, expand, fill, padding)
|
||||
top_hbox.pack_start(rb2, True, True, 0) # child uses expand space if fill is true
|
||||
|
||||
self.rb['ring'] = rb1
|
||||
self.rb['tour'] = rb2
|
||||
#print "about to set ring to true"
|
||||
rb1.set_active(True)
|
||||
# set_active doesn't seem to call this for some reason so call manually:
|
||||
self.__set_limit_select(rb1, 'ring')
|
||||
self.type = 'ring'
|
||||
top_hbox.pack_start(showb, expand=False, padding=1)
|
||||
|
||||
def fillSeatsFrame(self, vbox, display):
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox.pack_start(hbox, False, False, 0)
|
||||
|
@ -401,15 +546,6 @@ class Filters(threading.Thread):
|
|||
hbox.pack_start(lbl_to, expand=False, padding=3)
|
||||
hbox.pack_start(sb2, False, False, 0)
|
||||
|
||||
if "SeatSep" in display and display["SeatSep"] == True:
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox1.pack_start(hbox, False, True, 0)
|
||||
cb = gtk.CheckButton(self.filterText['seatsshow'])
|
||||
cb.connect('clicked', self.__set_seat_select, 'show')
|
||||
hbox.pack_start(cb, False, False, 0)
|
||||
self.sbSeats['show'] = cb
|
||||
self.seats['show'] = False
|
||||
|
||||
self.sbSeats['from'] = sb1
|
||||
self.sbSeats['to'] = sb2
|
||||
|
||||
|
@ -429,14 +565,26 @@ class Filters(threading.Thread):
|
|||
self.boxes['groups'] = vbox1
|
||||
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox1.pack_start(hbox, False, True, 0)
|
||||
vbox1.pack_start(hbox, False, False, 0)
|
||||
cb = self.createLimitLine(hbox, 'show', self.filterText['limitsshow'])
|
||||
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox1.pack_start(hbox, False, True, 0)
|
||||
cb = gtk.CheckButton(self.filterText['posnshow'])
|
||||
cb.connect('clicked', self.__set_group_select, 'posn')
|
||||
hbox.pack_start(cb, False, False, 0)
|
||||
self.sbGroups['posn'] = cb
|
||||
self.groups['posn'] = False
|
||||
|
||||
if "SeatSep" in display and display["SeatSep"] == True:
|
||||
hbox = gtk.HBox(False, 0)
|
||||
vbox1.pack_start(hbox, False, True, 0)
|
||||
cb = gtk.CheckButton(self.filterText['seatsshow'])
|
||||
cb.connect('clicked', self.__set_seat_select, 'show')
|
||||
hbox.pack_start(cb, False, False, 0)
|
||||
self.sbSeats['show'] = cb
|
||||
self.seats['show'] = False
|
||||
|
||||
def fillCardsFrame(self, vbox):
|
||||
hbox1 = gtk.HBox(True,0)
|
||||
hbox1.show()
|
||||
|
|
8
pyfpdb/FulltiltToFpdb.py
Normal file → Executable file
8
pyfpdb/FulltiltToFpdb.py
Normal file → Executable file
|
@ -40,6 +40,7 @@ class Fulltilt(HandHistoryConverter):
|
|||
(?P<SB>[.0-9]+)/
|
||||
\$?(?P<BB>[.0-9]+)\s
|
||||
(Ante\s\$?(?P<ANTE>[.0-9]+)\s)?-\s
|
||||
\$?(?P<CAP>[.0-9]+\sCap\s)?
|
||||
(?P<LIMIT>(No\sLimit|Pot\sLimit|Limit))?\s
|
||||
(?P<GAME>(Hold\'em|Omaha\sHi|Omaha\sH/L|7\sCard\sStud|Stud\sH/L|Razz|Stud\sHi))
|
||||
''', re.VERBOSE)
|
||||
|
@ -52,6 +53,7 @@ class Fulltilt(HandHistoryConverter):
|
|||
(?P<TABLE>[-\s\da-zA-Z]+)\s
|
||||
(\((?P<TABLEATTRIBUTES>.+)\)\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<GAMETYPE>[a-zA-Z\/\'\s]+)\s-\s
|
||||
(?P<DATETIME>\d+:\d+:\d+\s\w+\s-\s\d+/\d+/\d+)\s?
|
||||
(?P<PARTIAL>\(partial\))?\n
|
||||
|
@ -143,6 +145,7 @@ class Fulltilt(HandHistoryConverter):
|
|||
return [["ring", "hold", "nl"],
|
||||
["ring", "hold", "pl"],
|
||||
["ring", "hold", "fl"],
|
||||
["ring", "hold", "cn"],
|
||||
|
||||
["ring", "stud", "fl"],
|
||||
|
||||
|
@ -175,7 +178,10 @@ class Fulltilt(HandHistoryConverter):
|
|||
'Stud H/L' : ('stud','studhilo')
|
||||
}
|
||||
currencies = { u' €':'EUR', '$':'USD', '':'T$' }
|
||||
info['limitType'] = limits[mg['LIMIT']]
|
||||
if mg['CAP']:
|
||||
info['limitType'] = 'cn'
|
||||
else:
|
||||
info['limitType'] = limits[mg['LIMIT']]
|
||||
info['sb'] = mg['SB']
|
||||
info['bb'] = mg['BB']
|
||||
if mg['GAME'] != None:
|
||||
|
|
|
@ -53,20 +53,26 @@ class GuiGraphViewer (threading.Thread):
|
|||
self.db = Database.Database(self.conf, sql=self.sql)
|
||||
|
||||
|
||||
filters_display = { "Heroes" : True,
|
||||
"Sites" : True,
|
||||
"Games" : True,
|
||||
"Limits" : True,
|
||||
"Seats" : False,
|
||||
"Dates" : True,
|
||||
"Button1" : True,
|
||||
"Button2" : True
|
||||
filters_display = { "Heroes" : True,
|
||||
"Sites" : True,
|
||||
"Games" : True,
|
||||
"Limits" : True,
|
||||
"LimitSep" : True,
|
||||
"LimitType" : True,
|
||||
"Type" : False,
|
||||
"UseType" : 'ring',
|
||||
"Seats" : False,
|
||||
"SeatSep" : False,
|
||||
"Dates" : True,
|
||||
"Groups" : False,
|
||||
"Button1" : True,
|
||||
"Button2" : True
|
||||
}
|
||||
|
||||
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
|
||||
self.filters.registerButton1Name("Refresh Graph")
|
||||
self.filters.registerButton1Name("Refresh _Graph")
|
||||
self.filters.registerButton1Callback(self.generateGraph)
|
||||
self.filters.registerButton2Name("Export to File")
|
||||
self.filters.registerButton2Name("_Export to File")
|
||||
self.filters.registerButton2Callback(self.exportGraph)
|
||||
|
||||
self.mainHBox = gtk.HBox(False, 0)
|
||||
|
@ -146,10 +152,8 @@ class GuiGraphViewer (threading.Thread):
|
|||
raise
|
||||
|
||||
def generateGraph(self, widget, data):
|
||||
print "generateGraph: start"
|
||||
try:
|
||||
self.clearGraphData()
|
||||
print "after cleardata"
|
||||
|
||||
sitenos = []
|
||||
playerids = []
|
||||
|
@ -158,15 +162,18 @@ class GuiGraphViewer (threading.Thread):
|
|||
heroes = self.filters.getHeroes()
|
||||
siteids = self.filters.getSiteIds()
|
||||
limits = self.filters.getLimits()
|
||||
print "got filter data"
|
||||
for i in ('show', 'none'):
|
||||
if i in limits:
|
||||
limits.remove(i)
|
||||
# Which sites are selected?
|
||||
for site in sites:
|
||||
if sites[site] == True:
|
||||
sitenos.append(siteids[site])
|
||||
self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],))
|
||||
result = self.db.cursor.fetchall()
|
||||
c = self.db.get_cursor()
|
||||
c.execute(self.sql.query['getPlayerId'], (heroes[site],))
|
||||
result = c.fetchall()
|
||||
if len(result) == 1:
|
||||
playerids.append(result[0][0])
|
||||
playerids.append( int(result[0][0]) )
|
||||
|
||||
if not sitenos:
|
||||
#Should probably pop up here.
|
||||
|
@ -182,12 +189,10 @@ class GuiGraphViewer (threading.Thread):
|
|||
return
|
||||
|
||||
#Set graph properties
|
||||
print "add_subplot"
|
||||
self.ax = self.fig.add_subplot(111)
|
||||
|
||||
#Get graph data from DB
|
||||
starttime = time()
|
||||
print "get line: playerids =", playerids, "sitenos =", sitenos, "limits =", limits
|
||||
line = self.getRingProfitGraph(playerids, sitenos, limits)
|
||||
print "Graph generated in: %s" %(time() - starttime)
|
||||
|
||||
|
@ -234,12 +239,31 @@ class GuiGraphViewer (threading.Thread):
|
|||
# [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829)
|
||||
nametest = str(tuple(names))
|
||||
sitetest = str(tuple(sites))
|
||||
limittest = str(tuple(limits))
|
||||
nametest = nametest.replace("L", "")
|
||||
nametest = nametest.replace(",)",")")
|
||||
sitetest = sitetest.replace(",)",")")
|
||||
limittest = limittest.replace("L", "")
|
||||
limittest = limittest.replace(",)",")")
|
||||
#nametest = nametest.replace("L", "")
|
||||
|
||||
lims = [int(x) for x in limits if x.isdigit()]
|
||||
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
||||
limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
||||
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
||||
if lims:
|
||||
blindtest = str(tuple(lims))
|
||||
blindtest = blindtest.replace("L", "")
|
||||
blindtest = blindtest.replace(",)",")")
|
||||
limittest = limittest + blindtest + ' ) '
|
||||
else:
|
||||
limittest = limittest + '(-1) ) '
|
||||
limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
||||
if nolims:
|
||||
blindtest = str(tuple(nolims))
|
||||
blindtest = blindtest.replace("L", "")
|
||||
blindtest = blindtest.replace(",)",")")
|
||||
limittest = limittest + blindtest + ' ) )'
|
||||
else:
|
||||
limittest = limittest + '(-1) ) )'
|
||||
if type == 'ring':
|
||||
limittest = limittest + " and gt.type = 'ring' "
|
||||
elif type == 'tour':
|
||||
limittest = limittest + " and gt.type = 'tour' "
|
||||
|
||||
#Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf
|
||||
tmp = tmp.replace("<player_test>", nametest)
|
||||
|
@ -247,6 +271,7 @@ class GuiGraphViewer (threading.Thread):
|
|||
tmp = tmp.replace("<startdate_test>", start_date)
|
||||
tmp = tmp.replace("<enddate_test>", end_date)
|
||||
tmp = tmp.replace("<limit_test>", limittest)
|
||||
tmp = tmp.replace(",)", ")")
|
||||
|
||||
#print "DEBUG: sql query:"
|
||||
#print tmp
|
||||
|
@ -255,10 +280,10 @@ class GuiGraphViewer (threading.Thread):
|
|||
winnings = self.db.cursor.fetchall()
|
||||
self.db.rollback()
|
||||
|
||||
if(winnings == ()):
|
||||
if winnings == ():
|
||||
return None
|
||||
|
||||
y=map(lambda x:float(x[3]), winnings)
|
||||
y = map(lambda x:float(x[1]), winnings)
|
||||
line = cumsum(y)
|
||||
return line/100
|
||||
#end of def getRingProfitGraph
|
||||
|
|
|
@ -54,17 +54,19 @@ class GuiPlayerStats (threading.Thread):
|
|||
self.filterText = {'handhead':'Hand Breakdown for all levels listed above'
|
||||
}
|
||||
|
||||
filters_display = { "Heroes" : True,
|
||||
"Sites" : True,
|
||||
"Games" : False,
|
||||
"Limits" : True,
|
||||
"LimitSep" : True,
|
||||
"Seats" : True,
|
||||
"SeatSep" : True,
|
||||
"Dates" : True,
|
||||
"Groups" : True,
|
||||
"Button1" : True,
|
||||
"Button2" : True
|
||||
filters_display = { "Heroes" : True,
|
||||
"Sites" : True,
|
||||
"Games" : False,
|
||||
"Limits" : True,
|
||||
"LimitSep" : True,
|
||||
"LimitType" : True,
|
||||
"Type" : True,
|
||||
"Seats" : True,
|
||||
"SeatSep" : True,
|
||||
"Dates" : True,
|
||||
"Groups" : True,
|
||||
"Button1" : True,
|
||||
"Button2" : True
|
||||
}
|
||||
|
||||
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
|
||||
|
@ -157,6 +159,7 @@ class GuiPlayerStats (threading.Thread):
|
|||
heroes = self.filters.getHeroes()
|
||||
siteids = self.filters.getSiteIds()
|
||||
limits = self.filters.getLimits()
|
||||
type = self.filters.getType()
|
||||
seats = self.filters.getSeats()
|
||||
groups = self.filters.getGroups()
|
||||
dates = self.filters.getDates()
|
||||
|
@ -185,16 +188,16 @@ class GuiPlayerStats (threading.Thread):
|
|||
print "No limits found"
|
||||
return
|
||||
|
||||
self.createStatsTable(vbox, playerids, sitenos, limits, seats, groups, dates)
|
||||
self.createStatsTable(vbox, playerids, sitenos, limits, type, seats, groups, dates)
|
||||
|
||||
def createStatsTable(self, vbox, playerids, sitenos, limits, seats, groups, dates):
|
||||
def createStatsTable(self, vbox, playerids, sitenos, limits, type, seats, groups, dates):
|
||||
starttime = time()
|
||||
|
||||
# Display summary table at top of page
|
||||
# 3rd parameter passes extra flags, currently includes:
|
||||
# holecards - whether to display card breakdown (True/False)
|
||||
flags = [False]
|
||||
self.addTable(vbox, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, groups, dates)
|
||||
self.addTable(vbox, 'playerDetailedStats', flags, playerids, sitenos, limits, type, seats, groups, dates)
|
||||
|
||||
# Separator
|
||||
sep = gtk.HSeparator()
|
||||
|
@ -217,13 +220,13 @@ class GuiPlayerStats (threading.Thread):
|
|||
|
||||
# Detailed table
|
||||
flags = [True]
|
||||
self.addTable(vbox1, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, groups, dates)
|
||||
self.addTable(vbox1, 'playerDetailedStats', flags, playerids, sitenos, limits, type, seats, groups, dates)
|
||||
|
||||
self.db.rollback()
|
||||
print "Stats page displayed in %4.2f seconds" % (time() - starttime)
|
||||
#end def fillStatsFrame(self, vbox):
|
||||
|
||||
def addTable(self, vbox, query, flags, playerids, sitenos, limits, seats, groups, dates):
|
||||
def addTable(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates):
|
||||
row = 0
|
||||
sqlrow = 0
|
||||
colalias,colshow,colheading,colxalign,colformat = 0,1,2,3,4
|
||||
|
@ -231,7 +234,7 @@ class GuiPlayerStats (threading.Thread):
|
|||
else: holecards = flags[0]
|
||||
|
||||
tmp = self.sql.query[query]
|
||||
tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, seats, groups, dates)
|
||||
tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, type, seats, groups, dates)
|
||||
self.cursor.execute(tmp)
|
||||
result = self.cursor.fetchall()
|
||||
colnames = [desc[0].lower() for desc in self.cursor.description]
|
||||
|
@ -317,9 +320,9 @@ class GuiPlayerStats (threading.Thread):
|
|||
row += 1
|
||||
vbox.show_all()
|
||||
|
||||
#end def addTable(self, query, vars, playerids, sitenos, limits, seats):
|
||||
#end def addTable(self, query, vars, playerids, sitenos, limits, type, seats, groups, dates):
|
||||
|
||||
def refineQuery(self, query, flags, playerids, sitenos, limits, seats, groups, dates):
|
||||
def refineQuery(self, query, flags, playerids, sitenos, limits, type, seats, groups, dates):
|
||||
if not flags: holecards = False
|
||||
else: holecards = flags[0]
|
||||
|
||||
|
@ -344,13 +347,30 @@ class GuiPlayerStats (threading.Thread):
|
|||
query = query.replace('<groupbyseats>', '')
|
||||
query = query.replace('<orderbyseats>', '')
|
||||
|
||||
if [x for x in limits if str(x).isdigit()]:
|
||||
blindtest = str(tuple([x for x in limits if str(x).isdigit()]))
|
||||
lims = [int(x) for x in limits if x.isdigit()]
|
||||
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
||||
bbtest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
||||
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
||||
if lims:
|
||||
blindtest = str(tuple(lims))
|
||||
blindtest = blindtest.replace("L", "")
|
||||
blindtest = blindtest.replace(",)",")")
|
||||
query = query.replace("<gtbigBlind_test>", " and gt.bigBlind in " + blindtest + " ")
|
||||
bbtest = bbtest + blindtest + ' ) '
|
||||
else:
|
||||
query = query.replace("<gtbigBlind_test>", "")
|
||||
bbtest = bbtest + '(-1) ) '
|
||||
bbtest = bbtest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
||||
if nolims:
|
||||
blindtest = str(tuple(nolims))
|
||||
blindtest = blindtest.replace("L", "")
|
||||
blindtest = blindtest.replace(",)",")")
|
||||
bbtest = bbtest + blindtest + ' ) )'
|
||||
else:
|
||||
bbtest = bbtest + '(-1) ) )'
|
||||
if type == 'ring':
|
||||
bbtest = bbtest + " and gt.type = 'ring' "
|
||||
elif type == 'tour':
|
||||
bbtest = bbtest + " and gt.type = 'tour' "
|
||||
query = query.replace("<gtbigBlind_test>", bbtest)
|
||||
|
||||
if holecards: # pinch level variables for hole card query
|
||||
query = query.replace("<hgameTypeId>", "hp.startcards")
|
||||
|
|
|
@ -4,8 +4,96 @@
|
|||
|
||||
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
|
||||
|
||||
<hud_ui label="FPDB Menu - Right-click
|
||||
Left-Drag to Move" />
|
||||
<!-- These values need some explaining
|
||||
|
||||
aggregate_ring_game_stats :
|
||||
- True/False
|
||||
- if set to True, includes data from other blind levels
|
||||
- defaults to False
|
||||
|
||||
aggregate_tourney_stats :
|
||||
- True/False
|
||||
- if set to True, includes data from other blind levels
|
||||
- defaults to True
|
||||
|
||||
stat_aggregation_range :
|
||||
- A/S/T
|
||||
- if set to A, includes stats from all time
|
||||
- if set to S, includes stats from current sessions
|
||||
- if set to T, includes stats from last N days; set value in hud_days
|
||||
- defaults to A
|
||||
|
||||
aggregation_days :
|
||||
- a numeric value
|
||||
- if hud_style is set to 'T', this value tells how many days are
|
||||
included in the stat calculation
|
||||
- defaults to 90
|
||||
- value not used by default, as depends on hud_style setting
|
||||
|
||||
aggregation_level_multiplier :
|
||||
- float value
|
||||
- defines how many blind levels are used for aggregation
|
||||
- the logic is weird, at best
|
||||
- if value is 100, almost all levels are included
|
||||
- if value is 2.1, levels from half to double the current blind
|
||||
level are included
|
||||
- if value it 1, no aggregation is performed
|
||||
- defaults to 1
|
||||
|
||||
|
||||
The following values define how hero's stats are done
|
||||
|
||||
|
||||
aggregate_hero_ring_game_stats :
|
||||
- True/False
|
||||
- if set to True, hero's data is calculated over multiple blind levels
|
||||
- defaults to False
|
||||
|
||||
aggregate_hero_tourney_stats :
|
||||
- True/False
|
||||
- if set to True, hero's data is calculated over multiple blind levels
|
||||
- defaults to False
|
||||
|
||||
hero_stat_aggregation_range :
|
||||
- A/S/T
|
||||
- if set to A, includes stats from all time
|
||||
- if set to S, includes stats from current sessions
|
||||
- if set to T, includes stats from last N days; set value in hud_days
|
||||
- defaults to S
|
||||
|
||||
hero_aggregation_days :
|
||||
- a numeric value
|
||||
- if hero_stat_aggregation_range is set to 'T', this value tells
|
||||
how many days are included in the stat calculation
|
||||
- defaults to 30
|
||||
- value not used by default, as depends on hud_style setting
|
||||
|
||||
hero_aggregation_level_multiplier :
|
||||
- float value
|
||||
- defines how many blind levels are used for aggregation
|
||||
- the logic is weird, at best
|
||||
- if value is 100, almost all levels are included
|
||||
- if value is 2.1, levels from half to double the current blind
|
||||
level are included
|
||||
- if value it 1, no aggregation is performed
|
||||
- defaults to 1
|
||||
-->
|
||||
<hud_ui
|
||||
aggregate_ring_game_stats="False"
|
||||
aggregate_tourney_stats="False"
|
||||
stat_aggregation_range="A"
|
||||
aggregation_days="90"
|
||||
aggregation_level_multiplier="1"
|
||||
|
||||
aggregate_hero_ring_game_stats="False"
|
||||
aggregate_hero_tourney_stats="True"
|
||||
hero_stat_aggregation_range="S"
|
||||
hero_aggregation_days="30"
|
||||
hero_aggregation_level_multiplier="1"
|
||||
|
||||
label="FPDB Menu - Right-click
|
||||
Left-Drag to Move"
|
||||
/>
|
||||
|
||||
<supported_sites>
|
||||
|
||||
|
|
|
@ -56,23 +56,32 @@ import Database
|
|||
import Tables
|
||||
import Hud
|
||||
|
||||
# To add to config:
|
||||
aggregate_stats = {"ring": False, "tour": False} # uses agg_bb_mult
|
||||
hud_style = 'A' # A=All-time
|
||||
# S=Session
|
||||
# T=timed (last n days - set hud_days to required value)
|
||||
# Future values may also include:
|
||||
# H=Hands (last n hands)
|
||||
hud_days = 90 # Max number of days from each player to use for hud stats
|
||||
agg_bb_mult = 100 # 1 = no aggregation. When aggregating stats across levels larger blinds
|
||||
# must be < (agg_bb_mult * smaller blinds) to be aggregated
|
||||
# ie. 100 will aggregate almost everything, 2 will probably agg just the
|
||||
# next higher and lower levels into the current one, try 3/10/30/100
|
||||
hud_session_gap = 30 # Gap (minutes) between hands that indicates a change of session
|
||||
# (hands every 2 mins for 1 hour = one session, if followed
|
||||
# by a 40 minute gap and then more hands on same table that is
|
||||
# a new session)
|
||||
#hud_hands = 0 # Max number of hands from each player to use for hud stats (not used)
|
||||
|
||||
# HUD params:
|
||||
# - Set aggregate_ring and/or aggregate_tour to True is you want to include stats from other blind levels in the HUD display
|
||||
# - If aggregation is used, the value of agg_bb_mult determines how what levels are included, e.g.
|
||||
# if agg_bb_mult is 100, almost all levels are included in all HUD displays
|
||||
# if agg_bb_mult is 2.1, levels from half to double the current blind level are included in the HUD
|
||||
# - Set hud_style to A to see stats for all-time
|
||||
# Set hud_style to S to only see stats for current session (currently this shows stats for the last 24 hours)
|
||||
# Set hud_style to T to only see stats for the last N days (uses value in hud_days)
|
||||
# - Set hud_days to N to see stats for the last N days in the HUD (only applies if hud_style is T)
|
||||
def_hud_params = { # Settings for all players apart from program owner ('hero')
|
||||
'aggregate_ring' : False
|
||||
, 'aggregate_tour' : True
|
||||
, 'hud_style' : 'A'
|
||||
, 'hud_days' : 90
|
||||
, 'agg_bb_mult' : 1 # 1 means no aggregation
|
||||
# , 'hud_session_gap' : 30 not currently used
|
||||
# Second set of variables for hero - these settings only apply to the program owner
|
||||
, 'h_aggregate_ring' : False
|
||||
, 'h_aggregate_tour' : True
|
||||
, 'h_hud_style' : 'S' # A(ll) / S(ession) / T(ime in days)
|
||||
, 'h_hud_days' : 30
|
||||
, 'h_agg_bb_mult' : 1 # 1 means no aggregation
|
||||
# , 'h_hud_session_gap' : 30 not currently used
|
||||
}
|
||||
|
||||
|
||||
class HUD_main(object):
|
||||
"""A main() object to own both the read_stdin thread and the gui."""
|
||||
|
@ -82,6 +91,7 @@ class HUD_main(object):
|
|||
self.db_name = db_name
|
||||
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
|
||||
self.hud_dict = {}
|
||||
self.hud_params = self.config.get_hud_ui_parameters()
|
||||
|
||||
# a thread to read stdin
|
||||
gobject.threads_init() # this is required
|
||||
|
@ -104,12 +114,17 @@ class HUD_main(object):
|
|||
# called by an event in the HUD, to kill this specific HUD
|
||||
if table in self.hud_dict:
|
||||
self.hud_dict[table].kill()
|
||||
self.hud_dict[table].main_window.destroy()
|
||||
try:
|
||||
# throws exception in windows sometimes (when closing using main_window menu?)
|
||||
self.hud_dict[table].main_window.destroy()
|
||||
except:
|
||||
pass
|
||||
self.vb.remove(self.hud_dict[table].tablehudlabel)
|
||||
del(self.hud_dict[table])
|
||||
self.main_window.resize(1,1)
|
||||
|
||||
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, stat_dict, cards):
|
||||
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, type, stat_dict, cards):
|
||||
"""type is "ring" or "tour" used to set hud_params"""
|
||||
|
||||
def idle_func():
|
||||
|
||||
|
@ -135,6 +150,18 @@ class HUD_main(object):
|
|||
self.hud_dict[table_name].table_name = table_name
|
||||
self.hud_dict[table_name].stat_dict = stat_dict
|
||||
self.hud_dict[table_name].cards = cards
|
||||
|
||||
if type == "tour" and self.hud_params['aggregate_tour'] == False:
|
||||
self.hud_dict[table_name].hud_params['agg_bb_mult'] = 1
|
||||
elif type == "ring" and self.hud_params['aggregate_ring'] == False:
|
||||
self.hud_dict[table_name].hud_params['agg_bb_mult'] = 1
|
||||
if type == "tour" and self.hud_params['h_aggregate_tour'] == False:
|
||||
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
|
||||
elif type == "ring" and self.hud_params['h_aggregate_ring'] == False:
|
||||
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
|
||||
self.hud_params['aggregate_ring'] == True
|
||||
self.hud_params['h_aggregate_ring'] == True
|
||||
|
||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[table_name].aux_windows]
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
|
@ -160,68 +187,99 @@ class HUD_main(object):
|
|||
# be passed to HUDs for use in the gui thread. HUD objects should not
|
||||
# need their own access to the database, but should open their own
|
||||
# if it is required.
|
||||
self.db_connection = Database.Database(self.config)
|
||||
self.db_connection.init_hud_stat_vars(hud_days)
|
||||
tourny_finder = re.compile('(\d+) (\d+)')
|
||||
|
||||
while 1: # wait for a new hand number on stdin
|
||||
new_hand_id = sys.stdin.readline()
|
||||
new_hand_id = string.rstrip(new_hand_id)
|
||||
if new_hand_id == "": # blank line means quit
|
||||
self.destroy()
|
||||
break # this thread is not always killed immediately with gtk.main_quit()
|
||||
# get basic info about the new hand from the db
|
||||
# if there is a db error, complain, skip hand, and proceed
|
||||
try:
|
||||
(table_name, max, poker_game, type) = self.db_connection.get_table_name(new_hand_id)
|
||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate_stats[type]
|
||||
,hud_style, agg_bb_mult)
|
||||
try:
|
||||
self.db_connection = Database.Database(self.config)
|
||||
tourny_finder = re.compile('(\d+) (\d+)')
|
||||
|
||||
# get hero's screen names and player ids
|
||||
self.hero, self.hero_ids = {}, {}
|
||||
for site in self.config.get_supported_sites():
|
||||
result = self.db_connection.get_site_id(site)
|
||||
if result:
|
||||
site_id = result[0][0]
|
||||
self.hero[site_id] = self.config.supported_sites[site].screen_name
|
||||
self.hero_ids[site_id] = self.db_connection.get_player_id(self.config, site, self.hero[site_id])
|
||||
|
||||
while 1: # wait for a new hand number on stdin
|
||||
new_hand_id = sys.stdin.readline()
|
||||
new_hand_id = string.rstrip(new_hand_id)
|
||||
if new_hand_id == "": # blank line means quit
|
||||
self.destroy()
|
||||
break # this thread is not always killed immediately with gtk.main_quit()
|
||||
# get basic info about the new hand from the db
|
||||
# if there is a db error, complain, skip hand, and proceed
|
||||
try:
|
||||
(table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id)
|
||||
|
||||
cards = self.db_connection.get_cards(new_hand_id)
|
||||
comm_cards = self.db_connection.get_common_cards(new_hand_id)
|
||||
if comm_cards != {}: # stud!
|
||||
cards['common'] = comm_cards['common']
|
||||
except Exception, err:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "db error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
||||
sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||
continue
|
||||
|
||||
if type == "tour": # hand is from a tournament
|
||||
mat_obj = tourny_finder.search(table_name)
|
||||
if mat_obj:
|
||||
(tour_number, tab_number) = mat_obj.group(1, 2)
|
||||
temp_key = tour_number
|
||||
else: # tourney, but can't get number and table
|
||||
print "could not find tournament: skipping "
|
||||
#sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id)))
|
||||
cards = self.db_connection.get_cards(new_hand_id)
|
||||
comm_cards = self.db_connection.get_common_cards(new_hand_id)
|
||||
if comm_cards != {}: # stud!
|
||||
cards['common'] = comm_cards['common']
|
||||
except Exception, err:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "db error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
||||
sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||
continue
|
||||
|
||||
else:
|
||||
temp_key = table_name
|
||||
|
||||
# Update an existing HUD
|
||||
if temp_key in self.hud_dict:
|
||||
self.hud_dict[temp_key].stat_dict = stat_dict
|
||||
self.hud_dict[temp_key].cards = cards
|
||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
||||
self.update_HUD(new_hand_id, temp_key, self.config)
|
||||
|
||||
# Or create a new HUD
|
||||
else:
|
||||
if type == "tour":
|
||||
tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number)
|
||||
if type == "tour": # hand is from a tournament
|
||||
mat_obj = tourny_finder.search(table_name)
|
||||
if mat_obj:
|
||||
(tour_number, tab_number) = mat_obj.group(1, 2)
|
||||
temp_key = tour_number
|
||||
else: # tourney, but can't get number and table
|
||||
print "could not find tournament: skipping "
|
||||
#sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id)))
|
||||
continue
|
||||
|
||||
else:
|
||||
tablewindow = Tables.discover_table_by_name(self.config, table_name)
|
||||
if tablewindow == None:
|
||||
# If no client window is found on the screen, complain and continue
|
||||
temp_key = table_name
|
||||
|
||||
# Update an existing HUD
|
||||
if temp_key in self.hud_dict:
|
||||
try:
|
||||
# get stats using hud's specific params
|
||||
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
||||
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params, self.hero_ids[site_id])
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
||||
sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||
continue
|
||||
self.hud_dict[temp_key].stat_dict = stat_dict
|
||||
self.hud_dict[temp_key].cards = cards
|
||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
||||
self.update_HUD(new_hand_id, temp_key, self.config)
|
||||
|
||||
# Or create a new HUD
|
||||
else:
|
||||
try:
|
||||
# get stats using default params
|
||||
self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] )
|
||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params, self.hero_ids[site_id])
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
||||
sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||
continue
|
||||
if type == "tour":
|
||||
table_name = "%s %s" % (tour_number, tab_number)
|
||||
sys.stderr.write("table name "+table_name+" not found, skipping.\n")
|
||||
else:
|
||||
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, stat_dict, cards)
|
||||
self.db_connection.connection.rollback()
|
||||
tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number)
|
||||
else:
|
||||
tablewindow = Tables.discover_table_by_name(self.config, table_name)
|
||||
if tablewindow == None:
|
||||
# If no client window is found on the screen, complain and continue
|
||||
if type == "tour":
|
||||
table_name = "%s %s" % (tour_number, tab_number)
|
||||
sys.stderr.write("table name "+table_name+" not found, skipping.\n")
|
||||
else:
|
||||
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
|
||||
self.db_connection.connection.rollback()
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
|
||||
if __name__== "__main__":
|
||||
|
||||
|
|
|
@ -194,64 +194,32 @@ dealt whether they were seen in a 'dealt to' line
|
|||
""" Function to insert Hand into database
|
||||
Should not commit, and do minimal selects. Callers may want to cache commits
|
||||
db: a connected fpdb_db object"""
|
||||
# TODO:
|
||||
|
||||
#####
|
||||
# Players, Gametypes, TourneyTypes are all shared functions that are needed for additional tables
|
||||
# These functions are intended for prep insert eventually
|
||||
#####
|
||||
# Players - base playerid and siteid tuple
|
||||
sqlids = db.getSqlPlayerIDs([p[1] for p in self.players], self.siteId)
|
||||
|
||||
#Gametypes
|
||||
gtid = db.getGameTypeId(self.siteId, self.gametype)
|
||||
|
||||
self.stats.assembleHands(self)
|
||||
|
||||
#####
|
||||
# End prep functions
|
||||
#####
|
||||
|
||||
# HudCache data to come from DerivedStats class
|
||||
# HandsActions - all actions for all players for all streets - self.actions
|
||||
|
||||
# Hands - Summary information of hand indexed by handId - gameinfo
|
||||
#This should be moved to prepInsert
|
||||
hh = {}
|
||||
hh['siteHandNo'] = self.handid
|
||||
hh['handStart'] = self.starttime
|
||||
hh = self.stats.getHands()
|
||||
hh['gameTypeId'] = gtid
|
||||
# seats TINYINT NOT NULL,
|
||||
hh['tableName'] = self.tablename
|
||||
hh['maxSeats'] = self.maxseats
|
||||
hh['seats'] = len(sqlids)
|
||||
# Flop turn and river may all be empty - add (likely) too many elements and trim with range
|
||||
boardcards = self.board['FLOP'] + self.board['TURN'] + self.board['RIVER'] + [u'0x', u'0x', u'0x', u'0x', u'0x']
|
||||
cards = [Card.encodeCard(c) for c in boardcards[0:5]]
|
||||
hh['boardcard1'] = cards[0]
|
||||
hh['boardcard2'] = cards[1]
|
||||
hh['boardcard3'] = cards[2]
|
||||
hh['boardcard4'] = cards[3]
|
||||
hh['boardcard5'] = cards[4]
|
||||
|
||||
# texture smallint,
|
||||
# playersVpi SMALLINT NOT NULL, /* num of players vpi */
|
||||
# Needs to be recorded
|
||||
# playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4 */
|
||||
# Needs to be recorded
|
||||
# playersAtStreet2 SMALLINT NOT NULL,
|
||||
# Needs to be recorded
|
||||
# playersAtStreet3 SMALLINT NOT NULL,
|
||||
# Needs to be recorded
|
||||
# playersAtStreet4 SMALLINT NOT NULL,
|
||||
# Needs to be recorded
|
||||
# playersAtShowdown SMALLINT NOT NULL,
|
||||
# Needs to be recorded
|
||||
# street0Raises TINYINT NOT NULL, /* num small bets paid to see flop/street4, including blind */
|
||||
# Needs to be recorded
|
||||
# street1Raises TINYINT NOT NULL, /* num small bets paid to see turn/street5 */
|
||||
# Needs to be recorded
|
||||
# street2Raises TINYINT NOT NULL, /* num big bets paid to see river/street6 */
|
||||
# Needs to be recorded
|
||||
# street3Raises TINYINT NOT NULL, /* num big bets paid to see sd/street7 */
|
||||
# Needs to be recorded
|
||||
# street4Raises TINYINT NOT NULL, /* num big bets paid to see showdown */
|
||||
# Needs to be recorded
|
||||
|
||||
#print "DEBUG: self.getStreetTotals = (%s, %s, %s, %s, %s)" % self.getStreetTotals()
|
||||
#FIXME: Pot size still in decimal, needs to be converted to cents
|
||||
(hh['street1Pot'], hh['street2Pot'], hh['street3Pot'], hh['street4Pot'], hh['showdownPot']) = self.getStreetTotals()
|
||||
|
||||
# comment TEXT,
|
||||
# commentTs DATETIME
|
||||
#print hh
|
||||
handid = db.storeHand(hh)
|
||||
# HandsPlayers - ? ... Do we fix winnings?
|
||||
|
@ -603,7 +571,11 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
|||
return gs + timestr
|
||||
|
||||
def writeTableLine(self):
|
||||
table_string = "Table \'%s\' %s-max" % (self.tablename, self.maxseats)
|
||||
table_string = "Table "
|
||||
if self.gametype['type'] == 'tour':
|
||||
table_string = table_string + "\'%s %s\' %s-max" % (self.tourNo, self.tablename, self.maxseats)
|
||||
else:
|
||||
table_string = table_string + "\'%s\' %s-max" % (self.tablename, self.maxseats)
|
||||
if self.gametype['currency'] == 'play':
|
||||
table_string = table_string + " (Play Money)"
|
||||
if self.buttonpos != None and self.buttonpos != 0:
|
||||
|
@ -673,7 +645,14 @@ class HoldemOmahaHand(Hand):
|
|||
if shown: self.shown.add(player)
|
||||
if mucked: self.mucked.add(player)
|
||||
else:
|
||||
self.addHoleCards('PREFLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||
if len(cards) in (2, 4): # avoid adding board by mistake (Everleaf problem)
|
||||
self.addHoleCards('PREFLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||
elif len(cards) == 5: # cards holds a winning hand, not hole cards
|
||||
# filter( lambda x: x not in b, a ) # calcs a - b where a and b are lists
|
||||
# so diff is set to the winning hand minus the board cards, if we're lucky that leaves the hole cards
|
||||
diff = filter( lambda x: x not in self.board['FLOP']+self.board['TURN']+self.board['RIVER'], cards )
|
||||
if len(diff) == 2 and self.gametype['category'] in ('holdem'):
|
||||
self.addHoleCards('PREFLOP', player, open=[], closed=diff, shown=shown, mucked=mucked, dealt=dealt)
|
||||
|
||||
def getStreetTotals(self):
|
||||
# street1Pot INT, /* pot size at flop/street4 */
|
||||
|
|
202
pyfpdb/Hud.py
202
pyfpdb/Hud.py
|
@ -73,6 +73,8 @@ class Hud:
|
|||
self.stacked = True
|
||||
self.site = table.site
|
||||
self.mw_created = False
|
||||
self.hud_params = parent.hud_params
|
||||
|
||||
|
||||
self.stat_windows = {}
|
||||
self.popup_windows = {}
|
||||
|
@ -144,6 +146,147 @@ class Hud:
|
|||
repositem = gtk.MenuItem('Reposition StatWindows')
|
||||
menu.append(repositem)
|
||||
repositem.connect("activate", self.reposition_windows)
|
||||
|
||||
aggitem = gtk.MenuItem('Show Player Stats')
|
||||
menu.append(aggitem)
|
||||
self.aggMenu = gtk.Menu()
|
||||
aggitem.set_submenu(self.aggMenu)
|
||||
# set agg_bb_mult to 1 to stop aggregation
|
||||
item = gtk.CheckMenuItem('For This Blind Level Only')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('P',1))
|
||||
setattr(self, 'h_aggBBmultItem1', item)
|
||||
#
|
||||
item = gtk.MenuItem('For Multiple Blind Levels:')
|
||||
self.aggMenu.append(item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' 0.5 to 2.0 x Current Blinds')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('P',2))
|
||||
setattr(self, 'h_aggBBmultItem2', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' 0.33 to 3.0 x Current Blinds')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('P',3))
|
||||
setattr(self, 'h_aggBBmultItem3', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' 0.1 to 10 x Current Blinds')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('P',10))
|
||||
setattr(self, 'h_aggBBmultItem10', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' All Levels')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('P',10000))
|
||||
setattr(self, 'h_aggBBmultItem10000', item)
|
||||
#
|
||||
item = gtk.MenuItem('Since:')
|
||||
self.aggMenu.append(item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' All Time')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_hud_style, ('P','A'))
|
||||
setattr(self, 'h_hudStyleOptionA', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' Session')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_hud_style, ('P','S'))
|
||||
setattr(self, 'h_hudStyleOptionS', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' %s Days' % (self.hud_params['h_hud_days']))
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_hud_style, ('P','T'))
|
||||
setattr(self, 'h_hudStyleOptionT', item)
|
||||
|
||||
aggitem = gtk.MenuItem('Show Opponent Stats')
|
||||
menu.append(aggitem)
|
||||
self.aggMenu = gtk.Menu()
|
||||
aggitem.set_submenu(self.aggMenu)
|
||||
# set agg_bb_mult to 1 to stop aggregation
|
||||
item = gtk.CheckMenuItem('For This Blind Level Only')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('O',1))
|
||||
setattr(self, 'aggBBmultItem1', item)
|
||||
#
|
||||
item = gtk.MenuItem('For Multiple Blind Levels:')
|
||||
self.aggMenu.append(item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' 0.5 to 2.0 x Current Blinds')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('O',2))
|
||||
setattr(self, 'aggBBmultItem2', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' 0.33 to 3.0 x Current Blinds')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('O',3))
|
||||
setattr(self, 'aggBBmultItem3', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' 0.1 to 10 x Current Blinds')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('O',10))
|
||||
setattr(self, 'aggBBmultItem10', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' All Levels')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_aggregation, ('O',10000))
|
||||
setattr(self, 'aggBBmultItem10000', item)
|
||||
#
|
||||
item = gtk.MenuItem('Since:')
|
||||
self.aggMenu.append(item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' All Time')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_hud_style, ('O','A'))
|
||||
setattr(self, 'hudStyleOptionA', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' Session')
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_hud_style, ('O','S'))
|
||||
setattr(self, 'hudStyleOptionS', item)
|
||||
#
|
||||
item = gtk.CheckMenuItem(' %s Days' % (self.hud_params['h_hud_days']))
|
||||
self.aggMenu.append(item)
|
||||
item.connect("activate", self.set_hud_style, ('O','T'))
|
||||
setattr(self, 'hudStyleOptionT', item)
|
||||
|
||||
# set active on current options:
|
||||
if self.hud_params['h_agg_bb_mult'] == 1:
|
||||
getattr(self, 'h_aggBBmultItem1').set_active(True)
|
||||
elif self.hud_params['h_agg_bb_mult'] == 2:
|
||||
getattr(self, 'h_aggBBmultItem2').set_active(True)
|
||||
elif self.hud_params['h_agg_bb_mult'] == 3:
|
||||
getattr(self, 'h_aggBBmultItem3').set_active(True)
|
||||
elif self.hud_params['h_agg_bb_mult'] == 10:
|
||||
getattr(self, 'h_aggBBmultItem10').set_active(True)
|
||||
elif self.hud_params['h_agg_bb_mult'] > 9000:
|
||||
getattr(self, 'h_aggBBmultItem10000').set_active(True)
|
||||
#
|
||||
if self.hud_params['agg_bb_mult'] == 1:
|
||||
getattr(self, 'aggBBmultItem1').set_active(True)
|
||||
elif self.hud_params['agg_bb_mult'] == 2:
|
||||
getattr(self, 'aggBBmultItem2').set_active(True)
|
||||
elif self.hud_params['agg_bb_mult'] == 3:
|
||||
getattr(self, 'aggBBmultItem3').set_active(True)
|
||||
elif self.hud_params['agg_bb_mult'] == 10:
|
||||
getattr(self, 'aggBBmultItem10').set_active(True)
|
||||
elif self.hud_params['agg_bb_mult'] > 9000:
|
||||
getattr(self, 'aggBBmultItem10000').set_active(True)
|
||||
#
|
||||
if self.hud_params['h_hud_style'] == 'A':
|
||||
getattr(self, 'h_hudStyleOptionA').set_active(True)
|
||||
elif self.hud_params['h_hud_style'] == 'S':
|
||||
getattr(self, 'h_hudStyleOptionS').set_active(True)
|
||||
elif self.hud_params['h_hud_style'] == 'T':
|
||||
getattr(self, 'h_hudStyleOptionT').set_active(True)
|
||||
#
|
||||
if self.hud_params['hud_style'] == 'A':
|
||||
getattr(self, 'hudStyleOptionA').set_active(True)
|
||||
elif self.hud_params['hud_style'] == 'S':
|
||||
getattr(self, 'hudStyleOptionS').set_active(True)
|
||||
elif self.hud_params['hud_style'] == 'T':
|
||||
getattr(self, 'hudStyleOptionT').set_active(True)
|
||||
|
||||
eventbox.connect_object("button-press-event", self.on_button_press, menu)
|
||||
|
||||
debugitem = gtk.MenuItem('Debug StatWindows')
|
||||
menu.append(debugitem)
|
||||
|
@ -177,9 +320,58 @@ class Hud:
|
|||
self.create(*self.creation_attrs)
|
||||
self.update(self.hand, self.config)
|
||||
except Exception, e:
|
||||
print "Expcetion:",str(e)
|
||||
print "Exception:",str(e)
|
||||
pass
|
||||
|
||||
def set_aggregation(self, widget, val):
|
||||
(player_opp, num) = val
|
||||
if player_opp == 'P':
|
||||
# set these true all the time, set the multiplier to 1 to turn agg off:
|
||||
self.hud_params['h_aggregate_ring'] = True
|
||||
self.hud_params['h_aggregate_tour'] = True
|
||||
|
||||
if self.hud_params['h_agg_bb_mult'] != num \
|
||||
and getattr(self, 'h_aggBBmultItem'+str(num)).get_active():
|
||||
print 'set_player_aggregation', num
|
||||
self.hud_params['h_agg_bb_mult'] = num
|
||||
for mult in ('1', '2', '3', '10', '10000'):
|
||||
if mult != str(num):
|
||||
getattr(self, 'h_aggBBmultItem'+mult).set_active(False)
|
||||
else:
|
||||
self.hud_params['aggregate_ring'] = True
|
||||
self.hud_params['aggregate_tour'] = True
|
||||
|
||||
if self.hud_params['agg_bb_mult'] != num \
|
||||
and getattr(self, 'aggBBmultItem'+str(num)).get_active():
|
||||
print 'set_opponent_aggregation', num
|
||||
self.hud_params['agg_bb_mult'] = num
|
||||
for mult in ('1', '2', '3', '10', '10000'):
|
||||
if mult != str(num):
|
||||
getattr(self, 'aggBBmultItem'+mult).set_active(False)
|
||||
|
||||
def set_hud_style(self, widget, val):
|
||||
(player_opp, style) = val
|
||||
if player_opp == 'P':
|
||||
param = 'h_hud_style'
|
||||
prefix = 'h_'
|
||||
else:
|
||||
param = 'hud_style'
|
||||
prefix = ''
|
||||
|
||||
if style == 'A' and getattr(self, prefix+'hudStyleOptionA').get_active():
|
||||
self.hud_params[param] = 'A'
|
||||
getattr(self, prefix+'hudStyleOptionS').set_active(False)
|
||||
getattr(self, prefix+'hudStyleOptionT').set_active(False)
|
||||
elif style == 'S' and getattr(self, prefix+'hudStyleOptionS').get_active():
|
||||
self.hud_params[param] = 'S'
|
||||
getattr(self, prefix+'hudStyleOptionA').set_active(False)
|
||||
getattr(self, prefix+'hudStyleOptionT').set_active(False)
|
||||
elif style == 'T' and getattr(self, prefix+'hudStyleOptionT').get_active():
|
||||
self.hud_params[param] = 'T'
|
||||
getattr(self, prefix+'hudStyleOptionA').set_active(False)
|
||||
getattr(self, prefix+'hudStyleOptionS').set_active(False)
|
||||
print "setting self.hud_params[%s] = %s" % (param, style)
|
||||
|
||||
def update_table_position(self):
|
||||
if os.name == 'nt':
|
||||
if not win32gui.IsWindow(self.table.number):
|
||||
|
@ -219,7 +411,11 @@ class Hud:
|
|||
# heap dead, burnt bodies, blood 'n guts, veins between my teeth
|
||||
for s in self.stat_windows.itervalues():
|
||||
s.kill_popups()
|
||||
s.window.destroy()
|
||||
try:
|
||||
# throws "invalid window handle" in WinXP (sometimes?)
|
||||
s.window.destroy()
|
||||
except:
|
||||
pass
|
||||
self.stat_windows = {}
|
||||
# also kill any aux windows
|
||||
for aux in self.aux_windows:
|
||||
|
@ -627,7 +823,7 @@ class Popup_window:
|
|||
# window.window.reparent(self.table.gdkhandle, 0, 0)
|
||||
window.window.set_transient_for(self.table.gdkhandle)
|
||||
# window.present()
|
||||
|
||||
|
||||
|
||||
if __name__== "__main__":
|
||||
main_window = gtk.Window()
|
||||
|
|
265
pyfpdb/SQL.py
265
pyfpdb/SQL.py
|
@ -331,7 +331,8 @@ class Sql:
|
|||
speed varchar(10),
|
||||
headsUp BOOLEAN NOT NULL DEFAULT False,
|
||||
shootout BOOLEAN NOT NULL DEFAULT False,
|
||||
matrix BOOLEAN NOT NULL DEFAULT False
|
||||
matrix BOOLEAN NOT NULL DEFAULT False,
|
||||
sng BOOLEAN NOT NULL DEFAULT False
|
||||
)
|
||||
ENGINE=INNODB"""
|
||||
elif db_server == 'postgresql':
|
||||
|
@ -346,7 +347,8 @@ class Sql:
|
|||
speed varchar(10),
|
||||
headsUp BOOLEAN NOT NULL DEFAULT False,
|
||||
shootout BOOLEAN NOT NULL DEFAULT False,
|
||||
matrix BOOLEAN NOT NULL DEFAULT False
|
||||
matrix BOOLEAN NOT NULL DEFAULT False,
|
||||
sng BOOLEAN NOT NULL DEFAULT False
|
||||
)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
|
||||
|
@ -360,7 +362,8 @@ class Sql:
|
|||
speed TEXT,
|
||||
headsUp BOOLEAN NOT NULL DEFAULT 0,
|
||||
shootout BOOLEAN NOT NULL DEFAULT 0,
|
||||
matrix BOOLEAN NOT NULL DEFAULT 0
|
||||
matrix BOOLEAN NOT NULL DEFAULT 0,
|
||||
sng BOOLEAN NOT NULL DEFAULT 0
|
||||
)"""
|
||||
|
||||
################################
|
||||
|
@ -820,7 +823,21 @@ class Sql:
|
|||
comment TEXT,
|
||||
commentTs timestamp without time zone)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['createTourneysPlayersTable'] = """ """
|
||||
self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
|
||||
id INT PRIMARY KEY,
|
||||
tourneyId INT,
|
||||
playerId INT,
|
||||
payinAmount INT,
|
||||
rank INT,
|
||||
winnings INT,
|
||||
nbRebuys INT DEFAULT 0,
|
||||
nbAddons INT DEFAULT 0,
|
||||
nbKO INT DEFAULT 0,
|
||||
comment TEXT,
|
||||
commentTs timestamp without time zone,
|
||||
FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
|
||||
FOREIGN KEY (playerId) REFERENCES Players(id)
|
||||
)"""
|
||||
|
||||
|
||||
################################
|
||||
|
@ -851,7 +868,18 @@ class Sql:
|
|||
comment TEXT,
|
||||
commentTs timestamp without time zone)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['createHandsActionsTable'] = """ """
|
||||
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
|
||||
id INT PRIMARY KEY,
|
||||
handsPlayerId BIGINT,
|
||||
street SMALLINT,
|
||||
actionNo SMALLINT,
|
||||
action CHAR(5),
|
||||
allIn INT,
|
||||
amount INT,
|
||||
comment TEXT,
|
||||
commentTs timestamp without time zone,
|
||||
FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id)
|
||||
)"""
|
||||
|
||||
|
||||
################################
|
||||
|
@ -1160,26 +1188,42 @@ class Sql:
|
|||
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
|
||||
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD UNIQUE INDEX siteTourneyNo(siteTourneyNo, tourneyTypeId)"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['addTourneyIndex'] = """CREATE INDEX siteTourneyNo ON Tourneys (siteTourneyNo)"""
|
||||
self.query['addTourneyIndex'] = """CREATE UNIQUE INDEX siteTourneyNo ON Tourneys (siteTourneyNo, tourneyTypeId)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['addHandsIndex'] = """ """
|
||||
self.query['addTourneyIndex'] = """CREATE UNIQUE INDEX siteTourneyNo ON Tourneys (siteTourneyNo, tourneyTypeId)"""
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
|
||||
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD UNIQUE INDEX siteHandNo(siteHandNo, gameTypeId)"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['addHandsIndex'] = """CREATE INDEX siteHandNo ON Hands (siteHandNo)"""
|
||||
self.query['addHandsIndex'] = """CREATE UNIQUE INDEX siteHandNo ON Hands (siteHandNo, gameTypeId)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['addHandsIndex'] = """ """
|
||||
self.query['addHandsIndex'] = """CREATE UNIQUE INDEX siteHandNo ON Hands (siteHandNo, gameTypeId)"""
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)"""
|
||||
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD UNIQUE INDEX name(name, siteId)"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['addPlayersIndex'] = """CREATE INDEX name ON Players (name)"""
|
||||
self.query['addPlayersIndex'] = """CREATE UNIQUE INDEX name ON Players (name, siteId)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['addPlayersIndex'] = """ """
|
||||
self.query['addPlayersIndex'] = """CREATE UNIQUE INDEX name ON Players (name, siteId)"""
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['addTPlayersIndex'] = """ALTER TABLE TourneysPlayers ADD UNIQUE INDEX tourneyId(tourneyId, playerId)"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['addTPlayersIndex'] = """CREATE UNIQUE INDEX tourneyId ON TourneysPlayers (tourneyId, playerId)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['addTPlayersIndex'] = """CREATE UNIQUE INDEX tourneyId ON TourneysPlayers (tourneyId, playerId)"""
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['addTTypesIndex'] = """ALTER TABLE TourneyTypes ADD UNIQUE INDEX tourneytypes_all(buyin, fee
|
||||
, maxSeats, knockout, rebuyOrAddon, speed, headsUp, shootout, matrix, sng)"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['addTTypesIndex'] = """CREATE UNIQUE INDEX tourneyTypes_all ON TourneyTypes (buyin, fee
|
||||
, maxSeats, knockout, rebuyOrAddon, speed, headsUp, shootout, matrix, sng)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['addTTypesIndex'] = """CREATE UNIQUE INDEX tourneyTypes_all ON TourneyTypes (buyin, fee
|
||||
, maxSeats, knockout, rebuyOrAddon, speed, headsUp, shootout, matrix, sng)"""
|
||||
|
||||
self.query['get_last_hand'] = "select max(id) from Hands"
|
||||
|
||||
|
@ -1188,7 +1232,14 @@ class Sql:
|
|||
from Players, Sites
|
||||
where Players.name = %s
|
||||
and Sites.name = %s
|
||||
and Players.SiteId = Sites.id
|
||||
and Players.siteId = Sites.id
|
||||
"""
|
||||
|
||||
self.query['get_player_names'] = """
|
||||
select p.name
|
||||
from Players p
|
||||
where lower(p.name) like lower(%s)
|
||||
and (p.siteId = %s or %s = -1)
|
||||
"""
|
||||
|
||||
self.query['getSiteId'] = """SELECT id from Sites where name = %s"""
|
||||
|
@ -1340,28 +1391,45 @@ class Sql:
|
|||
INNER JOIN HudCache hc ON (hc.playerId = hp.playerId)
|
||||
INNER JOIN Players p ON (p.id = hc.playerId)
|
||||
WHERE h.id = %s
|
||||
AND hc.styleKey > %s
|
||||
/* styleKey is currently 'd' (for date) followed by a yyyymmdd
|
||||
date key. Set it to 0000000 or similar to get all records */
|
||||
/* Note: s means the placeholder 'percent's but we can't include that
|
||||
in comments. (db api thinks they are actual arguments)
|
||||
Could also check activeseats here even if only 3 groups eg 2-3/4-6/7+
|
||||
e.g. could use a multiplier:
|
||||
AND h.seats > s / 1.25 and hp.seats < s * 1.25
|
||||
where s is the number of active players at the current table (and
|
||||
1.25 would be a config value so user could change it)
|
||||
*/
|
||||
AND hc.gametypeId+0 in
|
||||
(SELECT gt1.id from Gametypes gt1, Gametypes gt2
|
||||
WHERE gt1.siteid = gt2.siteid /* find gametypes where these match: */
|
||||
AND gt1.type = gt2.type /* ring/tourney */
|
||||
AND gt1.category = gt2.category /* holdem/stud*/
|
||||
AND gt1.limittype = gt2.limittype /* fl/nl */
|
||||
AND gt1.bigblind < gt2.bigblind * %s /* bigblind similar size */
|
||||
AND gt1.bigblind > gt2.bigblind / %s
|
||||
AND gt2.id = h.gametypeId)
|
||||
AND ( /* 2 separate parts for hero and opponents */
|
||||
( hp.playerId != %s
|
||||
AND hc.styleKey > %s
|
||||
AND hc.gametypeId+0 in
|
||||
(SELECT gt1.id from Gametypes gt1, Gametypes gt2
|
||||
WHERE gt1.siteid = gt2.siteid /* find gametypes where these match: */
|
||||
AND gt1.type = gt2.type /* ring/tourney */
|
||||
AND gt1.category = gt2.category /* holdem/stud*/
|
||||
AND gt1.limittype = gt2.limittype /* fl/nl */
|
||||
AND gt1.bigblind <= gt2.bigblind * %s /* bigblind similar size */
|
||||
AND gt1.bigblind >= gt2.bigblind / %s
|
||||
AND gt2.id = h.gametypeId)
|
||||
)
|
||||
OR
|
||||
( hp.playerId = %s
|
||||
AND hc.styleKey > %s
|
||||
AND hc.gametypeId+0 in
|
||||
(SELECT gt1.id from Gametypes gt1, Gametypes gt2
|
||||
WHERE gt1.siteid = gt2.siteid /* find gametypes where these match: */
|
||||
AND gt1.type = gt2.type /* ring/tourney */
|
||||
AND gt1.category = gt2.category /* holdem/stud*/
|
||||
AND gt1.limittype = gt2.limittype /* fl/nl */
|
||||
AND gt1.bigblind <= gt2.bigblind * %s /* bigblind similar size */
|
||||
AND gt1.bigblind >= gt2.bigblind / %s
|
||||
AND gt2.id = h.gametypeId)
|
||||
)
|
||||
)
|
||||
GROUP BY hc.PlayerId, p.name
|
||||
"""
|
||||
# NOTES on above cursor:
|
||||
# - Do NOT include %s inside query in a comment - the db api thinks
|
||||
# they are actual arguments.
|
||||
# - styleKey is currently 'd' (for date) followed by a yyyymmdd
|
||||
# date key. Set it to 0000000 or similar to get all records
|
||||
# Could also check activeseats here even if only 3 groups eg 2-3/4-6/7+
|
||||
# e.g. could use a multiplier:
|
||||
# AND h.seats > %s / 1.25 and hp.seats < %s * 1.25
|
||||
# where %s is the number of active players at the current table (and
|
||||
# 1.25 would be a config value so user could change it)
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['get_stats_from_hand_session'] = """
|
||||
|
@ -1537,10 +1605,11 @@ class Sql:
|
|||
"""
|
||||
|
||||
self.query['get_table_name'] = """
|
||||
select tableName, maxSeats, category, type
|
||||
from Hands,Gametypes
|
||||
where Hands.id = %s
|
||||
and Gametypes.id = Hands.gametypeId
|
||||
select h.tableName, h.maxSeats, gt.category, gt.type, gt.siteId
|
||||
from Hands h
|
||||
,Gametypes gt
|
||||
where h.id = %s
|
||||
and gt.id = h.gametypeId
|
||||
"""
|
||||
|
||||
self.query['get_actual_seat'] = """
|
||||
|
@ -1651,6 +1720,9 @@ class Sql:
|
|||
self.query['getSiteId'] = """SELECT id from Sites where name = %s"""
|
||||
self.query['getGames'] = """SELECT DISTINCT category from Gametypes"""
|
||||
self.query['getLimits'] = """SELECT DISTINCT bigBlind from Gametypes ORDER by bigBlind DESC"""
|
||||
self.query['getLimits2'] = """SELECT DISTINCT type, limitType, bigBlind
|
||||
from Gametypes
|
||||
ORDER by type, limitType DESC, bigBlind DESC"""
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['playerDetailedStats'] = """
|
||||
|
@ -1706,7 +1778,7 @@ class Sql:
|
|||
inner join Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
inner join Sites s on (s.Id = gt.siteId)
|
||||
where hp.playerId in <player_test>
|
||||
and hp.tourneysPlayersId IS NULL
|
||||
/*and hp.tourneysPlayersId IS NULL*/
|
||||
and h.seats <seats_test>
|
||||
<flagtest>
|
||||
<gtbigBlind_test>
|
||||
|
@ -1728,11 +1800,11 @@ class Sql:
|
|||
else concat('Z', <position>)
|
||||
end
|
||||
<orderbyhgameTypeId>
|
||||
,upper(gt.limitType) desc
|
||||
,maxbigblind desc
|
||||
,upper(gt.limitType)
|
||||
,s.name
|
||||
"""
|
||||
else: # assume postgresql
|
||||
elif db_server == 'postgresql':
|
||||
self.query['playerDetailedStats'] = """
|
||||
select <hgameTypeId> AS hgametypeid
|
||||
,gt.base
|
||||
|
@ -1786,7 +1858,7 @@ class Sql:
|
|||
inner join Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
inner join Sites s on (s.Id = gt.siteId)
|
||||
where hp.playerId in <player_test>
|
||||
and hp.tourneysPlayersId IS NULL
|
||||
/*and hp.tourneysPlayersId IS NULL*/
|
||||
and h.seats <seats_test>
|
||||
<flagtest>
|
||||
<gtbigBlind_test>
|
||||
|
@ -1809,12 +1881,91 @@ class Sql:
|
|||
else 'Z'||<position>
|
||||
end
|
||||
<orderbyhgameTypeId>
|
||||
,upper(gt.limitType) desc
|
||||
,maxbigblind desc
|
||||
,s.name
|
||||
"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['playerDetailedStats'] = """
|
||||
select <hgameTypeId> AS hgametypeid
|
||||
,gt.base
|
||||
,gt.category
|
||||
,upper(gt.limitType) AS limittype
|
||||
,s.name
|
||||
,min(gt.bigBlind) AS minbigblind
|
||||
,max(gt.bigBlind) AS maxbigblind
|
||||
/*,<hcgametypeId> AS gtid*/
|
||||
,<position> AS plposition
|
||||
,count(1) AS n
|
||||
,100.0*sum(cast(hp.street0VPI as <signed>integer))/count(1) AS vpip
|
||||
,100.0*sum(cast(hp.street0Aggr as <signed>integer))/count(1) AS pfr
|
||||
,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))
|
||||
end AS pf3
|
||||
,case when sum(cast(hp.stealattemptchance as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.stealattempted as <signed>integer))/sum(cast(hp.stealattemptchance as <signed>integer))
|
||||
end AS steals
|
||||
,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
|
||||
,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))
|
||||
end AS wtsdwsf
|
||||
,case when sum(cast(hp.sawShowdown as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.wonAtSD as <signed>integer))/sum(cast(hp.sawShowdown as <signed>integer))
|
||||
end AS wmsd
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street1Aggr as <signed>integer))/sum(cast(hp.street1Seen as <signed>integer))
|
||||
end AS flafq
|
||||
,case when sum(cast(hp.street2Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street2Aggr as <signed>integer))/sum(cast(hp.street2Seen as <signed>integer))
|
||||
end AS tuafq
|
||||
,case when sum(cast(hp.street3Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street3Aggr as <signed>integer))/sum(cast(hp.street3Seen as <signed>integer))
|
||||
end AS rvafq
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer))+sum(cast(hp.street2Seen as <signed>integer))+sum(cast(hp.street3Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*(sum(cast(hp.street1Aggr as <signed>integer))+sum(cast(hp.street2Aggr as <signed>integer))+sum(cast(hp.street3Aggr as <signed>integer)))
|
||||
/(sum(cast(hp.street1Seen as <signed>integer))+sum(cast(hp.street2Seen as <signed>integer))+sum(cast(hp.street3Seen as <signed>integer)))
|
||||
end AS pofafq
|
||||
,sum(hp.totalProfit)/100.0 AS net
|
||||
,sum(hp.rake)/100.0 AS rake
|
||||
,100.0*avg(hp.totalProfit/(gt.bigBlind+0.0)) AS bbper100
|
||||
,avg(hp.totalProfit)/100.0 AS profitperhand
|
||||
,100.0*avg((hp.totalProfit+hp.rake)/(gt.bigBlind+0.0)) AS bb100xr
|
||||
,avg((hp.totalProfit+hp.rake)/100.0) AS profhndxr
|
||||
,avg(h.seats+0.0) AS avgseats
|
||||
,variance(hp.totalProfit/100.0) AS variance
|
||||
from HandsPlayers hp
|
||||
inner join Hands h on (h.id = hp.handId)
|
||||
inner join Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
inner join Sites s on (s.Id = gt.siteId)
|
||||
where hp.playerId in <player_test>
|
||||
/*and hp.tourneysPlayersId IS NULL*/
|
||||
and h.seats <seats_test>
|
||||
<flagtest>
|
||||
<gtbigBlind_test>
|
||||
and to_char(h.handStart, 'YYYY-MM-DD') <datestest>
|
||||
group by hgameTypeId
|
||||
,hp.playerId
|
||||
,gt.base
|
||||
,gt.category
|
||||
<groupbyseats>
|
||||
,plposition
|
||||
,upper(gt.limitType)
|
||||
,s.name
|
||||
order by hp.playerId
|
||||
,gt.base
|
||||
,gt.category
|
||||
<orderbyseats>
|
||||
,case <position> when 'B' then 'B'
|
||||
when 'S' then 'S'
|
||||
when '0' then 'Y'
|
||||
else 'Z'||<position>
|
||||
end
|
||||
<orderbyhgameTypeId>
|
||||
,upper(gt.limitType) desc
|
||||
,maxbigblind desc
|
||||
,upper(gt.limitType)
|
||||
,s.name
|
||||
"""
|
||||
#elif db_server == 'sqlite':
|
||||
# self.query['playerDetailedStats'] = """ """
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['playerStats'] = """
|
||||
|
@ -2304,16 +2455,16 @@ class Sql:
|
|||
# self.query['playerStatsByPosition'] = """ """
|
||||
|
||||
self.query['getRingProfitAllHandsPlayerIdSite'] = """
|
||||
SELECT hp.handId, hp.totalProfit, hp.totalProfit, hp.totalProfit
|
||||
SELECT hp.handId, hp.totalProfit
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Players pl ON (hp.playerId = pl.id)
|
||||
INNER JOIN Hands h ON (h.id = hp.handId)
|
||||
INNER JOIN Gametypes g ON (h.gametypeId = g.id)
|
||||
where pl.id in <player_test>
|
||||
INNER JOIN Players pl ON (pl.id = hp.playerId)
|
||||
INNER JOIN Hands h ON (h.id = hp.handId)
|
||||
INNER JOIN Gametypes gt ON (gt.id = h.gametypeId)
|
||||
WHERE pl.id in <player_test>
|
||||
AND pl.siteId in <site_test>
|
||||
AND h.handStart > '<startdate_test>'
|
||||
AND h.handStart < '<enddate_test>'
|
||||
AND g.bigBlind in <limit_test>
|
||||
<limit_test>
|
||||
AND hp.tourneysPlayersId IS NULL
|
||||
GROUP BY h.handStart, hp.handId, hp.totalProfit
|
||||
ORDER BY h.handStart"""
|
||||
|
@ -2466,6 +2617,7 @@ class Sql:
|
|||
,sum(street4CheckCallRaiseDone)
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Hands h ON (h.id = hp.handId)
|
||||
<where_clause>
|
||||
GROUP BY h.gametypeId
|
||||
,hp.playerId
|
||||
,h.seats
|
||||
|
@ -2614,6 +2766,7 @@ class Sql:
|
|||
,sum(CAST(street4CheckCallRaiseDone as integer))
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Hands h ON (h.id = hp.handId)
|
||||
<where_clause>
|
||||
GROUP BY h.gametypeId
|
||||
,hp.playerId
|
||||
,h.seats
|
||||
|
@ -2762,6 +2915,7 @@ class Sql:
|
|||
,sum(CAST(street4CheckCallRaiseDone as integer))
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Hands h ON (h.id = hp.handId)
|
||||
<where_clause>
|
||||
GROUP BY h.gametypeId
|
||||
,hp.playerId
|
||||
,h.seats
|
||||
|
@ -2770,9 +2924,14 @@ class Sql:
|
|||
,'d' || substr(strftime('%Y%m%d', h.handStart),3,7)
|
||||
"""
|
||||
|
||||
self.query['get_hero_hudcache_start'] = """select min(hc.styleKey)
|
||||
from HudCache hc
|
||||
where hc.playerId in <playerid_list>
|
||||
and hc.styleKey like 'd%'"""
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['analyze'] = """
|
||||
analyze table Autorates, GameTypes, Hands, HandsPlayers, Hudcache, Players
|
||||
analyze table Autorates, GameTypes, Hands, HandsPlayers, HudCache, Players
|
||||
, Settings, Sites, Tourneys, TourneysPlayers, TourneyTypes
|
||||
"""
|
||||
else: # assume postgres
|
||||
|
|
|
@ -257,6 +257,10 @@ def discover_nt_tournament(c, tour_number, tab_number):
|
|||
titles ={}
|
||||
win32gui.EnumWindows(win_enum_handler, titles)
|
||||
for hwnd in titles:
|
||||
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
|
||||
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window
|
||||
if 'HUD:' in titles[hwnd]: continue # FPDB HUD window
|
||||
|
||||
if re.search(search_string, titles[hwnd]):
|
||||
return decode_windows(c, titles[hwnd], hwnd)
|
||||
return None
|
||||
|
@ -376,7 +380,7 @@ def clean_title(name):
|
|||
"""Clean the little info strings from the table name."""
|
||||
# these strings could go in a config file
|
||||
for pattern in [' \(6 max\)', ' \(heads up\)', ' \(deep\)',
|
||||
' \(deep hu\)', ' \(deep 6\)', ' \(2\)',
|
||||
' \(deep hu\)', ' \(deep 6\)', '\(6 max, deep\)', ' \(2\)',
|
||||
' \(edu\)', ' \(edu, 6 max\)', ' \(6\)',
|
||||
' \(speed\)', 'special', 'newVPP',
|
||||
' no all-in', ' fast', ',', ' 50BB min', '50bb min', '\s+$']:
|
||||
|
|
|
@ -248,7 +248,7 @@ class ttracker_main(object):
|
|||
# get basic info about the new hand from the db
|
||||
# if there is a db error, complain, skip hand, and proceed
|
||||
try:
|
||||
(table_name, max, poker_game, type) = self.db_connection.get_table_name(new_hand_id)
|
||||
(table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id)
|
||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate_stats[type]
|
||||
,hud_style, agg_bb_mult)
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ else:
|
|||
|
||||
print "Python " + sys.version[0:3] + '...\n'
|
||||
|
||||
import traceback
|
||||
import threading
|
||||
import Options
|
||||
import string
|
||||
|
@ -64,7 +65,6 @@ import gtk
|
|||
import interlocks
|
||||
|
||||
|
||||
import fpdb_simple
|
||||
import GuiBulkImport
|
||||
import GuiPlayerStats
|
||||
import GuiPositionalStats
|
||||
|
@ -234,13 +234,13 @@ class fpdb:
|
|||
dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
|
||||
buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
|
||||
diastring = "Please confirm that you want to (re-)create the tables. If there already are tables in the database " \
|
||||
+self.db.fdb.database+" on "+self.db.fdb.host+" they will be deleted."
|
||||
+self.db.database+" on "+self.db.host+" they will be deleted."
|
||||
dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
|
||||
|
||||
response = dia_confirm.run()
|
||||
dia_confirm.destroy()
|
||||
if response == gtk.RESPONSE_YES:
|
||||
#if self.db.fdb.backend == self.fdb_lock.fdb.MYSQL_INNODB:
|
||||
#if self.db.backend == self.fdb_lock.fdb.MYSQL_INNODB:
|
||||
# mysql requires locks on all tables or none - easier to release this lock
|
||||
# than lock all the other tables
|
||||
# ToDo: lock all other tables so that lock doesn't have to be released
|
||||
|
@ -257,17 +257,65 @@ class fpdb:
|
|||
|
||||
def dia_recreate_hudcache(self, widget, data=None):
|
||||
if self.obtain_global_lock():
|
||||
dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache")
|
||||
self.dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache")
|
||||
diastring = "Please confirm that you want to re-create the HUD cache."
|
||||
dia_confirm.format_secondary_text(diastring)
|
||||
|
||||
response = dia_confirm.run()
|
||||
dia_confirm.destroy()
|
||||
self.dia_confirm.format_secondary_text(diastring)
|
||||
|
||||
hb = gtk.HBox(True, 1)
|
||||
self.start_date = gtk.Entry(max=12)
|
||||
self.start_date.set_text( self.db.get_hero_hudcache_start() )
|
||||
lbl = gtk.Label(" Hero's cache starts: ")
|
||||
btn = gtk.Button()
|
||||
btn.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
|
||||
btn.connect('clicked', self.__calendar_dialog, self.start_date)
|
||||
|
||||
hb.pack_start(lbl, expand=True, padding=3)
|
||||
hb.pack_start(self.start_date, expand=True, padding=2)
|
||||
hb.pack_start(btn, expand=False, padding=3)
|
||||
self.dia_confirm.vbox.add(hb)
|
||||
hb.show_all()
|
||||
|
||||
response = self.dia_confirm.run()
|
||||
self.dia_confirm.destroy()
|
||||
if response == gtk.RESPONSE_YES:
|
||||
self.db.rebuild_hudcache()
|
||||
elif response == gtk.REPSONSE_NO:
|
||||
self.db.rebuild_hudcache( self.start_date.get_text() )
|
||||
elif response == gtk.RESPONSE_NO:
|
||||
print 'User cancelled rebuilding hud cache'
|
||||
|
||||
self.release_global_lock()
|
||||
|
||||
def __calendar_dialog(self, widget, entry):
|
||||
self.dia_confirm.set_modal(False)
|
||||
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()
|
||||
|
||||
def __get_dates(self):
|
||||
t1 = self.start_date.get_text()
|
||||
if t1 == '':
|
||||
t1 = '1970-01-01'
|
||||
return (t1)
|
||||
|
||||
def __get_date(self, widget, calendar, entry, win):
|
||||
# year and day are correct, month is 0..11
|
||||
(year, month, day) = calendar.get_date()
|
||||
month += 1
|
||||
ds = '%04d-%02d-%02d' % (year, month, day)
|
||||
entry.set_text(ds)
|
||||
win.destroy()
|
||||
self.dia_confirm.set_modal(True)
|
||||
|
||||
def dia_regression_test(self, widget, data=None):
|
||||
self.warning_box("Unimplemented: Regression Test")
|
||||
|
@ -405,9 +453,25 @@ class fpdb:
|
|||
self.db.disconnect()
|
||||
|
||||
self.sql = SQL.Sql(type = self.settings['db-type'], db_server = self.settings['db-server'])
|
||||
self.db = Database.Database(self.config, sql = self.sql)
|
||||
try:
|
||||
self.db = Database.Database(self.config, sql = self.sql)
|
||||
except FpdbMySQLFailedError:
|
||||
self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
|
||||
exit()
|
||||
except FpdbError:
|
||||
#print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||
self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||
sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||
except:
|
||||
#print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||
self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||
sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||
|
||||
if self.db.fdb.wrongDbVersion:
|
||||
if self.db.wrongDbVersion:
|
||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||
|
||||
label = gtk.Label("An invalid DB version or missing tables have been detected.")
|
||||
|
@ -426,14 +490,14 @@ class fpdb:
|
|||
diaDbVersionWarning.destroy()
|
||||
|
||||
if self.status_bar == None:
|
||||
self.status_bar = gtk.Label("Status: Connected to %s database named %s on host %s"%(self.db.get_backend_name(),self.db.fdb.database, self.db.fdb.host))
|
||||
self.status_bar = gtk.Label("Status: Connected to %s database named %s on host %s"%(self.db.get_backend_name(),self.db.database, self.db.host))
|
||||
self.main_vbox.pack_end(self.status_bar, False, True, 0)
|
||||
self.status_bar.show()
|
||||
else:
|
||||
self.status_bar.set_text("Status: Connected to %s database named %s on host %s" % (self.db.get_backend_name(),self.db.fdb.database, self.db.fdb.host))
|
||||
self.status_bar.set_text("Status: Connected to %s database named %s on host %s" % (self.db.get_backend_name(),self.db.database, self.db.host))
|
||||
|
||||
# Database connected to successfully, load queries to pass on to other classes
|
||||
self.db.connection.rollback()
|
||||
self.db.rollback()
|
||||
|
||||
self.validate_config()
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ class fpdb_db:
|
|||
MYSQL_INNODB = 2
|
||||
PGSQL = 3
|
||||
SQLITE = 4
|
||||
sqlite_db_dir = ".." + os.sep + "database"
|
||||
|
||||
def __init__(self):
|
||||
"""Simple constructor, doesnt really do anything"""
|
||||
self.db = None
|
||||
|
@ -78,7 +80,7 @@ class fpdb_db:
|
|||
try:
|
||||
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True)
|
||||
except:
|
||||
raise FpdbError("MySQL connection failed")
|
||||
raise FpdbMySQLFailedError("MySQL connection failed")
|
||||
elif backend==fpdb_db.PGSQL:
|
||||
import psycopg2
|
||||
import psycopg2.extensions
|
||||
|
@ -109,7 +111,7 @@ class fpdb_db:
|
|||
password = password,
|
||||
database = database)
|
||||
except:
|
||||
msg = "PostgreSQL connection to database (%s) user (%s) failed." % (database, user)
|
||||
msg = "PostgreSQL connection to database (%s) user (%s) failed. Are you sure the DB is running?" % (database, user)
|
||||
print msg
|
||||
raise FpdbError(msg)
|
||||
elif backend == fpdb_db.SQLITE:
|
||||
|
@ -119,7 +121,12 @@ class fpdb_db:
|
|||
sqlite3 = pool.manage(sqlite3, pool_size=1)
|
||||
else:
|
||||
logging.warning("SQLite won't work well without 'sqlalchemy' installed.")
|
||||
self.db = sqlite3.connect(database,detect_types=sqlite3.PARSE_DECLTYPES)
|
||||
|
||||
if not os.path.isdir(self.sqlite_db_dir):
|
||||
print "Creating directory: '%s'" % (self.sqlite_db_dir)
|
||||
os.mkdir(self.sqlite_db_dir)
|
||||
self.db = sqlite3.connect( self.sqlite_db_dir + os.sep + database
|
||||
, detect_types=sqlite3.PARSE_DECLTYPES )
|
||||
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||
else:
|
||||
|
|
|
@ -547,7 +547,7 @@ class Importer:
|
|||
if self.callHud:
|
||||
#print "call to HUD here. handsId:",handsId
|
||||
#pipe the Hands.id out to the HUD
|
||||
#print "sending hand to hud", handsId, "pipe =", self.caller.pipe_to_hud
|
||||
print "sending hand to hud", handsId, "pipe =", self.caller.pipe_to_hud
|
||||
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
||||
except Exceptions.DuplicateError:
|
||||
duplicates += 1
|
||||
|
|
|
@ -118,7 +118,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
|
|||
seatLines.append(line)
|
||||
|
||||
names = fpdb_simple.parseNames(seatLines)
|
||||
playerIDs = fpdb_simple.recognisePlayerIDs(db, names, siteID) # inserts players as needed
|
||||
playerIDs = db.recognisePlayerIDs(names, siteID) # inserts players as needed
|
||||
tmp = fpdb_simple.parseCashesAndSeatNos(seatLines)
|
||||
startCashes = tmp['startCashes']
|
||||
seatNos = tmp['seatNos']
|
||||
|
|
|
@ -913,92 +913,54 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c
|
|||
#end def recogniseGametypeID
|
||||
|
||||
def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebuyOrAddon):
|
||||
ret = -1
|
||||
cursor = db.get_cursor()
|
||||
# First we try to find the tourney itself (by its tourneySiteId) in case it has already been inserted before (by a summary file for instance)
|
||||
# The reason is that some tourneys may not be identified correctly in the HH toplines (especially Buy-In and Fee which are used to search/create the TourneyTypeId)
|
||||
#TODO: When the summary file will be dumped to BD, if the tourney is already in, Buy-In/Fee may need an update (e.g. creation of a new type and link to the Tourney)
|
||||
cursor.execute (db.sql.query['getTourneyTypeIdByTourneyNo'].replace('%s', db.sql.query['placeholder']), (tourneySiteId, siteId))
|
||||
result=cursor.fetchone()
|
||||
result = cursor.fetchone()
|
||||
|
||||
try:
|
||||
len(result)
|
||||
ret = result[0]
|
||||
except:
|
||||
cursor.execute ("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
|
||||
result=cursor.fetchone()
|
||||
#print "tried SELECTing gametypes.id, result:",result
|
||||
cursor.execute( """SELECT id FROM TourneyTypes
|
||||
WHERE siteId=%s AND buyin=%s AND fee=%s
|
||||
AND knockout=%s AND rebuyOrAddon=%s"""
|
||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||
result = cursor.fetchone()
|
||||
#print "tried selecting tourneytypes.id, result:", result
|
||||
|
||||
try:
|
||||
len(result)
|
||||
ret = result[0]
|
||||
except TypeError:#this means we need to create a new entry
|
||||
cursor.execute("""INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) VALUES (%s, %s, %s, %s, %s)""", (siteId, buyin, fee, knockout, rebuyOrAddon))
|
||||
cursor.execute("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
|
||||
result=cursor.fetchone()
|
||||
#print "insert new tourneytype record ..."
|
||||
try:
|
||||
cursor.execute( """INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon)
|
||||
VALUES (%s, %s, %s, %s, %s)"""
|
||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||
ret = db.get_last_insert_id(cursor)
|
||||
except:
|
||||
#print "maybe tourneytype was created since select, try selecting again ..."
|
||||
cursor.execute( """SELECT id FROM TourneyTypes
|
||||
WHERE siteId=%s AND buyin=%s AND fee=%s
|
||||
AND knockout=%s AND rebuyOrAddon=%s"""
|
||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||
result = cursor.fetchone()
|
||||
try:
|
||||
len(result)
|
||||
ret = result[0]
|
||||
except:
|
||||
print "Failed to find or insert TourneyTypes record"
|
||||
ret = -1 # failed to find or insert record
|
||||
#print "tried selecting tourneytypes.id again, result:", result
|
||||
|
||||
return result[0]
|
||||
#print "recogniseTourneyTypeId: returning", ret
|
||||
return ret
|
||||
#end def recogniseTourneyTypeId
|
||||
|
||||
#returns the SQL ids of the names given in an array
|
||||
# TODO: if someone gets industrious, they should make the parts that use the output of this function deal with a dict
|
||||
# { playername: id } instead of depending on it's relation to the positions list
|
||||
# then this can be reduced in complexity a bit
|
||||
|
||||
#def recognisePlayerIDs(cursor, names, site_id):
|
||||
# result = []
|
||||
# for i in xrange(len(names)):
|
||||
# cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
|
||||
# tmp=cursor.fetchall()
|
||||
# if (len(tmp)==0): #new player
|
||||
# cursor.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (names[i], site_id))
|
||||
# #print "Number of players rows inserted: %d" % cursor.rowcount
|
||||
# cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
|
||||
# tmp=cursor.fetchall()
|
||||
# #print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
|
||||
# result.append(tmp[0][0])
|
||||
# return result
|
||||
|
||||
def recognisePlayerIDs(db, names, site_id):
|
||||
c = db.get_cursor()
|
||||
q = "SELECT name,id FROM Players WHERE siteid=%d and (name=%s)" %(site_id, " OR name=".join([db.sql.query['placeholder'] for n in names]))
|
||||
c.execute(q, names) # get all playerids by the names passed in
|
||||
ids = dict(c.fetchall()) # convert to dict
|
||||
if len(ids) != len(names):
|
||||
notfound = [n for n in names if n not in ids] # make list of names not in database
|
||||
if notfound: # insert them into database
|
||||
q_ins = "INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")"
|
||||
q_ins = q_ins.replace('%s', db.sql.query['placeholder'])
|
||||
c.executemany(q_ins, [(n,) for n in notfound])
|
||||
q2 = "SELECT name,id FROM Players WHERE siteid=%d and (name=%s)" % (site_id, " OR name=".join(["%s" for n in notfound]))
|
||||
q2 = q2.replace('%s', db.sql.query['placeholder'])
|
||||
c.execute(q2, notfound) # get their new ids
|
||||
tmp = c.fetchall()
|
||||
for n,id in tmp: # put them all into the same dict
|
||||
ids[n] = id
|
||||
# return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB
|
||||
return [ids[n] for n in names]
|
||||
#end def recognisePlayerIDs
|
||||
|
||||
|
||||
# Here's a version that would work if it wasn't for the fact that it needs to have the output in the same order as input
|
||||
# this version could also be improved upon using list comprehensions, etc
|
||||
|
||||
#def recognisePlayerIDs(cursor, names, site_id):
|
||||
# result = []
|
||||
# notfound = []
|
||||
# cursor.execute("SELECT name,id FROM Players WHERE name='%s'" % "' OR name='".join(names))
|
||||
# tmp = dict(cursor.fetchall())
|
||||
# for n in names:
|
||||
# if n not in tmp:
|
||||
# notfound.append(n)
|
||||
# else:
|
||||
# result.append(tmp[n])
|
||||
# if notfound:
|
||||
# cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", (notfound))
|
||||
# cursor.execute("SELECT id FROM Players WHERE name='%s'" % "' OR name='".join(notfound))
|
||||
# tmp = cursor.fetchall()
|
||||
# for n in tmp:
|
||||
# result.append(n[0])
|
||||
#
|
||||
# return result
|
||||
|
||||
#recognises the name in the given line and returns its array position in the given array
|
||||
def recognisePlayerNo(line, names, atype):
|
||||
|
|
Loading…
Reference in New Issue
Block a user