Merge branch 'master' of git://git.assembla.com/free_poker_tools
This commit is contained in:
		
						commit
						21df5900e9
					
				|  | @ -379,7 +379,6 @@ class Config: | |||
| 
 | ||||
|     def edit_layout(self, site_name, max, width = None, height = None, | ||||
|                     fav_seat = None, locations = None): | ||||
|         print "max = ", max | ||||
|         site_node   = self.get_site_node(site_name) | ||||
|         layout_node = self.get_layout_node(site_node, max) | ||||
|         if layout_node == None: return | ||||
|  | @ -484,6 +483,10 @@ class Config: | |||
|                           (  0, 280), (121, 280), ( 46,  30) ) | ||||
|         return locations | ||||
| 
 | ||||
|     def get_supported_sites(self): | ||||
|         """Returns the list of supported sites.""" | ||||
|         return self.supported_sites.keys() | ||||
| 
 | ||||
|     def get_site_parameters(self, site): | ||||
|         """Returns a dict of the site parameters for the specified site""" | ||||
|         if not self.supported_sites.has_key(site): | ||||
|  | @ -498,6 +501,7 @@ class Config: | |||
|         parms["site_path"]    = self.supported_sites[site].site_path | ||||
|         parms["table_finder"] = self.supported_sites[site].table_finder | ||||
|         parms["HH_path"]      = self.supported_sites[site].HH_path | ||||
|         parms["site_name"]    = self.supported_sites[site].site_name | ||||
|         parms["enabled"]      = self.supported_sites[site].enabled | ||||
|         return parms | ||||
| 
 | ||||
|  |  | |||
|  | @ -142,12 +142,17 @@ class Database: | |||
|             cards[s_dict['seat_number']] = s_dict | ||||
|         return (cards) | ||||
| 
 | ||||
|     def get_stats_from_hand(self, hand, player_id = False): | ||||
|     def get_stats_from_hand(self, hand, aggregate = False): | ||||
|         c = self.connection.cursor() | ||||
| 
 | ||||
|         if not player_id: player_id = "%" | ||||
|         if aggregate: | ||||
|             query = 'get_stats_from_hand' | ||||
|             subs = (hand, hand) | ||||
|         else: | ||||
|             query = 'get_stats_from_hand_aggregated' | ||||
|             subs = (hand, hand, hand) | ||||
| 
 | ||||
| #    get the players in the hand and their seats | ||||
| #        c.execute(self.sql.query['get_players_from_hand'], (hand, player_id)) | ||||
|         c.execute(self.sql.query['get_players_from_hand'], (hand, )) | ||||
|         names = {} | ||||
|         seats = {} | ||||
|  | @ -156,8 +161,7 @@ class Database: | |||
|             seats[row[0]] = row[1] | ||||
| 
 | ||||
| #    now get the stats | ||||
| #        c.execute(self.sql.query['get_stats_from_hand'], (hand, hand, player_id)) | ||||
|         c.execute(self.sql.query['get_stats_from_hand'], (hand, hand)) | ||||
|         c.execute(self.sql.query[query], subs) | ||||
|         colnames = [desc[0] for desc in c.description] | ||||
|         stat_dict = {} | ||||
|         for row in c.fetchall(): | ||||
|  |  | |||
|  | @ -92,7 +92,7 @@ def read_stdin():            # This is the thread function | |||
|     global hud_dict | ||||
| 
 | ||||
|     db_connection = Database.Database(config, db_name, 'temp') | ||||
| #    tourny_finder = re.compile('(\d+) (\d+)') | ||||
|     tourny_finder = re.compile('(\d+) (\d+)') | ||||
| 
 | ||||
|     while True: # wait for a new hand number on stdin | ||||
|         new_hand_id = sys.stdin.readline() | ||||
|  | @ -110,11 +110,12 @@ def read_stdin():            # This is the thread function | |||
| 
 | ||||
| #    find out if this hand is from a tournament | ||||
|         is_tournament = False | ||||
| #        (t_number, s_number) = (0, 0) | ||||
| #        mat_obj = tourny_finder(table_name) | ||||
|         (tour_number, tab_number) = (0, 0) | ||||
|         mat_obj = tourny_finder.search(table_name) | ||||
| #        if len(mat_obj.groups) == 2: | ||||
| #            is_tournament = True | ||||
| #            (t_number, s_number) = mat_obj.group(1, 2) | ||||
|         if mat_obj: | ||||
|             is_tournament = True | ||||
|             (tour_number, tab_number) = mat_obj.group(1, 2) | ||||
|              | ||||
|         stat_dict = db_connection.get_stats_from_hand(new_hand_id) | ||||
| 
 | ||||
