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

Conflicts:
	pyfpdb/AbsoluteToFpdb.py
This commit is contained in:
eblade 2009-08-06 00:00:29 -04:00
commit 2e698bb1d4
10 changed files with 2888 additions and 2512 deletions

View File

@ -181,9 +181,9 @@ or None if we fail to get the info """
#m = re.search('(\*\* Dealing down cards \*\*\n)(?P<PREFLOP>.*?\n\*\*)?( Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \])?(?P<FLOP>.*?\*\*)?( Dealing Turn \*\* \[ (?P<TURN1>\S\S) \])?(?P<TURN>.*?\*\*)?( Dealing River \*\* \[ (?P<RIVER1>\S\S) \])?(?P<RIVER>.*)', hand.handText,re.DOTALL)
if hand.gametype['base'] == 'hold':
m = re.search(r"\*\*\* POCKET CARDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP \*\*\*)|.+)"
r"\*\*\* FLOP \*\*\*(?P<FLOP>.+(?=\*\*\* TURN \*\*\*)|.+)"
r"\*\*\* TURN \*\*\*(?P<TURN>.+(?=\*\*\* RIVER \*\*\*)|.+)"
r"\*\*\* RIVER \*\*\*(?P<RIVER>.+)", hand.handText, re.DOTALL)
r"(\*\*\* FLOP \*\*\*(?P<FLOP>.+(?=\*\*\* TURN \*\*\*)|.+))?"
r"(\*\*\* TURN \*\*\*(?P<TURN>.+(?=\*\*\* RIVER \*\*\*)|.+))?"
r"(\*\*\* RIVER \*\*\*(?P<RIVER>.+))?", hand.handText, re.DOTALL)
elif hand.gametype['base'] == 'stud': # TODO: Not implemented yet
m = re.search(r"(?P<ANTES>.+(?=\*\* Dealing down cards \*\*)|.+)"
@ -313,7 +313,6 @@ def validCard(card):
if card == '10c': card = 'Tc'
return card
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="-")

View File

@ -452,7 +452,7 @@ class Database:
def get_player_id(self, config, site, player_name):
c = self.connection.cursor()
c.execute(self.sql.query['get_player_id'], {'player': player_name, 'site': site})
c.execute(self.sql.query['get_player_id'], (player_name, site))
row = c.fetchone()
if row:
return row[0]
@ -813,9 +813,11 @@ class Database:
self.fillDefaultData()
self.commit()
except:
print "Error creating tables: ", str(sys.exc_value)
#print "Error creating tables: ", str(sys.exc_value)
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "***Error creating tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
self.rollback()
raise fpdb_simple.FpdbError( "Error creating tables " + str(sys.exc_value) )
raise
#end def disconnect
def drop_tables(self):
@ -845,8 +847,9 @@ class Database:
self.commit()
except:
print "Error dropping tables: " + str(sys.exc_value)
raise fpdb_simple.FpdbError( "Error dropping tables " + str(sys.exc_value) )
print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
self.rollback()
raise
#end def drop_tables
def createAllIndexes(self):
@ -917,8 +920,14 @@ class Database:
c.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('Win2day', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('OnGame', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('UltimateBet', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('Betfair', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('Absolute', 'USD')")
c.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
if self.backend == self.SQLITE:
c.execute("INSERT INTO TourneyTypes VALUES (NULL, 1, 0, 0, 0, 0);")
else:
c.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
#c.execute("""INSERT INTO TourneyTypes
# (siteId,buyin,fee,knockout,rebuyOrAddon) VALUES
# (1,0,0,0,?)""",(False,) )
@ -1795,6 +1804,8 @@ if __name__=="__main__":
print "database connection object = ", db_connection.connection
print "database type = ", db_connection.type
db_connection.recreate_tables()
h = db_connection.get_last_hand()
print "last hand = ", h

View File

