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

This commit is contained in:
grindi 2009-08-08 12:09:45 +04:00
commit e748f4e2a1
18 changed files with 914 additions and 653 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2008, Carl Gherardi
@ -60,7 +60,7 @@ debugging: if False, pass on partially supported game types. If true, have a go
logging.info("Initialising Absolute converter class")
self.filetype = "text"
self.codepage = "cp1252"
self.siteId = 3 # Needs to match id entry in Sites database
self.siteId = 8 # Needs to match id entry in Sites database
self.debugging = debugging
if autostart:
self.start()
@ -79,7 +79,7 @@ debugging: if False, pass on partially supported game types. If true, have a go
# TODO: Absolute posting when coming in new: %s - Posts $0.02 .. should that be a new Post line? where do we need to add support for that? *confused*
self.re_PostBoth = re.compile(ur"^%s - Posts dead (?:\$| €|)(?P<SBBB>[0-9]*[.0-9]+)" % player_re, re.MULTILINE)
self.re_Action = re.compile(ur"^%s - (?P<ATYPE>Bets |Raises |All-In |All-In\(Raise\) |Calls |Folds|Checks)?\$?(?P<BET>[0-9]*[.0-9]+)?" % player_re, re.MULTILINE)
print "^%s - (?P<ATYPE>Bets |Raises |All-In |All-In\(Raise\) |Calls |Folds|Checks)?\$?(?P<BET>[0-9]*[.0-9]+)?" % player_re
# print "^%s - (?P<ATYPE>Bets |Raises |All-In |All-In\(Raise\) |Calls |Folds|Checks)?\$?(?P<BET>[0-9]*[.0-9]+)?" % player_re
self.re_ShowdownAction = re.compile(ur"^%s - Shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
self.re_CollectPot = re.compile(ur"^Seat [0-9]: %s(?: \(dealer\)| \(big blind\)| \(small blind\)|) (?:won|collected) Total \((?:\$| €|)(?P<POT>[0-9]*[.0-9]+)\)" % player_re, re.MULTILINE)
#self.re_PostSB = re.compile(ur"^%s: posts small blind \[(?:\$| €|) (?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
@ -249,7 +249,6 @@ or None if we fail to get the info """
#Not involved in hand
hand.involved = False
def readStudPlayerCards(self, hand, street):
# lol. see Plymouth.txt
logging.warning("Absolute readStudPlayerCards is only a stub.")

View File

@ -593,19 +593,20 @@ class Config:
return paths
def get_frames(self, site = "PokerStars"):
if site not in self.supported_sites: return False
return self.supported_sites[site].use_frames == True
def get_default_colors(self, site = "PokerStars"):
colors = {}
if self.supported_sites[site].hudopacity == "":
if site not in self.supported_sites or self.supported_sites[site].hudopacity == "":
colors['hudopacity'] = 0.90
else:
colors['hudopacity'] = float(self.supported_sites[site].hudopacity)
if self.supported_sites[site].hudbgcolor == "":
if site not in self.supported_sites or self.supported_sites[site].hudbgcolor == "":
colors['hudbgcolor'] = "#FFFFFF"
else:
colors['hudbgcolor'] = self.supported_sites[site].hudbgcolor
if self.supported_sites[site].hudfgcolor == "":
if site not in self.supported_sites or self.supported_sites[site].hudfgcolor == "":
colors['hudfgcolor'] = "#000000"
else:
colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor
@ -613,6 +614,8 @@ class Config:
def get_default_font(self, site = 'PokerStars'):
(font, font_size) = ("Sans", "8")
if site not in self.supported_sites:
return ("Sans", "8")
if self.supported_sites[site].font == "":
font = "Sans"
else:

View File

@ -98,7 +98,7 @@ class Database:
foreignKeys = [
[ ] # no db with index 0
, [ ] # no db with index 1
, [ # foreign keys for mysql
, [ # foreign keys for mysql (index 2)
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
@ -107,7 +107,7 @@ class Database:
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
, {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
]
, [ # foreign keys for postgres
, [ # foreign keys for postgres (index 3)
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
@ -116,6 +116,8 @@ class Database:
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
, {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
]
, [ # no foreign keys in sqlite (index 4)
]
]
@ -233,9 +235,15 @@ class Database:
self.fdb.reconnect(due_to_error=False)
def get_backend_name(self):
"""Reconnects the DB"""
return self.fdb.get_backend_name()
"""Returns the name of the currently used backend"""
if self.backend==2:
return "MySQL InnoDB"
elif self.backend==3:
return "PostgreSQL"
elif self.backend==4:
return "SQLite"
else:
raise fpdb_simple.FpdbError("invalid backend")
def get_table_name(self, hand_id):
c = self.connection.cursor()
@ -465,11 +473,39 @@ class Database:
result = c.fetchall()
return result
def get_last_insert_id(self):
def get_last_insert_id(self, cursor=None):
ret = None
try:
ret = self.fdb.getLastInsertId()
if self.backend == self.MYSQL_INNODB:
ret = self.connection.insert_id()
if ret < 1 or ret > 999999999:
print "getLastInsertId(): problem fetching insert_id? ret=", ret
ret = -1
elif self.backend == self.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)
c = self.get_cursor()
ret = c.execute ("SELECT lastval()")
row = c.fetchone()
if not row:
print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row
ret = -1
else:
ret = row[0]
elif self.backend == self.SQLITE:
ret = cursor.lastrowid
else:
print "getLastInsertId(): unknown backend ", self.backend
ret = -1
except:
print "get_last_insert_id error:", str(sys.exc_value)
ret = -1
err = traceback.extract_tb(sys.exc_info()[2])
print "***get_last_insert_id error: " + str(sys.exc_info()[1])
print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
raise
return ret
@ -847,6 +883,7 @@ class Database:
self.commit()
except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
self.rollback()
raise
@ -939,12 +976,14 @@ class Database:
try:
stime = time()
self.connection.cursor().execute(self.sql.query['clearHudCache'])
self.connection.cursor().execute(self.sql.query['rebuildHudCache'])
self.get_cursor().execute(self.sql.query['clearHudCache'])
self.get_cursor().execute(self.sql.query['rebuildHudCache'])
self.commit()
print "Rebuild hudcache took %.1f seconds" % (time() - stime,)
except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "Error rebuilding hudcache:", str(sys.exc_value)
print err
#end def rebuild_hudcache
@ -1001,15 +1040,26 @@ class Database:
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]
q = "SELECT name, id FROM Players WHERE siteid=%s and name=%s"
q = q.replace('%s', self.sql.query['placeholder'])
print "DEBUG: name: %s site: %s" %(name, site_id)
c.execute (q, (site_id, name))
tmp = c.fetchone()
if (tmp == None): #new player
c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)".replace('%s',self.sql.query['placeholder'])
,(name, site_id))
#Get last id might be faster here.
#c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
tmp = [self.get_last_insert_id(c)]
return tmp[0]
def insertGameTypes(self, row):
c = self.get_cursor()
c.execute( self.sql.query['insertGameTypes'], row )
return [self.get_last_insert_id(c)]
def store_the_hand(self, h):
"""Take a HandToWrite object and store it in the db"""
@ -1069,6 +1119,76 @@ class Database:
return result
#end def store_the_hand
def storeHand(self, p):
#stores into table hands:
self.cursor.execute ("""INSERT INTO Hands (
tablename,
sitehandno,
gametypeid,
handstart,
importtime,
seats,
maxseats,
boardcard1,
boardcard2,
boardcard3,
boardcard4,
boardcard5,
-- texture,
playersVpi,
playersAtStreet1,
playersAtStreet2,
playersAtStreet3,
playersAtStreet4,
playersAtShowdown,
street0Raises,
street1Raises,
street2Raises,
street3Raises,
street4Raises,
-- street1Pot,
-- street2Pot,
-- street3Pot,
-- street4Pot,
-- showdownPot
)
VALUES
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s)""",
(
p['tablename'],
p['sitehandno'],
p['gametypeid'],
p['handStart'],
datetime.datetime.today(),
len(p['names']),
p['maxSeats'],
p['boardcard1'],
p['boardcard2'],
p['boardcard3'],
p['boardcard4'],
p['boardcard5'],
hudCache['playersVpi'],
hudCache['playersAtStreet1'],
hudCache['playersAtStreet2'],
hudCache['playersAtStreet3'],
hudCache['playersAtStreet4'],
hudCache['playersAtShowdown'],
hudCache['street0Raises'],
hudCache['street1Raises'],
hudCache['street2Raises'],
hudCache['street3Raises'],
hudCache['street4Raises'],
hudCache['street1Pot'],
hudCache['street2Pot'],
hudCache['street3Pot'],
hudCache['street4Pot'],
hudCache['showdownPot']
)
)
#return getLastInsertId(backend, conn, cursor)
# def storeHand
def storeHands(self, backend, site_hand_no, gametype_id
,hand_start_time, names, tableName, maxSeats, hudCache
,board_values, board_suits):
@ -1076,30 +1196,31 @@ class Database:
cards = [Card.cardFromValueSuit(v,s) for v,s in zip(board_values,board_suits)]
#stores into table hands:
try:
self.get_cursor().execute ("""INSERT INTO Hands
(siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats
,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5
,playersVpi, playersAtStreet1, playersAtStreet2
,playersAtStreet3, playersAtStreet4, playersAtShowdown
,street0Raises, street1Raises, street2Raises
,street3Raises, street4Raises, street1Pot
,street2Pot, street3Pot, street4Pot
,showdownPot
)
VALUES
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
, (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats
,cards[0], cards[1], cards[2], cards[3], cards[4]
,hudCache['playersVpi'], hudCache['playersAtStreet1'], hudCache['playersAtStreet2']
,hudCache['playersAtStreet3'], hudCache['playersAtStreet4'], hudCache['playersAtShowdown']
,hudCache['street0Raises'], hudCache['street1Raises'], hudCache['street2Raises']
,hudCache['street3Raises'], hudCache['street4Raises'], hudCache['street1Pot']
,hudCache['street2Pot'], hudCache['street3Pot'], hudCache['street4Pot']
,hudCache['showdownPot']
))
ret = self.get_last_insert_id()
c = self.get_cursor()
c.execute ("""INSERT INTO Hands
(siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats
,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5
,playersVpi, playersAtStreet1, playersAtStreet2
,playersAtStreet3, playersAtStreet4, playersAtShowdown
,street0Raises, street1Raises, street2Raises
,street3Raises, street4Raises, street1Pot
,street2Pot, street3Pot, street4Pot
,showdownPot
)
VALUES
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
""".replace('%s', self.sql.query['placeholder'])
, (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats
,cards[0], cards[1], cards[2], cards[3], cards[4]
,hudCache['playersVpi'], hudCache['playersAtStreet1'], hudCache['playersAtStreet2']
,hudCache['playersAtStreet3'], hudCache['playersAtStreet4'], hudCache['playersAtShowdown']
,hudCache['street0Raises'], hudCache['street1Raises'], hudCache['street2Raises']
,hudCache['street3Raises'], hudCache['street4Raises'], hudCache['street1Pot']
,hudCache['street2Pot'], hudCache['street3Pot'], hudCache['street4Pot']
,hudCache['showdownPot']
))
ret = self.get_last_insert_id(c)
except:
ret = -1
raise fpdb_simple.FpdbError( "storeHands error: " + str(sys.exc_value) )
@ -1168,7 +1289,8 @@ class Database:
hudCache['street0Calls'][i], hudCache['street1Calls'][i], hudCache['street2Calls'][i], hudCache['street3Calls'][i], hudCache['street4Calls'][i],
hudCache['street0Bets'][i], hudCache['street1Bets'][i], hudCache['street2Bets'][i], hudCache['street3Bets'][i], hudCache['street4Bets'][i]
) )
self.get_cursor().executemany ("""
c = self.get_cursor()
c.executemany ("""
INSERT INTO HandsPlayers
(handId, playerId, startCash, position, tourneyTypeId,
card1, card2, card3, card4, startCards, winnings, rake, seatNo, totalProfit,
@ -1191,13 +1313,9 @@ class Database:
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder'])
,inserts )
result.append( self.get_last_insert_id() )
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
#result.append(cursor.fetchall()[0][0])
result.append( self.get_last_insert_id() )
result.append( self.get_last_insert_id(c) ) # wrong? not used currently
except:
raise fpdb_simple.FpdbError( "store_hands_players_holdem_omaha error: " + str(sys.exc_value) )
@ -1220,13 +1338,14 @@ class Database:
card6 = Card.cardFromValueSuit(card_values[i][5], card_suits[i][5])
card7 = Card.cardFromValueSuit(card_values[i][6], card_suits[i][6])
self.get_cursor().execute ("""INSERT INTO HandsPlayers
c = self.get_cursor()
c.execute ("""INSERT INTO HandsPlayers
(handId, playerId, startCash, ante, tourneyTypeId,
card1, card2,
card3, card4,
card5, card6,
card7, winnings, rake, seatNo)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']),
(hands_id, player_ids[i], start_cashes[i], antes[i], 1,
card1, card2,
card3, card4,
@ -1234,7 +1353,7 @@ class Database:
card7, winnings[i], rakes[i], seatNos[i]))
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
#result.append(cursor.fetchall()[0][0])
result.append( self.get_last_insert_id() )
result.append( self.get_last_insert_id(c) )
except:
raise fpdb_simple.FpdbError( "store_hands_players_stud error: " + str(sys.exc_value) )
@ -1297,7 +1416,8 @@ class Database:
hudCache['street3Bets'][i], hudCache['street4Bets'][i]
) )
self.get_cursor().executemany ("""
c = self.get_cursor()
c.executemany ("""
INSERT INTO HandsPlayers
(handId, playerId, startCash, position, tourneyTypeId,
card1, card2, card3, card4, startCards, winnings, rake, tourneysPlayersId, seatNo, totalProfit,
@ -1321,10 +1441,10 @@ class Database:
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder'])
,inserts )
result.append( self.get_last_insert_id() )
result.append( self.get_last_insert_id(c) )
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
#result.append(cursor.fetchall()[0][0])
except:
@ -1340,14 +1460,15 @@ class Database:
try:
result=[]
for i in xrange(len(player_ids)):
self.get_cursor().execute ("""INSERT INTO HandsPlayers
c = self.get_cursor()
c.execute ("""INSERT INTO HandsPlayers
(handId, playerId, startCash, ante,
card1Value, card1Suit, card2Value, card2Suit,
card3Value, card3Suit, card4Value, card4Suit,
card5Value, card5Suit, card6Value, card6Suit,
card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s)""",
%s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']),
(hands_id, player_ids[i], start_cashes[i], antes[i],
card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
@ -1355,7 +1476,7 @@ class Database:
card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
#result.append(cursor.fetchall()[0][0])
result.append( self.get_last_insert_id() )
result.append( self.get_last_insert_id(c) )
except:
raise fpdb_simple.FpdbError( "store_hands_players_stud_tourney error: " + str(sys.exc_value) )
@ -1493,24 +1614,28 @@ class Database:
AND position=%s
AND tourneyTypeId+0=%s
AND styleKey=%s
""", (row[6], row[7], row[8], row[9], row[10],
row[11], row[12], row[13], row[14], row[15],
row[16], row[17], row[18], row[19], row[20],
row[21], row[22], row[23], row[24], row[25],
row[26], row[27], row[28], row[29], row[30],
row[31], row[32], row[33], row[34], row[35],
row[36], row[37], row[38], row[39], row[40],
row[41], row[42], row[43], row[44], row[45],
row[46], row[47], row[48], row[49], row[50],
row[51], row[52], row[53], row[54], row[55],
row[56], row[57], row[58], row[59], row[60],
row[1], row[2], row[3], str(row[4]), row[5], styleKey))
""".replace('%s', self.sql.query['placeholder'])
,(row[6], row[7], row[8], row[9], row[10],
row[11], row[12], row[13], row[14], row[15],
row[16], row[17], row[18], row[19], row[20],
row[21], row[22], row[23], row[24], row[25],
row[26], row[27], row[28], row[29], row[30],
row[31], row[32], row[33], row[34], row[35],
row[36], row[37], row[38], row[39], row[40],
row[41], row[42], row[43], row[44], row[45],
row[46], row[47], row[48], row[49], row[50],
row[51], row[52], row[53], row[54], row[55],
row[56], row[57], row[58], row[59], row[60],
row[1], row[2], row[3], str(row[4]), row[5], styleKey))
# Test statusmessage to see if update worked, do insert if not
#print "storehud2, upd num =", num
#print "storehud2, upd num =", num.rowcount
# num is a cursor in sqlite
if ( (backend == self.PGSQL and cursor.statusmessage != "UPDATE 1")
or (backend == self.MYSQL_INNODB and num == 0) ):
or (backend == self.MYSQL_INNODB and num == 0)
or (backend == self.SQLITE and num.rowcount == 0)
):
#print "playerid before insert:",row[2]," num = ", num
cursor.execute("""INSERT INTO HudCache
num = cursor.execute("""INSERT INTO HudCache
(gametypeId, playerId, activeSeats, position, tourneyTypeId, styleKey,
HDs, street0VPI, street0Aggr, street0_3BChance, street0_3BDone,
street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown,
@ -1534,14 +1659,14 @@ class Database:
%s, %s, %s, %s, %s,
%s, %s, %s, %s, %s,
%s, %s, %s, %s, %s,
%s, %s, %s, %s, %s)"""
%s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder'])
, (row[1], row[2], row[3], row[4], row[5], styleKey, row[6], row[7], row[8], row[9], row[10]
,row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20]
,row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30]
,row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40]
,row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50]
,row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60]) )
#print "hopefully inserted hud data line: ", cursor.statusmessage
#print "hopefully inserted hud data line: ", cursor.rowcount
# message seems to be "INSERT 0 1"
else:
#print "updated(2) hud data line"
@ -1557,7 +1682,8 @@ class Database:
def store_tourneys(self, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
try:
cursor = self.get_cursor()
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s".replace('%s', self.sql.query['placeholder'])
, (siteTourneyNo, tourneyTypeId))
tmp=cursor.fetchone()
#print "tried SELECTing tourneys.id, result:",tmp
@ -1566,7 +1692,8 @@ class Database:
except TypeError:#means we have to create new one
cursor.execute("""INSERT INTO Tourneys
(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
VALUES (%s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder'])
,(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
tmp=cursor.fetchone()
#print "created new tourneys.id:",tmp
@ -1586,7 +1713,8 @@ class Database:
#print "ranks:",ranks
#print "winnings:",winnings
for i in xrange(len(player_ids)):
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s".replace('%s', self.sql.query['placeholder'])
,(tourney_id, player_ids[i]))
tmp=cursor.fetchone()
#print "tried SELECTing tourneys_players.id:",tmp
@ -1594,10 +1722,10 @@ class Database:
len(tmp)
except TypeError:
cursor.execute("""INSERT INTO TourneysPlayers
(tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
(tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']),
(tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s".replace('%s', self.sql.query['placeholder']),
(tourney_id, player_ids[i]))
tmp=cursor.fetchone()
#print "created new tourneys_players.id:",tmp

View File

@ -17,6 +17,7 @@
import threading
import subprocess
import traceback
import pygtk
pygtk.require('2.0')

View File

@ -74,7 +74,10 @@ class GuiBulkImport():
cb_hmodel = self.cb_drophudcache.get_model()
cb_hindex = self.cb_drophudcache.get_active()
self.lab_info.set_text("Importing") # doesn't display :-(
self.lab_info.set_markup('<span foreground="blue">Importing ...</span>') # uses pango markup!
while gtk.events_pending(): # see http://faq.pygtk.org/index.py?req=index for more hints (3.7)
gtk.main_iteration(False)
if cb_index:
self.importer.setDropIndexes(cb_model[cb_index][0])
else:

View File

@ -20,6 +20,7 @@ import pygtk
pygtk.require('2.0')
import gtk
import os
import traceback
from time import *
#import pokereval
@ -72,20 +73,19 @@ class GuiGraphViewer (threading.Thread):
self.mainHBox.show()
self.leftPanelBox = self.filters.get_vbox()
self.graphBox = gtk.VBox(False, 0)
self.graphBox.show()
self.hpane = gtk.HPaned()
self.hpane.pack1(self.leftPanelBox)
self.mainHBox.add(self.hpane)
# hierarchy: self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax
self.graphBox = gtk.VBox(False, 0)
self.graphBox.show()
self.hpane.pack2(self.graphBox)
self.hpane.show()
self.mainHBox.add(self.hpane)
self.fig = None
#self.exportButton.set_sensitive(False)
self.fig = Figure(figsize=(5,4), dpi=100)
self.canvas = None
@ -125,79 +125,103 @@ class GuiGraphViewer (threading.Thread):
#end def get_vbox
def clearGraphData(self):
self.fig.clear()
if self.canvas is not None:
self.canvas.destroy()
self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea
try:
try:
if self.canvas:
self.graphBox.remove(self.canvas)
except:
pass
if self.fig != None:
self.fig.clear()
self.fig = Figure(figsize=(5,4), dpi=100)
if self.canvas is not None:
self.canvas.destroy()
self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea
except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
raise
def generateGraph(self, widget, data):
self.clearGraphData()
print "generateGraph: start"
try:
self.clearGraphData()
print "after cleardata"
sitenos = []
playerids = []
sitenos = []
playerids = []
sites = self.filters.getSites()
heroes = self.filters.getHeroes()
siteids = self.filters.getSiteIds()
limits = self.filters.getLimits()
# Which sites are selected?
for site in sites:
if sites[site] == True:
sitenos.append(siteids[site])
self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],))
result = self.db.cursor.fetchall()
if len(result) == 1:
playerids.append(result[0][0])
sites = self.filters.getSites()
heroes = self.filters.getHeroes()
siteids = self.filters.getSiteIds()
limits = self.filters.getLimits()
print "got filter data"
# Which sites are selected?
for site in sites:
if sites[site] == True:
sitenos.append(siteids[site])
self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],))
result = self.db.cursor.fetchall()
if len(result) == 1:
playerids.append(result[0][0])
if not sitenos:
#Should probably pop up here.
print "No sites selected - defaulting to PokerStars"
return
if not sitenos:
#Should probably pop up here.
print "No sites selected - defaulting to PokerStars"
return
if not playerids:
print "No player ids found"
return
if not playerids:
print "No player ids found"
return
if not limits:
print "No limits found"
return
if not limits:
print "No limits found"
return
#Set graph properties
self.ax = self.fig.add_subplot(111)
#Set graph properties
print "add_subplot"
self.ax = self.fig.add_subplot(111)
#Get graph data from DB
starttime = time()
line = self.getRingProfitGraph(playerids, sitenos, limits)
print "Graph generated in: %s" %(time() - starttime)
#Get graph data from DB
starttime = time()
print "get line: playerids =", playerids, "sitenos =", sitenos, "limits =", limits
line = self.getRingProfitGraph(playerids, sitenos, limits)
print "Graph generated in: %s" %(time() - starttime)
self.ax.set_title("Profit graph for ring games")
self.ax.set_title("Profit graph for ring games")
#Set axis labels and grid overlay properites
self.ax.set_xlabel("Hands", fontsize = 12)
self.ax.set_ylabel("$", fontsize = 12)
self.ax.grid(color='g', linestyle=':', linewidth=0.2)
if line == None or line == []:
#Set axis labels and grid overlay properites
self.ax.set_xlabel("Hands", fontsize = 12)
self.ax.set_ylabel("$", fontsize = 12)
self.ax.grid(color='g', linestyle=':', linewidth=0.2)
if line == None or line == []:
#TODO: Do something useful like alert user
print "No hands returned by graph query"
else:
# text = "All Hands, " + sitename + str(name) + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line))
text = "All Hands, " + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line))
#TODO: Do something useful like alert user
print "No hands returned by graph query"
else:
# text = "All Hands, " + sitename + str(name) + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line))
text = "All Hands, " + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line))
self.ax.annotate(text,
xy=(10, -10),
xycoords='axes points',
horizontalalignment='left', verticalalignment='top',
fontsize=10)
self.ax.annotate(text,
xy=(10, -10),
xycoords='axes points',
horizontalalignment='left', verticalalignment='top',
fontsize=10)
#Draw plot
self.ax.plot(line,)
#Draw plot
self.ax.plot(line,)
self.graphBox.add(self.canvas)
self.canvas.show()
self.canvas.draw()
#self.exportButton.set_sensitive(True)
except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
self.graphBox.add(self.canvas)
self.canvas.show()
self.canvas.draw()
#self.exportButton.set_sensitive(True)
#end of def showClicked
def getRingProfitGraph(self, names, sites, limits):

