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

This commit is contained in:
sqlcoder 2010-02-10 19:39:01 +00:00
commit 0449c06e29
15 changed files with 137 additions and 59 deletions

BIN
gfx/fpdb_large_icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -171,6 +171,10 @@ if LOCALE_ENCODING == "US-ASCII":
# needs LOCALE_ENCODING (above), imported for sqlite setup in Config class below # needs LOCALE_ENCODING (above), imported for sqlite setup in Config class below
FROZEN = hasattr(sys, "frozen")
EXEC_PATH = get_exec_path()
import Charset import Charset
@ -618,7 +622,11 @@ class Config:
def save(self, file = None): def save(self, file = None):
if file is None: if file is None:
file = self.file file = self.file
shutil.move(file, file+".backup") try:
shutil.move(file, file+".backup")
except:
pass
with open(file, 'w') as f: with open(file, 'w') as f:
self.doc.writexml(f) self.doc.writexml(f)
@ -1035,3 +1043,9 @@ if __name__== "__main__":
PrettyPrint(site_node, stream=sys.stdout, encoding="utf-8") PrettyPrint(site_node, stream=sys.stdout, encoding="utf-8")
except: except:
print "xml.dom.ext needs PyXML to be installed!" print "xml.dom.ext needs PyXML to be installed!"
print "FROZEN =", FROZEN
print "EXEC_PATH =", EXEC_PATH
print "press enter to end"
sys.stdin.readline()

View File

