Coverage for TableWindow.py: 15%
136 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 18:50 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 18:50 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""Base class for interacting with poker client windows.
5There are currently subclasses for X, OSX, and Windows.
7The class queries the poker client window for data of interest, such as
8size and location. It also controls the signals to alert the HUD when the
9client has been resized, destroyed, etc.
10"""
11# Copyright 2008 - 2011, Ray E. Barker
13# This program is free software; you can redistribute it and/or modify
14# it under the terms of the GNU General Public License as published by
15# the Free Software Foundation; either version 2 of the License, or
16# (at your option) any later version.
17#
18# This program is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21# GNU General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write to the Free Software
25# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27########################################################################
30#import L10n
31#_ = L10n.get_translation()
33# Standard Library modules
34import re
35import logging
36from time import sleep
38# FreePokerTools modules
39import Configuration
40from HandHistoryConverter import getTableTitleRe
41from HandHistoryConverter import getTableNoRe
43c = Configuration.Config()
44log = logging.getLogger("hud")
46# Global used for figuring out the current game being played from the title.
47# The dict key is a tuple of (limit type, category) for the game.
48# The list is the names for those games used by the supported poker sites
49# This is currently only used for mixed games, so it only needs to support those
50# games on PokerStars and Full Tilt.
51nlpl_game_names = { #fpdb name Stars Name FTP Name (if different)
52 ("nl", "holdem" ) : ("No Limit Hold\'em" , ),
53 ("pl", "holdem" ) : ("Pot Limit Hold\'em" , ),
54 ("pl", "omahahi" ) : ("Pot Limit Omaha" ,"Pot Limit Omaha Hi" ),
55 }
56limit_game_names = { #fpdb name Stars Name FTP Name
57 ("fl", "holdem" ) : ("Limit Hold\'em" , ),
58 ("fl", "omahahilo" ) : ("Limit Omaha H/L" , ),
59 ("fl", "studhilo" ) : ("Limit Stud H/L" , ),
60 ("fl", "razz" ) : ("Limit Razz" , ),
61 ("fl", "studhi" ) : ("Limit Stud" , "Stud Hi"),
62 ("fl", "27_3draw" ) : ("Limit Triple Draw 2-7 Lowball", )
63 }
65# A window title might have our table name + one of these words/
66# phrases. If it has this word in the title, it is not a table.
67bad_words = ('History for table:', 'HUD:', 'Chat:', 'FPDBHUD', 'Lobby')
69# Each TableWindow object must have the following attributes correctly populated:
70# tw.name = the table name from the title bar, which must to match the table name
71# from the corresponding hand record in the db.
72# tw.number = This is the system id number for the client table window in the
73# format that the system presents it. This is Xid in Xwindows and
74# hwnd in Microsoft Windows.
75# tw.title = The full title from the window title bar.
76# tw.width, tw.height = The width and height of the window in pixels. This is
77# the internal width and height, not including the title bar and
78# window borders.
79# tw.x, tw.y = The x, y (horizontal, vertical) location of the window relative
80# to the top left of the display screen. This also does not include the
81# title bar and window borders. To put it another way, this is the
82# screen location of (0, 0) in the working window.
83# tournament = Tournament number for a tournament or None for a cash game.
84# table = Table number for a tournament.
85# gdkhandle =
86# window =
87# parent =
88# game =
89# search_string =
91class Table_Window(object):
92 def __init__(self, config, site, table_name = None, tournament = None, table_number = None):
94 self.config = config
95 self.site = site
96 self.hud = None # fill in later
97 self.gdkhandle = None
98 self.number = None
99 if tournament is not None and table_number is not None:
100 print(tournament)
101 self.tournament = int(tournament)
102 print(' tournement:')
103 print(self.tournament)
104 print('table_number:')
105 print(type(table_number))
106 print(table_number)
107 #temp bug correction for ipoker must investigate
108 #if table_number is not an interger
110 print('table_number error:')
111 print(type(table_number))
112 print(table_number)
113 self.table = int(table_number)
114 print(self.table)
115 self.name = "%s - %s" % (self.tournament, self.table)
116 self.type = "tour"
117 table_kwargs = dict(tournament = self.tournament, table_number = self.table)
118 self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament)
119 elif table_name is not None:
121 print('table_number cash:')
122 print(type(table_name))
123 print((table_name))
124 self.name = table_name
125 self.type = "cash"
126 self.tournament = None
127 table_kwargs = dict(table_name = table_name)
128 print('table_kwarg cash:')
129 print(type(table_kwargs))
130 print((table_kwargs))
131 else:
132 return None
134 self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs)
135 log.debug(f"search string: {self.search_string}")
136 # make a small delay otherwise Xtables.root.get_windows()
137 # returns empty for unknown reasons
138 sleep(0.1)
140 self.find_table_parameters()
141 if not self.number:
142 log.error(("Can't find table \"%s\" with search string \"%s\""), table_name, self.search_string)
145 geo = self.get_geometry()
146 if geo is None: return None
147 self.width = geo['width']
148 self.height = geo['height']
149 self.x = geo['x']
150 print(self.x)
151 self.y = geo['y']
152 print(self.y)
153 self.oldx = self.x # attn ray: remove these two lines and update Hud.py::update_table_position()
154 print(self.oldx)
155 self.oldy = self.y
156 print(self.oldy)
157 self.game = self.get_game()
159 def __str__(self):
160 likely_attrs = ("number", "title", "site", "width", "height", "x", "y",
161 "tournament", "table", "gdkhandle", "window", "parent",
162 "key", "hud", "game", "search_string", "tableno_re")
163 temp = 'TableWindow object\n'
164 for a in likely_attrs:
165 if getattr(self, a, 0):
166 temp += " %s = %s\n" % (a, getattr(self, a))
167 return temp
169####################################################################
170# "get" methods. These query the table and return the info to get.
171# They don't change the data in the table and are generally used
172# by the "check" methods. Most of the get methods are in the
173# subclass because they are specific to X, Windows, etc.
174 def get_game(self):
175# title = self.get_window_title()
176# if title is None:
177# return False
178 title = self.title
180# check for nl and pl games first, to avoid bad matches
181 for game, names in list(nlpl_game_names.items()):
182 for name in names:
183 if name in title:
184 return game
185 for game, names in list(limit_game_names.items()):
186 for name in names:
187 if name in title:
188 return game
189 return False
191 def get_table_no(self):
192 new_title = self.get_window_title()
193 log.debug(f"new table title: {new_title}")
194 if new_title is None:
195 return False
197 try:
198 log.debug(f"before searching: {new_title}")
199 mo = re.search(self.tableno_re, new_title)
200 except AttributeError: #'Table' object has no attribute 'tableno_re'
201 log.debug(f"'Table' object has no attribute 'tableno_re'")
202 return False
204 if mo is not None:
205 return int(mo.group(1))
206 return False
208####################################################################
209# check_table() is meant to be called by the hud periodically to
210# determine if the client has been moved or resized. check_table()
211# also checks and signals if the client has been closed.
212 def check_table(self):
213 return self.check_size() or self.check_loc()
215####################################################################
216# "check" methods. They use the corresponding get method, update the
217# table object and return the name of the signal to be emitted or
218# False if unchanged. These do not signal for destroyed
219# clients to prevent a race condition.
221# These might be called by a Window.timeout, so they must not
222# return False, or the timeout will be cancelled.
223 def check_size(self):
224 new_geo = self.get_geometry()
225 if new_geo is None: # window destroyed
226 return "client_destroyed"
228 elif self.width != new_geo['width'] or self.height != new_geo['height']: # window resized
229 self.oldwidth = self.width
230 self.width = new_geo['width']
231 self.oldheight = self.height
232 self.height = new_geo['height']
233 return "client_resized"
234 return False # no change
236 def check_loc(self):
237 new_geo = self.get_geometry()
238 if new_geo is None: # window destroyed
239 return "client_destroyed"
241 if self.x != new_geo['x'] or self.y != new_geo['y']: # window moved
242 self.x = new_geo['x']
243 self.y = new_geo['y']
244 return "client_moved"
245 return False # no change
247 def has_table_title_changed(self, hud):
248 log.debug(f"before get_table_no()")
249 result = self.get_table_no()
250 log.debug(f"tb has change nb {result}")
251 if result is not False and result != self.table:
252 log.debug(f"compare result and self.table {result} {self.table}")
253 self.table = result
254 if hud is not None:
255 log.debug(f"return True")
256 return True
257 log.debug(f"return False")
258 return False
260 def check_bad_words(self, title):
261 for word in bad_words:
262 if word in title: return True
263 return False