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

This commit is contained in:
sqlcoder 2009-11-17 20:48:06 +00:00
commit 289922e43a
14 changed files with 207 additions and 159 deletions

View File

@ -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")

View File

@ -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):

View File

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

View File

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

View File

@ -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])

View File

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

View File

@ -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,7 +197,18 @@ 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 == 'TOURNO':
hand.tourNo = info[key]
if key == 'BUYIN':
hand.buyin = info[key]
if key == 'LEVEL':
hand.level = info[key]
if key == 'TABLE': if key == 'TABLE':
if hand.tourNo != None:
hand.tablename = re.split(" ", info[key])[1]
else:
hand.tablename = info[key] hand.tablename = info[key]
if key == 'BUTTON': if key == 'BUTTON':
hand.buttonpos = info[key] hand.buttonpos = info[key]
@ -206,13 +217,6 @@ class PokerStars(HandHistoryConverter):
if key == 'MIXED': if key == 'MIXED':
hand.mixed = self.mixes[info[key]] if info[key] is not None else None hand.mixed = self.mixes[info[key]] if info[key] is not None else None
if key == 'TOURNO':
hand.tourNo = info[key]
if key == 'BUYIN':
hand.buyin = info[key]
if key == 'LEVEL':
hand.level = info[key]
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')))

View File

@ -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

View File

@ -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):

0
pyfpdb/Tables_Demo.py Normal file → Executable file
View File

View 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:

View File

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

View File

@ -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:

View File

@ -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\*'))
] ]
) )