Merge branch 'master' of git://git.assembla.com/free_poker_tools
This commit is contained in:
commit
b1281385ec
|
@ -94,29 +94,32 @@ def cardFromValueSuit(value, suit):
|
||||||
elif suit == 's': return(value+38)
|
elif suit == 's': return(value+38)
|
||||||
else: return(0)
|
else: return(0)
|
||||||
|
|
||||||
def valueSuitFromCard(card):
|
suitFromCardList = ['', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', 'Th', 'Jh', 'Qh', 'Kh', 'Ah'
|
||||||
""" Function to convert a card stored in the database (int 0-52) into value
|
|
||||||
and suit like 9s, 4c etc """
|
|
||||||
if card < 0 or card > 52 or not card:
|
|
||||||
return('')
|
|
||||||
else:
|
|
||||||
return( ['', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', 'Th', 'Jh', 'Qh', 'Kh', 'Ah'
|
|
||||||
, '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', 'Td', 'Jd', 'Qd', 'Kd', 'Ad'
|
, '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', 'Td', 'Jd', 'Qd', 'Kd', 'Ad'
|
||||||
, '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', 'Tc', 'Jc', 'Qc', 'Kc', 'Ac'
|
, '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', 'Tc', 'Jc', 'Qc', 'Kc', 'Ac'
|
||||||
, '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'Ts', 'Js', 'Qs', 'Ks', 'As'
|
, '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'Ts', 'Js', 'Qs', 'Ks', 'As'
|
||||||
][card] )
|
]
|
||||||
|
def valueSuitFromCard(card):
|
||||||
|
""" Function to convert a card stored in the database (int 0-52) into value
|
||||||
|
and suit like 9s, 4c etc """
|
||||||
|
global suitFromCardList
|
||||||
|
if card < 0 or card > 52 or not card:
|
||||||
|
return('')
|
||||||
|
else:
|
||||||
|
return suitFromCardList[card]
|
||||||
|
|
||||||
def encodeCard(cardString):
|
encodeCardList = {'2h': 1, '3h': 2, '4h': 3, '5h': 4, '6h': 5, '7h': 6, '8h': 7, '9h': 8, 'Th': 9, 'Jh': 10, 'Qh': 11, 'Kh': 12, 'Ah': 13,
|
||||||
"""Take a card string (Ah) and convert it to the db card code (1)."""
|
|
||||||
try:
|
|
||||||
return {'2h': 1, '3h': 2, '4h': 3, '5h': 4, '6h': 5, '7h': 6, '8h': 7, '9h': 8, 'Th': 9, 'Jh': 10, 'Qh': 11, 'Kh': 12, 'Ah': 13,
|
|
||||||
'2d': 14, '3d': 15, '4d': 16, '5d': 17, '6d': 18, '7d': 19, '8d': 20, '9d': 21, 'Td': 22, 'Jd': 23, 'Qd': 24, 'Kd': 25, 'Ad': 26,
|
'2d': 14, '3d': 15, '4d': 16, '5d': 17, '6d': 18, '7d': 19, '8d': 20, '9d': 21, 'Td': 22, 'Jd': 23, 'Qd': 24, 'Kd': 25, 'Ad': 26,
|
||||||
'2c': 27, '3c': 28, '4c': 29, '5c': 30, '6c': 31, '7c': 32, '8c': 33, '9c': 34, 'Tc': 35, 'Jc': 36, 'Qc': 27, 'Kc': 38, 'Ac': 39,
|
'2c': 27, '3c': 28, '4c': 29, '5c': 30, '6c': 31, '7c': 32, '8c': 33, '9c': 34, 'Tc': 35, 'Jc': 36, 'Qc': 27, 'Kc': 38, 'Ac': 39,
|
||||||
'2s': 40, '3s': 41, '4s': 42, '5s': 43, '6s': 44, '7s': 45, '8s': 46, '9s': 47, 'Ts': 48, 'Js': 49, 'Qs': 50, 'Ks': 51, 'As': 52,
|
'2s': 40, '3s': 41, '4s': 42, '5s': 43, '6s': 44, '7s': 45, '8s': 46, '9s': 47, 'Ts': 48, 'Js': 49, 'Qs': 50, 'Ks': 51, 'As': 52,
|
||||||
' ': 0
|
' ': 0
|
||||||
}[cardString]
|
}
|
||||||
except:
|
|
||||||
return 0 # everthing that isn't known is a unknown!
|
def encodeCard(cardString):
|
||||||
|
"""Take a card string (Ah) and convert it to the db card code (1)."""
|
||||||
|
global encodeCardList
|
||||||
|
if cardString not in encodeCardList: return 0
|
||||||
|
return encodeCardList[cardString]
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print "fpdb card encoding(same as pokersource)"
|
print "fpdb card encoding(same as pokersource)"
|
||||||
|
|
|
@ -27,10 +27,11 @@ Create and manage the database objects.
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from datetime import datetime, date, time, timedelta
|
from datetime import datetime, date, time, timedelta
|
||||||
from time import time, strftime
|
from time import time, strftime, sleep
|
||||||
import string
|
import string
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
|
import Queue
|
||||||
|
|
||||||
# pyGTK modules
|
# pyGTK modules
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ class Database:
|
||||||
, {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09
|
, {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09
|
||||||
, {'tab':'HandsPlayers', 'col':'handId', 'drop':0} # not needed, handled by fk
|
, {'tab':'HandsPlayers', 'col':'handId', 'drop':0} # not needed, handled by fk
|
||||||
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':0} # not needed, handled by fk
|
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':0} # not needed, handled by fk
|
||||||
, {'tab':'HandsPlayers', 'col':'tourneysTypeId', 'drop':0}
|
, {'tab':'HandsPlayers', 'col':'tourneyTypeId', 'drop':0}
|
||||||
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
|
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
|
||||||
, {'tab':'Tourneys', 'col':'siteTourneyNo', 'drop':0}
|
, {'tab':'Tourneys', 'col':'siteTourneyNo', 'drop':0}
|
||||||
]
|
]
|
||||||
|
@ -181,57 +182,24 @@ class Database:
|
||||||
else:
|
else:
|
||||||
self.sql = sql
|
self.sql = sql
|
||||||
|
|
||||||
|
self.pcache = None # PlayerId cache
|
||||||
|
self.cachemiss = 0 # Delete me later - using to count player cache misses
|
||||||
|
self.cachehit = 0 # Delete me later - using to count player cache hits
|
||||||
|
|
||||||
# config while trying out new hudcache mechanism
|
# config while trying out new hudcache mechanism
|
||||||
self.use_date_in_hudcache = True
|
self.use_date_in_hudcache = True
|
||||||
|
|
||||||
# To add to config:
|
#self.hud_hero_style = 'T' # Duplicate set of vars just for hero - not used yet.
|
||||||
self.hud_session_gap = 30 # Gap (minutes) between hands that indicates a change of session
|
#self.hud_hero_hands = 2000 # Idea is that you might want all-time stats for others
|
||||||
# (hands every 2 mins for 1 hour = one session, if followed
|
#self.hud_hero_days = 30 # but last T days or last H hands for yourself
|
||||||
# by a 40 minute gap and then more hands on same table that is
|
|
||||||
# a new session)
|
|
||||||
self.hud_style = 'T' # A=All-time
|
|
||||||
# S=Session
|
|
||||||
# T=timed (last n days)
|
|
||||||
# Future values may also include:
|
|
||||||
# H=Hands (last n hands)
|
|
||||||
self.hud_hands = 2000 # Max number of hands from each player to use for hud stats
|
|
||||||
self.hud_days = 30 # Max number of days from each player to use for hud stats
|
|
||||||
|
|
||||||
self.hud_hero_style = 'T' # Duplicate set of vars just for hero
|
# vars for hand ids or dates fetched according to above config:
|
||||||
self.hud_hero_hands = 2000
|
self.hand_1day_ago = 0 # max hand id more than 24 hrs earlier than now
|
||||||
self.hud_hero_days = 30
|
self.date_ndays_ago = 'd000000' # date N days ago ('d' + YYMMDD)
|
||||||
|
self.date_nhands_ago = {} # dates N hands ago per player - not used yet
|
||||||
|
|
||||||
self.cursor = self.fdb.cursor
|
self.cursor = self.fdb.cursor
|
||||||
|
|
||||||
if self.fdb.wrongDbVersion == False:
|
|
||||||
# self.hand_1day_ago used to fetch stats for current session (i.e. if hud_style = 'S')
|
|
||||||
self.hand_1day_ago = 0
|
|
||||||
self.cursor.execute(self.sql.query['get_hand_1day_ago'])
|
|
||||||
row = self.cursor.fetchone()
|
|
||||||
if row and row[0]:
|
|
||||||
self.hand_1day_ago = row[0]
|
|
||||||
#print "hand 1day ago =", self.hand_1day_ago
|
|
||||||
|
|
||||||
# self.date_ndays_ago used if hud_style = 'T'
|
|
||||||
d = timedelta(days=self.hud_days)
|
|
||||||
now = datetime.utcnow() - d
|
|
||||||
self.date_ndays_ago = "d%02d%02d%02d" % (now.year-2000, now.month, now.day)
|
|
||||||
|
|
||||||
# self.hand_nhands_ago is used for fetching stats for last n hands (hud_style = 'H')
|
|
||||||
# This option not used yet
|
|
||||||
self.hand_nhands_ago = 0
|
|
||||||
# should use aggregated version of query if appropriate
|
|
||||||
self.cursor.execute(self.sql.query['get_hand_nhands_ago'], (self.hud_hands,self.hud_hands))
|
|
||||||
row = self.cursor.fetchone()
|
|
||||||
if row and row[0]:
|
|
||||||
self.hand_nhands_ago = row[0]
|
|
||||||
print "hand n hands ago =", self.hand_nhands_ago
|
|
||||||
|
|
||||||
#self.cursor.execute(self.sql.query['get_table_name'], (hand_id, ))
|
|
||||||
#row = self.cursor.fetchone()
|
|
||||||
else:
|
|
||||||
print "Bailing on DB query, not sure it exists yet"
|
|
||||||
|
|
||||||
self.saveActions = False if self.import_options['saveActions'] == False else True
|
self.saveActions = False if self.import_options['saveActions'] == False else True
|
||||||
|
|
||||||
self.connection.rollback() # make sure any locks taken so far are released
|
self.connection.rollback() # make sure any locks taken so far are released
|
||||||
|
@ -364,22 +332,67 @@ class Database:
|
||||||
winners[row[0]] = row[1]
|
winners[row[0]] = row[1]
|
||||||
return winners
|
return winners
|
||||||
|
|
||||||
def get_stats_from_hand(self, hand, aggregate = False):
|
def init_hud_stat_vars(self, hud_days):
|
||||||
if self.hud_style == 'S':
|
"""Initialise variables used by Hud to fetch stats."""
|
||||||
return( self.get_stats_from_hand_session(hand) )
|
|
||||||
else: # self.hud_style == A
|
|
||||||
if aggregate:
|
|
||||||
query = 'get_stats_from_hand_aggregated'
|
|
||||||
else:
|
|
||||||
query = 'get_stats_from_hand'
|
|
||||||
|
|
||||||
if self.hud_style == 'T':
|
try:
|
||||||
|
# self.hand_1day_ago used to fetch stats for current session (i.e. if hud_style = 'S')
|
||||||
|
self.hand_1day_ago = 1
|
||||||
|
c = self.get_cursor()
|
||||||
|
c.execute(self.sql.query['get_hand_1day_ago'])
|
||||||
|
row = c.fetchone()
|
||||||
|
if row and row[0]:
|
||||||
|
self.hand_1day_ago = row[0]
|
||||||
|
#print "hand 1day ago =", self.hand_1day_ago
|
||||||
|
|
||||||
|
# self.date_ndays_ago used if hud_style = 'T'
|
||||||
|
d = timedelta(days=hud_days)
|
||||||
|
now = datetime.utcnow() - d
|
||||||
|
self.date_ndays_ago = "d%02d%02d%02d" % (now.year-2000, now.month, now.day)
|
||||||
|
except:
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
|
|
||||||
|
def init_player_hud_stat_vars(self, playerid):
|
||||||
|
# not sure if this is workable, to be continued ...
|
||||||
|
try:
|
||||||
|
# self.date_nhands_ago is used for fetching stats for last n hands (hud_style = 'H')
|
||||||
|
# This option not used yet - needs to be called for each player :-(
|
||||||
|
self.date_nhands_ago[str(playerid)] = 'd000000'
|
||||||
|
|
||||||
|
# should use aggregated version of query if appropriate
|
||||||
|
c.execute(self.sql.query['get_date_nhands_ago'], (self.hud_hands, playerid))
|
||||||
|
row = c.fetchone()
|
||||||
|
if row and row[0]:
|
||||||
|
self.date_nhands_ago[str(playerid)] = row[0]
|
||||||
|
c.close()
|
||||||
|
print "date n hands ago = " + self.date_nhands_ago[str(playerid)] + "(playerid "+str(playerid)+")"
|
||||||
|
except:
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
|
|
||||||
|
def get_stats_from_hand(self, hand, aggregate = False, hud_style = 'A', agg_bb_mult = 100):
|
||||||
|
if hud_style == 'S':
|
||||||
|
|
||||||
|
return( self.get_stats_from_hand_session(hand) )
|
||||||
|
|
||||||
|
else: # hud_style == A
|
||||||
|
|
||||||
|
if hud_style == 'T':
|
||||||
stylekey = self.date_ndays_ago
|
stylekey = self.date_ndays_ago
|
||||||
|
#elif hud_style == 'H':
|
||||||
|
# stylekey = date_nhands_ago needs array by player here ...
|
||||||
else: # assume A (all-time)
|
else: # assume A (all-time)
|
||||||
stylekey = '0000000' # all stylekey values should be higher than this
|
stylekey = '0000000' # all stylekey values should be higher than this
|
||||||
|
|
||||||
subs = (hand, hand, stylekey)
|
if aggregate:
|
||||||
#print "get stats: hud style =", self.hud_style, "subs =", subs
|
query = 'get_stats_from_hand_aggregated'
|
||||||
|
subs = (hand, stylekey, agg_bb_mult, agg_bb_mult)
|
||||||
|
else:
|
||||||
|
query = 'get_stats_from_hand'
|
||||||
|
subs = (hand, stylekey)
|
||||||
|
|
||||||
|
#print "get stats: hud style =", hud_style, "query =", query, "subs =", subs
|
||||||
c = self.connection.cursor()
|
c = self.connection.cursor()
|
||||||
|
|
||||||
# now get the stats
|
# now get the stats
|
||||||
|
@ -398,17 +411,14 @@ class Database:
|
||||||
# uses query on handsplayers instead of hudcache to get stats on just this session
|
# uses query on handsplayers instead of hudcache to get stats on just this session
|
||||||
def get_stats_from_hand_session(self, hand):
|
def get_stats_from_hand_session(self, hand):
|
||||||
|
|
||||||
if self.hud_style == 'S':
|
|
||||||
query = self.sql.query['get_stats_from_hand_session']
|
query = self.sql.query['get_stats_from_hand_session']
|
||||||
if self.db_server == 'mysql':
|
if self.db_server == 'mysql':
|
||||||
query = query.replace("<signed>", 'signed ')
|
query = query.replace("<signed>", 'signed ')
|
||||||
else:
|
else:
|
||||||
query = query.replace("<signed>", '')
|
query = query.replace("<signed>", '')
|
||||||
else: # self.hud_style == A
|
|
||||||
return None
|
|
||||||
|
|
||||||
subs = (self.hand_1day_ago, hand)
|
subs = (self.hand_1day_ago, hand)
|
||||||
c = self.connection.cursor()
|
c = self.get_cursor()
|
||||||
|
|
||||||
# now get the stats
|
# now get the stats
|
||||||
#print "sess_stats: subs =", subs, "subs[0] =", subs[0]
|
#print "sess_stats: subs =", subs, "subs[0] =", subs[0]
|
||||||
|
@ -442,7 +452,7 @@ class Database:
|
||||||
|
|
||||||
def get_player_id(self, config, site, player_name):
|
def get_player_id(self, config, site, player_name):
|
||||||
c = self.connection.cursor()
|
c = self.connection.cursor()
|
||||||
c.execute(self.sql.query['get_player_id'], {'player': player_name, 'site': site})
|
c.execute(self.sql.query['get_player_id'], (player_name, site))
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
if row:
|
if row:
|
||||||
return row[0]
|
return row[0]
|
||||||
|
@ -469,7 +479,6 @@ class Database:
|
||||||
,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName
|
,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName
|
||||||
,seatNos):
|
,seatNos):
|
||||||
|
|
||||||
try:
|
|
||||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||||
|
|
||||||
hands_id = self.storeHands(self.backend, site_hand_no, gametype_id
|
hands_id = self.storeHands(self.backend, site_hand_no, gametype_id
|
||||||
|
@ -483,9 +492,6 @@ class Database:
|
||||||
|
|
||||||
if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop':
|
if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop':
|
||||||
self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
||||||
except:
|
|
||||||
print "ring_stud error: " + str(sys.exc_value) # in case exception doesn't get printed
|
|
||||||
raise fpdb_simple.FpdbError("ring_stud error: " + str(sys.exc_value))
|
|
||||||
|
|
||||||
return hands_id
|
return hands_id
|
||||||
#end def ring_stud
|
#end def ring_stud
|
||||||
|
@ -496,7 +502,6 @@ class Database:
|
||||||
,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||||
"""stores a holdem/omaha hand into the database"""
|
"""stores a holdem/omaha hand into the database"""
|
||||||
|
|
||||||
try:
|
|
||||||
t0 = time()
|
t0 = time()
|
||||||
#print "in ring_holdem_omaha"
|
#print "in ring_holdem_omaha"
|
||||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||||
|
@ -517,9 +522,6 @@ class Database:
|
||||||
self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
||||||
t5 = time()
|
t5 = time()
|
||||||
#print "fills=(%4.3f) saves=(%4.3f,%4.3f,%4.3f)" % (t2-t0, t3-t2, t4-t3, t5-t4)
|
#print "fills=(%4.3f) saves=(%4.3f,%4.3f,%4.3f)" % (t2-t0, t3-t2, t4-t3, t5-t4)
|
||||||
except:
|
|
||||||
print "ring_holdem_omaha error: " + str(sys.exc_value) # in case exception doesn't get printed
|
|
||||||
raise fpdb_simple.FpdbError("ring_holdem_omaha error: " + str(sys.exc_value))
|
|
||||||
return hands_id
|
return hands_id
|
||||||
#end def ring_holdem_omaha
|
#end def ring_holdem_omaha
|
||||||
|
|
||||||
|
@ -532,7 +534,6 @@ class Database:
|
||||||
,actionNos, hudImportData, maxSeats, tableName, seatNos):
|
,actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||||
"""stores a tourney holdem/omaha hand into the database"""
|
"""stores a tourney holdem/omaha hand into the database"""
|
||||||
|
|
||||||
try:
|
|
||||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||||
fpdb_simple.fill_board_cards(board_values, board_suits)
|
fpdb_simple.fill_board_cards(board_values, board_suits)
|
||||||
|
|
||||||
|
@ -551,9 +552,6 @@ class Database:
|
||||||
#print "tourney holdem, backend=%d" % backend
|
#print "tourney holdem, backend=%d" % backend
|
||||||
if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop':
|
if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop':
|
||||||
self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
||||||
except:
|
|
||||||
print "tourney_holdem_omaha error: " + str(sys.exc_value) # in case exception doesn't get printed
|
|
||||||
raise fpdb_simple.FpdbError("tourney_holdem_omaha error: " + str(sys.exc_value))
|
|
||||||
|
|
||||||
return hands_id
|
return hands_id
|
||||||
#end def tourney_holdem_omaha
|
#end def tourney_holdem_omaha
|
||||||
|
@ -565,7 +563,6 @@ class Database:
|
||||||
,actionNos, hudImportData, maxSeats, tableName, seatNos):
|
,actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||||
#stores a tourney stud/razz hand into the database
|
#stores a tourney stud/razz hand into the database
|
||||||
|
|
||||||
try:
|
|
||||||
fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
|
fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
|
||||||
|
|
||||||
tourney_id = self.store_tourneys(tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime)
|
tourney_id = self.store_tourneys(tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime)
|
||||||
|
@ -582,9 +579,6 @@ class Database:
|
||||||
|
|
||||||
if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop':
|
if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop':
|
||||||
self.storeHudCache(self.backend, base, category, gametypeId, hand_start_time, playerIds, hudImportData)
|
self.storeHudCache(self.backend, base, category, gametypeId, hand_start_time, playerIds, hudImportData)
|
||||||
except:
|
|
||||||
print "tourney_stud error: " + str(sys.exc_value) # in case exception doesn't get printed
|
|
||||||
raise fpdb_simple.FpdbError("tourney_stud error: " + str(sys.exc_value))
|
|
||||||
|
|
||||||
return hands_id
|
return hands_id
|
||||||
#end def tourney_stud
|
#end def tourney_stud
|
||||||
|
@ -613,7 +607,7 @@ class Database:
|
||||||
"AND referenced_column_name = %s ",
|
"AND referenced_column_name = %s ",
|
||||||
(fk['fktab'], fk['fkcol'], fk['rtab'], fk['rcol']) )
|
(fk['fktab'], fk['fkcol'], fk['rtab'], fk['rcol']) )
|
||||||
cons = c.fetchone()
|
cons = c.fetchone()
|
||||||
print "preparebulk find fk: cons=", cons
|
#print "preparebulk find fk: cons=", cons
|
||||||
if cons:
|
if cons:
|
||||||
print "dropping mysql fk", cons[0], fk['fktab'], fk['fkcol']
|
print "dropping mysql fk", cons[0], fk['fktab'], fk['fkcol']
|
||||||
try:
|
try:
|
||||||
|
@ -740,8 +734,8 @@ class Database:
|
||||||
if self.backend == self.MYSQL_INNODB:
|
if self.backend == self.MYSQL_INNODB:
|
||||||
print "creating mysql index ", idx['tab'], idx['col']
|
print "creating mysql index ", idx['tab'], idx['col']
|
||||||
try:
|
try:
|
||||||
c.execute( "alter table %s add index %s(%s)"
|
s = "alter table %s add index %s(%s)" % (idx['tab'],idx['col'],idx['col'])
|
||||||
, (idx['tab'],idx['col'],idx['col']) )
|
c.execute(s)
|
||||||
except:
|
except:
|
||||||
print " create fk failed: " + str(sys.exc_info())
|
print " create fk failed: " + str(sys.exc_info())
|
||||||
elif self.backend == self.PGSQL:
|
elif self.backend == self.PGSQL:
|
||||||
|
@ -749,9 +743,8 @@ class Database:
|
||||||
# mod to use tab_col for index name?
|
# mod to use tab_col for index name?
|
||||||
print "creating pg index ", idx['tab'], idx['col']
|
print "creating pg index ", idx['tab'], idx['col']
|
||||||
try:
|
try:
|
||||||
print "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col'])
|
s = "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col'])
|
||||||
c.execute( "create index %s_%s_idx on %s(%s)"
|
c.execute(s)
|
||||||
% (idx['tab'], idx['col'], idx['tab'], idx['col']) )
|
|
||||||
except:
|
except:
|
||||||
print " create index failed: " + str(sys.exc_info())
|
print " create index failed: " + str(sys.exc_info())
|
||||||
else:
|
else:
|
||||||
|
@ -820,9 +813,11 @@ class Database:
|
||||||
self.fillDefaultData()
|
self.fillDefaultData()
|
||||||
self.commit()
|
self.commit()
|
||||||
except:
|
except:
|
||||||
print "Error creating tables: ", str(sys.exc_value)
|
#print "Error creating tables: ", str(sys.exc_value)
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
print "***Error creating tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
self.rollback()
|
self.rollback()
|
||||||
raise fpdb_simple.FpdbError( "Error creating tables " + str(sys.exc_value) )
|
raise
|
||||||
#end def disconnect
|
#end def disconnect
|
||||||
|
|
||||||
def drop_tables(self):
|
def drop_tables(self):
|
||||||
|
@ -852,8 +847,9 @@ class Database:
|
||||||
|
|
||||||
self.commit()
|
self.commit()
|
||||||
except:
|
except:
|
||||||
print "Error dropping tables: " + str(sys.exc_value)
|
print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
raise fpdb_simple.FpdbError( "Error dropping tables " + str(sys.exc_value) )
|
self.rollback()
|
||||||
|
raise
|
||||||
#end def drop_tables
|
#end def drop_tables
|
||||||
|
|
||||||
def createAllIndexes(self):
|
def createAllIndexes(self):
|
||||||
|
@ -866,20 +862,18 @@ class Database:
|
||||||
if self.backend == self.MYSQL_INNODB:
|
if self.backend == self.MYSQL_INNODB:
|
||||||
print "creating mysql index ", idx['tab'], idx['col']
|
print "creating mysql index ", idx['tab'], idx['col']
|
||||||
try:
|
try:
|
||||||
self.get_cursor().execute( "alter table %s add index %s(%s)"
|
s = "create index %s on %s(%s)" % (idx['col'],idx['tab'],idx['col'])
|
||||||
, (idx['tab'],idx['col'],idx['col']) )
|
self.get_cursor().execute(s)
|
||||||
except:
|
except:
|
||||||
pass
|
print " create idx failed: " + str(sys.exc_info())
|
||||||
elif self.backend == self.PGSQL:
|
elif self.backend == self.PGSQL:
|
||||||
# mod to use tab_col for index name?
|
# mod to use tab_col for index name?
|
||||||
print "creating pg index ", idx['tab'], idx['col']
|
print "creating pg index ", idx['tab'], idx['col']
|
||||||
try:
|
try:
|
||||||
print "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col'])
|
s = "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col'])
|
||||||
self.get_cursor().execute( "create index %s_%s_idx on %s(%s)"
|
self.get_cursor().execute(s)
|
||||||
% (idx['tab'], idx['col'], idx['tab'], idx['col']) )
|
|
||||||
except:
|
except:
|
||||||
print " ERROR! :-("
|
print " create idx failed: " + str(sys.exc_info())
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
print "Only MySQL and Postgres supported so far"
|
print "Only MySQL and Postgres supported so far"
|
||||||
return -1
|
return -1
|
||||||
|
@ -926,6 +920,9 @@ class Database:
|
||||||
c.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')")
|
c.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')")
|
||||||
c.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')")
|
c.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')")
|
||||||
c.execute("INSERT INTO Sites (name,currency) VALUES ('Win2day', 'USD')")
|
c.execute("INSERT INTO Sites (name,currency) VALUES ('Win2day', 'USD')")
|
||||||
|
if self.backend == self.SQLITE:
|
||||||
|
c.execute("INSERT INTO TourneyTypes VALUES (NULL, 1, 0, 0, 0, 0);")
|
||||||
|
else:
|
||||||
c.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
|
c.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
|
||||||
#c.execute("""INSERT INTO TourneyTypes
|
#c.execute("""INSERT INTO TourneyTypes
|
||||||
# (siteId,buyin,fee,knockout,rebuyOrAddon) VALUES
|
# (siteId,buyin,fee,knockout,rebuyOrAddon) VALUES
|
||||||
|
@ -979,6 +976,35 @@ class Database:
|
||||||
print "Error during fdb.lock_for_insert:", str(sys.exc_value)
|
print "Error during fdb.lock_for_insert:", str(sys.exc_value)
|
||||||
#end def lock_for_insert
|
#end def lock_for_insert
|
||||||
|
|
||||||
|
def getSqlPlayerIDs(self, pnames, siteid):
|
||||||
|
result = {}
|
||||||
|
if(self.pcache == None):
|
||||||
|
self.pcache = LambdaDict(lambda key:self.insertPlayer(key, siteid))
|
||||||
|
|
||||||
|
for player in pnames:
|
||||||
|
result[player] = self.pcache[player]
|
||||||
|
# NOTE: Using the LambdaDict does the same thing as:
|
||||||
|
#if player in self.pcache:
|
||||||
|
# #print "DEBUG: cachehit"
|
||||||
|
# pass
|
||||||
|
#else:
|
||||||
|
# self.pcache[player] = self.insertPlayer(player, siteid)
|
||||||
|
#result[player] = self.pcache[player]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def insertPlayer(self, name, site_id):
|
||||||
|
result = None
|
||||||
|
c = self.get_cursor()
|
||||||
|
c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
|
||||||
|
tmp=c.fetchall()
|
||||||
|
if (len(tmp)==0): #new player
|
||||||
|
c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (name, site_id))
|
||||||
|
#Get last id might be faster here.
|
||||||
|
c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
|
||||||
|
tmp=c.fetchall()
|
||||||
|
return tmp[0][0]
|
||||||
|
|
||||||
|
|
||||||
def store_the_hand(self, h):
|
def store_the_hand(self, h):
|
||||||
"""Take a HandToWrite object and store it in the db"""
|
"""Take a HandToWrite object and store it in the db"""
|
||||||
|
@ -994,7 +1020,7 @@ class Database:
|
||||||
result = self.tourney_holdem_omaha(
|
result = self.tourney_holdem_omaha(
|
||||||
h.config, h.settings, h.base, h.category, h.siteTourneyNo, h.buyin
|
h.config, h.settings, h.base, h.category, h.siteTourneyNo, h.buyin
|
||||||
, h.fee, h.knockout, h.entries, h.prizepool, h.tourneyStartTime
|
, h.fee, h.knockout, h.entries, h.prizepool, h.tourneyStartTime
|
||||||
, h.payin_amounts, h.ranks, h.tourneyTypeId, h.siteID, h.siteHandNo
|
, payin_amounts, ranks, h.tourneyTypeId, h.siteID, h.siteHandNo
|
||||||
, h.gametypeID, h.handStartTime, h.names, h.playerIDs, h.startCashes
|
, h.gametypeID, h.handStartTime, h.names, h.playerIDs, h.startCashes
|
||||||
, h.positions, h.cardValues, h.cardSuits, h.boardValues, h.boardSuits
|
, h.positions, h.cardValues, h.cardSuits, h.boardValues, h.boardSuits
|
||||||
, h.winnings, h.rakes, h.actionTypes, h.allIns, h.actionAmounts
|
, h.winnings, h.rakes, h.actionTypes, h.allIns, h.actionAmounts
|
||||||
|
@ -1003,13 +1029,13 @@ class Database:
|
||||||
result = self.tourney_stud(
|
result = self.tourney_stud(
|
||||||
h.config, h.settings, h.base, h.category, h.siteTourneyNo
|
h.config, h.settings, h.base, h.category, h.siteTourneyNo
|
||||||
, h.buyin, h.fee, h.knockout, h.entries, h.prizepool, h.tourneyStartTime
|
, h.buyin, h.fee, h.knockout, h.entries, h.prizepool, h.tourneyStartTime
|
||||||
, h.payin_amounts, h.ranks, h.tourneyTypeId, h.siteID, h.siteHandNo
|
, payin_amounts, ranks, h.tourneyTypeId, h.siteID, h.siteHandNo
|
||||||
, h.gametypeID, h.handStartTime, h.names, h.playerIDs, h.startCashes
|
, h.gametypeID, h.handStartTime, h.names, h.playerIDs, h.startCashes
|
||||||
, h.antes, h.cardValues, h.cardSuits, h.winnings, h.rakes, h.actionTypes
|
, h.antes, h.cardValues, h.cardSuits, h.winnings, h.rakes, h.actionTypes
|
||||||
, h.allIns, h.actionAmounts, h.actionNos, h.hudImportData, h.maxSeats
|
, h.allIns, h.actionAmounts, h.actionNos, h.hudImportData, h.maxSeats
|
||||||
, h.tableName, h.seatNos)
|
, h.tableName, h.seatNos)
|
||||||
else:
|
else:
|
||||||
raise fpself.simple.Fpself.rror("unrecognised category")
|
raise fpdb_simple.FpdbError("unrecognised category")
|
||||||
else:
|
else:
|
||||||
if h.base == "hold":
|
if h.base == "hold":
|
||||||
result = self.ring_holdem_omaha(
|
result = self.ring_holdem_omaha(
|
||||||
|
@ -1027,11 +1053,13 @@ class Database:
|
||||||
, h.actionAmounts, h.actionNos, h.hudImportData, h.maxSeats, h.tableName
|
, h.actionAmounts, h.actionNos, h.hudImportData, h.maxSeats, h.tableName
|
||||||
, h.seatNos)
|
, h.seatNos)
|
||||||
else:
|
else:
|
||||||
raise fpself.simple.Fpself.rror ("unrecognised category")
|
raise fpdb_simple.FpdbError("unrecognised category")
|
||||||
self.commit()
|
|
||||||
except:
|
except:
|
||||||
print "Error storing hand: " + str(sys.exc_value)
|
print "Error storing hand: " + str(sys.exc_value)
|
||||||
self.rollback()
|
self.rollback()
|
||||||
|
# re-raise the exception so that the calling routine can decide what to do:
|
||||||
|
# (e.g. a write thread might try again)
|
||||||
|
raise
|
||||||
|
|
||||||
return result
|
return result
|
||||||
#end def store_the_hand
|
#end def store_the_hand
|
||||||
|
@ -1576,8 +1604,85 @@ class Database:
|
||||||
#end def store_tourneys_players
|
#end def store_tourneys_players
|
||||||
|
|
||||||
|
|
||||||
|
# read HandToWrite objects from q and insert into database
|
||||||
|
def insert_queue_hands(self, q, maxwait=10, commitEachHand=True):
|
||||||
|
n,fails,maxTries,firstWait = 0,0,4,0.1
|
||||||
|
sendFinal = False
|
||||||
|
t0 = time()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
h = q.get(True) # (True,maxWait) has probs if 1st part of import is all dups
|
||||||
|
except Queue.Empty:
|
||||||
|
# Queue.Empty exception thrown if q was empty for
|
||||||
|
# if q.empty() also possible - no point if testing for Queue.Empty exception
|
||||||
|
# maybe increment a counter and only break after a few times?
|
||||||
|
# could also test threading.active_count() or look through threading.enumerate()
|
||||||
|
# so break immediately if no threads, but count up to X exceptions if a writer
|
||||||
|
# thread is still alive???
|
||||||
|
print "queue empty too long - writer stopping ..."
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
print "writer stopping, error reading queue: " + str(sys.exc_info())
|
||||||
|
break
|
||||||
|
#print "got hand", str(h.get_finished())
|
||||||
|
|
||||||
|
tries,wait,again = 0,firstWait,True
|
||||||
|
while again:
|
||||||
|
try:
|
||||||
|
again = False # set this immediately to avoid infinite loops!
|
||||||
|
if h.get_finished():
|
||||||
|
# all items on queue processed
|
||||||
|
sendFinal = True
|
||||||
|
else:
|
||||||
|
self.store_the_hand(h)
|
||||||
|
# optional commit, could be every hand / every N hands / every time a
|
||||||
|
# commit message received?? mark flag to indicate if commits outstanding
|
||||||
|
if commitEachHand:
|
||||||
|
self.commit()
|
||||||
|
n = n + 1
|
||||||
|
except:
|
||||||
|
#print "iqh store error", sys.exc_value # debug
|
||||||
|
self.rollback()
|
||||||
|
if re.search('deadlock', str(sys.exc_info()[1]), re.I):
|
||||||
|
# deadlocks only a problem if hudcache is being updated
|
||||||
|
tries = tries + 1
|
||||||
|
if tries < maxTries and wait < 5: # wait < 5 just to make sure
|
||||||
|
print "deadlock detected - trying again ..."
|
||||||
|
sleep(wait)
|
||||||
|
wait = wait + wait
|
||||||
|
again = True
|
||||||
|
else:
|
||||||
|
print "too many deadlocks - failed to store hand " + h.get_siteHandNo()
|
||||||
|
if not again:
|
||||||
|
fails = fails + 1
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
print "***Error storing hand: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
|
# finished trying to store hand
|
||||||
|
|
||||||
|
# always reduce q count, whether or not this hand was saved ok
|
||||||
|
q.task_done()
|
||||||
|
# while True loop
|
||||||
|
|
||||||
|
self.commit()
|
||||||
|
if sendFinal:
|
||||||
|
q.task_done()
|
||||||
|
print "db writer finished: stored %d hands (%d fails) in %.1f seconds" % (n, fails, time()-t0)
|
||||||
|
# end def insert_queue_hands():
|
||||||
|
|
||||||
|
|
||||||
|
def send_finish_msg(self, q):
|
||||||
|
try:
|
||||||
|
h = HandToWrite(True)
|
||||||
|
q.put(h)
|
||||||
|
except:
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
print "***Error sending finish: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
|
# end def send_finish_msg():
|
||||||
|
|
||||||
|
|
||||||
# Class used to hold all the data needed to write a hand to the db
|
# Class used to hold all the data needed to write a hand to the db
|
||||||
# mainParser() in fpdb_parse_logic.py creates one of these and then passes it to
|
# mainParser() in fpdb_parse_logic.py creates one of these and then passes it to
|
||||||
|
# self.insert_queue_hands()
|
||||||
|
|
||||||
class HandToWrite:
|
class HandToWrite:
|
||||||
|
|
||||||
|
@ -1676,49 +1781,6 @@ class HandToWrite:
|
||||||
raise
|
raise
|
||||||
# end def set_hand
|
# end def set_hand
|
||||||
|
|
||||||
def set_ring_holdem_omaha( self, config, settings, base, category, siteHandNo
|
|
||||||
, gametypeID, handStartTime, names, playerIDs
|
|
||||||
, startCashes, positions, cardValues, cardSuits
|
|
||||||
, boardValues, boardSuits, winnings, rakes
|
|
||||||
, actionTypes, allIns, actionAmounts, actionNos
|
|
||||||
, hudImportData, maxSeats, tableName, seatNos ):
|
|
||||||
self.config = config
|
|
||||||
self.settings = settings
|
|
||||||
self.base = base
|
|
||||||
self.category = category
|
|
||||||
self.siteHandNo = siteHandNo
|
|
||||||
self.gametypeID = gametypeID
|
|
||||||
self.handStartTime = handStartTime
|
|
||||||
self.names = names
|
|
||||||
self.playerIDs = playerIDs
|
|
||||||
self.startCashes = startCashes
|
|
||||||
self.positions = positions
|
|
||||||
self.cardValues = cardValues
|
|
||||||
self.cardSuits = cardSuits
|
|
||||||
self.boardValues = boardValues
|
|
||||||
self.boardSuits = boardSuits
|
|
||||||
self.winnings = winnings
|
|
||||||
self.rakes = rakes
|
|
||||||
self.actionTypes = actionTypes
|
|
||||||
self.allIns = allIns
|
|
||||||
self.actionAmounts = actionAmounts
|
|
||||||
self.actionNos = actionNos
|
|
||||||
self.hudImportData = hudImportData
|
|
||||||
self.maxSeats = maxSeats
|
|
||||||
self.tableName = tableName
|
|
||||||
self.seatNos = seatNos
|
|
||||||
# end def set_ring_holdem_omaha
|
|
||||||
|
|
||||||
def send_ring_holdem_omaha(self, db):
|
|
||||||
result = db.ring_holdem_omaha(
|
|
||||||
self.config, self.settings, self.base, self.category, self.siteHandNo
|
|
||||||
, self.gametypeID, self.handStartTime, self.names, self.playerIDs
|
|
||||||
, self.startCashes, self.positions, self.cardValues, self.cardSuits
|
|
||||||
, self.boardValues, self.boardSuits, self.winnings, self.rakes
|
|
||||||
, self.actionTypes, self.allIns, self.actionAmounts, self.actionNos
|
|
||||||
, self.hudImportData, self.maxSeats, self.tableName, self.seatNos)
|
|
||||||
# end def send_ring_holdem_omaha
|
|
||||||
|
|
||||||
def get_finished(self):
|
def get_finished(self):
|
||||||
return( self.finished )
|
return( self.finished )
|
||||||
# end def get_finished
|
# end def get_finished
|
||||||
|
@ -1738,6 +1800,8 @@ if __name__=="__main__":
|
||||||
print "database connection object = ", db_connection.connection
|
print "database connection object = ", db_connection.connection
|
||||||
print "database type = ", db_connection.type
|
print "database type = ", db_connection.type
|
||||||
|
|
||||||
|
db_connection.recreate_tables()
|
||||||
|
|
||||||
h = db_connection.get_last_hand()
|
h = db_connection.get_last_hand()
|
||||||
print "last hand = ", h
|
print "last hand = ", h
|
||||||
|
|
||||||
|
@ -1759,3 +1823,17 @@ if __name__=="__main__":
|
||||||
|
|
||||||
print "press enter to continue"
|
print "press enter to continue"
|
||||||
sys.stdin.readline()
|
sys.stdin.readline()
|
||||||
|
|
||||||
|
|
||||||
|
#Code borrowed from http://push.cx/2008/caching-dictionaries-in-python-vs-ruby
|
||||||
|
class LambdaDict(dict):
|
||||||
|
def __init__(self, l):
|
||||||
|
super(LambdaDict, self).__init__()
|
||||||
|
self.l = l
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key in self:
|
||||||
|
return self.get(key)
|
||||||
|
else:
|
||||||
|
self.__setitem__(key, self.l(key))
|
||||||
|
return self.get(key)
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
#In the "official" distribution you can find the license in
|
#In the "official" distribution you can find the license in
|
||||||
#agpl-3.0.txt in the docs folder of the package.
|
#agpl-3.0.txt in the docs folder of the package.
|
||||||
|
|
||||||
|
#fpdb modules
|
||||||
|
import Card
|
||||||
|
|
||||||
class DerivedStats():
|
class DerivedStats():
|
||||||
def __init__(self, hand):
|
def __init__(self, hand):
|
||||||
self.hand = hand
|
self.hand = hand
|
||||||
|
@ -89,5 +92,69 @@ class DerivedStats():
|
||||||
self.street4CheckCallRaiseChance = 0
|
self.street4CheckCallRaiseChance = 0
|
||||||
self.street4CheckCallRaiseDone = 0
|
self.street4CheckCallRaiseDone = 0
|
||||||
|
|
||||||
def getStats():
|
self.hands = {}
|
||||||
|
self.handsplayers = {}
|
||||||
|
|
||||||
|
def getStats(self, hand):
|
||||||
|
|
||||||
|
for player in hand.players:
|
||||||
|
self.handsplayers[player[1]] = {}
|
||||||
|
|
||||||
|
self.assembleHands(self.hand)
|
||||||
|
self.assembleHandsPlayers(self.hand)
|
||||||
|
|
||||||
|
print "hands =", self.hands
|
||||||
|
print "handsplayers =", self.handsplayers
|
||||||
|
|
||||||
|
def assembleHands(self, hand):
|
||||||
|
self.hands['tableName'] = hand.tablename
|
||||||
|
self.hands['siteHandNo'] = hand.handid
|
||||||
|
self.hands['gametypeId'] = None # Leave None, handled later after checking db
|
||||||
|
self.hands['handStart'] = hand.starttime # format this!
|
||||||
|
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
|
||||||
|
|
||||||
|
boardCard = 1
|
||||||
|
for street in hand.communityStreets:
|
||||||
|
for card in hand.board[street]:
|
||||||
|
self.hands['boardcard%s' % str(boardCard)] = Card.encodeCard(card)
|
||||||
|
boardCard += 1
|
||||||
|
|
||||||
|
def assembleHandsPlayers(self, hand):
|
||||||
|
self.vpip(self.hand)
|
||||||
|
for i, street in enumerate(hand.actionStreets[1:]):
|
||||||
|
self.aggr(self.hand, i)
|
||||||
|
|
||||||
|
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
|
||||||
|
self.hands['playersVpi'] = len(vpipers)
|
||||||
|
|
||||||
|
def aggr(self, hand, i):
|
||||||
|
aggrers = set()
|
||||||
|
for act in hand.actions[hand.actionStreets[i]]:
|
||||||
|
if act[1] in ('completes', 'raises'):
|
||||||
|
aggrers.add(act[0])
|
||||||
|
|
||||||
|
for player in hand.players:
|
||||||
|
if player[1] in aggrers:
|
||||||
|
self.handsplayers[player[1]]['street%sAggr' % i] = True
|
||||||
|
else:
|
||||||
|
self.handsplayers[player[1]]['street%sAggr' % i] = False
|
||||||
|
|
||||||
|
def countPlayers(self, hand):
|
||||||
pass
|
pass
|
|
@ -31,10 +31,11 @@ import Configuration
|
||||||
import string
|
import string
|
||||||
|
|
||||||
class GuiAutoImport (threading.Thread):
|
class GuiAutoImport (threading.Thread):
|
||||||
def __init__(self, settings, config):
|
def __init__(self, settings, config, sql):
|
||||||
"""Constructor for GuiAutoImport"""
|
"""Constructor for GuiAutoImport"""
|
||||||
self.settings=settings
|
self.settings=settings
|
||||||
self.config=config
|
self.config=config
|
||||||
|
self.sql = sql
|
||||||
|
|
||||||
imp = self.config.get_import_parameters()
|
imp = self.config.get_import_parameters()
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ class GuiAutoImport (threading.Thread):
|
||||||
self.input_settings = {}
|
self.input_settings = {}
|
||||||
self.pipe_to_hud = None
|
self.pipe_to_hud = None
|
||||||
|
|
||||||
self.importer = fpdb_import.Importer(self,self.settings, self.config)
|
self.importer = fpdb_import.Importer(self, self.settings, self.config, self.sql)
|
||||||
self.importer.setCallHud(True)
|
self.importer.setCallHud(True)
|
||||||
self.importer.setMinPrint(settings['minPrint'])
|
self.importer.setMinPrint(settings['minPrint'])
|
||||||
self.importer.setQuiet(False)
|
self.importer.setQuiet(False)
|
||||||
|
@ -159,6 +160,7 @@ class GuiAutoImport (threading.Thread):
|
||||||
# - Ideally we want to release the lock if the auto-import is killed by some
|
# - Ideally we want to release the lock if the auto-import is killed by some
|
||||||
# kind of exception - is this possible?
|
# kind of exception - is this possible?
|
||||||
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
||||||
|
try:
|
||||||
print "\nGlobal lock taken ..."
|
print "\nGlobal lock taken ..."
|
||||||
self.doAutoImportBool = True
|
self.doAutoImportBool = True
|
||||||
widget.set_label(u' _Stop Autoimport ')
|
widget.set_label(u' _Stop Autoimport ')
|
||||||
|
@ -182,6 +184,9 @@ class GuiAutoImport (threading.Thread):
|
||||||
|
|
||||||
interval=int(self.intervalEntry.get_text())
|
interval=int(self.intervalEntry.get_text())
|
||||||
gobject.timeout_add(interval*1000, self.do_import)
|
gobject.timeout_add(interval*1000, self.do_import)
|
||||||
|
except:
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
else:
|
else:
|
||||||
print "auto-import aborted - global lock not available"
|
print "auto-import aborted - global lock not available"
|
||||||
else: # toggled off
|
else: # toggled off
|
||||||
|
|
|
@ -21,6 +21,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
from time import time
|
from time import time
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
import traceback
|
||||||
|
|
||||||
# pyGTK modules
|
# pyGTK modules
|
||||||
import pygtk
|
import pygtk
|
||||||
|
@ -34,6 +35,9 @@ import Configuration
|
||||||
|
|
||||||
class GuiBulkImport():
|
class GuiBulkImport():
|
||||||
|
|
||||||
|
# CONFIGURATION - update these as preferred:
|
||||||
|
allowThreads = True # set to True to try out the threads field
|
||||||
|
|
||||||
# not used
|
# not used
|
||||||
def import_dir(self):
|
def import_dir(self):
|
||||||
"""imports a directory, non-recursive. todo: move this to fpdb_import so CLI can use it"""
|
"""imports a directory, non-recursive. todo: move this to fpdb_import so CLI can use it"""
|
||||||
|
@ -67,12 +71,19 @@ class GuiBulkImport():
|
||||||
self.importer.setHandsInDB(self.n_hands_in_db)
|
self.importer.setHandsInDB(self.n_hands_in_db)
|
||||||
cb_model = self.cb_dropindexes.get_model()
|
cb_model = self.cb_dropindexes.get_model()
|
||||||
cb_index = self.cb_dropindexes.get_active()
|
cb_index = self.cb_dropindexes.get_active()
|
||||||
|
cb_hmodel = self.cb_drophudcache.get_model()
|
||||||
|
cb_hindex = self.cb_drophudcache.get_active()
|
||||||
|
|
||||||
|
self.lab_info.set_text("Importing") # doesn't display :-(
|
||||||
if cb_index:
|
if cb_index:
|
||||||
self.importer.setDropIndexes(cb_model[cb_index][0])
|
self.importer.setDropIndexes(cb_model[cb_index][0])
|
||||||
else:
|
else:
|
||||||
self.importer.setDropIndexes("auto")
|
self.importer.setDropIndexes("auto")
|
||||||
|
if cb_hindex:
|
||||||
|
self.importer.setDropHudCache(cb_hmodel[cb_hindex][0])
|
||||||
|
else:
|
||||||
|
self.importer.setDropHudCache("auto")
|
||||||
sitename = self.cbfilter.get_model()[self.cbfilter.get_active()][0]
|
sitename = self.cbfilter.get_model()[self.cbfilter.get_active()][0]
|
||||||
self.lab_info.set_text("Importing")
|
|
||||||
|
|
||||||
self.importer.addBulkImportImportFileOrDir(self.inputFile, site = sitename)
|
self.importer.addBulkImportImportFileOrDir(self.inputFile, site = sitename)
|
||||||
self.importer.setCallHud(False)
|
self.importer.setCallHud(False)
|
||||||
|
@ -81,14 +92,21 @@ class GuiBulkImport():
|
||||||
ttime = time() - starttime
|
ttime = time() - starttime
|
||||||
if ttime == 0:
|
if ttime == 0:
|
||||||
ttime = 1
|
ttime = 1
|
||||||
print 'GuiBulkImport.load done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %d/sec'\
|
print 'GuiBulkImport.load done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %.0f/sec'\
|
||||||
% (stored, dups, partial, errs, ttime, stored / ttime)
|
% (stored, dups, partial, errs, ttime, (stored+0.0) / ttime)
|
||||||
self.importer.clearFileList()
|
self.importer.clearFileList()
|
||||||
|
if self.n_hands_in_db == 0 and stored > 0:
|
||||||
|
self.cb_dropindexes.set_sensitive(True)
|
||||||
|
self.cb_dropindexes.set_active(0)
|
||||||
|
self.lab_drop.set_sensitive(True)
|
||||||
|
self.cb_drophudcache.set_sensitive(True)
|
||||||
|
self.cb_drophudcache.set_active(0)
|
||||||
|
self.lab_hdrop.set_sensitive(True)
|
||||||
|
|
||||||
self.lab_info.set_text("Import finished")
|
self.lab_info.set_text("Import finished")
|
||||||
except:
|
except:
|
||||||
print "bulkimport.loadclicked error: "+str(sys.exc_value)
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
pass
|
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
self.settings['global_lock'].release()
|
self.settings['global_lock'].release()
|
||||||
else:
|
else:
|
||||||
print "bulk-import aborted - global lock not available"
|
print "bulk-import aborted - global lock not available"
|
||||||
|
@ -111,7 +129,7 @@ class GuiBulkImport():
|
||||||
self.chooser.show()
|
self.chooser.show()
|
||||||
|
|
||||||
# Table widget to hold the settings
|
# Table widget to hold the settings
|
||||||
self.table = gtk.Table(rows = 3, columns = 5, homogeneous = False)
|
self.table = gtk.Table(rows = 5, columns = 5, homogeneous = False)
|
||||||
self.vbox.add(self.table)
|
self.vbox.add(self.table)
|
||||||
self.table.show()
|
self.table.show()
|
||||||
|
|
||||||
|
@ -126,6 +144,7 @@ class GuiBulkImport():
|
||||||
self.table.attach(self.lab_status, 1, 2, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.lab_status, 1, 2, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.lab_status.show()
|
self.lab_status.show()
|
||||||
self.lab_status.set_justify(gtk.JUSTIFY_RIGHT)
|
self.lab_status.set_justify(gtk.JUSTIFY_RIGHT)
|
||||||
|
self.lab_status.set_alignment(1.0, 0.5)
|
||||||
|
|
||||||
# spin button - status
|
# spin button - status
|
||||||
status_adj = gtk.Adjustment(value=100, lower=0, upper=300, step_incr=10, page_incr=1, page_size=0) #not sure what upper value should be!
|
status_adj = gtk.Adjustment(value=100, lower=0, upper=300, step_incr=10, page_incr=1, page_size=0) #not sure what upper value should be!
|
||||||
|
@ -137,14 +156,17 @@ class GuiBulkImport():
|
||||||
self.lab_threads = gtk.Label("Number of threads:")
|
self.lab_threads = gtk.Label("Number of threads:")
|
||||||
self.table.attach(self.lab_threads, 3, 4, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.lab_threads, 3, 4, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.lab_threads.show()
|
self.lab_threads.show()
|
||||||
|
if not self.allowThreads:
|
||||||
self.lab_threads.set_sensitive(False)
|
self.lab_threads.set_sensitive(False)
|
||||||
self.lab_threads.set_justify(gtk.JUSTIFY_RIGHT)
|
self.lab_threads.set_justify(gtk.JUSTIFY_RIGHT)
|
||||||
|
self.lab_threads.set_alignment(1.0, 0.5)
|
||||||
|
|
||||||
# spin button - threads
|
# spin button - threads
|
||||||
threads_adj = gtk.Adjustment(value=0, lower=0, upper=10, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be!
|
threads_adj = gtk.Adjustment(value=0, lower=0, upper=32, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be!
|
||||||
self.spin_threads = gtk.SpinButton(adjustment=threads_adj, climb_rate=0.0, digits=0)
|
self.spin_threads = gtk.SpinButton(adjustment=threads_adj, climb_rate=0.0, digits=0)
|
||||||
self.table.attach(self.spin_threads, 4, 5, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.spin_threads, 4, 5, 0, 1, xpadding = 10, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.spin_threads.show()
|
self.spin_threads.show()
|
||||||
|
if not self.allowThreads:
|
||||||
self.spin_threads.set_sensitive(False)
|
self.spin_threads.set_sensitive(False)
|
||||||
|
|
||||||
# checkbox - fail on error?
|
# checkbox - fail on error?
|
||||||
|
@ -157,6 +179,7 @@ class GuiBulkImport():
|
||||||
self.table.attach(self.lab_hands, 1, 2, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.lab_hands, 1, 2, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.lab_hands.show()
|
self.lab_hands.show()
|
||||||
self.lab_hands.set_justify(gtk.JUSTIFY_RIGHT)
|
self.lab_hands.set_justify(gtk.JUSTIFY_RIGHT)
|
||||||
|
self.lab_hands.set_alignment(1.0, 0.5)
|
||||||
|
|
||||||
# spin button - hands to import
|
# spin button - hands to import
|
||||||
hands_adj = gtk.Adjustment(value=0, lower=0, upper=10, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be!
|
hands_adj = gtk.Adjustment(value=0, lower=0, upper=10, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be!
|
||||||
|
@ -169,6 +192,7 @@ class GuiBulkImport():
|
||||||
self.table.attach(self.lab_drop, 3, 4, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.lab_drop, 3, 4, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.lab_drop.show()
|
self.lab_drop.show()
|
||||||
self.lab_drop.set_justify(gtk.JUSTIFY_RIGHT)
|
self.lab_drop.set_justify(gtk.JUSTIFY_RIGHT)
|
||||||
|
self.lab_drop.set_alignment(1.0, 0.5)
|
||||||
|
|
||||||
# ComboBox - drop indexes
|
# ComboBox - drop indexes
|
||||||
self.cb_dropindexes = gtk.combo_box_new_text()
|
self.cb_dropindexes = gtk.combo_box_new_text()
|
||||||
|
@ -181,9 +205,10 @@ class GuiBulkImport():
|
||||||
|
|
||||||
# label - filter
|
# label - filter
|
||||||
self.lab_filter = gtk.Label("Site filter:")
|
self.lab_filter = gtk.Label("Site filter:")
|
||||||
self.table.attach(self.lab_filter, 2, 3, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.lab_filter, 1, 2, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.lab_filter.show()
|
self.lab_filter.show()
|
||||||
self.lab_filter.set_justify(gtk.JUSTIFY_RIGHT)
|
self.lab_filter.set_justify(gtk.JUSTIFY_RIGHT)
|
||||||
|
self.lab_filter.set_alignment(1.0, 0.5)
|
||||||
|
|
||||||
# ComboBox - filter
|
# ComboBox - filter
|
||||||
self.cbfilter = gtk.combo_box_new_text()
|
self.cbfilter = gtk.combo_box_new_text()
|
||||||
|
@ -191,21 +216,42 @@ class GuiBulkImport():
|
||||||
print w
|
print w
|
||||||
self.cbfilter.append_text(w)
|
self.cbfilter.append_text(w)
|
||||||
self.cbfilter.set_active(0)
|
self.cbfilter.set_active(0)
|
||||||
self.table.attach(self.cbfilter, 3, 4, 2, 3, xpadding = 10, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.cbfilter, 2, 3, 2, 3, xpadding = 10, ypadding = 1, yoptions=gtk.SHRINK)
|
||||||
self.cbfilter.show()
|
self.cbfilter.show()
|
||||||
|
|
||||||
# label - info
|
# label - drop hudcache
|
||||||
self.lab_info = gtk.Label()
|
self.lab_hdrop = gtk.Label("Drop HudCache:")
|
||||||
self.table.attach(self.lab_info, 0, 4, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.lab_hdrop, 3, 4, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.lab_info.show()
|
self.lab_hdrop.show()
|
||||||
|
self.lab_hdrop.set_justify(gtk.JUSTIFY_RIGHT)
|
||||||
|
self.lab_hdrop.set_alignment(1.0, 0.5)
|
||||||
|
|
||||||
|
# ComboBox - drop hudcache
|
||||||
|
self.cb_drophudcache = gtk.combo_box_new_text()
|
||||||
|
self.cb_drophudcache.append_text('auto')
|
||||||
|
self.cb_drophudcache.append_text("don't drop")
|
||||||
|
self.cb_drophudcache.append_text('drop')
|
||||||
|
self.cb_drophudcache.set_active(0)
|
||||||
|
self.table.attach(self.cb_drophudcache, 4, 5, 2, 3, xpadding = 10, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
|
self.cb_drophudcache.show()
|
||||||
|
|
||||||
# button - Import
|
# button - Import
|
||||||
self.load_button = gtk.Button('Import') # todo: rename variables to import too
|
self.load_button = gtk.Button('Import') # todo: rename variables to import too
|
||||||
self.load_button.connect('clicked', self.load_clicked,
|
self.load_button.connect('clicked', self.load_clicked,
|
||||||
'Import clicked')
|
'Import clicked')
|
||||||
self.table.attach(self.load_button, 4, 5, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
self.table.attach(self.load_button, 2, 3, 4, 5, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
self.load_button.show()
|
self.load_button.show()
|
||||||
|
|
||||||
|
# label - spacer (keeps rows 3 & 5 apart)
|
||||||
|
self.lab_spacer = gtk.Label()
|
||||||
|
self.table.attach(self.lab_spacer, 3, 5, 3, 4, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
|
self.lab_spacer.show()
|
||||||
|
|
||||||
|
# label - info
|
||||||
|
self.lab_info = gtk.Label()
|
||||||
|
self.table.attach(self.lab_info, 3, 5, 4, 5, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
|
||||||
|
self.lab_info.show()
|
||||||
|
|
||||||
# see how many hands are in the db and adjust accordingly
|
# see how many hands are in the db and adjust accordingly
|
||||||
tcursor = self.importer.database.cursor
|
tcursor = self.importer.database.cursor
|
||||||
tcursor.execute("Select count(1) from Hands")
|
tcursor.execute("Select count(1) from Hands")
|
||||||
|
@ -217,6 +263,9 @@ class GuiBulkImport():
|
||||||
self.cb_dropindexes.set_active(2)
|
self.cb_dropindexes.set_active(2)
|
||||||
self.cb_dropindexes.set_sensitive(False)
|
self.cb_dropindexes.set_sensitive(False)
|
||||||
self.lab_drop.set_sensitive(False)
|
self.lab_drop.set_sensitive(False)
|
||||||
|
self.cb_drophudcache.set_active(2)
|
||||||
|
self.cb_drophudcache.set_sensitive(False)
|
||||||
|
self.lab_hdrop.set_sensitive(False)
|
||||||
|
|
||||||
def main(argv=None):
|
def main(argv=None):
|
||||||
"""main can also be called in the python interpreter, by supplying the command line as the argument."""
|
"""main can also be called in the python interpreter, by supplying the command line as the argument."""
|
||||||
|
|
|
@ -210,7 +210,7 @@
|
||||||
<game cols="3" db="fpdb" game_name="holdem" rows="2" aux="mucked">
|
<game cols="3" db="fpdb" game_name="holdem" rows="2" aux="mucked">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
@ -219,7 +219,7 @@
|
||||||
<game cols="3" db="fpdb" game_name="razz" rows="2" aux="stud_mucked">
|
<game cols="3" db="fpdb" game_name="razz" rows="2" aux="stud_mucked">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
@ -228,7 +228,7 @@
|
||||||
<game cols="3" db="fpdb" game_name="omahahi" rows="2" aux="mucked">
|
<game cols="3" db="fpdb" game_name="omahahi" rows="2" aux="mucked">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
@ -237,7 +237,7 @@
|
||||||
<game cols="3" db="fpdb" game_name="omahahilo" rows="2" aux="mucked">
|
<game cols="3" db="fpdb" game_name="omahahilo" rows="2" aux="mucked">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
@ -246,7 +246,7 @@
|
||||||
<game cols="3" db="fpdb" game_name="studhi" rows="2" aux="stud_mucked">
|
<game cols="3" db="fpdb" game_name="studhi" rows="2" aux="stud_mucked">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
@ -255,7 +255,7 @@
|
||||||
<game cols="3" db="fpdb" game_name="studhilo" rows="2" aux="stud_mucked">
|
<game cols="3" db="fpdb" game_name="studhilo" rows="2" aux="stud_mucked">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
@ -274,18 +274,18 @@
|
||||||
<pu_stat pu_stat_name="wmsd"> </pu_stat>
|
<pu_stat pu_stat_name="wmsd"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="wtsd"> </pu_stat>
|
<pu_stat pu_stat_name="wtsd"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="WMsF"> </pu_stat>
|
<pu_stat pu_stat_name="WMsF"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="a_freq_1"> </pu_stat>
|
<pu_stat pu_stat_name="a_freq1"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="a_freq_2"> </pu_stat>
|
<pu_stat pu_stat_name="a_freq2"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="a_freq_3"> </pu_stat>
|
<pu_stat pu_stat_name="a_freq3"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="a_freq_4"> </pu_stat>
|
<pu_stat pu_stat_name="a_freq4"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="cb_1"> </pu_stat>
|
<pu_stat pu_stat_name="cb1"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="cb_2"> </pu_stat>
|
<pu_stat pu_stat_name="cb2"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="cb_3"> </pu_stat>
|
<pu_stat pu_stat_name="cb3"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="cb_4"> </pu_stat>
|
<pu_stat pu_stat_name="cb4"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="ffreq_1"> </pu_stat>
|
<pu_stat pu_stat_name="ffreq1"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="ffreq_2"> </pu_stat>
|
<pu_stat pu_stat_name="ffreq2"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="ffreq_3"> </pu_stat>
|
<pu_stat pu_stat_name="ffreq3"> </pu_stat>
|
||||||
<pu_stat pu_stat_name="ffreq_4"> </pu_stat>
|
<pu_stat pu_stat_name="ffreq4"> </pu_stat>
|
||||||
</pu>
|
</pu>
|
||||||
</popup_windows>
|
</popup_windows>
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ Main for FreePokerTools HUD.
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import Options
|
import Options
|
||||||
|
import traceback
|
||||||
|
|
||||||
(options, sys.argv) = Options.fpdb_options()
|
(options, sys.argv) = Options.fpdb_options()
|
||||||
|
|
||||||
|
@ -55,7 +56,23 @@ import Database
|
||||||
import Tables
|
import Tables
|
||||||
import Hud
|
import Hud
|
||||||
|
|
||||||
aggregate_stats = {"ring": False, "tour": False} # config file!
|
# 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)
|
||||||
|
|
||||||
class HUD_main(object):
|
class HUD_main(object):
|
||||||
"""A main() object to own both the read_stdin thread and the gui."""
|
"""A main() object to own both the read_stdin thread and the gui."""
|
||||||
|
@ -144,6 +161,7 @@ class HUD_main(object):
|
||||||
# need their own access to the database, but should open their own
|
# need their own access to the database, but should open their own
|
||||||
# if it is required.
|
# if it is required.
|
||||||
self.db_connection = Database.Database(self.config, self.db_name, 'temp')
|
self.db_connection = Database.Database(self.config, self.db_name, 'temp')
|
||||||
|
self.db_connection.init_hud_stat_vars(hud_days)
|
||||||
tourny_finder = re.compile('(\d+) (\d+)')
|
tourny_finder = re.compile('(\d+) (\d+)')
|
||||||
|
|
||||||
while 1: # wait for a new hand number on stdin
|
while 1: # wait for a new hand number on stdin
|
||||||
|
@ -156,13 +174,17 @@ class HUD_main(object):
|
||||||
# if there is a db error, complain, skip hand, and proceed
|
# if there is a db error, complain, skip hand, and proceed
|
||||||
try:
|
try:
|
||||||
(table_name, max, poker_game, type) = self.db_connection.get_table_name(new_hand_id)
|
(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 = aggregate_stats[type])
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate_stats[type]
|
||||||
|
,hud_style, agg_bb_mult)
|
||||||
|
|
||||||
cards = self.db_connection.get_cards(new_hand_id)
|
cards = self.db_connection.get_cards(new_hand_id)
|
||||||
comm_cards = self.db_connection.get_common_cards(new_hand_id)
|
comm_cards = self.db_connection.get_common_cards(new_hand_id)
|
||||||
if comm_cards != {}: # stud!
|
if comm_cards != {}: # stud!
|
||||||
cards['common'] = comm_cards['common']
|
cards['common'] = comm_cards['common']
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
print "db error: skipping ", new_hand_id, 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)))
|
sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,12 @@ class Hand(object):
|
||||||
LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'}
|
LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'}
|
||||||
SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''}
|
SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''}
|
||||||
MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'}
|
MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'}
|
||||||
|
SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
|
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
|
||||||
self.sitename = sitename
|
self.sitename = sitename
|
||||||
|
self.siteId = self.SITEIDS[sitename]
|
||||||
self.stats = DerivedStats.DerivedStats(self)
|
self.stats = DerivedStats.DerivedStats(self)
|
||||||
self.gametype = gametype
|
self.gametype = gametype
|
||||||
self.starttime = 0
|
self.starttime = 0
|
||||||
|
|
|
@ -204,7 +204,9 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
logging.info("Unsupported game type: %s" % gametype)
|
logging.info("Unsupported game type: %s" % gametype)
|
||||||
|
|
||||||
if hand:
|
if hand:
|
||||||
|
# uncomment these to calculate some stats
|
||||||
# print hand
|
# print hand
|
||||||
|
# hand.stats.getStats(hand)
|
||||||
hand.writeHand(self.out_fh)
|
hand.writeHand(self.out_fh)
|
||||||
return hand
|
return hand
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -32,6 +32,9 @@ def fpdb_options():
|
||||||
parser.add_option("-c", "--configFile",
|
parser.add_option("-c", "--configFile",
|
||||||
dest="config", default=None,
|
dest="config", default=None,
|
||||||
help="Specifies a configuration file.")
|
help="Specifies a configuration file.")
|
||||||
|
parser.add_option("-r", "--rerunPython",
|
||||||
|
action="store_true",
|
||||||
|
help="Indicates program was restarted with a different path (only allowed once).")
|
||||||
(options, sys.argv) = parser.parse_args()
|
(options, sys.argv) = parser.parse_args()
|
||||||
return (options, sys.argv)
|
return (options, sys.argv)
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,11 @@ class PokerStars(HandHistoryConverter):
|
||||||
############################################################
|
############################################################
|
||||||
# Class Variables
|
# Class Variables
|
||||||
|
|
||||||
|
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games
|
||||||
|
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\x80", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE
|
||||||
substitutions = {
|
substitutions = {
|
||||||
'LEGAL_ISO' : "USD|EUR|GBP|CAD", # legal ISO currency codes
|
'LEGAL_ISO' : "USD|EUR|GBP|CAD", # legal ISO currency codes
|
||||||
'LS' : "\$" # legal currency symbols
|
'LS' : "\$|\x80|\xa3" # legal currency symbols ADD Euro, Sterling, etc HERE
|
||||||
}
|
}
|
||||||
|
|
||||||
# Static regexes
|
# Static regexes
|
||||||
|
@ -48,25 +50,32 @@ class PokerStars(HandHistoryConverter):
|
||||||
(-\sLevel\s(?P<LEVEL>[IVXLC]+)\s)?
|
(-\sLevel\s(?P<LEVEL>[IVXLC]+)\s)?
|
||||||
\(? # open paren of the stakes
|
\(? # open paren of the stakes
|
||||||
(?P<CURRENCY>%(LS)s|)?
|
(?P<CURRENCY>%(LS)s|)?
|
||||||
(?P<SB>[.0-9]+)/%(LS)s?
|
(?P<SB>[.0-9]+)/(%(LS)s)?
|
||||||
(?P<BB>[.0-9]+)
|
(?P<BB>[.0-9]+)
|
||||||
\s?(?P<ISO>%(LEGAL_ISO)s)?
|
\s?(?P<ISO>%(LEGAL_ISO)s)?
|
||||||
\)\s-\s # close paren of the stakes
|
\)\s-\s # close paren of the stakes
|
||||||
(?P<DATETIME>.*$)""" % substitutions,
|
(?P<DATETIME>.*$)""" % substitutions,
|
||||||
re.MULTILINE|re.VERBOSE)
|
re.MULTILINE|re.VERBOSE)
|
||||||
re_SplitHands = re.compile('\n\n+')
|
|
||||||
re_TailSplitHands = re.compile('(\n\n\n+)')
|
re_PlayerInfo = re.compile("""
|
||||||
re_HandInfo = re.compile("""^Table\s\'(?P<TABLE>[-\ a-zA-Z\d]+)\'\s
|
^Seat\s(?P<SEAT>[0-9]+):\s
|
||||||
|
(?P<PNAME>.*)\s
|
||||||
|
\((%(LS)s)?(?P<CASH>[.0-9]+)\sin\schips\)""" % substitutions,
|
||||||
|
re.MULTILINE|re.VERBOSE)
|
||||||
|
|
||||||
|
re_HandInfo = re.compile("""
|
||||||
|
^Table\s\'(?P<TABLE>[-\ a-zA-Z\d]+)\'\s
|
||||||
((?P<MAX>\d+)-max\s)?
|
((?P<MAX>\d+)-max\s)?
|
||||||
(?P<PLAY>\(Play\sMoney\)\s)?
|
(?P<PLAY>\(Play\sMoney\)\s)?
|
||||||
(Seat\s\#(?P<BUTTON>\d+)\sis\sthe\sbutton)?""",
|
(Seat\s\#(?P<BUTTON>\d+)\sis\sthe\sbutton)?""",
|
||||||
re.MULTILINE|re.VERBOSE)
|
re.MULTILINE|re.VERBOSE)
|
||||||
|
|
||||||
|
re_SplitHands = re.compile('\n\n+')
|
||||||
|
re_TailSplitHands = re.compile('(\n\n\n+)')
|
||||||
re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
|
re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
|
||||||
re_PlayerInfo = re.compile('^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$?(?P<CASH>[.0-9]+) in chips\)', re.MULTILINE)
|
|
||||||
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
||||||
# self.re_setHandInfoRegex('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[ a-zA-Z]+) - \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) - (?P<GAMETYPE>.*) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+) ET - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+)Table (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
|
# self.re_setHandInfoRegex('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[ a-zA-Z]+) - \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) - (?P<GAMETYPE>.*) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+) ET - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+)Table (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
|
||||||
|
|
||||||
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'}
|
|
||||||
|
|
||||||
def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True, index=0):
|
def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True, index=0):
|
||||||
"""\
|
"""\
|
||||||
|
@ -91,19 +100,21 @@ follow : whether to tail -f the input"""
|
||||||
# They still identify the hero.
|
# They still identify the hero.
|
||||||
self.compiledPlayers = players
|
self.compiledPlayers = players
|
||||||
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
||||||
|
subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]}
|
||||||
logging.debug("player_re: " + player_re)
|
logging.debug("player_re: " + player_re)
|
||||||
self.re_PostSB = re.compile(r"^%s: posts small blind \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostSB = re.compile(r"^%(PLYR)s: posts small blind %(CUR)s(?P<SB>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_PostBB = re.compile(r"^%s: posts big blind \$?(?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostBB = re.compile(r"^%(PLYR)s: posts big blind %(CUR)s(?P<BB>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_Antes = re.compile(r"^%s: posts the ante \$?(?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante %(CUR)s(?P<ANTE>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_BringIn = re.compile(r"^%s: brings[- ]in( low|) for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_BringIn = re.compile(r"^%(PLYR)s: brings[- ]in( low|) for %(CUR)s(?P<BRINGIN>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_PostBoth = re.compile(r"^%s: posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostBoth = re.compile(r"^%(PLYR)s: posts small \& big blinds \[%(CUR)s (?P<SBBB>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
|
self.re_HeroCards = re.compile(r"^Dealt to %(PLYR)s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % subst, re.MULTILINE)
|
||||||
self.re_Action = re.compile(r"""^%s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat)
|
self.re_Action = re.compile(r"""
|
||||||
(\s\$?(?P<BET>[.\d]+))?(\sto\s\$?(?P<BETTO>[.\d]+))? # the number discarded goes in <BET>
|
^%(PLYR)s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat)
|
||||||
|
(\s%(CUR)s(?P<BET>[.\d]+))?(\sto\s%(CUR)s(?P<BETTO>[.\d]+))? # the number discarded goes in <BET>
|
||||||
(\scards?(\s\[(?P<DISCARDED>.+?)\])?)?"""
|
(\scards?(\s\[(?P<DISCARDED>.+?)\])?)?"""
|
||||||
% player_re, re.MULTILINE|re.VERBOSE)
|
% subst, re.MULTILINE|re.VERBOSE)
|
||||||
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
||||||
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$?(?P<POT>[.\d]+)\)(, mucked| with.*|)" % player_re, re.MULTILINE)
|
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %(PLYR)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(%(CUR)s(?P<POT>[.\d]+)\)(, mucked| with.*|)" % subst, re.MULTILINE)
|
||||||
self.re_sitsOut = re.compile("^%s sits out" % player_re, re.MULTILINE)
|
self.re_sitsOut = re.compile("^%s sits out" % player_re, re.MULTILINE)
|
||||||
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s (\(.*\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s (\(.*\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
||||||
|
|
||||||
|
|
650
pyfpdb/SQL.py
650
pyfpdb/SQL.py
|
@ -19,9 +19,15 @@ Set up all of the SQL statements for a given game and database type.
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
# NOTES: The sql statements use the placeholder %s for bind variables
|
||||||
|
# which is then replaced by ? for sqlite. Comments can be included
|
||||||
|
# within sql statements using C style /* ... */ comments, BUT
|
||||||
|
# THE COMMENTS MUST NOT INCLUDE %s OR ?.
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
# Standard Library modules
|
# Standard Library modules
|
||||||
|
import re
|
||||||
|
|
||||||
# pyGTK modules
|
# pyGTK modules
|
||||||
|
|
||||||
|
@ -165,12 +171,11 @@ class Sql:
|
||||||
################################
|
################################
|
||||||
# List tables
|
# List tables
|
||||||
################################
|
################################
|
||||||
print "db_server =", db_server
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
self.query['list_tables'] = """SHOW TABLES"""
|
self.query['list_tables'] = """SHOW TABLES"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"""
|
self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['list_tables'] = """SELECT name FROM sqlite_master
|
self.query['list_tables'] = """SELECT name FROM sqlite_master
|
||||||
WHERE type='table'
|
WHERE type='table'
|
||||||
ORDER BY name;"""
|
ORDER BY name;"""
|
||||||
|
@ -189,12 +194,12 @@ class Sql:
|
||||||
self.query['createSettingsTable'] = """CREATE TABLE Settings (
|
self.query['createSettingsTable'] = """CREATE TABLE Settings (
|
||||||
version SMALLINT NOT NULL)
|
version SMALLINT NOT NULL)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)"""
|
self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT NOT NULL)"""
|
||||||
|
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createSettingsTable'] = """CREATE TABLE Settings
|
self.query['createSettingsTable'] = """CREATE TABLE Settings
|
||||||
(version INTEGER) """
|
(version INTEGER NOT NULL) """
|
||||||
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
@ -207,12 +212,12 @@ class Sql:
|
||||||
name varchar(32) NOT NULL,
|
name varchar(32) NOT NULL,
|
||||||
currency char(3) NOT NULL)
|
currency char(3) NOT NULL)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createSitesTable'] = """CREATE TABLE Sites (
|
self.query['createSitesTable'] = """CREATE TABLE Sites (
|
||||||
id SERIAL, PRIMARY KEY (id),
|
id SERIAL, PRIMARY KEY (id),
|
||||||
name varchar(32),
|
name varchar(32),
|
||||||
currency char(3))"""
|
currency char(3))"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createSitesTable'] = """CREATE TABLE Sites (
|
self.query['createSitesTable'] = """CREATE TABLE Sites (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
@ -237,7 +242,7 @@ class Sql:
|
||||||
smallBet int NOT NULL,
|
smallBet int NOT NULL,
|
||||||
bigBet int NOT NULL)
|
bigBet int NOT NULL)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
|
self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
|
||||||
id SERIAL, PRIMARY KEY (id),
|
id SERIAL, PRIMARY KEY (id),
|
||||||
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
||||||
|
@ -250,7 +255,7 @@ class Sql:
|
||||||
bigBlind int,
|
bigBlind int,
|
||||||
smallBet int,
|
smallBet int,
|
||||||
bigBet int)"""
|
bigBet int)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createGametypesTable'] = """CREATE TABLE GameTypes (
|
self.query['createGametypesTable'] = """CREATE TABLE GameTypes (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
siteId INTEGER,
|
siteId INTEGER,
|
||||||
|
@ -278,20 +283,20 @@ class Sql:
|
||||||
comment text,
|
comment text,
|
||||||
commentTs DATETIME)
|
commentTs DATETIME)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createPlayersTable'] = """CREATE TABLE Players (
|
self.query['createPlayersTable'] = """CREATE TABLE Players (
|
||||||
id SERIAL, PRIMARY KEY (id),
|
id SERIAL, PRIMARY KEY (id),
|
||||||
name VARCHAR(32),
|
name VARCHAR(32),
|
||||||
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
||||||
comment text,
|
comment text,
|
||||||
commentTs timestamp without time zone)"""
|
commentTs timestamp without time zone)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createPlayersTable'] = """CREATE TABLE Players (
|
self.query['createPlayersTable'] = """CREATE TABLE Players (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
name TEXT,
|
name TEXT,
|
||||||
siteId INTEGER,
|
siteId INTEGER,
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs BLOB,
|
commentTs REAL,
|
||||||
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
|
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -309,7 +314,7 @@ class Sql:
|
||||||
ratingTime DATETIME NOT NULL,
|
ratingTime DATETIME NOT NULL,
|
||||||
handCount int NOT NULL)
|
handCount int NOT NULL)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
|
self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
|
||||||
id BIGSERIAL, PRIMARY KEY (id),
|
id BIGSERIAL, PRIMARY KEY (id),
|
||||||
playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
|
playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
|
||||||
|
@ -318,8 +323,15 @@ class Sql:
|
||||||
shortDesc char(8),
|
shortDesc char(8),
|
||||||
ratingTime timestamp without time zone,
|
ratingTime timestamp without time zone,
|
||||||
handCount int)"""
|
handCount int)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createAutoratesTable'] = """ """
|
self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
playerId INT,
|
||||||
|
gametypeId INT,
|
||||||
|
description TEXT,
|
||||||
|
shortDesc TEXT,
|
||||||
|
ratingTime REAL,
|
||||||
|
handCount int)"""
|
||||||
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
@ -361,7 +373,7 @@ class Sql:
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs DATETIME)
|
commentTs DATETIME)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createHandsTable'] = """CREATE TABLE Hands (
|
self.query['createHandsTable'] = """CREATE TABLE Hands (
|
||||||
id BIGSERIAL, PRIMARY KEY (id),
|
id BIGSERIAL, PRIMARY KEY (id),
|
||||||
tableName VARCHAR(20) NOT NULL,
|
tableName VARCHAR(20) NOT NULL,
|
||||||
|
@ -395,18 +407,18 @@ class Sql:
|
||||||
showdownPot INT, /* pot size at sd/street7 */
|
showdownPot INT, /* pot size at sd/street7 */
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs timestamp without time zone)"""
|
commentTs timestamp without time zone)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createHandsTable'] = """CREATE TABLE Hands (
|
self.query['createHandsTable'] = """CREATE TABLE Hands (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
tableName TEXT(20),
|
tableName TEXT(20),
|
||||||
siteHandNo INTEGER,
|
siteHandNo INTEGER,
|
||||||
gametypeId INTEGER,
|
gametypeId INTEGER,
|
||||||
handStart BLOB,
|
handStart REAL,
|
||||||
importTime BLOB,
|
importTime REAL,
|
||||||
seats INTEGER,
|
seats INTEGER,
|
||||||
maxSeats INTEGER,
|
maxSeats INTEGER,
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs BLOB,
|
commentTs REAL,
|
||||||
FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)"""
|
FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -423,17 +435,22 @@ class Sql:
|
||||||
knockout INT NOT NULL,
|
knockout INT NOT NULL,
|
||||||
rebuyOrAddon BOOLEAN NOT NULL)
|
rebuyOrAddon BOOLEAN NOT NULL)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
|
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
|
||||||
id SERIAL, PRIMARY KEY (id),
|
id SERIAL, PRIMARY KEY (id),
|
||||||
siteId INT, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
siteId INT NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
||||||
buyin INT,
|
buyin INT NOT NULL,
|
||||||
fee INT,
|
fee INT NOT NULL,
|
||||||
knockout INT,
|
knockout INT NOT NULL,
|
||||||
rebuyOrAddon BOOLEAN)"""
|
rebuyOrAddon BOOLEAN NOT NULL)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createTourneyTypesTable'] = """ """
|
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
siteId INT NOT NULL,
|
||||||
|
buyin INT NOT NULL,
|
||||||
|
fee INT NOT NULL,
|
||||||
|
knockout INT NOT NULL,
|
||||||
|
rebuyOrAddon BOOLEAN NOT NULL)"""
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# Create Tourneys
|
# Create Tourneys
|
||||||
|
@ -450,7 +467,7 @@ class Sql:
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs DATETIME)
|
commentTs DATETIME)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
|
self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
|
||||||
id SERIAL, PRIMARY KEY (id),
|
id SERIAL, PRIMARY KEY (id),
|
||||||
tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
||||||
|
@ -460,16 +477,16 @@ class Sql:
|
||||||
startTime timestamp without time zone,
|
startTime timestamp without time zone,
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs timestamp without time zone)"""
|
commentTs timestamp without time zone)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createTourneysTable'] = """CREATE TABLE TourneyTypes (
|
self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
siteId INTEGER,
|
tourneyTypeId INT,
|
||||||
buyin INTEGER,
|
siteTourneyNo INT,
|
||||||
fee INTEGER,
|
entries INT,
|
||||||
knockout INTEGER,
|
prizepool INT,
|
||||||
rebuyOrAddon BOOL,
|
startTime REAL,
|
||||||
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
|
comment TEXT,
|
||||||
|
commentTs REAL)"""
|
||||||
################################
|
################################
|
||||||
# Create HandsPlayers
|
# Create HandsPlayers
|
||||||
################################
|
################################
|
||||||
|
@ -495,82 +512,82 @@ class Sql:
|
||||||
ante INT,
|
ante INT,
|
||||||
winnings int NOT NULL,
|
winnings int NOT NULL,
|
||||||
rake int NOT NULL,
|
rake int NOT NULL,
|
||||||
totalProfit INT NOT NULL,
|
totalProfit INT,
|
||||||
comment text,
|
comment text,
|
||||||
commentTs DATETIME,
|
commentTs DATETIME,
|
||||||
tourneysPlayersId BIGINT UNSIGNED,
|
tourneysPlayersId BIGINT UNSIGNED,
|
||||||
tourneyTypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
tourneyTypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
||||||
|
|
||||||
wonWhenSeenStreet1 FLOAT NOT NULL,
|
wonWhenSeenStreet1 FLOAT,
|
||||||
wonWhenSeenStreet2 FLOAT,
|
wonWhenSeenStreet2 FLOAT,
|
||||||
wonWhenSeenStreet3 FLOAT,
|
wonWhenSeenStreet3 FLOAT,
|
||||||
wonWhenSeenStreet4 FLOAT,
|
wonWhenSeenStreet4 FLOAT,
|
||||||
wonAtSD FLOAT NOT NULL,
|
wonAtSD FLOAT,
|
||||||
|
|
||||||
street0VPI BOOLEAN NOT NULL,
|
street0VPI BOOLEAN,
|
||||||
street0Aggr BOOLEAN NOT NULL,
|
street0Aggr BOOLEAN,
|
||||||
street0_3BChance BOOLEAN NOT NULL,
|
street0_3BChance BOOLEAN,
|
||||||
street0_3BDone BOOLEAN NOT NULL,
|
street0_3BDone BOOLEAN,
|
||||||
street0_4BChance BOOLEAN,
|
street0_4BChance BOOLEAN,
|
||||||
street0_4BDone BOOLEAN,
|
street0_4BDone BOOLEAN,
|
||||||
other3BStreet0 BOOLEAN,
|
other3BStreet0 BOOLEAN,
|
||||||
other4BStreet0 BOOLEAN,
|
other4BStreet0 BOOLEAN,
|
||||||
|
|
||||||
street1Seen BOOLEAN NOT NULL,
|
street1Seen BOOLEAN,
|
||||||
street2Seen BOOLEAN NOT NULL,
|
street2Seen BOOLEAN,
|
||||||
street3Seen BOOLEAN NOT NULL,
|
street3Seen BOOLEAN,
|
||||||
street4Seen BOOLEAN NOT NULL,
|
street4Seen BOOLEAN,
|
||||||
sawShowdown BOOLEAN NOT NULL,
|
sawShowdown BOOLEAN,
|
||||||
|
|
||||||
street1Aggr BOOLEAN NOT NULL,
|
street1Aggr BOOLEAN,
|
||||||
street2Aggr BOOLEAN NOT NULL,
|
street2Aggr BOOLEAN,
|
||||||
street3Aggr BOOLEAN NOT NULL,
|
street3Aggr BOOLEAN,
|
||||||
street4Aggr BOOLEAN NOT NULL,
|
street4Aggr BOOLEAN,
|
||||||
|
|
||||||
otherRaisedStreet0 BOOLEAN,
|
otherRaisedStreet0 BOOLEAN,
|
||||||
otherRaisedStreet1 BOOLEAN NOT NULL,
|
otherRaisedStreet1 BOOLEAN,
|
||||||
otherRaisedStreet2 BOOLEAN NOT NULL,
|
otherRaisedStreet2 BOOLEAN,
|
||||||
otherRaisedStreet3 BOOLEAN NOT NULL,
|
otherRaisedStreet3 BOOLEAN,
|
||||||
otherRaisedStreet4 BOOLEAN NOT NULL,
|
otherRaisedStreet4 BOOLEAN,
|
||||||
foldToOtherRaisedStreet0 BOOLEAN,
|
foldToOtherRaisedStreet0 BOOLEAN,
|
||||||
foldToOtherRaisedStreet1 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet1 BOOLEAN,
|
||||||
foldToOtherRaisedStreet2 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet2 BOOLEAN,
|
||||||
foldToOtherRaisedStreet3 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet3 BOOLEAN,
|
||||||
foldToOtherRaisedStreet4 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet4 BOOLEAN,
|
||||||
|
|
||||||
stealAttemptChance BOOLEAN NOT NULL,
|
stealAttemptChance BOOLEAN,
|
||||||
stealAttempted BOOLEAN NOT NULL,
|
stealAttempted BOOLEAN,
|
||||||
foldBbToStealChance BOOLEAN NOT NULL,
|
foldBbToStealChance BOOLEAN,
|
||||||
foldedBbToSteal BOOLEAN NOT NULL,
|
foldedBbToSteal BOOLEAN,
|
||||||
foldSbToStealChance BOOLEAN NOT NULL,
|
foldSbToStealChance BOOLEAN,
|
||||||
foldedSbToSteal BOOLEAN NOT NULL,
|
foldedSbToSteal BOOLEAN,
|
||||||
|
|
||||||
street1CBChance BOOLEAN NOT NULL,
|
street1CBChance BOOLEAN,
|
||||||
street1CBDone BOOLEAN NOT NULL,
|
street1CBDone BOOLEAN,
|
||||||
street2CBChance BOOLEAN NOT NULL,
|
street2CBChance BOOLEAN,
|
||||||
street2CBDone BOOLEAN NOT NULL,
|
street2CBDone BOOLEAN,
|
||||||
street3CBChance BOOLEAN NOT NULL,
|
street3CBChance BOOLEAN,
|
||||||
street3CBDone BOOLEAN NOT NULL,
|
street3CBDone BOOLEAN,
|
||||||
street4CBChance BOOLEAN NOT NULL,
|
street4CBChance BOOLEAN,
|
||||||
street4CBDone BOOLEAN NOT NULL,
|
street4CBDone BOOLEAN,
|
||||||
|
|
||||||
foldToStreet1CBChance BOOLEAN NOT NULL,
|
foldToStreet1CBChance BOOLEAN,
|
||||||
foldToStreet1CBDone BOOLEAN NOT NULL,
|
foldToStreet1CBDone BOOLEAN,
|
||||||
foldToStreet2CBChance BOOLEAN NOT NULL,
|
foldToStreet2CBChance BOOLEAN,
|
||||||
foldToStreet2CBDone BOOLEAN NOT NULL,
|
foldToStreet2CBDone BOOLEAN,
|
||||||
foldToStreet3CBChance BOOLEAN NOT NULL,
|
foldToStreet3CBChance BOOLEAN,
|
||||||
foldToStreet3CBDone BOOLEAN NOT NULL,
|
foldToStreet3CBDone BOOLEAN,
|
||||||
foldToStreet4CBChance BOOLEAN NOT NULL,
|
foldToStreet4CBChance BOOLEAN,
|
||||||
foldToStreet4CBDone BOOLEAN NOT NULL,
|
foldToStreet4CBDone BOOLEAN,
|
||||||
|
|
||||||
street1CheckCallRaiseChance BOOLEAN NOT NULL,
|
street1CheckCallRaiseChance BOOLEAN,
|
||||||
street1CheckCallRaiseDone BOOLEAN NOT NULL,
|
street1CheckCallRaiseDone BOOLEAN,
|
||||||
street2CheckCallRaiseChance BOOLEAN NOT NULL,
|
street2CheckCallRaiseChance BOOLEAN,
|
||||||
street2CheckCallRaiseDone BOOLEAN NOT NULL,
|
street2CheckCallRaiseDone BOOLEAN,
|
||||||
street3CheckCallRaiseChance BOOLEAN NOT NULL,
|
street3CheckCallRaiseChance BOOLEAN,
|
||||||
street3CheckCallRaiseDone BOOLEAN NOT NULL,
|
street3CheckCallRaiseDone BOOLEAN,
|
||||||
street4CheckCallRaiseChance BOOLEAN NOT NULL,
|
street4CheckCallRaiseChance BOOLEAN,
|
||||||
street4CheckCallRaiseDone BOOLEAN NOT NULL,
|
street4CheckCallRaiseDone BOOLEAN,
|
||||||
|
|
||||||
street0Calls TINYINT,
|
street0Calls TINYINT,
|
||||||
street1Calls TINYINT,
|
street1Calls TINYINT,
|
||||||
|
@ -592,7 +609,7 @@ class Sql:
|
||||||
|
|
||||||
FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))
|
FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
|
self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
|
||||||
id BIGSERIAL, PRIMARY KEY (id),
|
id BIGSERIAL, PRIMARY KEY (id),
|
||||||
handId BIGINT NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
|
handId BIGINT NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
|
||||||
|
@ -613,82 +630,82 @@ class Sql:
|
||||||
ante INT,
|
ante INT,
|
||||||
winnings int NOT NULL,
|
winnings int NOT NULL,
|
||||||
rake int NOT NULL,
|
rake int NOT NULL,
|
||||||
totalProfit INT NOT NULL,
|
totalProfit INT,
|
||||||
comment text,
|
comment text,
|
||||||
commentTs timestamp without time zone,
|
commentTs timestamp without time zone,
|
||||||
tourneysPlayersId BIGINT,
|
tourneysPlayersId BIGINT,
|
||||||
tourneyTypeId INT NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
tourneyTypeId INT NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
|
||||||
|
|
||||||
wonWhenSeenStreet1 FLOAT NOT NULL,
|
wonWhenSeenStreet1 FLOAT,
|
||||||
wonWhenSeenStreet2 FLOAT,
|
wonWhenSeenStreet2 FLOAT,
|
||||||
wonWhenSeenStreet3 FLOAT,
|
wonWhenSeenStreet3 FLOAT,
|
||||||
wonWhenSeenStreet4 FLOAT,
|
wonWhenSeenStreet4 FLOAT,
|
||||||
wonAtSD FLOAT NOT NULL,
|
wonAtSD FLOAT,
|
||||||
|
|
||||||
street0VPI BOOLEAN NOT NULL,
|
street0VPI BOOLEAN,
|
||||||
street0Aggr BOOLEAN NOT NULL,
|
street0Aggr BOOLEAN,
|
||||||
street0_3BChance BOOLEAN NOT NULL,
|
street0_3BChance BOOLEAN,
|
||||||
street0_3BDone BOOLEAN NOT NULL,
|
street0_3BDone BOOLEAN,
|
||||||
street0_4BChance BOOLEAN,
|
street0_4BChance BOOLEAN,
|
||||||
street0_4BDone BOOLEAN,
|
street0_4BDone BOOLEAN,
|
||||||
other3BStreet0 BOOLEAN,
|
other3BStreet0 BOOLEAN,
|
||||||
other4BStreet0 BOOLEAN,
|
other4BStreet0 BOOLEAN,
|
||||||
|
|
||||||
street1Seen BOOLEAN NOT NULL,
|
street1Seen BOOLEAN,
|
||||||
street2Seen BOOLEAN NOT NULL,
|
street2Seen BOOLEAN,
|
||||||
street3Seen BOOLEAN NOT NULL,
|
street3Seen BOOLEAN,
|
||||||
street4Seen BOOLEAN NOT NULL,
|
street4Seen BOOLEAN,
|
||||||
sawShowdown BOOLEAN NOT NULL,
|
sawShowdown BOOLEAN,
|
||||||
|
|
||||||
street1Aggr BOOLEAN NOT NULL,
|
street1Aggr BOOLEAN,
|
||||||
street2Aggr BOOLEAN NOT NULL,
|
street2Aggr BOOLEAN,
|
||||||
street3Aggr BOOLEAN NOT NULL,
|
street3Aggr BOOLEAN,
|
||||||
street4Aggr BOOLEAN NOT NULL,
|
street4Aggr BOOLEAN,
|
||||||
|
|
||||||
otherRaisedStreet0 BOOLEAN,
|
otherRaisedStreet0 BOOLEAN,
|
||||||
otherRaisedStreet1 BOOLEAN NOT NULL,
|
otherRaisedStreet1 BOOLEAN,
|
||||||
otherRaisedStreet2 BOOLEAN NOT NULL,
|
otherRaisedStreet2 BOOLEAN,
|
||||||
otherRaisedStreet3 BOOLEAN NOT NULL,
|
otherRaisedStreet3 BOOLEAN,
|
||||||
otherRaisedStreet4 BOOLEAN NOT NULL,
|
otherRaisedStreet4 BOOLEAN,
|
||||||
foldToOtherRaisedStreet0 BOOLEAN,
|
foldToOtherRaisedStreet0 BOOLEAN,
|
||||||
foldToOtherRaisedStreet1 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet1 BOOLEAN,
|
||||||
foldToOtherRaisedStreet2 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet2 BOOLEAN,
|
||||||
foldToOtherRaisedStreet3 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet3 BOOLEAN,
|
||||||
foldToOtherRaisedStreet4 BOOLEAN NOT NULL,
|
foldToOtherRaisedStreet4 BOOLEAN,
|
||||||
|
|
||||||
stealAttemptChance BOOLEAN NOT NULL,
|
stealAttemptChance BOOLEAN,
|
||||||
stealAttempted BOOLEAN NOT NULL,
|
stealAttempted BOOLEAN,
|
||||||
foldBbToStealChance BOOLEAN NOT NULL,
|
foldBbToStealChance BOOLEAN,
|
||||||
foldedBbToSteal BOOLEAN NOT NULL,
|
foldedBbToSteal BOOLEAN,
|
||||||
foldSbToStealChance BOOLEAN NOT NULL,
|
foldSbToStealChance BOOLEAN,
|
||||||
foldedSbToSteal BOOLEAN NOT NULL,
|
foldedSbToSteal BOOLEAN,
|
||||||
|
|
||||||
street1CBChance BOOLEAN NOT NULL,
|
street1CBChance BOOLEAN,
|
||||||
street1CBDone BOOLEAN NOT NULL,
|
street1CBDone BOOLEAN,
|
||||||
street2CBChance BOOLEAN NOT NULL,
|
street2CBChance BOOLEAN,
|
||||||
street2CBDone BOOLEAN NOT NULL,
|
street2CBDone BOOLEAN,
|
||||||
street3CBChance BOOLEAN NOT NULL,
|
street3CBChance BOOLEAN,
|
||||||
street3CBDone BOOLEAN NOT NULL,
|
street3CBDone BOOLEAN,
|
||||||
street4CBChance BOOLEAN NOT NULL,
|
street4CBChance BOOLEAN,
|
||||||
street4CBDone BOOLEAN NOT NULL,
|
street4CBDone BOOLEAN,
|
||||||
|
|
||||||
foldToStreet1CBChance BOOLEAN NOT NULL,
|
foldToStreet1CBChance BOOLEAN,
|
||||||
foldToStreet1CBDone BOOLEAN NOT NULL,
|
foldToStreet1CBDone BOOLEAN,
|
||||||
foldToStreet2CBChance BOOLEAN NOT NULL,
|
foldToStreet2CBChance BOOLEAN,
|
||||||
foldToStreet2CBDone BOOLEAN NOT NULL,
|
foldToStreet2CBDone BOOLEAN,
|
||||||
foldToStreet3CBChance BOOLEAN NOT NULL,
|
foldToStreet3CBChance BOOLEAN,
|
||||||
foldToStreet3CBDone BOOLEAN NOT NULL,
|
foldToStreet3CBDone BOOLEAN,
|
||||||
foldToStreet4CBChance BOOLEAN NOT NULL,
|
foldToStreet4CBChance BOOLEAN,
|
||||||
foldToStreet4CBDone BOOLEAN NOT NULL,
|
foldToStreet4CBDone BOOLEAN,
|
||||||
|
|
||||||
street1CheckCallRaiseChance BOOLEAN NOT NULL,
|
street1CheckCallRaiseChance BOOLEAN,
|
||||||
street1CheckCallRaiseDone BOOLEAN NOT NULL,
|
street1CheckCallRaiseDone BOOLEAN,
|
||||||
street2CheckCallRaiseChance BOOLEAN NOT NULL,
|
street2CheckCallRaiseChance BOOLEAN,
|
||||||
street2CheckCallRaiseDone BOOLEAN NOT NULL,
|
street2CheckCallRaiseDone BOOLEAN,
|
||||||
street3CheckCallRaiseChance BOOLEAN NOT NULL,
|
street3CheckCallRaiseChance BOOLEAN,
|
||||||
street3CheckCallRaiseDone BOOLEAN NOT NULL,
|
street3CheckCallRaiseDone BOOLEAN,
|
||||||
street4CheckCallRaiseChance BOOLEAN NOT NULL,
|
street4CheckCallRaiseChance BOOLEAN,
|
||||||
street4CheckCallRaiseDone BOOLEAN NOT NULL,
|
street4CheckCallRaiseDone BOOLEAN,
|
||||||
|
|
||||||
street0Calls SMALLINT,
|
street0Calls SMALLINT,
|
||||||
street1Calls SMALLINT,
|
street1Calls SMALLINT,
|
||||||
|
@ -709,8 +726,122 @@ class Sql:
|
||||||
actionString VARCHAR(15),
|
actionString VARCHAR(15),
|
||||||
|
|
||||||
FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))"""
|
FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createHandsPlayersTable'] = """ """
|
self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
handId INT NOT NULL,
|
||||||
|
playerId INT NOT NULL,
|
||||||
|
startCash INT NOT NULL,
|
||||||
|
position TEXT,
|
||||||
|
seatNo INT NOT NULL,
|
||||||
|
|
||||||
|
card1 INT NOT NULL, /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */
|
||||||
|
card2 INT NOT NULL,
|
||||||
|
card3 INT,
|
||||||
|
card4 INT,
|
||||||
|
card5 INT,
|
||||||
|
card6 INT,
|
||||||
|
card7 INT,
|
||||||
|
startCards INT,
|
||||||
|
|
||||||
|
ante INT,
|
||||||
|
winnings INT NOT NULL,
|
||||||
|
rake INT NOT NULL,
|
||||||
|
totalProfit INT,
|
||||||
|
comment TEXT,
|
||||||
|
commentTs REAL,
|
||||||
|
tourneysPlayersId INT,
|
||||||
|
tourneyTypeId INT NOT NULL,
|
||||||
|
|
||||||
|
wonWhenSeenStreet1 REAL,
|
||||||
|
wonWhenSeenStreet2 REAL,
|
||||||
|
wonWhenSeenStreet3 REAL,
|
||||||
|
wonWhenSeenStreet4 REAL,
|
||||||
|
wonAtSD REAL,
|
||||||
|
|
||||||
|
street0VPI INT,
|
||||||
|
street0Aggr INT,
|
||||||
|
street0_3BChance INT,
|
||||||
|
street0_3BDone INT,
|
||||||
|
street0_4BChance INT,
|
||||||
|
street0_4BDone INT,
|
||||||
|
other3BStreet0 INT,
|
||||||
|
other4BStreet0 INT,
|
||||||
|
|
||||||
|
street1Seen INT,
|
||||||
|
street2Seen INT,
|
||||||
|
street3Seen INT,
|
||||||
|
street4Seen INT,
|
||||||
|
sawShowdown INT,
|
||||||
|
|
||||||
|
street1Aggr INT,
|
||||||
|
street2Aggr INT,
|
||||||
|
street3Aggr INT,
|
||||||
|
street4Aggr INT,
|
||||||
|
|
||||||
|
otherRaisedStreet0 INT,
|
||||||
|
otherRaisedStreet1 INT,
|
||||||
|
otherRaisedStreet2 INT,
|
||||||
|
otherRaisedStreet3 INT,
|
||||||
|
otherRaisedStreet4 INT,
|
||||||
|
foldToOtherRaisedStreet0 INT,
|
||||||
|
foldToOtherRaisedStreet1 INT,
|
||||||
|
foldToOtherRaisedStreet2 INT,
|
||||||
|
foldToOtherRaisedStreet3 INT,
|
||||||
|
foldToOtherRaisedStreet4 INT,
|
||||||
|
|
||||||
|
stealAttemptChance INT,
|
||||||
|
stealAttempted INT,
|
||||||
|
foldBbToStealChance INT,
|
||||||
|
foldedBbToSteal INT,
|
||||||
|
foldSbToStealChance INT,
|
||||||
|
foldedSbToSteal INT,
|
||||||
|
|
||||||
|
street1CBChance INT,
|
||||||
|
street1CBDone INT,
|
||||||
|
street2CBChance INT,
|
||||||
|
street2CBDone INT,
|
||||||
|
street3CBChance INT,
|
||||||
|
street3CBDone INT,
|
||||||
|
street4CBChance INT,
|
||||||
|
street4CBDone INT,
|
||||||
|
|
||||||
|
foldToStreet1CBChance INT,
|
||||||
|
foldToStreet1CBDone INT,
|
||||||
|
foldToStreet2CBChance INT,
|
||||||
|
foldToStreet2CBDone INT,
|
||||||
|
foldToStreet3CBChance INT,
|
||||||
|
foldToStreet3CBDone INT,
|
||||||
|
foldToStreet4CBChance INT,
|
||||||
|
foldToStreet4CBDone INT,
|
||||||
|
|
||||||
|
street1CheckCallRaiseChance INT,
|
||||||
|
street1CheckCallRaiseDone INT,
|
||||||
|
street2CheckCallRaiseChance INT,
|
||||||
|
street2CheckCallRaiseDone INT,
|
||||||
|
street3CheckCallRaiseChance INT,
|
||||||
|
street3CheckCallRaiseDone INT,
|
||||||
|
street4CheckCallRaiseChance INT,
|
||||||
|
street4CheckCallRaiseDone INT,
|
||||||
|
|
||||||
|
street0Calls INT,
|
||||||
|
street1Calls INT,
|
||||||
|
street2Calls INT,
|
||||||
|
street3Calls INT,
|
||||||
|
street4Calls INT,
|
||||||
|
street0Bets INT,
|
||||||
|
street1Bets INT,
|
||||||
|
street2Bets INT,
|
||||||
|
street3Bets INT,
|
||||||
|
street4Bets INT,
|
||||||
|
street0Raises INT,
|
||||||
|
street1Raises INT,
|
||||||
|
street2Raises INT,
|
||||||
|
street3Raises INT,
|
||||||
|
street4Raises INT,
|
||||||
|
|
||||||
|
actionString REAL)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
@ -728,7 +859,7 @@ class Sql:
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs DATETIME)
|
commentTs DATETIME)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
|
self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
|
||||||
id BIGSERIAL, PRIMARY KEY (id),
|
id BIGSERIAL, PRIMARY KEY (id),
|
||||||
tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
|
tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
|
||||||
|
@ -738,7 +869,7 @@ class Sql:
|
||||||
winnings INT,
|
winnings INT,
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs timestamp without time zone)"""
|
commentTs timestamp without time zone)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createTourneysPlayersTable'] = """ """
|
self.query['createTourneysPlayersTable'] = """ """
|
||||||
|
|
||||||
|
|
||||||
|
@ -758,7 +889,7 @@ class Sql:
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs DATETIME)
|
commentTs DATETIME)
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
|
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
|
||||||
id BIGSERIAL, PRIMARY KEY (id),
|
id BIGSERIAL, PRIMARY KEY (id),
|
||||||
handsPlayerId BIGINT, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id),
|
handsPlayerId BIGINT, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id),
|
||||||
|
@ -769,7 +900,7 @@ class Sql:
|
||||||
amount INT,
|
amount INT,
|
||||||
comment TEXT,
|
comment TEXT,
|
||||||
commentTs timestamp without time zone)"""
|
commentTs timestamp without time zone)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createHandsActionsTable'] = """ """
|
self.query['createHandsActionsTable'] = """ """
|
||||||
|
|
||||||
|
|
||||||
|
@ -878,7 +1009,7 @@ class Sql:
|
||||||
street4Raises INT)
|
street4Raises INT)
|
||||||
|
|
||||||
ENGINE=INNODB"""
|
ENGINE=INNODB"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
|
self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
|
||||||
id BIGSERIAL, PRIMARY KEY (id),
|
id BIGSERIAL, PRIMARY KEY (id),
|
||||||
gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
|
gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
|
||||||
|
@ -977,37 +1108,136 @@ class Sql:
|
||||||
street3Raises INT,
|
street3Raises INT,
|
||||||
street4Raises INT)
|
street4Raises INT)
|
||||||
"""
|
"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['createHudCacheTable'] = """ """
|
self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
gametypeId INT,
|
||||||
|
playerId INT,
|
||||||
|
activeSeats INT,
|
||||||
|
position TEXT,
|
||||||
|
tourneyTypeId INT,
|
||||||
|
styleKey TEXT NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
|
||||||
|
HDs INT,
|
||||||
|
|
||||||
|
wonWhenSeenStreet1 REAL NOT NULL,
|
||||||
|
wonWhenSeenStreet2 REAL,
|
||||||
|
wonWhenSeenStreet3 REAL,
|
||||||
|
wonWhenSeenStreet4 REAL,
|
||||||
|
wonAtSD REAL NOT NULL,
|
||||||
|
|
||||||
|
street0VPI INT NOT NULL,
|
||||||
|
street0Aggr INT,
|
||||||
|
street0_3BChance INT NOT NULL,
|
||||||
|
street0_3BDone INT NOT NULL,
|
||||||
|
street0_4BChance INT,
|
||||||
|
street0_4BDone INT,
|
||||||
|
other3BStreet0 INT,
|
||||||
|
other4BStreet0 INT,
|
||||||
|
|
||||||
|
street1Seen INT,
|
||||||
|
street2Seen INT,
|
||||||
|
street3Seen INT,
|
||||||
|
street4Seen INT,
|
||||||
|
sawShowdown INT,
|
||||||
|
street1Aggr INT,
|
||||||
|
street2Aggr INT,
|
||||||
|
street3Aggr INT,
|
||||||
|
street4Aggr INT,
|
||||||
|
|
||||||
|
otherRaisedStreet0 INT,
|
||||||
|
otherRaisedStreet1 INT,
|
||||||
|
otherRaisedStreet2 INT,
|
||||||
|
otherRaisedStreet3 INT,
|
||||||
|
otherRaisedStreet4 INT,
|
||||||
|
foldToOtherRaisedStreet0 INT,
|
||||||
|
foldToOtherRaisedStreet1 INT,
|
||||||
|
foldToOtherRaisedStreet2 INT,
|
||||||
|
foldToOtherRaisedStreet3 INT,
|
||||||
|
foldToOtherRaisedStreet4 INT,
|
||||||
|
|
||||||
|
stealAttemptChance INT,
|
||||||
|
stealAttempted INT,
|
||||||
|
foldBbToStealChance INT,
|
||||||
|
foldedBbToSteal INT,
|
||||||
|
foldSbToStealChance INT,
|
||||||
|
foldedSbToSteal INT,
|
||||||
|
|
||||||
|
street1CBChance INT,
|
||||||
|
street1CBDone INT,
|
||||||
|
street2CBChance INT,
|
||||||
|
street2CBDone INT,
|
||||||
|
street3CBChance INT,
|
||||||
|
street3CBDone INT,
|
||||||
|
street4CBChance INT,
|
||||||
|
street4CBDone INT,
|
||||||
|
|
||||||
|
foldToStreet1CBChance INT,
|
||||||
|
foldToStreet1CBDone INT,
|
||||||
|
foldToStreet2CBChance INT,
|
||||||
|
foldToStreet2CBDone INT,
|
||||||
|
foldToStreet3CBChance INT,
|
||||||
|
foldToStreet3CBDone INT,
|
||||||
|
foldToStreet4CBChance INT,
|
||||||
|
foldToStreet4CBDone INT,
|
||||||
|
|
||||||
|
totalProfit INT,
|
||||||
|
|
||||||
|
street1CheckCallRaiseChance INT,
|
||||||
|
street1CheckCallRaiseDone INT,
|
||||||
|
street2CheckCallRaiseChance INT,
|
||||||
|
street2CheckCallRaiseDone INT,
|
||||||
|
street3CheckCallRaiseChance INT,
|
||||||
|
street3CheckCallRaiseDone INT,
|
||||||
|
street4CheckCallRaiseChance INT,
|
||||||
|
street4CheckCallRaiseDone INT,
|
||||||
|
|
||||||
|
street0Calls INT,
|
||||||
|
street1Calls INT,
|
||||||
|
street2Calls INT,
|
||||||
|
street3Calls INT,
|
||||||
|
street4Calls INT,
|
||||||
|
street0Bets INT,
|
||||||
|
street1Bets INT,
|
||||||
|
street2Bets INT,
|
||||||
|
street3Bets INT,
|
||||||
|
street4Bets INT,
|
||||||
|
street0Raises INT,
|
||||||
|
street1Raises INT,
|
||||||
|
street2Raises INT,
|
||||||
|
street3Raises INT,
|
||||||
|
street4Raises INT)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
|
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['addTourneyIndex'] = """CREATE INDEX siteTourneyNo ON Tourneys (siteTourneyNo)"""
|
self.query['addTourneyIndex'] = """CREATE INDEX siteTourneyNo ON Tourneys (siteTourneyNo)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['addHandsIndex'] = """ """
|
self.query['addHandsIndex'] = """ """
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
|
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['addHandsIndex'] = """CREATE INDEX siteHandNo ON Hands (siteHandNo)"""
|
self.query['addHandsIndex'] = """CREATE INDEX siteHandNo ON Hands (siteHandNo)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['addHandsIndex'] = """ """
|
self.query['addHandsIndex'] = """ """
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)"""
|
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)"""
|
||||||
elif db_server == 'postgresql': # what is the correct value here?
|
elif db_server == 'postgresql':
|
||||||
self.query['addPlayersIndex'] = """CREATE INDEX name ON Players (name)"""
|
self.query['addPlayersIndex'] = """CREATE INDEX name ON Players (name)"""
|
||||||
elif db_server == 'sqlite': # what is the correct value here?
|
elif db_server == 'sqlite':
|
||||||
self.query['addPlayersIndex'] = """ """
|
self.query['addPlayersIndex'] = """ """
|
||||||
|
|
||||||
|
|
||||||
self.query['get_last_hand'] = "select max(id) from Hands"
|
self.query['get_last_hand'] = "select max(id) from Hands"
|
||||||
|
|
||||||
self.query['get_player_id'] = """
|
self.query['get_player_id'] = """
|
||||||
select Players.id AS player_id from Players, Sites
|
select Players.id AS player_id
|
||||||
where Players.name = %(player)s
|
from Players, Sites
|
||||||
and Sites.name = %(site)s
|
where Players.name = %s
|
||||||
|
and Sites.name = %s
|
||||||
and Players.SiteId = Sites.id
|
and Players.SiteId = Sites.id
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1074,7 +1304,7 @@ class Sql:
|
||||||
sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4,
|
sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4,
|
||||||
sum(hc.street4CheckCallRaiseDone) AS ccr_4
|
sum(hc.street4CheckCallRaiseDone) AS ccr_4
|
||||||
FROM Hands h
|
FROM Hands h
|
||||||
INNER JOIN HandsPlayers hp ON (hp.handId = %s)
|
INNER JOIN HandsPlayers hp ON (hp.handId = h.id)
|
||||||
INNER JOIN HudCache hc ON ( hc.PlayerId = hp.PlayerId+0
|
INNER JOIN HudCache hc ON ( hc.PlayerId = hp.PlayerId+0
|
||||||
AND hc.gametypeId+0 = h.gametypeId+0)
|
AND hc.gametypeId+0 = h.gametypeId+0)
|
||||||
INNER JOIN Players p ON (p.id = hp.PlayerId+0)
|
INNER JOIN Players p ON (p.id = hp.PlayerId+0)
|
||||||
|
@ -1082,7 +1312,7 @@ class Sql:
|
||||||
AND hc.styleKey > %s
|
AND hc.styleKey > %s
|
||||||
/* styleKey is currently 'd' (for date) followed by a yyyymmdd
|
/* styleKey is currently 'd' (for date) followed by a yyyymmdd
|
||||||
date key. Set it to 0000000 or similar to get all records */
|
date key. Set it to 0000000 or similar to get all records */
|
||||||
/* also check activeseats here? even if only 3 groups eg 2-3/4-6/7+ ??
|
/* also check activeseats here even if only 3 groups eg 2-3/4-6/7+
|
||||||
e.g. could use a multiplier:
|
e.g. could use a multiplier:
|
||||||
AND h.seats > X / 1.25 and hp.seats < X * 1.25
|
AND h.seats > X / 1.25 and hp.seats < X * 1.25
|
||||||
where X is the number of active players at the current table (and
|
where X is the number of active players at the current table (and
|
||||||
|
@ -1156,27 +1386,31 @@ class Sql:
|
||||||
sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4,
|
sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4,
|
||||||
sum(hc.street4CheckCallRaiseDone) AS ccr_4
|
sum(hc.street4CheckCallRaiseDone) AS ccr_4
|
||||||
FROM Hands h
|
FROM Hands h
|
||||||
INNER JOIN HandsPlayers hp ON (hp.handId = %s)
|
INNER JOIN HandsPlayers hp ON (hp.handId = h.id)
|
||||||
INNER JOIN HudCache hc ON (hc.playerId = hp.playerId)
|
INNER JOIN HudCache hc ON (hc.playerId = hp.playerId)
|
||||||
INNER JOIN Players p ON (p.id = hc.playerId)
|
INNER JOIN Players p ON (p.id = hc.playerId)
|
||||||
WHERE h.id = %s
|
WHERE h.id = %s
|
||||||
AND hc.styleKey > %s
|
AND hc.styleKey > %s
|
||||||
/* styleKey is currently 'd' (for date) followed by a yyyymmdd
|
/* styleKey is currently 'd' (for date) followed by a yyyymmdd
|
||||||
date key. Set it to 0000000 or similar to get all records */
|
date key. Set it to 0000000 or similar to get all records */
|
||||||
/* also check activeseats here? even if only 3 groups eg 2-3/4-6/7+ ??
|
/* 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:
|
e.g. could use a multiplier:
|
||||||
AND h.seats > %s / 1.25 and hp.seats < %s * 1.25
|
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
|
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)
|
1.25 would be a config value so user could change it)
|
||||||
*/
|
*/
|
||||||
AND hc.gametypeId+0 in
|
AND hc.gametypeId+0 in
|
||||||
(SELECT gt1.id from Gametypes gt1, Gametypes gt2
|
(SELECT gt1.id from Gametypes gt1, Gametypes gt2
|
||||||
WHERE gt1.siteid = gt2.siteid
|
WHERE gt1.siteid = gt2.siteid /* find gametypes where these match: */
|
||||||
AND gt1.type = gt2.type
|
AND gt1.type = gt2.type /* ring/tourney */
|
||||||
AND gt1.category = gt2.category
|
AND gt1.category = gt2.category /* holdem/stud*/
|
||||||
AND gt1.limittype = gt2.limittype
|
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 gt2.id = h.gametypeId)
|
||||||
GROUP BY hc.PlayerId, p.name, hc.styleKey
|
GROUP BY hc.PlayerId, p.name
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
|
@ -1249,7 +1483,7 @@ class Sql:
|
||||||
INNER JOIN HandsPlayers hp2 ON (hp2.playerId+0 = hp.playerId+0 AND (hp2.handId = h2.id+0)) /* other hands by these players */
|
INNER JOIN HandsPlayers hp2 ON (hp2.playerId+0 = hp.playerId+0 AND (hp2.handId = h2.id+0)) /* other hands by these players */
|
||||||
INNER JOIN Players p ON (p.id = hp2.PlayerId+0)
|
INNER JOIN Players p ON (p.id = hp2.PlayerId+0)
|
||||||
WHERE hp.handId = %s
|
WHERE hp.handId = %s
|
||||||
/* check activeseats once this data returned? (don't want to do that here as it might
|
/* check activeseats once this data returned (don't want to do that here as it might
|
||||||
assume a session ended just because the number of seats dipped for a few hands)
|
assume a session ended just because the number of seats dipped for a few hands)
|
||||||
*/
|
*/
|
||||||
ORDER BY h.handStart desc, hp2.PlayerId
|
ORDER BY h.handStart desc, hp2.PlayerId
|
||||||
|
@ -1328,7 +1562,7 @@ class Sql:
|
||||||
AND hp2.handId = h2.id) /* other hands by these players */
|
AND hp2.handId = h2.id) /* other hands by these players */
|
||||||
INNER JOIN Players p ON (p.id = hp2.PlayerId+0)
|
INNER JOIN Players p ON (p.id = hp2.PlayerId+0)
|
||||||
WHERE h.id = %s
|
WHERE h.id = %s
|
||||||
/* check activeseats once this data returned? (don't want to do that here as it might
|
/* check activeseats once this data returned (don't want to do that here as it might
|
||||||
assume a session ended just because the number of seats dipped for a few hands)
|
assume a session ended just because the number of seats dipped for a few hands)
|
||||||
*/
|
*/
|
||||||
ORDER BY h.handStart desc, hp2.PlayerId
|
ORDER BY h.handStart desc, hp2.PlayerId
|
||||||
|
@ -1407,16 +1641,50 @@ class Sql:
|
||||||
select coalesce(max(id),0)
|
select coalesce(max(id),0)
|
||||||
from Hands
|
from Hands
|
||||||
where handStart < date_sub(utc_timestamp(), interval '1' day)"""
|
where handStart < date_sub(utc_timestamp(), interval '1' day)"""
|
||||||
else: # assume postgresql
|
elif db_server == 'postgresql':
|
||||||
self.query['get_hand_1day_ago'] = """
|
self.query['get_hand_1day_ago'] = """
|
||||||
select coalesce(max(id),0)
|
select coalesce(max(id),0)
|
||||||
from Hands
|
from Hands
|
||||||
where handStart < now() at time zone 'UTC' - interval '1 day'"""
|
where handStart < now() at time zone 'UTC' - interval '1 day'"""
|
||||||
|
|
||||||
#if db_server == 'mysql':
|
# not used yet ...
|
||||||
self.query['get_hand_nhands_ago'] = """
|
# gets a date, would need to use handsplayers (not hudcache) to get exact hand Id
|
||||||
select coalesce(greatest(max(id),%s)-%s,0)
|
if db_server == 'mysql':
|
||||||
from Hands"""
|
self.query['get_date_nhands_ago'] = """
|
||||||
|
select concat( 'd', date_format(max(h.handStart), '%Y%m%d') )
|
||||||
|
from (select hp.playerId
|
||||||
|
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
|
||||||
|
from HandsPlayers hp
|
||||||
|
where hp.playerId = %s
|
||||||
|
group by hp.playerId) hp2
|
||||||
|
inner join HandsPlayers hp3 on ( hp3.handId <= hp2.maxminusx
|
||||||
|
and hp3.playerId = hp2.playerId)
|
||||||
|
inner join Hands h on (h.id = hp3.handId)
|
||||||
|
"""
|
||||||
|
elif db_server == 'postgresql':
|
||||||
|
self.query['get_date_nhands_ago'] = """
|
||||||
|
select 'd' || to_char(max(h3.handStart), 'YYMMDD')
|
||||||
|
from (select hp.playerId
|
||||||
|
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
|
||||||
|
from HandsPlayers hp
|
||||||
|
where hp.playerId = %s
|
||||||
|
group by hp.playerId) hp2
|
||||||
|
inner join HandsPlayers hp3 on ( hp3.handId <= hp2.maxminusx
|
||||||
|
and hp3.playerId = hp2.playerId)
|
||||||
|
inner join Hands h on (h.id = hp3.handId)
|
||||||
|
"""
|
||||||
|
elif db_server == 'sqlite': # untested guess at query:
|
||||||
|
self.query['get_date_nhands_ago'] = """
|
||||||
|
select 'd' || strftime(max(h3.handStart), 'YYMMDD')
|
||||||
|
from (select hp.playerId
|
||||||
|
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
|
||||||
|
from HandsPlayers hp
|
||||||
|
where hp.playerId = %s
|
||||||
|
group by hp.playerId) hp2
|
||||||
|
inner join HandsPlayers hp3 on ( hp3.handId <= hp2.maxminusx
|
||||||
|
and hp3.playerId = hp2.playerId)
|
||||||
|
inner join Hands h on (h.id = hp3.handId)
|
||||||
|
"""
|
||||||
|
|
||||||
# used in GuiPlayerStats:
|
# used in GuiPlayerStats:
|
||||||
self.query['getPlayerId'] = """SELECT id from Players where name = %s"""
|
self.query['getPlayerId'] = """SELECT id from Players where name = %s"""
|
||||||
|
@ -1587,7 +1855,7 @@ class Sql:
|
||||||
,upper(gt.limitType)
|
,upper(gt.limitType)
|
||||||
,s.name
|
,s.name
|
||||||
"""
|
"""
|
||||||
#elif db_server == 'sqlite': # what is the correct value here?
|
#elif db_server == 'sqlite':
|
||||||
# self.query['playerDetailedStats'] = """ """
|
# self.query['playerDetailedStats'] = """ """
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
|
@ -1799,7 +2067,7 @@ class Sql:
|
||||||
) hprof2
|
) hprof2
|
||||||
on hprof2.gtId = stats.gtId
|
on hprof2.gtId = stats.gtId
|
||||||
order by stats.base, stats.limittype, stats.bigBlindDesc desc <orderbyseats>"""
|
order by stats.base, stats.limittype, stats.bigBlindDesc desc <orderbyseats>"""
|
||||||
#elif db_server == 'sqlite': # what is the correct value here?
|
#elif db_server == 'sqlite':
|
||||||
# self.query['playerStats'] = """ """
|
# self.query['playerStats'] = """ """
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
|
@ -2074,7 +2342,7 @@ class Sql:
|
||||||
order by stats.category, stats.limitType, stats.bigBlindDesc desc
|
order by stats.category, stats.limitType, stats.bigBlindDesc desc
|
||||||
<orderbyseats>, cast(stats.PlPosition as smallint)
|
<orderbyseats>, cast(stats.PlPosition as smallint)
|
||||||
"""
|
"""
|
||||||
#elif db_server == 'sqlite': # what is the correct value here?
|
#elif db_server == 'sqlite':
|
||||||
# self.query['playerStatsByPosition'] = """ """
|
# self.query['playerStatsByPosition'] = """ """
|
||||||
|
|
||||||
self.query['getRingProfitAllHandsPlayerIdSite'] = """
|
self.query['getRingProfitAllHandsPlayerIdSite'] = """
|
||||||
|
@ -2413,6 +2681,10 @@ class Sql:
|
||||||
else: # assume postgres
|
else: # assume postgres
|
||||||
self.query['lockForInsert'] = ""
|
self.query['lockForInsert'] = ""
|
||||||
|
|
||||||
|
if db_server == 'sqlite':
|
||||||
|
for k,q in self.query.iteritems():
|
||||||
|
self.query[k] = re.sub('%s','?',q)
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
# just print the default queries and exit
|
# just print the default queries and exit
|
||||||
s = Sql(game = 'razz', type = 'ptracks')
|
s = Sql(game = 'razz', type = 'ptracks')
|
||||||
|
|
|
@ -17,6 +17,33 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
# if path is set to use an old version of python look for a new one:
|
||||||
|
# (does this work in linux?)
|
||||||
|
if os.name == 'nt' and sys.version[0:3] not in ('2.5', '2.6') and '-r' not in sys.argv:
|
||||||
|
#print "old path =", os.environ['PATH']
|
||||||
|
dirs = re.split(os.pathsep, os.environ['PATH'])
|
||||||
|
# remove any trailing / or \ chars from dirs:
|
||||||
|
dirs = [re.sub('[\\/]$','',p) for p in dirs]
|
||||||
|
# remove any dirs containing 'python' apart from those ending in 'python25', 'python26' or 'python':
|
||||||
|
dirs = [p for p in dirs if not re.search('python', p, re.I) or re.search('python25$', p, re.I) or re.search('python26$', p, re.I)]
|
||||||
|
tmppath = ";".join(dirs)
|
||||||
|
#print "new path =", tmppath
|
||||||
|
if re.search('python', tmppath, re.I):
|
||||||
|
os.environ['PATH'] = tmppath
|
||||||
|
print "Python " + sys.version[0:3] + ' - press return to continue\n'
|
||||||
|
sys.stdin.readline()
|
||||||
|
os.execvpe('python.exe', ('python.exe', 'fpdb.py', '-r'), os.environ) # first arg is ignored (name of program being run)
|
||||||
|
else:
|
||||||
|
print "\npython 2.5 not found, please install python 2.5 or 2.6 for fpdb\n"
|
||||||
|
exit
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
#print "debug - not changing path"
|
||||||
|
|
||||||
|
print "Python " + sys.version[0:3] + '...\n'
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import Options
|
import Options
|
||||||
import string
|
import string
|
||||||
|
@ -204,10 +231,10 @@ class fpdb:
|
||||||
# print 'User cancelled loading profile'
|
# print 'User cancelled loading profile'
|
||||||
#except:
|
#except:
|
||||||
# pass
|
# pass
|
||||||
try:
|
#try:
|
||||||
self.load_profile()
|
self.load_profile()
|
||||||
except:
|
#except:
|
||||||
pass
|
# pass
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
#end def dia_load_profile
|
#end def dia_load_profile
|
||||||
|
|
||||||
|
@ -246,7 +273,6 @@ class fpdb:
|
||||||
|
|
||||||
def dia_recreate_hudcache(self, widget, data=None):
|
def dia_recreate_hudcache(self, widget, data=None):
|
||||||
if self.obtain_global_lock():
|
if self.obtain_global_lock():
|
||||||
try:
|
|
||||||
dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache")
|
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."
|
diastring = "Please confirm that you want to re-create the HUD cache."
|
||||||
dia_confirm.format_secondary_text(diastring)
|
dia_confirm.format_secondary_text(diastring)
|
||||||
|
@ -257,8 +283,6 @@ class fpdb:
|
||||||
self.db.rebuild_hudcache()
|
self.db.rebuild_hudcache()
|
||||||
elif response == gtk.REPSONSE_NO:
|
elif response == gtk.REPSONSE_NO:
|
||||||
print 'User cancelled rebuilding hud cache'
|
print 'User cancelled rebuilding hud cache'
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
|
|
||||||
|
|
||||||
|
@ -467,7 +491,7 @@ class fpdb:
|
||||||
|
|
||||||
def tab_auto_import(self, widget, data=None):
|
def tab_auto_import(self, widget, data=None):
|
||||||
"""opens the auto import tab"""
|
"""opens the auto import tab"""
|
||||||
new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config)
|
new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config, self.sql)
|
||||||
self.threads.append(new_aimp_thread)
|
self.threads.append(new_aimp_thread)
|
||||||
aimp_tab=new_aimp_thread.get_vbox()
|
aimp_tab=new_aimp_thread.get_vbox()
|
||||||
self.add_and_display_tab(aimp_tab, "Auto Import")
|
self.add_and_display_tab(aimp_tab, "Auto Import")
|
||||||
|
|
|
@ -64,7 +64,7 @@ class fpdb_db:
|
||||||
if backend==fpdb_db.MYSQL_INNODB:
|
if backend==fpdb_db.MYSQL_INNODB:
|
||||||
import MySQLdb
|
import MySQLdb
|
||||||
try:
|
try:
|
||||||
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True)
|
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True, charset="utf8")
|
||||||
except:
|
except:
|
||||||
raise fpdb_simple.FpdbError("MySQL connection failed")
|
raise fpdb_simple.FpdbError("MySQL connection failed")
|
||||||
elif backend==fpdb_db.PGSQL:
|
elif backend==fpdb_db.PGSQL:
|
||||||
|
@ -155,7 +155,7 @@ class fpdb_db:
|
||||||
return (self.host, self.database, self.user, self.password)
|
return (self.host, self.database, self.user, self.password)
|
||||||
#end def get_db_info
|
#end def get_db_info
|
||||||
|
|
||||||
def getLastInsertId(self):
|
def getLastInsertId(self, cursor=None):
|
||||||
try:
|
try:
|
||||||
if self.backend == self.MYSQL_INNODB:
|
if self.backend == self.MYSQL_INNODB:
|
||||||
ret = self.db.insert_id()
|
ret = self.db.insert_id()
|
||||||
|
@ -177,9 +177,7 @@ class fpdb_db:
|
||||||
else:
|
else:
|
||||||
ret = row[0]
|
ret = row[0]
|
||||||
elif self.backend == fpdb_db.SQLITE:
|
elif self.backend == fpdb_db.SQLITE:
|
||||||
# don't know how to do this in sqlite
|
ret = cursor.lastrowid
|
||||||
print "getLastInsertId(): not coded for sqlite yet"
|
|
||||||
ret = -1
|
|
||||||
else:
|
else:
|
||||||
print "getLastInsertId(): unknown backend ", self.backend
|
print "getLastInsertId(): unknown backend ", self.backend
|
||||||
ret = -1
|
ret = -1
|
||||||
|
|
|
@ -21,12 +21,15 @@
|
||||||
|
|
||||||
import os # todo: remove this once import_dir is in fpdb_import
|
import os # todo: remove this once import_dir is in fpdb_import
|
||||||
import sys
|
import sys
|
||||||
from time import time, strftime
|
from time import time, strftime, sleep
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
import math
|
import math
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
import Queue
|
||||||
|
from collections import deque # using Queue for now
|
||||||
|
import threading
|
||||||
|
|
||||||
# fpdb/FreePokerTools modules
|
# fpdb/FreePokerTools modules
|
||||||
|
|
||||||
|
@ -61,27 +64,36 @@ class Importer:
|
||||||
self.config = config
|
self.config = config
|
||||||
self.sql = sql
|
self.sql = sql
|
||||||
|
|
||||||
self.database = None # database will be the main db interface eventually
|
|
||||||
self.filelist = {}
|
self.filelist = {}
|
||||||
self.dirlist = {}
|
self.dirlist = {}
|
||||||
self.siteIds = {}
|
self.siteIds = {}
|
||||||
self.addToDirList = {}
|
self.addToDirList = {}
|
||||||
self.removeFromFileList = {} # to remove deleted files
|
self.removeFromFileList = {} # to remove deleted files
|
||||||
self.monitor = False
|
self.monitor = False
|
||||||
self.updated = {} #Time last import was run {file:mtime}
|
self.updatedsize = {}
|
||||||
|
self.updatedtime = {}
|
||||||
self.lines = None
|
self.lines = None
|
||||||
self.faobs = None # File as one big string
|
self.faobs = None # File as one big string
|
||||||
self.pos_in_file = {} # dict to remember how far we have read in the file
|
self.pos_in_file = {} # dict to remember how far we have read in the file
|
||||||
#Set defaults
|
#Set defaults
|
||||||
self.callHud = self.config.get_import_parameters().get("callFpdbHud")
|
self.callHud = self.config.get_import_parameters().get("callFpdbHud")
|
||||||
|
|
||||||
|
# CONFIGURATION OPTIONS
|
||||||
self.settings.setdefault("minPrint", 30)
|
self.settings.setdefault("minPrint", 30)
|
||||||
self.settings.setdefault("handCount", 0)
|
self.settings.setdefault("handCount", 0)
|
||||||
|
#self.settings.setdefault("allowHudcacheRebuild", True) # NOT USED NOW
|
||||||
|
#self.settings.setdefault("forceThreads", 2) # NOT USED NOW
|
||||||
|
self.settings.setdefault("writeQSize", 1000) # no need to change
|
||||||
|
self.settings.setdefault("writeQMaxWait", 10) # not used
|
||||||
|
|
||||||
self.database = Database.Database(self.config, sql = self.sql) # includes .connection and .sql variables
|
self.writeq = None
|
||||||
|
self.database = Database.Database(self.config, sql = self.sql)
|
||||||
|
self.writerdbs = []
|
||||||
|
self.settings.setdefault("threads", 1) # value set by GuiBulkImport
|
||||||
|
for i in xrange(self.settings['threads']):
|
||||||
|
self.writerdbs.append( Database.Database(self.config, sql = self.sql) )
|
||||||
|
|
||||||
self.NEWIMPORT = False
|
self.NEWIMPORT = False
|
||||||
self.allow_hudcache_rebuild = False
|
|
||||||
|
|
||||||
#Set functions
|
#Set functions
|
||||||
def setCallHud(self, value):
|
def setCallHud(self, value):
|
||||||
|
@ -104,16 +116,27 @@ class Importer:
|
||||||
|
|
||||||
def setThreads(self, value):
|
def setThreads(self, value):
|
||||||
self.settings['threads'] = value
|
self.settings['threads'] = value
|
||||||
|
if self.settings["threads"] > len(self.writerdbs):
|
||||||
|
for i in xrange(self.settings['threads'] - len(self.writerdbs)):
|
||||||
|
self.writerdbs.append( Database.Database(self.config, sql = self.sql) )
|
||||||
|
|
||||||
def setDropIndexes(self, value):
|
def setDropIndexes(self, value):
|
||||||
self.settings['dropIndexes'] = value
|
self.settings['dropIndexes'] = value
|
||||||
|
|
||||||
|
def setDropHudCache(self, value):
|
||||||
|
self.settings['dropHudCache'] = value
|
||||||
|
|
||||||
# def setWatchTime(self):
|
# def setWatchTime(self):
|
||||||
# self.updated = time()
|
# self.updated = time()
|
||||||
|
|
||||||
def clearFileList(self):
|
def clearFileList(self):
|
||||||
self.filelist = {}
|
self.filelist = {}
|
||||||
|
|
||||||
|
def closeDBs(self):
|
||||||
|
self.database.disconnect()
|
||||||
|
for i in xrange(len(self.writerdbs)):
|
||||||
|
self.writerdbs[i].disconnect()
|
||||||
|
|
||||||
#Add an individual file to filelist
|
#Add an individual file to filelist
|
||||||
def addImportFile(self, filename, site = "default", filter = "passthrough"):
|
def addImportFile(self, filename, site = "default", filter = "passthrough"):
|
||||||
#TODO: test it is a valid file -> put that in config!!
|
#TODO: test it is a valid file -> put that in config!!
|
||||||
|
@ -164,51 +187,99 @@ class Importer:
|
||||||
print "Warning: Attempted to add non-directory: '" + str(dir) + "' as an import directory"
|
print "Warning: Attempted to add non-directory: '" + str(dir) + "' as an import directory"
|
||||||
|
|
||||||
def runImport(self):
|
def runImport(self):
|
||||||
""""Run full import on self.filelist."""
|
""""Run full import on self.filelist. This is called from GuiBulkImport.py"""
|
||||||
|
#if self.settings['forceThreads'] > 0: # use forceThreads until threading enabled in GuiBulkImport
|
||||||
|
# self.setThreads(self.settings['forceThreads'])
|
||||||
|
|
||||||
|
# Initial setup
|
||||||
start = datetime.datetime.now()
|
start = datetime.datetime.now()
|
||||||
|
starttime = time()
|
||||||
print "Started at", start, "--", len(self.filelist), "files to import.", self.settings['dropIndexes']
|
print "Started at", start, "--", len(self.filelist), "files to import.", self.settings['dropIndexes']
|
||||||
if self.settings['dropIndexes'] == 'auto':
|
if self.settings['dropIndexes'] == 'auto':
|
||||||
self.settings['dropIndexes'] = self.calculate_auto2(12.0, 500.0)
|
self.settings['dropIndexes'] = self.calculate_auto2(self.database, 12.0, 500.0)
|
||||||
if self.allow_hudcache_rebuild:
|
if self.settings['dropHudCache'] == 'auto':
|
||||||
self.settings['dropHudCache'] = self.calculate_auto2(25.0, 500.0) # returns "drop"/"don't drop"
|
self.settings['dropHudCache'] = self.calculate_auto2(self.database, 25.0, 500.0) # returns "drop"/"don't drop"
|
||||||
|
|
||||||
if self.settings['dropIndexes'] == 'drop':
|
if self.settings['dropIndexes'] == 'drop':
|
||||||
self.database.prepareBulkImport()
|
self.database.prepareBulkImport()
|
||||||
else:
|
else:
|
||||||
print "No need to drop indexes."
|
print "No need to drop indexes."
|
||||||
#print "dropInd =", self.settings['dropIndexes'], " dropHudCache =", self.settings['dropHudCache']
|
#print "dropInd =", self.settings['dropIndexes'], " dropHudCache =", self.settings['dropHudCache']
|
||||||
|
|
||||||
|
if self.settings['threads'] <= 0:
|
||||||
|
(totstored, totdups, totpartial, toterrors) = self.importFiles(self.database, None)
|
||||||
|
else:
|
||||||
|
# create queue (will probably change to deque at some point):
|
||||||
|
self.writeq = Queue.Queue( self.settings['writeQSize'] )
|
||||||
|
# start separate thread(s) to read hands from queue and write to db:
|
||||||
|
for i in xrange(self.settings['threads']):
|
||||||
|
t = threading.Thread( target=self.writerdbs[i].insert_queue_hands
|
||||||
|
, args=(self.writeq, self.settings["writeQMaxWait"])
|
||||||
|
, name="dbwriter-"+str(i) )
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
# read hands and write to q:
|
||||||
|
(totstored, totdups, totpartial, toterrors) = self.importFiles(self.database, self.writeq)
|
||||||
|
|
||||||
|
if self.writeq.empty():
|
||||||
|
print "writers finished already"
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print "waiting for writers to finish ..."
|
||||||
|
#for t in threading.enumerate():
|
||||||
|
# print " "+str(t)
|
||||||
|
#self.writeq.join()
|
||||||
|
#using empty() might be more reliable:
|
||||||
|
while not self.writeq.empty() and len(threading.enumerate()) > 1:
|
||||||
|
sleep(0.5)
|
||||||
|
print " ... writers finished"
|
||||||
|
|
||||||
|
# Tidying up after import
|
||||||
|
if self.settings['dropIndexes'] == 'drop':
|
||||||
|
self.database.afterBulkImport()
|
||||||
|
else:
|
||||||
|
print "No need to rebuild indexes."
|
||||||
|
if self.settings['dropHudCache'] == 'drop':
|
||||||
|
self.database.rebuild_hudcache()
|
||||||
|
else:
|
||||||
|
print "No need to rebuild hudcache."
|
||||||
|
self.database.analyzeDB()
|
||||||
|
endtime = time()
|
||||||
|
return (totstored, totdups, totpartial, toterrors, endtime-starttime)
|
||||||
|
# end def runImport
|
||||||
|
|
||||||
|
def importFiles(self, db, q):
|
||||||
|
""""Read filenames in self.filelist and pass to import_file_dict().
|
||||||
|
Uses a separate database connection if created as a thread (caller
|
||||||
|
passes None or no param as db)."""
|
||||||
|
|
||||||
totstored = 0
|
totstored = 0
|
||||||
totdups = 0
|
totdups = 0
|
||||||
totpartial = 0
|
totpartial = 0
|
||||||
toterrors = 0
|
toterrors = 0
|
||||||
tottime = 0
|
tottime = 0
|
||||||
# if threads <= 1: do this bit
|
|
||||||
for file in self.filelist:
|
for file in self.filelist:
|
||||||
(stored, duplicates, partial, errors, ttime) = self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
|
(stored, duplicates, partial, errors, ttime) = self.import_file_dict(db, file
|
||||||
|
,self.filelist[file][0], self.filelist[file][1], q)
|
||||||
totstored += stored
|
totstored += stored
|
||||||
totdups += duplicates
|
totdups += duplicates
|
||||||
totpartial += partial
|
totpartial += partial
|
||||||
toterrors += errors
|
toterrors += errors
|
||||||
tottime += ttime
|
|
||||||
if self.settings['dropIndexes'] == 'drop':
|
|
||||||
self.database.afterBulkImport()
|
|
||||||
else:
|
|
||||||
print "No need to rebuild indexes."
|
|
||||||
if self.allow_hudcache_rebuild and self.settings['dropHudCache'] == 'drop':
|
|
||||||
self.database.rebuild_hudcache()
|
|
||||||
else:
|
|
||||||
print "No need to rebuild hudcache."
|
|
||||||
self.database.analyzeDB()
|
|
||||||
return (totstored, totdups, totpartial, toterrors, tottime)
|
|
||||||
# else: import threaded
|
|
||||||
|
|
||||||
def calculate_auto(self):
|
for i in xrange( self.settings['threads'] ):
|
||||||
|
print "sending finish msg qlen =", q.qsize()
|
||||||
|
db.send_finish_msg(q)
|
||||||
|
|
||||||
|
return (totstored, totdups, totpartial, toterrors)
|
||||||
|
# end def importFiles
|
||||||
|
|
||||||
|
# not used currently
|
||||||
|
def calculate_auto(self, db):
|
||||||
"""An heuristic to determine a reasonable value of drop/don't drop"""
|
"""An heuristic to determine a reasonable value of drop/don't drop"""
|
||||||
if len(self.filelist) == 1: return "don't drop"
|
if len(self.filelist) == 1: return "don't drop"
|
||||||
if 'handsInDB' not in self.settings:
|
if 'handsInDB' not in self.settings:
|
||||||
try:
|
try:
|
||||||
tmpcursor = self.database.get_cursor()
|
tmpcursor = db.get_cursor()
|
||||||
tmpcursor.execute("Select count(1) from Hands;")
|
tmpcursor.execute("Select count(1) from Hands;")
|
||||||
self.settings['handsInDB'] = tmpcursor.fetchone()[0]
|
self.settings['handsInDB'] = tmpcursor.fetchone()[0]
|
||||||
except:
|
except:
|
||||||
|
@ -218,7 +289,7 @@ class Importer:
|
||||||
if self.settings['handsInDB'] > 50000: return "don't drop"
|
if self.settings['handsInDB'] > 50000: return "don't drop"
|
||||||
return "drop"
|
return "drop"
|
||||||
|
|
||||||
def calculate_auto2(self, scale, increment):
|
def calculate_auto2(self, db, scale, increment):
|
||||||
"""A second heuristic to determine a reasonable value of drop/don't drop
|
"""A second heuristic to determine a reasonable value of drop/don't drop
|
||||||
This one adds up size of files to import to guess number of hands in them
|
This one adds up size of files to import to guess number of hands in them
|
||||||
Example values of scale and increment params might be 10 and 500 meaning
|
Example values of scale and increment params might be 10 and 500 meaning
|
||||||
|
@ -231,7 +302,7 @@ class Importer:
|
||||||
# get number of hands in db
|
# get number of hands in db
|
||||||
if 'handsInDB' not in self.settings:
|
if 'handsInDB' not in self.settings:
|
||||||
try:
|
try:
|
||||||
tmpcursor = self.database.get_cursor()
|
tmpcursor = db.get_cursor()
|
||||||
tmpcursor.execute("Select count(1) from Hands;")
|
tmpcursor.execute("Select count(1) from Hands;")
|
||||||
self.settings['handsInDB'] = tmpcursor.fetchone()[0]
|
self.settings['handsInDB'] = tmpcursor.fetchone()[0]
|
||||||
except:
|
except:
|
||||||
|
@ -253,7 +324,7 @@ class Importer:
|
||||||
# size_per_hand, "inc =", increment, "return:", ret
|
# size_per_hand, "inc =", increment, "return:", ret
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
#Run import on updated files, then store latest update time.
|
#Run import on updated files, then store latest update time. Called from GuiAutoImport.py
|
||||||
def runUpdated(self):
|
def runUpdated(self):
|
||||||
#Check for new files in monitored directories
|
#Check for new files in monitored directories
|
||||||
#todo: make efficient - always checks for new file, should be able to use mtime of directory
|
#todo: make efficient - always checks for new file, should be able to use mtime of directory
|
||||||
|
@ -268,15 +339,18 @@ class Importer:
|
||||||
if os.path.exists(file):
|
if os.path.exists(file):
|
||||||
stat_info = os.stat(file)
|
stat_info = os.stat(file)
|
||||||
#rulog.writelines("path exists ")
|
#rulog.writelines("path exists ")
|
||||||
if file in self.updated:
|
if file in self.updatedsize: # we should be able to assume that if we're in size, we're in time as well
|
||||||
if stat_info.st_size > self.updated[file]:
|
if stat_info.st_size > self.updatedsize[file] or stat_info.st_mtime > self.updatedtime[file]:
|
||||||
self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
|
self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None)
|
||||||
self.updated[file] = stat_info.st_size
|
self.updatedsize[file] = stat_info.st_size
|
||||||
|
self.updatedtime[file] = time()
|
||||||
else:
|
else:
|
||||||
if os.path.isdir(file) or (time() - stat_info.st_mtime) < 60:
|
if os.path.isdir(file) or (time() - stat_info.st_mtime) < 60:
|
||||||
self.updated[file] = 0
|
self.updatedsize[file] = 0
|
||||||
|
self.updatedtime[file] = 0
|
||||||
else:
|
else:
|
||||||
self.updated[file] = stat_info.st_size
|
self.updatedsize[file] = stat_info.st_size
|
||||||
|
self.updatedtime[file] = time()
|
||||||
else:
|
else:
|
||||||
self.removeFromFileList[file] = True
|
self.removeFromFileList[file] = True
|
||||||
self.addToDirList = filter(lambda x: self.addImportDirectory(x, True, self.addToDirList[x][0], self.addToDirList[x][1]), self.addToDirList)
|
self.addToDirList = filter(lambda x: self.addImportDirectory(x, True, self.addToDirList[x][0], self.addToDirList[x][1]), self.addToDirList)
|
||||||
|
@ -292,16 +366,21 @@ class Importer:
|
||||||
#rulog.close()
|
#rulog.close()
|
||||||
|
|
||||||
# This is now an internal function that should not be called directly.
|
# This is now an internal function that should not be called directly.
|
||||||
def import_file_dict(self, file, site, filter):
|
def import_file_dict(self, db, file, site, filter, q=None):
|
||||||
#print "import_file_dict"
|
#print "import_file_dict"
|
||||||
if os.path.isdir(file):
|
if os.path.isdir(file):
|
||||||
self.addToDirList[file] = [site] + [filter]
|
self.addToDirList[file] = [site] + [filter]
|
||||||
return
|
return
|
||||||
|
|
||||||
conv = None
|
conv = None
|
||||||
|
(stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0)
|
||||||
|
|
||||||
# Load filter, process file, pass returned filename to import_fpdb_file
|
# Load filter, process file, pass returned filename to import_fpdb_file
|
||||||
|
|
||||||
print "\nConverting %s" % file
|
if self.writeq != None:
|
||||||
|
print "\nConverting " + file + " (" + str(q.qsize()) + ")"
|
||||||
|
else:
|
||||||
|
print "\nConverting " + file
|
||||||
hhbase = self.config.get_import_parameters().get("hhArchiveBase")
|
hhbase = self.config.get_import_parameters().get("hhArchiveBase")
|
||||||
hhbase = os.path.expanduser(hhbase)
|
hhbase = os.path.expanduser(hhbase)
|
||||||
hhdir = os.path.join(hhbase,site)
|
hhdir = os.path.join(hhbase,site)
|
||||||
|
@ -315,34 +394,34 @@ class Importer:
|
||||||
mod = __import__(filter)
|
mod = __import__(filter)
|
||||||
obj = getattr(mod, filter_name, None)
|
obj = getattr(mod, filter_name, None)
|
||||||
if callable(obj):
|
if callable(obj):
|
||||||
conv = obj(in_path = file, out_path = out_path, index = 0) # Index into file 0 until changeover
|
hhc = obj(in_path = file, out_path = out_path, index = 0) # Index into file 0 until changeover
|
||||||
if(conv.getStatus() and self.NEWIMPORT == False):
|
if(hhc.getStatus() and self.NEWIMPORT == False):
|
||||||
(stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(out_path, site)
|
(stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(db, out_path, site, q)
|
||||||
elif (conv.getStatus() and self.NEWIMPORT == True):
|
elif (hhc.getStatus() and self.NEWIMPORT == True):
|
||||||
#This code doesn't do anything yet
|
#This code doesn't do anything yet
|
||||||
handlist = hhc.getProcessedHands()
|
handlist = hhc.getProcessedHands()
|
||||||
self.pos_in_file[file] = hhc.getLastCharacterRead()
|
self.pos_in_file[file] = hhc.getLastCharacterRead()
|
||||||
|
|
||||||
for hand in handlist:
|
for hand in handlist:
|
||||||
hand.prepInsert()
|
#hand.prepInsert()
|
||||||
hand.insert()
|
hand.insert(self.database)
|
||||||
else:
|
else:
|
||||||
# conversion didn't work
|
# conversion didn't work
|
||||||
# TODO: appropriate response?
|
# TODO: appropriate response?
|
||||||
return (0, 0, 0, 1, 0)
|
return (0, 0, 0, 1, 0, -1)
|
||||||
else:
|
else:
|
||||||
print "Unknown filter filter_name:'%s' in filter:'%s'" %(filter_name, filter)
|
print "Unknown filter filter_name:'%s' in filter:'%s'" %(filter_name, filter)
|
||||||
return
|
return (0, 0, 0, 1, 0, -1)
|
||||||
|
|
||||||
#This will barf if conv.getStatus != True
|
#This will barf if conv.getStatus != True
|
||||||
return (stored, duplicates, partial, errors, ttime)
|
return (stored, duplicates, partial, errors, ttime)
|
||||||
|
|
||||||
|
|
||||||
def import_fpdb_file(self, file, site):
|
def import_fpdb_file(self, db, file, site, q):
|
||||||
#print "import_fpdb_file"
|
|
||||||
starttime = time()
|
starttime = time()
|
||||||
last_read_hand = 0
|
last_read_hand = 0
|
||||||
loc = 0
|
loc = 0
|
||||||
|
(stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0)
|
||||||
# print "file =", file
|
# print "file =", file
|
||||||
if file == "stdin":
|
if file == "stdin":
|
||||||
inputFile = sys.stdin
|
inputFile = sys.stdin
|
||||||
|
@ -369,20 +448,46 @@ class Importer:
|
||||||
self.pos_in_file[file] = inputFile.tell()
|
self.pos_in_file[file] = inputFile.tell()
|
||||||
inputFile.close()
|
inputFile.close()
|
||||||
|
|
||||||
#self.database.lock_for_insert() # should be ok when using one thread
|
(stored, duplicates, partial, errors, ttime, handsId) = self.import_fpdb_lines(db, self.lines, starttime, file, site, q)
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
ttime = time() - starttime
|
||||||
|
if q == None:
|
||||||
|
print "\rTotal stored:", stored, " duplicates:", duplicates, "errors:", errors, " time:", ttime
|
||||||
|
|
||||||
|
if not stored:
|
||||||
|
if duplicates:
|
||||||
|
for line_no in xrange(len(self.lines)):
|
||||||
|
if self.lines[line_no].find("Game #")!=-1:
|
||||||
|
final_game_line=self.lines[line_no]
|
||||||
|
handsId=fpdb_simple.parseSiteHandNo(final_game_line)
|
||||||
|
else:
|
||||||
|
print "failed to read a single hand from file:", inputFile
|
||||||
|
handsId=0
|
||||||
|
#todo: this will cause return of an unstored hand number if the last hand was error
|
||||||
|
self.handsId=handsId
|
||||||
|
|
||||||
|
return (stored, duplicates, partial, errors, ttime)
|
||||||
|
# end def import_fpdb_file
|
||||||
|
|
||||||
|
|
||||||
|
def import_fpdb_lines(self, db, lines, starttime, file, site, q = None):
|
||||||
|
"""Import an fpdb hand history held in the list lines, could be one hand or many"""
|
||||||
|
|
||||||
|
#db.lock_for_insert() # should be ok when using one thread, but doesn't help??
|
||||||
|
|
||||||
try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
|
try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
|
||||||
firstline = self.lines[0]
|
firstline = lines[0]
|
||||||
except:
|
except:
|
||||||
# just skip the debug message and return silently:
|
# just skip the debug message and return silently:
|
||||||
#print "DEBUG: import_fpdb_file: failed on self.lines[0]: '%s' '%s' '%s' '%s' " %( file, site, self.lines, loc)
|
#print "DEBUG: import_fpdb_file: failed on lines[0]: '%s' '%s' '%s' '%s' " %( file, site, lines, loc)
|
||||||
return (0,0,0,1,0)
|
return (0,0,0,1,0,0)
|
||||||
|
|
||||||
if firstline.find("Tournament Summary")!=-1:
|
if firstline.find("Tournament Summary")!=-1:
|
||||||
print "TODO: implement importing tournament summaries"
|
print "TODO: implement importing tournament summaries"
|
||||||
#self.faobs = readfile(inputFile)
|
#self.faobs = readfile(inputFile)
|
||||||
#self.parseTourneyHistory()
|
#self.parseTourneyHistory()
|
||||||
return (0,0,0,1,0)
|
return (0,0,0,1,0,0)
|
||||||
|
|
||||||
category=fpdb_simple.recogniseCategory(firstline)
|
category=fpdb_simple.recogniseCategory(firstline)
|
||||||
|
|
||||||
|
@ -391,11 +496,13 @@ class Importer:
|
||||||
duplicates = 0 #counter
|
duplicates = 0 #counter
|
||||||
partial = 0 #counter
|
partial = 0 #counter
|
||||||
errors = 0 #counter
|
errors = 0 #counter
|
||||||
|
ttime = 0
|
||||||
|
handsId = 0
|
||||||
|
|
||||||
for i in xrange (len(self.lines)):
|
for i in xrange (len(lines)):
|
||||||
if (len(self.lines[i])<2): #Wierd way to detect for '\r\n' or '\n'
|
if (len(lines[i])<2): #Wierd way to detect for '\r\n' or '\n'
|
||||||
endpos=i
|
endpos=i
|
||||||
hand=self.lines[startpos:endpos]
|
hand=lines[startpos:endpos]
|
||||||
|
|
||||||
if (len(hand[0])<2):
|
if (len(hand[0])<2):
|
||||||
hand=hand[1:]
|
hand=hand[1:]
|
||||||
|
@ -412,10 +519,10 @@ class Importer:
|
||||||
self.hand=hand
|
self.hand=hand
|
||||||
|
|
||||||
try:
|
try:
|
||||||
handsId = fpdb_parse_logic.mainParser( self.settings
|
handsId = fpdb_parse_logic.mainParser( self.settings, self.siteIds[site]
|
||||||
, self.siteIds[site], category, hand
|
, category, hand, self.config
|
||||||
, self.config, self.database )
|
, db, q )
|
||||||
self.database.commit()
|
db.commit()
|
||||||
|
|
||||||
stored += 1
|
stored += 1
|
||||||
if self.callHud:
|
if self.callHud:
|
||||||
|
@ -425,28 +532,28 @@ class Importer:
|
||||||
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
||||||
except fpdb_simple.DuplicateError:
|
except fpdb_simple.DuplicateError:
|
||||||
duplicates += 1
|
duplicates += 1
|
||||||
self.database.rollback()
|
db.rollback()
|
||||||
except (ValueError), fe:
|
except (ValueError), fe:
|
||||||
errors += 1
|
errors += 1
|
||||||
self.printEmailErrorMessage(errors, file, hand)
|
self.printEmailErrorMessage(errors, file, hand)
|
||||||
|
|
||||||
if (self.settings['failOnError']):
|
if (self.settings['failOnError']):
|
||||||
self.database.commit() #dont remove this, in case hand processing was cancelled.
|
db.commit() #dont remove this, in case hand processing was cancelled.
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
self.database.rollback()
|
db.rollback()
|
||||||
except (fpdb_simple.FpdbError), fe:
|
except (fpdb_simple.FpdbError), fe:
|
||||||
errors += 1
|
errors += 1
|
||||||
self.printEmailErrorMessage(errors, file, hand)
|
self.printEmailErrorMessage(errors, file, hand)
|
||||||
self.database.rollback()
|
db.rollback()
|
||||||
|
|
||||||
if self.settings['failOnError']:
|
if self.settings['failOnError']:
|
||||||
self.database.commit() #dont remove this, in case hand processing was cancelled.
|
db.commit() #dont remove this, in case hand processing was cancelled.
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if self.settings['minPrint']:
|
if self.settings['minPrint']:
|
||||||
if not ((stored+duplicates+errors) % self.settings['minPrint']):
|
if not ((stored+duplicates+errors) % self.settings['minPrint']):
|
||||||
print "stored:", stored, "duplicates:", duplicates, "errors:", errors
|
print "stored:", stored, " duplicates:", duplicates, "errors:", errors
|
||||||
|
|
||||||
if self.settings['handCount']:
|
if self.settings['handCount']:
|
||||||
if ((stored+duplicates+errors) >= self.settings['handCount']):
|
if ((stored+duplicates+errors) >= self.settings['handCount']):
|
||||||
|
@ -455,22 +562,8 @@ class Importer:
|
||||||
print "Total stored:", stored, "duplicates:", duplicates, "errors:", errors, " time:", (time() - starttime)
|
print "Total stored:", stored, "duplicates:", duplicates, "errors:", errors, " time:", (time() - starttime)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
startpos = endpos
|
startpos = endpos
|
||||||
ttime = time() - starttime
|
return (stored, duplicates, partial, errors, ttime, handsId)
|
||||||
print "\rTotal stored:", stored, "duplicates:", duplicates, "errors:", errors, " time:", ttime
|
# end def import_fpdb_lines
|
||||||
|
|
||||||
if not stored:
|
|
||||||
if duplicates:
|
|
||||||
for line_no in xrange(len(self.lines)):
|
|
||||||
if self.lines[line_no].find("Game #")!=-1:
|
|
||||||
final_game_line=self.lines[line_no]
|
|
||||||
handsId=fpdb_simple.parseSiteHandNo(final_game_line)
|
|
||||||
else:
|
|
||||||
print "failed to read a single hand from file:", inputFile
|
|
||||||
handsId=0
|
|
||||||
#todo: this will cause return of an unstored hand number if the last hand was error
|
|
||||||
self.database.commit()
|
|
||||||
self.handsId=handsId
|
|
||||||
return (stored, duplicates, partial, errors, ttime)
|
|
||||||
|
|
||||||
def printEmailErrorMessage(self, errors, filename, line):
|
def printEmailErrorMessage(self, errors, filename, line):
|
||||||
traceback.print_exc(file=sys.stderr)
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
|
@ -25,13 +25,12 @@ from time import time, strftime
|
||||||
|
|
||||||
|
|
||||||
#parses a holdem hand
|
#parses a holdem hand
|
||||||
def mainParser(settings, siteID, category, hand, config, db = None):
|
def mainParser(settings, siteID, category, hand, config, db = None, writeq = None):
|
||||||
#print "mainparser"
|
|
||||||
# fdb is not used now - to be removed ...
|
|
||||||
|
|
||||||
t0 = time()
|
t0 = time()
|
||||||
#print "mainparser"
|
#print "mainparser"
|
||||||
backend = settings['db-backend']
|
backend = settings['db-backend']
|
||||||
|
# Ideally db connection is passed in, if not use sql list if passed in, otherwise start from scratch
|
||||||
if db == None:
|
if db == None:
|
||||||
db = Database.Database(c = config, sql = None)
|
db = Database.Database(c = config, sql = None)
|
||||||
category = fpdb_simple.recogniseCategory(hand[0])
|
category = fpdb_simple.recogniseCategory(hand[0])
|
||||||
|
@ -80,7 +79,6 @@ def mainParser(settings, siteID, category, hand, config, db = None):
|
||||||
rebuyOrAddon = -1
|
rebuyOrAddon = -1
|
||||||
|
|
||||||
tourneyTypeId = 1
|
tourneyTypeId = 1
|
||||||
|
|
||||||
fpdb_simple.isAlreadyInDB(db.get_cursor(), gametypeID, siteHandNo)
|
fpdb_simple.isAlreadyInDB(db.get_cursor(), gametypeID, siteHandNo)
|
||||||
|
|
||||||
hand = fpdb_simple.filterCrap(hand, isTourney)
|
hand = fpdb_simple.filterCrap(hand, isTourney)
|
||||||
|
@ -182,7 +180,13 @@ def mainParser(settings, siteID, category, hand, config, db = None):
|
||||||
, positions, antes, cardValues, cardSuits, boardValues, boardSuits
|
, positions, antes, cardValues, cardSuits, boardValues, boardSuits
|
||||||
, winnings, rakes, actionTypes, allIns, actionAmounts
|
, winnings, rakes, actionTypes, allIns, actionAmounts
|
||||||
, actionNos, hudImportData, maxSeats, tableName, seatNos)
|
, actionNos, hudImportData, maxSeats, tableName, seatNos)
|
||||||
|
|
||||||
|
# save hand in db via direct call or via q if in a thread
|
||||||
|
if writeq == None:
|
||||||
result = db.store_the_hand(htw)
|
result = db.store_the_hand(htw)
|
||||||
|
else:
|
||||||
|
writeq.put(htw)
|
||||||
|
result = -999 # meaning unknown
|
||||||
|
|
||||||
t9 = time()
|
t9 = time()
|
||||||
#print "parse and save=(%4.3f)" % (t9-t0)
|
#print "parse and save=(%4.3f)" % (t9-t0)
|
||||||
|
|
|
@ -49,37 +49,6 @@ class FpdbError(Exception):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
# gets value for last auto-increment key generated
|
|
||||||
# returns -1 if a problem occurs
|
|
||||||
def getLastInsertId(backend, conn, cursor):
|
|
||||||
if backend == MYSQL_INNODB:
|
|
||||||
ret = conn.insert_id()
|
|
||||||
if ret < 1 or ret > 999999999:
|
|
||||||
print "getLastInsertId(): problem fetching insert_id? ret=", ret
|
|
||||||
ret = -1
|
|
||||||
elif backend == PGSQL:
|
|
||||||
# some options:
|
|
||||||
# currval(hands_id_seq) - use name of implicit seq here
|
|
||||||
# lastval() - still needs sequences set up?
|
|
||||||
# insert ... returning is useful syntax (but postgres specific?)
|
|
||||||
# see rules (fancy trigger type things)
|
|
||||||
cursor.execute ("SELECT lastval()")
|
|
||||||
row = cursor.fetchone()
|
|
||||||
if not row:
|
|
||||||
print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row
|
|
||||||
ret = -1
|
|
||||||
else:
|
|
||||||
ret = row[0]
|
|
||||||
elif backend == SQLITE:
|
|
||||||
# don't know how to do this in sqlite
|
|
||||||
print "getLastInsertId(): not coded for sqlite yet"
|
|
||||||
ret = -1
|
|
||||||
else:
|
|
||||||
print "getLastInsertId(): unknown backend ", backend
|
|
||||||
ret = -1
|
|
||||||
return ret
|
|
||||||
#end def getLastInsertId
|
|
||||||
|
|
||||||
#returns an array of the total money paid. intending to add rebuys/addons here
|
#returns an array of the total money paid. intending to add rebuys/addons here
|
||||||
def calcPayin(count, buyin, fee):
|
def calcPayin(count, buyin, fee):
|
||||||
return [buyin + fee for i in xrange(count)]
|
return [buyin + fee for i in xrange(count)]
|
||||||
|
|
1
pyfpdb/makeexe.bat
Normal file
1
pyfpdb/makeexe.bat
Normal file
|
@ -0,0 +1 @@
|
||||||
|
python makeexe.py py2exe
|
10
pyfpdb/makeexe.py
Normal file
10
pyfpdb/makeexe.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from distutils.core import setup
|
||||||
|
import py2exe
|
||||||
|
opts = {
|
||||||
|
'py2exe': {
|
||||||
|
'includes': "pango,atk,gobject",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup(name='Free Poker Database', version='0.12', console=[{"script":"fpdb.py"}])
|
||||||
|
|
47
pyfpdb/windows_make_bats.py
Executable file
47
pyfpdb/windows_make_bats.py
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
# create .bat scripts in windows to try out different gtk dirs
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
if os.name != 'nt':
|
||||||
|
print "\nThis script is only for windows\n"
|
||||||
|
exit()
|
||||||
|
|
||||||
|
dirs = re.split(os.pathsep, os.environ['PATH'])
|
||||||
|
# remove any trailing / or \ chars from dirs:
|
||||||
|
dirs = [re.sub('[\\/]$','',p) for p in dirs]
|
||||||
|
# remove any dirs containing 'python' apart from those ending in 'python25', 'python26' or 'python':
|
||||||
|
dirs = [p for p in dirs if not re.search('python', p, re.I) or re.search('python25$', p, re.I) or re.search('python26$', p, re.I)]
|
||||||
|
# find gtk dirs:
|
||||||
|
gtkdirs = [p for p in dirs if re.search('gtk', p, re.I)]
|
||||||
|
|
||||||
|
lines = [ '@echo off\n\n'
|
||||||
|
, '<path goes here>'
|
||||||
|
, 'python fpdb.py\n\n'
|
||||||
|
, 'pause\n\n'
|
||||||
|
]
|
||||||
|
if gtkdirs:
|
||||||
|
i = 1
|
||||||
|
for gpath in gtkdirs: # enumerate converts the \\ into \
|
||||||
|
tmpdirs = [p for p in dirs if not re.search('gtk', p, re.I) or p == gpath]
|
||||||
|
tmppath = ";".join(tmpdirs)
|
||||||
|
lines[1] = 'PATH=' + tmppath + '\n\n'
|
||||||
|
bat = open('run_fpdb'+str(i)+'.bat', 'w')
|
||||||
|
bat.writelines(lines)
|
||||||
|
bat.close()
|
||||||
|
i = i + 1
|
||||||
|
else:
|
||||||
|
print "\nno gtk directories found in your path - install gtk or edit the path manually\n"
|
||||||
|
|
||||||
|
except SystemExit:
|
||||||
|
pass
|
||||||
|
|
||||||
|
except:
|
||||||
|
print "Error:", str(sys.exc_info())
|
||||||
|
pass
|
||||||
|
|
||||||
|
# sys.stdin.readline()
|
42
utils/fix_table_desc.py
Normal file
42
utils/fix_table_desc.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
desc = """
|
||||||
|
+-------------+---------------------+------+-----+---------+----------------+
|
||||||
|
| Field | Type | Null | Key | Default | Extra |
|
||||||
|
+-------------+---------------------+------+-----+---------+----------------+
|
||||||
|
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
|
||||||
|
| tourneyId | int(10) unsigned | NO | MUL | NULL | |
|
||||||
|
| playerId | int(10) unsigned | NO | MUL | NULL | |
|
||||||
|
| payinAmount | int(11) | NO | | NULL | |
|
||||||
|
| rank | int(11) | NO | | NULL | |
|
||||||
|
| winnings | int(11) | NO | | NULL | |
|
||||||
|
| comment | text | YES | | NULL | |
|
||||||
|
| commentTs | datetime | YES | | NULL | |
|
||||||
|
+-------------+---------------------+------+-----+---------+----------------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
table = """
|
||||||
|
{| border="1"
|
||||||
|
|+Gametypes Table
|
||||||
|
"""
|
||||||
|
|
||||||
|
# get rid of the verticle spacing and clean up
|
||||||
|
desc = re.sub("[\+\-]+", "", desc)
|
||||||
|
desc = re.sub("^\n+", "", desc) # there's probably a better way
|
||||||
|
desc = re.sub("\n\n", "\n", desc)
|
||||||
|
|
||||||
|
# the first line is the header info
|
||||||
|
temp, desc = re.split("\n", desc, 1)
|
||||||
|
temp = re.sub("\|", "!", temp)
|
||||||
|
temp = re.sub(" !", " !!", temp)
|
||||||
|
table += temp + " Comments\n"
|
||||||
|
|
||||||
|
# the rest is he body of the table
|
||||||
|
for line in re.split("\n", desc):
|
||||||
|
line = re.sub(" \|", " ||", line)
|
||||||
|
table += "|+\n" + line + "\n"
|
||||||
|
|
||||||
|
table += "|}\n"
|
||||||
|
print table
|
Loading…
Reference in New Issue
Block a user