View File

@ -132,7 +132,7 @@ class GuiPlayerStats (threading.Thread):
self.stats_vbox = gtk.VBox(False, 0)
self.stats_vbox.show()
self.stats_frame.add(self.stats_vbox)
self.fillStatsFrame(self.stats_vbox)
# self.fillStatsFrame(self.stats_vbox)
self.main_hbox.pack_start(self.filters.get_vbox())
self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True)
@ -167,7 +167,9 @@ class GuiPlayerStats (threading.Thread):
for site in sites:
if sites[site] == True:
sitenos.append(siteids[site])
self.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],))
# Nasty hack to deal with multiple sites + same player name -Eric
que = self.sql.query['getPlayerId'] + " AND siteId=%d" % siteids[site]
self.cursor.execute(que, (heroes[site],))
result = self.db.cursor.fetchall()
if len(result) == 1:
playerids.append(result[0][0])

View File

@ -22,288 +22,270 @@ import gtk
import os
import fpdb_simple
try:
import MySQLdb
except:
diaSQLLibMissing = gtk.Dialog(title="Fatal Error - SQL interface library missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
label = gtk.Label("Please note that the table viewer only works with MySQL, if you use PostgreSQL this error is expected.")
diaSQLLibMissing.vbox.add(label)
label.show()
label = gtk.Label("Since the HUD now runs on all supported plattforms I do not see any point in table viewer anymore, if you disagree please send a message to steffen@sycamoretest.info")
diaSQLLibMissing.vbox.add(label)
label.show()
response = diaSQLLibMissing.run()
#sys.exit(1)
import fpdb_import
import fpdb_db
class GuiTableViewer (threading.Thread):
def hudDivide (self, a, b):
if b==0:
return "n/a"
else:
return str(int((a/float(b))*100))+"%"
#end def hudDivide
def hudDivide (self, a, b):
if b==0:
return "n/a"
else:
return str(int((a/float(b))*100))+"%"
#end def hudDivide
def browse_clicked(self, widget, data):
"""runs when user clicks browse on tv tab"""
#print "start of table_viewer.browser_clicked"
current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
def browse_clicked(self, widget, data):
"""runs when user clicks browse on tv tab"""
#print "start of table_viewer.browser_clicked"
current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer",
action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
#dia_chooser.set_current_folder(pathname)
dia_chooser.set_filename(current_path)
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer",
action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
#dia_chooser.set_current_folder(pathname)
dia_chooser.set_filename(current_path)
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
response = dia_chooser.run()
if response == gtk.RESPONSE_OK:
#print dia_chooser.get_filename(), 'selected'
self.filename_tbuffer.set_text(dia_chooser.get_filename())
elif response == gtk.RESPONSE_CANCEL:
print 'Closed, no files selected'
dia_chooser.destroy()
#end def table_viewer.browse_clicked
response = dia_chooser.run()
if response == gtk.RESPONSE_OK:
#print dia_chooser.get_filename(), 'selected'
self.filename_tbuffer.set_text(dia_chooser.get_filename())
elif response == gtk.RESPONSE_CANCEL:
print 'Closed, no files selected'
dia_chooser.destroy()
#end def table_viewer.browse_clicked
def prepare_data(self):
"""prepares the data for display by refresh_clicked, returns a 2D array"""
#print "start of prepare_data"
arr=[]
#first prepare the header row
if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"):
tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST")
def prepare_data(self):
"""prepares the data for display by refresh_clicked, returns a 2D array"""
#print "start of prepare_data"
arr=[]
#first prepare the header row
if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"):
tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST")
tmp+=("FS", "FB")
tmp+=("FS", "FB")
tmp+=("CB", )
tmp+=("CB", )
tmp+=("2B", "3B")
tmp+=("2B", "3B")
tmp+=("AF", "FF", "AT", "FT", "AR", "FR")
tmp+=("AF", "FF", "AT", "FT", "AR", "FR")
tmp+=("WtSD", "W$wsF", "W$SD")
else:
raise fpdb_simple.FpdbError("reimplement stud")
arr.append(tmp)
tmp+=("WtSD", "W$wsF", "W$SD")
else:
raise fpdb_simple.FpdbError("reimplement stud")
arr.append(tmp)
#then the data rows
for player in range(len(self.player_names)):
tmp=[]
tmp.append(self.player_names[player][0])
#then the data rows
for player in range(len(self.player_names)):
tmp=[]
tmp.append(self.player_names[player][0])
seatCount=len(self.player_names)
if seatCount>=8:
minSeats,maxSeats=7,10
elif seatCount==7:
minSeats,maxSeats=6,10
elif seatCount==6 or seatCount==5:
minSeats,maxSeats=seatCount-1,seatCount+1
elif seatCount==4:
minSeats,maxSeats=4,5
elif seatCount==2 or seatCount==3:
minSeats,maxSeats=seatCount,seatCount
else:
fpdb_simple.FpdbError("invalid seatCount")
seatCount=len(self.player_names)
if seatCount>=8:
minSeats,maxSeats=7,10
elif seatCount==7:
minSeats,maxSeats=6,10
elif seatCount==6 or seatCount==5:
minSeats,maxSeats=seatCount-1,seatCount+1
elif seatCount==4:
minSeats,maxSeats=4,5
elif seatCount==2 or seatCount==3:
minSeats,maxSeats=seatCount,seatCount
else:
fpdb_simple.FpdbError("invalid seatCount")
self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats))
rows=self.cursor.fetchall()
self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats))
rows=self.cursor.fetchall()
row=[]
for field_no in range(len(rows[0])):
row.append(rows[0][field_no])
row=[]
for field_no in range(len(rows[0])):
row.append(rows[0][field_no])
for row_no in range(len(rows)):
if row_no==0:
pass
else:
for field_no in range(len(rows[row_no])):
if field_no<=3:
pass
else:
#print "in prep data, row_no:",row_no,"field_no:",field_no
row[field_no]+=rows[row_no][field_no]
for row_no in range(len(rows)):
if row_no==0:
pass
else:
for field_no in range(len(rows[row_no])):
if field_no<=3:
pass
else:
#print "in prep data, row_no:",row_no,"field_no:",field_no
row[field_no]+=rows[row_no][field_no]
tmp.append(str(row[6]))#Hands
tmp.append(self.hudDivide(row[7],row[6])) #VPIP
tmp.append(self.hudDivide(row[8],row[6])) #PFR
tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B
tmp.append(str(row[6]))#Hands
tmp.append(self.hudDivide(row[7],row[6])) #VPIP
tmp.append(self.hudDivide(row[8],row[6])) #PFR
tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B
tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST
tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST
tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS
tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB
tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS
tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB
tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB
tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB
tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B
tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B
tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B
tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B
tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF
tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF
tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT
tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT
tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR
tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR
tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF
tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF
tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT
tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT
tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR
tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR
tmp.append(self.hudDivide(row[15],row[11])) #WtSD
tmp.append(self.hudDivide(row[28],row[11])) #W$wSF
tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD
tmp.append(self.hudDivide(row[15],row[11])) #WtSD
tmp.append(self.hudDivide(row[28],row[11])) #W$wSF
tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD
arr.append(tmp)
return arr
#end def table_viewer.prepare_data
arr.append(tmp)
return arr
#end def table_viewer.prepare_data
def refresh_clicked(self, widget, data):
"""runs when user clicks refresh"""
#print "start of table_viewer.refresh_clicked"
arr=self.prepare_data()
def refresh_clicked(self, widget, data):
"""runs when user clicks refresh"""
#print "start of table_viewer.refresh_clicked"
arr=self.prepare_data()
try: self.data_table.destroy()
except AttributeError: pass
self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False)
self.main_vbox.pack_start(self.data_table)
self.data_table.show()
try: self.data_table.destroy()
except AttributeError: pass
self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False)
self.main_vbox.pack_start(self.data_table)
self.data_table.show()
for row in range(len(arr)):
for column in range (len(arr[row])):
eventBox=gtk.EventBox()
new_label=gtk.Label(arr[row][column])
if row%2==0: #
bg_col="white"
if column==0 or (column>=5 and column<=10):
bg_col="lightgrey"
else:
bg_col="lightgrey"
if column==0 or (column>=5 and column<=10):
bg_col="grey"
#style = eventBox.get_style()
#style.font.height=8
#eventBox.set_style(style)
for row in range(len(arr)):
for column in range (len(arr[row])):
eventBox=gtk.EventBox()
new_label=gtk.Label(arr[row][column])
if row%2==0: #
bg_col="white"
if column==0 or (column>=5 and column<=10):
bg_col="lightgrey"
else:
bg_col="lightgrey"
if column==0 or (column>=5 and column<=10):
bg_col="grey"
#style = eventBox.get_style()
#style.font.height=8
#eventBox.set_style(style)
eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col))
eventBox.add(new_label)
self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1)
eventBox.show()
new_label.show()
#end def table_viewer.refresh_clicked
eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col))
eventBox.add(new_label)
self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1)
eventBox.show()
new_label.show()
#end def table_viewer.refresh_clicked
def read_names_clicked(self, widget, data):
"""runs when user clicks read names"""
#print "start of table_viewer.read_names_clicked"
self.db.reconnect()
self.cursor=self.db.cursor
#self.hands_id=self.last_read_hand_id
def read_names_clicked(self, widget, data):
"""runs when user clicks read names"""
#print "start of table_viewer.read_names_clicked"
self.db.reconnect()
self.cursor=self.db.get_cursor()
#self.hands_id=self.last_read_hand_id
self.db.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, ))
self.gametype_id=self.db.cursor.fetchone()[0]
self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, ))
self.category=self.db.cursor.fetchone()[0]
#print "self.gametype_id", self.gametype_id," category:", self.category, " self.hands_id:", self.hands_id
self.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, ))
self.gametype_id=self.cursor.fetchone()[0]
self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, ))
self.category=self.cursor.fetchone()[0]
#print "self.gametype_id", self.gametype_id," category:", self.category, " self.hands_id:", self.hands_id
self.db.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_ids=self.db.cursor.fetchall()
#print "self.player_ids:",self.player_ids
self.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_ids=self.cursor.fetchall()
#print "self.player_ids:",self.player_ids
self.db.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_names=self.db.cursor.fetchall()
#print "self.player_names:",self.player_names
#end def table_viewer.read_names_clicked
self.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_names=self.cursor.fetchall()
#print "self.player_names:",self.player_names
#end def table_viewer.read_names_clicked
def import_clicked(self, widget, data):
"""runs when user clicks import"""
#print "start of table_viewer.import_clicked"
self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
def import_clicked(self, widget, data):
"""runs when user clicks import"""
#print "start of table_viewer.import_clicked"
self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
self.server=self.db.host
self.database=self.db.database
self.user=self.db.user
self.password=self.db.password
self.importer = fpdb_import.Importer(self, self.settings, self.config)
self.importer.setMinPrint(0)
self.importer.setQuiet(False)
self.importer.setFailOnError(False)
self.importer.setHandCount(0)
self.importer = fpdb_import.Importer(self, self.settings)
self.importer.setMinPrint(0)
self.importer.setQuiet(False)
self.importer.setFailOnError(False)
self.importer.setHandCount(0)
self.importer.addImportFile(self.inputFile)
self.importer.runImport()
self.hands_id=self.importer.handsId
#end def table_viewer.import_clicked
self.importer.addImportFile(self.inputFile)
self.importer.runImport()
self.hands_id=self.importer.handsId
#end def table_viewer.import_clicked
def all_clicked(self, widget, data):
"""runs when user clicks all"""
#print "start of table_viewer.all_clicked"
self.import_clicked(widget, data)
self.read_names_clicked(widget, data)
self.refresh_clicked(widget, data)
#end def table_viewer.all_clicked
def all_clicked(self, widget, data):
"""runs when user clicks all"""
#print "start of table_viewer.all_clicked"
self.import_clicked(widget, data)
self.read_names_clicked(widget, data)
self.refresh_clicked(widget, data)
#end def table_viewer.all_clicked
def get_vbox(self):
"""returns the vbox of this thread"""
return self.main_vbox
#end def get_vbox
def get_vbox(self):
"""returns the vbox of this thread"""
return self.main_vbox
#end def get_vbox
def __init__(self, db, settings, config=None, debug=True):
"""Constructor for table_viewer"""
self.debug=debug
#print "start of table_viewer constructor"
self.db = db
self.cursor = db.get_cursor()
self.settings = settings
self.config = config
def __init__(self, db, settings, debug=True):
"""Constructor for table_viewer"""
self.debug=debug
#print "start of table_viewer constructor"
self.db=db
self.cursor=db.cursor
self.settings=settings
self.main_vbox = gtk.VBox(False, 0)
self.main_vbox.show()
self.main_vbox = gtk.VBox(False, 0)
self.main_vbox.show()
self.settings_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.settings_hbox, False, True, 0)
self.settings_hbox.show()
self.settings_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.settings_hbox, False, True, 0)
self.settings_hbox.show()
self.filename_label = gtk.Label("Path of history file")
self.settings_hbox.pack_start(self.filename_label, False, False)
self.filename_label.show()
self.filename_label = gtk.Label("Path of history file")
self.settings_hbox.pack_start(self.filename_label, False, False)
self.filename_label.show()
self.filename_tbuffer=gtk.TextBuffer()
self.filename_tbuffer.set_text(self.settings['hud-defaultPath'])
self.filename_tview=gtk.TextView(self.filename_tbuffer)
self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5)
self.filename_tview.show()
self.filename_tbuffer=gtk.TextBuffer()
self.filename_tbuffer.set_text(self.settings['hud-defaultPath'])
self.filename_tview=gtk.TextView(self.filename_tbuffer)
self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5)
self.filename_tview.show()
self.browse_button=gtk.Button("Browse...")
self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked")
self.settings_hbox.pack_start(self.browse_button, False, False)
self.browse_button.show()
self.browse_button=gtk.Button("Browse...")
self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked")
self.settings_hbox.pack_start(self.browse_button, False, False)
self.browse_button.show()
self.button_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.button_hbox, False, True, 0)
self.button_hbox.show()
self.button_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.button_hbox, False, True, 0)
self.button_hbox.show()
#self.import_button = gtk.Button("Import")
#self.import_button.connect("clicked", self.import_clicked, "Import clicked")
#self.button_hbox.add(self.import_button)
#self.import_button.show()
#self.import_button = gtk.Button("Import")
#self.import_button.connect("clicked", self.import_clicked, "Import clicked")
#self.button_hbox.add(self.import_button)
#self.import_button.show()
#self.read_names_button = gtk.Button("Read Names")
#self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked")
#self.button_hbox.add(self.read_names_button)
#self.read_names_button.show()
#self.read_names_button = gtk.Button("Read Names")
#self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked")
#self.button_hbox.add(self.read_names_button)
#self.read_names_button.show()
#self.refresh_button = gtk.Button("Show/Refresh data")
#self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked")
#self.button_hbox.add(self.refresh_button)
#self.refresh_button.show()
#self.refresh_button = gtk.Button("Show/Refresh data")
#self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked")
#self.button_hbox.add(self.refresh_button)
#self.refresh_button.show()
self.all_button = gtk.Button("Import&Read&Refresh")
self.all_button.connect("clicked", self.all_clicked, "All clicked")
self.button_hbox.add(self.all_button)
self.all_button.show()
#end of table_viewer.__init__
self.all_button = gtk.Button("Import&Read&Refresh")
self.all_button.connect("clicked", self.all_clicked, "All clicked")
self.button_hbox.add(self.all_button)
self.all_button.show()
#end of table_viewer.__init__