|  | @ -122,16 +123,16 @@ def read_stdin():            # This is the thread function | |||
|         if hud_dict.has_key(table_name): | ||||
|             update_HUD(new_hand_id, table_name, config, stat_dict) | ||||
| #    if a hud for this TOURNAMENT table exists, just update it | ||||
| #        elif hud_dict.has_key(t_number): | ||||
| #            update_HUD(new_hand_id, t_number, config, stat_dict) | ||||
| #        otherwise create a new hud | ||||
|         elif hud_dict.has_key(tour_number): | ||||
|             update_HUD(new_hand_id, tour_number, config, stat_dict) | ||||
| #    otherwise create a new hud | ||||
|         else: | ||||
|             if is_tournament: | ||||
|                 tablewindow = Tables.discover_tournament_table(config, t_number, s_number) | ||||
|                 tablewindow = Tables.discover_tournament_table(config, tour_number, tab_number) | ||||
|                 if tablewindow == None: | ||||
|                     sys.stderr.write("table name "+table_name+" not found\n") | ||||
|                     sys.stderr.write("tournament %s,  table %s not found\n" % (tour_number, tab_number)) | ||||
|                 else: | ||||
|                     create_HUD(new_hand_id, tablewindow, db_name, t_number, max, poker_game, db_connection, config, stat_dict) | ||||
|                     create_HUD(new_hand_id, tablewindow, db_name, tour_number, max, poker_game, db_connection, config, stat_dict) | ||||
|             else: | ||||
|                 tablewindow = Tables.discover_table_by_name(config, table_name) | ||||
|                 if tablewindow == None: | ||||
|  |  | |||
|  | @ -237,11 +237,81 @@ class Sql: | |||
|                     AND   Hands.gametypeId = HudCache.gametypeId | ||||
|                     GROUP BY HudCache.PlayerId | ||||
|                 """ | ||||
| #                    AND   PlayerId LIKE %s | ||||
| #                        HudCache.gametypeId              AS gametypeId, | ||||
| #                        activeSeats                      AS n_active, | ||||
| #                        position                         AS position, | ||||
| #                        HudCache.tourneyTypeId           AS tourneyTypeId, | ||||
| 
 | ||||
| #    same as above except stats are aggregated for all blind/limit levels | ||||
|             self.query['get_stats_from_hand_aggregated'] = """ | ||||
|                     SELECT HudCache.playerId             AS player_id,  | ||||
|                         sum(HDs)                         AS n, | ||||
|                         sum(street0VPI)                  AS vpip, | ||||
|                         sum(street0Aggr)                 AS pfr, | ||||
|                         sum(street0_3B4BChance)          AS TB_opp_0, | ||||
|                         sum(street0_3B4BDone)            AS TB_0, | ||||
|                         sum(street1Seen)                 AS saw_f, | ||||
|                         sum(street1Seen)                 AS saw_1, | ||||
|                         sum(street2Seen)                 AS saw_2, | ||||
|                         sum(street3Seen)                 AS saw_3, | ||||
|                         sum(street4Seen)                 AS saw_4, | ||||
|                         sum(sawShowdown)                 AS sd, | ||||
|                         sum(street1Aggr)                 AS aggr_1, | ||||
|                         sum(street2Aggr)                 AS aggr_2, | ||||
|                         sum(street3Aggr)                 AS aggr_3, | ||||
|                         sum(street4Aggr)                 AS aggr_4, | ||||
|                         sum(otherRaisedStreet1)          AS was_raised_1, | ||||
|                         sum(otherRaisedStreet2)          AS was_raised_2, | ||||
|                         sum(otherRaisedStreet3)          AS was_raised_3, | ||||
|                         sum(otherRaisedStreet4)          AS was_raised_4, | ||||
|                         sum(foldToOtherRaisedStreet1)    AS f_freq_1, | ||||
|                         sum(foldToOtherRaisedStreet2)    AS f_freq_2, | ||||
|                         sum(foldToOtherRaisedStreet3)    AS f_freq_3, | ||||
|                         sum(foldToOtherRaisedStreet4)    AS f_freq_4, | ||||
|                         sum(wonWhenSeenStreet1)          AS w_w_s_1, | ||||
|                         sum(wonAtSD)                     AS wmsd, | ||||
|                         sum(stealAttemptChance)          AS steal_opp, | ||||
|                         sum(stealAttempted)              AS steal, | ||||
|                         sum(foldSbToStealChance)         AS SBstolen, | ||||
|                         sum(foldedSbToSteal)             AS SBnotDef, | ||||
|                         sum(foldBbToStealChance)         AS BBstolen, | ||||
|                         sum(foldedBbToSteal)             AS BBnotDef, | ||||
|                         sum(street1CBChance)             AS CB_opp_1, | ||||
|                         sum(street1CBDone)               AS CB_1, | ||||
|                         sum(street2CBChance)             AS CB_opp_2, | ||||
|                         sum(street2CBDone)               AS CB_2, | ||||
|                         sum(street3CBChance)             AS CB_opp_3, | ||||
|                         sum(street3CBDone)               AS CB_3, | ||||
|                         sum(street4CBChance)             AS CB_opp_4, | ||||
|                         sum(street4CBDone)               AS CB_4, | ||||
|                         sum(foldToStreet1CBChance)       AS f_cb_opp_1, | ||||
|                         sum(foldToStreet1CBDone)         AS f_cb_1, | ||||
|                         sum(foldToStreet2CBChance)       AS f_cb_opp_2, | ||||
|                         sum(foldToStreet2CBDone)         AS f_cb_2, | ||||
|                         sum(foldToStreet3CBChance)       AS f_cb_opp_3, | ||||
|                         sum(foldToStreet3CBDone)         AS f_cb_3, | ||||
|                         sum(foldToStreet4CBChance)       AS f_cb_opp_4, | ||||
|                         sum(foldToStreet4CBDone)         AS f_cb_4, | ||||
|                         sum(totalProfit)                 AS net, | ||||
|                         sum(street1CheckCallRaiseChance) AS ccr_opp_1, | ||||
|                         sum(street1CheckCallRaiseDone)   AS ccr_1, | ||||
|                         sum(street2CheckCallRaiseChance) AS ccr_opp_2, | ||||
|                         sum(street2CheckCallRaiseDone)   AS ccr_2, | ||||
|                         sum(street3CheckCallRaiseChance) AS ccr_opp_3, | ||||
|                         sum(street3CheckCallRaiseDone)   AS ccr_3, | ||||
|                         sum(street4CheckCallRaiseChance) AS ccr_opp_4, | ||||
|                         sum(street4CheckCallRaiseDone)   AS ccr_4 | ||||
|                     FROM HudCache, Hands | ||||
|                     WHERE HudCache.PlayerId in  | ||||
|                         (SELECT PlayerId FROM HandsPlayers  | ||||
|                         WHERE handId = %s) | ||||
|                     AND  Hands.id = %s | ||||
|                     AND  HudCache.gametypeId in | ||||
|                         (SELECT gt1.id from Gametypes gt1, Gametypes gt2, Hands | ||||
|                         WHERE  gt1.siteid = gt2.siteid | ||||
|                         AND    gt1.type = gt2.type | ||||
|                         AND    gt1.category = gt2.category | ||||
|                         AND    gt1.limittype = gt2.limittype | ||||
|                         AND    gt2.id = Hands.gametypeId | ||||
|                         AND    Hands.id = %s) | ||||
|                     GROUP BY HudCache.PlayerId | ||||
|                 """ | ||||
|           | ||||
|             self.query['get_players_from_hand'] = """ | ||||
|                     SELECT HandsPlayers.playerId, seatNo, name | ||||
|  |  | |||
							
								
								
									
										412
									
								
								pyfpdb/Tables.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										412
									
								
								pyfpdb/Tables.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							|  | @ -7,7 +7,6 @@ of Table_Window objects representing the windows found. | |||
