Merge branch 'master' of git://git.assembla.com/free_poker_tools
This commit is contained in:
commit
0449c06e29
BIN
gfx/fpdb_large_icon.ico
Normal file
BIN
gfx/fpdb_large_icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -71,7 +71,7 @@ follow : whether to tail -f the input"""
|
||||||
self.config = config
|
self.config = config
|
||||||
#log = Configuration.get_logger("logging.conf", "parser", log_dir=self.config.dir_log)
|
#log = Configuration.get_logger("logging.conf", "parser", log_dir=self.config.dir_log)
|
||||||
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 = index
|
self.index = index
|
||||||
self.starsArchive = starsArchive
|
self.starsArchive = starsArchive
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ follow : whether to tail -f the input"""
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
if in_path == '-':
|
if in_path == '-':
|
||||||
self.in_fh = sys.stdin
|
self.in_fh = sys.stdin
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ follow : whether to tail -f the input"""
|
||||||
self.follow = follow
|
self.follow = follow
|
||||||
self.compiledPlayers = set()
|
self.compiledPlayers = set()
|
||||||
self.maxseats = 10
|
self.maxseats = 10
|
||||||
|
|
||||||
self.status = True
|
self.status = True
|
||||||
|
|
||||||
self.parsedObjectType = "HH" #default behaviour : parsing HH files, can be "Summary" if the parsing encounters a Summary File
|
self.parsedObjectType = "HH" #default behaviour : parsing HH files, can be "Summary" if the parsing encounters a Summary File
|
||||||
|
@ -128,7 +128,7 @@ HandHistoryConverter: '%(sitename)s'
|
||||||
in_path '%(in_path)s'
|
in_path '%(in_path)s'
|
||||||
out_path '%(out_path)s'
|
out_path '%(out_path)s'
|
||||||
follow '%(follow)s'
|
follow '%(follow)s'
|
||||||
""" % locals()
|
""" % locals()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Process a hand at a time from the input specified by in_path.
|
"""Process a hand at a time from the input specified by in_path.
|
||||||
|
@ -148,7 +148,7 @@ Otherwise, finish at EOF.
|
||||||
self.numHands = 0
|
self.numHands = 0
|
||||||
self.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:
|
||||||
|
@ -183,7 +183,7 @@ Otherwise, finish at EOF.
|
||||||
endtime = time.time()
|
endtime = time.time()
|
||||||
if summaryParsingStatus :
|
if summaryParsingStatus :
|
||||||
log.info("Summary file '%s' correctly parsed (took %.3f seconds)" % (self.in_path, endtime - starttime))
|
log.info("Summary file '%s' correctly parsed (took %.3f seconds)" % (self.in_path, endtime - starttime))
|
||||||
else :
|
else :
|
||||||
log.warning("Error converting summary file '%s' (took %.3f seconds)" % (self.in_path, endtime - starttime))
|
log.warning("Error converting summary file '%s' (took %.3f seconds)" % (self.in_path, endtime - starttime))
|
||||||
|
|
||||||
except IOError, ioe:
|
except IOError, ioe:
|
||||||
|
@ -237,7 +237,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
# x-- [x,--,] x,--
|
# x-- [x,--,] x,--
|
||||||
# x--x [x,--,x] x,x
|
# x--x [x,--,x] x,x
|
||||||
# x--x-- [x,--,x,--,] x,x,--
|
# x--x-- [x,--,x,--,] x,x,--
|
||||||
|
|
||||||
# The length is always odd.
|
# The length is always odd.
|
||||||
# 'odd' indices are always splitters.
|
# 'odd' indices are always splitters.
|
||||||
# 'even' indices are always paragraphs or ''
|
# 'even' indices are always paragraphs or ''
|
||||||
|
@ -271,13 +271,13 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
log.info("Read no hands.")
|
log.info("Read no hands.")
|
||||||
return []
|
return []
|
||||||
return re.split(self.re_SplitHands, self.obs)
|
return re.split(self.re_SplitHands, self.obs)
|
||||||
|
|
||||||
def processHand(self, handText):
|
def processHand(self, handText):
|
||||||
gametype = self.determineGameType(handText)
|
gametype = self.determineGameType(handText)
|
||||||
log.debug("gametype %s" % gametype)
|
log.debug("gametype %s" % gametype)
|
||||||
hand = None
|
hand = None
|
||||||
l = None
|
l = None
|
||||||
if gametype is None:
|
if gametype is None:
|
||||||
gametype = "unmatched"
|
gametype = "unmatched"
|
||||||
# TODO: not ideal, just trying to not error.
|
# TODO: not ideal, just trying to not error.
|
||||||
# TODO: Need to count failed hands.
|
# TODO: Need to count failed hands.
|
||||||
|
@ -311,7 +311,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
# This function should return a list of lists looking like:
|
# This function should return a list of lists looking like:
|
||||||
# return [["ring", "hold", "nl"], ["tour", "hold", "nl"]]
|
# return [["ring", "hold", "nl"], ["tour", "hold", "nl"]]
|
||||||
# Showing all supported games limits and types
|
# Showing all supported games limits and types
|
||||||
|
|
||||||
def readSupportedGames(self): abstract
|
def readSupportedGames(self): abstract
|
||||||
|
|
||||||
# should return a list
|
# should return a list
|
||||||
|
@ -346,17 +346,17 @@ or None if we fail to get the info """
|
||||||
# Needs to return a list of lists in the format
|
# Needs to return a list of lists in the format
|
||||||
# [['seat#', 'player1name', 'stacksize'] ['seat#', 'player2name', 'stacksize'] [...]]
|
# [['seat#', 'player1name', 'stacksize'] ['seat#', 'player2name', 'stacksize'] [...]]
|
||||||
def readPlayerStacks(self, hand): abstract
|
def readPlayerStacks(self, hand): abstract
|
||||||
|
|
||||||
def compilePlayerRegexs(self): abstract
|
def compilePlayerRegexs(self): abstract
|
||||||
"""Compile dynamic regexes -- these explicitly match known player names and must be updated if a new player joins"""
|
"""Compile dynamic regexes -- these explicitly match known player names and must be updated if a new player joins"""
|
||||||
|
|
||||||
# Needs to return a MatchObject with group names identifying the streets into the Hand object
|
# Needs to return a MatchObject with group names identifying the streets into the Hand object
|
||||||
# so groups are called by street names 'PREFLOP', 'FLOP', 'STREET2' etc
|
# so groups are called by street names 'PREFLOP', 'FLOP', 'STREET2' etc
|
||||||
# blinds are done seperately
|
# blinds are done seperately
|
||||||
def markStreets(self, hand): abstract
|
def markStreets(self, hand): abstract
|
||||||
|
|
||||||
#Needs to return a list in the format
|
#Needs to return a list in the format
|
||||||
# ['player1name', 'player2name', ...] where player1name is the sb and player2name is bb,
|
# ['player1name', 'player2name', ...] where player1name is the sb and player2name is bb,
|
||||||
# addtional players are assumed to post a bb oop
|
# addtional players are assumed to post a bb oop
|
||||||
def readBlinds(self, hand): abstract
|
def readBlinds(self, hand): abstract
|
||||||
def readAntes(self, hand): abstract
|
def readAntes(self, hand): abstract
|
||||||
|
@ -369,16 +369,16 @@ or None if we fail to get the info """
|
||||||
def readShownCards(self, hand): abstract
|
def readShownCards(self, hand): abstract
|
||||||
|
|
||||||
# Some sites do odd stuff that doesn't fall in to the normal HH parsing.
|
# Some sites do odd stuff that doesn't fall in to the normal HH parsing.
|
||||||
# e.g., FTP doesn't put mixed game info in the HH, but puts in in the
|
# e.g., FTP doesn't put mixed game info in the HH, but puts in in the
|
||||||
# file name. Use readOther() to clean up those messes.
|
# file name. Use readOther() to clean up those messes.
|
||||||
def readOther(self, hand): pass
|
def readOther(self, hand): pass
|
||||||
|
|
||||||
# Some sites don't report the rake. This will be called at the end of the hand after the pot total has been calculated
|
# Some sites don't report the rake. This will be called at the end of the hand after the pot total has been calculated
|
||||||
# an inheriting class can calculate it for the specific site if need be.
|
# an inheriting class can calculate it for the specific site if need be.
|
||||||
def getRake(self, hand):
|
def getRake(self, hand):
|
||||||
hand.rake = hand.totalpot - hand.totalcollected # * Decimal('0.05') # probably not quite right
|
hand.rake = hand.totalpot - hand.totalcollected # * Decimal('0.05') # probably not quite right
|
||||||
|
|
||||||
|
|
||||||
def sanityCheck(self):
|
def sanityCheck(self):
|
||||||
"""Check we aren't going to do some stupid things"""
|
"""Check we aren't going to do some stupid things"""
|
||||||
#TODO: the hhbase stuff needs to be in fpdb_import
|
#TODO: the hhbase stuff needs to be in fpdb_import
|
||||||
|
@ -403,7 +403,7 @@ or None if we fail to get the info """
|
||||||
# Make sure input and output files are different or we'll overwrite the source file
|
# Make sure input and output files are different or we'll overwrite the source file
|
||||||
if True: # basically.. I don't know
|
if True: # basically.. I don't know
|
||||||
sane = True
|
sane = True
|
||||||
|
|
||||||
if self.in_path != '-' and self.out_path == self.in_path:
|
if self.in_path != '-' and self.out_path == self.in_path:
|
||||||
print "HH Sanity Check: output and input files are the same, check config"
|
print "HH Sanity Check: output and input files are the same, check config"
|
||||||
sane = False
|
sane = False
|
||||||
|
@ -436,7 +436,7 @@ or None if we fail to get the info """
|
||||||
|
|
||||||
def readFile(self):
|
def readFile(self):
|
||||||
"""Open in_path according to self.codepage. Exceptions caught further up"""
|
"""Open in_path according to self.codepage. Exceptions caught further up"""
|
||||||
|
|
||||||
if self.filetype == "text":
|
if self.filetype == "text":
|
||||||
if self.in_path == '-':
|
if self.in_path == '-':
|
||||||
# read from stdin
|
# read from stdin
|
||||||
|
@ -471,7 +471,7 @@ or None if we fail to get the info """
|
||||||
|
|
||||||
if hand.gametype['base'] == 'stud':
|
if hand.gametype['base'] == 'stud':
|
||||||
if mo <= 8: return 8
|
if mo <= 8: return 8
|
||||||
else: return mo
|
else: return mo
|
||||||
|
|
||||||
if hand.gametype['base'] == 'draw':
|
if hand.gametype['base'] == 'draw':
|
||||||
if mo <= 6: return 6
|
if mo <= 6: return 6
|
||||||
|
@ -507,9 +507,9 @@ or None if we fail to get the info """
|
||||||
def getParsedObjectType(self):
|
def getParsedObjectType(self):
|
||||||
return self.parsedObjectType
|
return self.parsedObjectType
|
||||||
|
|
||||||
#returns a status (True/False) indicating wether the parsing could be done correctly or not
|
#returns a status (True/False) indicating wether the parsing could be done correctly or not
|
||||||
def readSummaryInfo(self, summaryInfoList): abstract
|
def readSummaryInfo(self, summaryInfoList): abstract
|
||||||
|
|
||||||
def getTourney(self):
|
def getTourney(self):
|
||||||
return self.tourney
|
return self.tourney
|
||||||
|
|
||||||
|
@ -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])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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']),
|
||||||
|
|
|
@ -11,12 +11,12 @@ of Table_Window objects representing the windows found.
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
@ -58,7 +58,7 @@ bad_words = ('History for table:', 'HUD:', 'Chat:')
|
||||||
|
|
||||||
# Here are the custom signals we define for allowing the 'client watcher'
|
# Here are the custom signals we define for allowing the 'client watcher'
|
||||||
# thread to communicate with the gui thread. Any time a poker client is
|
# thread to communicate with the gui thread. Any time a poker client is
|
||||||
# is moved, resized, or closed on of these signals is emitted to the
|
# is moved, resized, or closed on of these signals is emitted to the
|
||||||
# HUD main window.
|
# HUD main window.
|
||||||
gobject.signal_new("client_moved", gtk.Window,
|
gobject.signal_new("client_moved", gtk.Window,
|
||||||
gobject.SIGNAL_RUN_LAST,
|
gobject.SIGNAL_RUN_LAST,
|
||||||
|
@ -80,16 +80,16 @@ gobject.signal_new("client_destroyed", gtk.Window,
|
||||||
# from the corresponding hand history.
|
# from the corresponding hand history.
|
||||||
# tw.site = the site name, e.g. PokerStars, FullTilt. This must match the site
|
# tw.site = the site name, e.g. PokerStars, FullTilt. This must match the site
|
||||||
# name specified in the config file.
|
# name specified in the config file.
|
||||||
# tw.number = This is the system id number for the client table window in the
|
# tw.number = This is the system id number for the client table window in the
|
||||||
# format that the system presents it. This is Xid in Xwindows and
|
# format that the system presents it. This is Xid in Xwindows and
|
||||||
# hwnd in Microsoft Windows.
|
# hwnd in Microsoft Windows.
|
||||||
# tw.title = The full title from the window title bar.
|
# tw.title = The full title from the window title bar.
|
||||||
# tw.width, tw.height = The width and height of the window in pixels. This is
|
# tw.width, tw.height = The width and height of the window in pixels. This is
|
||||||
# the internal width and height, not including the title bar and
|
# the internal width and height, not including the title bar and
|
||||||
# window borders.
|
# window borders.
|
||||||
# tw.x, tw.y = The x, y (horizontal, vertical) location of the window relative
|
# tw.x, tw.y = The x, y (horizontal, vertical) location of the window relative
|
||||||
# to the top left of the display screen. This also does not include the
|
# to the top left of the display screen. This also does not include the
|
||||||
# title bar and window borders. To put it another way, this is the
|
# title bar and window borders. To put it another way, this is the
|
||||||
# screen location of (0, 0) in the working window.
|
# screen location of (0, 0) in the working window.
|
||||||
|
|
||||||
class Table_Window(object):
|
class Table_Window(object):
|
||||||
|
@ -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:
|
||||||
|
@ -111,7 +111,7 @@ class Table_Window(object):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# __str__ method for testing
|
# __str__ method for testing
|
||||||
likely_attrs = ("site", "number", "title", "width", "height", "x", "y",
|
likely_attrs = ("site", "number", "title", "width", "height", "x", "y",
|
||||||
"tournament", "table", "gdkhandle")
|
"tournament", "table", "gdkhandle")
|
||||||
temp = 'TableWindow object\n'
|
temp = 'TableWindow object\n'
|
||||||
for a in likely_attrs:
|
for a in likely_attrs:
|
||||||
|
@ -125,7 +125,7 @@ class Table_Window(object):
|
||||||
for game, names in game_names.iteritems():
|
for game, names in game_names.iteritems():
|
||||||
for name in names:
|
for name in names:
|
||||||
if name in title:
|
if name in title:
|
||||||
return game
|
return game
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def check_geometry(self):
|
def check_geometry(self):
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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', }
|
||||||
],
|
],
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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'}),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user