@ -38,8 +38,9 @@ class Everleaf(HandHistoryConverter):
#re.compile(ur"^(Blinds )?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/(?:\$| €)?(?P<BB>[.0-9]+) (?P<LIMIT>NL|PL|) (?P<GAME>(Hold\'em|Omaha|7 Card Stud))", re.MULTILINE) #re.compile(ur"^(Blinds )?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/(?:\$| €)?(?P<BB>[.0-9]+) (?P<LIMIT>NL|PL|) (?P<GAME>(Hold\'em|Omaha|7 Card Stud))", re.MULTILINE)
re_HandInfo = re.compile(ur".*#(?P<HID>[0-9]+)\n.*\n(Blinds )?(?:\$| €|)(?P<SB>[.0-9]+)/(?:\$| €|)(?P<BB>[.0-9]+) (?P<GAMETYPE>.*) - (?P<DATETIME>\d\d\d\d/\d\d/\d\d - \d\d:\d\d:\d\d)\nTable (?P<TABLE>.+$)", re.MULTILINE) re_HandInfo = re.compile(ur".*#(?P<HID>[0-9]+)\n.*\n(Blinds )?(?:\$| €|)(?P<SB>[.0-9]+)/(?:\$| €|)(?P<BB>[.0-9]+) (?P<GAMETYPE>.*) - (?P<DATETIME>\d\d\d\d/\d\d/\d\d - \d\d:\d\d:\d\d)\nTable (?P<TABLE>.+$)", re.MULTILINE)
re_Button = re.compile(ur"^Seat (?P<BUTTON>\d+) is the button", re.MULTILINE) re_Button = re.compile(ur"^Seat (?P<BUTTON>\d+) is the button", re.MULTILINE)
re_PlayerInfo = re.compile(ur"^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+((?:\$| €|) (?P<CASH>[.0-9]+) (USD|EUR|)|new player|All-in) \)", re.MULTILINE) re_PlayerInfo = re.compile(ur"^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+((?:\$| €|) (?P<CASH>[.0-9]+) (USD|EURO|Chips)|new player|All-in) \)", re.MULTILINE)
re_Board = re.compile(ur"\[ (?P<CARDS>.+) \]") re_Board = re.compile(ur"\[ (?P<CARDS>.+) \]")
re_TourneyInfoFromFilename = re.compile(ur".*TID_(?P<TOURNO>[0-9]+)-(?P<TABLE>[0-9]+)\.txt")
def compilePlayerRegexs(self, hand): def compilePlayerRegexs(self, hand):
@ -55,10 +56,10 @@ class Everleaf(HandHistoryConverter):
self.re_Antes = re.compile(ur"^%s: posts ante \[(?:\$| €|) (?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE) self.re_Antes = re.compile(ur"^%s: posts ante \[(?:\$| €|) (?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
self.re_BringIn = re.compile(ur"^%s posts bring-in (?:\$| €|)(?P<BRINGIN>[.0-9]+)\." % player_re, re.MULTILINE) self.re_BringIn = re.compile(ur"^%s posts bring-in (?:\$| €|)(?P<BRINGIN>[.0-9]+)\." % player_re, re.MULTILINE)
self.re_HeroCards = re.compile(ur"^Dealt to %s \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE) self.re_HeroCards = re.compile(ur"^Dealt to %s \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[(?:\$| €|) (?P<BET>[.\d]+) (USD|EUR|)\])?" % player_re, re.MULTILINE) self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[(?:\$| €|) (?P<BET>[.,\d]+) (USD|EURO|Chips)\])?" % player_re, re.MULTILINE)
#self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds| complete to)(\s\[?(?:\$| €|) ?(?P<BET>\d+\.?\d*)\.?\s?(USD|EUR|)\]?)?" % player_re, re.MULTILINE) #self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds| complete to)(\s\[?(?:\$| €|) ?(?P<BET>\d+\.?\d*)\.?\s?(USD|EUR|)\]?)?" % player_re, re.MULTILINE)
self.re_ShowdownAction = re.compile(ur"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE) self.re_ShowdownAction = re.compile(ur"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
self.re_CollectPot = re.compile(ur"^%s wins (?:\$| €|) (?P<POT>[.\d]+) (USD|EUR|chips)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE) self.re_CollectPot = re.compile(ur"^%s wins (?:\$| €|) (?P<POT>[.\d]+) (USD|EURO|chips)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE)
self.re_SitsOut = re.compile(ur"^%s sits out" % player_re, re.MULTILINE) self.re_SitsOut = re.compile(ur"^%s sits out" % player_re, re.MULTILINE)
def readSupportedGames(self): def readSupportedGames(self):
@ -66,7 +67,9 @@ class Everleaf(HandHistoryConverter):
["ring", "hold", "pl"], ["ring", "hold", "pl"],
["ring", "hold", "fl"], ["ring", "hold", "fl"],
["ring", "studhi", "fl"], ["ring", "studhi", "fl"],
["ring", "omahahi", "pl"] ["ring", "omahahi", "pl"],
["ring", "omahahilo", "pl"],
["tour", "hold", "nl"]
] ]
def determineGameType(self, handText): def determineGameType(self, handText):
@ -138,6 +141,12 @@ or None if we fail to get the info """
hand.tablename = m.group('TABLE') hand.tablename = m.group('TABLE')
hand.maxseats = 6 # assume 6-max unless we have proof it's a larger/smaller game, since everleaf doesn't give seat max info hand.maxseats = 6 # assume 6-max unless we have proof it's a larger/smaller game, since everleaf doesn't give seat max info
t = self.re_TourneyInfoFromFilename.search(self.in_path)
if t:
tourno = t.group('TOURNO')
hand.tourNo = tourno
hand.tablename = t.group('TABLE')
# Believe Everleaf time is GMT/UTC, no transation necessary # Believe Everleaf time is GMT/UTC, no transation necessary
# Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET] # Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET]
# or : 2008/11/07 12:38:49 ET # or : 2008/11/07 12:38:49 ET
@ -287,7 +296,9 @@ or None if we fail to get the info """
@staticmethod @staticmethod
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None): def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
return "^%s -" % (table_name) if tournament:
return "%s - Tournament ID: %s -" % (table_number, tournament)
return "%s -" % (table_name)

