Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
commit
28345009e1
11
Makefile
Normal file
11
Makefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Variable definitions
|
||||||
|
VERSION = 0.12
|
||||||
|
DATE = $(shell date +%Y%m%d)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@echo "Usage:"
|
||||||
|
@echo " make snapshot - Tags the repository with $(VERSION)-$(DATE) and creates a tarball from that"
|
||||||
|
|
||||||
|
snapshot:
|
||||||
|
git tag $(VERSION)-$(DATE)
|
||||||
|
git archive --prefix=fpdb-$(VERSION)-$(DATE)/ $(VERSION)-$(DATE) | gzip -9 > ../fpdb-$(VERSION)-$(DATE).tar.gz
|
37
pyfpdb/Anonymise.py
Normal file
37
pyfpdb/Anonymise.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import codecs
|
||||||
|
import Options
|
||||||
|
import HandHistoryConverter
|
||||||
|
|
||||||
|
(options, argv) = Options.fpdb_options()
|
||||||
|
|
||||||
|
filter = options.hhc
|
||||||
|
|
||||||
|
filter_name = filter.replace("ToFpdb", "")
|
||||||
|
|
||||||
|
mod = __import__(filter)
|
||||||
|
obj = getattr(mod, filter_name, None)
|
||||||
|
|
||||||
|
hhc = obj(autostart=False)
|
||||||
|
|
||||||
|
if os.path.exists(options.infile):
|
||||||
|
in_fh = codecs.open(options.infile, 'r', "utf8")
|
||||||
|
filecontents = in_fh.read()
|
||||||
|
in_fh.close()
|
||||||
|
else:
|
||||||
|
print "Could not find file %s" % options.infile
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
m = hhc.re_PlayerInfo.finditer(filecontents)
|
||||||
|
|
||||||
|
players = []
|
||||||
|
for a in m:
|
||||||
|
players = players + [a.group('PNAME')]
|
||||||
|
|
||||||
|
uniq = set(players)
|
||||||
|
|
||||||
|
for i, name in enumerate(uniq, 1):
|
||||||
|
filecontents = filecontents.replace(name, 'Player%d' %i)
|
||||||
|
|
||||||
|
print filecontents
|
166
pyfpdb/Database.py
Executable file → Normal file
166
pyfpdb/Database.py
Executable file → Normal file
|
@ -59,6 +59,7 @@ class Database:
|
||||||
SQLITE = 4
|
SQLITE = 4
|
||||||
|
|
||||||
hero_hudstart_def = '1999-12-31' # default for length of Hero's stats in HUD
|
hero_hudstart_def = '1999-12-31' # default for length of Hero's stats in HUD
|
||||||
|
villain_hudstart_def = '1999-12-31' # default for length of Villain's stats in HUD
|
||||||
|
|
||||||
# Data Structures for index and foreign key creation
|
# Data Structures for index and foreign key creation
|
||||||
# drop_code is an int with possible values: 0 - don't drop for bulk import
|
# drop_code is an int with possible values: 0 - don't drop for bulk import
|
||||||
|
@ -186,6 +187,7 @@ class Database:
|
||||||
def __init__(self, c, sql = None):
|
def __init__(self, c, sql = None):
|
||||||
log.info("Creating Database instance, sql = %s" % sql)
|
log.info("Creating Database instance, sql = %s" % sql)
|
||||||
self.config = c
|
self.config = c
|
||||||
|
self.__connected = False
|
||||||
self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||||
self.do_connect(c)
|
self.do_connect(c)
|
||||||
|
|
||||||
|
@ -236,7 +238,12 @@ class Database:
|
||||||
self.hud_style = style
|
self.hud_style = style
|
||||||
|
|
||||||
def do_connect(self, c):
|
def do_connect(self, c):
|
||||||
|
try:
|
||||||
self.fdb.do_connect(c)
|
self.fdb.do_connect(c)
|
||||||
|
except:
|
||||||
|
# error during connect
|
||||||
|
self.__connected = False
|
||||||
|
raise
|
||||||
self.connection = self.fdb.db
|
self.connection = self.fdb.db
|
||||||
self.wrongDbVersion = self.fdb.wrongDbVersion
|
self.wrongDbVersion = self.fdb.wrongDbVersion
|
||||||
|
|
||||||
|
@ -246,6 +253,7 @@ class Database:
|
||||||
self.db_server = db_params['db-server']
|
self.db_server = db_params['db-server']
|
||||||
self.database = db_params['db-databaseName']
|
self.database = db_params['db-databaseName']
|
||||||
self.host = db_params['db-host']
|
self.host = db_params['db-host']
|
||||||
|
self.__connected = True
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
self.fdb.db.commit()
|
self.fdb.db.commit()
|
||||||
|
@ -253,6 +261,9 @@ class Database:
|
||||||
def rollback(self):
|
def rollback(self):
|
||||||
self.fdb.db.rollback()
|
self.fdb.db.rollback()
|
||||||
|
|
||||||
|
def connected(self):
|
||||||
|
return self.__connected
|
||||||
|
|
||||||
def get_cursor(self):
|
def get_cursor(self):
|
||||||
return self.connection.cursor()
|
return self.connection.cursor()
|
||||||
|
|
||||||
|
@ -473,8 +484,9 @@ class Database:
|
||||||
else:
|
else:
|
||||||
h_seats_min, h_seats_max = 0, 10
|
h_seats_min, h_seats_max = 0, 10
|
||||||
print "bad h_seats_style value:", h_seats_style
|
print "bad h_seats_style value:", h_seats_style
|
||||||
print "opp seats style", seats_style, "hero seats style", h_seats_style
|
log.info("opp seats style %s %d %d hero seats style %s %d %d"
|
||||||
print "opp seats:", seats_min, seats_max, " hero seats:", h_seats_min, h_seats_max
|
% (seats_style, seats_min, seats_max
|
||||||
|
,h_seats_style, h_seats_min, h_seats_max) )
|
||||||
|
|
||||||
if hud_style == 'S' or h_hud_style == 'S':
|
if hud_style == 'S' or h_hud_style == 'S':
|
||||||
self.get_stats_from_hand_session(hand, stat_dict, hero_id
|
self.get_stats_from_hand_session(hand, stat_dict, hero_id
|
||||||
|
@ -1324,7 +1336,7 @@ class Database:
|
||||||
self.dropAllForeignKeys()
|
self.dropAllForeignKeys()
|
||||||
self.createAllForeignKeys()
|
self.createAllForeignKeys()
|
||||||
|
|
||||||
def rebuild_hudcache(self, start=None):
|
def rebuild_hudcache(self, h_start=None, v_start=None):
|
||||||
"""clears hudcache and rebuilds from the individual handsplayers records"""
|
"""clears hudcache and rebuilds from the individual handsplayers records"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1344,13 +1356,17 @@ class Database:
|
||||||
if p_id:
|
if p_id:
|
||||||
self.hero_ids[site_id] = int(p_id)
|
self.hero_ids[site_id] = int(p_id)
|
||||||
|
|
||||||
if start is None:
|
if h_start is None:
|
||||||
start = self.hero_hudstart_def
|
h_start = self.hero_hudstart_def
|
||||||
|
if v_start is None:
|
||||||
|
v_start = self.villain_hudstart_def
|
||||||
if self.hero_ids == {}:
|
if self.hero_ids == {}:
|
||||||
where = ""
|
where = ""
|
||||||
else:
|
else:
|
||||||
where = "where hp.playerId not in " + str(tuple(self.hero_ids.values())) \
|
where = "where ( hp.playerId not in " + str(tuple(self.hero_ids.values())) \
|
||||||
+ " or h.handStart > '" + start + "'"
|
+ " and h.handStart > '" + v_start + "')" \
|
||||||
|
+ " or ( hp.playerId in " + str(tuple(self.hero_ids.values())) \
|
||||||
|
+ " and h.handStart > '" + h_start + "')"
|
||||||
rebuild_sql = self.sql.query['rebuildHudCache'].replace('<where_clause>', where)
|
rebuild_sql = self.sql.query['rebuildHudCache'].replace('<where_clause>', where)
|
||||||
|
|
||||||
self.get_cursor().execute(self.sql.query['clearHudCache'])
|
self.get_cursor().execute(self.sql.query['clearHudCache'])
|
||||||
|
@ -1602,103 +1618,43 @@ class Database:
|
||||||
pdata[p]['street2Bets'],
|
pdata[p]['street2Bets'],
|
||||||
pdata[p]['street3Bets'],
|
pdata[p]['street3Bets'],
|
||||||
pdata[p]['street4Bets'],
|
pdata[p]['street4Bets'],
|
||||||
|
pdata[p]['position'],
|
||||||
|
pdata[p]['tourneyTypeId'],
|
||||||
|
pdata[p]['startCards'],
|
||||||
|
pdata[p]['street0_3BChance'],
|
||||||
|
pdata[p]['street0_3BDone'],
|
||||||
|
pdata[p]['otherRaisedStreet1'],
|
||||||
|
pdata[p]['otherRaisedStreet2'],
|
||||||
|
pdata[p]['otherRaisedStreet3'],
|
||||||
|
pdata[p]['otherRaisedStreet4'],
|
||||||
|
pdata[p]['foldToOtherRaisedStreet1'],
|
||||||
|
pdata[p]['foldToOtherRaisedStreet2'],
|
||||||
|
pdata[p]['foldToOtherRaisedStreet3'],
|
||||||
|
pdata[p]['foldToOtherRaisedStreet4'],
|
||||||
|
pdata[p]['stealAttemptChance'],
|
||||||
|
pdata[p]['stealAttempted'],
|
||||||
|
pdata[p]['foldBbToStealChance'],
|
||||||
|
pdata[p]['foldedBbToSteal'],
|
||||||
|
pdata[p]['foldSbToStealChance'],
|
||||||
|
pdata[p]['foldedSbToSteal'],
|
||||||
|
pdata[p]['foldToStreet1CBChance'],
|
||||||
|
pdata[p]['foldToStreet1CBDone'],
|
||||||
|
pdata[p]['foldToStreet2CBChance'],
|
||||||
|
pdata[p]['foldToStreet2CBDone'],
|
||||||
|
pdata[p]['foldToStreet3CBChance'],
|
||||||
|
pdata[p]['foldToStreet3CBDone'],
|
||||||
|
pdata[p]['foldToStreet4CBChance'],
|
||||||
|
pdata[p]['foldToStreet4CBDone'],
|
||||||
|
pdata[p]['street1CheckCallRaiseChance'],
|
||||||
|
pdata[p]['street1CheckCallRaiseDone'],
|
||||||
|
pdata[p]['street2CheckCallRaiseChance'],
|
||||||
|
pdata[p]['street2CheckCallRaiseDone'],
|
||||||
|
pdata[p]['street3CheckCallRaiseChance'],
|
||||||
|
pdata[p]['street3CheckCallRaiseDone'],
|
||||||
|
pdata[p]['street4CheckCallRaiseChance']
|
||||||
) )
|
) )
|
||||||
|
|
||||||
q = """INSERT INTO HandsPlayers (
|
q = self.sql.query['store_hands_players']
|
||||||
handId,
|
|
||||||
playerId,
|
|
||||||
startCash,
|
|
||||||
seatNo,
|
|
||||||
card1,
|
|
||||||
card2,
|
|
||||||
card3,
|
|
||||||
card4,
|
|
||||||
card5,
|
|
||||||
card6,
|
|
||||||
card7,
|
|
||||||
winnings,
|
|
||||||
rake,
|
|
||||||
totalProfit,
|
|
||||||
street0VPI,
|
|
||||||
street1Seen,
|
|
||||||
street2Seen,
|
|
||||||
street3Seen,
|
|
||||||
street4Seen,
|
|
||||||
sawShowdown,
|
|
||||||
wonAtSD,
|
|
||||||
street0Aggr,
|
|
||||||
street1Aggr,
|
|
||||||
street2Aggr,
|
|
||||||
street3Aggr,
|
|
||||||
street4Aggr,
|
|
||||||
street1CBChance,
|
|
||||||
street2CBChance,
|
|
||||||
street3CBChance,
|
|
||||||
street4CBChance,
|
|
||||||
street1CBDone,
|
|
||||||
street2CBDone,
|
|
||||||
street3CBDone,
|
|
||||||
street4CBDone,
|
|
||||||
wonWhenSeenStreet1,
|
|
||||||
street0Calls,
|
|
||||||
street1Calls,
|
|
||||||
street2Calls,
|
|
||||||
street3Calls,
|
|
||||||
street4Calls,
|
|
||||||
street0Bets,
|
|
||||||
street1Bets,
|
|
||||||
street2Bets,
|
|
||||||
street3Bets,
|
|
||||||
street4Bets
|
|
||||||
)
|
|
||||||
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
|
|
||||||
)"""
|
|
||||||
|
|
||||||
# position,
|
|
||||||
# tourneyTypeId,
|
|
||||||
# startCards,
|
|
||||||
# street0_3BChance,
|
|
||||||
# street0_3BDone,
|
|
||||||
# otherRaisedStreet1,
|
|
||||||
# otherRaisedStreet2,
|
|
||||||
# otherRaisedStreet3,
|
|
||||||
# otherRaisedStreet4,
|
|
||||||
# foldToOtherRaisedStreet1,
|
|
||||||
# foldToOtherRaisedStreet2,
|
|
||||||
# foldToOtherRaisedStreet3,
|
|
||||||
# foldToOtherRaisedStreet4,
|
|
||||||
# stealAttemptChance,
|
|
||||||
# stealAttempted,
|
|
||||||
# foldBbToStealChance,
|
|
||||||
# foldedBbToSteal,
|
|
||||||
# foldSbToStealChance,
|
|
||||||
# foldedSbToSteal,
|
|
||||||
# foldToStreet1CBChance,
|
|
||||||
# foldToStreet1CBDone,
|
|
||||||
# foldToStreet2CBChance,
|
|
||||||
# foldToStreet2CBDone,
|
|
||||||
# foldToStreet3CBChance,
|
|
||||||
# foldToStreet3CBDone,
|
|
||||||
# foldToStreet4CBChance,
|
|
||||||
# foldToStreet4CBDone,
|
|
||||||
# street1CheckCallRaiseChance,
|
|
||||||
# street1CheckCallRaiseDone,
|
|
||||||
# street2CheckCallRaiseChance,
|
|
||||||
# street2CheckCallRaiseDone,
|
|
||||||
# street3CheckCallRaiseChance,
|
|
||||||
# street3CheckCallRaiseDone,
|
|
||||||
# street4CheckCallRaiseChance,
|
|
||||||
# street4CheckCallRaiseDone,
|
|
||||||
|
|
||||||
q = q.replace('%s', self.sql.query['placeholder'])
|
q = q.replace('%s', self.sql.query['placeholder'])
|
||||||
|
|
||||||
#print "DEBUG: inserts: %s" %inserts
|
#print "DEBUG: inserts: %s" %inserts
|
||||||
|
@ -1911,8 +1867,10 @@ class Database:
|
||||||
,(name, site_id))
|
,(name, site_id))
|
||||||
#Get last id might be faster here.
|
#Get last id might be faster here.
|
||||||
#c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
|
#c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
|
||||||
tmp = [self.get_last_insert_id(c)]
|
result = self.get_last_insert_id(c)
|
||||||
return tmp[0]
|
else:
|
||||||
|
result = tmp[1]
|
||||||
|
return result
|
||||||
|
|
||||||
def insertGameTypes(self, row):
|
def insertGameTypes(self, row):
|
||||||
c = self.get_cursor()
|
c = self.get_cursor()
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#fpdb modules
|
#fpdb modules
|
||||||
import Card
|
import Card
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
|
@ -43,9 +44,9 @@ class DerivedStats():
|
||||||
self.handsplayers[player[1]]['totalProfit'] = 0
|
self.handsplayers[player[1]]['totalProfit'] = 0
|
||||||
self.handsplayers[player[1]]['street4Seen'] = False
|
self.handsplayers[player[1]]['street4Seen'] = False
|
||||||
self.handsplayers[player[1]]['street4Aggr'] = False
|
self.handsplayers[player[1]]['street4Aggr'] = False
|
||||||
self.handsplayers[player[1]]['wonWhenSeenStreet1'] = False
|
self.handsplayers[player[1]]['wonWhenSeenStreet1'] = 0.0
|
||||||
self.handsplayers[player[1]]['sawShowdown'] = False
|
self.handsplayers[player[1]]['sawShowdown'] = False
|
||||||
self.handsplayers[player[1]]['wonAtSD'] = False
|
self.handsplayers[player[1]]['wonAtSD'] = 0.0
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
self.handsplayers[player[1]]['street%dCalls' % i] = 0
|
self.handsplayers[player[1]]['street%dCalls' % i] = 0
|
||||||
self.handsplayers[player[1]]['street%dBets' % i] = 0
|
self.handsplayers[player[1]]['street%dBets' % i] = 0
|
||||||
|
@ -53,6 +54,27 @@ class DerivedStats():
|
||||||
self.handsplayers[player[1]]['street%dCBChance' %i] = False
|
self.handsplayers[player[1]]['street%dCBChance' %i] = False
|
||||||
self.handsplayers[player[1]]['street%dCBDone' %i] = False
|
self.handsplayers[player[1]]['street%dCBDone' %i] = False
|
||||||
|
|
||||||
|
#FIXME - Everything below this point is incomplete.
|
||||||
|
self.handsplayers[player[1]]['position'] = 2
|
||||||
|
self.handsplayers[player[1]]['tourneyTypeId'] = 1
|
||||||
|
self.handsplayers[player[1]]['startCards'] = 0
|
||||||
|
self.handsplayers[player[1]]['street0_3BChance'] = False
|
||||||
|
self.handsplayers[player[1]]['street0_3BDone'] = False
|
||||||
|
self.handsplayers[player[1]]['stealAttemptChance'] = False
|
||||||
|
self.handsplayers[player[1]]['stealAttempted'] = False
|
||||||
|
self.handsplayers[player[1]]['foldBbToStealChance'] = False
|
||||||
|
self.handsplayers[player[1]]['foldBbToStealChance'] = False
|
||||||
|
self.handsplayers[player[1]]['foldSbToStealChance'] = False
|
||||||
|
self.handsplayers[player[1]]['foldedSbToSteal'] = False
|
||||||
|
self.handsplayers[player[1]]['foldedBbToSteal'] = False
|
||||||
|
for i in range(1,5):
|
||||||
|
self.handsplayers[player[1]]['otherRaisedStreet%d' %i] = False
|
||||||
|
self.handsplayers[player[1]]['foldToOtherRaisedStreet%d' %i] = False
|
||||||
|
self.handsplayers[player[1]]['foldToStreet%dCBChance' %i] = False
|
||||||
|
self.handsplayers[player[1]]['foldToStreet%dCBDone' %i] = False
|
||||||
|
self.handsplayers[player[1]]['street%dCheckCallRaiseChance' %i] = False
|
||||||
|
self.handsplayers[player[1]]['street%dCheckCallRaiseDone' %i] = False
|
||||||
|
|
||||||
self.assembleHands(self.hand)
|
self.assembleHands(self.hand)
|
||||||
self.assembleHandsPlayers(self.hand)
|
self.assembleHandsPlayers(self.hand)
|
||||||
|
|
||||||
|
@ -114,7 +136,7 @@ class DerivedStats():
|
||||||
#hand.players = [[seat, name, chips],[seat, name, chips]]
|
#hand.players = [[seat, name, chips],[seat, name, chips]]
|
||||||
for player in hand.players:
|
for player in hand.players:
|
||||||
self.handsplayers[player[1]]['seatNo'] = player[0]
|
self.handsplayers[player[1]]['seatNo'] = player[0]
|
||||||
self.handsplayers[player[1]]['startCash'] = player[2]
|
self.handsplayers[player[1]]['startCash'] = int(100 * Decimal(player[2]))
|
||||||
|
|
||||||
for i, street in enumerate(hand.actionStreets[2:]):
|
for i, street in enumerate(hand.actionStreets[2:]):
|
||||||
self.seen(self.hand, i+1)
|
self.seen(self.hand, i+1)
|
||||||
|
@ -134,9 +156,9 @@ class DerivedStats():
|
||||||
# Should be fine for split-pots, but won't be accurate for multi-way pots
|
# Should be fine for split-pots, but won't be accurate for multi-way pots
|
||||||
self.handsplayers[player]['rake'] = int(100* hand.rake)/len(hand.collectees)
|
self.handsplayers[player]['rake'] = int(100* hand.rake)/len(hand.collectees)
|
||||||
if self.handsplayers[player]['street1Seen'] == True:
|
if self.handsplayers[player]['street1Seen'] == True:
|
||||||
self.handsplayers[player]['wonWhenSeenStreet1'] = True
|
self.handsplayers[player]['wonWhenSeenStreet1'] = 1.0
|
||||||
if self.handsplayers[player]['sawShowdown'] == True:
|
if self.handsplayers[player]['sawShowdown'] == True:
|
||||||
self.handsplayers[player]['wonAtSD'] = True
|
self.handsplayers[player]['wonAtSD'] = 1.0
|
||||||
|
|
||||||
for player in hand.pot.committed:
|
for player in hand.pot.committed:
|
||||||
self.handsplayers[player]['totalProfit'] = int(self.handsplayers[player]['winnings'] - (100*hand.pot.committed[player]))
|
self.handsplayers[player]['totalProfit'] = int(self.handsplayers[player]['winnings'] - (100*hand.pot.committed[player]))
|
||||||
|
@ -149,6 +171,33 @@ class DerivedStats():
|
||||||
for i, card in enumerate(hcs[:7], 1):
|
for i, card in enumerate(hcs[:7], 1):
|
||||||
self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card)
|
self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card)
|
||||||
|
|
||||||
|
|
||||||
|
# position,
|
||||||
|
#Stud 3rd street card test
|
||||||
|
# denny501: brings in for $0.02
|
||||||
|
# s0rrow: calls $0.02
|
||||||
|
# TomSludge: folds
|
||||||
|
# Soroka69: calls $0.02
|
||||||
|
# rdiezchang: calls $0.02 (Seat 8)
|
||||||
|
# u.pressure: folds (Seat 1)
|
||||||
|
# 123smoothie: calls $0.02
|
||||||
|
# gashpor: calls $0.02
|
||||||
|
|
||||||
|
# Additional stats
|
||||||
|
# 3betSB, 3betBB
|
||||||
|
# Squeeze, Ratchet?
|
||||||
|
|
||||||
|
|
||||||
|
def getPosition(hand, seat):
|
||||||
|
"""Returns position value like 'B', 'S', 0, 1, ..."""
|
||||||
|
# Flop/Draw games with blinds
|
||||||
|
# Need a better system???
|
||||||
|
# -2 BB - B (all)
|
||||||
|
# -1 SB - S (all)
|
||||||
|
# 0 Button
|
||||||
|
# 1 Cutoff
|
||||||
|
# 2 Hijack
|
||||||
|
|
||||||
def assembleHudCache(self, hand):
|
def assembleHudCache(self, hand):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -195,6 +244,7 @@ class DerivedStats():
|
||||||
pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners)
|
pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners)
|
||||||
self.hands['playersAtShowdown'] = len(pas)
|
self.hands['playersAtShowdown'] = len(pas)
|
||||||
|
|
||||||
|
if self.hands['playersAtShowdown'] > 1:
|
||||||
for player in pas:
|
for player in pas:
|
||||||
self.handsplayers[player]['sawShowdown'] = True
|
self.handsplayers[player]['sawShowdown'] = True
|
||||||
|
|
||||||
|
|
|
@ -34,5 +34,19 @@ class FpdbMySQLNoDatabase(FpdbDatabaseError):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value +" " + self.errmsg)
|
return repr(self.value +" " + self.errmsg)
|
||||||
|
|
||||||
|
class FpdbPostgresqlAccessDenied(FpdbDatabaseError):
|
||||||
|
def __init__(self, value='', errmsg=''):
|
||||||
|
self.value = value
|
||||||
|
self.errmsg = errmsg
|
||||||
|
def __str__(self):
|
||||||
|
return repr(self.value +" " + self.errmsg)
|
||||||
|
|
||||||
|
class FpdbPostgresqlNoDatabase(FpdbDatabaseError):
|
||||||
|
def __init__(self, value='', errmsg=''):
|
||||||
|
self.value = value
|
||||||
|
self.errmsg = errmsg
|
||||||
|
def __str__(self):
|
||||||
|
return repr(self.value +" " + self.errmsg)
|
||||||
|
|
||||||
class DuplicateError(FpdbError):
|
class DuplicateError(FpdbError):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -479,7 +479,8 @@ class Filters(threading.Thread):
|
||||||
self.cursor.execute(self.sql.query['getLimits2'])
|
self.cursor.execute(self.sql.query['getLimits2'])
|
||||||
# selects limitType, bigBlind
|
# selects limitType, bigBlind
|
||||||
result = self.db.cursor.fetchall()
|
result = self.db.cursor.fetchall()
|
||||||
fl, nl = False, False
|
found = {'nl':False, 'fl':False, 'ring':False, 'tour':False}
|
||||||
|
|
||||||
if len(result) >= 1:
|
if len(result) >= 1:
|
||||||
hbox = gtk.HBox(True, 0)
|
hbox = gtk.HBox(True, 0)
|
||||||
vbox1.pack_start(hbox, False, False, 0)
|
vbox1.pack_start(hbox, False, False, 0)
|
||||||
|
@ -487,7 +488,6 @@ class Filters(threading.Thread):
|
||||||
hbox.pack_start(vbox2, False, False, 0)
|
hbox.pack_start(vbox2, False, False, 0)
|
||||||
vbox3 = gtk.VBox(False, 0)
|
vbox3 = gtk.VBox(False, 0)
|
||||||
hbox.pack_start(vbox3, False, False, 0)
|
hbox.pack_start(vbox3, False, False, 0)
|
||||||
found = {'nl':False, 'fl':False, 'ring':False, 'tour':False}
|
|
||||||
for i, line in enumerate(result):
|
for i, line in enumerate(result):
|
||||||
if "UseType" in self.display:
|
if "UseType" in self.display:
|
||||||
if line[0] != self.display["UseType"]:
|
if line[0] != self.display["UseType"]:
|
||||||
|
|
|
@ -326,6 +326,8 @@ def main(argv=None):
|
||||||
help="How often to print a one-line status report (0 (default) means never)")
|
help="How often to print a one-line status report (0 (default) means never)")
|
||||||
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
||||||
help="Print some useful one liners")
|
help="Print some useful one liners")
|
||||||
|
parser.add_option("-s", "--starsarchive", action="store_true", dest="starsArchive", default=False,
|
||||||
|
help="Do the required conversion for Stars Archive format (ie. as provided by support")
|
||||||
(options, argv) = parser.parse_args(args = argv)
|
(options, argv) = parser.parse_args(args = argv)
|
||||||
|
|
||||||
if options.usage == True:
|
if options.usage == True:
|
||||||
|
@ -369,6 +371,8 @@ def main(argv=None):
|
||||||
importer.setThreads(-1)
|
importer.setThreads(-1)
|
||||||
importer.addBulkImportImportFileOrDir(os.path.expanduser(options.filename), site=options.filtername)
|
importer.addBulkImportImportFileOrDir(os.path.expanduser(options.filename), site=options.filtername)
|
||||||
importer.setCallHud(False)
|
importer.setCallHud(False)
|
||||||
|
if options.starsArchive:
|
||||||
|
importer.setStarsArchive(True)
|
||||||
(stored, dups, partial, errs, ttime) = importer.runImport()
|
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||||
importer.clearFileList()
|
importer.clearFileList()
|
||||||
print 'GuiBulkImport done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %.0f/sec'\
|
print 'GuiBulkImport done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %.0f/sec'\
|
||||||
|
|
|
@ -31,6 +31,7 @@ try:
|
||||||
from matplotlib.figure import Figure
|
from matplotlib.figure import Figure
|
||||||
from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
|
from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
|
||||||
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
|
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
|
||||||
|
from matplotlib.font_manager import FontProperties
|
||||||
from numpy import arange, cumsum
|
from numpy import arange, cumsum
|
||||||
from pylab import *
|
from pylab import *
|
||||||
except ImportError, inst:
|
except ImportError, inst:
|
||||||
|
@ -170,7 +171,7 @@ class GuiGraphViewer (threading.Thread):
|
||||||
|
|
||||||
#Get graph data from DB
|
#Get graph data from DB
|
||||||
starttime = time()
|
starttime = time()
|
||||||
line = self.getRingProfitGraph(playerids, sitenos, limits)
|
(green, blue, red) = self.getRingProfitGraph(playerids, sitenos, limits)
|
||||||
print "Graph generated in: %s" %(time() - starttime)
|
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")
|
||||||
|
@ -179,22 +180,27 @@ class GuiGraphViewer (threading.Thread):
|
||||||
self.ax.set_xlabel("Hands", fontsize = 12)
|
self.ax.set_xlabel("Hands", fontsize = 12)
|
||||||
self.ax.set_ylabel("$", fontsize = 12)
|
self.ax.set_ylabel("$", fontsize = 12)
|
||||||
self.ax.grid(color='g', linestyle=':', linewidth=0.2)
|
self.ax.grid(color='g', linestyle=':', linewidth=0.2)
|
||||||
if line == None or line == []:
|
if green == None or green == []:
|
||||||
|
|
||||||
#TODO: Do something useful like alert user
|
#TODO: Do something useful like alert user
|
||||||
print "No hands returned by graph query"
|
print "No hands returned by graph query"
|
||||||
else:
|
else:
|
||||||
# text = "All Hands, " + sitename + str(name) + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line))
|
#text = "Profit: $%.2f\nTotal Hands: %d" %(green[-1], len(green))
|
||||||
text = "All Hands, " + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line))
|
#self.ax.annotate(text,
|
||||||
|
# xy=(10, -10),
|
||||||
self.ax.annotate(text,
|
# xycoords='axes points',
|
||||||
xy=(10, -10),
|
# horizontalalignment='left', verticalalignment='top',
|
||||||
xycoords='axes points',
|
# fontsize=10)
|
||||||
horizontalalignment='left', verticalalignment='top',
|
|
||||||
fontsize=10)
|
|
||||||
|
|
||||||
#Draw plot
|
#Draw plot
|
||||||
self.ax.plot(line,)
|
self.ax.plot(green, color='green', label='Hands: %d\nProfit: $%.2f' %(len(green), green[-1]))
|
||||||
|
self.ax.plot(blue, color='blue', label='Showdown: $%.2f' %(blue[-1]))
|
||||||
|
self.ax.plot(red, color='red', label='Non-showdown: $%.2f' %(red[-1]))
|
||||||
|
if sys.version[0:3] == '2.5':
|
||||||
|
self.ax.legend(loc='best', shadow=True, prop=FontProperties(size='smaller'))
|
||||||
|
else:
|
||||||
|
self.ax.legend(loc='best', fancybox=True, shadow=True, prop=FontProperties(size='smaller'))
|
||||||
|
|
||||||
|
|
||||||
self.graphBox.add(self.canvas)
|
self.graphBox.add(self.canvas)
|
||||||
self.canvas.show()
|
self.canvas.show()
|
||||||
|
@ -270,9 +276,13 @@ class GuiGraphViewer (threading.Thread):
|
||||||
if winnings == ():
|
if winnings == ():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
y = map(lambda x:float(x[1]), winnings)
|
green = map(lambda x:float(x[1]), winnings)
|
||||||
line = cumsum(y)
|
blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings)
|
||||||
return line/100
|
red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings)
|
||||||
|
greenline = cumsum(green)
|
||||||
|
blueline = cumsum(blue)
|
||||||
|
redline = cumsum(red)
|
||||||
|
return (greenline/100, blueline/100, redline/100)
|
||||||
#end of def getRingProfitGraph
|
#end of def getRingProfitGraph
|
||||||
|
|
||||||
def exportGraph (self, widget, data):
|
def exportGraph (self, widget, data):
|
||||||
|
|
185
pyfpdb/GuiLogView.py
Executable file
185
pyfpdb/GuiLogView.py
Executable file
|
@ -0,0 +1,185 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#Copyright 2008 Carl Gherardi
|
||||||
|
#This program is free software: you can redistribute it and/or modify
|
||||||
|
#it under the terms of the GNU Affero General Public License as published by
|
||||||
|
#the Free Software Foundation, version 3 of the License.
|
||||||
|
#
|
||||||
|
#This program is distributed in the hope that it will be useful,
|
||||||
|
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
#GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
#You should have received a copy of the GNU Affero General Public License
|
||||||
|
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#In the "official" distribution you can find the license in
|
||||||
|
#agpl-3.0.txt in the docs folder of the package.
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import Queue
|
||||||
|
|
||||||
|
import pygtk
|
||||||
|
pygtk.require('2.0')
|
||||||
|
import gtk
|
||||||
|
import gobject
|
||||||
|
import pango
|
||||||
|
|
||||||
|
import Configuration
|
||||||
|
|
||||||
|
log = Configuration.get_logger("logging.conf", "logview")
|
||||||
|
|
||||||
|
MAX_LINES = 100000 # max lines to display in window
|
||||||
|
EST_CHARS_PER_LINE = 150 # used to guesstimate number of lines in log file
|
||||||
|
logfile = 'logging.out' # name of logfile
|
||||||
|
|
||||||
|
class GuiLogView:
|
||||||
|
|
||||||
|
def __init__(self, config, mainwin, closeq):
|
||||||
|
self.config = config
|
||||||
|
self.main_window = mainwin
|
||||||
|
self.closeq = closeq
|
||||||
|
|
||||||
|
self.dia = gtk.Dialog(title="Log Messages"
|
||||||
|
,parent=None
|
||||||
|
,flags=gtk.DIALOG_DESTROY_WITH_PARENT
|
||||||
|
,buttons=(gtk.STOCK_CLOSE,gtk.RESPONSE_OK))
|
||||||
|
self.dia.set_modal(False)
|
||||||
|
|
||||||
|
self.vbox = self.dia.vbox
|
||||||
|
gtk.Widget.set_size_request(self.vbox, 700, 400);
|
||||||
|
|
||||||
|
self.liststore = gtk.ListStore(str, str, str, str, gobject.TYPE_BOOLEAN) # date, module, level, text
|
||||||
|
# this is how to add a filter:
|
||||||
|
#
|
||||||
|
# # Creation of the filter, from the model
|
||||||
|
# filter = self.liststore.filter_new()
|
||||||
|
# filter.set_visible_column(1)
|
||||||
|
#
|
||||||
|
# # The TreeView gets the filter as model
|
||||||
|
# self.listview = gtk.TreeView(filter)
|
||||||
|
self.listview = gtk.TreeView(model=self.liststore)
|
||||||
|
self.listview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_NONE)
|
||||||
|
self.listcols = []
|
||||||
|
|
||||||
|
scrolledwindow = gtk.ScrolledWindow()
|
||||||
|
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||||
|
scrolledwindow.add(self.listview)
|
||||||
|
self.vbox.pack_start(scrolledwindow, expand=True, fill=True, padding=0)
|
||||||
|
|
||||||
|
refreshbutton = gtk.Button("Refresh")
|
||||||
|
refreshbutton.connect("clicked", self.refresh, None)
|
||||||
|
self.vbox.pack_start(refreshbutton, False, False, 3)
|
||||||
|
refreshbutton.show()
|
||||||
|
|
||||||
|
self.listview.show()
|
||||||
|
scrolledwindow.show()
|
||||||
|
self.vbox.show()
|
||||||
|
self.dia.set_focus(self.listview)
|
||||||
|
|
||||||
|
col = self.addColumn("Date/Time", 0)
|
||||||
|
col = self.addColumn("Module", 1)
|
||||||
|
col = self.addColumn("Level", 2)
|
||||||
|
col = self.addColumn("Text", 3)
|
||||||
|
|
||||||
|
self.loadLog()
|
||||||
|
self.vbox.show_all()
|
||||||
|
self.dia.show()
|
||||||
|
|
||||||
|
self.dia.connect('response', self.dialog_response_cb)
|
||||||
|
|
||||||
|
def dialog_response_cb(self, dialog, response_id):
|
||||||
|
# this is called whether close button is pressed or window is closed
|
||||||
|
self.closeq.put(self.__class__)
|
||||||
|
dialog.destroy()
|
||||||
|
|
||||||
|
def get_dialog(self):
|
||||||
|
return self.dia
|
||||||
|
|
||||||
|
def addColumn(self, title, n):
|
||||||
|
col = gtk.TreeViewColumn(title)
|
||||||
|
self.listview.append_column(col)
|
||||||
|
cRender = gtk.CellRendererText()
|
||||||
|
cRender.set_property("wrap-mode", pango.WRAP_WORD_CHAR)
|
||||||
|
col.pack_start(cRender, True)
|
||||||
|
col.add_attribute(cRender, 'text', n)
|
||||||
|
col.set_max_width(1000)
|
||||||
|
col.set_spacing(0) # no effect
|
||||||
|
self.listcols.append(col)
|
||||||
|
col.set_clickable(True)
|
||||||
|
col.connect("clicked", self.sortCols, n)
|
||||||
|
return(col)
|
||||||
|
|
||||||
|
def loadLog(self):
|
||||||
|
|
||||||
|
self.liststore.clear()
|
||||||
|
self.listcols = []
|
||||||
|
|
||||||
|
# guesstimate number of lines in file
|
||||||
|
if os.path.exists(logfile):
|
||||||
|
stat_info = os.stat(logfile)
|
||||||
|
lines = stat_info.st_size / EST_CHARS_PER_LINE
|
||||||
|
print "logview: size =", stat_info.st_size, "lines =", lines
|
||||||
|
|
||||||
|
# set startline to line number to start display from
|
||||||
|
startline = 0
|
||||||
|
if lines > MAX_LINES:
|
||||||
|
# only display from startline if log file is large
|
||||||
|
startline = lines - MAX_LINES
|
||||||
|
|
||||||
|
l = 0
|
||||||
|
for line in open(logfile):
|
||||||
|
# eg line:
|
||||||
|
# 2009-12-02 15:23:21,716 - config DEBUG config logger initialised
|
||||||
|
l = l + 1
|
||||||
|
if l > startline and len(line) > 49:
|
||||||
|
iter = self.liststore.append( (line[0:23], line[26:32], line[39:46], line[48:].strip(), True) )
|
||||||
|
|
||||||
|
def sortCols(self, col, n):
|
||||||
|
try:
|
||||||
|
if not col.get_sort_indicator() or col.get_sort_order() == gtk.SORT_ASCENDING:
|
||||||
|
col.set_sort_order(gtk.SORT_DESCENDING)
|
||||||
|
else:
|
||||||
|
col.set_sort_order(gtk.SORT_ASCENDING)
|
||||||
|
self.liststore.set_sort_column_id(n, col.get_sort_order())
|
||||||
|
#self.liststore.set_sort_func(n, self.sortnums, (n,grid))
|
||||||
|
for i in xrange(len(self.listcols)):
|
||||||
|
self.listcols[i].set_sort_indicator(False)
|
||||||
|
self.listcols[n].set_sort_indicator(True)
|
||||||
|
# use this listcols[col].set_sort_indicator(True)
|
||||||
|
# to turn indicator off for other cols
|
||||||
|
except:
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])
|
||||||
|
print "***sortCols error: " + str(sys.exc_info()[1])
|
||||||
|
print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
|
||||||
|
|
||||||
|
def refresh(self, widget, data):
|
||||||
|
self.loadLog()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=="__main__":
|
||||||
|
|
||||||
|
config = Configuration.Config()
|
||||||
|
|
||||||
|
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
|
win.set_title("Test Log Viewer")
|
||||||
|
win.set_border_width(1)
|
||||||
|
win.set_default_size(600, 500)
|
||||||
|
win.set_resizable(True)
|
||||||
|
|
||||||
|
dia = gtk.Dialog("Log Viewer",
|
||||||
|
win,
|
||||||
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
(gtk.STOCK_CLOSE, gtk.RESPONSE_OK))
|
||||||
|
dia.set_default_size(500, 500)
|
||||||
|
log = GuiLogView(config, win, dia.vbox)
|
||||||
|
response = dia.run()
|
||||||
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
pass
|
||||||
|
dia.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -91,10 +91,15 @@ class GuiPrefs:
|
||||||
#iter = self.configStore.append( parent, [node.nodeValue, None] )
|
#iter = self.configStore.append( parent, [node.nodeValue, None] )
|
||||||
iter = None
|
iter = None
|
||||||
if node.nodeType != node.TEXT_NODE and node.nodeType != node.COMMENT_NODE:
|
if node.nodeType != node.TEXT_NODE and node.nodeType != node.COMMENT_NODE:
|
||||||
|
name = ""
|
||||||
iter = self.configStore.append( parent, [node, setting, value] )
|
iter = self.configStore.append( parent, [node, setting, value] )
|
||||||
if node.hasAttributes():
|
if node.hasAttributes():
|
||||||
for i in xrange(node.attributes.length):
|
for i in xrange(node.attributes.length):
|
||||||
self.configStore.append( iter, [node, node.attributes.item(i).localName, node.attributes.item(i).value] )
|
self.configStore.append( iter, [node, node.attributes.item(i).localName, node.attributes.item(i).value] )
|
||||||
|
if node.attributes.item(i).localName in ('site_name', 'game_name', 'stat_name', 'name', 'db_server', 'site'):
|
||||||
|
name = " " + node.attributes.item(i).value
|
||||||
|
if name != "":
|
||||||
|
self.configStore.set_value(iter, 1, setting+name)
|
||||||
if node.hasChildNodes():
|
if node.hasChildNodes():
|
||||||
for elem in node.childNodes:
|
for elem in node.childNodes:
|
||||||
self.addTreeRows(iter, elem)
|
self.addTreeRows(iter, elem)
|
||||||
|
@ -156,7 +161,7 @@ if __name__=="__main__":
|
||||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||||
gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
|
gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
|
||||||
dia.set_default_size(500, 500)
|
dia.set_default_size(700, 500)
|
||||||
prefs = GuiPrefs(config, win, dia.vbox)
|
prefs = GuiPrefs(config, win, dia.vbox)
|
||||||
response = dia.run()
|
response = dia.run()
|
||||||
if response == gtk.RESPONSE_ACCEPT:
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
|
|
@ -574,7 +574,7 @@ Left-Drag to Move"
|
||||||
</hhcs>
|
</hhcs>
|
||||||
|
|
||||||
<supported_databases>
|
<supported_databases>
|
||||||
<database db_ip="localhost" db_name=":memory:" db_pass="fpdb" db_server="sqlite" db_user="fpdb"/>
|
<database db_ip="localhost" db_name="fpdb" db_pass="fpdb" db_server="sqlite" db_user="fpdb"/>
|
||||||
</supported_databases>
|
</supported_databases>
|
||||||
|
|
||||||
</FreePokerToolsConfig>
|
</FreePokerToolsConfig>
|
||||||
|
|
|
@ -387,6 +387,18 @@ Left-Drag to Move"
|
||||||
<location seat="8" x="0" y="181"> </location>
|
<location seat="8" x="0" y="181"> </location>
|
||||||
<location seat="9" x="70" y="53"> </location>
|
<location seat="9" x="70" y="53"> </location>
|
||||||
</layout>
|
</layout>
|
||||||
|
<layout fav_seat="6" height="547" max="10" width="794">
|
||||||
|
<location seat="1" x="698" y="69"> </location>
|
||||||
|
<location seat="2" x="716" y="243"> </location>
|
||||||
|
<location seat="3" x="699" y="301"> </location>
|
||||||
|
<location seat="4" x="456" y="391"> </location>
|
||||||
|
<location seat="5" x="338" y="369"> </location>
|
||||||
|
<location seat="6" x="98" y="363"> </location>
|
||||||
|
<location seat="7" x="15" y="242"> </location>
|
||||||
|
<location seat="8" x="11" y="55"> </location>
|
||||||
|
<location seat="9" x="341" y="30"> </location>
|
||||||
|
<location seat="10" x="562" y="8"> </location>
|
||||||
|
</layout>
|
||||||
</site>
|
</site>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@ elif os.name == 'nt':
|
||||||
import Hud
|
import Hud
|
||||||
|
|
||||||
|
|
||||||
|
log = Configuration.get_logger("logging.conf")
|
||||||
|
|
||||||
|
|
||||||
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."""
|
||||||
# This class mainly provides state for controlling the multiple HUDs.
|
# This class mainly provides state for controlling the multiple HUDs.
|
||||||
|
@ -159,10 +162,10 @@ class HUD_main(object):
|
||||||
# function idle_func() to be run by the gui thread, at its leisure.
|
# function idle_func() to be run by the gui thread, at its leisure.
|
||||||
def idle_func():
|
def idle_func():
|
||||||
gtk.gdk.threads_enter()
|
gtk.gdk.threads_enter()
|
||||||
|
try:
|
||||||
self.hud_dict[table_name].update(new_hand_id, config)
|
self.hud_dict[table_name].update(new_hand_id, config)
|
||||||
# The HUD could get destroyed in the above call ^^, which leaves us with a KeyError here vv
|
# The HUD could get destroyed in the above call ^^, which leaves us with a KeyError here vv
|
||||||
# if we ever get an error we need to expect ^^ then we need to handle it vv - Eric
|
# if we ever get an error we need to expect ^^ then we need to handle it vv - Eric
|
||||||
try:
|
|
||||||
[aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows]
|
[aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
@ -192,6 +195,8 @@ class HUD_main(object):
|
||||||
|
|
||||||
while 1: # wait for a new hand number on stdin
|
while 1: # wait for a new hand number on stdin
|
||||||
new_hand_id = sys.stdin.readline()
|
new_hand_id = sys.stdin.readline()
|
||||||
|
t0 = time.time()
|
||||||
|
t1 = t2 = t3 = t4 = t5 = t6 = t0
|
||||||
new_hand_id = string.rstrip(new_hand_id)
|
new_hand_id = string.rstrip(new_hand_id)
|
||||||
if new_hand_id == "": # blank line means quit
|
if new_hand_id == "": # blank line means quit
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
@ -206,6 +211,7 @@ class HUD_main(object):
|
||||||
print "db error: skipping %s" % new_hand_id
|
print "db error: skipping %s" % new_hand_id
|
||||||
sys.stderr.write("Database error: could not find hand %s.\n" % new_hand_id)
|
sys.stderr.write("Database error: could not find hand %s.\n" % new_hand_id)
|
||||||
continue
|
continue
|
||||||
|
t1 = time.time()
|
||||||
|
|
||||||
if type == "tour": # hand is from a tournament
|
if type == "tour": # hand is from a tournament
|
||||||
temp_key = tour_number
|
temp_key = tour_number
|
||||||
|
@ -215,6 +221,12 @@ class HUD_main(object):
|
||||||
# Update an existing HUD
|
# Update an existing HUD
|
||||||
if temp_key in self.hud_dict:
|
if temp_key in self.hud_dict:
|
||||||
# get stats using hud's specific params and get cards
|
# get stats using hud's specific params and get cards
|
||||||
|
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
||||||
|
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
||||||
|
t2 = time.time()
|
||||||
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params
|
||||||
|
,self.hero_ids[site_id], num_seats)
|
||||||
|
t3 = time.time()
|
||||||
try:
|
try:
|
||||||
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
||||||
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
||||||
|
@ -238,8 +250,10 @@ class HUD_main(object):
|
||||||
else:
|
else:
|
||||||
# get stats using default params--also get cards
|
# get stats using default params--also get cards
|
||||||
self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] )
|
self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] )
|
||||||
|
t4 = time.time()
|
||||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params
|
||||||
,self.hero_ids[site_id], num_seats)
|
,self.hero_ids[site_id], num_seats)
|
||||||
|
t5 = time.time()
|
||||||
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!
|
||||||
|
@ -263,6 +277,9 @@ class HUD_main(object):
|
||||||
else:
|
else:
|
||||||
sys.stderr.write('Table "%s" no longer exists\n' % table_name)
|
sys.stderr.write('Table "%s" no longer exists\n' % table_name)
|
||||||
|
|
||||||
|
t6 = time.time()
|
||||||
|
log.info("HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f,%4.3f,%4.3f)"
|
||||||
|
% (t6-t0,t1-t0,t2-t0,t3-t0,t4-t0,t5-t0,t6-t0))
|
||||||
self.db_connection.connection.rollback()
|
self.db_connection.connection.rollback()
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
|
|
|
@ -54,6 +54,10 @@ class Hand(object):
|
||||||
self.starttime = 0
|
self.starttime = 0
|
||||||
self.handText = handText
|
self.handText = handText
|
||||||
self.handid = 0
|
self.handid = 0
|
||||||
|
self.cancelled = False
|
||||||
|
self.dbid_hands = 0
|
||||||
|
self.dbid_pids = None
|
||||||
|
self.dbid_gt = 0
|
||||||
self.tablename = ""
|
self.tablename = ""
|
||||||
self.hero = ""
|
self.hero = ""
|
||||||
self.maxseats = None
|
self.maxseats = None
|
||||||
|
@ -188,22 +192,21 @@ dealt whether they were seen in a 'dealt to' line
|
||||||
self.holecards[street][player] = [open, closed]
|
self.holecards[street][player] = [open, closed]
|
||||||
|
|
||||||
def prepInsert(self, db):
|
def prepInsert(self, db):
|
||||||
pass
|
#####
|
||||||
|
# Players, Gametypes, TourneyTypes are all shared functions that are needed for additional tables
|
||||||
|
# These functions are intended for prep insert eventually
|
||||||
|
#####
|
||||||
|
# Players - base playerid and siteid tuple
|
||||||
|
self.dbid_pids = db.getSqlPlayerIDs([p[1] for p in self.players], self.siteId)
|
||||||
|
|
||||||
|
#Gametypes
|
||||||
|
self.dbid_gt = db.getGameTypeId(self.siteId, self.gametype)
|
||||||
|
|
||||||
def insert(self, db):
|
def insert(self, db):
|
||||||
""" Function to insert Hand into database
|
""" Function to insert Hand into database
|
||||||
Should not commit, and do minimal selects. Callers may want to cache commits
|
Should not commit, and do minimal selects. Callers may want to cache commits
|
||||||
db: a connected fpdb_db object"""
|
db: a connected fpdb_db object"""
|
||||||
|
|
||||||
#####
|
|
||||||
# Players, Gametypes, TourneyTypes are all shared functions that are needed for additional tables
|
|
||||||
# These functions are intended for prep insert eventually
|
|
||||||
#####
|
|
||||||
# Players - base playerid and siteid tuple
|
|
||||||
sqlids = db.getSqlPlayerIDs([p[1] for p in self.players], self.siteId)
|
|
||||||
|
|
||||||
#Gametypes
|
|
||||||
gtid = db.getGameTypeId(self.siteId, self.gametype)
|
|
||||||
|
|
||||||
self.stats.getStats(self)
|
self.stats.getStats(self)
|
||||||
|
|
||||||
|
@ -212,14 +215,14 @@ db: a connected fpdb_db object"""
|
||||||
#####
|
#####
|
||||||
hh = self.stats.getHands()
|
hh = self.stats.getHands()
|
||||||
|
|
||||||
if not db.isDuplicate(gtid, hh['siteHandNo']):
|
if not db.isDuplicate(self.dbid_gt, hh['siteHandNo']):
|
||||||
# Hands - Summary information of hand indexed by handId - gameinfo
|
# Hands - Summary information of hand indexed by handId - gameinfo
|
||||||
hh['gameTypeId'] = gtid
|
hh['gameTypeId'] = self.dbid_gt
|
||||||
# seats TINYINT NOT NULL,
|
# seats TINYINT NOT NULL,
|
||||||
hh['seats'] = len(sqlids)
|
hh['seats'] = len(self.dbid_pids)
|
||||||
|
|
||||||
handid = db.storeHand(hh)
|
self.dbid_hands = db.storeHand(hh)
|
||||||
db.storeHandsPlayers(handid, sqlids, self.stats.getHandsPlayers())
|
db.storeHandsPlayers(self.dbid_hands, self.dbid_pids, self.stats.getHandsPlayers())
|
||||||
# HandsActions - all actions for all players for all streets - self.actions
|
# HandsActions - all actions for all players for all streets - self.actions
|
||||||
# HudCache data can be generated from HandsActions (HandsPlayers?)
|
# HudCache data can be generated from HandsActions (HandsPlayers?)
|
||||||
# Tourneys ?
|
# Tourneys ?
|
||||||
|
@ -261,6 +264,9 @@ If a player has None chips he won't be added."""
|
||||||
log.debug("markStreets:\n"+ str(self.streets))
|
log.debug("markStreets:\n"+ str(self.streets))
|
||||||
else:
|
else:
|
||||||
log.error("markstreets didn't match")
|
log.error("markstreets didn't match")
|
||||||
|
log.error(" - Assuming hand cancelled")
|
||||||
|
self.cancelled = True
|
||||||
|
raise FpdbParseError
|
||||||
|
|
||||||
def checkPlayerExists(self,player):
|
def checkPlayerExists(self,player):
|
||||||
if player not in [p[1] for p in self.players]:
|
if player not in [p[1] for p in self.players]:
|
||||||
|
@ -611,6 +617,8 @@ class HoldemOmahaHand(Hand):
|
||||||
hhc.readPlayerStacks(self)
|
hhc.readPlayerStacks(self)
|
||||||
hhc.compilePlayerRegexs(self)
|
hhc.compilePlayerRegexs(self)
|
||||||
hhc.markStreets(self)
|
hhc.markStreets(self)
|
||||||
|
if self.cancelled:
|
||||||
|
return
|
||||||
hhc.readBlinds(self)
|
hhc.readBlinds(self)
|
||||||
hhc.readAntes(self)
|
hhc.readAntes(self)
|
||||||
hhc.readButton(self)
|
hhc.readButton(self)
|
||||||
|
|
|
@ -57,7 +57,7 @@ class HandHistoryConverter():
|
||||||
codepage = "cp1252"
|
codepage = "cp1252"
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, in_path = '-', out_path = '-', follow=False, index=0, autostart=True):
|
def __init__(self, in_path = '-', out_path = '-', follow=False, index=0, autostart=True, starsArchive=False):
|
||||||
"""\
|
"""\
|
||||||
in_path (default '-' = sys.stdin)
|
in_path (default '-' = sys.stdin)
|
||||||
out_path (default '-' = sys.stdout)
|
out_path (default '-' = sys.stdout)
|
||||||
|
@ -66,11 +66,14 @@ follow : whether to tail -f the input"""
|
||||||
log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) )
|
log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) )
|
||||||
|
|
||||||
self.index = 0
|
self.index = 0
|
||||||
|
self.starsArchive = starsArchive
|
||||||
|
|
||||||
self.in_path = in_path
|
self.in_path = in_path
|
||||||
self.out_path = out_path
|
self.out_path = out_path
|
||||||
|
|
||||||
self.processedHands = []
|
self.processedHands = []
|
||||||
|
self.numHands = 0
|
||||||
|
self.numErrors = 0
|
||||||
|
|
||||||
# Tourney object used to store TourneyInfo when called to deal with a Summary file
|
# Tourney object used to store TourneyInfo when called to deal with a Summary file
|
||||||
self.tourney = None
|
self.tourney = None
|
||||||
|
@ -135,17 +138,17 @@ Otherwise, finish at EOF.
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
numHands = 0
|
self.numHands = 0
|
||||||
numErrors = 0
|
self.numErrors = 0
|
||||||
if self.follow:
|
if self.follow:
|
||||||
#TODO: See how summary files can be handled on the fly (here they should be rejected as before)
|
#TODO: See how summary files can be handled on the fly (here they should be rejected as before)
|
||||||
log.info("Tailing '%s'" % self.in_path)
|
log.info("Tailing '%s'" % self.in_path)
|
||||||
for handText in self.tailHands():
|
for handText in self.tailHands():
|
||||||
try:
|
try:
|
||||||
self.processHand(handText)
|
self.processHand(handText)
|
||||||
numHands += 1
|
self.numHands += 1
|
||||||
except FpdbParseError, e:
|
except FpdbParseError, e:
|
||||||
numErrors += 1
|
self.numErrors += 1
|
||||||
log.warning("Failed to convert hand %s" % e.hid)
|
log.warning("Failed to convert hand %s" % e.hid)
|
||||||
log.warning("Exception msg: '%s'" % str(e))
|
log.warning("Exception msg: '%s'" % str(e))
|
||||||
log.debug(handText)
|
log.debug(handText)
|
||||||
|
@ -160,13 +163,13 @@ Otherwise, finish at EOF.
|
||||||
try:
|
try:
|
||||||
self.processedHands.append(self.processHand(handText))
|
self.processedHands.append(self.processHand(handText))
|
||||||
except FpdbParseError, e:
|
except FpdbParseError, e:
|
||||||
numErrors += 1
|
self.numErrors += 1
|
||||||
log.warning("Failed to convert hand %s" % e.hid)
|
log.warning("Failed to convert hand %s" % e.hid)
|
||||||
log.warning("Exception msg: '%s'" % str(e))
|
log.warning("Exception msg: '%s'" % str(e))
|
||||||
log.debug(handText)
|
log.debug(handText)
|
||||||
numHands = len(handsList)
|
self.numHands = len(handsList)
|
||||||
endtime = time.time()
|
endtime = time.time()
|
||||||
log.info("Read %d hands (%d failed) in %.3f seconds" % (numHands, numErrors, endtime - starttime))
|
log.info("Read %d hands (%d failed) in %.3f seconds" % (self.numHands, self.numErrors, endtime - starttime))
|
||||||
else:
|
else:
|
||||||
self.parsedObjectType = "Summary"
|
self.parsedObjectType = "Summary"
|
||||||
summaryParsingStatus = self.readSummaryInfo(handsList)
|
summaryParsingStatus = self.readSummaryInfo(handsList)
|
||||||
|
@ -252,6 +255,11 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
self.readFile()
|
self.readFile()
|
||||||
self.obs = self.obs.strip()
|
self.obs = self.obs.strip()
|
||||||
self.obs = self.obs.replace('\r\n', '\n')
|
self.obs = self.obs.replace('\r\n', '\n')
|
||||||
|
if self.starsArchive == True:
|
||||||
|
log.debug("Converting starsArchive format to readable")
|
||||||
|
m = re.compile('^Hand #\d+', re.MULTILINE)
|
||||||
|
self.obs = m.sub('', self.obs)
|
||||||
|
|
||||||
if self.obs is None or self.obs == "":
|
if self.obs is None or self.obs == "":
|
||||||
log.info("Read no hands.")
|
log.info("Read no hands.")
|
||||||
return []
|
return []
|
||||||
|
|
|
@ -358,7 +358,7 @@ class Hud:
|
||||||
|
|
||||||
def change_max_seats(self, widget):
|
def change_max_seats(self, widget):
|
||||||
if self.max != widget.ms:
|
if self.max != widget.ms:
|
||||||
print 'change_max_seats', widget.ms
|
#print 'change_max_seats', widget.ms
|
||||||
self.max = widget.ms
|
self.max = widget.ms
|
||||||
try:
|
try:
|
||||||
self.kill()
|
self.kill()
|
||||||
|
@ -678,7 +678,7 @@ class Stat_Window:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def kill_popup(self, popup):
|
def kill_popup(self, popup):
|
||||||
print "remove popup", popup
|
#print "remove popup", popup
|
||||||
self.popups.remove(popup)
|
self.popups.remove(popup)
|
||||||
popup.window.destroy()
|
popup.window.destroy()
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,11 @@ def fpdb_options():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Indicates program was restarted with a different path (only allowed once).")
|
help="Indicates program was restarted with a different path (only allowed once).")
|
||||||
parser.add_option("-i", "--infile",
|
parser.add_option("-i", "--infile",
|
||||||
dest="config", default=None,
|
dest="infile", default="Slartibartfast",
|
||||||
help="Input file")
|
help="Input file")
|
||||||
|
parser.add_option("-k", "--konverter",
|
||||||
|
dest="hhc", default="PokerStarsToFpdb",
|
||||||
|
help="Module name for Hand History Converter")
|
||||||
(options, argv) = parser.parse_args()
|
(options, argv) = parser.parse_args()
|
||||||
return (options, argv)
|
return (options, argv)
|
||||||
|
|
||||||
|
|
109
pyfpdb/SQL.py
109
pyfpdb/SQL.py
|
@ -1317,6 +1317,7 @@ class Sql:
|
||||||
1.25 would be a config value so user could change it)
|
1.25 would be a config value so user could change it)
|
||||||
*/
|
*/
|
||||||
GROUP BY hc.PlayerId, hp.seatNo, p.name
|
GROUP BY hc.PlayerId, hp.seatNo, p.name
|
||||||
|
ORDER BY hc.PlayerId, hp.seatNo, p.name
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# same as above except stats are aggregated for all blind/limit levels
|
# same as above except stats are aggregated for all blind/limit levels
|
||||||
|
@ -1418,6 +1419,7 @@ class Sql:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
GROUP BY hc.PlayerId, p.name
|
GROUP BY hc.PlayerId, p.name
|
||||||
|
ORDER BY hc.PlayerId, p.name
|
||||||
"""
|
"""
|
||||||
# NOTES on above cursor:
|
# NOTES on above cursor:
|
||||||
# - Do NOT include %s inside query in a comment - the db api thinks
|
# - Do NOT include %s inside query in a comment - the db api thinks
|
||||||
|
@ -2561,7 +2563,7 @@ class Sql:
|
||||||
# self.query['playerStatsByPosition'] = """ """
|
# self.query['playerStatsByPosition'] = """ """
|
||||||
|
|
||||||
self.query['getRingProfitAllHandsPlayerIdSite'] = """
|
self.query['getRingProfitAllHandsPlayerIdSite'] = """
|
||||||
SELECT hp.handId, hp.totalProfit
|
SELECT hp.handId, hp.totalProfit, hp.sawShowdown
|
||||||
FROM HandsPlayers hp
|
FROM HandsPlayers hp
|
||||||
INNER JOIN Players pl ON (pl.id = hp.playerId)
|
INNER JOIN Players pl ON (pl.id = hp.playerId)
|
||||||
INNER JOIN Hands h ON (h.id = hp.handId)
|
INNER JOIN Hands h ON (h.id = hp.handId)
|
||||||
|
@ -2572,7 +2574,7 @@ class Sql:
|
||||||
AND h.handStart < '<enddate_test>'
|
AND h.handStart < '<enddate_test>'
|
||||||
<limit_test>
|
<limit_test>
|
||||||
AND hp.tourneysPlayersId IS NULL
|
AND hp.tourneysPlayersId IS NULL
|
||||||
GROUP BY h.handStart, hp.handId, hp.totalProfit
|
GROUP BY h.handStart, hp.handId, hp.sawShowdown, hp.totalProfit
|
||||||
ORDER BY h.handStart"""
|
ORDER BY h.handStart"""
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
|
@ -2787,8 +2789,6 @@ class Sql:
|
||||||
,hp.tourneyTypeId
|
,hp.tourneyTypeId
|
||||||
,date_format(h.handStart, 'd%y%m%d')
|
,date_format(h.handStart, 'd%y%m%d')
|
||||||
"""
|
"""
|
||||||
#>>>>>>> 28ca49d592c8e706ad6ee58dd26655bcc33fc5fb:pyfpdb/SQL.py
|
|
||||||
#"""
|
|
||||||
elif db_server == 'postgresql':
|
elif db_server == 'postgresql':
|
||||||
self.query['rebuildHudCache'] = """
|
self.query['rebuildHudCache'] = """
|
||||||
INSERT INTO HudCache
|
INSERT INTO HudCache
|
||||||
|
@ -3325,8 +3325,105 @@ class Sql:
|
||||||
%s, %s, %s, %s, %s, %s, %s, %s, %s)"""
|
%s, %s, %s, %s, %s, %s, %s, %s, %s)"""
|
||||||
|
|
||||||
|
|
||||||
|
self.query['store_hands_players'] = """INSERT INTO HandsPlayers (
|
||||||
|
handId,
|
||||||
|
playerId,
|
||||||
|
startCash,
|
||||||
|
seatNo,
|
||||||
|
card1,
|
||||||
|
card2,
|
||||||
|
card3,
|
||||||
|
card4,
|
||||||
|
card5,
|
||||||
|
card6,
|
||||||
|
card7,
|
||||||
|
winnings,
|
||||||
|
rake,
|
||||||
|
totalProfit,
|
||||||
|
street0VPI,
|
||||||
|
street1Seen,
|
||||||
|
street2Seen,
|
||||||
|
street3Seen,
|
||||||
|
street4Seen,
|
||||||
|
sawShowdown,
|
||||||
|
wonAtSD,
|
||||||
|
street0Aggr,
|
||||||
|
street1Aggr,
|
||||||
|
street2Aggr,
|
||||||
|
street3Aggr,
|
||||||
|
street4Aggr,
|
||||||
|
street1CBChance,
|
||||||
|
street2CBChance,
|
||||||
|
street3CBChance,
|
||||||
|
street4CBChance,
|
||||||
|
street1CBDone,
|
||||||
|
street2CBDone,
|
||||||
|
street3CBDone,
|
||||||
|
street4CBDone,
|
||||||
|
wonWhenSeenStreet1,
|
||||||
|
street0Calls,
|
||||||
|
street1Calls,
|
||||||
|
street2Calls,
|
||||||
|
street3Calls,
|
||||||
|
street4Calls,
|
||||||
|
street0Bets,
|
||||||
|
street1Bets,
|
||||||
|
street2Bets,
|
||||||
|
street3Bets,
|
||||||
|
street4Bets,
|
||||||
|
position,
|
||||||
|
tourneyTypeId,
|
||||||
|
startCards,
|
||||||
|
street0_3BChance,
|
||||||
|
street0_3BDone,
|
||||||
|
otherRaisedStreet1,
|
||||||
|
otherRaisedStreet2,
|
||||||
|
otherRaisedStreet3,
|
||||||
|
otherRaisedStreet4,
|
||||||
|
foldToOtherRaisedStreet1,
|
||||||
|
foldToOtherRaisedStreet2,
|
||||||
|
foldToOtherRaisedStreet3,
|
||||||
|
foldToOtherRaisedStreet4,
|
||||||
|
stealAttemptChance,
|
||||||
|
stealAttempted,
|
||||||
|
foldBbToStealChance,
|
||||||
|
foldedBbToSteal,
|
||||||
|
foldSbToStealChance,
|
||||||
|
foldedSbToSteal,
|
||||||
|
foldToStreet1CBChance,
|
||||||
|
foldToStreet1CBDone,
|
||||||
|
foldToStreet2CBChance,
|
||||||
|
foldToStreet2CBDone,
|
||||||
|
foldToStreet3CBChance,
|
||||||
|
foldToStreet3CBDone,
|
||||||
|
foldToStreet4CBChance,
|
||||||
|
foldToStreet4CBDone,
|
||||||
|
street1CheckCallRaiseChance,
|
||||||
|
street1CheckCallRaiseDone,
|
||||||
|
street2CheckCallRaiseChance,
|
||||||
|
street2CheckCallRaiseDone,
|
||||||
|
street3CheckCallRaiseChance,
|
||||||
|
street3CheckCallRaiseDone,
|
||||||
|
street4CheckCallRaiseChance
|
||||||
|
)
|
||||||
|
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
|
||||||
|
)"""
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
self.query['placeholder'] = u'%s'
|
self.query['placeholder'] = u'%s'
|
||||||
|
|
259
pyfpdb/fpdb.py
259
pyfpdb/fpdb.py
|
@ -18,6 +18,7 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
|
import Queue
|
||||||
|
|
||||||
# if path is set to use an old version of python look for a new one:
|
# if path is set to use an old version of python look for a new one:
|
||||||
# (does this work in linux?)
|
# (does this work in linux?)
|
||||||
|
@ -37,14 +38,20 @@ if os.name == 'nt' and sys.version[0:3] not in ('2.5', '2.6') and '-r' not in sy
|
||||||
os.execvpe('python.exe', ('python.exe', 'fpdb.py', '-r'), os.environ) # first arg is ignored (name of program being run)
|
os.execvpe('python.exe', ('python.exe', 'fpdb.py', '-r'), os.environ) # first arg is ignored (name of program being run)
|
||||||
else:
|
else:
|
||||||
print "\npython 2.5 not found, please install python 2.5 or 2.6 for fpdb\n"
|
print "\npython 2.5 not found, please install python 2.5 or 2.6 for fpdb\n"
|
||||||
exit
|
raw_input("Press ENTER to continue.")
|
||||||
|
exit()
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
#print "debug - not changing path"
|
#print "debug - not changing path"
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
try:
|
||||||
import win32api
|
import win32api
|
||||||
import win32con
|
import win32con
|
||||||
|
except ImportError:
|
||||||
|
print "We appear to be running in Windows, but the Windows Python Extensions are not loading. Please install the PYWIN32 package from http://sourceforge.net/projects/pywin32/"
|
||||||
|
raw_input("Press ENTER to continue.")
|
||||||
|
exit()
|
||||||
|
|
||||||
print "Python " + sys.version[0:3] + '...\n'
|
print "Python " + sys.version[0:3] + '...\n'
|
||||||
|
|
||||||
|
@ -60,16 +67,42 @@ if not options.errorsToConsole:
|
||||||
errorFile = open('fpdb-error-log.txt', 'w', 0)
|
errorFile = open('fpdb-error-log.txt', 'w', 0)
|
||||||
sys.stderr = errorFile
|
sys.stderr = errorFile
|
||||||
|
|
||||||
import logging
|
#import logging
|
||||||
|
import logging, logging.config
|
||||||
|
|
||||||
|
try:
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
|
import pango
|
||||||
|
except:
|
||||||
|
print "Unable to load PYGTK modules required for GUI. Please install PyCairo, PyGObject, and PyGTK from www.pygtk.org."
|
||||||
|
raw_input("Press ENTER to continue.")
|
||||||
|
exit()
|
||||||
|
|
||||||
import interlocks
|
import interlocks
|
||||||
|
|
||||||
|
# these imports not required in this module, imported here to report version in About dialog
|
||||||
|
try:
|
||||||
|
import matplotlib
|
||||||
|
matplotlib_version = matplotlib.__version__
|
||||||
|
except:
|
||||||
|
matplotlib_version = 'not found'
|
||||||
|
try:
|
||||||
|
import numpy
|
||||||
|
numpy_version = numpy.__version__
|
||||||
|
except:
|
||||||
|
numpy_version = 'not found'
|
||||||
|
try:
|
||||||
|
import sqlite3
|
||||||
|
sqlite3_version = sqlite3.version
|
||||||
|
sqlite_version = sqlite3.sqlite_version
|
||||||
|
except:
|
||||||
|
sqlite3_version = 'not found'
|
||||||
|
sqlite_version = 'not found'
|
||||||
|
|
||||||
import GuiPrefs
|
import GuiPrefs
|
||||||
|
import GuiLogView
|
||||||
import GuiBulkImport
|
import GuiBulkImport
|
||||||
import GuiPlayerStats
|
import GuiPlayerStats
|
||||||
import GuiPositionalStats
|
import GuiPositionalStats
|
||||||
|
@ -85,6 +118,8 @@ import Exceptions
|
||||||
|
|
||||||
VERSION = "0.12"
|
VERSION = "0.12"
|
||||||
|
|
||||||
|
log = Configuration.get_logger("logging.conf", "fpdb")
|
||||||
|
|
||||||
class fpdb:
|
class fpdb:
|
||||||
def tab_clicked(self, widget, tab_name):
|
def tab_clicked(self, widget, tab_name):
|
||||||
"""called when a tab button is clicked to activate that tab"""
|
"""called when a tab button is clicked to activate that tab"""
|
||||||
|
@ -97,12 +132,12 @@ class fpdb:
|
||||||
|
|
||||||
def add_tab(self, new_page, new_tab_name):
|
def add_tab(self, new_page, new_tab_name):
|
||||||
"""adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
|
"""adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
|
||||||
for name in self.nb_tabs: #todo: check this is valid
|
for name in self.nb_tab_names: #todo: check this is valid
|
||||||
if name == new_tab_name:
|
if name == new_tab_name:
|
||||||
return # if tab already exists, just go to it
|
return # if tab already exists, just go to it
|
||||||
|
|
||||||
used_before = False
|
used_before = False
|
||||||
for i, name in enumerate(self.tab_names): #todo: check this is valid
|
for i, name in enumerate(self.tab_names):
|
||||||
if name == new_tab_name:
|
if name == new_tab_name:
|
||||||
used_before = True
|
used_before = True
|
||||||
event_box = self.tabs[i]
|
event_box = self.tabs[i]
|
||||||
|
@ -118,13 +153,13 @@ class fpdb:
|
||||||
|
|
||||||
#self.nb.append_page(new_page, gtk.Label(new_tab_name))
|
#self.nb.append_page(new_page, gtk.Label(new_tab_name))
|
||||||
self.nb.append_page(page, event_box)
|
self.nb.append_page(page, event_box)
|
||||||
self.nb_tabs.append(new_tab_name)
|
self.nb_tab_names.append(new_tab_name)
|
||||||
page.show()
|
page.show()
|
||||||
|
|
||||||
def display_tab(self, new_tab_name):
|
def display_tab(self, new_tab_name):
|
||||||
"""displays the indicated tab"""
|
"""displays the indicated tab"""
|
||||||
tab_no = -1
|
tab_no = -1
|
||||||
for i, name in enumerate(self.nb_tabs):
|
for i, name in enumerate(self.nb_tab_names):
|
||||||
if new_tab_name == name:
|
if new_tab_name == name:
|
||||||
tab_no = i
|
tab_no = i
|
||||||
break
|
break
|
||||||
|
@ -175,13 +210,13 @@ class fpdb:
|
||||||
(nb, text) = data
|
(nb, text) = data
|
||||||
page = -1
|
page = -1
|
||||||
#print "\n remove_tab: start", text
|
#print "\n remove_tab: start", text
|
||||||
for i, tab in enumerate(self.nb_tabs):
|
for i, tab in enumerate(self.nb_tab_names):
|
||||||
if text == tab:
|
if text == tab:
|
||||||
page = i
|
page = i
|
||||||
#print " page =", page
|
#print " page =", page
|
||||||
if page >= 0 and page < self.nb.get_n_pages():
|
if page >= 0 and page < self.nb.get_n_pages():
|
||||||
#print " removing page", page
|
#print " removing page", page
|
||||||
del self.nb_tabs[page]
|
del self.nb_tab_names[page]
|
||||||
nb.remove_page(page)
|
nb.remove_page(page)
|
||||||
# Need to refresh the widget --
|
# Need to refresh the widget --
|
||||||
# This forces the widget to redraw itself.
|
# This forces the widget to redraw itself.
|
||||||
|
@ -196,16 +231,48 @@ class fpdb:
|
||||||
def dia_about(self, widget, data=None):
|
def dia_about(self, widget, data=None):
|
||||||
#self.warning_box("About FPDB:\n\nFPDB was originally created by a guy named Steffen, sometime in 2008, \nand is mostly worked on these days by people named Eratosthenes, s0rrow, _mt, EricBlade, sqlcoder, and other strange people.\n\n", "ABOUT FPDB")
|
#self.warning_box("About FPDB:\n\nFPDB was originally created by a guy named Steffen, sometime in 2008, \nand is mostly worked on these days by people named Eratosthenes, s0rrow, _mt, EricBlade, sqlcoder, and other strange people.\n\n", "ABOUT FPDB")
|
||||||
dia = gtk.AboutDialog()
|
dia = gtk.AboutDialog()
|
||||||
dia.set_name("FPDB")
|
dia.set_name("Free Poker Database (FPDB)")
|
||||||
dia.set_version(VERSION)
|
dia.set_version(VERSION)
|
||||||
dia.set_copyright("2008-2009, Steffen, Eratosthenes, s0rrow, EricBlade, _mt, sqlcoder, and others")
|
dia.set_copyright("2008-2010, Steffen, Eratosthenes, s0rrow, EricBlade, _mt, sqlcoder, Bostik, and others")
|
||||||
dia.set_comments("GTK AboutDialog comments here")
|
dia.set_comments("GTK AboutDialog comments here")
|
||||||
dia.set_license("GPL v3")
|
dia.set_license("GPL v3")
|
||||||
dia.set_website("http://fpdb.sourceforge.net/")
|
dia.set_website("http://fpdb.sourceforge.net/")
|
||||||
dia.set_authors("Steffen, Eratosthenes, s0rrow, EricBlade, _mt, and others")
|
dia.set_authors(['Steffen', 'Eratosthenes', 's0rrow',
|
||||||
dia.set_program_name("FPDB")
|
'EricBlade', '_mt', 'sqlcoder', 'Bostik', 'and others'])
|
||||||
|
dia.set_program_name("Free Poker Database (FPDB)")
|
||||||
|
|
||||||
|
db_version = ""
|
||||||
|
#if self.db is not None:
|
||||||
|
# db_version = self.db.get_version()
|
||||||
|
nums = [ ('Operating System', os.name)
|
||||||
|
, ('Python', sys.version[0:3])
|
||||||
|
, ('GTK+', '.'.join([str(x) for x in gtk.gtk_version]))
|
||||||
|
, ('PyGTK', '.'.join([str(x) for x in gtk.pygtk_version]))
|
||||||
|
, ('matplotlib', matplotlib_version)
|
||||||
|
, ('numpy', numpy_version)
|
||||||
|
, ('sqlite3', sqlite3_version)
|
||||||
|
, ('sqlite', sqlite_version)
|
||||||
|
, ('database', self.settings['db-server'] + db_version)
|
||||||
|
]
|
||||||
|
versions = gtk.TextBuffer()
|
||||||
|
w = 20 # width used for module names and version numbers
|
||||||
|
versions.set_text( '\n'.join( [x[0].rjust(w)+' '+ x[1].ljust(w) for x in nums] ) )
|
||||||
|
view = gtk.TextView(versions)
|
||||||
|
view.set_editable(False)
|
||||||
|
view.set_justification(gtk.JUSTIFY_CENTER)
|
||||||
|
view.modify_font(pango.FontDescription('monospace 10'))
|
||||||
|
view.show()
|
||||||
|
dia.vbox.pack_end(view, True, True, 2)
|
||||||
|
l = gtk.Label('Version Information:')
|
||||||
|
l.set_alignment(0.5, 0.5)
|
||||||
|
l.show()
|
||||||
|
dia.vbox.pack_end(l, True, True, 2)
|
||||||
|
|
||||||
dia.run()
|
dia.run()
|
||||||
dia.destroy()
|
dia.destroy()
|
||||||
|
log.debug("Threads: ")
|
||||||
|
for t in self.threads:
|
||||||
|
log.debug("........." + str(t.__class__))
|
||||||
|
|
||||||
def dia_preferences(self, widget, data=None):
|
def dia_preferences(self, widget, data=None):
|
||||||
dia = gtk.Dialog("Preferences",
|
dia = gtk.Dialog("Preferences",
|
||||||
|
@ -213,12 +280,20 @@ class fpdb:
|
||||||
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||||
gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
|
gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
|
||||||
dia.set_default_size(500, 500)
|
dia.set_default_size(700, 500)
|
||||||
|
|
||||||
prefs = GuiPrefs.GuiPrefs(self.config, self.window, dia.vbox)
|
prefs = GuiPrefs.GuiPrefs(self.config, self.window, dia.vbox)
|
||||||
response = dia.run()
|
response = dia.run()
|
||||||
if response == gtk.RESPONSE_ACCEPT:
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
# save updated config
|
# save updated config
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
if len(self.nb_tab_names) == 1:
|
||||||
|
# only main tab open, reload profile
|
||||||
|
self.load_profile()
|
||||||
|
else:
|
||||||
|
self.warning_box("Updated preferences have not been loaded because "
|
||||||
|
+ "windows are open. Re-start fpdb to load them.")
|
||||||
|
|
||||||
dia.destroy()
|
dia.destroy()
|
||||||
|
|
||||||
def dia_create_del_database(self, widget, data=None):
|
def dia_create_del_database(self, widget, data=None):
|
||||||
|
@ -334,27 +409,48 @@ class fpdb:
|
||||||
diastring = "Please confirm that you want to re-create the HUD cache."
|
diastring = "Please confirm that you want to re-create the HUD cache."
|
||||||
self.dia_confirm.format_secondary_text(diastring)
|
self.dia_confirm.format_secondary_text(diastring)
|
||||||
|
|
||||||
hb = gtk.HBox(True, 1)
|
hb1 = gtk.HBox(True, 1)
|
||||||
|
self.h_start_date = gtk.Entry(max=12)
|
||||||
|
self.h_start_date.set_text( self.db.get_hero_hudcache_start() )
|
||||||
|
lbl = gtk.Label(" Hero's cache starts: ")
|
||||||
|
btn = gtk.Button()
|
||||||
|
btn.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
|
||||||
|
btn.connect('clicked', self.__calendar_dialog, self.h_start_date)
|
||||||
|
|
||||||
|
hb1.pack_start(lbl, expand=True, padding=3)
|
||||||
|
hb1.pack_start(self.h_start_date, expand=True, padding=2)
|
||||||
|
hb1.pack_start(btn, expand=False, padding=3)
|
||||||
|
self.dia_confirm.vbox.add(hb1)
|
||||||
|
hb1.show_all()
|
||||||
|
|
||||||
|
hb2 = gtk.HBox(True, 1)
|
||||||
self.start_date = gtk.Entry(max=12)
|
self.start_date = gtk.Entry(max=12)
|
||||||
self.start_date.set_text( self.db.get_hero_hudcache_start() )
|
self.start_date.set_text( self.db.get_hero_hudcache_start() )
|
||||||
lbl = gtk.Label(" Hero's cache starts: ")
|
lbl = gtk.Label(" Villains' cache starts: ")
|
||||||
btn = gtk.Button()
|
btn = gtk.Button()
|
||||||
btn.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
|
btn.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
|
||||||
btn.connect('clicked', self.__calendar_dialog, self.start_date)
|
btn.connect('clicked', self.__calendar_dialog, self.start_date)
|
||||||
|
|
||||||
hb.pack_start(lbl, expand=True, padding=3)
|
hb2.pack_start(lbl, expand=True, padding=3)
|
||||||
hb.pack_start(self.start_date, expand=True, padding=2)
|
hb2.pack_start(self.start_date, expand=True, padding=2)
|
||||||
hb.pack_start(btn, expand=False, padding=3)
|
hb2.pack_start(btn, expand=False, padding=3)
|
||||||
self.dia_confirm.vbox.add(hb)
|
self.dia_confirm.vbox.add(hb2)
|
||||||
hb.show_all()
|
hb2.show_all()
|
||||||
|
|
||||||
response = self.dia_confirm.run()
|
response = self.dia_confirm.run()
|
||||||
self.dia_confirm.destroy()
|
|
||||||
if response == gtk.RESPONSE_YES:
|
if response == gtk.RESPONSE_YES:
|
||||||
self.db.rebuild_hudcache( self.start_date.get_text() )
|
lbl = gtk.Label(" Rebuilding HUD Cache ... ")
|
||||||
|
self.dia_confirm.vbox.add(lbl)
|
||||||
|
lbl.show()
|
||||||
|
while gtk.events_pending():
|
||||||
|
gtk.main_iteration_do(False)
|
||||||
|
|
||||||
|
self.db.rebuild_hudcache( self.h_start_date.get_text(), self.start_date.get_text() )
|
||||||
elif response == gtk.RESPONSE_NO:
|
elif response == gtk.RESPONSE_NO:
|
||||||
print 'User cancelled rebuilding hud cache'
|
print 'User cancelled rebuilding hud cache'
|
||||||
|
|
||||||
|
self.dia_confirm.destroy()
|
||||||
|
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
|
|
||||||
def dia_rebuild_indexes(self, widget, data=None):
|
def dia_rebuild_indexes(self, widget, data=None):
|
||||||
|
@ -368,16 +464,77 @@ class fpdb:
|
||||||
self.dia_confirm.format_secondary_text(diastring)
|
self.dia_confirm.format_secondary_text(diastring)
|
||||||
|
|
||||||
response = self.dia_confirm.run()
|
response = self.dia_confirm.run()
|
||||||
self.dia_confirm.destroy()
|
|
||||||
if response == gtk.RESPONSE_YES:
|
if response == gtk.RESPONSE_YES:
|
||||||
|
lbl = gtk.Label(" Rebuilding Indexes ... ")
|
||||||
|
self.dia_confirm.vbox.add(lbl)
|
||||||
|
lbl.show()
|
||||||
|
while gtk.events_pending():
|
||||||
|
gtk.main_iteration_do(False)
|
||||||
self.db.rebuild_indexes()
|
self.db.rebuild_indexes()
|
||||||
|
|
||||||
|
lbl.set_text(" Cleaning Database ... ")
|
||||||
|
while gtk.events_pending():
|
||||||
|
gtk.main_iteration_do(False)
|
||||||
self.db.vacuumDB()
|
self.db.vacuumDB()
|
||||||
|
|
||||||
|
lbl.set_text(" Analyzing Database ... ")
|
||||||
|
while gtk.events_pending():
|
||||||
|
gtk.main_iteration_do(False)
|
||||||
self.db.analyzeDB()
|
self.db.analyzeDB()
|
||||||
elif response == gtk.RESPONSE_NO:
|
elif response == gtk.RESPONSE_NO:
|
||||||
print 'User cancelled rebuilding db indexes'
|
print 'User cancelled rebuilding db indexes'
|
||||||
|
|
||||||
|
self.dia_confirm.destroy()
|
||||||
|
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
|
|
||||||
|
def dia_logs(self, widget, data=None):
|
||||||
|
"""opens the log viewer window"""
|
||||||
|
|
||||||
|
#lock_set = False
|
||||||
|
#if self.obtain_global_lock():
|
||||||
|
# lock_set = True
|
||||||
|
|
||||||
|
# remove members from self.threads if close messages received
|
||||||
|
self.process_close_messages()
|
||||||
|
|
||||||
|
viewer = None
|
||||||
|
for i, t in enumerate(self.threads):
|
||||||
|
if str(t.__class__) == 'GuiLogView.GuiLogView':
|
||||||
|
viewer = t
|
||||||
|
break
|
||||||
|
|
||||||
|
if viewer is None:
|
||||||
|
#print "creating new log viewer"
|
||||||
|
new_thread = GuiLogView.GuiLogView(self.config, self.window, self.closeq)
|
||||||
|
self.threads.append(new_thread)
|
||||||
|
else:
|
||||||
|
#print "showing existing log viewer"
|
||||||
|
viewer.get_dialog().present()
|
||||||
|
|
||||||
|
#if lock_set:
|
||||||
|
# self.release_global_lock()
|
||||||
|
|
||||||
|
def addLogText(self, text):
|
||||||
|
end_iter = self.logbuffer.get_end_iter()
|
||||||
|
self.logbuffer.insert(end_iter, text)
|
||||||
|
self.logview.scroll_to_mark(self.logbuffer.get_insert(), 0)
|
||||||
|
|
||||||
|
|
||||||
|
def process_close_messages(self):
|
||||||
|
# check for close messages
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
name = self.closeq.get(False)
|
||||||
|
for i, t in enumerate(self.threads):
|
||||||
|
if str(t.__class__) == str(name):
|
||||||
|
# thread has ended so remove from list:
|
||||||
|
del self.threads[i]
|
||||||
|
break
|
||||||
|
except Queue.Empty:
|
||||||
|
# no close messages on queue, do nothing
|
||||||
|
pass
|
||||||
|
|
||||||
def __calendar_dialog(self, widget, entry):
|
def __calendar_dialog(self, widget, entry):
|
||||||
self.dia_confirm.set_modal(False)
|
self.dia_confirm.set_modal(False)
|
||||||
d = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
d = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
|
@ -397,10 +554,13 @@ class fpdb:
|
||||||
d.show_all()
|
d.show_all()
|
||||||
|
|
||||||
def __get_dates(self):
|
def __get_dates(self):
|
||||||
t1 = self.start_date.get_text()
|
t1 = self.h_start_date.get_text()
|
||||||
if t1 == '':
|
if t1 == '':
|
||||||
t1 = '1970-01-01'
|
t1 = '1970-01-01'
|
||||||
return (t1)
|
t2 = self.start_date.get_text()
|
||||||
|
if t2 == '':
|
||||||
|
t2 = '1970-01-01'
|
||||||
|
return (t1, t2)
|
||||||
|
|
||||||
def __get_date(self, widget, calendar, entry, win):
|
def __get_date(self, widget, calendar, entry, win):
|
||||||
# year and day are correct, month is 0..11
|
# year and day are correct, month is 0..11
|
||||||
|
@ -477,6 +637,7 @@ class fpdb:
|
||||||
</menu>
|
</menu>
|
||||||
<menu action="help">
|
<menu action="help">
|
||||||
<menuitem action="Abbrev"/>
|
<menuitem action="Abbrev"/>
|
||||||
|
<menuitem action="Logs"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<menuitem action="About"/>
|
<menuitem action="About"/>
|
||||||
<menuitem action="License"/>
|
<menuitem action="License"/>
|
||||||
|
@ -494,7 +655,7 @@ class fpdb:
|
||||||
('LoadProf', None, '_Load Profile (broken)', '<control>L', 'Load your profile', self.dia_load_profile),
|
('LoadProf', None, '_Load Profile (broken)', '<control>L', 'Load your profile', self.dia_load_profile),
|
||||||
('EditProf', None, '_Edit Profile (todo)', '<control>E', 'Edit your profile', self.dia_edit_profile),
|
('EditProf', None, '_Edit Profile (todo)', '<control>E', 'Edit your profile', self.dia_edit_profile),
|
||||||
('SaveProf', None, '_Save Profile (todo)', '<control>S', 'Save your profile', self.dia_save_profile),
|
('SaveProf', None, '_Save Profile (todo)', '<control>S', 'Save your profile', self.dia_save_profile),
|
||||||
('Preferences', None, '_Preferences', None, 'Edit your preferences', self.dia_preferences),
|
('Preferences', None, 'Pre_ferences', '<control>F', 'Edit your preferences', self.dia_preferences),
|
||||||
('import', None, '_Import'),
|
('import', None, '_Import'),
|
||||||
('sethharchive', None, '_Set HandHistory Archive Directory', None, 'Set HandHistory Archive Directory', self.select_hhArchiveBase),
|
('sethharchive', None, '_Set HandHistory Archive Directory', None, 'Set HandHistory Archive Directory', self.select_hhArchiveBase),
|
||||||
('bulkimp', None, '_Bulk Import', '<control>B', 'Bulk Import', self.tab_bulk_import),
|
('bulkimp', None, '_Bulk Import', '<control>B', 'Bulk Import', self.tab_bulk_import),
|
||||||
|
@ -518,6 +679,7 @@ class fpdb:
|
||||||
('stats', None, '_Statistics (todo)', None, 'View Database Statistics', self.dia_database_stats),
|
('stats', None, '_Statistics (todo)', None, 'View Database Statistics', self.dia_database_stats),
|
||||||
('help', None, '_Help'),
|
('help', None, '_Help'),
|
||||||
('Abbrev', None, '_Abbrevations (todo)', None, 'List of Abbrevations', self.tab_abbreviations),
|
('Abbrev', None, '_Abbrevations (todo)', None, 'List of Abbrevations', self.tab_abbreviations),
|
||||||
|
('Logs', None, '_Log Messages', None, 'Log and Debug Messages', self.dia_logs),
|
||||||
('About', None, 'A_bout', None, 'About the program', self.dia_about),
|
('About', None, 'A_bout', None, 'About the program', self.dia_about),
|
||||||
('License', None, '_License and Copying (todo)', None, 'License and Copying', self.dia_licensing),
|
('License', None, '_License and Copying (todo)', None, 'License and Copying', self.dia_licensing),
|
||||||
])
|
])
|
||||||
|
@ -547,19 +709,26 @@ class fpdb:
|
||||||
self.settings.update(self.config.get_import_parameters())
|
self.settings.update(self.config.get_import_parameters())
|
||||||
self.settings.update(self.config.get_default_paths())
|
self.settings.update(self.config.get_default_paths())
|
||||||
|
|
||||||
if self.db is not None and self.db.fdb is not None:
|
if self.db is not None and self.db.connected:
|
||||||
self.db.disconnect()
|
self.db.disconnect()
|
||||||
|
|
||||||
self.sql = SQL.Sql(db_server = self.settings['db-server'])
|
self.sql = SQL.Sql(db_server = self.settings['db-server'])
|
||||||
|
err_msg = None
|
||||||
try:
|
try:
|
||||||
self.db = Database.Database(self.config, sql = self.sql)
|
self.db = Database.Database(self.config, sql = self.sql)
|
||||||
except Exceptions.FpdbMySQLAccessDenied:
|
except Exceptions.FpdbMySQLAccessDenied:
|
||||||
self.warning_box("MySQL Server reports: Access denied. Are your permissions set correctly?")
|
err_msg = "MySQL Server reports: Access denied. Are your permissions set correctly?"
|
||||||
exit()
|
|
||||||
except Exceptions.FpdbMySQLNoDatabase:
|
except Exceptions.FpdbMySQLNoDatabase:
|
||||||
msg = "MySQL client reports: 2002 error. Unable to connect - Please check that the MySQL service has been started"
|
err_msg = "MySQL client reports: 2002 or 2003 error. Unable to connect - " \
|
||||||
self.warning_box(msg)
|
+ "Please check that the MySQL service has been started"
|
||||||
exit
|
except Exceptions.FpdbPostgresqlAccessDenied:
|
||||||
|
err_msg = "Postgres Server reports: Access denied. Are your permissions set correctly?"
|
||||||
|
except Exceptions.FpdbPostgresqlNoDatabase:
|
||||||
|
err_msg = "Postgres client reports: Unable to connect - " \
|
||||||
|
+ "Please check that the Postgres service has been started"
|
||||||
|
if err_msg is not None:
|
||||||
|
self.db = None
|
||||||
|
self.warning_box(err_msg)
|
||||||
|
|
||||||
# except FpdbMySQLFailedError:
|
# except FpdbMySQLFailedError:
|
||||||
# self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
|
# self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
|
||||||
|
@ -577,7 +746,7 @@ class fpdb:
|
||||||
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||||
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||||
|
|
||||||
if self.db.wrongDbVersion:
|
if self.db is not None and self.db.wrongDbVersion:
|
||||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||||
|
|
||||||
label = gtk.Label("An invalid DB version or missing tables have been detected.")
|
label = gtk.Label("An invalid DB version or missing tables have been detected.")
|
||||||
|
@ -596,13 +765,14 @@ class fpdb:
|
||||||
diaDbVersionWarning.destroy()
|
diaDbVersionWarning.destroy()
|
||||||
|
|
||||||
if self.status_bar is None:
|
if self.status_bar is None:
|
||||||
self.status_bar = gtk.Label("Status: Connected to %s database named %s on host %s"%(self.db.get_backend_name(),self.db.database, self.db.host))
|
self.status_bar = gtk.Label("")
|
||||||
self.main_vbox.pack_end(self.status_bar, False, True, 0)
|
self.main_vbox.pack_end(self.status_bar, False, True, 0)
|
||||||
self.status_bar.show()
|
self.status_bar.show()
|
||||||
else:
|
|
||||||
self.status_bar.set_text("Status: Connected to %s database named %s on host %s" % (self.db.get_backend_name(),self.db.database, self.db.host))
|
|
||||||
|
|
||||||
# Database connected to successfully, load queries to pass on to other classes
|
if self.db is not None and self.db.connected:
|
||||||
|
self.status_bar.set_text("Status: Connected to %s database named %s on host %s"
|
||||||
|
% (self.db.get_backend_name(),self.db.database, self.db.host))
|
||||||
|
# rollback to make sure any locks are cleared:
|
||||||
self.db.rollback()
|
self.db.rollback()
|
||||||
|
|
||||||
self.validate_config()
|
self.validate_config()
|
||||||
|
@ -624,6 +794,7 @@ class fpdb:
|
||||||
# TODO: can we get some / all of the stuff done in this function to execute on any kind of abort?
|
# TODO: can we get some / all of the stuff done in this function to execute on any kind of abort?
|
||||||
print "Quitting normally"
|
print "Quitting normally"
|
||||||
# TODO: check if current settings differ from profile, if so offer to save or abort
|
# TODO: check if current settings differ from profile, if so offer to save or abort
|
||||||
|
if self.db is not None and self.db.connected:
|
||||||
self.db.disconnect()
|
self.db.disconnect()
|
||||||
self.statusIcon.set_visible(False)
|
self.statusIcon.set_visible(False)
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
@ -691,7 +862,6 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
self.add_and_display_tab(gv_tab, "Graphs")
|
self.add_and_display_tab(gv_tab, "Graphs")
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.threads = []
|
|
||||||
# no more than 1 process can this lock at a time:
|
# no more than 1 process can this lock at a time:
|
||||||
self.lock = interlocks.InterProcessLock(name="fpdb_global_lock")
|
self.lock = interlocks.InterProcessLock(name="fpdb_global_lock")
|
||||||
self.db = None
|
self.db = None
|
||||||
|
@ -715,14 +885,17 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
menubar.show()
|
menubar.show()
|
||||||
#done menubar
|
#done menubar
|
||||||
|
|
||||||
|
self.threads = [] # objects used by tabs - no need for threads, gtk handles it
|
||||||
|
self.closeq = Queue.Queue(20) # used to signal ending of a thread (only logviewer for now)
|
||||||
|
|
||||||
self.nb = gtk.Notebook()
|
self.nb = gtk.Notebook()
|
||||||
self.nb.set_show_tabs(True)
|
self.nb.set_show_tabs(True)
|
||||||
self.nb.show()
|
self.nb.show()
|
||||||
self.main_vbox.pack_start(self.nb, True, True, 0)
|
self.main_vbox.pack_start(self.nb, True, True, 0)
|
||||||
self.pages=[]
|
self.tabs=[] # the event_boxes forming the actual tabs
|
||||||
self.tabs=[]
|
self.tab_names=[] # names of tabs used since program started, not removed if tab is closed
|
||||||
self.tab_names=[]
|
self.pages=[] # the contents of the page, not removed if tab is closed
|
||||||
self.nb_tabs=[]
|
self.nb_tab_names=[] # list of tab names currently displayed in notebook
|
||||||
|
|
||||||
self.tab_main_help(None, None)
|
self.tab_main_help(None, None)
|
||||||
|
|
||||||
|
@ -752,7 +925,6 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
sys.stderr.write("fpdb starting ...")
|
sys.stderr.write("fpdb starting ...")
|
||||||
|
|
||||||
def window_state_event_cb(self, window, event):
|
def window_state_event_cb(self, window, event):
|
||||||
print "window_state_event", event
|
|
||||||
if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||||
# -20 = GWL_EXSTYLE can't find it in the pywin32 libs
|
# -20 = GWL_EXSTYLE can't find it in the pywin32 libs
|
||||||
#bits = win32api.GetWindowLong(self.window.window.handle, -20)
|
#bits = win32api.GetWindowLong(self.window.window.handle, -20)
|
||||||
|
@ -835,6 +1007,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
gtk.main()
|
gtk.main()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
me = fpdb()
|
me = fpdb()
|
||||||
me.main()
|
me.main()
|
||||||
|
|
|
@ -106,7 +106,7 @@ class fpdb_db:
|
||||||
except MySQLdb.Error, ex:
|
except MySQLdb.Error, ex:
|
||||||
if ex.args[0] == 1045:
|
if ex.args[0] == 1045:
|
||||||
raise FpdbMySQLAccessDenied(ex.args[0], ex.args[1])
|
raise FpdbMySQLAccessDenied(ex.args[0], ex.args[1])
|
||||||
elif ex.args[0] == 2002:
|
elif ex.args[0] == 2002 or ex.args[0] == 2003: # 2002 is no unix socket, 2003 is no tcp socket
|
||||||
raise FpdbMySQLNoDatabase(ex.args[0], ex.args[1])
|
raise FpdbMySQLNoDatabase(ex.args[0], ex.args[1])
|
||||||
else:
|
else:
|
||||||
print "*** WARNING UNKNOWN MYSQL ERROR", ex
|
print "*** WARNING UNKNOWN MYSQL ERROR", ex
|
||||||
|
@ -129,18 +129,22 @@ class fpdb_db:
|
||||||
self.db = psycopg2.connect(database = database)
|
self.db = psycopg2.connect(database = database)
|
||||||
connected = True
|
connected = True
|
||||||
except:
|
except:
|
||||||
|
# direct connection failed so try user/pass/... version
|
||||||
pass
|
pass
|
||||||
#msg = "PostgreSQL direct connection to database (%s) failed, trying with user ..." % (database,)
|
|
||||||
#print msg
|
|
||||||
#raise FpdbError(msg)
|
|
||||||
if not connected:
|
if not connected:
|
||||||
try:
|
try:
|
||||||
self.db = psycopg2.connect(host = host,
|
self.db = psycopg2.connect(host = host,
|
||||||
user = user,
|
user = user,
|
||||||
password = password,
|
password = password,
|
||||||
database = database)
|
database = database)
|
||||||
except:
|
except Exception, ex:
|
||||||
msg = "PostgreSQL connection to database (%s) user (%s) failed. Are you sure the DB is running?" % (database, user)
|
if 'Connection refused' in ex.args[0]:
|
||||||
|
# meaning eg. db not running
|
||||||
|
raise FpdbPostgresqlNoDatabase(errmsg = ex.args[0])
|
||||||
|
elif 'password authentication' in ex.args[0]:
|
||||||
|
raise FpdbPostgresqlAccessDenied(errmsg = ex.args[0])
|
||||||
|
else:
|
||||||
|
msg = ex.args[0]
|
||||||
print msg
|
print msg
|
||||||
raise FpdbError(msg)
|
raise FpdbError(msg)
|
||||||
elif backend == fpdb_db.SQLITE:
|
elif backend == fpdb_db.SQLITE:
|
||||||
|
@ -154,7 +158,7 @@ class fpdb_db:
|
||||||
if not os.path.isdir(Configuration.DIR_DATABASES) and not database == ":memory:":
|
if not os.path.isdir(Configuration.DIR_DATABASES) and not database == ":memory:":
|
||||||
print "Creating directory: '%s'" % (Configuration.DIR_DATABASES)
|
print "Creating directory: '%s'" % (Configuration.DIR_DATABASES)
|
||||||
os.mkdir(Configuration.DIR_DATABASES)
|
os.mkdir(Configuration.DIR_DATABASES)
|
||||||
database = os.path.join(Configuration.DIR_DATABASE, database)
|
database = os.path.join(Configuration.DIR_DATABASES, database)
|
||||||
self.db = sqlite3.connect(database, detect_types=sqlite3.PARSE_DECLTYPES )
|
self.db = sqlite3.connect(database, detect_types=sqlite3.PARSE_DECLTYPES )
|
||||||
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||||
|
@ -167,6 +171,7 @@ class fpdb_db:
|
||||||
logging.warning("Some database functions will not work without NumPy support")
|
logging.warning("Some database functions will not work without NumPy support")
|
||||||
else:
|
else:
|
||||||
raise FpdbError("unrecognised database backend:"+backend)
|
raise FpdbError("unrecognised database backend:"+backend)
|
||||||
|
|
||||||
self.cursor = self.db.cursor()
|
self.cursor = self.db.cursor()
|
||||||
# Set up query dictionary as early in the connection process as we can.
|
# Set up query dictionary as early in the connection process as we can.
|
||||||
self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name())
|
self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name())
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
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, sleep
|
from time import time, strftime, sleep, clock
|
||||||
import traceback
|
import traceback
|
||||||
import math
|
import math
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -91,6 +91,7 @@ class Importer:
|
||||||
self.settings.setdefault("writeQMaxWait", 10) # not used
|
self.settings.setdefault("writeQMaxWait", 10) # not used
|
||||||
self.settings.setdefault("dropIndexes", "don't drop")
|
self.settings.setdefault("dropIndexes", "don't drop")
|
||||||
self.settings.setdefault("dropHudCache", "don't drop")
|
self.settings.setdefault("dropHudCache", "don't drop")
|
||||||
|
self.settings.setdefault("starsArchive", False)
|
||||||
|
|
||||||
self.writeq = None
|
self.writeq = None
|
||||||
self.database = Database.Database(self.config, sql = self.sql)
|
self.database = Database.Database(self.config, sql = self.sql)
|
||||||
|
@ -101,6 +102,8 @@ class Importer:
|
||||||
|
|
||||||
self.NEWIMPORT = Configuration.NEWIMPORT
|
self.NEWIMPORT = Configuration.NEWIMPORT
|
||||||
|
|
||||||
|
clock() # init clock in windows
|
||||||
|
|
||||||
#Set functions
|
#Set functions
|
||||||
def setCallHud(self, value):
|
def setCallHud(self, value):
|
||||||
self.callHud = value
|
self.callHud = value
|
||||||
|
@ -132,6 +135,9 @@ class Importer:
|
||||||
def setDropHudCache(self, value):
|
def setDropHudCache(self, value):
|
||||||
self.settings['dropHudCache'] = value
|
self.settings['dropHudCache'] = value
|
||||||
|
|
||||||
|
def setStarsArchive(self, value):
|
||||||
|
self.settings['starsArchive'] = value
|
||||||
|
|
||||||
# def setWatchTime(self):
|
# def setWatchTime(self):
|
||||||
# self.updated = time()
|
# self.updated = time()
|
||||||
|
|
||||||
|
@ -359,10 +365,15 @@ class Importer:
|
||||||
# print "file",counter," updated", os.path.basename(file), stat_info.st_size, self.updatedsize[file], stat_info.st_mtime, self.updatedtime[file]
|
# print "file",counter," updated", os.path.basename(file), stat_info.st_size, self.updatedsize[file], stat_info.st_mtime, self.updatedtime[file]
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(file):
|
if not os.path.isdir(file):
|
||||||
self.caller.addText("\n"+file)
|
self.caller.addText("\n"+os.path.basename(file))
|
||||||
except KeyError: # TODO: What error happens here?
|
except KeyError: # TODO: What error happens here?
|
||||||
pass
|
pass
|
||||||
self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None)
|
(stored, duplicates, partial, errors, ttime) = self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None)
|
||||||
|
try:
|
||||||
|
if not os.path.isdir(file):
|
||||||
|
self.caller.addText(" %d stored, %d duplicates, %d partial, %d errors (time = %f)" % (stored, duplicates, partial, errors, ttime))
|
||||||
|
except KeyError: # TODO: Again, what error happens here? fix when we find out ..
|
||||||
|
pass
|
||||||
self.updatedsize[file] = stat_info.st_size
|
self.updatedsize[file] = stat_info.st_size
|
||||||
self.updatedtime[file] = time()
|
self.updatedtime[file] = time()
|
||||||
else:
|
else:
|
||||||
|
@ -393,7 +404,7 @@ class Importer:
|
||||||
|
|
||||||
if os.path.isdir(file):
|
if os.path.isdir(file):
|
||||||
self.addToDirList[file] = [site] + [filter]
|
self.addToDirList[file] = [site] + [filter]
|
||||||
return
|
return (0,0,0,0,0)
|
||||||
|
|
||||||
conv = None
|
conv = None
|
||||||
(stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0)
|
(stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0)
|
||||||
|
@ -418,17 +429,33 @@ 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):
|
||||||
hhc = 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, starsArchive = self.settings['starsArchive']) # Index into file 0 until changeover
|
||||||
if hhc.getStatus() and self.NEWIMPORT == False:
|
if hhc.getStatus() and self.NEWIMPORT == False:
|
||||||
(stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(db, out_path, site, q)
|
(stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(db, out_path, site, q)
|
||||||
elif hhc.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()
|
||||||
|
to_hud = []
|
||||||
|
|
||||||
for hand in handlist:
|
for hand in handlist:
|
||||||
#hand.prepInsert()
|
if hand is not None:
|
||||||
|
#try, except duplicates here?
|
||||||
|
hand.prepInsert(self.database)
|
||||||
hand.insert(self.database)
|
hand.insert(self.database)
|
||||||
|
if self.callHud and hand.dbid_hands != 0:
|
||||||
|
to_hud.append(hand.dbid_hands)
|
||||||
|
else:
|
||||||
|
log.error("Hand processed but empty")
|
||||||
|
self.database.commit()
|
||||||
|
|
||||||
|
#pipe the Hands.id out to the HUD
|
||||||
|
for hid in to_hud:
|
||||||
|
print "fpdb_import: sending hand to hud", hand.dbid_hands, "pipe =", self.caller.pipe_to_hud
|
||||||
|
self.caller.pipe_to_hud.stdin.write("%s" % (hid) + os.linesep)
|
||||||
|
|
||||||
|
errors = getattr(hhc, 'numErrors')
|
||||||
|
stored = getattr(hhc, 'numHands')
|
||||||
else:
|
else:
|
||||||
# conversion didn't work
|
# conversion didn't work
|
||||||
# TODO: appropriate response?
|
# TODO: appropriate response?
|
||||||
|
@ -472,10 +499,13 @@ class Importer:
|
||||||
self.pos_in_file[file] = inputFile.tell()
|
self.pos_in_file[file] = inputFile.tell()
|
||||||
inputFile.close()
|
inputFile.close()
|
||||||
|
|
||||||
|
x = clock()
|
||||||
(stored, duplicates, partial, errors, ttime, handsId) = self.import_fpdb_lines(db, self.lines, starttime, file, site, q)
|
(stored, duplicates, partial, errors, ttime, handsId) = self.import_fpdb_lines(db, self.lines, starttime, file, site, q)
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
ttime = time() - starttime
|
y = clock()
|
||||||
|
ttime = y - x
|
||||||
|
#ttime = time() - starttime
|
||||||
if q is None:
|
if q is None:
|
||||||
log.info("Total stored: %(stored)d\tduplicates:%(duplicates)d\terrors:%(errors)d\ttime:%(ttime)s" % locals())
|
log.info("Total stored: %(stored)d\tduplicates:%(duplicates)d\terrors:%(errors)d\ttime:%(ttime)s" % locals())
|
||||||
|
|
||||||
|
@ -554,7 +584,11 @@ class Importer:
|
||||||
#print "call to HUD here. handsId:",handsId
|
#print "call to HUD here. handsId:",handsId
|
||||||
#pipe the Hands.id out to the HUD
|
#pipe the Hands.id out to the HUD
|
||||||
# print "fpdb_import: sending hand to hud", handsId, "pipe =", self.caller.pipe_to_hud
|
# print "fpdb_import: sending hand to hud", handsId, "pipe =", self.caller.pipe_to_hud
|
||||||
|
try:
|
||||||
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
||||||
|
except IOError: # hud closed
|
||||||
|
self.callHud = False
|
||||||
|
pass # continue import without hud
|
||||||
except Exceptions.DuplicateError:
|
except Exceptions.DuplicateError:
|
||||||
duplicates += 1
|
duplicates += 1
|
||||||
db.rollback()
|
db.rollback()
|
||||||
|
|
|
@ -1241,38 +1241,34 @@ sure to also change the following storage method and table_viewer.prepare_data i
|
||||||
|
|
||||||
|
|
||||||
#calculate saw* values
|
#calculate saw* values
|
||||||
isAllIn = False
|
isAllIn = any(i for i in allIns[0][player])
|
||||||
if any(i for i in allIns[0][player]):
|
if isAllIn or len(action_types[1][player]) > 0:
|
||||||
isAllIn = True
|
|
||||||
if (len(action_types[1][player])>0 or isAllIn):
|
|
||||||
myStreet1Seen = True
|
myStreet1Seen = True
|
||||||
|
|
||||||
if any(i for i in allIns[1][player]):
|
if not isAllIn:
|
||||||
isAllIn = True
|
isAllIn = any(i for i in allIns[1][player])
|
||||||
if (len(action_types[2][player])>0 or isAllIn):
|
if isAllIn or len(action_types[2][player]) > 0:
|
||||||
|
if all(actiontype != "fold" for actiontype in action_types[1][player]):
|
||||||
myStreet2Seen = True
|
myStreet2Seen = True
|
||||||
|
|
||||||
if any(i for i in allIns[2][player]):
|
if not isAllIn:
|
||||||
isAllIn = True
|
isAllAin = any(i for i in allIns[2][player])
|
||||||
if (len(action_types[3][player])>0 or isAllIn):
|
if isAllIn or len(action_types[3][player]) > 0:
|
||||||
|
if all(actiontype != "fold" for actiontype in action_types[2][player]):
|
||||||
myStreet3Seen = True
|
myStreet3Seen = True
|
||||||
|
|
||||||
#print "base:", base
|
#print "base:", base
|
||||||
if base == "hold":
|
if base == "hold":
|
||||||
mySawShowdown = True
|
mySawShowdown = not any(actiontype == "fold" for actiontype in action_types[3][player])
|
||||||
if any(actiontype == "fold" for actiontype in action_types[3][player]):
|
|
||||||
mySawShowdown = False
|
|
||||||
else:
|
else:
|
||||||
#print "in else"
|
#print "in else"
|
||||||
if any(i for i in allIns[3][player]):
|
if not isAllIn:
|
||||||
isAllIn = True
|
isAllIn = any(i for i in allIns[3][player])
|
||||||
if (len(action_types[4][player])>0 or isAllIn):
|
if isAllIn or len(action_types[4][player]) > 0:
|
||||||
#print "in if"
|
#print "in if"
|
||||||
myStreet4Seen = True
|
myStreet4Seen = True
|
||||||
|
|
||||||
mySawShowdown = True
|
mySawShowdown = not any(actiontype == "fold" for actiontype in action_types[4][player])
|
||||||
if any(actiontype == "fold" for actiontype in action_types[4][player]):
|
|
||||||
mySawShowdown = False
|
|
||||||
|
|
||||||
if myStreet1Seen:
|
if myStreet1Seen:
|
||||||
result['playersAtStreet1'] += 1
|
result['playersAtStreet1'] += 1
|
||||||
|
@ -1288,9 +1284,7 @@ sure to also change the following storage method and table_viewer.prepare_data i
|
||||||
#flop stuff
|
#flop stuff
|
||||||
street = 1
|
street = 1
|
||||||
if myStreet1Seen:
|
if myStreet1Seen:
|
||||||
if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
myStreet1Aggr = any(actiontype == "bet" for actiontype in action_types[street][player])
|
||||||
myStreet1Aggr = True
|
|
||||||
|
|
||||||
myStreet1Calls = action_types[street][player].count('call')
|
myStreet1Calls = action_types[street][player].count('call')
|
||||||
myStreet1Bets = action_types[street][player].count('bet')
|
myStreet1Bets = action_types[street][player].count('bet')
|
||||||
# street1Raises = action_types[street][player].count('raise') bet count includes raises for now
|
# street1Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||||
|
@ -1310,9 +1304,7 @@ sure to also change the following storage method and table_viewer.prepare_data i
|
||||||
#turn stuff - copy of flop with different vars
|
#turn stuff - copy of flop with different vars
|
||||||
street = 2
|
street = 2
|
||||||
if myStreet2Seen:
|
if myStreet2Seen:
|
||||||
if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
myStreet2Aggr = any(actiontype == "bet" for actiontype in action_types[street][player])
|
||||||
myStreet2Aggr = True
|
|
||||||
|
|
||||||
myStreet2Calls = action_types[street][player].count('call')
|
myStreet2Calls = action_types[street][player].count('call')
|
||||||
myStreet2Bets = action_types[street][player].count('bet')
|
myStreet2Bets = action_types[street][player].count('bet')
|
||||||
# street2Raises = action_types[street][player].count('raise') bet count includes raises for now
|
# street2Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||||
|
@ -1332,9 +1324,7 @@ sure to also change the following storage method and table_viewer.prepare_data i
|
||||||
#river stuff - copy of flop with different vars
|
#river stuff - copy of flop with different vars
|
||||||
street = 3
|
street = 3
|
||||||
if myStreet3Seen:
|
if myStreet3Seen:
|
||||||
if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
myStreet3Aggr = any(actiontype == "bet" for actiontype in action_types[street][player])
|
||||||
myStreet3Aggr = True
|
|
||||||
|
|
||||||
myStreet3Calls = action_types[street][player].count('call')
|
myStreet3Calls = action_types[street][player].count('call')
|
||||||
myStreet3Bets = action_types[street][player].count('bet')
|
myStreet3Bets = action_types[street][player].count('bet')
|
||||||
# street3Raises = action_types[street][player].count('raise') bet count includes raises for now
|
# street3Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||||
|
@ -1354,9 +1344,7 @@ sure to also change the following storage method and table_viewer.prepare_data i
|
||||||
#stud river stuff - copy of flop with different vars
|
#stud river stuff - copy of flop with different vars
|
||||||
street = 4
|
street = 4
|
||||||
if myStreet4Seen:
|
if myStreet4Seen:
|
||||||
if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
myStreet4Aggr = any(actiontype == "bet" for actiontype in action_types[street][player])
|
||||||
myStreet4Aggr=True
|
|
||||||
|
|
||||||
myStreet4Calls = action_types[street][player].count('call')
|
myStreet4Calls = action_types[street][player].count('call')
|
||||||
myStreet4Bets = action_types[street][player].count('bet')
|
myStreet4Bets = action_types[street][player].count('bet')
|
||||||
# street4Raises = action_types[street][player].count('raise') bet count includes raises for now
|
# street4Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||||
|
|
|
@ -11,6 +11,18 @@ keys=fileFormatter,stderrFormatter
|
||||||
level=INFO
|
level=INFO
|
||||||
handlers=consoleHandler,fileHandler
|
handlers=consoleHandler,fileHandler
|
||||||
|
|
||||||
|
[logger_fpdb]
|
||||||
|
level=INFO
|
||||||
|
handlers=consoleHandler,fileHandler
|
||||||
|
qualname=fpdb
|
||||||
|
propagate=0
|
||||||
|
|
||||||
|
[logger_logview]
|
||||||
|
level=INFO
|
||||||
|
handlers=consoleHandler,fileHandler
|
||||||
|
qualname=logview
|
||||||
|
propagate=0
|
||||||
|
|
||||||
[logger_parser]
|
[logger_parser]
|
||||||
level=INFO
|
level=INFO
|
||||||
handlers=consoleHandler,fileHandler
|
handlers=consoleHandler,fileHandler
|
||||||
|
@ -24,7 +36,7 @@ qualname=importer
|
||||||
propagate=0
|
propagate=0
|
||||||
|
|
||||||
[logger_config]
|
[logger_config]
|
||||||
level=DEBUG
|
level=INFO
|
||||||
handlers=consoleHandler,fileHandler
|
handlers=consoleHandler,fileHandler
|
||||||
qualname=config
|
qualname=config
|
||||||
propagate=0
|
propagate=0
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
***** Betfair Poker Hand History for Game 100000000 *****
|
||||||
|
PL $0.05/$0.10 Omaha - Sunday, October 18, 20:00:00 GMT 2009
|
||||||
|
Table Death 1 6-max (Real Money)
|
||||||
|
Seat 2 is the button
|
||||||
|
Total number of active players : 6
|
||||||
|
Seat 1: Player6 ( $1 )
|
||||||
|
Seat 2: Player3 ( $9.38 )
|
||||||
|
Seat 3: Player2 ( $2.82 )
|
||||||
|
Seat 4: Player4 ( $4.13 )
|
||||||
|
Seat 5: Player5 ( $28.77 )
|
||||||
|
Seat 6: Player1 ( $6.46 )
|
||||||
|
Player2 posts small blind [$0.05]
|
||||||
|
Player4 posts big blind [$0.10]
|
||||||
|
Player6 posts big blind [$0.10]
|
||||||
|
** Dealing down cards **
|
||||||
|
Dealt to Player6 [ 7c, 6c, 5h, Jh ]
|
||||||
|
Player5 folds
|
||||||
|
Player1 calls [$0.10]
|
||||||
|
Player6 checks
|
||||||
|
Player3 calls [$0.10]
|
||||||
|
Player2 raises to [$0.30]
|
||||||
|
Player4 calls [$0.20]
|
||||||
|
Player1 calls [$0.20]
|
||||||
|
Player6 goes all-in
|
||||||
|
Player6 raises to [$1]
|
||||||
|
Player3 calls [$0.90]
|
||||||
|
Player2 calls [$0.70]
|
||||||
|
Player4 calls [$0.70]
|
||||||
|
Player1 calls [$0.70]
|
||||||
|
** Dealing Flop ** [ 4d, 5d, 6d ]
|
||||||
|
Player2 checks
|
||||||
|
Player4 checks
|
||||||
|
Player1 checks
|
||||||
|
Player3 checks
|
||||||
|
** Dealing Turn ** [ 3s ]
|
||||||
|
Player2 checks
|
||||||
|
Player4 bets [$0.10]
|
||||||
|
Player1 calls [$0.10]
|
||||||
|
Player3 folds
|
||||||
|
Player2 folds
|
||||||
|
** Dealing River ** [ 4c ]
|
||||||
|
Player4 goes all-in
|
||||||
|
Player4 bets [$3.03]
|
||||||
|
Player1 calls [$3.03]
|
||||||
|
** Showdown **
|
||||||
|
Player6 shows [ 7c, 6c, 5h, Jh ] a straight, Seven to Three
|
||||||
|
Player4 shows [ 7d, 8c, 3d, 6h ] a straight flush, Seven to Three
|
||||||
|
Player1 shows [ 3h, 4h, Td, 4s ] four of a kind, Fours
|
||||||
|
** Hand Conclusion **
|
||||||
|
Player4 wins $6.26 from side pot #1 with a straight flush, Seven to Three
|
||||||
|
Player4 wins $4.44 from main pot with a straight flush, Seven to Three
|
||||||
|
************ Game 100000000 ends ************
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
PokerStars Game #25979907808: Omaha Pot Limit ($0.05/$0.10 USD) - 2009/03/15 6:20:33 ET
|
||||||
|
Table 'Waterman' 6-max Seat #1 is the button
|
||||||
|
Seat 1: s0rrow ($11.65 in chips)
|
||||||
|
s0rrow: posts small blind $0.05
|
||||||
|
ritalinIV: is sitting out
|
||||||
|
Hand cancelled
|
||||||
|
*** SUMMARY ***
|
||||||
|
Seat 1: s0rrow (button) collected ($0)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
PokerStars Game #36185273365: Hold'em No Limit ($0.05/$0.10 USD) - 2009/12/03 9:16:10 ET
|
||||||
|
Table 'Eurynome IV' 6-max Seat #3 is the button
|
||||||
|
Seat 1: s0rrow ($16.10 in chips)
|
||||||
|
Seat 2: chrisbiz ($9.45 in chips)
|
||||||
|
Seat 3: papajohn77 ($6.55 in chips)
|
||||||
|
Seat 4: WSOFish ($21.05 in chips)
|
||||||
|
Seat 5: drefron ($10 in chips)
|
||||||
|
Seat 6: garegerret ($10.60 in chips)
|
||||||
|
WSOFish: posts small blind $0.05
|
||||||
|
drefron: posts big blind $0.10
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [5s As]
|
||||||
|
garegerret: folds
|
||||||
|
s0rrow: raises $0.20 to $0.30
|
||||||
|
chrisbiz: calls $0.30
|
||||||
|
papajohn77: folds
|
||||||
|
WSOFish: folds
|
||||||
|
drefron: folds
|
||||||
|
*** FLOP *** [8c 4c 4d]
|
||||||
|
s0rrow: checks
|
||||||
|
chrisbiz: bets $0.40
|
||||||
|
s0rrow: raises $1 to $1.40
|
||||||
|
chrisbiz: calls $1
|
||||||
|
*** TURN *** [8c 4c 4d] [Kc]
|
||||||
|
s0rrow: bets $3.20
|
||||||
|
chrisbiz: calls $3.20
|
||||||
|
*** RIVER *** [8c 4c 4d Kc] [2s]
|
||||||
|
s0rrow: bets $11.20 and is all-in
|
||||||
|
chrisbiz: folds
|
||||||
|
Uncalled bet ($11.20) returned to s0rrow
|
||||||
|
s0rrow collected $9.50 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $9.95 | Rake $0.45
|
||||||
|
Board [8c 4c 4d Kc 2s]
|
||||||
|
Seat 1: s0rrow collected ($9.50)
|
||||||
|
Seat 2: chrisbiz folded on the River
|
||||||
|
Seat 3: papajohn77 (button) folded before Flop (didn't bet)
|
||||||
|
Seat 4: WSOFish (small blind) folded before Flop
|
||||||
|
Seat 5: drefron (big blind) folded before Flop
|
||||||
|
Seat 6: garegerret folded before Flop (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,602 @@
|
||||||
|
PokerStars Game #35874998500: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:36:51 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #3 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.27 in chips)
|
||||||
|
Seat 2: UnderMeSensi ($3.33 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.19 in chips)
|
||||||
|
Seat 4: xgz520 ($1.81 in chips)
|
||||||
|
Seat 5: s0rrow ($3 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
xgz520: posts small blind $0.01
|
||||||
|
s0rrow: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [2h 2c 3s 9h]
|
||||||
|
tiger48475: folds
|
||||||
|
EricSteph261: folds
|
||||||
|
UnderMeSensi: raises $0.05 to $0.07
|
||||||
|
supermeXXX: folds
|
||||||
|
xgz520: folds
|
||||||
|
s0rrow: calls $0.05
|
||||||
|
*** FLOP *** [Jd 5c Kc]
|
||||||
|
s0rrow: checks
|
||||||
|
UnderMeSensi: checks
|
||||||
|
*** TURN *** [Jd 5c Kc] [4c]
|
||||||
|
s0rrow: checks
|
||||||
|
UnderMeSensi: bets $0.08
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
*** RIVER *** [Jd 5c Kc 4c] [Th]
|
||||||
|
s0rrow: checks
|
||||||
|
UnderMeSensi: bets $0.31
|
||||||
|
EricSteph261 is sitting out
|
||||||
|
s0rrow: folds
|
||||||
|
Uncalled bet ($0.31) returned to UnderMeSensi
|
||||||
|
UnderMeSensi collected $0.31 from pot
|
||||||
|
UnderMeSensi: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.31 | Rake $0
|
||||||
|
Board [Jd 5c Kc 4c Th]
|
||||||
|
Seat 1: EricSteph261 folded before Flop (didn't bet)
|
||||||
|
Seat 2: UnderMeSensi collected ($0.31)
|
||||||
|
Seat 3: supermeXXX (button) folded before Flop (didn't bet)
|
||||||
|
Seat 4: xgz520 (small blind) folded before Flop
|
||||||
|
Seat 5: s0rrow (big blind) folded on the River
|
||||||
|
Seat 6: tiger48475 folded before Flop (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875026976: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:37:39 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #4 is the button
|
||||||
|
Seat 2: UnderMeSensi ($3.49 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.19 in chips)
|
||||||
|
Seat 4: xgz520 ($1.80 in chips)
|
||||||
|
Seat 5: s0rrow ($2.85 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
s0rrow: posts small blind $0.01
|
||||||
|
tiger48475: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [4d 3s 8d Jd]
|
||||||
|
UnderMeSensi: raises $0.05 to $0.07
|
||||||
|
supermeXXX: folds
|
||||||
|
xgz520: folds
|
||||||
|
s0rrow: folds
|
||||||
|
tiger48475: folds
|
||||||
|
Uncalled bet ($0.05) returned to UnderMeSensi
|
||||||
|
xgz520 leaves the table
|
||||||
|
UnderMeSensi collected $0.05 from pot
|
||||||
|
UnderMeSensi: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.05 | Rake $0
|
||||||
|
Seat 2: UnderMeSensi collected ($0.05)
|
||||||
|
Seat 3: supermeXXX folded before Flop (didn't bet)
|
||||||
|
Seat 4: xgz520 (button) folded before Flop (didn't bet)
|
||||||
|
Seat 5: s0rrow (small blind) folded before Flop
|
||||||
|
Seat 6: tiger48475 (big blind) folded before Flop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875034981: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:37:53 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #5 is the button
|
||||||
|
Seat 2: UnderMeSensi ($3.52 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.19 in chips)
|
||||||
|
Seat 5: s0rrow ($2.84 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
tiger48475: posts small blind $0.01
|
||||||
|
UnderMeSensi: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [Qh 6c Th 9c]
|
||||||
|
supermeXXX: raises $0.04 to $0.06
|
||||||
|
s0rrow: calls $0.06
|
||||||
|
tiger48475: folds
|
||||||
|
UnderMeSensi: calls $0.04
|
||||||
|
*** FLOP *** [5h 4d 2d]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
supermeXXX: bets $0.10
|
||||||
|
s0rrow: folds
|
||||||
|
UnderMeSensi: calls $0.10
|
||||||
|
*** TURN *** [5h 4d 2d] [Jd]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** RIVER *** [5h 4d 2d Jd] [6h]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
UnderMeSensi: shows [7c 6s 7h As] (HI: a pair of Sevens; LO: 6,5,4,2,A)
|
||||||
|
supermeXXX: shows [Ah 2h Kh 2s] (HI: three of a kind, Deuces; LO: 6,5,4,2,A)
|
||||||
|
supermeXXX collected $0.20 from pot
|
||||||
|
UnderMeSensi collected $0.10 from pot
|
||||||
|
supermeXXX collected $0.09 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.39 | Rake $0
|
||||||
|
Board [5h 4d 2d Jd 6h]
|
||||||
|
Seat 2: UnderMeSensi (big blind) showed [7c 6s 7h As] and won ($0.10) with HI: a pair of Sevens; LO: 6,5,4,2,A
|
||||||
|
Seat 3: supermeXXX showed [Ah 2h Kh 2s] and won ($0.29) with HI: three of a kind, Deuces; LO: 6,5,4,2,A
|
||||||
|
Seat 5: s0rrow (button) folded on the Flop
|
||||||
|
Seat 6: tiger48475 (small blind) folded before Flop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875059163: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:38:34 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #6 is the button
|
||||||
|
Seat 2: UnderMeSensi ($3.46 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.32 in chips)
|
||||||
|
Seat 5: s0rrow ($2.78 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
UnderMeSensi: posts small blind $0.01
|
||||||
|
supermeXXX: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [Ts Qs 9d 7c]
|
||||||
|
s0rrow: raises $0.04 to $0.06
|
||||||
|
tiger48475: folds
|
||||||
|
UnderMeSensi: calls $0.05
|
||||||
|
diyi69 joins the table at seat #4
|
||||||
|
supermeXXX: folds
|
||||||
|
*** FLOP *** [3h Ah 5d]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
s0rrow: checks
|
||||||
|
*** TURN *** [3h Ah 5d] [Kc]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
s0rrow: bets $0.14
|
||||||
|
UnderMeSensi: folds
|
||||||
|
Uncalled bet ($0.14) returned to s0rrow
|
||||||
|
s0rrow collected $0.14 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.14 | Rake $0
|
||||||
|
Board [3h Ah 5d Kc]
|
||||||
|
Seat 2: UnderMeSensi (small blind) folded on the Turn
|
||||||
|
Seat 3: supermeXXX (big blind) folded before Flop
|
||||||
|
Seat 5: s0rrow collected ($0.14)
|
||||||
|
Seat 6: tiger48475 (button) folded before Flop (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875079294: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:39:09 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #2 is the button
|
||||||
|
Seat 2: UnderMeSensi ($3.40 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.30 in chips)
|
||||||
|
Seat 4: diyi69 ($1 in chips)
|
||||||
|
Seat 5: s0rrow ($2.86 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
supermeXXX: posts small blind $0.01
|
||||||
|
diyi69: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [8s 6d 7s 2s]
|
||||||
|
s0rrow: folds
|
||||||
|
tiger48475: folds
|
||||||
|
UnderMeSensi: folds
|
||||||
|
supermeXXX: calls $0.01
|
||||||
|
diyi69 has timed out
|
||||||
|
diyi69: checks
|
||||||
|
*** FLOP *** [As Js 5h]
|
||||||
|
supermeXXX: bets $0.04
|
||||||
|
diyi69 has timed out
|
||||||
|
diyi69: folds
|
||||||
|
Uncalled bet ($0.04) returned to supermeXXX
|
||||||
|
diyi69 is sitting out
|
||||||
|
supermeXXX collected $0.04 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.04 | Rake $0
|
||||||
|
Board [As Js 5h]
|
||||||
|
Seat 2: UnderMeSensi (button) folded before Flop (didn't bet)
|
||||||
|
Seat 3: supermeXXX (small blind) collected ($0.04)
|
||||||
|
Seat 4: diyi69 (big blind) folded on the Flop
|
||||||
|
Seat 5: s0rrow folded before Flop (didn't bet)
|
||||||
|
Seat 6: tiger48475 folded before Flop (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875131707: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:40:40 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #3 is the button
|
||||||
|
Seat 2: UnderMeSensi ($3.40 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.32 in chips)
|
||||||
|
Seat 5: s0rrow ($2.86 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
s0rrow: posts small blind $0.01
|
||||||
|
tiger48475: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [7c As 4d 4h]
|
||||||
|
UnderMeSensi: calls $0.02
|
||||||
|
supermeXXX: folds
|
||||||
|
s0rrow: calls $0.01
|
||||||
|
tiger48475: checks
|
||||||
|
*** FLOP *** [Ks 9d Ts]
|
||||||
|
s0rrow: checks
|
||||||
|
tiger48475: bets $0.06
|
||||||
|
UnderMeSensi: calls $0.06
|
||||||
|
s0rrow: folds
|
||||||
|
*** TURN *** [Ks 9d Ts] [7h]
|
||||||
|
tiger48475: checks
|
||||||
|
EricSteph261 has returned
|
||||||
|
UnderMeSensi: checks
|
||||||
|
*** RIVER *** [Ks 9d Ts 7h] [4s]
|
||||||
|
tiger48475: checks
|
||||||
|
UnderMeSensi: bets $0.10
|
||||||
|
tiger48475: folds
|
||||||
|
Uncalled bet ($0.10) returned to UnderMeSensi
|
||||||
|
UnderMeSensi collected $0.18 from pot
|
||||||
|
UnderMeSensi: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.18 | Rake $0
|
||||||
|
Board [Ks 9d Ts 7h 4s]
|
||||||
|
Seat 2: UnderMeSensi collected ($0.18)
|
||||||
|
Seat 3: supermeXXX (button) folded before Flop (didn't bet)
|
||||||
|
Seat 5: s0rrow (small blind) folded on the Flop
|
||||||
|
Seat 6: tiger48475 (big blind) folded on the River
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875159084: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:41:27 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #5 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.27 in chips)
|
||||||
|
Seat 2: UnderMeSensi ($3.50 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.32 in chips)
|
||||||
|
Seat 5: s0rrow ($2.84 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
tiger48475: posts small blind $0.01
|
||||||
|
EricSteph261: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [Jc 3h 2s Qc]
|
||||||
|
UnderMeSensi: calls $0.02
|
||||||
|
supermeXXX: calls $0.02
|
||||||
|
s0rrow: raises $0.08 to $0.10
|
||||||
|
tiger48475: folds
|
||||||
|
EricSteph261: folds
|
||||||
|
UnderMeSensi: calls $0.08
|
||||||
|
supermeXXX: folds
|
||||||
|
*** FLOP *** [Ac 5s Js]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
s0rrow: bets $0.20
|
||||||
|
UnderMeSensi: calls $0.20
|
||||||
|
*** TURN *** [Ac 5s Js] [8c]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
s0rrow: bets $0.50
|
||||||
|
UnderMeSensi: calls $0.50
|
||||||
|
*** RIVER *** [Ac 5s Js 8c] [Jd]
|
||||||
|
UnderMeSensi: bets $1.60
|
||||||
|
s0rrow: calls $1.60
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
UnderMeSensi: shows [7s 9s Jh 3c] (HI: three of a kind, Jacks; LO: 8,7,5,3,A)
|
||||||
|
s0rrow: shows [Jc 3h 2s Qc] (HI: three of a kind, Jacks - Ace+Queen kicker; LO: 8,5,3,2,A)
|
||||||
|
s0rrow collected $2.33 from pot
|
||||||
|
s0rrow collected $2.32 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $4.85 | Rake $0.20
|
||||||
|
Board [Ac 5s Js 8c Jd]
|
||||||
|
Seat 1: EricSteph261 (big blind) folded before Flop
|
||||||
|
Seat 2: UnderMeSensi showed [7s 9s Jh 3c] and lost with HI: three of a kind, Jacks; LO: 8,7,5,3,A
|
||||||
|
Seat 3: supermeXXX folded before Flop
|
||||||
|
Seat 5: s0rrow (button) showed [Jc 3h 2s Qc] and won ($4.65) with HI: three of a kind, Jacks; LO: 8,5,3,2,A
|
||||||
|
Seat 6: tiger48475 (small blind) folded before Flop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875194885: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:42:28 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #6 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.25 in chips)
|
||||||
|
Seat 2: UnderMeSensi ($1.10 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.30 in chips)
|
||||||
|
Seat 5: s0rrow ($5.09 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
EricSteph261: posts small blind $0.01
|
||||||
|
UnderMeSensi: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [7s 3c 3h 8d]
|
||||||
|
supermeXXX: folds
|
||||||
|
s0rrow: raises $0.02 to $0.04
|
||||||
|
tiger48475: calls $0.04
|
||||||
|
EricSteph261: calls $0.03
|
||||||
|
UnderMeSensi: calls $0.02
|
||||||
|
*** FLOP *** [8c 3s 4s]
|
||||||
|
EricSteph261: checks
|
||||||
|
UnderMeSensi: checks
|
||||||
|
s0rrow: bets $0.14
|
||||||
|
tiger48475: folds
|
||||||
|
EricSteph261: folds
|
||||||
|
UnderMeSensi: folds
|
||||||
|
Uncalled bet ($0.14) returned to s0rrow
|
||||||
|
s0rrow collected $0.16 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.16 | Rake $0
|
||||||
|
Board [8c 3s 4s]
|
||||||
|
Seat 1: EricSteph261 (small blind) folded on the Flop
|
||||||
|
Seat 2: UnderMeSensi (big blind) folded on the Flop
|
||||||
|
Seat 3: supermeXXX folded before Flop (didn't bet)
|
||||||
|
Seat 5: s0rrow collected ($0.16)
|
||||||
|
Seat 6: tiger48475 (button) folded on the Flop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875219121: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:43:08 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #1 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.21 in chips)
|
||||||
|
Seat 2: UnderMeSensi ($1.06 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.30 in chips)
|
||||||
|
Seat 5: s0rrow ($5.21 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
UnderMeSensi: posts small blind $0.01
|
||||||
|
supermeXXX: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [Ks Qd Kd Kc]
|
||||||
|
s0rrow: raises $0.04 to $0.06
|
||||||
|
tiger48475: folds
|
||||||
|
EricSteph261: calls $0.06
|
||||||
|
UnderMeSensi: calls $0.05
|
||||||
|
supermeXXX: calls $0.04
|
||||||
|
*** FLOP *** [2d Jh 5h]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
s0rrow: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
*** TURN *** [2d Jh 5h] [Js]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
s0rrow: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
*** RIVER *** [2d Jh 5h Js] [7s]
|
||||||
|
UnderMeSensi: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
s0rrow: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
UnderMeSensi: shows [5d 6c As 9d] (HI: two pair, Jacks and Fives; LO: 7,6,5,2,A)
|
||||||
|
supermeXXX: shows [6s Th 7c Ac] (HI: two pair, Jacks and Sevens; LO: 7,6,5,2,A)
|
||||||
|
s0rrow: shows [Ks Qd Kd Kc] (HI: two pair, Kings and Jacks)
|
||||||
|
EricSteph261: shows [4s 9c 3d 2c] (HI: two pair, Jacks and Deuces; LO: 7,5,4,3,2)
|
||||||
|
s0rrow collected $0.12 from pot
|
||||||
|
EricSteph261 collected $0.12 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.24 | Rake $0
|
||||||
|
Board [2d Jh 5h Js 7s]
|
||||||
|
Seat 1: EricSteph261 (button) showed [4s 9c 3d 2c] and won ($0.12) with HI: two pair, Jacks and Deuces; LO: 7,5,4,3,2
|
||||||
|
Seat 2: UnderMeSensi (small blind) showed [5d 6c As 9d] and lost with HI: two pair, Jacks and Fives; LO: 7,6,5,2,A
|
||||||
|
Seat 3: supermeXXX (big blind) showed [6s Th 7c Ac] and lost with HI: two pair, Jacks and Sevens; LO: 7,6,5,2,A
|
||||||
|
Seat 5: s0rrow showed [Ks Qd Kd Kc] and won ($0.12) with HI: two pair, Kings and Jacks
|
||||||
|
Seat 6: tiger48475 folded before Flop (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875246335: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:43:54 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #2 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.27 in chips)
|
||||||
|
Seat 2: UnderMeSensi ($1 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.24 in chips)
|
||||||
|
Seat 5: s0rrow ($5.27 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
supermeXXX: posts small blind $0.01
|
||||||
|
s0rrow: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [Jd Kc 6h Jc]
|
||||||
|
tiger48475: folds
|
||||||
|
EricSteph261: calls $0.02
|
||||||
|
UnderMeSensi is disconnected
|
||||||
|
UnderMeSensi has timed out while disconnected
|
||||||
|
UnderMeSensi: folds
|
||||||
|
UnderMeSensi is sitting out
|
||||||
|
supermeXXX: calls $0.01
|
||||||
|
s0rrow: checks
|
||||||
|
*** FLOP *** [8d 7s Qh]
|
||||||
|
supermeXXX: bets $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
EricSteph261: calls $0.02
|
||||||
|
*** TURN *** [8d 7s Qh] [As]
|
||||||
|
supermeXXX: bets $0.04
|
||||||
|
EricSteph261: calls $0.04
|
||||||
|
*** RIVER *** [8d 7s Qh As] [5d]
|
||||||
|
supermeXXX: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
supermeXXX: shows [Kh Qd 9s Th] (HI: a pair of Queens)
|
||||||
|
EricSteph261: shows [Jh 2d 5s 6c] (HI: a pair of Fives; LO: 7,6,5,2,A)
|
||||||
|
supermeXXX collected $0.09 from pot
|
||||||
|
EricSteph261 collected $0.09 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.18 | Rake $0
|
||||||
|
Board [8d 7s Qh As 5d]
|
||||||
|
Seat 1: EricSteph261 showed [Jh 2d 5s 6c] and won ($0.09) with HI: a pair of Fives; LO: 7,6,5,2,A
|
||||||
|
Seat 2: UnderMeSensi (button) folded before Flop (didn't bet)
|
||||||
|
Seat 3: supermeXXX (small blind) showed [Kh Qd 9s Th] and won ($0.09) with HI: a pair of Queens
|
||||||
|
Seat 5: s0rrow (big blind) folded on the Flop
|
||||||
|
Seat 6: tiger48475 folded before Flop (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875293439: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:45:14 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #3 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.28 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.25 in chips)
|
||||||
|
Seat 5: s0rrow ($5.25 in chips)
|
||||||
|
Seat 6: tiger48475 ($5 in chips)
|
||||||
|
s0rrow: posts small blind $0.01
|
||||||
|
tiger48475: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [9c 8h 8s 3c]
|
||||||
|
EricSteph261: calls $0.02
|
||||||
|
supermeXXX: calls $0.02
|
||||||
|
s0rrow: calls $0.01
|
||||||
|
tiger48475: checks
|
||||||
|
*** FLOP *** [Ah 2d Qc]
|
||||||
|
s0rrow: checks
|
||||||
|
tiger48475: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** TURN *** [Ah 2d Qc] [3d]
|
||||||
|
s0rrow: checks
|
||||||
|
tiger48475: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** RIVER *** [Ah 2d Qc 3d] [6s]
|
||||||
|
s0rrow: checks
|
||||||
|
tiger48475: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
s0rrow: shows [9c 8h 8s 3c] (HI: a pair of Eights; LO: 8,6,3,2,A)
|
||||||
|
tiger48475: shows [3s 5s Ts Th] (HI: a pair of Tens; LO: 6,5,3,2,A)
|
||||||
|
EricSteph261: shows [As Ks Jh 7h] (HI: a pair of Aces; LO: 7,6,3,2,A)
|
||||||
|
supermeXXX: mucks hand
|
||||||
|
EricSteph261 collected $0.04 from pot
|
||||||
|
tiger48475 collected $0.04 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.08 | Rake $0
|
||||||
|
Board [Ah 2d Qc 3d 6s]
|
||||||
|
Seat 1: EricSteph261 showed [As Ks Jh 7h] and won ($0.04) with HI: a pair of Aces; LO: 7,6,3,2,A
|
||||||
|
Seat 3: supermeXXX (button) mucked [9h 9s 4c Kc]
|
||||||
|
Seat 5: s0rrow (small blind) showed [9c 8h 8s 3c] and lost with HI: a pair of Eights; LO: 8,6,3,2,A
|
||||||
|
Seat 6: tiger48475 (big blind) showed [3s 5s Ts Th] and won ($0.04) with HI: a pair of Tens; LO: 6,5,3,2,A
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875328026: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:46:13 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #5 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.30 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.23 in chips)
|
||||||
|
Seat 5: s0rrow ($5.23 in chips)
|
||||||
|
Seat 6: tiger48475 ($5.02 in chips)
|
||||||
|
tiger48475: posts small blind $0.01
|
||||||
|
EricSteph261: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [Qd 6h 8s 6c]
|
||||||
|
supermeXXX: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
tiger48475: calls $0.01
|
||||||
|
EricSteph261: checks
|
||||||
|
*** FLOP *** [Kc Ac 5s]
|
||||||
|
tiger48475: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** TURN *** [Kc Ac 5s] [3h]
|
||||||
|
tiger48475: checks
|
||||||
|
EricSteph261: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** RIVER *** [Kc Ac 5s 3h] [Qh]
|
||||||
|
tiger48475: bets $0.06
|
||||||
|
EricSteph261: folds
|
||||||
|
EricSteph261 is sitting out
|
||||||
|
supermeXXX: folds
|
||||||
|
Uncalled bet ($0.06) returned to tiger48475
|
||||||
|
tiger48475 collected $0.06 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.06 | Rake $0
|
||||||
|
Board [Kc Ac 5s 3h Qh]
|
||||||
|
Seat 1: EricSteph261 (big blind) folded on the River
|
||||||
|
Seat 3: supermeXXX folded on the River
|
||||||
|
Seat 5: s0rrow (button) folded before Flop (didn't bet)
|
||||||
|
Seat 6: tiger48475 (small blind) collected ($0.06)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875356253: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:47:00 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #6 is the button
|
||||||
|
Seat 3: supermeXXX ($1.21 in chips)
|
||||||
|
Seat 5: s0rrow ($5.23 in chips)
|
||||||
|
Seat 6: tiger48475 ($5.06 in chips)
|
||||||
|
supermeXXX: posts small blind $0.01
|
||||||
|
s0rrow: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [8h Jd 5d 8d]
|
||||||
|
tiger48475: folds
|
||||||
|
supermeXXX: calls $0.01
|
||||||
|
s0rrow: checks
|
||||||
|
*** FLOP *** [Ks 9s 6c]
|
||||||
|
supermeXXX: bets $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
*** TURN *** [Ks 9s 6c] [Qc]
|
||||||
|
supermeXXX: bets $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
*** RIVER *** [Ks 9s 6c Qc] [Ad]
|
||||||
|
supermeXXX: checks
|
||||||
|
s0rrow: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
supermeXXX: shows [Tc 7d 8c 3s] (HI: high card Ace)
|
||||||
|
s0rrow: shows [8h Jd 5d 8d] (HI: a pair of Eights)
|
||||||
|
s0rrow collected $0.12 from pot
|
||||||
|
No low hand qualified
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.12 | Rake $0
|
||||||
|
Board [Ks 9s 6c Qc Ad]
|
||||||
|
Seat 3: supermeXXX (small blind) showed [Tc 7d 8c 3s] and lost with HI: high card Ace
|
||||||
|
Seat 5: s0rrow (big blind) showed [8h Jd 5d 8d] and won ($0.12) with HI: a pair of Eights
|
||||||
|
Seat 6: tiger48475 (button) folded before Flop (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875379792: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:47:39 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #3 is the button
|
||||||
|
Seat 3: supermeXXX ($1.15 in chips)
|
||||||
|
Seat 5: s0rrow ($5.29 in chips)
|
||||||
|
Seat 6: tiger48475 ($5.06 in chips)
|
||||||
|
s0rrow: posts small blind $0.01
|
||||||
|
tiger48475: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [9c 5h 3s Th]
|
||||||
|
supermeXXX: calls $0.02
|
||||||
|
s0rrow: calls $0.01
|
||||||
|
tiger48475: checks
|
||||||
|
*** FLOP *** [Jc 3h Jd]
|
||||||
|
s0rrow: checks
|
||||||
|
tiger48475: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** TURN *** [Jc 3h Jd] [6d]
|
||||||
|
s0rrow: checks
|
||||||
|
tiger48475: bets $0.06
|
||||||
|
supermeXXX: folds
|
||||||
|
EricSteph261 has returned
|
||||||
|
s0rrow: calls $0.06
|
||||||
|
*** RIVER *** [Jc 3h Jd 6d] [5c]
|
||||||
|
s0rrow: checks
|
||||||
|
tiger48475: bets $0.14
|
||||||
|
s0rrow: folds
|
||||||
|
Uncalled bet ($0.14) returned to tiger48475
|
||||||
|
tiger48475 collected $0.18 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.18 | Rake $0
|
||||||
|
Board [Jc 3h Jd 6d 5c]
|
||||||
|
Seat 3: supermeXXX (button) folded on the Turn
|
||||||
|
Seat 5: s0rrow (small blind) folded on the River
|
||||||
|
Seat 6: tiger48475 (big blind) collected ($0.18)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35875409365: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:48:29 ET
|
||||||
|
Table 'Gaby II' 6-max Seat #5 is the button
|
||||||
|
Seat 1: EricSteph261 ($11.28 in chips)
|
||||||
|
Seat 3: supermeXXX ($1.13 in chips)
|
||||||
|
Seat 5: s0rrow ($5.21 in chips)
|
||||||
|
Seat 6: tiger48475 ($5.16 in chips)
|
||||||
|
tiger48475: posts small blind $0.01
|
||||||
|
EricSteph261: posts big blind $0.02
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [6h 3c Th 2s]
|
||||||
|
supermeXXX: calls $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
tiger48475: calls $0.01
|
||||||
|
EricSteph261 has timed out
|
||||||
|
EricSteph261: checks
|
||||||
|
*** FLOP *** [9d 5s Jh]
|
||||||
|
tiger48475: bets $0.06
|
||||||
|
EricSteph261 has timed out
|
||||||
|
EricSteph261: folds
|
||||||
|
EricSteph261 is sitting out
|
||||||
|
supermeXXX: calls $0.06
|
||||||
|
s0rrow: calls $0.06
|
||||||
|
*** TURN *** [9d 5s Jh] [Ks]
|
||||||
|
tiger48475: checks
|
||||||
|
supermeXXX: bets $0.10
|
||||||
|
s0rrow: folds
|
||||||
|
tiger48475: calls $0.10
|
||||||
|
*** RIVER *** [9d 5s Jh Ks] [9s]
|
||||||
|
tiger48475: checks
|
||||||
|
supermeXXX: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
tiger48475: shows [6s 9h 9c Ad] (HI: four of a kind, Nines)
|
||||||
|
supermeXXX: mucks hand
|
||||||
|
tiger48475 collected $0.46 from pot
|
||||||
|
No low hand qualified
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.46 | Rake $0
|
||||||
|
Board [9d 5s Jh Ks 9s]
|
||||||
|
Seat 1: EricSteph261 (big blind) folded on the Flop
|
||||||
|
Seat 3: supermeXXX mucked [Qd Tc 5h Ts]
|
||||||
|
Seat 5: s0rrow (button) folded on the Turn
|
||||||
|
Seat 6: tiger48475 (small blind) showed [6s 9h 9c Ad] and won ($0.46) with HI: four of a kind, Nines
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
PokerStars Game #35874676388: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:27:46 ET
|
||||||
|
Table 'Dawn II' 8-max
|
||||||
|
Seat 1: u.pressure ($11.17 in chips)
|
||||||
|
Seat 2: 123smoothie ($0.99 in chips)
|
||||||
|
Seat 3: gashpor ($1.40 in chips)
|
||||||
|
Seat 4: denny501 ($0.71 in chips)
|
||||||
|
Seat 5: s0rrow ($1.52 in chips)
|
||||||
|
Seat 6: TomSludge ($1.58 in chips)
|
||||||
|
Seat 7: Soroka69 ($0.83 in chips)
|
||||||
|
Seat 8: rdiezchang ($2.05 in chips)
|
||||||
|
u.pressure: posts the ante $0.01
|
||||||
|
123smoothie: posts the ante $0.01
|
||||||
|
gashpor: posts the ante $0.01
|
||||||
|
denny501: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
TomSludge: posts the ante $0.01
|
||||||
|
Soroka69: posts the ante $0.01
|
||||||
|
rdiezchang: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to u.pressure [Td]
|
||||||
|
Dealt to 123smoothie [4c]
|
||||||
|
Dealt to gashpor [5d]
|
||||||
|
Dealt to denny501 [2c]
|
||||||
|
Dealt to s0rrow [7c 3s 5h]
|
||||||
|
Dealt to TomSludge [8s]
|
||||||
|
Dealt to Soroka69 [7d]
|
||||||
|
Dealt to rdiezchang [Ad]
|
||||||
|
denny501: brings in for $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
TomSludge: folds
|
||||||
|
Soroka69: calls $0.02
|
||||||
|
rdiezchang: calls $0.02
|
||||||
|
u.pressure: folds
|
||||||
|
123smoothie: calls $0.02
|
||||||
|
gashpor: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to 123smoothie [4c] [3c]
|
||||||
|
Dealt to gashpor [5d] [Qd]
|
||||||
|
Dealt to denny501 [2c] [7s]
|
||||||
|
Dealt to s0rrow [7c 3s 5h] [Qc]
|
||||||
|
Dealt to Soroka69 [7d] [5s]
|
||||||
|
Dealt to rdiezchang [Ad] [Js]
|
||||||
|
rdiezchang: checks
|
||||||
|
123smoothie: checks
|
||||||
|
gashpor: checks
|
||||||
|
denny501: folds
|
||||||
|
denny501 leaves the table
|
||||||
|
s0rrow: checks
|
||||||
|
Soroka69: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to 123smoothie [4c 3c] [9s]
|
||||||
|
Dealt to gashpor [5d Qd] [Jd]
|
||||||
|
Dealt to s0rrow [7c 3s 5h Qc] [Kc]
|
||||||
|
Dealt to Soroka69 [7d 5s] [5c]
|
||||||
|
Dealt to rdiezchang [Ad Js] [Ts]
|
||||||
|
LainaRahat joins the table at seat #4
|
||||||
|
Soroka69: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
123smoothie: checks
|
||||||
|
gashpor: bets $0.08
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
Soroka69: calls $0.08
|
||||||
|
rdiezchang: folds
|
||||||
|
123smoothie: folds
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to gashpor [5d Qd Jd] [9d]
|
||||||
|
Dealt to s0rrow [7c 3s 5h Qc Kc] [6d]
|
||||||
|
Dealt to Soroka69 [7d 5s 5c] [2s]
|
||||||
|
Soroka69: checks
|
||||||
|
gashpor: bets $0.08
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
Soroka69: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
Dealt to s0rrow [7c 3s 5h Qc Kc 6d] [4d]
|
||||||
|
Soroka69: checks
|
||||||
|
gashpor: bets $0.08
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
Soroka69: folds
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
gashpor: shows [4h 3d 5d Qd Jd 9d 6h] (HI: a flush, Queen high)
|
||||||
|
s0rrow: shows [7c 3s 5h Qc Kc 6d 4d] (HI: a straight, Three to Seven; LO: 7,6,5,4,3)
|
||||||
|
gashpor collected $0.40 from pot
|
||||||
|
s0rrow collected $0.40 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.84 | Rake $0.04
|
||||||
|
Seat 1: u.pressure folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 2: 123smoothie folded on the 5th Street
|
||||||
|
Seat 3: gashpor showed [4h 3d 5d Qd Jd 9d 6h] and won ($0.40) with HI: a flush, Queen high
|
||||||
|
Seat 4: denny501 folded on the 4th Street
|
||||||
|
Seat 5: s0rrow showed [7c 3s 5h Qc Kc 6d 4d] and won ($0.40) with HI: a straight, Three to Seven; LO: 7,6,5,4,3
|
||||||
|
Seat 6: TomSludge folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 7: Soroka69 folded on the River
|
||||||
|
Seat 8: rdiezchang folded on the 5th Street
|
||||||
|
|
||||||
|
|
||||||
|
|
29
pyfpdb/test1.py
Executable file
29
pyfpdb/test1.py
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""test1.py
|
||||||
|
|
||||||
|
Test if python is working.
|
||||||
|
"""
|
||||||
|
# Copyright 2008, Ray E. Barker
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print "\npython is working!"
|
||||||
|
print "\npress return to finish"
|
||||||
|
|
||||||
|
sys.stdin.readline()
|
57
pyfpdb/test2.py
Executable file
57
pyfpdb/test2.py
Executable file
|
@ -0,0 +1,57 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""test2.py
|
||||||
|
|
||||||
|
Test if gtk is working.
|
||||||
|
"""
|
||||||
|
# Copyright 2008, Ray E. Barker
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pygtk
|
||||||
|
pygtk.require('2.0')
|
||||||
|
import gtk
|
||||||
|
|
||||||
|
|
||||||
|
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
|
win.set_title("Test GTK")
|
||||||
|
win.set_border_width(1)
|
||||||
|
win.set_default_size(600, 500)
|
||||||
|
win.set_resizable(True)
|
||||||
|
#win.show()
|
||||||
|
|
||||||
|
dia = gtk.Dialog("Test GTK",
|
||||||
|
win,
|
||||||
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
(gtk.STOCK_CLOSE, gtk.RESPONSE_OK))
|
||||||
|
dia.set_default_size(500, 300)
|
||||||
|
|
||||||
|
l = gtk.Label("GTK is working!")
|
||||||
|
dia.vbox.add(l)
|
||||||
|
l.show()
|
||||||
|
|
||||||
|
response = dia.run()
|
||||||
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
pass
|
||||||
|
dia.destroy()
|
||||||
|
|
||||||
|
except:
|
||||||
|
print "\nError:", sys.exc_info()
|
||||||
|
print "\npress return to finish"
|
||||||
|
sys.stdin.readline()
|
|
@ -1,21 +1,34 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import BetfairToFpdb
|
import BetfairToFpdb
|
||||||
|
from Hand import *
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
import Configuration
|
||||||
|
import Database
|
||||||
|
import SQL
|
||||||
|
import fpdb_import
|
||||||
|
|
||||||
def checkGameInfo(hhc, header, info):
|
config = Configuration.Config(file = "HUD_config.test.xml")
|
||||||
assert hhc.determineGameType(header) == info
|
db = Database.Database(config)
|
||||||
|
sql = SQL.Sql(db_server = 'sqlite')
|
||||||
|
|
||||||
def testGameInfo():
|
settings = {}
|
||||||
hhc = BetfairToFpdb.Betfair(autostart=False)
|
settings.update(config.get_db_parameters())
|
||||||
pairs = (
|
settings.update(config.get_tv_parameters())
|
||||||
(u"""***** Betfair Poker Hand History for Game 472386869 *****
|
settings.update(config.get_import_parameters())
|
||||||
NL $0.02/$0.04 Texas Hold'em - Sunday, January 25, 10:10:42 GMT 2009
|
settings.update(config.get_default_paths())
|
||||||
Table Rookie 191 6-max (Real Money)
|
|
||||||
Seat 1 is the button
|
|
||||||
Total number of active players : 6""",
|
|
||||||
{'type':'ring', 'base':"hold", 'category':'holdem', 'limitType':'nl', 'sb':'0.02', 'bb':'0.04', 'currency':'USD'}),
|
|
||||||
)
|
|
||||||
|
|
||||||
for (header, info) in pairs:
|
def testFlopImport():
|
||||||
yield checkGameInfo, hhc, header, info
|
db.recreate_tables()
|
||||||
|
importer = fpdb_import.Importer(False, settings, config)
|
||||||
|
importer.setDropIndexes("don't drop")
|
||||||
|
importer.setFailOnError(True)
|
||||||
|
importer.setThreads(-1)
|
||||||
|
importer.addBulkImportImportFileOrDir(
|
||||||
|
"""regression-test-files/cash/Betfair/Flop/PLO-6max-USD-0.05-0.10-200909.All.in.river.splitpot.txt""", site="Betfair")
|
||||||
|
importer.setCallHud(False)
|
||||||
|
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||||
|
importer.clearFileList()
|
||||||
|
|
||||||
|
# Should actually do some testing here
|
||||||
|
assert 1 == 1
|
||||||
|
|
|
@ -74,12 +74,45 @@ def testFlopImport():
|
||||||
# """regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt""", site="PokerStars")
|
# """regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt""", site="PokerStars")
|
||||||
importer.addBulkImportImportFileOrDir(
|
importer.addBulkImportImportFileOrDir(
|
||||||
"""regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt""", site="PokerStars")
|
"""regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt""", site="PokerStars")
|
||||||
|
#HID - 36185273365
|
||||||
|
# Besides the horrible play it contains lots of useful cases
|
||||||
|
# Preflop: raise, then 3bet chance for seat 2
|
||||||
|
# Flop: Checkraise by hero, 4bet chance not taken by villain
|
||||||
|
# Turn: Turn continuation bet by hero, called
|
||||||
|
# River: hero (continuation bets?) all-in and is not called
|
||||||
|
importer.addBulkImportImportFileOrDir(
|
||||||
|
"""regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Stats-comparision.txt""", site="PokerStars")
|
||||||
importer.setCallHud(False)
|
importer.setCallHud(False)
|
||||||
(stored, dups, partial, errs, ttime) = importer.runImport()
|
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||||
|
print "DEBUG: stored: %s dups: %s partial: %s errs: %s ttime: %s" %(stored, dups, partial, errs, ttime)
|
||||||
importer.clearFileList()
|
importer.clearFileList()
|
||||||
|
|
||||||
# Should actually do some testing here
|
col = { 'sawShowdown': 2
|
||||||
assert 1 == 1
|
}
|
||||||
|
|
||||||
|
q = """SELECT
|
||||||
|
s.name,
|
||||||
|
p.name,
|
||||||
|
hp.sawShowdown
|
||||||
|
FROM
|
||||||
|
Hands as h,
|
||||||
|
Sites as s,
|
||||||
|
Gametypes as g,
|
||||||
|
HandsPlayers as hp,
|
||||||
|
Players as p
|
||||||
|
WHERE
|
||||||
|
h.siteHandNo = 36185273365
|
||||||
|
and g.id = h.gametypeid
|
||||||
|
and hp.handid = h.id
|
||||||
|
and p.id = hp.playerid
|
||||||
|
and s.id = p.siteid"""
|
||||||
|
c = db.get_cursor()
|
||||||
|
c.execute(q)
|
||||||
|
result = c.fetchall()
|
||||||
|
for row, data in enumerate(result):
|
||||||
|
print "DEBUG: result[%s]: %s" %(row, result[row])
|
||||||
|
# Assert if any sawShowdown = True
|
||||||
|
assert result[row][col['sawShowdown']] == 0
|
||||||
|
|
||||||
def testStudImport():
|
def testStudImport():
|
||||||
db.recreate_tables()
|
db.recreate_tables()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user