Coverage for TableWindow.py: 15%

136 statements  

« 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. 

4 

5There are currently subclasses for X, OSX, and Windows. 

6 

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 

12 

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 

26 

27######################################################################## 

28 

29 

30#import L10n 

31#_ = L10n.get_translation() 

32 

33# Standard Library modules 

34import re 

35import logging 

36from time import sleep 

37 

38# FreePokerTools modules 

39import Configuration 

40from HandHistoryConverter import getTableTitleRe 

41from HandHistoryConverter import getTableNoRe 

42 

43c = Configuration.Config() 

44log = logging.getLogger("hud") 

45 

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 } 

64 

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') 

68 

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 =  

90 

91class Table_Window(object): 

92 def __init__(self, config, site, table_name = None, tournament = None, table_number = None): 

93 

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 

109 

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: 

120 

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 

133 

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) 

139 

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) 

143 

144 

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() 

158 

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 

168 

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 

179 

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 

190 

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 

196 

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 

203 

204 if mo is not None: 

205 return int(mo.group(1)) 

206 return False 

207 

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() 

214 

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. 

220 

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" 

227 

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 

235 

236 def check_loc(self): 

237 new_geo = self.get_geometry() 

238 if new_geo is None: # window destroyed 

239 return "client_destroyed" 

240 

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 

246 

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 

259 

260 def check_bad_words(self, title): 

261 for word in bad_words: 

262 if word in title: return True 

263 return False