View File

@ -193,12 +193,13 @@ class GuiAutoImport (threading.Thread):
self.doAutoImportBool = True self.doAutoImportBool = True
widget.set_label(u' _Stop Autoimport ') widget.set_label(u' _Stop Autoimport ')
if self.pipe_to_hud is None: if self.pipe_to_hud is None:
if os.name == 'nt': if Configuration.FROZEN:
if sys.argv[0] == 'fpdb.exe': path = Configuration.EXEC_PATH
command = 'HUD_main.exe' command = "HUD_main.exe"
else: bs = 0
path = sys.path[0].replace('\\','\\\\') elif os.name == 'nt':
command = 'python "'+path+'\\HUD_main.py" ' + self.settings['cl_options'] path = sys.path[0].replace('\\','\\\\')
command = 'python "'+path+'\\HUD_main.py" ' + self.settings['cl_options']
bs = 0 bs = 0
else: else:
command = os.path.join(sys.path[0], 'HUD_main.py') command = os.path.join(sys.path[0], 'HUD_main.py')
@ -206,6 +207,7 @@ class GuiAutoImport (threading.Thread):
bs = 1 bs = 1
try: try:
print "opening pipe to HUD"
self.pipe_to_hud = subprocess.Popen(command, bufsize=bs, self.pipe_to_hud = subprocess.Popen(command, bufsize=bs,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
universal_newlines=True) universal_newlines=True)

View File

@ -277,7 +277,8 @@ class HUD_main(object):
cards['common'] = comm_cards['common'] cards['common'] = comm_cards['common']
table_kwargs = dict(table_name = table_name, tournament = tour_number, table_number = tab_number) table_kwargs = dict(table_name = table_name, tournament = tour_number, table_number = tab_number)
search_string = getTableTitleRe(self.config, site, type, **table_kwargs) search_string = getTableTitleRe(self.config, site_name, type, **table_kwargs)
# print "getTableTitleRe ", self.config, site_name, type, "=", search_string
tablewindow = Tables.Table(search_string, **table_kwargs) tablewindow = Tables.Table(search_string, **table_kwargs)
if tablewindow is None: if tablewindow is None:

View File

@ -532,6 +532,3 @@ def getSiteHhc(config, sitename):
hhcName = config.supported_sites[sitename].converter hhcName = config.supported_sites[sitename].converter
hhcModule = __import__(hhcName) hhcModule = __import__(hhcName)
return getattr(hhcModule, hhcName[:-6]) return getattr(hhcModule, hhcName[:-6])

View File

@ -15,9 +15,9 @@
#In the "official" distribution you can find the license in #In the "official" distribution you can find the license in
#agpl-3.0.txt in the docs folder of the package. #agpl-3.0.txt in the docs folder of the package.
import os
import sys import sys
from optparse import OptionParser from optparse import OptionParser
# http://docs.python.org/library/optparse.html
def fpdb_options(): def fpdb_options():
@ -41,6 +41,14 @@ def fpdb_options():
parser.add_option("-k", "--konverter", parser.add_option("-k", "--konverter",
dest="hhc", default="PokerStarsToFpdb", dest="hhc", default="PokerStarsToFpdb",
help="Module name for Hand History Converter") help="Module name for Hand History Converter")
parser.add_option("-l", "--logging",
dest = "log_level",
choices = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL', 'EMPTY'),
help = "Error logging level. (DEBUG, INFO, WARNING, ERROR, CRITICAL, EMPTY)",
default = 'EMPTY')
parser.add_option("-v", "--version", action = "store_true",
help = "Print version information and exit.")
(options, argv) = parser.parse_args() (options, argv) = parser.parse_args()
return (options, argv) return (options, argv)

View File