@ -15,6 +15,9 @@
#In the "official" distribution you can find the license in
#agpl-3.0.txt in the docs folder of the package.
#fpdb modules
import Card
class DerivedStats():
def __init__(self, hand):
self.hand = hand
@ -88,6 +91,70 @@ class DerivedStats():
self.street3CheckCallRaiseDone = 0
self.street4CheckCallRaiseChance = 0
self.street4CheckCallRaiseDone = 0
self.hands = {}
self.handsplayers = {}
def getStats():
pass
def getStats(self, hand):
for player in hand.players:
self.handsplayers[player[1]] = {}
self.assembleHands(self.hand)
self.assembleHandsPlayers(self.hand)
print "hands =", self.hands
print "handsplayers =", self.handsplayers
def assembleHands(self, hand):
self.hands['tableName'] = hand.tablename
self.hands['siteHandNo'] = hand.handid
self.hands['gametypeId'] = None # Leave None, handled later after checking db
self.hands['handStart'] = hand.starttime # format this!
self.hands['importTime'] = None
self.hands['seats'] = self.countPlayers(hand)
self.hands['maxSeats'] = hand.maxseats
self.hands['boardcard1'] = None
self.hands['boardcard2'] = None
self.hands['boardcard3'] = None
self.hands['boardcard4'] = None
self.hands['boardcard5'] = None
boardCard = 1
for street in hand.communityStreets:
for card in hand.board[street]:
self.hands['boardcard%s' % str(boardCard)] = Card.encodeCard(card)
boardCard += 1
def assembleHandsPlayers(self, hand):
self.vpip(self.hand)
for i, street in enumerate(hand.actionStreets[1:]):
self.aggr(self.hand, i)
def vpip(self, hand):
vpipers = set()
for act in hand.actions[hand.actionStreets[1]]:
if act[1] in ('calls','bets', 'raises'):
vpipers.add(act[0])
for player in hand.players:
if player[1] in vpipers:
self.handsplayers[player[1]]['vpip'] = True
else:
self.handsplayers[player[1]]['vpip'] = False
self.hands['playersVpi'] = len(vpipers)
def aggr(self, hand, i):
aggrers = set()
for act in hand.actions[hand.actionStreets[i]]:
if act[1] in ('completes', 'raises'):
aggrers.add(act[0])
for player in hand.players:
if player[1] in aggrers:
self.handsplayers[player[1]]['street%sAggr' % i] = True
else:
self.handsplayers[player[1]]['street%sAggr' % i] = False
def countPlayers(self, hand):
pass

View File