View File

@ -432,7 +432,8 @@
</hhcs>
<supported_databases>
<database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD" db_type="fpdb"></database>
<database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD" db_type="fpdb"></database>
<!-- <database db_ip="localhost" db_name="fpdb" db_pass="fpdb" db_server="sqlite" db_type="fpdb" db_user="fpdb"/> -->
</supported_databases>
</FreePokerToolsConfig>

View File

@ -37,7 +37,7 @@ import traceback
if not options.errorsToConsole:
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
errorFile = open('fpdb-error-log.txt', 'w', 0)
errorFile = open('HUD-error.txt', 'w', 0)
sys.stderr = errorFile
import thread

View File

@ -60,6 +60,8 @@ class Hud:
def __init__(self, parent, table, max, poker_game, config, db_connection):
# __init__ is (now) intended to be called from the stdin thread, so it
# cannot touch the gui
if parent == None: # running from cli ..
self.parent = self
self.parent = parent
self.table = table
self.config = config
@ -125,7 +127,8 @@ class Hud:
self.menu = gtk.Menu()
self.item1 = gtk.MenuItem('Kill this HUD')
self.menu.append(self.item1)
self.item1.connect("activate", self.parent.kill_hud, self.table_name)
if self.parent != None:
self.item1.connect("activate", self.parent.kill_hud, self.table_name)
self.item1.show()
self.item2 = gtk.MenuItem('Save Layout')
@ -233,7 +236,7 @@ class Hud:
# Need range here, not xrange -> need the actual list
adj = range(0, self.max + 1) # default seat adjustments = no adjustment
# does the user have a fav_seat?
if int(config.supported_sites[self.table.site].layout[self.max].fav_seat) > 0:
if self.table.site != None and int(config.supported_sites[self.table.site].layout[self.max].fav_seat) > 0:
try:
fav_seat = config.supported_sites[self.table.site].layout[self.max].fav_seat
actual_seat = self.get_actual_seat(config.supported_sites[self.table.site].screen_name)
@ -600,15 +603,17 @@ if __name__== "__main__":
c = Configuration.Config()
#tables = Tables.discover(c)
t = Tables.discover_table_by_name(c, "Motorway")
t = Tables.discover_table_by_name(c, "Patriot Dr")
if t is None:
print "Table not found."
db = Database.Database(c, 'fpdb', 'holdem')
stat_dict = db.get_stats_from_hand(1)
# for t in tables:
win = Hud(t, 10, 'holdem', c, db)
win.create(1, c)
win = Hud(None, t, 10, 'holdem', c, db) # parent, table, max, poker_game, config, db_connection
win.create(1, c, stat_dict, None) # hand, config, stat_dict, cards):
# t.get_details()
win.update(8300, db, c)
win.update(8300, c) # self, hand, config):
gtk.main()

