From 5c468d0a3877fc4ab09344bb9bc6d5221f35dd96 Mon Sep 17 00:00:00 2001 From: grindi Date: Sat, 8 Aug 2009 15:47:58 +0400 Subject: [PATCH 01/12] Added party hh path into HUD_config.xml.example --- pyfpdb/HUD_config.xml.example | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index bd8cb7df..adc8141c 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -252,10 +252,10 @@ From 4074092f322dff53f1ce4bbe619a542e80f83c11 Mon Sep 17 00:00:00 2001 From: grindi Date: Sat, 8 Aug 2009 17:36:48 +0400 Subject: [PATCH 02/12] Removed .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index f3d74a9a..00000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pyc -*~ From c042bea1817a99a6639c4ecbd66be20d54e76d28 Mon Sep 17 00:00:00 2001 From: grindi Date: Sun, 9 Aug 2009 16:24:31 +0400 Subject: [PATCH 03/12] Improved table-by-name recognition for non-latin window titles What i mean: u'1464739' in 'Speed #1464739 - \xc1\xcb \xd5\xee\xeb\xe4\xe5\xec' -> Exception u'1464739' in 'Speed #1464739 - \xc1\xcb \xd5\xee\xeb\xe4\xe5\xec'.decode('cp1251') -> True --- pyfpdb/Tables.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index 97a897ca..9fdc8630 100755 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -230,11 +230,20 @@ def discover_nt_by_name(c, tablename): """Finds poker client window with the given table name.""" titles = {} win32gui.EnumWindows(win_enum_handler, titles) + + def getDefaultEncoding(): + # FIXME: if somebody know better place fot this function - move it + # FIXME: it's better to use GetCPInfo for windows http://msdn.microsoft.com/en-us/library/dd318078(VS.85).aspx + # but i have no idea, how to call it + import locale + return locale.getpreferredencoding() + for hwnd in titles: #print "Tables.py: tablename =", tablename, "title =", titles[hwnd] try: + # maybe it's better to make global titles[hwnd] decoding? # this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html - if not tablename.lower() in titles[hwnd].lower(): continue + if not tablename.lower() in titles[hwnd].decode(getDefaultEncoding()).lower(): continue except: continue if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window From 730c82bc95613030559925cbac30e225ff7c0cc1 Mon Sep 17 00:00:00 2001 From: grindi Date: Sun, 9 Aug 2009 16:38:55 +0400 Subject: [PATCH 04/12] Party hhc: added max seats recognition --- pyfpdb/PartyPokerToFpdb.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pyfpdb/PartyPokerToFpdb.py b/pyfpdb/PartyPokerToFpdb.py index af1081df..81044e78 100644 --- a/pyfpdb/PartyPokerToFpdb.py +++ b/pyfpdb/PartyPokerToFpdb.py @@ -88,6 +88,7 @@ class PartyPoker(HandHistoryConverter): """, re.MULTILINE|re.VERBOSE) + re_TotalPlayers = re.compile("^Total\s+number\s+of\s+players\s*:\s*(?P\d+)", re.MULTILINE) re_SplitHands = re.compile('\x00+') re_TailSplitHands = re.compile('(\x00+)') lineSplitter = '\n' @@ -112,6 +113,8 @@ follow : whether to tail -f the input""" def allHandsAsList(self): list = HandHistoryConverter.allHandsAsList(self) + if list is None: + return None return filter(lambda text: len(text.strip()), list) def compilePlayerRegexs(self, hand): @@ -249,6 +252,9 @@ follow : whether to tail -f the input""" m = self.re_Hid.search(hand.handText) if m: info.update(m.groupdict()) + m = self.re_TotalPlayers.search(hand.handText) + if m: info.update(m.groupdict()) + # FIXME: it's a hack cause party doesn't supply hand.maxseats info #hand.maxseats = ??? hand.mixed = None @@ -281,6 +287,8 @@ follow : whether to tail -f the input""" #FIXME: it's dirty hack T_T cur = info[key][0] if info[key][0] not in '0123456789' else '' hand.buyin = info[key] + '+%s0' % cur + if key == 'MAXSEATS': + hand.maxseats = int(info[key]) if key == 'LEVEL': hand.level = info[key] if key == 'PLAY' and info['PLAY'] != 'Real': From a32d4e053a4df6d1d7a469307e5784d9e6fb3db2 Mon Sep 17 00:00:00 2001 From: Matt Turnbull Date: Sun, 9 Aug 2009 15:19:43 +0100 Subject: [PATCH 05/12] FulltiltToFpdb handles canceled hands Better exception handling during parsing FpdbParseEcxeption takes an optional HID Stripped pointless __init__s from *ToFpdb subclasses Logging now has logging.conf config - default is to log only INFO to file but easily changed to DEBUG for devel work --- pyfpdb/BetfairToFpdb.py | 18 ++--- pyfpdb/EverleafToFpdb.py | 23 ++---- pyfpdb/Exceptions.py | 5 +- pyfpdb/FulltiltToFpdb.py | 35 ++++----- pyfpdb/Hand.py | 51 ++++++------- pyfpdb/HandHistoryConverter.py | 133 +++++++++++++++++++++------------ pyfpdb/PartyPokerToFpdb.py | 19 ++--- pyfpdb/PokerStarsToFpdb.py | 26 ++----- pyfpdb/Win2dayToFpdb.py | 16 ++-- pyfpdb/test_FullTilt.py | 7 +- pyfpdb/test_PokerStars.py | 2 +- 11 files changed, 164 insertions(+), 171 deletions(-) diff --git a/pyfpdb/BetfairToFpdb.py b/pyfpdb/BetfairToFpdb.py index 1ccec5d0..59344991 100755 --- a/pyfpdb/BetfairToFpdb.py +++ b/pyfpdb/BetfairToFpdb.py @@ -26,6 +26,11 @@ from HandHistoryConverter import * class Betfair(HandHistoryConverter): + sitename = 'Betfair' + filetype = "text" + codepage = "cp1252" + siteId = 7 # Needs to match id entry in Sites database + # Static regexes re_GameInfo = re.compile("^(?PNL|PL|) (?P\$|)?(?P[.0-9]+)/\$?(?P[.0-9]+) (?P(Texas Hold\'em|Omaha Hi|Razz))", re.MULTILINE) re_SplitHands = re.compile(r'\n\n+') @@ -34,19 +39,6 @@ class Betfair(HandHistoryConverter): re_PlayerInfo = re.compile("Seat (?P[0-9]+): (?P.*)\s\(\s(\$(?P[.0-9]+)) \)") re_Board = re.compile(ur"\[ (?P.+) \]") - def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True, index=0): - """\ -in_path (default '-' = sys.stdin) -out_path (default '-' = sys.stdout) -follow : whether to tail -f the input""" - HandHistoryConverter.__init__(self, in_path, out_path, sitename="Betfair", follow=follow, index) # Call super class init. - logging.info("Initialising Betfair converter class") - self.filetype = "text" - self.codepage = "cp1252" - self.siteId = 7 # Needs to match id entry in Sites database - if autostart: - self.start() - def compilePlayerRegexs(self, hand): players = set([player[1] for player in hand.players]) diff --git a/pyfpdb/EverleafToFpdb.py b/pyfpdb/EverleafToFpdb.py index 9c63bcf0..2835b6ff 100755 --- a/pyfpdb/EverleafToFpdb.py +++ b/pyfpdb/EverleafToFpdb.py @@ -26,6 +26,11 @@ from HandHistoryConverter import * class Everleaf(HandHistoryConverter): + sitename = 'Everleaf' + filetype = "text" + codepage = "cp1252" + siteId = 3 # Needs to match id entry in Sites database + # Static regexes re_SplitHands = re.compile(r"\n\n\n+") re_TailSplitHands = re.compile(r"(\n\n\n+)") @@ -37,24 +42,6 @@ class Everleaf(HandHistoryConverter): re_Board = re.compile(ur"\[ (?P.+) \]") - def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True, debugging=False, index=0): - """\ -in_path (default '-' = sys.stdin) -out_path (default '-' = sys.stdout) -follow : whether to tail -f the input -autostart: whether to run the thread (or you can call start() yourself) -debugging: if False, pass on partially supported game types. If true, have a go and error...""" - #print "DEBUG: XXXXXXXXXXXXXXX" - HandHistoryConverter.__init__(self, in_path, out_path, sitename="Everleaf", follow=follow, index=index) - logging.info("Initialising Everleaf converter class") - self.filetype = "text" - self.codepage = "cp1252" - self.siteId = 3 # Needs to match id entry in Sites database - self.debugging = debugging - if autostart: - self.start() - # otherwise you need to call start yourself. - def compilePlayerRegexs(self, hand): players = set([player[1] for player in hand.players]) if not players <= self.compiledPlayers: # x <= y means 'x is subset of y' diff --git a/pyfpdb/Exceptions.py b/pyfpdb/Exceptions.py index fa76f3cd..8259a484 100644 --- a/pyfpdb/Exceptions.py +++ b/pyfpdb/Exceptions.py @@ -1 +1,4 @@ -class FpdbParseError(Exception): pass +class FpdbParseError(Exception): + def __init__(self,hid=None): + self.hid = hid + diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index a68c1cbd..19a666f1 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -27,6 +27,11 @@ from HandHistoryConverter import * class Fulltilt(HandHistoryConverter): + sitename = "Fulltilt" + filetype = "text" + codepage = "cp1252" + siteId = 1 # Needs to match id entry in Sites database + # Static regexes re_GameInfo = re.compile('''(?:(?P.+)\s\((?P\d+)\),\s)? .+ @@ -39,7 +44,7 @@ class Fulltilt(HandHistoryConverter): ''', re.VERBOSE) re_SplitHands = re.compile(r"\n\n+") re_TailSplitHands = re.compile(r"(\n\n+)") - re_HandInfo = re.compile('''.*\#(?P[0-9]+):\s + re_HandInfo = re.compile(r'''.*\#(?P[0-9]+):\s (?:(?P.+)\s\((?P\d+)\),\s)? Table\s (?PPlay\sChip\s|PC)? @@ -47,8 +52,9 @@ class Fulltilt(HandHistoryConverter): (\((?P.+)\)\s)?-\s \$?(?P[.0-9]+)/\$?(?P[.0-9]+)\s(Ante\s\$?(?P[.0-9]+)\s)?-\s (?P[a-zA-Z\/\'\s]+)\s-\s - (?P.*) - ''', re.VERBOSE) + (?P.*?)\n + (?:.*?\n(?PHand\s\#(?P=HID)\shas\sbeen\scanceled))? + ''', re.VERBOSE|re.DOTALL) re_Button = re.compile('^The button is in seat #(?P