@ -74,7 +74,7 @@ class GuiBulkImport():
cb_hmodel = self.cb_drophudcache.get_model()
cb_hindex = self.cb_drophudcache.get_active()
self.lab_info.set_text("Importing")
self.lab_info.set_text("Importing") # doesn't display :-(
if cb_index:
self.importer.setDropIndexes(cb_model[cb_index][0])
else:
@ -95,6 +95,13 @@ class GuiBulkImport():
print 'GuiBulkImport.load done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %.0f/sec'\
% (stored, dups, partial, errs, ttime, (stored+0.0) / ttime)
self.importer.clearFileList()
if self.n_hands_in_db == 0 and stored > 0:
self.cb_dropindexes.set_sensitive(True)
self.cb_dropindexes.set_active(0)
self.lab_drop.set_sensitive(True)
self.cb_drophudcache.set_sensitive(True)
self.cb_drophudcache.set_active(0)
self.lab_hdrop.set_sensitive(True)
self.lab_info.set_text("Import finished")
except:
@ -213,11 +220,11 @@ class GuiBulkImport():
self.cbfilter.show()
# label - drop hudcache
self.lab_drop = gtk.Label("Drop HudCache:")
self.table.attach(self.lab_drop, 3, 4, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_drop.show()
self.lab_drop.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_drop.set_alignment(1.0, 0.5)
self.lab_hdrop = gtk.Label("Drop HudCache:")
self.table.attach(self.lab_hdrop, 3, 4, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_hdrop.show()
self.lab_hdrop.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_hdrop.set_alignment(1.0, 0.5)
# ComboBox - drop hudcache
self.cb_drophudcache = gtk.combo_box_new_text()
@ -258,7 +265,7 @@ class GuiBulkImport():
self.lab_drop.set_sensitive(False)
self.cb_drophudcache.set_active(2)
self.cb_drophudcache.set_sensitive(False)
self.lab_drop.set_sensitive(False)
self.lab_hdrop.set_sensitive(False)
def main(argv=None):
"""main can also be called in the python interpreter, by supplying the command line as the argument."""

View File

@ -203,6 +203,51 @@
<location seat="9" x="70" y="53"> </location>
</layout>
</site>
<site enabled="False"
site_name="Absolute"
table_finder="AbsolutePoker.exe"
screen_name="YOUR SCREEN NAME HERE"
site_path=""
HH_path=""
decoder="everleaf_decode_table"
converter="AbsoluteToFpdb"
supported_games="holdem">
<layout fav_seat="0" height="547" max="8" width="794">
<location seat="1" x="640" y="64"> </location>
<location seat="2" x="650" y="230"> </location>
<location seat="3" x="650" y="385"> </location>
<location seat="4" x="588" y="425"> </location>
<location seat="5" x="92" y="425"> </location>
<location seat="6" x="0" y="373"> </location>
<location seat="7" x="0" y="223"> </location>
<location seat="8" x="25" y="50"> </location>
</layout>
<layout fav_seat="0" height="547" max="6" width="794">
<location seat="1" x="640" y="58"> </location>
<location seat="2" x="654" y="288"> </location>
<location seat="3" x="615" y="424"> </location>
<location seat="4" x="70" y="421"> </location>
<location seat="5" x="0" y="280"> </location>
<location seat="6" x="70" y="58"> </location>
</layout>
<layout fav_seat="0" height="547" max="2" width="794">
<location seat="1" x="651" y="288"> </location>
<location seat="2" x="10" y="288"> </location>
</layout>
<layout fav_seat="0" height="547" max="9" width="794">
<location seat="1" x="634" y="38"> </location>
<location seat="2" x="667" y="184"> </location>
<location seat="3" x="667" y="321"> </location>
<location seat="4" x="667" y="445"> </location>
<location seat="5" x="337" y="459"> </location>
<location seat="6" x="0" y="400"> </location>
<location seat="7" x="0" y="322"> </location>
<location seat="8" x="0" y="181"> </location>
<location seat="9" x="70" y="53"> </location>
</layout>
</site>
</supported_sites>
<supported_games>
@ -337,6 +382,7 @@
<hhc site="Full Tilt Poker" converter="FulltiltToFpdb"/>
<hhc site="Everleaf" converter="EverleafToFpdb"/>
<hhc site="Win2day" converter="Win2dayToFpdb"/>
<hhc site="Absolute" converter="AbsoluteToFpdb"/>
</hhcs>
<supported_databases>

View File

@ -204,7 +204,9 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
logging.info("Unsupported game type: %s" % gametype)
if hand:
# uncomment these to calculate some stats
# print hand
# hand.stats.getStats(hand)
hand.writeHand(self.out_fh)
return hand
else:

File diff suppressed because it is too large Load Diff

View File

@ -155,7 +155,7 @@ class fpdb_db:
return (self.host, self.database, self.user, self.password)
#end def get_db_info
def getLastInsertId(self):
def getLastInsertId(self, cursor=None):
try:
if self.backend == self.MYSQL_INNODB:
ret = self.db.insert_id()
@ -177,9 +177,7 @@ class fpdb_db:
else:
ret = row[0]
elif self.backend == fpdb_db.SQLITE:
# don't know how to do this in sqlite
print "getLastInsertId(): not coded for sqlite yet"
ret = -1
ret = cursor.lastrowid
else:
print "getLastInsertId(): unknown backend ", self.backend
ret = -1

View File

@ -48,37 +48,6 @@ class FpdbError(Exception):
self.value = value
def __str__(self):
return repr(self.value)
# gets value for last auto-increment key generated
# returns -1 if a problem occurs
def getLastInsertId(backend, conn, cursor):
if backend == MYSQL_INNODB:
ret = conn.insert_id()
if ret < 1 or ret > 999999999:
print "getLastInsertId(): problem fetching insert_id? ret=", ret
ret = -1
elif backend == PGSQL:
# some options:
# currval(hands_id_seq) - use name of implicit seq here
# lastval() - still needs sequences set up?
# insert ... returning is useful syntax (but postgres specific?)
# see rules (fancy trigger type things)
cursor.execute ("SELECT lastval()")
row = cursor.fetchone()
if not row:
print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row
ret = -1
else:
ret = row[0]
elif backend == SQLITE:
# don't know how to do this in sqlite
print "getLastInsertId(): not coded for sqlite yet"
ret = -1
else:
print "getLastInsertId(): unknown backend ", backend
ret = -1
return ret
#end def getLastInsertId
#returns an array of the total money paid. intending to add rebuys/addons here
def calcPayin(count, buyin, fee):

42
utils/fix_table_desc.py Normal file
View File

@ -0,0 +1,42 @@
#!/usr/bin/python
import re
desc = """
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| tourneyId | int(10) unsigned | NO | MUL | NULL | |
| playerId | int(10) unsigned | NO | MUL | NULL | |
| payinAmount | int(11) | NO | | NULL | |
| rank | int(11) | NO | | NULL | |
| winnings | int(11) | NO | | NULL | |
| comment | text | YES | | NULL | |
| commentTs | datetime | YES | | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
"""
table = """
{| border="1"
|+Gametypes Table
"""
# get rid of the verticle spacing and clean up
desc = re.sub("[\+\-]+", "", desc)
desc = re.sub("^\n+", "", desc) # there's probably a better way
desc = re.sub("\n\n", "\n", desc)
# the first line is the header info
temp, desc = re.split("\n", desc, 1)
temp = re.sub("\|", "!", temp)
temp = re.sub(" !", " !!", temp)
table += temp + " Comments\n"
# the rest is he body of the table
for line in re.split("\n", desc):
line = re.sub(" \|", " ||", line)
table += "|+\n" + line + "\n"
table += "|}\n"
print table