Merge branch 'master' of git://git.assembla.com/free_poker_tools

This commit is contained in:
Worros 2010-11-23 13:00:58 +08:00
commit aa31a4d67b
4 changed files with 65 additions and 51 deletions

View File

@ -24,9 +24,6 @@
Main for FreePokerTools HUD. Main for FreePokerTools HUD.
""" """
# TODO allow window resizing # TODO allow window resizing
# TODO hud to echo, but ignore non numbers
# TODO no stat window for hero
# TODO things to add to config.xml
# Standard Library modules # Standard Library modules
import sys import sys
@ -39,26 +36,21 @@ import traceback
import thread import thread
import time import time
import string import string
import re
# pyGTK modules # pyGTK modules
import pygtk
import gtk import gtk
import gobject import gobject
# FreePokerTools modules # FreePokerTools modules
import Configuration import Configuration
import Database import Database
from HandHistoryConverter import getTableTitleRe import Hud
# get the correct module for the current os # get the correct module for the current os
if os.name == 'posix': if os.name == 'posix':
import XTables as Tables import XTables as Tables
elif os.name == 'nt': elif os.name == 'nt':
import WinTables as Tables import WinTables as Tables
#import Tables
import Hud
import locale import locale
lang = locale.getdefaultlocale()[0][0:2] lang = locale.getdefaultlocale()[0][0:2]
@ -79,7 +71,6 @@ else:
c = Configuration.Config(file=options.config, dbname=options.dbname) c = Configuration.Config(file=options.config, dbname=options.dbname)
log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt') log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt')
class HUD_main(object): class HUD_main(object):
"""A main() object to own both the read_stdin thread and the gui.""" """A main() object to own both the read_stdin thread and the gui."""
# This class mainly provides state for controlling the multiple HUDs. # This class mainly provides state for controlling the multiple HUDs.
@ -144,14 +135,13 @@ class HUD_main(object):
pass pass
def client_destroyed(self, widget, hud): # call back for terminating the main eventloop def client_destroyed(self, widget, hud): # call back for terminating the main eventloop
self.kill_hud(None, hud.table.name) self.kill_hud(None, hud.table.key)
def game_changed(self, widget, hud): def game_changed(self, widget, hud):
print _("hud_main: Game changed.") print _("hud_main: Game changed.")
def table_changed(self, widget, hud): def table_changed(self, widget, hud):
print _("hud_main: Table changed.") self.kill_hud(None, hud.table.key)
self.kill_hud(None, hud.table.name)
def destroy(self, *args): # call back for terminating the main eventloop def destroy(self, *args): # call back for terminating the main eventloop
log.info(_("Terminating normally.")) log.info(_("Terminating normally."))
@ -159,12 +149,24 @@ class HUD_main(object):
def kill_hud(self, event, table): def kill_hud(self, event, table):
# called by an event in the HUD, to kill this specific HUD # called by an event in the HUD, to kill this specific HUD
if table in self.hud_dict:
self.hud_dict[table].kill() # This method can be called by either gui or non-gui thread. It doesn't
self.hud_dict[table].main_window.destroy() # cost much to always do it in a thread-safe manner.
self.vb.remove(self.hud_dict[table].tablehudlabel) def idle():
del(self.hud_dict[table]) gtk.gdk.threads_enter()
self.main_window.resize(1, 1) try:
if table in self.hud_dict:
self.hud_dict[table].kill()
self.hud_dict[table].main_window.destroy()
self.vb.remove(self.hud_dict[table].tablehudlabel)
del(self.hud_dict[table])
self.main_window.resize(1, 1)
except:
pass
finally:
gtk.gdk.threads_leave()
gobject.idle_add(idle)
def check_tables(self): def check_tables(self):
for hud in self.hud_dict.keys(): for hud in self.hud_dict.keys():
@ -178,42 +180,42 @@ class HUD_main(object):
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
table.gdkhandle = gtk.gdk.window_foreign_new(table.number)
newlabel = gtk.Label("%s - %s" % (table.site, table_name)) newlabel = gtk.Label("%s - %s" % (table.site, table_name))
self.vb.add(newlabel) self.vb.add(newlabel)
newlabel.show() newlabel.show()
self.main_window.resize_children() self.main_window.resize_children()
self.hud_dict[table_name].tablehudlabel = newlabel self.hud_dict[table.key].tablehudlabel = newlabel
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards) self.hud_dict[table.key].create(new_hand_id, self.config, stat_dict, cards)
for m in self.hud_dict[table_name].aux_windows: for m in self.hud_dict[table.key].aux_windows:
m.create() m.create()
m.update_gui(new_hand_id) m.update_gui(new_hand_id)
self.hud_dict[table_name].update(new_hand_id, self.config) self.hud_dict[table.key].update(new_hand_id, self.config)
self.hud_dict[table_name].reposition_windows() self.hud_dict[table.key].reposition_windows()
except: except:
log.error("*** Exception in HUD_main::idle_func() *** " + str(sys.exc_info())) log.error("*** Exception in HUD_main::idle_func() *** " + str(sys.exc_info()))
for e in traceback.format_tb(sys.exc_info()[2]): for e in traceback.format_tb(sys.exc_info()[2]):
log.error(e) log.error(e)
finally: finally:
gtk.gdk.threads_leave() gtk.gdk.threads_leave()
return False return False
self.hud_dict[table_name] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection)
self.hud_dict[table_name].table_name = table_name
self.hud_dict[table_name].stat_dict = stat_dict
self.hud_dict[table_name].cards = cards
self.hud_dict[table.key] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection)
self.hud_dict[table.key].table_name = table_name
self.hud_dict[table.key].stat_dict = stat_dict
self.hud_dict[table.key].cards = cards
table.hud = self.hud_dict[table.key]
# set agg_bb_mult so that aggregate_tour and aggregate_ring can be ignored, # set agg_bb_mult so that aggregate_tour and aggregate_ring can be ignored,
# agg_bb_mult == 1 means no aggregation after these if statements: # agg_bb_mult == 1 means no aggregation after these if statements:
if type == "tour" and self.hud_params['aggregate_tour'] == False: if type == "tour" and self.hud_params['aggregate_tour'] == False:
self.hud_dict[table_name].hud_params['agg_bb_mult'] = 1 self.hud_dict[table.key].hud_params['agg_bb_mult'] = 1
elif type == "ring" and self.hud_params['aggregate_ring'] == False: elif type == "ring" and self.hud_params['aggregate_ring'] == False:
self.hud_dict[table_name].hud_params['agg_bb_mult'] = 1 self.hud_dict[table.key].hud_params['agg_bb_mult'] = 1
if type == "tour" and self.hud_params['h_aggregate_tour'] == False: if type == "tour" and self.hud_params['h_aggregate_tour'] == False:
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1 self.hud_dict[table.key].hud_params['h_agg_bb_mult'] = 1
elif type == "ring" and self.hud_params['h_aggregate_ring'] == False: elif type == "ring" and self.hud_params['h_aggregate_ring'] == False:
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1 self.hud_dict[table.key].hud_params['h_agg_bb_mult'] = 1
# sqlcoder: I forget why these are set to true (aren't they ignored from now on?) # sqlcoder: I forget why these are set to true (aren't they ignored from now on?)
# but I think it's needed: # but I think it's needed:
self.hud_params['aggregate_ring'] = True self.hud_params['aggregate_ring'] = True
@ -222,7 +224,7 @@ class HUD_main(object):
self.hud_params['aggregate_tour'] = True self.hud_params['aggregate_tour'] = True
self.hud_params['h_aggregate_tour'] = True self.hud_params['h_aggregate_tour'] = True
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[table_name].aux_windows] [aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[table.key].aux_windows]
gobject.idle_add(idle_func) gobject.idle_add(idle_func)
def update_HUD(self, new_hand_id, table_name, config): def update_HUD(self, new_hand_id, table_name, config):
@ -268,6 +270,8 @@ class HUD_main(object):
self.destroy() self.destroy()
break # this thread is not always killed immediately with gtk.main_quit() break # this thread is not always killed immediately with gtk.main_quit()
# This block cannot be hoisted outside the while loop, because it would
# cause a problem when auto importing into an empty db.
if not found: if not found:
for site in self.config.get_supported_sites(): for site in self.config.get_supported_sites():
result = self.db_connection.get_site_id(site) result = self.db_connection.get_site_id(site)
@ -355,9 +359,10 @@ class HUD_main(object):
log.info(_("HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f,%4.3f,%4.3f)") log.info(_("HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f,%4.3f,%4.3f)")
% (t6 - t0,t1 - t0,t2 - t0,t3 - t0,t4 - t0,t5 - t0,t6 - t0)) % (t6 - t0,t1 - t0,t2 - t0,t3 - t0,t4 - t0,t5 - t0,t6 - t0))
self.db_connection.connection.rollback() self.db_connection.connection.rollback()
# if type == "tour":
# tablewindow.check_table_no(None) if type == "tour":
# # Ray!! tablewindow::check_table_no expects a HUD as an argument! self.hud_dict[temp_key].table.check_table_no(self.hud_dict[temp_key])
if __name__== "__main__": if __name__== "__main__":
# start the HUD_main object # start the HUD_main object