View File

@ -410,16 +410,37 @@ class Sql:
elif db_server == 'sqlite':
self.query['createHandsTable'] = """CREATE TABLE Hands (
id INTEGER PRIMARY KEY,
tableName TEXT(20),
siteHandNo INTEGER,
gametypeId INTEGER,
handStart REAL,
importTime REAL,
seats INTEGER,
maxSeats INTEGER,
tableName TEXT(20) NOT NULL,
siteHandNo INT NOT NULL,
gametypeId INT NOT NULL,
handStart REAL NOT NULL,
importTime REAL NOT NULL,
seats INT NOT NULL,
maxSeats INT NOT NULL,
boardcard1 INT, /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */
boardcard2 INT,
boardcard3 INT,
boardcard4 INT,
boardcard5 INT,
texture INT,
playersVpi INT NOT NULL, /* num of players vpi */
playersAtStreet1 INT NOT NULL, /* num of players seeing flop/street4 */
playersAtStreet2 INT NOT NULL,
playersAtStreet3 INT NOT NULL,
playersAtStreet4 INT NOT NULL,
playersAtShowdown INT NOT NULL,
street0Raises INT NOT NULL, /* num small bets paid to see flop/street4, including blind */
street1Raises INT NOT NULL, /* num small bets paid to see turn/street5 */
street2Raises INT NOT NULL, /* num big bets paid to see river/street6 */
street3Raises INT NOT NULL, /* num big bets paid to see sd/street7 */
street4Raises INT NOT NULL, /* num big bets paid to see showdown */
street1Pot INT, /* pot size at flop/street4 */
street2Pot INT, /* pot size at turn/street5 */
street3Pot INT, /* pot size at river/street6 */
street4Pot INT, /* pot size at sd/street7 */
showdownPot INT, /* pot size at sd/street7 */
comment TEXT,
commentTs REAL,
FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)"""
commentTs REAL)"""
################################
@ -919,78 +940,78 @@ class Sql:
styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
HDs INT NOT NULL,
wonWhenSeenStreet1 FLOAT NOT NULL,
wonWhenSeenStreet1 FLOAT,
wonWhenSeenStreet2 FLOAT,
wonWhenSeenStreet3 FLOAT,
wonWhenSeenStreet4 FLOAT,
wonAtSD FLOAT NOT NULL,
wonAtSD FLOAT,
street0VPI INT NOT NULL,
street0Aggr INT NOT NULL,
street0_3BChance INT NOT NULL,
street0_3BDone INT NOT NULL,
street0VPI INT,
street0Aggr INT,
street0_3BChance INT,
street0_3BDone INT,
street0_4BChance INT,
street0_4BDone INT,
other3BStreet0 INT,
other4BStreet0 INT,
street1Seen INT NOT NULL,
street2Seen INT NOT NULL,
street3Seen INT NOT NULL,
street4Seen INT NOT NULL,
sawShowdown INT NOT NULL,
street1Seen INT,
street2Seen INT,
street3Seen INT,
street4Seen INT,
sawShowdown INT,
street1Aggr INT NOT NULL,
street2Aggr INT NOT NULL,
street3Aggr INT NOT NULL,
street4Aggr INT NOT NULL,
street1Aggr INT,
street2Aggr INT,
street3Aggr INT,
street4Aggr INT,
otherRaisedStreet0 INT,
otherRaisedStreet1 INT NOT NULL,
otherRaisedStreet2 INT NOT NULL,
otherRaisedStreet3 INT NOT NULL,
otherRaisedStreet4 INT NOT NULL,
otherRaisedStreet1 INT,
otherRaisedStreet2 INT,
otherRaisedStreet3 INT,
otherRaisedStreet4 INT,
foldToOtherRaisedStreet0 INT,
foldToOtherRaisedStreet1 INT NOT NULL,
foldToOtherRaisedStreet2 INT NOT NULL,
foldToOtherRaisedStreet3 INT NOT NULL,
foldToOtherRaisedStreet4 INT NOT NULL,
foldToOtherRaisedStreet1 INT,
foldToOtherRaisedStreet2 INT,
foldToOtherRaisedStreet3 INT,
foldToOtherRaisedStreet4 INT,
stealAttemptChance INT NOT NULL,
stealAttempted INT NOT NULL,
foldBbToStealChance INT NOT NULL,
foldedBbToSteal INT NOT NULL,
foldSbToStealChance INT NOT NULL,
foldedSbToSteal INT NOT NULL,
stealAttemptChance INT,
stealAttempted INT,
foldBbToStealChance INT,
foldedBbToSteal INT,
foldSbToStealChance INT,
foldedSbToSteal INT,
street1CBChance INT NOT NULL,
street1CBDone INT NOT NULL,
street2CBChance INT NOT NULL,
street2CBDone INT NOT NULL,
street3CBChance INT NOT NULL,
street3CBDone INT NOT NULL,
street4CBChance INT NOT NULL,
street4CBDone INT NOT NULL,
street1CBChance INT,
street1CBDone INT,
street2CBChance INT,
street2CBDone INT,
street3CBChance INT,
street3CBDone INT,
street4CBChance INT,
street4CBDone INT,
foldToStreet1CBChance INT NOT NULL,
foldToStreet1CBDone INT NOT NULL,
foldToStreet2CBChance INT NOT NULL,
foldToStreet2CBDone INT NOT NULL,
foldToStreet3CBChance INT NOT NULL,
foldToStreet3CBDone INT NOT NULL,
foldToStreet4CBChance INT NOT NULL,
foldToStreet4CBDone INT NOT NULL,
foldToStreet1CBChance INT,
foldToStreet1CBDone INT,
foldToStreet2CBChance INT,
foldToStreet2CBDone INT,
foldToStreet3CBChance INT,
foldToStreet3CBDone INT,
foldToStreet4CBChance INT,
foldToStreet4CBDone INT,
totalProfit INT NOT NULL,
totalProfit INT,
street1CheckCallRaiseChance INT NOT NULL,
street1CheckCallRaiseDone INT NOT NULL,
street2CheckCallRaiseChance INT NOT NULL,
street2CheckCallRaiseDone INT NOT NULL,
street3CheckCallRaiseChance INT NOT NULL,
street3CheckCallRaiseDone INT NOT NULL,
street4CheckCallRaiseChance INT NOT NULL,
street4CheckCallRaiseDone INT NOT NULL,
street1CheckCallRaiseChance INT,
street1CheckCallRaiseDone INT,
street2CheckCallRaiseChance INT,
street2CheckCallRaiseDone INT,
street3CheckCallRaiseChance INT,
street3CheckCallRaiseDone INT,
street4CheckCallRaiseChance INT,
street4CheckCallRaiseDone INT,
street0Calls INT,
street1Calls INT,
@ -1020,16 +1041,16 @@ class Sql:
styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
HDs INT,
wonWhenSeenStreet1 FLOAT NOT NULL,
wonWhenSeenStreet1 FLOAT,
wonWhenSeenStreet2 FLOAT,
wonWhenSeenStreet3 FLOAT,
wonWhenSeenStreet4 FLOAT,
wonAtSD FLOAT NOT NULL,
wonAtSD FLOAT,
street0VPI INT NOT NULL,
street0VPI INT,
street0Aggr INT,
street0_3BChance INT NOT NULL,
street0_3BDone INT NOT NULL,
street0_3BChance INT,
street0_3BDone INT,
street0_4BChance INT,
street0_4BDone INT,
other3BStreet0 INT,
@ -1119,16 +1140,16 @@ class Sql:
styleKey TEXT NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
HDs INT,
wonWhenSeenStreet1 REAL NOT NULL,
wonWhenSeenStreet1 REAL,
wonWhenSeenStreet2 REAL,
wonWhenSeenStreet3 REAL,
wonWhenSeenStreet4 REAL,
wonAtSD REAL NOT NULL,
wonAtSD REAL,
street0VPI INT NOT NULL,
street0VPI INT,
street0Aggr INT,
street0_3BChance INT NOT NULL,
street0_3BDone INT NOT NULL,
street0_3BChance INT,
street0_3BDone INT,
street0_4BChance INT,
street0_4BDone INT,
other3BStreet0 INT,
@ -1646,6 +1667,11 @@ class Sql:
select coalesce(max(id),0)
from Hands
where handStart < now() at time zone 'UTC' - interval '1 day'"""
elif db_server == 'sqlite':
self.query['get_hand_1day_ago'] = """
select coalesce(max(id),0)
from Hands
where handStart < strftime('%J', 'now') - 1"""
# not used yet ...
# gets a date, would need to use handsplayers (not hudcache) to get exact hand Id
@ -2084,7 +2110,7 @@ class Sql:
when stats.PlPosition = 1 then 'CO'
when stats.PlPosition = 2 then 'MP'
when stats.PlPosition = 5 then 'EP'
else '??'
else 'xx'
end AS PlPosition
,stats.n
,stats.vpip
@ -2218,7 +2244,7 @@ class Sql:
when stats.PlPosition = 1 then 'CO'
when stats.PlPosition = 2 then 'MP'
when stats.PlPosition = 5 then 'EP'
else '??'
else 'xx'
end AS PlPosition
,stats.n
,stats.vpip
@ -2515,7 +2541,7 @@ class Sql:
,hp.tourneyTypeId
,date_format(h.handStart, 'd%y%m%d')
"""
else: # assume postgres
elif db_server == 'postgresql':
self.query['rebuildHudCache'] = """
INSERT INTO HudCache
(gametypeId
@ -2663,6 +2689,154 @@ class Sql:
,hp.tourneyTypeId
,to_char(h.handStart, 'YYMMDD')
"""
else: # assume sqlite
self.query['rebuildHudCache'] = """
INSERT INTO HudCache
(gametypeId
,playerId
,activeSeats
,position
,tourneyTypeId
,styleKey
,HDs
,wonWhenSeenStreet1
,wonAtSD
,street0VPI
,street0Aggr
,street0_3BChance
,street0_3BDone
,street1Seen
,street2Seen
,street3Seen
,street4Seen
,sawShowdown
,street1Aggr
,street2Aggr
,street3Aggr
,street4Aggr
,otherRaisedStreet1
,otherRaisedStreet2
,otherRaisedStreet3
,otherRaisedStreet4
,foldToOtherRaisedStreet1
,foldToOtherRaisedStreet2
,foldToOtherRaisedStreet3
,foldToOtherRaisedStreet4
,stealAttemptChance
,stealAttempted
,foldBbToStealChance
,foldedBbToSteal
,foldSbToStealChance
,foldedSbToSteal
,street1CBChance
,street1CBDone
,street2CBChance
,street2CBDone
,street3CBChance
,street3CBDone
,street4CBChance
,street4CBDone
,foldToStreet1CBChance
,foldToStreet1CBDone
,foldToStreet2CBChance
,foldToStreet2CBDone
,foldToStreet3CBChance
,foldToStreet3CBDone
,foldToStreet4CBChance
,foldToStreet4CBDone
,totalProfit
,street1CheckCallRaiseChance
,street1CheckCallRaiseDone
,street2CheckCallRaiseChance
,street2CheckCallRaiseDone
,street3CheckCallRaiseChance
,street3CheckCallRaiseDone
,street4CheckCallRaiseChance
,street4CheckCallRaiseDone
)
SELECT h.gametypeId
,hp.playerId
,h.seats
,case when hp.position = 'B' then 'B'
when hp.position = 'S' then 'S'
when hp.position = '0' then 'D'
when hp.position = '1' then 'C'
when hp.position = '2' then 'M'
when hp.position = '3' then 'M'
when hp.position = '4' then 'M'
when hp.position = '5' then 'E'
when hp.position = '6' then 'E'
when hp.position = '7' then 'E'
when hp.position = '8' then 'E'
when hp.position = '9' then 'E'
else 'E'
end AS hc_position
,hp.tourneyTypeId
,'d' || substr(strftime('%Y%m%d', h.handStart),3,7)
,count(1)
,sum(wonWhenSeenStreet1)
,sum(wonAtSD)
,sum(CAST(street0VPI as integer))
,sum(CAST(street0Aggr as integer))
,sum(CAST(street0_3BChance as integer))
,sum(CAST(street0_3BDone as integer))
,sum(CAST(street1Seen as integer))
,sum(CAST(street2Seen as integer))
,sum(CAST(street3Seen as integer))
,sum(CAST(street4Seen as integer))
,sum(CAST(sawShowdown as integer))
,sum(CAST(street1Aggr as integer))
,sum(CAST(street2Aggr as integer))
,sum(CAST(street3Aggr as integer))
,sum(CAST(street4Aggr as integer))
,sum(CAST(otherRaisedStreet1 as integer))
,sum(CAST(otherRaisedStreet2 as integer))
,sum(CAST(otherRaisedStreet3 as integer))
,sum(CAST(otherRaisedStreet4 as integer))
,sum(CAST(foldToOtherRaisedStreet1 as integer))
,sum(CAST(foldToOtherRaisedStreet2 as integer))
,sum(CAST(foldToOtherRaisedStreet3 as integer))
,sum(CAST(foldToOtherRaisedStreet4 as integer))
,sum(CAST(stealAttemptChance as integer))
,sum(CAST(stealAttempted as integer))
,sum(CAST(foldBbToStealChance as integer))
,sum(CAST(foldedBbToSteal as integer))
,sum(CAST(foldSbToStealChance as integer))
,sum(CAST(foldedSbToSteal as integer))
,sum(CAST(street1CBChance as integer))
,sum(CAST(street1CBDone as integer))
,sum(CAST(street2CBChance as integer))
,sum(CAST(street2CBDone as integer))
,sum(CAST(street3CBChance as integer))
,sum(CAST(street3CBDone as integer))
,sum(CAST(street4CBChance as integer))
,sum(CAST(street4CBDone as integer))
,sum(CAST(foldToStreet1CBChance as integer))
,sum(CAST(foldToStreet1CBDone as integer))
,sum(CAST(foldToStreet2CBChance as integer))
,sum(CAST(foldToStreet2CBDone as integer))
,sum(CAST(foldToStreet3CBChance as integer))
,sum(CAST(foldToStreet3CBDone as integer))
,sum(CAST(foldToStreet4CBChance as integer))
,sum(CAST(foldToStreet4CBDone as integer))
,sum(CAST(totalProfit as integer))
,sum(CAST(street1CheckCallRaiseChance as integer))
,sum(CAST(street1CheckCallRaiseDone as integer))
,sum(CAST(street2CheckCallRaiseChance as integer))
,sum(CAST(street2CheckCallRaiseDone as integer))
,sum(CAST(street3CheckCallRaiseChance as integer))
,sum(CAST(street3CheckCallRaiseDone as integer))
,sum(CAST(street4CheckCallRaiseChance as integer))
,sum(CAST(street4CheckCallRaiseDone as integer))
FROM HandsPlayers hp
INNER JOIN Hands h ON (h.id = hp.handId)
GROUP BY h.gametypeId
,hp.playerId
,h.seats
,hc_position
,hp.tourneyTypeId
,'d' || substr(strftime('%Y%m%d', h.handStart),3,7)
"""
if db_server == 'mysql':
self.query['analyze'] = """
@ -2681,6 +2855,44 @@ class Sql:
else: # assume postgres
self.query['lockForInsert'] = ""
self.query['getGametypeFL'] = """SELECT id
FROM Gametypes
WHERE siteId=%s
AND type=%s
AND category=%s
AND limitType=%s
AND smallBet=%s
AND bigBet=%s
"""
self.query['getGametypeNL'] = """SELECT id
FROM Gametypes
WHERE siteId=%s
AND type=%s
AND category=%s
AND limitType=%s
AND smallBlind=%s
AND bigBlind=%s
"""
self.query['insertGameTypes'] = """INSERT INTO Gametypes
(siteId, type, base, category, limitType
,hiLo, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
self.query['isAlreadyInDB'] = """SELECT id FROM Hands
WHERE gametypeId=%s AND siteHandNo=%s
"""
if db_server == 'mysql':
self.query['placeholder'] = u'%s'
elif db_server == 'postgresql':
self.query['placeholder'] = u'%s'
elif db_server == 'sqlite':
self.query['placeholder'] = u'?'
# If using sqlite, use the ? placeholder instead of %s
if db_server == 'sqlite':
for k,q in self.query.iteritems():
self.query[k] = re.sub('%s','?',q)

View File

@ -234,7 +234,7 @@ def discover_nt_by_name(c, tablename):
#print "Tables.py: tablename =", tablename, "title =", titles[hwnd]
try:
# this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html
if not tablename in titles[hwnd]: continue
if not tablename.lower() in titles[hwnd].lower(): continue
except:
continue
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window
@ -302,7 +302,9 @@ def decode_windows(c, title, hwnd):
return info
def win_enum_handler(hwnd, titles):
titles[hwnd] = win32gui.GetWindowText(hwnd)
str = win32gui.GetWindowText(hwnd)
if str != "":
titles[hwnd] = win32gui.GetWindowText(hwnd)
###################################################################
# Utility routines used by all the discoverers.

View File

@ -531,7 +531,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
def tab_table_viewer(self, widget, data=None):
"""opens a table viewer tab"""
#print "start of tab_table_viewer"
new_tv_thread=GuiTableViewer.GuiTableViewer(self.db.fdb, self.settings)
new_tv_thread = GuiTableViewer.GuiTableViewer(self.db, self.settings, self.config)
self.threads.append(new_tv_thread)
tv_tab=new_tv_thread.get_vbox()
self.add_and_display_tab(tv_tab, "Table Viewer")

View File

@ -64,7 +64,7 @@ class fpdb_db:
if backend==fpdb_db.MYSQL_INNODB:
import MySQLdb
try:
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True, charset="utf8")
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True)
except:
raise fpdb_simple.FpdbError("MySQL connection failed")
elif backend==fpdb_db.PGSQL:
@ -155,105 +155,4 @@ class fpdb_db:
return (self.host, self.database, self.user, self.password)
#end def get_db_info
def getLastInsertId(self, cursor=None):
try:
if self.backend == self.MYSQL_INNODB:
ret = self.db.insert_id()
if ret < 1 or ret > 999999999:
print "getLastInsertId(): problem fetching insert_id? ret=", ret
ret = -1
elif self.backend == self.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)
c = self.db.cursor()
ret = c.execute ("SELECT lastval()")
row = c.fetchone()
if not row:
print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row
ret = -1
else:
ret = row[0]
elif self.backend == fpdb_db.SQLITE:
ret = cursor.lastrowid
else:
print "getLastInsertId(): unknown backend ", self.backend
ret = -1
except:
ret = -1
print "getLastInsertId error:", str(sys.exc_value), " ret =", ret
raise fpdb_simple.FpdbError( "getLastInsertId error: " + str(sys.exc_value) )
return ret
def storeHand(self, p):
#stores into table hands:
self.cursor.execute ("""INSERT INTO Hands (
tablename,
sitehandno,
gametypeid,
handstart,
importtime,
seats,
maxseats,
boardcard1,
boardcard2,
boardcard3,
boardcard4,
boardcard5,
-- texture,
playersVpi,
playersAtStreet1,
playersAtStreet2,
playersAtStreet3,
playersAtStreet4,
playersAtShowdown,
street0Raises,
street1Raises,
street2Raises,
street3Raises,
street4Raises,
-- street1Pot,
-- street2Pot,
-- street3Pot,
-- street4Pot,
-- showdownPot
)
VALUES
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s)""",
(
p['tablename'],
p['sitehandno'],
p['gametypeid'],
p['handStart'],
datetime.datetime.today(),
len(p['names']),
p['maxSeats'],
p['boardcard1'],
p['boardcard2'],
p['boardcard3'],
p['boardcard4'],
p['boardcard5'],
hudCache['playersVpi'],
hudCache['playersAtStreet1'],
hudCache['playersAtStreet2'],
hudCache['playersAtStreet3'],
hudCache['playersAtStreet4'],
hudCache['playersAtShowdown'],
hudCache['street0Raises'],
hudCache['street1Raises'],
hudCache['street2Raises'],
hudCache['street3Raises'],
hudCache['street4Raises'],
hudCache['street1Pot'],
hudCache['street2Pot'],
hudCache['street3Pot'],
hudCache['street4Pot'],
hudCache['showdownPot']
)
)
#return getLastInsertId(backend, conn, cursor)
#end class fpdb_db

View File

@ -85,6 +85,8 @@ class Importer:
#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.settings.setdefault("dropIndexes", "don't drop")
self.settings.setdefault("dropHudCache", "don't drop")
self.writeq = None
self.database = Database.Database(self.config, sql = self.sql)
@ -380,7 +382,7 @@ class Importer:
# Load filter, process file, pass returned filename to import_fpdb_file
if self.writeq != None:
if self.settings['threads'] > 0 and self.writeq != None:
print "\nConverting " + file + " (" + str(q.qsize()) + ")"
else:
print "\nConverting " + file

View File

@ -79,7 +79,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
rebuyOrAddon = -1
tourneyTypeId = 1
fpdb_simple.isAlreadyInDB(db.get_cursor(), gametypeID, siteHandNo)
fpdb_simple.isAlreadyInDB(db, gametypeID, siteHandNo)
hand = fpdb_simple.filterCrap(hand, isTourney)
@ -93,7 +93,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
seatLines.append(line)
names = fpdb_simple.parseNames(seatLines)
playerIDs = fpdb_simple.recognisePlayerIDs(db.get_cursor(), names, siteID) # inserts players as needed
playerIDs = fpdb_simple.recognisePlayerIDs(db, names, siteID) # inserts players as needed
tmp = fpdb_simple.parseCashesAndSeatNos(seatLines)
startCashes = tmp['startCashes']
seatNos = tmp['seatNos']
@ -141,7 +141,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
fpdb_simple.checkPositions(positions)
c = db.get_cursor()
c.execute("SELECT limitType FROM Gametypes WHERE id=%s",(gametypeID, ))
c.execute("SELECT limitType FROM Gametypes WHERE id=%s" % (db.sql.query['placeholder'],), (gametypeID, ))
limit_type = c.fetchone()[0]
fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts)

View File

@ -400,10 +400,11 @@ def isActionLine(line):
#end def isActionLine
#returns whether this is a duplicate
def isAlreadyInDB(cursor, gametypeID, siteHandNo):
def isAlreadyInDB(db, gametypeID, siteHandNo):
#print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo
cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo))
result=cursor.fetchall()
c = db.get_cursor()
c.execute( db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo))
result = c.fetchall()
if (len(result)>=1):
raise DuplicateError ("dupl")
#end isAlreadyInDB
@ -898,9 +899,11 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c
#print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type
if (limit_type=="fl"):
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
cursor.execute ( db.sql.query['getGametypeFL']
, (site_id, type, category, limit_type, small_bet, big_bet))
else:
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
cursor.execute ( db.sql.query['getGametypeNL']
, (site_id, type, category, limit_type, small_bet, big_bet))
result=cursor.fetchone()
#print "recgt1 result=",result
#ret=result[0]
@ -935,25 +938,16 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c
small_blind=float2int(smallBlindLine[pos:])
else:
small_blind=0
cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType
,hiLo, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
, (site_id, type, base, category, limit_type, hiLo
,small_blind, big_blind, small_bet, big_bet) )
result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo
,small_blind, big_blind, small_bet, big_bet) )
#cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s
#AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
else:
cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType
,hiLo, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
, (site_id, type, base, category, limit_type
,hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo
,small_bet, big_bet, 0, 0) )#remember, for these bet means blind
#cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s
#AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
#result=(db.insert_id(),)
result=(db.get_last_insert_id(),)
return result[0]
#end def recogniseGametypeID
@ -990,17 +984,21 @@ def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
# result.append(tmp[0][0])
# return result
def recognisePlayerIDs(cursor, names, site_id):
q = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in names])
cursor.execute(q, names) # get all playerids by the names passed in
ids = dict(cursor.fetchall()) # convert to dict
def recognisePlayerIDs(db, names, site_id):
c = db.get_cursor()
q = "SELECT name,id FROM Players WHERE siteid=%d and (name=%s)" %(site_id, " OR name=".join([db.sql.query['placeholder'] for n in names]))
c.execute(q, names) # get all playerids by the names passed in
ids = dict(c.fetchall()) # convert to dict
if len(ids) != len(names):
notfound = [n for n in names if n not in ids] # make list of names not in database
if notfound: # insert them into database
cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", [(n,) for n in notfound])
q2 = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in notfound])
cursor.execute(q2, notfound) # get their new ids
tmp = cursor.fetchall()
q_ins = "INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")"
q_ins = q_ins.replace('%s', db.sql.query['placeholder'])
c.executemany(q_ins, [(n,) for n in notfound])
q2 = "SELECT name,id FROM Players WHERE siteid=%d and (name=%s)" % (site_id, " OR name=".join(["%s" for n in notfound]))
q2 = q2.replace('%s', db.sql.query['placeholder'])
c.execute(q2, notfound) # get their new ids
tmp = c.fetchall()
for n,id in tmp: # put them all into the same dict
ids[n] = id
# return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB