merge from Eric
This commit is contained in:
commit
518fd9e039
5
packaging/debian/changelog
Normal file
5
packaging/debian/changelog
Normal file
|
@ -0,0 +1,5 @@
|
|||
free-poker-tools (0.10.99) unstable; urgency=low
|
||||
|
||||
* Initial packaging release.
|
||||
|
||||
-- Mika Bostrom <bostik+fpdb@bostik.iki.fi> Thu, 20 Aug 2009 06:30:53 +0300
|
1
packaging/debian/compat
Normal file
1
packaging/debian/compat
Normal file
|
@ -0,0 +1 @@
|
|||
7
|
24
packaging/debian/control
Normal file
24
packaging/debian/control
Normal file
|
@ -0,0 +1,24 @@
|
|||
Source: free-poker-tools
|
||||
Maintainer: Mika Bostrom <bostik+fpdb@bostik.iki.fi>
|
||||
Section: games
|
||||
Priority: extra
|
||||
Build-Depends: debhelper, python-support
|
||||
Standards-Version: 3.8.0
|
||||
|
||||
Package: python-fpdb
|
||||
Architecture: any
|
||||
Section: games
|
||||
Priority: extra
|
||||
Depends: ${python:Depends}, python-gtk2, python-matplotlib,
|
||||
python-support, mysql-server | postgresql | python-pysqlite2,
|
||||
python-psycopg2 | python-mysqldb
|
||||
Suggests: wine
|
||||
Description: free poker database with HUD
|
||||
FPDB is a statistics tool for online poker. It supports most sites
|
||||
and several games. Most prominent feature is its heads-up display
|
||||
(HUD) which shows statistical details for players in real time.
|
||||
.
|
||||
Due to the fact that most online poker clients are Windows-only,
|
||||
you may need to install wine.
|
||||
.
|
||||
FPDB is under heavy development.
|
7
packaging/debian/copyright
Normal file
7
packaging/debian/copyright
Normal file
|
@ -0,0 +1,7 @@
|
|||
This package was debianised by Mika Bostrom <bostik+fpdb@bostik.iki.fi>
|
||||
|
||||
Upstream authors: ...
|
||||
|
||||
License: AGPL
|
||||
|
||||
Copyright (C) 2008- The FPDB developers
|
1
packaging/debian/links
Normal file
1
packaging/debian/links
Normal file
|
@ -0,0 +1 @@
|
|||
/usr/share/python-support/python-fpdb/fpdb/fpdb.py /usr/bin/fpdb
|
5
packaging/debian/python-fpdb.postinst
Normal file
5
packaging/debian/python-fpdb.postinst
Normal file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
# When installed into .../fpdb/ the script gets mode 644
|
||||
# Note: "dh_fixperms -Xfpdb.py" did not work, hence this hack
|
||||
chmod 755 /usr/bin/fpdb
|
1
packaging/debian/pyversions
Normal file
1
packaging/debian/pyversions
Normal file
|
@ -0,0 +1 @@
|
|||
2.4-
|
45
packaging/debian/rules
Executable file
45
packaging/debian/rules
Executable file
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
|
||||
PACKAGE := python-fpdb
|
||||
|
||||
build: build-stamp
|
||||
build-stamp:
|
||||
dh_testdir
|
||||
python setup.py build
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
python setup.py clean
|
||||
rm -rf build
|
||||
dh_clean build-stamp
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep || dh_clean -k
|
||||
dh_installdirs
|
||||
#
|
||||
python setup.py install --root=debian/$(PACKAGE) --prefix=/usr --no-compile
|
||||
|
||||
binary-indep: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installchangelogs
|
||||
dh_installdocs
|
||||
dh_link
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
dh_pysupport
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary-arch: build install
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
||||
|
|
@ -24,6 +24,7 @@ Handles HUD configuration files.
|
|||
########################################################################
|
||||
|
||||
# Standard Library modules
|
||||
from __future__ import with_statement
|
||||
import os
|
||||
import sys
|
||||
import inspect
|
||||
|
@ -316,8 +317,8 @@ class Config:
|
|||
|
||||
# Parse even if there was no real config file found and we are using the example
|
||||
# If using the example, we'll edit it later
|
||||
log.info("Reading configuration file %s" % file)
|
||||
try:
|
||||
log.info("Reading configuration file %s" % (file))
|
||||
doc = xml.dom.minidom.parse(file)
|
||||
except:
|
||||
log.error("Error parsing %s. See error log file." % (file))
|
||||
|
@ -353,20 +354,22 @@ class Config:
|
|||
for db_node in doc.getElementsByTagName("database"):
|
||||
try:
|
||||
db = Database(node = db_node)
|
||||
except:
|
||||
raise FpdbError("Unable to create database object")
|
||||
else:
|
||||
if db.db_name in self.supported_databases:
|
||||
raise FpdbError("Database names must be unique")
|
||||
# If there is only one Database node, or none are marked default, the first is selected
|
||||
if len(self.supported_databases) == 0:
|
||||
# If there is only one Database node, or none are marked
|
||||
# default, use first
|
||||
if not self.supported_databases:
|
||||
self.db_selected = db.db_name
|
||||
self.supported_databases[db.db_name] = db
|
||||
if db.db_selected:
|
||||
self.db_selected = db.db_name
|
||||
except:
|
||||
raise
|
||||
|
||||
if dbname and dbname in self.supported_databases:
|
||||
self.db_selected = dbname
|
||||
|
||||
|
||||
# s_dbs = doc.getElementsByTagName("mucked_windows")
|
||||
for aw_node in doc.getElementsByTagName("aw"):
|
||||
aw = Aux_window(node = aw_node)
|
||||
|
@ -442,12 +445,11 @@ class Config:
|
|||
|
||||
def read_default_conf(self, file):
|
||||
parms = {}
|
||||
fh = open(file, "r")
|
||||
for line in fh:
|
||||
line = string.strip(line)
|
||||
(key, value) = line.split('=')
|
||||
parms[key] = value
|
||||
fh.close
|
||||
with open(file, "r") as fh:
|
||||
for line in fh:
|
||||
line = string.strip(line)
|
||||
(key, value) = line.split('=')
|
||||
parms[key] = value
|
||||
return parms
|
||||
|
||||
def find_example_config(self):
|
||||
|
@ -496,14 +498,12 @@ class Config:
|
|||
|
||||
def save(self, file = None):
|
||||
if file != None:
|
||||
f = open(file, 'w')
|
||||
self.doc.writexml(f)
|
||||
f.close()
|
||||
with open(file, 'w') as f:
|
||||
self.doc.writexml(f)
|
||||
else:
|
||||
shutil.move(self.file, self.file+".backup")
|
||||
f = open(self.file, 'w')
|
||||
self.doc.writexml(f)
|
||||
f.close
|
||||
with open(self.file, 'w') as f:
|
||||
self.doc.writexml(f)
|
||||
|
||||
def edit_layout(self, site_name, max, width = None, height = None,
|
||||
fav_seat = None, locations = None):
|
||||
|
@ -535,6 +535,7 @@ class Config:
|
|||
def get_db_parameters(self):
|
||||
db = {}
|
||||
name = self.db_selected
|
||||
# TODO: What's up with all the exception handling here?!
|
||||
try: db['db-databaseName'] = name
|
||||
except: pass
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ class Database:
|
|||
# create index indexname on tablename (col);
|
||||
|
||||
|
||||
def __init__(self, c, db_name = None, game = None, sql = None): # db_name and game not used any more
|
||||
def __init__(self, c, sql = None):
|
||||
log.info("Creating Database instance, sql = %s" % sql)
|
||||
self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||
self.fdb.do_connect(c)
|
||||
|
@ -201,7 +201,7 @@ class Database:
|
|||
|
||||
|
||||
# where possible avoid creating new SQL instance by using the global one passed in
|
||||
if sql == None:
|
||||
if sql is None:
|
||||
self.sql = SQL.Sql(type = self.type, db_server = db_params['db-server'])
|
||||
else:
|
||||
self.sql = sql
|
||||
|
@ -370,23 +370,20 @@ class Database:
|
|||
def init_hud_stat_vars(self, hud_days):
|
||||
"""Initialise variables used by Hud to fetch stats."""
|
||||
|
||||
self.hand_1day_ago = 1
|
||||
try:
|
||||
# self.hand_1day_ago used to fetch stats for current session (i.e. if hud_style = 'S')
|
||||
self.hand_1day_ago = 1
|
||||
c = self.get_cursor()
|
||||
c.execute(self.sql.query['get_hand_1day_ago'])
|
||||
row = c.fetchone()
|
||||
except: # TODO: what error is a database error?!
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||
else:
|
||||
if row and row[0]:
|
||||
self.hand_1day_ago = row[0]
|
||||
#print "hand 1day ago =", self.hand_1day_ago
|
||||
|
||||
# self.date_ndays_ago used if hud_style = 'T'
|
||||
self.hand_1_day_ago = row[0]
|
||||
d = timedelta(days=hud_days)
|
||||
now = datetime.utcnow() - d
|
||||
self.date_ndays_ago = "d%02d%02d%02d" % (now.year-2000, now.month, now.day)
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
self.date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day)
|
||||
|
||||
def init_player_hud_stat_vars(self, playerid):
|
||||
# not sure if this is workable, to be continued ...
|
||||
|
@ -1092,6 +1089,8 @@ class Database:
|
|||
c.execute("INSERT INTO Sites (name,currency) VALUES ('PartyPoker', 'USD')")
|
||||
if self.backend == self.SQLITE:
|
||||
c.execute("INSERT INTO TourneyTypes (id, siteId, buyin, fee) VALUES (NULL, 1, 0, 0);")
|
||||
elif self.backend == self.PGSQL:
|
||||
c.execute("insert into TourneyTypes values (0,1,0,0,0,False,False,null,False,False,False);")
|
||||
else:
|
||||
c.execute("""insert into TourneyTypes(id, siteId, buyin, fee, maxSeats, knockout
|
||||
,rebuyOrAddon, speed, headsUp, shootout, matrix)
|
||||
|
@ -1263,6 +1262,10 @@ class Database:
|
|||
return result
|
||||
#end def store_the_hand
|
||||
|
||||
###########################
|
||||
# NEWIMPORT CODE
|
||||
###########################
|
||||
|
||||
def storeHand(self, p):
|
||||
#stores into table hands:
|
||||
q = """INSERT INTO Hands (
|
||||
|
@ -1338,6 +1341,109 @@ class Database:
|
|||
#return getLastInsertId(backend, conn, cursor)
|
||||
# def storeHand
|
||||
|
||||
def storeHandsPlayers(self, p):
|
||||
#def store_hands_players_holdem_omaha(self, backend, category, hands_id, player_ids, start_cashes
|
||||
# ,positions, card_values, card_suits, winnings, rakes, seatNos, hudCache):
|
||||
# result=[]
|
||||
#
|
||||
# # postgres (and others?) needs the booleans converted to ints before saving:
|
||||
# # (or we could just save them as boolean ... but then we can't sum them so easily in sql ???)
|
||||
# # NO - storing booleans for now so don't need this
|
||||
# #hudCacheInt = {}
|
||||
# #for k,v in hudCache.iteritems():
|
||||
# # if k in ('wonWhenSeenStreet1', 'wonAtSD', 'totalProfit'):
|
||||
# # hudCacheInt[k] = v
|
||||
# # else:
|
||||
# # hudCacheInt[k] = map(lambda x: 1 if x else 0, v)
|
||||
#
|
||||
# try:
|
||||
# inserts = []
|
||||
# for i in xrange(len(player_ids)):
|
||||
# card1 = Card.cardFromValueSuit(card_values[i][0], card_suits[i][0])
|
||||
# card2 = Card.cardFromValueSuit(card_values[i][1], card_suits[i][1])
|
||||
#
|
||||
# if (category=="holdem"):
|
||||
# startCards = Card.twoStartCards(card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1])
|
||||
# card3 = None
|
||||
# card4 = None
|
||||
# elif (category=="omahahi" or category=="omahahilo"):
|
||||
# startCards = Card.fourStartCards(card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1]
|
||||
# ,card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3])
|
||||
# card3 = Card.cardFromValueSuit(card_values[i][2], card_suits[i][2])
|
||||
# card4 = Card.cardFromValueSuit(card_values[i][3], card_suits[i][3])
|
||||
# else:
|
||||
# raise FpdbError("invalid category")
|
||||
#
|
||||
# inserts.append( (
|
||||
# hands_id, player_ids[i], start_cashes[i], positions[i], 1, # tourneytypeid - needed for hudcache
|
||||
# card1, card2, card3, card4, startCards,
|
||||
# winnings[i], rakes[i], seatNos[i], hudCache['totalProfit'][i],
|
||||
# hudCache['street0VPI'][i], hudCache['street0Aggr'][i],
|
||||
# hudCache['street0_3BChance'][i], hudCache['street0_3BDone'][i],
|
||||
# hudCache['street1Seen'][i], hudCache['street2Seen'][i], hudCache['street3Seen'][i],
|
||||
# hudCache['street4Seen'][i], hudCache['sawShowdown'][i],
|
||||
# hudCache['street1Aggr'][i], hudCache['street2Aggr'][i], hudCache['street3Aggr'][i], hudCache['street4Aggr'][i],
|
||||
# hudCache['otherRaisedStreet1'][i], hudCache['otherRaisedStreet2'][i],
|
||||
# hudCache['otherRaisedStreet3'][i], hudCache['otherRaisedStreet4'][i],
|
||||
# hudCache['foldToOtherRaisedStreet1'][i], hudCache['foldToOtherRaisedStreet2'][i],
|
||||
# hudCache['foldToOtherRaisedStreet3'][i], hudCache['foldToOtherRaisedStreet4'][i],
|
||||
# hudCache['wonWhenSeenStreet1'][i], hudCache['wonAtSD'][i],
|
||||
# hudCache['stealAttemptChance'][i], hudCache['stealAttempted'][i], hudCache['foldBbToStealChance'][i],
|
||||
# hudCache['foldedBbToSteal'][i], hudCache['foldSbToStealChance'][i], hudCache['foldedSbToSteal'][i],
|
||||
# hudCache['street1CBChance'][i], hudCache['street1CBDone'][i], hudCache['street2CBChance'][i], hudCache['street2CBDone'][i],
|
||||
# hudCache['street3CBChance'][i], hudCache['street3CBDone'][i], hudCache['street4CBChance'][i], hudCache['street4CBDone'][i],
|
||||
# hudCache['foldToStreet1CBChance'][i], hudCache['foldToStreet1CBDone'][i],
|
||||
# hudCache['foldToStreet2CBChance'][i], hudCache['foldToStreet2CBDone'][i],
|
||||
# hudCache['foldToStreet3CBChance'][i], hudCache['foldToStreet3CBDone'][i],
|
||||
# hudCache['foldToStreet4CBChance'][i], hudCache['foldToStreet4CBDone'][i],
|
||||
# hudCache['street1CheckCallRaiseChance'][i], hudCache['street1CheckCallRaiseDone'][i],
|
||||
# hudCache['street2CheckCallRaiseChance'][i], hudCache['street2CheckCallRaiseDone'][i],
|
||||
# hudCache['street3CheckCallRaiseChance'][i], hudCache['street3CheckCallRaiseDone'][i],
|
||||
# hudCache['street4CheckCallRaiseChance'][i], hudCache['street4CheckCallRaiseDone'][i],
|
||||
# hudCache['street0Calls'][i], hudCache['street1Calls'][i], hudCache['street2Calls'][i], hudCache['street3Calls'][i], hudCache['street4Calls'][i],
|
||||
# hudCache['street0Bets'][i], hudCache['street1Bets'][i], hudCache['street2Bets'][i], hudCache['street3Bets'][i], hudCache['street4Bets'][i]
|
||||
# ) )
|
||||
# c = self.get_cursor()
|
||||
# c.executemany ("""
|
||||
# INSERT INTO HandsPlayers
|
||||
# (handId, playerId, startCash, position, tourneyTypeId,
|
||||
# card1, card2, card3, card4, startCards, winnings, rake, seatNo, totalProfit,
|
||||
# street0VPI, street0Aggr, street0_3BChance, street0_3BDone,
|
||||
# street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown,
|
||||
# street1Aggr, street2Aggr, street3Aggr, street4Aggr,
|
||||
# otherRaisedStreet1, otherRaisedStreet2, otherRaisedStreet3, otherRaisedStreet4,
|
||||
# foldToOtherRaisedStreet1, foldToOtherRaisedStreet2, foldToOtherRaisedStreet3, foldToOtherRaisedStreet4,
|
||||
# wonWhenSeenStreet1, wonAtSD,
|
||||
# stealAttemptChance, stealAttempted, foldBbToStealChance, foldedBbToSteal, foldSbToStealChance, foldedSbToSteal,
|
||||
# street1CBChance, street1CBDone, street2CBChance, street2CBDone,
|
||||
# street3CBChance, street3CBDone, street4CBChance, street4CBDone,
|
||||
# foldToStreet1CBChance, foldToStreet1CBDone, foldToStreet2CBChance, foldToStreet2CBDone,
|
||||
# foldToStreet3CBChance, foldToStreet3CBDone, foldToStreet4CBChance, foldToStreet4CBDone,
|
||||
# street1CheckCallRaiseChance, street1CheckCallRaiseDone, street2CheckCallRaiseChance, street2CheckCallRaiseDone,
|
||||
# street3CheckCallRaiseChance, street3CheckCallRaiseDone, street4CheckCallRaiseChance, street4CheckCallRaiseDone,
|
||||
# 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, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
|
||||
# %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder'])
|
||||
# ,inserts )
|
||||
# result.append( self.get_last_insert_id(c) ) # wrong? not used currently
|
||||
# except:
|
||||
# raise FpdbError( "store_hands_players_holdem_omaha error: " + str(sys.exc_value) )
|
||||
#
|
||||
# return result
|
||||
|
||||
pass
|
||||
|
||||
|
||||
#################################
|
||||
# Finish of NEWIMPORT CODE
|
||||
#################################
|
||||
|
||||
|
||||
|
||||
def storeHands(self, backend, site_hand_no, gametype_id
|
||||
,hand_start_time, names, tableName, maxSeats, hudCache
|
||||
,board_values, board_suits):
|
||||
|
|
4
pyfpdb/FulltiltToFpdb.py
Executable file → Normal file
4
pyfpdb/FulltiltToFpdb.py
Executable file → Normal file
|
@ -656,7 +656,9 @@ class Fulltilt(HandHistoryConverter):
|
|||
heroName = n.group('HERO_NAME')
|
||||
tourney.hero = heroName
|
||||
# Is this really useful ?
|
||||
if (tourney.finishPositions[heroName] != Decimal(n.group('HERO_FINISHING_POS'))):
|
||||
if heroName not in tourney.finishPositions:
|
||||
print heroName, "not found in tourney.finishPositions ..."
|
||||
elif (tourney.finishPositions[heroName] != Decimal(n.group('HERO_FINISHING_POS'))):
|
||||
print "Bad parsing : finish position incoherent : %s / %s" % (tourney.finishPositions[heroName], n.group('HERO_FINISHING_POS'))
|
||||
|
||||
return True
|
||||
|
|
|
@ -60,6 +60,11 @@ class GuiBulkImport():
|
|||
return True
|
||||
|
||||
def load_clicked(self, widget, data=None):
|
||||
stored = None
|
||||
dups = None
|
||||
partial = None
|
||||
errs = None
|
||||
ttime = None
|
||||
# Does the lock acquisition need to be more sophisticated for multiple dirs?
|
||||
# (see comment above about what to do if pipe already open)
|
||||
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
||||
|
@ -101,13 +106,13 @@ class GuiBulkImport():
|
|||
self.importer.addBulkImportImportFileOrDir(self.inputFile, site = sitename)
|
||||
self.importer.setCallHud(False)
|
||||
starttime = time()
|
||||
try:
|
||||
(stored, dups, partial, errs, ttime) = self.importer.runImport()
|
||||
except:
|
||||
print "*** EXCEPTION DURING BULKIMPORT!!!"
|
||||
raise Exceptions.FpdbError
|
||||
finally:
|
||||
gobject.source_remove(self.timer)
|
||||
# try:
|
||||
(stored, dups, partial, errs, ttime) = self.importer.runImport()
|
||||
# except:
|
||||
# print "*** EXCEPTION DURING BULKIMPORT!!!"
|
||||
# raise Exceptions.FpdbError
|
||||
# finally:
|
||||
gobject.source_remove(self.timer)
|
||||
|
||||
ttime = time() - starttime
|
||||
if ttime == 0:
|
||||
|
|
|
@ -32,7 +32,7 @@ try:
|
|||
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
|
||||
from numpy import arange, cumsum
|
||||
from pylab import *
|
||||
except:
|
||||
except ImportError:
|
||||
print """Failed to load libs for graphing, graphing will not function. Please in
|
||||
stall numpy and matplotlib if you want to use graphs."""
|
||||
print """This is of no consequence for other parts of the program, e.g. import
|
||||
|
|
|
@ -339,11 +339,16 @@ class Hud:
|
|||
self.update_table_position()
|
||||
|
||||
for s in self.stat_dict:
|
||||
statd = self.stat_dict[s]
|
||||
try:
|
||||
statd = self.stat_dict[s]
|
||||
except KeyError:
|
||||
print "KeyError at the start of the for loop in update in hud_main. How this can possibly happen is totally beyond my comprehension. Your HUD may be about to get really weird. -Eric"
|
||||
print "(btw, the key was ", s, " and statd is...", statd
|
||||
continue
|
||||
try:
|
||||
self.stat_windows[statd['seat']].player_id = statd['player_id']
|
||||
#self.stat_windows[self.stat_dict[s]['seat']].player_id = self.stat_dict[s]['player_id']
|
||||
except: # omg, we have more seats than stat windows .. damn poker sites with incorrect max seating info .. let's force 10 here
|
||||
except KeyError: # omg, we have more seats than stat windows .. damn poker sites with incorrect max seating info .. let's force 10 here
|
||||
self.max = 10
|
||||
self.create(hand, config, self.stat_dict, self.cards)
|
||||
self.stat_windows[statd['seat']].player_id = statd['player_id']
|
||||
|
@ -379,6 +384,7 @@ class Stat_Window:
|
|||
# This handles all callbacks from button presses on the event boxes in
|
||||
# the stat windows. There is a bit of an ugly kludge to separate single-
|
||||
# and double-clicks.
|
||||
self.window.show_all()
|
||||
|
||||
if event.button == 3: # right button event
|
||||
newpopup = Popup_window(self.window, self)
|
||||
|
@ -393,7 +399,6 @@ class Stat_Window:
|
|||
|
||||
if event.button == 1: # left button event
|
||||
# TODO: make position saving save sizes as well?
|
||||
self.window.show_all()
|
||||
if event.state & gtk.gdk.SHIFT_MASK:
|
||||
self.window.begin_resize_drag(gtk.gdk.WINDOW_EDGE_SOUTH_EAST, event.button, int(event.x_root), int(event.y_root), event.time)
|
||||
else:
|
||||
|
|
|
@ -21,19 +21,18 @@ import re
|
|||
import sys
|
||||
import logging
|
||||
from time import time, strftime
|
||||
from Exceptions import *
|
||||
|
||||
use_pool = False
|
||||
try:
|
||||
import sqlalchemy.pool as pool
|
||||
use_pool = True
|
||||
except:
|
||||
except ImportError:
|
||||
logging.info("Not using sqlalchemy connection pool.")
|
||||
use_pool = False
|
||||
|
||||
|
||||
import fpdb_simple
|
||||
import FpdbSQLQueries
|
||||
from Exceptions import *
|
||||
|
||||
|
||||
class fpdb_db:
|
||||
MYSQL_INNODB = 2
|
||||
|
@ -69,12 +68,12 @@ class fpdb_db:
|
|||
"""Connects a database with the given parameters"""
|
||||
if backend is None:
|
||||
raise FpdbError('Database backend not defined')
|
||||
self.backend=backend
|
||||
self.host=host
|
||||
self.user=user
|
||||
self.password=password
|
||||
self.database=database
|
||||
if backend==fpdb_db.MYSQL_INNODB:
|
||||
self.backend = backend
|
||||
self.host = host
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.database = database
|
||||
if backend == fpdb_db.MYSQL_INNODB:
|
||||
import MySQLdb
|
||||
if use_pool:
|
||||
MySQLdb = pool.manage(MySQLdb, pool_size=5)
|
||||
|
@ -115,7 +114,7 @@ class fpdb_db:
|
|||
msg = "PostgreSQL connection to database (%s) user (%s) failed." % (database, user)
|
||||
print msg
|
||||
raise FpdbError(msg)
|
||||
elif backend==fpdb_db.SQLITE:
|
||||
elif backend == fpdb_db.SQLITE:
|
||||
logging.info("Connecting to SQLite:%(database)s" % {'database':database})
|
||||
import sqlite3
|
||||
if use_pool:
|
||||
|
@ -132,20 +131,20 @@ class fpdb_db:
|
|||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||
else:
|
||||
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.
|
||||
self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name())
|
||||
self.cursor.execute(self.sql.query['set tx level'])
|
||||
self.wrongDbVersion=False
|
||||
self.wrongDbVersion = False
|
||||
try:
|
||||
self.cursor.execute("SELECT * FROM Settings")
|
||||
settings=self.cursor.fetchone()
|
||||
if settings[0]!=118:
|
||||
settings = self.cursor.fetchone()
|
||||
if settings[0] != 118:
|
||||
print "outdated or too new database version - please recreate tables"
|
||||
self.wrongDbVersion=True
|
||||
self.wrongDbVersion = True
|
||||
except:# _mysql_exceptions.ProgrammingError:
|
||||
if database != ":memory:": print "failed to read settings table - please recreate tables"
|
||||
self.wrongDbVersion=True
|
||||
self.wrongDbVersion = True
|
||||
#end def connect
|
||||
|
||||
def disconnect(self, due_to_error=False):
|
||||
|
|
|
@ -49,22 +49,20 @@ log = logging.getLogger('importer')
|
|||
# database interface modules
|
||||
try:
|
||||
import MySQLdb
|
||||
mysqlLibFound=True
|
||||
log.debug("Import module: MySQLdb")
|
||||
except:
|
||||
log.debug("Import module: MySQLdb not found")
|
||||
except ImportError:
|
||||
log.debug("Import database module: MySQLdb not found")
|
||||
else:
|
||||
mysqlLibFound = True
|
||||
|
||||
try:
|
||||
import psycopg2
|
||||
pgsqlLibFound=True
|
||||
except ImportError:
|
||||
log.debug("Import database module: psycopg2 not found")
|
||||
else:
|
||||
import psycopg2.extensions
|
||||
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
|
||||
log.debug("Import module: psycopg2")
|
||||
except:
|
||||
log.debug("Import module: psycopg2 not found")
|
||||
|
||||
class Importer:
|
||||
|
||||
def __init__(self, caller, settings, config, sql = None):
|
||||
"""Constructor"""
|
||||
self.settings = settings
|
||||
|
|
|
@ -18,46 +18,63 @@
|
|||
#parses an in-memory fpdb hand history and calls db routine to store it
|
||||
|
||||
import sys
|
||||
|
||||
import fpdb_simple
|
||||
import Database
|
||||
from time import time, strftime
|
||||
from Exceptions import *
|
||||
|
||||
import fpdb_simple
|
||||
import Database
|
||||
|
||||
#parses a holdem hand
|
||||
def mainParser(settings, siteID, category, hand, config, db = None, writeq = None):
|
||||
|
||||
""" mainParser for Holdem Hands """
|
||||
t0 = time()
|
||||
#print "mainparser"
|
||||
backend = settings['db-backend']
|
||||
# Ideally db connection is passed in, if not use sql list if passed in, otherwise start from scratch
|
||||
# Ideally db connection is passed in, if not use sql list if passed in,
|
||||
# otherwise start from scratch
|
||||
if db == None:
|
||||
db = Database.Database(c = config, sql = None)
|
||||
category = fpdb_simple.recogniseCategory(hand[0])
|
||||
|
||||
base = "hold" if category == "holdem" or category == "omahahi" or category == "omahahilo" else "stud"
|
||||
base = "hold" if (category == "holdem" or category == "omahahi" or
|
||||
category == "omahahilo") else "stud"
|
||||
|
||||
#part 0: create the empty arrays
|
||||
lineTypes = [] #char, valid values: header, name, cards, action, win, rake, ignore
|
||||
lineStreets = [] #char, valid values: (predeal, preflop, flop, turn, river)
|
||||
|
||||
cardValues, cardSuits, boardValues, boardSuits, antes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo, seatLines, winnings, rakes=[],[],[],[],[],[],[],[],[],[],[],[],[]
|
||||
# lineTypes valid values: header, name, cards, action, win, rake, ignore
|
||||
# lineStreets valid values: predeal, preflop, flop, turn, river
|
||||
lineTypes = []
|
||||
lineStreets = []
|
||||
cardValues = []
|
||||
cardSuits = []
|
||||
boardValues = []
|
||||
boardSuits = []
|
||||
antes = []
|
||||
allIns = []
|
||||
actionAmounts = []
|
||||
actionNos = []
|
||||
actionTypes = []
|
||||
actionTypeByNo = []
|
||||
seatLines = []
|
||||
winnings = []
|
||||
rakes = []
|
||||
|
||||
#part 1: read hand no and check for duplicate
|
||||
siteHandNo = fpdb_simple.parseSiteHandNo(hand[0])
|
||||
#print "siteHandNo =", siteHandNo
|
||||
handStartTime = fpdb_simple.parseHandStartTime(hand[0])
|
||||
|
||||
isTourney = fpdb_simple.isTourney(hand[0])
|
||||
smallBlindLine = 0
|
||||
|
||||
smallBlindLine = None
|
||||
for i, line in enumerate(hand):
|
||||
if 'posts small blind' in line or 'posts the small blind' in line:
|
||||
if line[-2:] == "$0": continue
|
||||
smallBlindLine = i
|
||||
break
|
||||
else:
|
||||
smallBlindLine = 0
|
||||
# If we did not find a small blind line, what happens?
|
||||
# if we leave it at None, it errors two lines down.
|
||||
|
||||
gametypeID = fpdb_simple.recogniseGametypeID(backend, db, db.get_cursor(), hand[0], hand[smallBlindLine], siteID, category, isTourney)
|
||||
gametypeID = fpdb_simple.recogniseGametypeID(backend, db, db.get_cursor(),
|
||||
hand[0], hand[smallBlindLine],
|
||||
siteID, category, isTourney)
|
||||
if isTourney:
|
||||
siteTourneyNo = fpdb_simple.parseTourneyNo(hand[0])
|
||||
buyin = fpdb_simple.parseBuyin(hand[0])
|
||||
|
@ -68,8 +85,14 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
|
|||
tourneyStartTime= handStartTime #todo: read tourney start time
|
||||
rebuyOrAddon = fpdb_simple.isRebuyOrAddon(hand[0])
|
||||
|
||||
## The tourney site id has to be searched because it may already be in db with a TourneyTypeId which is different from the one automatically calculated (Summary import first)
|
||||
tourneyTypeId = fpdb_simple.recogniseTourneyTypeId(db, siteID, siteTourneyNo, buyin, fee, knockout, rebuyOrAddon)
|
||||
# The tourney site id has to be searched because it may already be in
|
||||
# db with a TourneyTypeId which is different from the one automatically
|
||||
# calculated (Summary import first)
|
||||
tourneyTypeId = fpdb_simple.recogniseTourneyTypeId(db, siteID,
|
||||
siteTourneyNo,
|
||||
buyin, fee,
|
||||
knockout,
|
||||
rebuyOrAddon)
|
||||
else:
|
||||
siteTourneyNo = -1
|
||||
buyin = -1
|
||||
|
@ -100,7 +123,9 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
|
|||
startCashes = tmp['startCashes']
|
||||
seatNos = tmp['seatNos']
|
||||
|
||||
fpdb_simple.createArrays(category, len(names), cardValues, cardSuits, antes, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
|
||||
fpdb_simple.createArrays(category, len(names), cardValues, cardSuits, antes,
|
||||
winnings, rakes, actionTypes, allIns,
|
||||
actionAmounts, actionNos, actionTypeByNo)
|
||||
|
||||
#3b read positions
|
||||
if base == "hold":
|
||||
|
@ -109,26 +134,31 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
|
|||
#part 4: take appropriate action for each line based on linetype
|
||||
for i, line in enumerate(hand):
|
||||
if lineTypes[i] == "cards":
|
||||
fpdb_simple.parseCardLine(category, lineStreets[i], line, names, cardValues, cardSuits, boardValues, boardSuits)
|
||||
fpdb_simple.parseCardLine(category, lineStreets[i], line, names,
|
||||
cardValues, cardSuits, boardValues,
|
||||
boardSuits)
|
||||
#if category=="studhilo":
|
||||
# print "hand[i]:", hand[i]
|
||||
# print "cardValues:", cardValues
|
||||
# print "cardSuits:", cardSuits
|
||||
elif lineTypes[i] == "action":
|
||||
fpdb_simple.parseActionLine(base, isTourney, line, lineStreets[i], playerIDs, names, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
|
||||
fpdb_simple.parseActionLine(base, isTourney, line, lineStreets[i],
|
||||
playerIDs, names, actionTypes, allIns,
|
||||
actionAmounts, actionNos, actionTypeByNo)
|
||||
elif lineTypes[i] == "win":
|
||||
fpdb_simple.parseWinLine(line, names, winnings, isTourney)
|
||||
elif lineTypes[i] == "rake":
|
||||
totalRake = 0 if isTourney else fpdb_simple.parseRake(line)
|
||||
fpdb_simple.splitRake(winnings, rakes, totalRake)
|
||||
elif lineTypes[i]=="header" or lineTypes[i]=="rake" or lineTypes[i]=="name" or lineTypes[i]=="ignore":
|
||||
elif (lineTypes[i] == "header" or lineTypes[i] == "rake" or
|
||||
lineTypes[i] == "name" or lineTypes[i] == "ignore"):
|
||||
pass
|
||||
elif lineTypes[i]=="ante":
|
||||
elif lineTypes[i] == "ante":
|
||||
fpdb_simple.parseAnteLine(line, isTourney, names, antes)
|
||||
elif lineTypes[i]=="table":
|
||||
elif lineTypes[i] == "table":
|
||||
tableResult=fpdb_simple.parseTableLine(base, line)
|
||||
else:
|
||||
raise FpdbError("unrecognised lineType:"+lineTypes[i])
|
||||
raise FpdbError("unrecognised lineType:" + lineTypes[i])
|
||||
|
||||
maxSeats = tableResult['maxSeats']
|
||||
tableName = tableResult['tableName']
|
||||
|
@ -152,26 +182,34 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non
|
|||
# if hold'em, use positions and not antes, if stud do not use positions, use antes
|
||||
# this is used for handsplayers inserts, so still needed even if hudcache update is being skipped
|
||||
if base == "hold":
|
||||
hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
|
||||
, allIns, actionTypeByNo, winnings, totalWinnings, positions
|
||||
, actionTypes, actionAmounts, None)
|
||||
hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base,
|
||||
category, actionTypes,
|
||||
allIns, actionTypeByNo,
|
||||
winnings,
|
||||
totalWinnings,
|
||||
positions, actionTypes,
|
||||
actionAmounts, None)
|
||||
else:
|
||||
hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
|
||||
, allIns, actionTypeByNo, winnings, totalWinnings, None
|
||||
, actionTypes, actionAmounts, antes)
|
||||
hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base,
|
||||
category, actionTypes,
|
||||
allIns, actionTypeByNo,
|
||||
winnings,
|
||||
totalWinnings, None,
|
||||
actionTypes,
|
||||
actionAmounts, antes)
|
||||
|
||||
#print "parse: hand data prepared" # only reads up to here apart from inserting new players
|
||||
try:
|
||||
db.commit() # need to commit new players as different db connection used
|
||||
# for other writes. maybe this will change maybe not ...
|
||||
except:
|
||||
except: # TODO: this really needs to be narrowed down
|
||||
print "parse: error during commit: " + str(sys.exc_value)
|
||||
|
||||
# HERE's an ugly kludge to keep from failing when positions is undef
|
||||
# We'll fix this by getting rid of the legacy importer. REB
|
||||
try:
|
||||
if positions: pass
|
||||
except:
|
||||
if positions:
|
||||
pass
|
||||
except NameError:
|
||||
positions = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
# save data structures in a HandToWrite instance and then insert into database:
|
||||
htw = Database.HandToWrite()
|
||||
|
|
|
@ -53,8 +53,9 @@ def checkPositions(positions):
|
|||
### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB
|
||||
### eric - position 8 could be valid - if only one blind is posted, but there's still 10 people, ie a sitout is present, and the small is dead...
|
||||
|
||||
#classifies each line for further processing in later code. Manipulates the passed arrays.
|
||||
def classifyLines(hand, category, lineTypes, lineStreets):
|
||||
""" makes a list of classifications for each line for further processing
|
||||
manipulates passed arrays """
|
||||
currentStreet = "predeal"
|
||||
done = False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats)
|
||||
for i, line in enumerate(hand):
|
||||
|
@ -114,61 +115,59 @@ def classifyLines(hand, category, lineTypes, lineStreets):
|
|||
else:
|
||||
raise FpdbError("unrecognised linetype in:"+hand[i])
|
||||
lineStreets.append(currentStreet)
|
||||
#end def classifyLines
|
||||
|
||||
def convert3B4B(category, limit_type, actionTypes, actionAmounts):
|
||||
"""calculates the actual bet amounts in the given amount array and changes it accordingly."""
|
||||
for i in xrange(len(actionTypes)):
|
||||
for j in xrange(len(actionTypes[i])):
|
||||
bets=[]
|
||||
bets = []
|
||||
for k in xrange(len(actionTypes[i][j])):
|
||||
if (actionTypes[i][j][k]=="bet"):
|
||||
if (actionTypes[i][j][k] == "bet"):
|
||||
bets.append((i,j,k))
|
||||
if (len(bets)>=2):
|
||||
#print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets)
|
||||
for betNo in reversed(xrange (1,len(bets))):
|
||||
amount2=actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]]
|
||||
amount1=actionAmounts[bets[betNo-1][0]][bets[betNo-1][1]][bets[betNo-1][2]]
|
||||
actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]]=amount2-amount1
|
||||
#print "actionAmounts postConvert",actionAmounts
|
||||
#end def convert3B4B(actionTypes, actionAmounts)
|
||||
amount2 = actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]]
|
||||
amount1 = actionAmounts[bets[betNo-1][0]][bets[betNo-1][1]][bets[betNo-1][2]]
|
||||
actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]] = amount2 - amount1
|
||||
|
||||
#Corrects the bet amount if the player had to pay blinds
|
||||
def convertBlindBet(actionTypes, actionAmounts):
|
||||
i=0#setting street to pre-flop
|
||||
""" Corrects the bet amount if the player had to pay blinds """
|
||||
i = 0#setting street to pre-flop
|
||||
for j in xrange(len(actionTypes[i])):#playerloop
|
||||
blinds=[]
|
||||
bets=[]
|
||||
blinds = []
|
||||
bets = []
|
||||
for k in xrange(len(actionTypes[i][j])):
|
||||
if actionTypes[i][j][k] == "blind":
|
||||
blinds.append((i,j,k))
|
||||
|
||||
if blinds and actionTypes[i][j][k] == "bet":
|
||||
# if (len(blinds)>0 and actionTypes[i][j][k]=="bet"):
|
||||
bets.append((i,j,k))
|
||||
if len(bets) == 1:
|
||||
blind_amount=actionAmounts[blinds[0][0]][blinds[0][1]][blinds[0][2]]
|
||||
bet_amount=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
|
||||
actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]=bet_amount-blind_amount
|
||||
#end def convertBlindBet
|
||||
actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]] = bet_amount - blind_amount
|
||||
|
||||
#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
|
||||
#todo: make this use convertCardValuesBoard
|
||||
def convertCardValues(arr):
|
||||
map(convertCardValuesBoard, arr)
|
||||
#end def convertCardValues
|
||||
|
||||
# a 0-card is one in a stud game that we did not see or was not shown
|
||||
card_map = { 0: 0, "2": 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8, "9" : 9, "T" : 10, "J" : 11, "Q" : 12, "K" : 13, "A" : 14}
|
||||
card_map = { 0: 0, "2": 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8,
|
||||
"9" : 9, "T" : 10, "J" : 11, "Q" : 12, "K" : 13, "A" : 14}
|
||||
|
||||
#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
|
||||
def convertCardValuesBoard(arr):
|
||||
""" converts the strings in the given array to ints
|
||||
(changes the passed array, no returning). see table design for
|
||||
conversion details """
|
||||
for i in xrange(len(arr)):
|
||||
arr[i] = card_map[arr[i]]
|
||||
#end def convertCardValuesBoard
|
||||
|
||||
#this creates the 2D/3D arrays. manipulates the passed arrays instead of returning.
|
||||
def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
|
||||
def createArrays(category, seats, card_values, card_suits, antes, winnings,
|
||||
rakes, action_types, allIns, action_amounts, actionNos,
|
||||
actionTypeByNo):
|
||||
""" this creates the 2D/3D arrays. manipulates the passed arrays instead of returning. """
|
||||
for i in xrange(seats):#create second dimension arrays
|
||||
card_values.append( [] )
|
||||
card_suits.append( [] )
|
||||
|
@ -176,7 +175,8 @@ def createArrays(category, seats, card_values, card_suits, antes, winnings, rake
|
|||
winnings.append(0)
|
||||
rakes.append(0)
|
||||
|
||||
streetCount = 4 if category == "holdem" or category == "omahahi" or category == "omahahilo" else 5
|
||||
streetCount = 4 if (category == "holdem" or category == "omahahi" or
|
||||
category == "omahahilo") else 5
|
||||
|
||||
for i in xrange(streetCount): #build the first dimension array, for streets
|
||||
action_types.append([])
|
||||
|
@ -184,14 +184,14 @@ def createArrays(category, seats, card_values, card_suits, antes, winnings, rake
|
|||
action_amounts.append([])
|
||||
actionNos.append([])
|
||||
actionTypeByNo.append([])
|
||||
for j in xrange (seats): #second dimension arrays: players
|
||||
for j in xrange(seats): # second dimension arrays: players
|
||||
action_types[i].append([])
|
||||
allIns[i].append([])
|
||||
action_amounts[i].append([])
|
||||
actionNos[i].append([])
|
||||
# if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
|
||||
# pass
|
||||
if category=="razz" or category=="studhi" or category=="studhilo":#need to fill card arrays.
|
||||
if category == "razz" or category == "studhi" or category == "studhilo": #need to fill card arrays.
|
||||
for i in xrange(seats):
|
||||
for j in xrange(7):
|
||||
card_values[i].append(0)
|
||||
|
@ -201,25 +201,24 @@ def createArrays(category, seats, card_values, card_suits, antes, winnings, rake
|
|||
#end def createArrays
|
||||
|
||||
def fill_board_cards(board_values, board_suits):
|
||||
#fill up the two board card arrays
|
||||
while (len(board_values)<5):
|
||||
""" fill up the two board card arrays """
|
||||
while len(board_values) < 5:
|
||||
board_values.append(0)
|
||||
board_suits.append("x")
|
||||
#end def fill_board_cards
|
||||
|
||||
def fillCardArrays(player_count, base, category, card_values, card_suits):
|
||||
"""fills up the two card arrays"""
|
||||
if (category=="holdem"):
|
||||
if category == "holdem":
|
||||
cardCount = 2
|
||||
elif (category=="omahahi" or category=="omahahilo"):
|
||||
elif category == "omahahi" or category == "omahahilo":
|
||||
cardCount = 4
|
||||
elif base=="stud":
|
||||
elif base == "stud":
|
||||
cardCount = 7
|
||||
else:
|
||||
raise FpdbError("invalid category:", category)
|
||||
|
||||
for i in xrange(player_count):
|
||||
while (len(card_values[i]) < cardCount):
|
||||
while len(card_values[i]) < cardCount:
|
||||
card_values[i].append(0)
|
||||
card_suits[i].append("x")
|
||||
#end def fillCardArrays
|
||||
|
@ -230,12 +229,12 @@ def filterAnteBlindFold(hand):
|
|||
#todo: this'll only get rid of one ante folder, not multiple ones
|
||||
#todo: in tourneys this should not be removed but
|
||||
#print "start of filterAnteBlindFold"
|
||||
pre3rd=[]
|
||||
pre3rd = []
|
||||
for i, line in enumerate(hand):
|
||||
if line.startswith("*** 3") or line.startswith("*** HOLE"):
|
||||
pre3rd = hand[0:i]
|
||||
|
||||
foldeeName=None
|
||||
foldeeName = None
|
||||
for line in pre3rd:
|
||||
if line.endswith("folds") or line.endswith("is sitting out") or line.endswith(" stands up"): #found ante fold or timeout
|
||||
pos = line.find(" folds")
|
||||
|
@ -251,26 +250,25 @@ def filterAnteBlindFold(hand):
|
|||
pos2 = line.find(" (")
|
||||
foldeeName = line[pos1:pos2]
|
||||
|
||||
if foldeeName!=None:
|
||||
if foldeeName is not None:
|
||||
#print "filterAnteBlindFold, foldeeName:",foldeeName
|
||||
for i, line in enumerate(hand):
|
||||
if foldeeName in line:
|
||||
hand[i] = None
|
||||
|
||||
return [line for line in hand if line]
|
||||
#end def filterAnteFold
|
||||
|
||||
def stripEOLspaces(str):
|
||||
return str.rstrip()
|
||||
|
||||
#removes useless lines as well as trailing spaces
|
||||
def filterCrap(hand, isTourney):
|
||||
#remove two trailing spaces at end of line
|
||||
""" removes useless lines as well as trailing spaces """
|
||||
|
||||
#remove trailing spaces at end of line
|
||||
hand = [line.rstrip() for line in hand]
|
||||
|
||||
#print "hand after trailing space removal in filterCrap:",hand
|
||||
#general variable position word filter/string filter
|
||||
for i in xrange (len(hand)):
|
||||
for i in xrange(len(hand)):
|
||||
if hand[i].startswith("Board ["):
|
||||
hand[i] = False
|
||||
elif hand[i].find(" out of hand ")!=-1:
|
||||
|
@ -347,15 +345,16 @@ def filterCrap(hand, isTourney):
|
|||
hand[i] = False
|
||||
elif (hand[i].endswith(" is sitting out")):
|
||||
hand[i] = False
|
||||
# python docs say this is identical to filter(None, list)
|
||||
# which removes all false items from the passed list (hand)
|
||||
hand = [line for line in hand if line]
|
||||
|
||||
hand = [line for line in hand if line] # python docs say this is identical to filter(None, list)
|
||||
|
||||
#print "done with filterCrap, hand:", hand
|
||||
return hand
|
||||
#end filterCrap
|
||||
|
||||
#takes a poker float (including , for thousand seperator and converts it to an int
|
||||
def float2int(string):
|
||||
""" takes a poker float (including , for thousand seperator) and
|
||||
converts it to an int """
|
||||
# Note that this automagically assumes US style currency formatters
|
||||
pos = string.find(",")
|
||||
if pos != -1: #remove , the thousand seperator
|
||||
string = "%s%s" % (string[0:pos], string[pos+1:])
|
||||
|
@ -368,56 +367,46 @@ def float2int(string):
|
|||
if pos == -1: #no decimal point - was in full dollars - need to multiply with 100
|
||||
result *= 100
|
||||
return result
|
||||
#end def float2int
|
||||
|
||||
ActionLines = ( "calls $", ": calls ", "brings in for", "completes it to", "posts small blind",
|
||||
"posts the small blind", "posts big blind", "posts the big blind",
|
||||
"posts small & big blinds", "posts $", "posts a dead", "bets $",
|
||||
": bets ", " raises")
|
||||
ActionLines = ( "calls $", ": calls ", "brings in for", "completes it to",
|
||||
"posts small blind", "posts the small blind", "posts big blind",
|
||||
"posts the big blind", "posts small & big blinds", "posts $",
|
||||
"posts a dead", "bets $", ": bets ", " raises")
|
||||
|
||||
#returns boolean whether the passed line is an action line
|
||||
def isActionLine(line):
|
||||
if (line.endswith("folds")):
|
||||
if line.endswith("folds"):
|
||||
return True
|
||||
elif (line.endswith("checks")):
|
||||
elif line.endswith("checks"):
|
||||
return True
|
||||
elif (line.startswith("Uncalled bet")):
|
||||
elif line.startswith("Uncalled bet"):
|
||||
return True
|
||||
|
||||
# searches for each member of ActionLines being in line, returns true
|
||||
# on first match .. neat func
|
||||
return any(x for x in ActionLines if x in line)
|
||||
# return bool([ x for x in ActionLines if x in line])
|
||||
# ret = any(True for searchstr in ActionLines if searchstr in line)
|
||||
# ret = len( [ x for x in ActionLines if line.find(x) > -1] ) > 0
|
||||
# ret = any(searchstr in line for searchstr in ActionLines)
|
||||
#end def isActionLine
|
||||
|
||||
#returns whether this is a duplicate
|
||||
def isAlreadyInDB(db, gametypeID, siteHandNo):
|
||||
#print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo
|
||||
c = db.get_cursor()
|
||||
c.execute( db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo))
|
||||
c.execute(db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo))
|
||||
result = c.fetchall()
|
||||
if (len(result)>=1):
|
||||
if len(result) >= 1:
|
||||
raise DuplicateError ("dupl")
|
||||
#end isAlreadyInDB
|
||||
|
||||
def isRebuyOrAddon(topline):
|
||||
"""isRebuyOrAddon not implemented yet"""
|
||||
return False
|
||||
#end def isRebuyOrAddon
|
||||
|
||||
#returns whether the passed topline indicates a tournament or not
|
||||
def isTourney(topline):
|
||||
return "Tournament" in topline
|
||||
#end def isTourney
|
||||
|
||||
WinLines = ( "wins the pot", "ties for the ", "wins side pot", "wins the low main pot", "wins the high main pot",
|
||||
"wins the low",
|
||||
"wins the high pot", "wins the high side pot", "wins the main pot", "wins the side pot", "collected" )
|
||||
#returns boolean whether the passed line is a win line
|
||||
|
||||
def isWinLine(line):
|
||||
""" returns boolean whether the passed line is a win line """
|
||||
return any(x for x in WinLines if x in line)
|
||||
#end def isWinLine
|
||||
|
||||
#returns the amount of cash/chips put into the put in the given action line
|
||||
def parseActionAmount(line, atype, isTourney):
|
||||
|
@ -426,7 +415,8 @@ def parseActionAmount(line, atype, isTourney):
|
|||
#elif (line.endswith(", and is all in")):
|
||||
# line=line[:-15]
|
||||
|
||||
if line.endswith(", and is capped"):#ideally we should recognise this as an all-in if category is capXl
|
||||
#ideally we should recognise this as an all-in if category is capXl
|
||||
if line.endswith(", and is capped"):
|
||||
line=line[:-15]
|
||||
if line.endswith(" and is capped"):
|
||||
line=line[:-14]
|
||||
|
@ -439,9 +429,9 @@ def parseActionAmount(line, atype, isTourney):
|
|||
pos1 = line.find("(") + 1
|
||||
pos2 = line.find(")")
|
||||
amount = float2int(line[pos1:pos2])
|
||||
elif atype == "bet" and line.find(": raises $")!=-1 and line.find("to $")!=-1:
|
||||
pos=line.find("to $")+4
|
||||
amount=float2int(line[pos:])
|
||||
elif atype == "bet" and ": raises $" in line and "to $" in line:
|
||||
pos = line.find("to $")+4
|
||||
amount = float2int(line[pos:])
|
||||
else:
|
||||
if not isTourney:
|
||||
pos = line.rfind("$")+1
|
||||
|
@ -489,7 +479,6 @@ def parseActionLine(base, isTourney, line, street, playerIDs, names, action_type
|
|||
actionNos[street][playerno].append(nextActionNo)
|
||||
tmp=(playerIDs[playerno], atype)
|
||||
actionTypeByNo[street].append(tmp)
|
||||
#end def parseActionLine
|
||||
|
||||
def goesAllInOnThisLine(line):
|
||||
"""returns whether the player went all-in on this line and removes the all-in text from the line."""
|
||||
|
@ -501,7 +490,6 @@ def goesAllInOnThisLine(line):
|
|||
line = line[:-15]
|
||||
isAllIn = True
|
||||
return (line, isAllIn)
|
||||
#end def goesAllInOnThisLine
|
||||
|
||||
#returns the action type code (see table design) of the given action line
|
||||
ActionTypes = { 'brings in for' :"blind",
|
||||
|
@ -530,7 +518,6 @@ def parseActionType(line):
|
|||
if x in line:
|
||||
return ActionTypes[x]
|
||||
raise FpdbError ("failed to recognise actiontype in parseActionLine in: "+line)
|
||||
#end def parseActionType
|
||||
|
||||
#parses the ante out of the given line and checks which player paid it, updates antes accordingly.
|
||||
def parseAnteLine(line, isTourney, names, antes):
|
||||
|
@ -547,15 +534,12 @@ def parseAnteLine(line, isTourney, names, antes):
|
|||
pos1 = line.rfind("ante") + 5
|
||||
pos2 = line.find(" ", pos1)
|
||||
antes[i] += int(line[pos1:pos2])
|
||||
#print "parseAnteLine line: ", line, "antes[i]", antes[i], "antes", antes
|
||||
#end def parseAntes
|
||||
|
||||
#returns the buyin of a tourney in cents
|
||||
def parseBuyin(topline):
|
||||
pos1 = topline.find("$")+1
|
||||
pos2 = topline.find("+")
|
||||
return float2int(topline[pos1:pos2])
|
||||
#end def parseBuyin
|
||||
|
||||
#parses a card line and changes the passed arrays accordingly
|
||||
#todo: reorganise this messy method
|
||||
|
@ -568,8 +552,9 @@ def parseCardLine(category, street, line, names, cardValues, cardSuits, boardVal
|
|||
for i in (pos, pos+3):
|
||||
cardValues[playerNo].append(line[i:i+1])
|
||||
cardSuits[playerNo].append(line[i+1:i+2])
|
||||
if len(cardValues[playerNo]) !=2:
|
||||
if cardValues[playerNo][0]==cardValues[playerNo][2] and cardSuits[playerNo][1]==cardSuits[playerNo][3]: #two tests will do
|
||||
if len(cardValues[playerNo]) != 2:
|
||||
if (cardValues[playerNo][0] == cardValues[playerNo][2] and
|
||||
cardSuits[playerNo][1] == cardSuits[playerNo][3]):
|
||||
cardValues[playerNo]=cardValues[playerNo][0:2]
|
||||
cardSuits[playerNo]=cardSuits[playerNo][0:2]
|
||||
else:
|
||||
|
@ -580,13 +565,14 @@ def parseCardLine(category, street, line, names, cardValues, cardSuits, boardVal
|
|||
cardValues[playerNo].append(line[i:i+1])
|
||||
cardSuits[playerNo].append(line[i+1:i+2])
|
||||
if (len(cardValues[playerNo])!=4):
|
||||
if cardValues[playerNo][0]==cardValues[playerNo][4] and cardSuits[playerNo][3]==cardSuits[playerNo][7]: #two tests will do
|
||||
cardValues[playerNo]=cardValues[playerNo][0:4]
|
||||
cardSuits[playerNo]=cardSuits[playerNo][0:4]
|
||||
if (cardValues[playerNo][0] == cardValues[playerNo][4] and
|
||||
cardSuits[playerNo][3] == cardSuits[playerNo][7]): #two tests will do
|
||||
cardValues[playerNo] = cardValues[playerNo][0:4]
|
||||
cardSuits[playerNo] = cardSuits[playerNo][0:4]
|
||||
else:
|
||||
print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
|
||||
raise FpdbError("read too many/too few holecards in parseCardLine")
|
||||
elif category=="razz" or category=="studhi" or category=="studhilo":
|
||||
elif category == "razz" or category == "studhi" or category == "studhilo":
|
||||
if "shows" not in line and "mucked" not in line:
|
||||
#print "parseCardLine(in stud if), street:", street
|
||||
if line[pos+2]=="]": #-> not (hero and 3rd street)
|
||||
|
@ -631,7 +617,6 @@ def parseCardLine(category, street, line, names, cardValues, cardSuits, boardVal
|
|||
#print boardValues
|
||||
else:
|
||||
raise FpdbError ("unrecognised line:"+line)
|
||||
#end def parseCardLine
|
||||
|
||||
def parseCashesAndSeatNos(lines):
|
||||
"""parses the startCashes and seatNos of each player out of the given lines and returns them as a dictionary of two arrays"""
|
||||
|
@ -647,7 +632,6 @@ def parseCashesAndSeatNos(lines):
|
|||
pos2=lines[i].find(" in chips")
|
||||
cashes.append(float2int(lines[i][pos1:pos2]))
|
||||
return {'startCashes':cashes, 'seatNos':seatNos}
|
||||
#end def parseCashesAndSeatNos
|
||||
|
||||
#returns the buyin of a tourney in cents
|
||||
def parseFee(topline):
|
||||
|
@ -655,7 +639,6 @@ def parseFee(topline):
|
|||
pos1=topline.find("$",pos1)+1
|
||||
pos2=topline.find(" ", pos1)
|
||||
return float2int(topline[pos1:pos2])
|
||||
#end def parsefee
|
||||
|
||||
#returns a datetime object with the starttime indicated in the given topline
|
||||
def parseHandStartTime(topline):
|
||||
|
@ -688,10 +671,9 @@ def parseHandStartTime(topline):
|
|||
result = datetime.datetime(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')), int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC')))
|
||||
|
||||
if not isUTC: #these use US ET
|
||||
result+=datetime.timedelta(hours=5)
|
||||
result += datetime.timedelta(hours=5)
|
||||
|
||||
return result
|
||||
#end def parseHandStartTime
|
||||
|
||||
#parses the names out of the given lines and returns them as an array
|
||||
def findName(line):
|
||||
|
@ -701,13 +683,11 @@ def findName(line):
|
|||
|
||||
def parseNames(lines):
|
||||
return [findName(line) for line in lines]
|
||||
#end def parseNames
|
||||
|
||||
def parsePositions(hand, names):
|
||||
positions = [-1 for i in names]
|
||||
sb, bb = -1, -1
|
||||
|
||||
#find blinds
|
||||
for line in hand:
|
||||
if sb == -1 and "small blind" in line and "dead small blind" not in line:
|
||||
sb = line
|
||||
|
@ -735,10 +715,7 @@ def parsePositions(hand, names):
|
|||
positions[bb]="B"
|
||||
|
||||
#fill up rest of array
|
||||
if sbExists:
|
||||
arraypos = sb-1
|
||||
else:
|
||||
arraypos = bb-1
|
||||
arraypos = sb - 1 if sbExists else bb - 1
|
||||
|
||||
distFromBtn=0
|
||||
while arraypos >= 0 and arraypos != bb:
|
||||
|
@ -754,20 +731,18 @@ def parsePositions(hand, names):
|
|||
positions[i] = 9
|
||||
i -= 1
|
||||
### RHH - Changed to set the null seats before BB to "9"
|
||||
if sbExists:
|
||||
i = sb-1
|
||||
else:
|
||||
i = bb-1
|
||||
i = sb - 1 if sbExists else bb - 1
|
||||
|
||||
while positions[i] < 0:
|
||||
positions[i]=9
|
||||
i-=1
|
||||
|
||||
arraypos=len(names)-1
|
||||
if (bb!=0 or (bb==0 and sbExists==False) or (bb == 1 and sb != arraypos) ):
|
||||
while (arraypos>bb and arraypos > sb):
|
||||
positions[arraypos]=distFromBtn
|
||||
arraypos-=1
|
||||
distFromBtn+=1
|
||||
while (arraypos > bb and arraypos > sb):
|
||||
positions[arraypos] = distFromBtn
|
||||
arraypos -= 1
|
||||
distFromBtn += 1
|
||||
|
||||
if any(p == -1 for p in positions):
|
||||
print "parsePositions names:",names
|
||||
|
@ -775,21 +750,18 @@ def parsePositions(hand, names):
|
|||
raise FpdbError ("failed to read positions")
|
||||
# print str(positions), "\n"
|
||||
return positions
|
||||
#end def parsePositions
|
||||
|
||||
#simply parses the rake amount and returns it as an int
|
||||
def parseRake(line):
|
||||
pos=line.find("Rake")+6
|
||||
rake=float2int(line[pos:])
|
||||
pos = line.find("Rake")+6
|
||||
rake = float2int(line[pos:])
|
||||
return rake
|
||||
#end def parseRake
|
||||
|
||||
def parseSiteHandNo(topline):
|
||||
"""returns the hand no assigned by the poker site"""
|
||||
pos1=topline.find("#")+1
|
||||
pos2=topline.find(":")
|
||||
pos1 = topline.find("#")+1
|
||||
pos2 = topline.find(":")
|
||||
return topline[pos1:pos2]
|
||||
#end def parseSiteHandNo
|
||||
|
||||
def parseTableLine(base, line):
|
||||
"""returns a dictionary with maxSeats and tableName"""
|
||||
|
@ -804,11 +776,10 @@ def parseTableLine(base, line):
|
|||
|
||||
#returns the hand no assigned by the poker site
|
||||
def parseTourneyNo(topline):
|
||||
pos1=topline.find("Tournament #")+12
|
||||
pos2=topline.find(",", pos1)
|
||||
pos1 = topline.find("Tournament #")+12
|
||||
pos2 = topline.find(",", pos1)
|
||||
#print "parseTourneyNo pos1:",pos1," pos2:",pos2, " result:",topline[pos1:pos2]
|
||||
return topline[pos1:pos2]
|
||||
#end def parseTourneyNo
|
||||
|
||||
#parses a win/collect line. manipulates the passed array winnings, no explicit return
|
||||
def parseWinLine(line, names, winnings, isTourney):
|
||||
|
@ -819,12 +790,11 @@ def parseWinLine(line, names, winnings, isTourney):
|
|||
if isTourney:
|
||||
pos1 = line.rfind("collected ") + 10
|
||||
pos2 = line.find(" ", pos1)
|
||||
winnings[i]+=int(line[pos1:pos2])
|
||||
winnings[i] += int(line[pos1:pos2])
|
||||
else:
|
||||
pos1 = line.rfind("$") + 1
|
||||
pos2 = line.find(" ", pos1)
|
||||
winnings[i] += float2int(line[pos1:pos2])
|
||||
#end def parseWinLine
|
||||
|
||||
#returns the category (as per database) string for the given line
|
||||
def recogniseCategory(line):
|
||||
|
@ -844,7 +814,6 @@ def recogniseCategory(line):
|
|||
return "studhilo"
|
||||
else:
|
||||
raise FpdbError("failed to recognise category, line:"+line)
|
||||
#end def recogniseCategory
|
||||
|
||||
#returns the int for the gametype_id for the given line
|
||||
def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
|
||||
|
@ -853,50 +822,50 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c
|
|||
|
||||
#note: the below variable names small_bet and big_bet are misleading, in NL/PL they mean small/big blind
|
||||
if isTourney:
|
||||
type="tour"
|
||||
pos1=topline.find("(")+1
|
||||
if (topline[pos1]=="H" or topline[pos1]=="O" or topline[pos1]=="R" or topline[pos1]=="S" or topline[pos1+2]=="C"):
|
||||
pos1=topline.find("(", pos1)+1
|
||||
pos2=topline.find("/", pos1)
|
||||
small_bet=int(topline[pos1:pos2])
|
||||
type = "tour"
|
||||
pos1 = topline.find("(")+1
|
||||
if(topline[pos1] == "H" or topline[pos1] == "O" or
|
||||
topline[pos1] == "R" or topline[pos1]=="S" or
|
||||
topline[pos1+2] == "C"):
|
||||
pos1 = topline.find("(", pos1)+1
|
||||
pos2 = topline.find("/", pos1)
|
||||
small_bet = int(topline[pos1:pos2])
|
||||
else:
|
||||
type="ring"
|
||||
pos1=topline.find("$")+1
|
||||
pos2=topline.find("/$")
|
||||
small_bet=float2int(topline[pos1:pos2])
|
||||
type = "ring"
|
||||
pos1 = topline.find("$")+1
|
||||
pos2 = topline.find("/$")
|
||||
small_bet = float2int(topline[pos1:pos2])
|
||||
|
||||
pos1=pos2+2
|
||||
pos1 = pos2+2
|
||||
if isTourney:
|
||||
pos1-=1
|
||||
pos2=topline.find(")")
|
||||
pos1 -= 1
|
||||
pos2 = topline.find(")")
|
||||
|
||||
if pos2<=pos1:
|
||||
pos2=topline.find(")", pos1)
|
||||
if pos2 <= pos1:
|
||||
pos2 = topline.find(")", pos1)
|
||||
|
||||
if isTourney:
|
||||
big_bet=int(topline[pos1:pos2])
|
||||
big_bet = int(topline[pos1:pos2])
|
||||
else:
|
||||
big_bet=float2int(topline[pos1:pos2])
|
||||
big_bet = float2int(topline[pos1:pos2])
|
||||
|
||||
if (topline.find("No Limit")!=-1):
|
||||
limit_type="nl"
|
||||
if (topline.find("Cap No")!=-1):
|
||||
limit_type="cn"
|
||||
elif (topline.find("Pot Limit")!=-1):
|
||||
limit_type="pl"
|
||||
if (topline.find("Cap Pot")!=-1):
|
||||
limit_type="cp"
|
||||
if 'No Limit' in topline:
|
||||
limit_type = "nl" if 'Cap No' not in topline else "cn"
|
||||
elif 'Pot Limit' in topline:
|
||||
limit_type = "pl" if 'Cap Pot' not in topline else "cp"
|
||||
else:
|
||||
limit_type="fl"
|
||||
limit_type = "fl"
|
||||
|
||||
#print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type
|
||||
if (limit_type=="fl"):
|
||||
cursor.execute ( db.sql.query['getGametypeFL']
|
||||
, (site_id, type, category, limit_type, small_bet, big_bet))
|
||||
if limit_type == "fl":
|
||||
cursor.execute(db.sql.query['getGametypeFL'], (site_id, type, category,
|
||||
limit_type, small_bet,
|
||||
big_bet))
|
||||
else:
|
||||
cursor.execute ( db.sql.query['getGametypeNL']
|
||||
, (site_id, type, category, limit_type, small_bet, big_bet))
|
||||
result=cursor.fetchone()
|
||||
cursor.execute(db.sql.query['getGametypeNL'], (site_id, type, category,
|
||||
limit_type, small_bet,
|
||||
big_bet))
|
||||
result = cursor.fetchone()
|
||||
#print "recgt1 result=",result
|
||||
#ret=result[0]
|
||||
#print "recgt1 ret=",ret
|
||||
|
|
17
setup.py
Normal file
17
setup.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# setup.py
|
||||
# Python packaging for fpdb
|
||||
|
||||
from distutils.core import setup
|
||||
|
||||
setup(name = 'fpdb',
|
||||
description = 'Free Poker Database',
|
||||
version = '0.10.999',
|
||||
author = 'FPDB team',
|
||||
author_email = 'fpdb-main@lists.sourceforge.net',
|
||||
packages = ['fpdb'],
|
||||
package_dir = { 'fpdb' : 'pyfpdb' },
|
||||
data_files = [
|
||||
('/usr/share/doc/python-fpdb',
|
||||
['docs/readme.txt', 'docs/release-notes.txt',
|
||||
'docs/tabledesign.html', 'THANKS.txt'])]
|
||||
)
|
Loading…
Reference in New Issue
Block a user