View File

@ -415,9 +415,12 @@ class Aux_Seats(Aux_Window):
# Methods likely to be of use for any Seat_Window implementation # Methods likely to be of use for any Seat_Window implementation
def destroy(self): def destroy(self):
"""Destroy all of the seat windows.""" """Destroy all of the seat windows."""
for i in self.m_windows.keys(): try:
self.m_windows[i].destroy() for i in self.m_windows.keys():
del(self.m_windows[i]) self.m_windows[i].destroy()
del(self.m_windows[i])
except AttributeError:
pass
# Methods likely to be useful for mucked card windows (or similar) only # Methods likely to be useful for mucked card windows (or similar) only
def hide(self): def hide(self):

View File

@ -116,6 +116,7 @@ class Table_Window(object):
self.config = config self.config = config
self.site = site self.site = site
self.hud = None # fill in later
if tournament is not None and table_number is not None: if tournament is not None and table_number is not None:
self.tournament = int(tournament) self.tournament = int(tournament)
self.table = int(table_number) self.table = int(table_number)
@ -123,11 +124,13 @@ class Table_Window(object):
self.type = "tour" self.type = "tour"
table_kwargs = dict(tournament = self.tournament, table_number = self.table) table_kwargs = dict(tournament = self.tournament, table_number = self.table)
self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament) self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament)
self.key = tournament # used as key for the hud_dict in HUD_main
elif table_name is not None: elif table_name is not None:
self.name = table_name self.name = table_name
self.type = "cash" self.type = "cash"
self.tournament = None self.tournament = None
table_kwargs = dict(table_name = table_name) table_kwargs = dict(table_name = table_name)
self.key = table_name
else: else:
return None return None
@ -135,6 +138,7 @@ class Table_Window(object):
self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs) self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs)
self.find_table_parameters() self.find_table_parameters()
self.gdkhandle = gtk.gdk.window_foreign_new(self.number)
geo = self.get_geometry() geo = self.get_geometry()
if geo is None: return None if geo is None: return None
self.width = geo['width'] self.width = geo['width']
@ -150,7 +154,7 @@ class Table_Window(object):
# __str__ method for testing # __str__ method for testing
likely_attrs = ("number", "title", "site", "width", "height", "x", "y", likely_attrs = ("number", "title", "site", "width", "height", "x", "y",
"tournament", "table", "gdkhandle", "window", "parent", "tournament", "table", "gdkhandle", "window", "parent",
"game", "search_string", "tableno_re") "key", "hud", "game", "search_string", "tableno_re")
temp = 'TableWindow object\n' temp = 'TableWindow object\n'
for a in likely_attrs: for a in likely_attrs:
if getattr(self, a, 0): if getattr(self, a, 0):
@ -185,13 +189,13 @@ class Table_Window(object):
return False return False
try: try:
mo = re.search(self.tableno_re, new_title) mo = re.search(self.tableno_re, new_title)
except AttributeError: #'Table' object has no attribute 'tableno_re' except AttributeError: #'Table' object has no attribute 'tableno_re'
return False return False
if mo is not None: if mo is not None:
#print "get_table_no: mo=",mo.groups() #print "get_table_no: mo=",mo.groups()
return mo.group(1) return int(mo.group(1))
return False return False
#################################################################### ####################################################################
@ -256,7 +260,7 @@ class Table_Window(object):
if result != False and result != self.table: if result != False and result != self.table:
self.table = result self.table = result
if hud is not None: if hud is not None:
hud.main_window.emit("table_changed", hud) hud.parent.main_window.emit("table_changed", hud)
return True return True
def check_bad_words(self, title): def check_bad_words(self, title):