| """ | ||||
| #    Copyright 2008, Ray E. Barker | ||||
| 
 | ||||
| #     | ||||
| #    This program is free software; you can redistribute it and/or modify | ||||
| #    it under the terms of the GNU General Public License as published by | ||||
| #    the Free Software Foundation; either version 2 of the License, or | ||||
|  | @ -40,7 +39,35 @@ if os.name == 'nt': | |||
| #    FreePokerTools modules | ||||
| import Configuration | ||||
| 
 | ||||
| #    Each TableWindow object must have the following attributes correctly populated: | ||||
| #    tw.name = the table name from the title bar, which must to match the table name | ||||
| #              from the corresponding hand history. | ||||
| #    tw.site = the site name, e.g. PokerStars, FullTilt.  This must match the site | ||||
| #            name specified in the config file. | ||||
| #    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 | ||||
| #                hwnd in Microsoft Windows. | ||||
| #    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  | ||||
| #            the internal width and height, not including the title bar and  | ||||
| #            window borders. | ||||
| #    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 | ||||
| #            title bar and window borders.  To put it another way, this is the  | ||||
| #            screen location of (0, 0) in the working window. | ||||
| 
 | ||||
| class Table_Window: | ||||
|     def __init__(self, info = {}): | ||||
|         if info.has_key('number'): self.number = info['number'] | ||||
|         if info.has_key('exe'):    self.exe    = info['exe'] | ||||
|         if info.has_key('width'):  self.width  = info['width'] | ||||
|         if info.has_key('height'): self.height = info['height'] | ||||
|         if info.has_key('x'):      self.x      = info['x'] | ||||
|         if info.has_key('y'):      self.y      = info['y'] | ||||
|         if info.has_key('site'):   self.site   = info['site'] | ||||
|         if info.has_key('title'):  self.title  = info['title'] | ||||
|         if info.has_key('name'):   self.name   = info['name'] | ||||
| 
 | ||||
|     def __str__(self): | ||||
| #    __str__ method for testing | ||||
|         temp = 'TableWindow object\n' | ||||
|  | @ -51,13 +78,10 @@ class Table_Window: | |||
|             temp = temp + "    tournament = %d\n    table = %d" % (self.tournament, self.table) | ||||
|         return temp | ||||
| 
 | ||||
|     def get_details(table): | ||||
|         table.game = 'razz' | ||||
|         table.max = 8 | ||||
|         table.struture = 'limit' | ||||
|         table.tournament = 0 | ||||
| 
 | ||||
| ############################################################################ | ||||
| #    Top-level discovery routines--these are the modules interface | ||||
| def discover(c): | ||||
|     """Dispatch routine for finding all potential poker client windows.""" | ||||
|     if os.name == 'posix': | ||||
|         tables = discover_posix(c) | ||||
|     elif os.name == 'nt': | ||||
|  | @ -66,86 +90,99 @@ def discover(c): | |||
|         tables = discover_mac(c) | ||||
|     else: | ||||
|         tables = {} | ||||
|      | ||||
|     return(tables) | ||||
|     return tables | ||||
| 
 | ||||
| def discover_table_by_name(c, tablename): | ||||
|     """Dispatch routine for finding poker client windows with the given name.""" | ||||
|     if os.name == 'posix': | ||||
|         table = discover_posix_by_name(c, tablename) | ||||
|         info = discover_posix_by_name(c, tablename) | ||||
|     elif os.name == 'nt': | ||||
|         table = discover_nt_by_name(c, tablename) | ||||
|         info = discover_nt_by_name(c, tablename) | ||||
|     elif os.name == 'mac': | ||||
|         table = discover_mac_by_name(c, tablename) | ||||
|         info = discover_mac_by_name(c, tablename) | ||||
|     else: | ||||
|         table = None | ||||
|     return(table) | ||||
|         return None | ||||
|     if info == None: | ||||
|         return None | ||||
|     return Table_Window(info) | ||||
| 
 | ||||
| def discover_tournament_table(c, tour_number, tab_number): | ||||
|     """Dispatch routine for finding poker clients with tour and table number.""" | ||||
|     if os.name == 'posix': | ||||
|         info = discover_posix_tournament(c, tour_number, tab_number) | ||||
|     elif os.name == 'nt': | ||||
|         info = discover_nt_tournament(c, tour_number, tab_number) | ||||
|     elif os.name == 'mac': | ||||
|         info = discover_mac_tournament(c, tour_number, tab_number) | ||||
|     else: | ||||
|         return None | ||||
|     if info: | ||||
|         return Table_Window(info) | ||||
|     return None | ||||
| 
 | ||||
| ############################################################################# | ||||
| # Posix (= XWindows) specific routines | ||||
| def discover_posix(c): | ||||
|     """    Poker client table window finder for posix/Linux = XWindows.""" | ||||
|     """Poker client table window finder for posix/Linux = XWindows.""" | ||||
|     tables = {} | ||||
|     for listing in os.popen('xwininfo -root -tree').readlines(): | ||||
| #    xwininfo -root -tree -id 0xnnnnn    gets the info on a single window | ||||
|         if re.search('Lobby', listing):                            continue | ||||
|         if re.search('Instant Hand History', listing):             continue | ||||
|         if not re.search('Logged In as ', listing, re.IGNORECASE): continue | ||||
|         if re.search('\"Full Tilt Poker\"', listing):              continue # FTP Lobby | ||||
|         for s in c.supported_sites.keys(): | ||||
|             if re.search(c.supported_sites[s].table_finder, listing): | ||||
|                 mo = re.match('\s+([\dxabcdef]+) (.+):.+  (\d+)x(\d+)\+\d+\+\d+  \+(\d+)\+(\d+)', listing) | ||||
|                 if mo.group(2) == '(has no name)': continue | ||||
|                 if re.match('[\(\)\d\s]+', mo.group(2)): continue  # this is a popup | ||||
|                 tw = Table_Window() | ||||
|                 tw.site = c.supported_sites[s].site_name | ||||
|                 tw.number = int(mo.group(1), 0) | ||||
|                 tw.title  = mo.group(2) | ||||
|                 tw.width  = int( mo.group(3) ) | ||||
|                 tw.height = int( mo.group(4) ) | ||||
|                 tw.x      = int (mo.group(5) ) | ||||
|                 tw.y      = int (mo.group(6) ) | ||||
|                 tw.title  = re.sub('\"', '', tw.title) | ||||
| 
 | ||||
| #    use this eval thingie to call the title bar decoder specified in the config file | ||||
|                 eval("%s(tw)" % c.supported_sites[s].decoder) | ||||
|                  | ||||
|         for s in c.get_supported_sites(): | ||||
|             params = c.get_site_parameters(s) | ||||
|             if re.search(params['table_finder'], listing): | ||||
|                 if re.search('Lobby', listing):                continue | ||||
|                 if re.search('Instant Hand History', listing): continue | ||||
|                 if re.search('\"Full Tilt Poker\"', listing):  continue # FTP Lobby | ||||
|                 if re.search('History for table:', listing):   continue | ||||
|                 if re.search('has no name', listing):          continue | ||||
|                 info = decode_xwininfo(c, listing) | ||||
|                 if info['site'] == None:                       continue | ||||
|                 if info['title'] == info['exe']:               continue | ||||
| #    this appears to be a poker client, so make a table object for it | ||||
|                 tw = Table_Window(info) | ||||
|                 eval("%s(tw)" % params['decoder']) | ||||
|                 tables[tw.name] = tw | ||||
|     return tables | ||||
| 
 | ||||
| def discover_posix_by_name(c, tablename): | ||||
|     tables = discover_posix(c) | ||||
|     for t in tables: | ||||
|         if tables[t].name.find(tablename) > -1: | ||||
|             return tables[t] | ||||
|     return None | ||||
|     """Find an XWindows poker client of the given name.""" | ||||
|     for listing in os.popen('xwininfo -root -tree').readlines(): | ||||
|         if re.search(tablename, listing): | ||||
|             if re.search('History for table:', listing): continue | ||||
|             info = decode_xwininfo(c, listing) | ||||
|             if not info['name'] == tablename:            continue | ||||
|             return info | ||||
|     return False | ||||
| 
 | ||||
| # | ||||
| #    The discover_xx functions query the system and report on the poker clients  | ||||
| #    currently displayed on the screen.  The discover_posix should give you  | ||||
| #    some idea how to support other systems. | ||||
| # | ||||
| #    discover_xx() returns a dict of TableWindow objects--one TableWindow | ||||
| #    object for each poker client table on the screen. | ||||
| # | ||||
| #    Each TableWindow object must have the following attributes correctly populated: | ||||
| #    tw.site = the site name, e.g. PokerStars, FullTilt.  This must match the site | ||||
| #            name specified in the config file. | ||||
| #    tw.number = This is the system id number for the client table window in the  | ||||
| #            format that the system presents it. | ||||
| #    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  | ||||
| #            the internal width and height, not including the title bar and  | ||||
| #            window borders. | ||||
| #    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 | ||||
| #            title bar and window borders.  To put it another way, this is the  | ||||
| #            screen location of (0, 0) in the working window. | ||||
| def discover_posix_tournament(c, t_number, s_number): | ||||
|     """Finds the X window for a client, given tournament and table nos.""" | ||||
|     search_string = "%s.+Table\s%s" % (t_number, s_number) | ||||
|     for listing in os.popen('xwininfo -root -tree').readlines(): | ||||
|         if re.search(search_string, listing): | ||||
|             return decode_xwininfo(c, listing) | ||||
|     return False | ||||
| 
 | ||||
| def win_enum_handler(hwnd, titles): | ||||
|     titles[hwnd] = win32gui.GetWindowText(hwnd) | ||||
|    | ||||
| 
 | ||||
| def child_enum_handler(hwnd, children): | ||||
|     print hwnd, win32.GetWindowRect(hwnd) | ||||
| def decode_xwininfo(c, info_string): | ||||
|     """Gets window parameters from xwinifo string--XWindows.""" | ||||
|     info = {} | ||||
|     mo = re.match('\s+([\dxabcdef]+) (.+):\s\(\"([a-zA-Z.]+)\".+  (\d+)x(\d+)\+\d+\+\d+  \+(\d+)\+(\d+)', info_string) | ||||
|     if not mo: | ||||
|         return None | ||||
|     else: | ||||
|         info['number'] = int( mo.group(1), 0) | ||||
|         info['exe']    = mo.group(3) | ||||
|         info['width']  = int( mo.group(4) ) | ||||
|         info['height'] = int( mo.group(5) ) | ||||
|         info['x']      = int( mo.group(6) ) | ||||
|         info['y']      = int( mo.group(7) ) | ||||
|         info['site']   = get_site_from_exe(c, info['exe']) | ||||
|         info['title']  = re.sub('\"', '', mo.group(2)) | ||||
|         title_bits     = re.split(' - ', info['title']) | ||||
|         info['name']   = clean_title(title_bits[0]) | ||||
|     return info | ||||
| 
 | ||||
| ############################################################################## | ||||
| #    NT (= Windows) specific routines | ||||
| def discover_nt(c): | ||||
|     """    Poker client table window finder for Windows.""" | ||||
| # | ||||
|  | @ -185,72 +222,87 @@ def discover_nt(c): | |||
|     return tables | ||||
| 
 | ||||
| def discover_nt_by_name(c, tablename): | ||||
|     # this is pretty much identical to the 'search all windows for all poker sites' code, but made to dig just for a specific table name | ||||
|     # it could be implemented a bunch better - and we need to not assume the width/height thing that (steffen?) assumed above, we should | ||||
|     # be able to dig up the window's titlebar handle and get it's information, and such .. but.. for now, i guess this will work. | ||||
|     # - eric | ||||
|     """Finds poker client window with the given table name.""" | ||||
|     titles = {} | ||||
|     win32gui.EnumWindows(win_enum_handler, titles) | ||||
|     for hwnd in titles.keys(): | ||||
|         if titles[hwnd].find(tablename) == -1: continue | ||||
|         if titles[hwnd].find("History for table:") > -1: continue | ||||
|         if titles[hwnd].find("HUD:") > -1: continue | ||||
|         return decode_windows(c, titles[hwnd], hwnd) | ||||
|     return False | ||||
| 
 | ||||
| def discover_nt_tournament(c, tour_number, tab_number): | ||||
|     """Finds the Windows window handle for the given tournament/table.""" | ||||
|     search_string = "%s.+%s" % (tour_number, tab_number) | ||||
| 
 | ||||
|     titles ={} | ||||
|     win32gui.EnumWindows(win_enum_handler, titles) | ||||
|     for hwnd in titles.keys(): | ||||
|         if re.search(search_string, titles[hwnd]): | ||||
|             return decode_windows(c, titles[hwnd], hwnd) | ||||
|     return False | ||||
| 
 | ||||
| def get_nt_exe(hwnd): | ||||
|     """Finds the name of the executable that the given window handle belongs to.""" | ||||
|     processid = win32process.GetWindowThreadProcessId(hwnd) | ||||
|     pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1]) | ||||
|     return win32process.GetModuleFileNameEx(pshandle, 0) | ||||
| 
 | ||||
| def decode_windows(c, title, hwnd): | ||||
|     """Gets window parameters from the window title and handle--Windows.""" | ||||
| 
 | ||||
| #    I cannot figure out how to get the inside dimensions of the poker table | ||||
| #    windows.  So I just assume all borders are 3 thick and all title bars | ||||
| #    are 29 high.  No doubt this will be off when used with certain themes. | ||||
|     b_width = 3 | ||||
|     tb_height = 29 | ||||
|     titles = {} | ||||
| #    tables = discover_nt(c) | ||||
|     win32gui.EnumWindows(win_enum_handler, titles) | ||||
|     for s in c.supported_sites.keys(): | ||||
|         for hwnd in titles.keys(): | ||||
|             processid = win32process.GetWindowThreadProcessId(hwnd) | ||||
|             pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1]) | ||||
|             exe = win32process.GetModuleFileNameEx(pshandle, 0) | ||||
|             if exe.find(c.supported_sites[s].table_finder) == -1: | ||||
|                 continue | ||||
|             if titles[hwnd].find(tablename) > -1: | ||||
|                 if titles[hwnd].find("History for table:") > -1 or titles[hwnd].find("FPDBHUD") > -1: | ||||
|                     continue | ||||
|                 tw = Table_Window() | ||||
|                 tw.number = hwnd | ||||
|                 (x, y, width, height) = win32gui.GetWindowRect(hwnd) | ||||
|                 tw.title = titles[hwnd] | ||||
|                 tw.width = int(width) - 2 * b_width | ||||
|                 tw.height = int(height) - b_width - tb_height | ||||
|                 tw.x = int(x) + b_width | ||||
|                 tw.y = int(y) + tb_height | ||||
|                 tw.site = c.supported_sites[s].site_name | ||||
|                 if not tw.site == "Unknown" and not c.supported_sites[tw.site].decoder == "Unknown": | ||||
|                     eval("%s(tw)" % c.supported_sites[tw.site].decoder) | ||||
|                 else: | ||||
|                     tw.name = tablename | ||||
|                 return tw | ||||
| 
 | ||||
|     # if we don't find anything by process name, let's search one more time, and call it Unknown ? | ||||
|     for hwnd in titles.keys(): | ||||
|         if titles[hwnd].find(tablename) > -1: | ||||
|             if titles[hwnd].find("History for table:") > -1 or titles[hwnd].find("FPDBHUD") > -1: | ||||
|                 continue | ||||
|             tw = Table_Window() | ||||
|             tw.number = hwnd | ||||
|             (x, y, width, height) = win32gui.GetWindowRect(hwnd) | ||||
|             tw.title = titles[hwnd] | ||||
|             tw.width = int(width) - 2 * b_width | ||||
|             tw.height = int(height) - b_width - tb_height | ||||
|             tw.x = int(x) + b_width | ||||
|             tw.y = int(y) + tb_height | ||||
|             tw.site = "Unknown" | ||||
|             tw.name = tablename | ||||
|             return tw | ||||
|     info = {} | ||||
|     info['number'] = hwnd | ||||
|     info['title'] = re.sub('\"', '', title) | ||||
|     (x, y, width, height) = win32gui.GetWindowRect(hwnd) | ||||
| 
 | ||||
|     info['x']      = int(x)  + b_width | ||||
|     info['y']      = int( y ) + tb_height | ||||
|     info['width']  = int( width ) - 2*b_width | ||||
|     info['height'] = int( height ) - b_width - tb_height | ||||
|     info['exe']    = get_nt_exe(hwnd) | ||||
| 
 | ||||
|     title_bits = re.split(' - ', info['title']) | ||||
|     info['name'] = title_bits[0] | ||||
|     info['site']   = get_site_from_exe(c, info['exe']) | ||||
| 
 | ||||
|     return info | ||||
| 
 | ||||
| def win_enum_handler(hwnd, titles): | ||||
|     titles[hwnd] = win32gui.GetWindowText(hwnd) | ||||
|    | ||||
| ################################################################### | ||||
| #    Utility routines used by all the discoverers. | ||||
| def get_site_from_exe(c, exe): | ||||
|     """Look up the site from config, given the exe.""" | ||||
|     for s in c.get_supported_sites(): | ||||
|         params = c.get_site_parameters(s) | ||||
|         if re.search(params['table_finder'], exe): | ||||
|             return params['site_name'] | ||||
|     return None | ||||
| 
 | ||||
| def discover_mac(c): | ||||
|     """    Poker client table window finder for Macintosh.""" | ||||
|     tables = {} | ||||
|     return tables | ||||
| 
 | ||||
| def discover_mac_by_name(c, tablename): | ||||
|     # again, i have no mac to test this on, sorry -eric | ||||
|     return discover_mac(c) | ||||
| 
 | ||||
| def clean_title(name): | ||||
|     """Clean the little info strings from the table name.""" | ||||
| #    these strings could go in a config file | ||||
|     for pattern in [' \(6 max\)', ' \(heads up\)', ' \(deep\)', | ||||
|                 ' \(deep hu\)', ' \(deep 6\)', ' \(2\)', | ||||
|                 ' \(edu\)', ' \(edu, 6 max\)', ' \(6\)', | ||||
|                 ' no all-in', ' fast', ',', ' 50BB min', '\s+$']: | ||||
|         name = re.sub(pattern, '', name) | ||||
|     name = name.rstrip() | ||||
|     return name | ||||
| 
 | ||||
| def pokerstars_decode_table(tw): | ||||
| #    extract the table name OR the tournament number and table name from the title | ||||
| #    other info in title is redundant with data in the database  | ||||
| #    Extract poker information from the window title.  This is not needed for | ||||
| #    fpdb, since all that information is available in the db via new_hand_number. | ||||
| #    This is needed only when using the HUD with a backend less integrated. | ||||
|     title_bits = re.split(' - ', tw.title) | ||||
|     name = title_bits[0] | ||||
|     mo = re.search('Tournament (\d+) Table (\d+)', name) | ||||
|  | @ -260,12 +312,8 @@ def pokerstars_decode_table(tw): | |||
|         tw.name       = name | ||||
|     else: | ||||
|         tw.tournament = None | ||||
|         for pattern in [' no all-in', ' fast', ',', ' 50BB min']: | ||||
|             name = re.sub(pattern, '', name) | ||||
|         name = re.sub('\s+$', '', name) | ||||
|         tw.name = name | ||||
| 
 | ||||
|     mo = re.search('(Razz|Stud H/L|Stud|Omaha H/L|Omaha|Hold\'em|5-Card Draw|Triple Draw 2-7 Lowball)', tw.title) | ||||
|         tw.name = clean_title(name) | ||||
|     mo = re.search('(Razz|Stud H/L|Stud|Omaha H/L|Omaha|Hold\'em|5-Card Draw|Triple Draw 2-7 Lowball|Badugi)', tw.title) | ||||
|      | ||||
|     tw.game = mo.group(1).lower() | ||||
|     tw.game = re.sub('\'', '', tw.game) | ||||
|  | @ -288,25 +336,103 @@ def pokerstars_decode_table(tw): | |||
|         pass | ||||
| 
 | ||||
| def fulltilt_decode_table(tw): | ||||
| #    extract the table name OR the tournament number and table name from the title | ||||
| #    other info in title is redundant with data in the database  | ||||
| #    Extract poker information from the window title.  This is not needed for | ||||
| #    fpdb, since all that information is available in the db via new_hand_number. | ||||
| #    This is needed only when using the HUD with a backend less integrated. | ||||
|     title_bits = re.split(' - ', tw.title) | ||||
|     name = title_bits[0] | ||||
|     tw.tournament = None | ||||
|     for pattern in [' (6 max)', ' (heads up)', ' (deep)', | ||||
|                     ' (deep hu)', ' (deep 6)', ' (2)', | ||||
|                     ' (edu)', ' (edu, 6 max)', ' (6)' ]: | ||||
|     tw.name = clean_title(name) | ||||
| 
 | ||||
| def clean_title(name): | ||||
|     """Clean the little info strings from the table name.""" | ||||
| #    these strings could go in a config file | ||||
|     for pattern in [' \(6 max\)', ' \(heads up\)', ' \(deep\)', | ||||
|                 ' \(deep hu\)', ' \(deep 6\)', ' \(2\)', | ||||
|                 ' \(edu\)', ' \(edu, 6 max\)', ' \(6\)', | ||||
|                 ' no all-in', ' fast', ',', ' 50BB min', '\s+$']: | ||||
|         name = re.sub(pattern, '', name) | ||||
| #    (tw.name, trash) = name.split(r' (', 1) | ||||
|     tw.name = name.rstrip() | ||||
|     name = name.rstrip() | ||||
|     return name | ||||
| 
 | ||||
| ########################################################################### | ||||
| #    Mac specific routines....all stubs for now | ||||
| def discover_mac_tournament(c, tour_number, tab_number): | ||||
|     """Mac users need help.""" | ||||
|     return None | ||||
| 
 | ||||
| def discover_mac(c): | ||||
|     """Poker client table window finder for Macintosh.""" | ||||
|     tables = {} | ||||
|     return tables | ||||
| 
 | ||||
| def discover_mac_by_name(c, tablename): | ||||
|     """Oh, the humanity.""" | ||||
|     # again, i have no mac to test this on, sorry -eric | ||||
|     return None | ||||
| 
 | ||||
| #def discover_nt_by_name(c, tablename): | ||||
| #    # this is pretty much identical to the 'search all windows for all poker sites' code, but made to dig just for a specific table name | ||||
| #    # it could be implemented a bunch better - and we need to not assume the width/height thing that (steffen?) assumed above, we should | ||||
| #    # be able to dig up the window's titlebar handle and get it's information, and such .. but.. for now, i guess this will work. | ||||
| #    # - eric | ||||
| #    b_width = 3 | ||||
| #    tb_height = 29 | ||||
| #    titles = {} | ||||
| ##    tables = discover_nt(c) | ||||
| #    win32gui.EnumWindows(win_enum_handler, titles) | ||||
| #    for s in c.supported_sites.keys(): | ||||
| #        for hwnd in titles.keys(): | ||||
| #            processid = win32process.GetWindowThreadProcessId(hwnd) | ||||
| #            pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1]) | ||||
| #            exe = win32process.GetModuleFileNameEx(pshandle, 0) | ||||
| #            if exe.find(c.supported_sites[s].table_finder) == -1: | ||||
| #                continue | ||||
| #            if titles[hwnd].find(tablename) > -1: | ||||
| #                if titles[hwnd].find("History for table:") > -1 or titles[hwnd].find("FPDBHUD") > -1: | ||||
| #                    continue | ||||
| #                tw = Table_Window() | ||||
| #                tw.number = hwnd | ||||
| #                (x, y, width, height) = win32gui.GetWindowRect(hwnd) | ||||
| #                tw.title = titles[hwnd] | ||||
| #                tw.width = int(width) - 2 * b_width | ||||
| #                tw.height = int(height) - b_width - tb_height | ||||
| #                tw.x = int(x) + b_width | ||||
| #                tw.y = int(y) + tb_height | ||||
| #                tw.site = c.supported_sites[s].site_name | ||||
| #                if not tw.site == "Unknown" and not c.supported_sites[tw.site].decoder == "Unknown": | ||||
| #                    eval("%s(tw)" % c.supported_sites[tw.site].decoder) | ||||
| #                else: | ||||
| #                    tw.name = tablename | ||||
| #                return tw | ||||
| #     | ||||
| #    # if we don't find anything by process name, let's search one more time, and call it Unknown ? | ||||
| #    for hwnd in titles.keys(): | ||||
| #        if titles[hwnd].find(tablename) > -1: | ||||
| #            if titles[hwnd].find("History for table:") > -1 or titles[hwnd].find("FPDBHUD") > -1: | ||||
| #                continue | ||||
| #            tw = Table_Window() | ||||
| #            tw.number = hwnd | ||||
| #            (x, y, width, height) = win32gui.GetWindowRect(hwnd) | ||||
| #            tw.title = titles[hwnd] | ||||
| #            tw.width = int(width) - 2 * b_width | ||||
| #            tw.height = int(height) - b_width - tb_height | ||||
| #            tw.x = int(x) + b_width | ||||
| #            tw.y = int(y) + tb_height | ||||
| #            tw.site = "Unknown" | ||||
| #            tw.name = tablename | ||||
| #            return tw | ||||
| #     | ||||
| #    return None | ||||
| 
 | ||||
| if __name__=="__main__": | ||||
|     c = Configuration.Config() | ||||
|     print discover_table_by_name(c, "Catacaos") | ||||
|     tables = discover(c) | ||||
| 
 | ||||
|     print discover_table_by_name(c, "Ostara V") | ||||
|     print discover_tournament_table(c, "118942908", "3") | ||||
| 
 | ||||
|     tables = discover(c) | ||||
|     for t in tables.keys(): | ||||
|         print "t = ", t | ||||
|         print tables[t] | ||||
| 
 | ||||
|     print "press enter to continue" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user