@ -103,7 +103,7 @@ class PokerStars(HandHistoryConverter):
self.re_Action = re.compile(r""" self.re_Action = re.compile(r"""
^%(PLYR)s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat) ^%(PLYR)s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat)
(\s(%(CUR)s)?(?P<BET>[.\d]+))?(\sto\s%(CUR)s(?P<BETTO>[.\d]+))? # the number discarded goes in <BET> (\s(%(CUR)s)?(?P<BET>[.\d]+))?(\sto\s%(CUR)s(?P<BETTO>[.\d]+))? # the number discarded goes in <BET>
(\scards?(\s\[(?P<DISCARDED>.+?)\])?)?""" (\scards?(\s\[(?P<DISCARDED>.+?)\])?)?$"""
% subst, re.MULTILINE|re.VERBOSE) % subst, re.MULTILINE|re.VERBOSE)
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE) self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %(PLYR)s (\(button\) |\(small blind\) |\(big blind\) |\(button\) \(small blind\) )?(collected|showed \[.*\] and won) \(%(CUR)s(?P<POT>[.\d]+)\)(, mucked| with.*|)" % subst, re.MULTILINE) self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %(PLYR)s (\(button\) |\(small blind\) |\(big blind\) |\(button\) \(small blind\) )?(collected|showed \[.*\] and won) \(%(CUR)s(?P<POT>[.\d]+)\)(, mucked| with.*|)" % subst, re.MULTILINE)

View File