View File

@ -44,6 +44,10 @@ class Table(Table_Window):
def find_table_parameters(self): def find_table_parameters(self):
# This is called by __init__(). Find the poker table window of interest,
# given the self.search_string. Then populate self.number, self.title,
# self.window, and self.parent (if required).
reg = ''' reg = '''
\s+(?P<XID>[\dxabcdef]+) # XID in hex \s+(?P<XID>[\dxabcdef]+) # XID in hex
\s(?P<TITLE>.+): # window title \s(?P<TITLE>.+): # window title
@ -53,12 +57,10 @@ class Table(Table_Window):
for listing in os.popen('xwininfo -root -tree').readlines(): for listing in os.popen('xwininfo -root -tree').readlines():
if re.search(self.search_string, listing, re.I): if re.search(self.search_string, listing, re.I):
mo = re.match(reg, listing, re.VERBOSE) mo = re.match(reg, listing, re.VERBOSE)
# mo = re.match('\s+([\dxabcdef]+) (.+):\s\(\"([a-zA-Z0-9\-.]+)\".+ (\d+)x(\d+)\+\d+\+\d+ \+(\d+)\+(\d+)', listing)
title = re.sub('\"', '', mo.groupdict()["TITLE"]) title = re.sub('\"', '', mo.groupdict()["TITLE"])
if self.check_bad_words(title): continue if self.check_bad_words(title): continue
self.number = int( mo.groupdict()["XID"], 0 ) self.number = int( mo.groupdict()["XID"], 0 )
self.title = title self.title = title
self.hud = None # specified later
break break
if self.number is None: if self.number is None: