Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
commit
289922e43a
|
@ -37,20 +37,79 @@ from xml.dom.minidom import Node
|
||||||
import logging, logging.config
|
import logging, logging.config
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
|
||||||
try: # local path
|
##############################################################################
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
# Functions for finding config files and setting up logging
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
# Also used in other modules that use logging.
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
def get_default_config_path():
|
||||||
|
"""Returns the path where the fpdb config file _should_ be stored."""
|
||||||
|
if os.name == 'posix':
|
||||||
|
config_path = os.path.join(os.path.expanduser("~"), '.fpdb')
|
||||||
|
elif os.name == 'nt':
|
||||||
|
config_path = os.path.join(os.environ["APPDATA"], 'fpdb')
|
||||||
|
else: config_path = False
|
||||||
|
return config_path
|
||||||
|
|
||||||
|
def get_exec_path():
|
||||||
|
"""Returns the path to the fpdb.(py|exe) file we are executing"""
|
||||||
|
if hasattr(sys, "frozen"): # compiled by py2exe
|
||||||
|
return os.path.dirname(sys.executable)
|
||||||
|
else:
|
||||||
|
return os.path.dirname(sys.path[0])
|
||||||
|
|
||||||
|
def get_config(file_name, fallback = True):
|
||||||
|
"""Looks in cwd and in self.default_config_path for a config file."""
|
||||||
|
config_path = os.path.join(get_exec_path(), file_name)
|
||||||
|
if os.path.exists(config_path): # there is a file in the cwd
|
||||||
|
return config_path # so we use it
|
||||||
|
else: # no file in the cwd, look where it should be in the first place
|
||||||
|
config_path = os.path.join(get_default_config_path(), file_name)
|
||||||
|
if os.path.exists(config_path):
|
||||||
|
return config_path
|
||||||
|
|
||||||
|
# No file found
|
||||||
|
if not fallback:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# OK, fall back to the .example file, should be in the start dir
|
||||||
|
if os.path.exists(file_name + ".example"):
|
||||||
|
try:
|
||||||
|
shutil.copyfile(file_name + ".example", file_name)
|
||||||
|
print "No %s found, using %s.example.\n" % (file_name, file_name)
|
||||||
|
print "A %s file has been created. You will probably have to edit it." % file_name
|
||||||
|
sys.stderr.write("No %s found, using %s.example.\n" % (file_name, file_name) )
|
||||||
|
except:
|
||||||
|
print "No %s found, cannot fall back. Exiting.\n" % file_name
|
||||||
|
sys.stderr.write("No %s found, cannot fall back. Exiting.\n" % file_name)
|
||||||
|
sys.exit()
|
||||||
|
return file_name
|
||||||
|
|
||||||
|
def get_logger(file_name, config = "config", fallback = False):
|
||||||
|
conf = get_config(file_name, fallback = fallback)
|
||||||
|
if conf:
|
||||||
|
try:
|
||||||
|
logging.config.fileConfig(conf)
|
||||||
|
log = logging.getLogger(config)
|
||||||
|
log.debug("%s logger initialised" % config)
|
||||||
|
return log
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
log = logging.basicConfig()
|
||||||
|
log = logging.getLogger()
|
||||||
|
log.debug("config logger initialised")
|
||||||
|
return log
|
||||||
|
|
||||||
|
# find a logging.conf file and set up logging
|
||||||
|
log = get_logger("logging.conf")
|
||||||
|
|
||||||
log = logging.getLogger("config")
|
|
||||||
log.debug("config logger initialised")
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# application wide consts
|
# application wide consts
|
||||||
|
|
||||||
APPLICATION_NAME_SHORT = 'fpdb'
|
APPLICATION_NAME_SHORT = 'fpdb'
|
||||||
APPLICATION_VERSION = 'xx.xx.xx'
|
APPLICATION_VERSION = 'xx.xx.xx'
|
||||||
|
|
||||||
DIR_SELF = os.path.dirname(os.path.abspath(__file__))
|
DIR_SELF = os.path.dirname(get_exec_path())
|
||||||
#TODO: imo no good idea to place 'database' in parent dir
|
#TODO: imo no good idea to place 'database' in parent dir
|
||||||
DIR_DATABASES = os.path.join(os.path.dirname(DIR_SELF), 'database')
|
DIR_DATABASES = os.path.join(os.path.dirname(DIR_SELF), 'database')
|
||||||
|
|
||||||
|
@ -335,7 +394,7 @@ class Config:
|
||||||
# "file" is a path to an xml file with the fpdb/HUD configuration
|
# "file" is a path to an xml file with the fpdb/HUD configuration
|
||||||
# we check the existence of "file" and try to recover if it doesn't exist
|
# we check the existence of "file" and try to recover if it doesn't exist
|
||||||
|
|
||||||
self.default_config_path = self.get_default_config_path()
|
# self.default_config_path = self.get_default_config_path()
|
||||||
if file is not None: # config file path passed in
|
if file is not None: # config file path passed in
|
||||||
file = os.path.expanduser(file)
|
file = os.path.expanduser(file)
|
||||||
if not os.path.exists(file):
|
if not os.path.exists(file):
|
||||||
|
@ -343,28 +402,12 @@ class Config:
|
||||||
sys.stderr.write("Configuration file %s not found. Using defaults." % (file))
|
sys.stderr.write("Configuration file %s not found. Using defaults." % (file))
|
||||||
file = None
|
file = None
|
||||||
|
|
||||||
if file is None: # configuration file path not passed or invalid
|
if file is None: file = get_config("HUD_config.xml")
|
||||||
file = self.find_config() #Look for a config file in the normal places
|
|
||||||
|
|
||||||
if file is None: # no config file in the normal places
|
|
||||||
file = self.find_example_config() #Look for an example file to edit
|
|
||||||
|
|
||||||
if file is None: # that didn't work either, just die
|
|
||||||
print "No HUD_config_xml found after looking in current directory and "+self.default_config_path+"\nExiting"
|
|
||||||
sys.stderr.write("No HUD_config_xml found after looking in current directory and "+self.default_config_path+"\nExiting")
|
|
||||||
print "press enter to continue"
|
|
||||||
sys.stdin.readline()
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
# Parse even if there was no real config file found and we are using the example
|
# Parse even if there was no real config file found and we are using the example
|
||||||
# If using the example, we'll edit it later
|
# If using the example, we'll edit it later
|
||||||
# sc 2009/10/04 Example already copied to main filename, is this ok?
|
|
||||||
log.info("Reading configuration file %s" % file)
|
log.info("Reading configuration file %s" % file)
|
||||||
if os.sep in file:
|
print "\nReading configuration file %s\n" % file
|
||||||
print "\nReading configuration file %s\n" % file
|
|
||||||
else:
|
|
||||||
print "\nReading configuration file %s" % file
|
|
||||||
print "in %s\n" % os.getcwd()
|
|
||||||
try:
|
try:
|
||||||
doc = xml.dom.minidom.parse(file)
|
doc = xml.dom.minidom.parse(file)
|
||||||
except:
|
except:
|
||||||
|
@ -460,28 +503,6 @@ class Config:
|
||||||
def set_hhArchiveBase(self, path):
|
def set_hhArchiveBase(self, path):
|
||||||
self.imp.node.setAttribute("hhArchiveBase", path)
|
self.imp.node.setAttribute("hhArchiveBase", path)
|
||||||
|
|
||||||
def find_config(self):
|
|
||||||
"""Looks in cwd and in self.default_config_path for a config file."""
|
|
||||||
if os.path.exists('HUD_config.xml'): # there is a HUD_config in the cwd
|
|
||||||
file = 'HUD_config.xml' # so we use it
|
|
||||||
else: # no HUD_config in the cwd, look where it should be in the first place
|
|
||||||
config_path = os.path.join(self.default_config_path, 'HUD_config.xml')
|
|
||||||
if os.path.exists(config_path):
|
|
||||||
file = config_path
|
|
||||||
else:
|
|
||||||
file = None
|
|
||||||
return file
|
|
||||||
|
|
||||||
def get_default_config_path(self):
|
|
||||||
"""Returns the path where the fpdb config file _should_ be stored."""
|
|
||||||
if os.name == 'posix':
|
|
||||||
config_path = os.path.join(os.path.expanduser("~"), '.fpdb')
|
|
||||||
elif os.name == 'nt':
|
|
||||||
config_path = os.path.join(os.environ["APPDATA"], 'fpdb')
|
|
||||||
else: config_path = None
|
|
||||||
return config_path
|
|
||||||
|
|
||||||
|
|
||||||
def find_default_conf(self):
|
def find_default_conf(self):
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'default.conf')
|
config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'default.conf')
|
||||||
|
@ -495,30 +516,6 @@ class Config:
|
||||||
file = None
|
file = None
|
||||||
return file
|
return file
|
||||||
|
|
||||||
def read_default_conf(self, file):
|
|
||||||
parms = {}
|
|
||||||
with open(file, "r") as fh:
|
|
||||||
for line in fh:
|
|
||||||
line = string.strip(line)
|
|
||||||
(key, value) = line.split('=')
|
|
||||||
parms[key] = value
|
|
||||||
return parms
|
|
||||||
|
|
||||||
def find_example_config(self):
|
|
||||||
if os.path.exists('HUD_config.xml.example'): # there is a HUD_config in the cwd
|
|
||||||
file = 'HUD_config.xml' # so we use it
|
|
||||||
try:
|
|
||||||
shutil.copyfile(file+'.example', file)
|
|
||||||
except:
|
|
||||||
file = ''
|
|
||||||
print "No HUD_config.xml found, using HUD_config.xml.example.\n", \
|
|
||||||
"A HUD_config.xml has been created. You will probably have to edit it."
|
|
||||||
sys.stderr.write("No HUD_config.xml found, using HUD_config.xml.example.\n" + \
|
|
||||||
"A HUD_config.xml has been created. You will probably have to edit it.")
|
|
||||||
else:
|
|
||||||
file = None
|
|
||||||
return file
|
|
||||||
|
|
||||||
def get_site_node(self, site):
|
def get_site_node(self, site):
|
||||||
for site_node in self.doc.getElementsByTagName("site"):
|
for site_node in self.doc.getElementsByTagName("site"):
|
||||||
if site_node.getAttribute("site_name") == site:
|
if site_node.getAttribute("site_name") == site:
|
||||||
|
@ -948,3 +945,7 @@ if __name__== "__main__":
|
||||||
print c.get_game_parameters(game)
|
print c.get_game_parameters(game)
|
||||||
|
|
||||||
print "start up path = ", c.execution_path("")
|
print "start up path = ", c.execution_path("")
|
||||||
|
|
||||||
|
from xml.dom.ext import PrettyPrint
|
||||||
|
for site_node in c.doc.getElementsByTagName("site"):
|
||||||
|
PrettyPrint(site_node, stream=sys.stdout, encoding="utf-8")
|
||||||
|
|
|
@ -45,16 +45,7 @@ import Card
|
||||||
import Tourney
|
import Tourney
|
||||||
from Exceptions import *
|
from Exceptions import *
|
||||||
|
|
||||||
import logging, logging.config
|
log = Configuration.get_logger("logging.conf")
|
||||||
import ConfigParser
|
|
||||||
|
|
||||||
try: # local path
|
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
|
||||||
log = logging.getLogger('db')
|
|
||||||
|
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
|
|
||||||
|
@ -2690,13 +2681,11 @@ class HandToWrite:
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
c = Configuration.Config()
|
c = Configuration.Config()
|
||||||
|
|
||||||
db_connection = Database(c, 'fpdb', 'holdem') # mysql fpdb holdem
|
db_connection = Database(c) # mysql fpdb holdem
|
||||||
# db_connection = Database(c, 'fpdb-p', 'test') # mysql fpdb holdem
|
# db_connection = Database(c, 'fpdb-p', 'test') # mysql fpdb holdem
|
||||||
# db_connection = Database(c, 'PTrackSv2', 'razz') # mysql razz
|
# db_connection = Database(c, 'PTrackSv2', 'razz') # mysql razz
|
||||||
# db_connection = Database(c, 'ptracks', 'razz') # postgres
|
# db_connection = Database(c, 'ptracks', 'razz') # postgres
|
||||||
print "database connection object = ", db_connection.connection
|
print "database connection object = ", db_connection.connection
|
||||||
print "database type = ", db_connection.type
|
|
||||||
|
|
||||||
db_connection.recreate_tables()
|
db_connection.recreate_tables()
|
||||||
|
|
||||||
h = db_connection.get_last_hand()
|
h = db_connection.get_last_hand()
|
||||||
|
@ -2710,18 +2699,12 @@ if __name__=="__main__":
|
||||||
for p in stat_dict.keys():
|
for p in stat_dict.keys():
|
||||||
print p, " ", stat_dict[p]
|
print p, " ", stat_dict[p]
|
||||||
|
|
||||||
#print "nutOmatics stats:"
|
|
||||||
#stat_dict = db_connection.get_stats_from_hand(h, "ring")
|
|
||||||
#for p in stat_dict.keys():
|
|
||||||
# print p, " ", stat_dict[p]
|
|
||||||
|
|
||||||
print "cards =", db_connection.get_cards(u'1')
|
print "cards =", db_connection.get_cards(u'1')
|
||||||
db_connection.close_connection
|
db_connection.close_connection
|
||||||
|
|
||||||
print "press enter to continue"
|
print "press enter to continue"
|
||||||
sys.stdin.readline()
|
sys.stdin.readline()
|
||||||
|
|
||||||
|
|
||||||
#Code borrowed from http://push.cx/2008/caching-dictionaries-in-python-vs-ruby
|
#Code borrowed from http://push.cx/2008/caching-dictionaries-in-python-vs-ruby
|
||||||
class LambdaDict(dict):
|
class LambdaDict(dict):
|
||||||
def __init__(self, l):
|
def __init__(self, l):
|
||||||
|
|
|
@ -9,8 +9,8 @@ class FpdbParseError(FpdbError):
|
||||||
self.value = value
|
self.value = value
|
||||||
self.hid = hid
|
self.hid = hid
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if hid:
|
if self.hid:
|
||||||
return repr("HID:"+hid+", "+self.value)
|
return repr("HID:"+self.hid+", "+self.value)
|
||||||
else:
|
else:
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,13 @@ import gobject
|
||||||
# FreePokerTools modules
|
# FreePokerTools modules
|
||||||
import Configuration
|
import Configuration
|
||||||
import Database
|
import Database
|
||||||
import Tables
|
from HandHistoryConverter import getTableTitleRe
|
||||||
|
# get the correct module for the current os
|
||||||
|
if os.name == 'posix':
|
||||||
|
import XTables as Tables
|
||||||
|
elif os.name == 'nt':
|
||||||
|
import WinTables as Tables
|
||||||
|
#import Tables
|
||||||
import Hud
|
import Hud
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,6 +137,7 @@ class HUD_main(object):
|
||||||
# TODO: The purpose of this try/finally block is to make darn sure that threads_leave()
|
# TODO: The purpose of this try/finally block is to make darn sure that threads_leave()
|
||||||
# TODO: gets called. If there is an exception and threads_leave() doesn't get called we
|
# TODO: gets called. If there is an exception and threads_leave() doesn't get called we
|
||||||
# TODO: lock up. REB
|
# TODO: lock up. REB
|
||||||
|
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()
|
||||||
|
@ -210,7 +217,7 @@ class HUD_main(object):
|
||||||
# get basic info about the new hand from the db
|
# get basic info about the new hand from the db
|
||||||
# if there is a db error, complain, skip hand, and proceed
|
# if there is a db error, complain, skip hand, and proceed
|
||||||
try:
|
try:
|
||||||
(table_name, max, poker_game, type, site_id, tour_number, tab_number) = \
|
(table_name, max, poker_game, type, site_id, site_name, tour_number, tab_number) = \
|
||||||
self.db_connection.get_table_info(new_hand_id)
|
self.db_connection.get_table_info(new_hand_id)
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
print "db error: skipping %s" % new_hand_id
|
print "db error: skipping %s" % new_hand_id
|
||||||
|
@ -247,16 +254,18 @@ class HUD_main(object):
|
||||||
if comm_cards != {}: # stud!
|
if comm_cards != {}: # stud!
|
||||||
cards['common'] = comm_cards['common']
|
cards['common'] = comm_cards['common']
|
||||||
|
|
||||||
if type == "tour":
|
table_kwargs = dict(table_name = table_name, tournament = tour_number, table_number = tab_number)
|
||||||
tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number)
|
search_string = getTableTitleRe(self.config, site, type, **table_kwargs)
|
||||||
else:
|
tablewindow = Tables.Table(search_string, **table_kwargs)
|
||||||
tablewindow = Tables.discover_table_by_name(self.config, table_name)
|
|
||||||
if tablewindow is None:
|
if tablewindow is None:
|
||||||
# If no client window is found on the screen, complain and continue
|
# If no client window is found on the screen, complain and continue
|
||||||
if type == "tour":
|
if type == "tour":
|
||||||
table_name = "%s %s" % (tour_number, tab_number)
|
table_name = "%s %s" % (tour_number, tab_number)
|
||||||
sys.stderr.write("HUD create: table name "+table_name+" not found, skipping.\n")
|
sys.stderr.write("HUD create: table name "+table_name+" not found, skipping.\n")
|
||||||
else:
|
else:
|
||||||
|
tablewindow.max = max
|
||||||
|
tablewindow.site = site_name
|
||||||
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
|
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
|
||||||
self.db_connection.connection.rollback()
|
self.db_connection.connection.rollback()
|
||||||
|
|
||||||
|
|
|
@ -32,19 +32,12 @@ from xml.dom.minidom import Node
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
from Exceptions import FpdbParseError
|
from Exceptions import FpdbParseError
|
||||||
|
import Configuration
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
gettext.install('fpdb')
|
gettext.install('fpdb')
|
||||||
|
|
||||||
import logging, logging.config
|
log = Configuration.get_logger("logging.conf")
|
||||||
import ConfigParser
|
|
||||||
|
|
||||||
try:
|
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
|
||||||
log = logging.getLogger("parser")
|
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
import gtk
|
import gtk
|
||||||
|
@ -154,6 +147,7 @@ Otherwise, finish at EOF.
|
||||||
except FpdbParseError, e:
|
except FpdbParseError, e:
|
||||||
numErrors += 1
|
numErrors += 1
|
||||||
log.warning("Failed to convert hand %s" % e.hid)
|
log.warning("Failed to convert hand %s" % e.hid)
|
||||||
|
log.warning("Exception msg: '%s'" % str(e))
|
||||||
log.debug(handText)
|
log.debug(handText)
|
||||||
else:
|
else:
|
||||||
handsList = self.allHandsAsList()
|
handsList = self.allHandsAsList()
|
||||||
|
@ -168,6 +162,7 @@ Otherwise, finish at EOF.
|
||||||
except FpdbParseError, e:
|
except FpdbParseError, e:
|
||||||
numErrors += 1
|
numErrors += 1
|
||||||
log.warning("Failed to convert hand %s" % e.hid)
|
log.warning("Failed to convert hand %s" % e.hid)
|
||||||
|
log.warning("Exception msg: '%s'" % str(e))
|
||||||
log.debug(handText)
|
log.debug(handText)
|
||||||
numHands = len(handsList)
|
numHands = len(handsList)
|
||||||
endtime = time.time()
|
endtime = time.time()
|
||||||
|
@ -506,3 +501,26 @@ or None if we fail to get the info """
|
||||||
|
|
||||||
def getTourney(self):
|
def getTourney(self):
|
||||||
return self.tourney
|
return self.tourney
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
|
||||||
|
"Returns string to search in windows titles"
|
||||||
|
if type=="tour":
|
||||||
|
return "%s.+Table\s%s" % (tournament, table_number)
|
||||||
|
else:
|
||||||
|
return table_name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def getTableTitleRe(config, sitename, *args, **kwargs):
|
||||||
|
"Returns string to search in windows titles for current site"
|
||||||
|
return getSiteHhc(config, sitename).getTableTitleRe(*args, **kwargs)
|
||||||
|
|
||||||
|
def getSiteHhc(config, sitename):
|
||||||
|
"Returns HHC class for current site"
|
||||||
|
hhcName = config.supported_sites[sitename].converter
|
||||||
|
hhcModule = __import__(hhcName)
|
||||||
|
return getattr(hhcModule, hhcName[:-6])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -386,9 +386,9 @@ class Hud:
|
||||||
(x, y) = loc[adj[i+1]]
|
(x, y) = loc[adj[i+1]]
|
||||||
w.relocate(x, y)
|
w.relocate(x, y)
|
||||||
|
|
||||||
# While we're at it, fix the positions of mucked cards too
|
# While we're at it, fix the positions of mucked cards too
|
||||||
for aux in self.aux_windows:
|
for aux in self.aux_windows:
|
||||||
aux.update_card_positions()
|
aux.update_card_positions()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@ class Hud:
|
||||||
new_layout[self.stat_windows[sw].adj - 1] = new_loc
|
new_layout[self.stat_windows[sw].adj - 1] = new_loc
|
||||||
self.config.edit_layout(self.table.site, self.max, locations = new_layout)
|
self.config.edit_layout(self.table.site, self.max, locations = new_layout)
|
||||||
# ask each aux to save its layout back to the config object
|
# ask each aux to save its layout back to the config object
|
||||||
(aux.save_layout() for aux in self.aux_windows)
|
[aux.save_layout() for aux in self.aux_windows]
|
||||||
# save the config object back to the file
|
# save the config object back to the file
|
||||||
print "saving new xml file"
|
print "saving new xml file"
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
|
|
@ -92,7 +92,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
self.compiledPlayers = players
|
self.compiledPlayers = players
|
||||||
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
||||||
subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]}
|
subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]}
|
||||||
logging.debug("player_re: " + player_re)
|
log.debug("player_re: " + player_re)
|
||||||
self.re_PostSB = re.compile(r"^%(PLYR)s: posts small blind %(CUR)s(?P<SB>[.0-9]+)" % subst, re.MULTILINE)
|
self.re_PostSB = re.compile(r"^%(PLYR)s: posts small blind %(CUR)s(?P<SB>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_PostBB = re.compile(r"^%(PLYR)s: posts big blind %(CUR)s(?P<BB>[.0-9]+)" % subst, re.MULTILINE)
|
self.re_PostBB = re.compile(r"^%(PLYR)s: posts big blind %(CUR)s(?P<BB>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante %(CUR)s(?P<ANTE>[.0-9]+)" % subst, re.MULTILINE)
|
self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante %(CUR)s(?P<ANTE>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
|
@ -186,7 +186,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
# m = self.re_Button.search(hand.handText)
|
# m = self.re_Button.search(hand.handText)
|
||||||
# if m: info.update(m.groupdict())
|
# if m: info.update(m.groupdict())
|
||||||
# TODO : I rather like the idea of just having this dict as hand.info
|
# TODO : I rather like the idea of just having this dict as hand.info
|
||||||
logging.debug("readHandInfo: %s" % info)
|
log.debug("readHandInfo: %s" % info)
|
||||||
for key in info:
|
for key in info:
|
||||||
if key == 'DATETIME':
|
if key == 'DATETIME':
|
||||||
#2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]
|
#2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]
|
||||||
|
@ -197,15 +197,6 @@ class PokerStars(HandHistoryConverter):
|
||||||
hand.starttime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S")
|
hand.starttime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S")
|
||||||
if key == 'HID':
|
if key == 'HID':
|
||||||
hand.handid = info[key]
|
hand.handid = info[key]
|
||||||
if key == 'TABLE':
|
|
||||||
hand.tablename = info[key]
|
|
||||||
if key == 'BUTTON':
|
|
||||||
hand.buttonpos = info[key]
|
|
||||||
if key == 'MAX':
|
|
||||||
hand.maxseats = int(info[key])
|
|
||||||
|
|
||||||
if key == 'MIXED':
|
|
||||||
hand.mixed = self.mixes[info[key]] if info[key] is not None else None
|
|
||||||
|
|
||||||
if key == 'TOURNO':
|
if key == 'TOURNO':
|
||||||
hand.tourNo = info[key]
|
hand.tourNo = info[key]
|
||||||
|
@ -213,6 +204,19 @@ class PokerStars(HandHistoryConverter):
|
||||||
hand.buyin = info[key]
|
hand.buyin = info[key]
|
||||||
if key == 'LEVEL':
|
if key == 'LEVEL':
|
||||||
hand.level = info[key]
|
hand.level = info[key]
|
||||||
|
|
||||||
|
if key == 'TABLE':
|
||||||
|
if hand.tourNo != None:
|
||||||
|
hand.tablename = re.split(" ", info[key])[1]
|
||||||
|
else:
|
||||||
|
hand.tablename = info[key]
|
||||||
|
if key == 'BUTTON':
|
||||||
|
hand.buttonpos = info[key]
|
||||||
|
if key == 'MAX':
|
||||||
|
hand.maxseats = int(info[key])
|
||||||
|
|
||||||
|
if key == 'MIXED':
|
||||||
|
hand.mixed = self.mixes[info[key]] if info[key] is not None else None
|
||||||
if key == 'PLAY' and info['PLAY'] is not None:
|
if key == 'PLAY' and info['PLAY'] is not None:
|
||||||
# hand.currency = 'play' # overrides previously set value
|
# hand.currency = 'play' # overrides previously set value
|
||||||
hand.gametype['currency'] = 'play'
|
hand.gametype['currency'] = 'play'
|
||||||
|
@ -222,10 +226,10 @@ class PokerStars(HandHistoryConverter):
|
||||||
if m:
|
if m:
|
||||||
hand.buttonpos = int(m.group('BUTTON'))
|
hand.buttonpos = int(m.group('BUTTON'))
|
||||||
else:
|
else:
|
||||||
logging.info('readButton: not found')
|
log.info('readButton: not found')
|
||||||
|
|
||||||
def readPlayerStacks(self, hand):
|
def readPlayerStacks(self, hand):
|
||||||
logging.debug("readPlayerStacks")
|
log.debug("readPlayerStacks")
|
||||||
m = self.re_PlayerInfo.finditer(hand.handText)
|
m = self.re_PlayerInfo.finditer(hand.handText)
|
||||||
players = []
|
players = []
|
||||||
for a in m:
|
for a in m:
|
||||||
|
@ -261,7 +265,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
hand.setCommunityCards(street, m.group('CARDS').split(' '))
|
hand.setCommunityCards(street, m.group('CARDS').split(' '))
|
||||||
|
|
||||||
def readAntes(self, hand):
|
def readAntes(self, hand):
|
||||||
logging.debug("reading antes")
|
log.debug("reading antes")
|
||||||
m = self.re_Antes.finditer(hand.handText)
|
m = self.re_Antes.finditer(hand.handText)
|
||||||
for player in m:
|
for player in m:
|
||||||
#~ logging.debug("hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE')))
|
#~ logging.debug("hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE')))
|
||||||
|
|
|
@ -1604,11 +1604,11 @@ class Sql:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.query['get_table_name'] = """
|
self.query['get_table_name'] = """
|
||||||
select h.tableName, h.maxSeats, gt.category, gt.type, gt.siteId
|
SELECT h.tableName, h.maxSeats, gt.category, gt.type, s.id, s.name
|
||||||
from Hands h
|
FROM Hands h, Gametypes gt, Sites s
|
||||||
,Gametypes gt
|
WHERE h.id = %s
|
||||||
where h.id = %s
|
AND gt.id = h.gametypeId
|
||||||
and gt.id = h.gametypeId
|
AND s.id = gt.siteID
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.query['get_actual_seat'] = """
|
self.query['get_actual_seat'] = """
|
||||||
|
@ -2942,8 +2942,9 @@ class Sql:
|
||||||
,hc_position
|
,hc_position
|
||||||
,hp.tourneyTypeId
|
,hp.tourneyTypeId
|
||||||
,date_format(h.handStart, 'd%y%m%d')
|
,date_format(h.handStart, 'd%y%m%d')
|
||||||
>>>>>>> 28ca49d592c8e706ad6ee58dd26655bcc33fc5fb:pyfpdb/SQL.py
|
|
||||||
"""
|
"""
|
||||||
|
#>>>>>>> 28ca49d592c8e706ad6ee58dd26655bcc33fc5fb:pyfpdb/SQL.py
|
||||||
|
#"""
|
||||||
elif db_server == 'postgresql':
|
elif db_server == 'postgresql':
|
||||||
self.query['rebuildHudCache'] = """
|
self.query['rebuildHudCache'] = """
|
||||||
INSERT INTO HudCache
|
INSERT INTO HudCache
|
||||||
|
|
|
@ -93,19 +93,17 @@ gobject.signal_new("client_destroyed", gtk.Window,
|
||||||
# screen location of (0, 0) in the working window.
|
# screen location of (0, 0) in the working window.
|
||||||
|
|
||||||
class Table_Window(object):
|
class Table_Window(object):
|
||||||
def __init__(self, table_name = None, tournament = None, table_number = None):
|
def __init__(self, search_string, table_name = None, tournament = None, table_number = None):
|
||||||
|
|
||||||
if table_name is not None:
|
if tournament is not None and table_number is not None:
|
||||||
search_string = table_name
|
|
||||||
self.name = table_name
|
|
||||||
self.tournament = None
|
|
||||||
self.table = None
|
|
||||||
elif tournament is not None and table_number is not None:
|
|
||||||
print "tournament %s, table %s" % (tournament, table_number)
|
print "tournament %s, table %s" % (tournament, table_number)
|
||||||
self.tournament = int(tournament)
|
self.tournament = int(tournament)
|
||||||
self.table = int(table_number)
|
self.table = int(table_number)
|
||||||
self.name = "%s - %s" % (self.tournament, self.table)
|
self.name = "%s - %s" % (self.tournament, self.table)
|
||||||
search_string = "%s.+Table\s%s" % (tournament, table_number)
|
elif table_name is not None:
|
||||||
|
search_string = table_name
|
||||||
|
self.name = table_name
|
||||||
|
self.tournament = None
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -113,12 +111,12 @@ class Table_Window(object):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# __str__ method for testing
|
# __str__ method for testing
|
||||||
|
likely_attrs = ("site", "number", "title", "width", "height", "x", "y",
|
||||||
|
"tournament", "table", "gdkhandle")
|
||||||
temp = 'TableWindow object\n'
|
temp = 'TableWindow object\n'
|
||||||
temp = temp + " name = %s\n site = %s\n number = %s\n title = %s\n" % (self.name, self.site, self.number, self.title)
|
for a in likely_attrs:
|
||||||
# temp = temp + " game = %s\n structure = %s\n max = %s\n" % (self.game, self.structure, self.max)
|
if getattr(self, a, 0):
|
||||||
temp = temp + " width = %d\n height = %d\n x = %d\n y = %d\n" % (self.width, self.height, self.x, self.y)
|
temp += " %s = %s\n" % (a, getattr(self, a))
|
||||||
if getattr(self, 'tournament', 0):
|
|
||||||
temp = temp + " tournament = %d\n table = %d" % (self.tournament, self.table)
|
|
||||||
return temp
|
return temp
|
||||||
|
|
||||||
def get_game(self):
|
def get_game(self):
|
||||||
|
@ -151,4 +149,4 @@ class Table_Window(object):
|
||||||
def check_bad_words(self, title):
|
def check_bad_words(self, title):
|
||||||
for word in bad_words:
|
for word in bad_words:
|
||||||
if word in title: return True
|
if word in title: return True
|
||||||
return False
|
return False
|
||||||
|
|
0
pyfpdb/Tables_Demo.py
Normal file → Executable file
0
pyfpdb/Tables_Demo.py
Normal file → Executable file
|
@ -79,7 +79,8 @@ class Table(Table_Window):
|
||||||
self.gdk_handle = None
|
self.gdk_handle = None
|
||||||
else:
|
else:
|
||||||
self.number = int( mo.group(1), 0)
|
self.number = int( mo.group(1), 0)
|
||||||
self.gdk_handle = gtk.gdk.window_foreign_new(int(self.number))
|
print "number =", self.number
|
||||||
|
# self.gdk_handle = gtk.gdk.window_foreign_new(int(self.number))
|
||||||
|
|
||||||
def get_geometry(self):
|
def get_geometry(self):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -30,11 +30,29 @@ except ImportError:
|
||||||
logging.info("Not using sqlalchemy connection pool.")
|
logging.info("Not using sqlalchemy connection pool.")
|
||||||
use_pool = False
|
use_pool = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
from numpy import var
|
||||||
|
use_numpy = True
|
||||||
|
except ImportError:
|
||||||
|
logging.info("Not using numpy to define variance in sqlite.")
|
||||||
|
use_numpy = False
|
||||||
|
|
||||||
import fpdb_simple
|
import fpdb_simple
|
||||||
import FpdbSQLQueries
|
import FpdbSQLQueries
|
||||||
import Configuration
|
import Configuration
|
||||||
|
|
||||||
|
# Variance created as sqlite has a bunch of undefined aggregate functions.
|
||||||
|
|
||||||
|
class VARIANCE:
|
||||||
|
def __init__(self):
|
||||||
|
self.store = []
|
||||||
|
|
||||||
|
def step(self, value):
|
||||||
|
self.store.append(value)
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
return float(var(self.store))
|
||||||
|
|
||||||
class fpdb_db:
|
class fpdb_db:
|
||||||
MYSQL_INNODB = 2
|
MYSQL_INNODB = 2
|
||||||
PGSQL = 3
|
PGSQL = 3
|
||||||
|
@ -130,6 +148,10 @@ class fpdb_db:
|
||||||
, detect_types=sqlite3.PARSE_DECLTYPES )
|
, detect_types=sqlite3.PARSE_DECLTYPES )
|
||||||
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||||
|
if use_numpy:
|
||||||
|
self.db.create_aggregate("variance", 1, VARIANCE)
|
||||||
|
else:
|
||||||
|
logging.warning("Some database functions will not work without NumPy support")
|
||||||
else:
|
else:
|
||||||
raise FpdbError("unrecognised database backend:"+backend)
|
raise FpdbError("unrecognised database backend:"+backend)
|
||||||
self.cursor = self.db.cursor()
|
self.cursor = self.db.cursor()
|
||||||
|
|
|
@ -42,15 +42,7 @@ import fpdb_parse_logic
|
||||||
import Configuration
|
import Configuration
|
||||||
import Exceptions
|
import Exceptions
|
||||||
|
|
||||||
import logging, logging.config
|
log = Configuration.get_logger("logging.conf", "importer")
|
||||||
import ConfigParser
|
|
||||||
|
|
||||||
try:
|
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
|
||||||
log = logging.getLogger('importer')
|
|
||||||
|
|
||||||
# database interface modules
|
# database interface modules
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -27,6 +27,22 @@ Py2exe script for fpdb.
|
||||||
# get rid of all the uneeded libraries (e.g., pyQT)
|
# get rid of all the uneeded libraries (e.g., pyQT)
|
||||||
# think about an installer
|
# think about an installer
|
||||||
|
|
||||||
|
#HOW TO USE this script:
|
||||||
|
#
|
||||||
|
# cd to the folder where this script is stored, usually .../pyfpdb.
|
||||||
|
# If there are build and dist subfolders present , delete them to get
|
||||||
|
# rid of earlier builds.
|
||||||
|
# Run the script with "py2exe_setup.py py2exe"
|
||||||
|
# You will frequently get messages about missing .dll files. E. g.,
|
||||||
|
# MSVCP90.dll. These are somewhere in your windows install, so you
|
||||||
|
# can just copy them to your working folder.
|
||||||
|
# If it works, you'll have 2 new folders, build and dist. Build is
|
||||||
|
# working space and should be deleted. Dist contains the files to be
|
||||||
|
# distributed. Last, you must copy the etc/, lib/ and share/ folders
|
||||||
|
# from your gtk/bin/ folder to the dist folder. (the whole folders, not
|
||||||
|
# just the contents) You can (should) then prune the etc/, lib/ and
|
||||||
|
# share/ folders to remove components we don't need.
|
||||||
|
|
||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
import py2exe
|
import py2exe
|
||||||
|
|
||||||
|
@ -36,7 +52,8 @@ setup(
|
||||||
version = '0.12',
|
version = '0.12',
|
||||||
|
|
||||||
console = [ {'script': 'fpdb.py', },
|
console = [ {'script': 'fpdb.py', },
|
||||||
{'script': 'HUD_main.py', }
|
{'script': 'HUD_main.py', },
|
||||||
|
{'script': 'Configuration.py', }
|
||||||
],
|
],
|
||||||
|
|
||||||
options = {'py2exe': {
|
options = {'py2exe': {
|
||||||
|
@ -47,8 +64,10 @@ setup(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data_files = ['HUD_config.xml',
|
data_files = ['HUD_config.xml.example',
|
||||||
'Cards01.png'
|
'Cards01.png',
|
||||||
|
'logging.conf',
|
||||||
|
(r'matplotlibdata', glob.glob(r'c:\python26\Lib\site-packages\matplotlib\mpl-data\*'))
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user