@ -245,8 +245,20 @@ def saw_f(stat_dict, player):
def n(stat_dict, player): def n(stat_dict, player):
""" Number of hands played.""" """ Number of hands played."""
try: try:
# If sample is large enough, use X.Yk notation instead
_n = stat_dict[player]['n']
fmt = '%d' % _n
if _n >= 1000:
k = _n / 1000
c = _n % 1000
_c = float(c) / 100.0
d = int(round(_c))
if d == 10:
k += 1
d = 0
fmt = '%d.%dk' % (k, d)
return (stat_dict[player]['n'], return (stat_dict[player]['n'],
'%d' % (stat_dict[player]['n']), '%s' % fmt,
'n=%d' % (stat_dict[player]['n']), 'n=%d' % (stat_dict[player]['n']),
'n=%d' % (stat_dict[player]['n']), 'n=%d' % (stat_dict[player]['n']),
'(%d)' % (stat_dict[player]['n']), '(%d)' % (stat_dict[player]['n']),

View File

@ -101,7 +101,7 @@ class Table_Window(object):
self.table = int(table_number) self.table = int(table_number)
self.name = "%s - %s" % (self.tournament, self.table) self.name = "%s - %s" % (self.tournament, self.table)
elif table_name is not None: elif table_name is not None:
search_string = table_name # search_string = table_name
self.name = table_name self.name = table_name
self.tournament = None self.tournament = None
else: else:

View File

@ -54,10 +54,13 @@ class Table(Table_Window):
titles = {} titles = {}
win32gui.EnumWindows(win_enum_handler, titles) win32gui.EnumWindows(win_enum_handler, titles)
for hwnd in titles: for hwnd in titles:
if titles[hwnd] == "": continue
# print "searching ", search_string, " in ", titles[hwnd]
if re.search(search_string, titles[hwnd]): if re.search(search_string, titles[hwnd]):
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window
if 'HUD:' in titles[hwnd]: continue # FPDB HUD window if 'HUD:' in titles[hwnd]: continue # FPDB HUD window
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
if 'FPDBHUD' in titles[hwnd]: continue # can't attach to ourselves!
self.window = hwnd self.window = hwnd
break break

View File

@ -796,8 +796,11 @@ 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: try:
self.db.disconnect() if self.db is not None and self.db.connected:
self.db.disconnect()
except _mysql_exceptions.OperationalError: # oh, damn, we're already disconnected
pass
self.statusIcon.set_visible(False) self.statusIcon.set_visible(False)
gtk.main_quit() gtk.main_quit()

View File

@ -129,7 +129,7 @@ setup(
description = 'Free Poker DataBase', description = 'Free Poker DataBase',
version = '0.12', version = '0.12',
console = [ {'script': 'fpdb.py', }, console = [ {'script': 'fpdb.py', "icon_resources": [(1, "../gfx/fpdb_large_icon.ico")]},
{'script': 'HUD_main.py', }, {'script': 'HUD_main.py', },
{'script': 'Configuration.py', } {'script': 'Configuration.py', }
], ],

View File

@ -22,12 +22,39 @@ Test if gtk is working.
######################################################################## ########################################################################
import sys import sys
import os
import Configuration
config_path = Configuration.get_default_config_path()
try: try:
import gobject as _gobject
print "Import of gobject:\tSuccess"
import pygtk import pygtk
print "Import of pygtk:\tSuccess"
pygtk.require('2.0') pygtk.require('2.0')
import gtk import gtk
print "Import of gtk:\t\tSuccess"
import pango
print "Import of pango:\tSuccess"
if os.name == 'nt':
import win32
import win32api
print "Import of win32:\tSuccess"
try:
import matplotlib
matplotlib.use('GTK')
print "Import of matplotlib:\tSuccess"
import numpy
print "Import of numpy:\tSuccess"
import pylab
print "Import of pylab:\tSuccess"
except:
print "\nError:", sys.exc_info()
print "\npress return to finish"
sys.stdin.readline()
win = gtk.Window(gtk.WINDOW_TOPLEVEL) win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.set_title("Test GTK") win.set_title("Test GTK")
@ -42,7 +69,7 @@ try:
(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)) (gtk.STOCK_CLOSE, gtk.RESPONSE_OK))
dia.set_default_size(500, 300) dia.set_default_size(500, 300)
l = gtk.Label("GTK is working!") l = gtk.Label("GTK is working!\nConfig location: %s" %config_path)
dia.vbox.add(l) dia.vbox.add(l)
l.show() l.show()

View File

@ -27,9 +27,9 @@ settings.update(config.get_default_paths())
gametype = {'type':'ring', 'base':'draw', 'category':'badugi', 'limitType':'fl', 'sb':'0.25', 'bb':'0.50','currency':'USD'} gametype = {'type':'ring', 'base':'draw', 'category':'badugi', 'limitType':'fl', 'sb':'0.25', 'bb':'0.50','currency':'USD'}
text = "" text = ""
hhc = PokerStarsToFpdb.PokerStars(autostart=False) hhc = PokerStarsToFpdb.PokerStars(config, autostart=False)
h = HoldemOmahaHand(None, "PokerStars", gametype, text, builtFrom = "Test") h = HoldemOmahaHand(config, None, "PokerStars", gametype, text, builtFrom = "Test")
h.addPlayer("1", "s0rrow", "100000") h.addPlayer("1", "s0rrow", "100000")
hhc.compilePlayerRegexs(h) hhc.compilePlayerRegexs(h)
@ -39,7 +39,7 @@ def checkGameInfo(hhc, header, info):
assert hhc.determineGameType(header) == info assert hhc.determineGameType(header) == info
def testGameInfo(): def testGameInfo():
hhc = PokerStarsToFpdb.PokerStars(autostart=False) hhc = PokerStarsToFpdb.PokerStars(config, autostart=False)
pairs = ( pairs = (
(u"PokerStars Game #20461877044: Hold'em No Limit ($1/$2) - 2008/09/16 18:58:01 ET", (u"PokerStars Game #20461877044: Hold'em No Limit ($1/$2) - 2008/09/16 18:58:01 ET",
{'type':'ring', 'base':"hold", 'category':'holdem', 'limitType':'nl', 'sb':'1', 'bb':'2', 'currency':'USD'}), {'type':'ring', 'base':"hold", 'category':'holdem', 'limitType':'nl', 'sb':'1', 'bb':'2', 'currency':'USD'}),