config changes for logging: logs rotate and go to APPDATA, hud_config now goes in /fpdb/ if they must use it but logging.conf stays in /pyfpdb/. TODO: Some logging still into /fpdb/log/

This commit is contained in:
sqlcoder 2010-01-31 11:25:24 +00:00
parent cc5f77e950
commit 5e9486aa3d
8 changed files with 126 additions and 81 deletions

View File

@ -52,16 +52,19 @@ def get_default_config_path():
return config_path
def get_exec_path():
"""Returns the path to the fpdb.(py|exe) file we are executing"""
"""Returns the path to the fpdb(dir|.exe) file we are executing"""
if hasattr(sys, "frozen"): # compiled by py2exe
return os.path.dirname(sys.executable)
else:
return sys.path[0]
return os.path.dirname(sys.path[0]) # should be path to /fpdb
def get_config(file_name, fallback = True):
"""Looks in cwd and in self.default_config_path for a config file."""
exec_dir = get_exec_path()
config_path = os.path.join(exec_dir, file_name)
if file_name == 'logging.conf':
config_path = os.path.join(exec_dir, 'pyfpdb', file_name)
else:
config_path = os.path.join(exec_dir, file_name)
# print "config_path=", config_path
if os.path.exists(config_path): # there is a file in the cwd
return config_path # so we use it
@ -80,11 +83,7 @@ def get_config(file_name, fallback = True):
if os.path.exists(file_name + ".example"):
try:
print ""
if not os.path.isdir(default_dir):
msg = "Creating directory: '%s'" % (default_dir)
print msg
logging.info(msg)
os.mkdir(default_dir)
check_dir(default_dir)
shutil.copyfile(file_name + ".example", config_path)
msg = "No %s found in %s or %s\n" % (file_name, exec_dir, default_dir) \
+ "Config file has been created at %s.\n" % config_path \
@ -104,11 +103,17 @@ def get_config(file_name, fallback = True):
sys.exit()
return file_name
def get_logger(file_name, config = "config", fallback = False):
conf = get_config(file_name, fallback = fallback)
if conf:
def get_logger(file_name, config = "config", fallback = False, log_dir=None):
conf_file = get_config(file_name, fallback = fallback)
if conf_file:
try:
logging.config.fileConfig(conf)
if log_dir is None:
log_dir = os.path.join(get_exec_path(), 'log')
check_dir(log_dir)
file = os.path.join(log_dir, 'logging.out')
file = file.replace('\\', '\\\\') # replace each \ with \\
# print " ="+file+" "+ str(type(file))+" len="+str(len(file))+"\n"
logging.config.fileConfig(conf_file, {"logFile":file})
log = logging.getLogger(config)
log.debug("%s logger initialised" % config)
return log
@ -120,8 +125,23 @@ def get_logger(file_name, config = "config", fallback = False):
log.debug("config logger initialised")
return log
def check_dir(path, create = True):
"""Check if a dir exists, optionally creates if not."""
if os.path.exists(path):
if os.path.isdir(path):
return path
else:
return False
if create:
msg = "Creating directory: '%s'" % (path)
print msg
log.info(msg)
os.mkdir(path)
else:
return False
# find a logging.conf file and set up logging
log = get_logger("logging.conf")
log = get_logger("logging.conf", "config")
########################################################################
# application wide consts
@ -421,7 +441,6 @@ class Tv:
class Config:
def __init__(self, file = None, dbname = ''):
# "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
@ -435,6 +454,13 @@ class Config:
if file is None: file = get_config("HUD_config.xml", True)
self.file = file
self.dir_self = get_exec_path()
self.dir_config = os.path.dirname(self.file)
self.dir_log = os.path.join(self.dir_config, 'log')
self.dir_database = os.path.join(self.dir_config, 'database')
log = get_logger("logging.conf", "config", log_dir=self.dir_log)
# 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
log.info("Reading configuration file %s" % file)
@ -449,9 +475,6 @@ class Config:
sys.exit()
self.doc = doc
self.file = file
self.dir = os.path.dirname(self.file)
self.dir_databases = os.path.join(self.dir, 'database')
self.supported_sites = {}
self.supported_games = {}
self.supported_databases = {} # databaseName --> Database instance

View File

@ -224,6 +224,7 @@ class Database:
def __init__(self, c, sql = None):
log = Configuration.get_logger("logging.conf", "db", log_dir=c.dir_log)
log.info("Creating Database instance, sql = %s" % sql)
self.config = c
self.__connected = False
@ -379,11 +380,11 @@ class Database:
log.warning("SQLite won't work well without 'sqlalchemy' installed.")
if database != ":memory:":
if not os.path.isdir(self.config.dir_databases):
print "Creating directory: '%s'" % (self.config.dir_databases)
log.info("Creating directory: '%s'" % (self.config.dir_databases))
os.mkdir(self.config.dir_databases)
database = os.path.join(self.config.dir_databases, database)
if not os.path.isdir(self.config.dir_database):
print "Creating directory: '%s'" % (self.config.dir_database)
log.info("Creating directory: '%s'" % (self.config.dir_database))
os.mkdir(self.config.dir_database)
database = os.path.join(self.config.dir_database, database)
log.info("Connecting to SQLite: %(database)s" % {'database':database})
print "Connecting to SQLite: %(database)s" % {'database':database}
self.connection = sqlite3.connect(database, detect_types=sqlite3.PARSE_DECLTYPES )
@ -787,6 +788,7 @@ class Database:
def get_player_id(self, config, site, player_name):
c = self.connection.cursor()
print "get_player_id: player_name =", player_name, type(player_name)
p_name = Charset.to_utf8(player_name)
c.execute(self.sql.query['get_player_id'], (p_name, site))
row = c.fetchone()

View File

@ -51,10 +51,8 @@ import gobject
# FreePokerTools modules
import Configuration
print "start logging"
log = Configuration.get_logger("logging.conf", config = 'hud')
log.debug("%s logger initialized." % "dud")
print "logging started"
log.debug("%s logger initialized." % "hud")
import Database
@ -68,36 +66,40 @@ elif os.name == 'nt':
import Hud
log = Configuration.get_logger("logging.conf")
class HUD_main(object):
"""A main() object to own both the read_stdin thread and the gui."""
# This class mainly provides state for controlling the multiple HUDs.
def __init__(self, db_name = 'fpdb'):
self.db_name = db_name
self.log = log
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
self.hud_dict = {}
self.hud_params = self.config.get_hud_ui_parameters()
try:
print "HUD_main: starting ..."
self.db_name = db_name
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
log = Configuration.get_logger("logging.conf", "hud", log_dir=self.config.dir_log)
log.debug("starting ...")
self.hud_dict = {}
self.hud_params = self.config.get_hud_ui_parameters()
# a thread to read stdin
gobject.threads_init() # this is required
thread.start_new_thread(self.read_stdin, ()) # starts the thread
# a thread to read stdin
gobject.threads_init() # this is required
thread.start_new_thread(self.read_stdin, ()) # starts the thread
# a main window
self.main_window = gtk.Window()
self.main_window.connect("destroy", self.destroy)
self.vb = gtk.VBox()
self.label = gtk.Label('Closing this window will exit from the HUD.')
self.vb.add(self.label)
self.main_window.add(self.vb)
self.main_window.set_title("HUD Main Window")
self.main_window.show_all()
except:
log.debug("commit "+str(i)+" failed: info=" + str(sys.exc_info())
+ " value=" + str(sys.exc_value))
# a main window
self.main_window = gtk.Window()
self.main_window.connect("destroy", self.destroy)
self.vb = gtk.VBox()
self.label = gtk.Label('Closing this window will exit from the HUD.')
self.vb.add(self.label)
self.main_window.add(self.vb)
self.main_window.set_title("HUD Main Window")
self.main_window.show_all()
def destroy(self, *args): # call back for terminating the main eventloop
self.log.info("Terminating normally.")
log.info("Terminating normally.")
gtk.main_quit()
def kill_hud(self, event, table):
@ -205,7 +207,7 @@ class HUD_main(object):
t0 = time.time()
t1 = t2 = t3 = t4 = t5 = t6 = t0
new_hand_id = string.rstrip(new_hand_id)
self.log.debug("Received hand no %s" % new_hand_id)
log.debug("Received hand no %s" % new_hand_id)
if new_hand_id == "": # blank line means quit
self.destroy()
break # this thread is not always killed immediately with gtk.main_quit()
@ -217,7 +219,7 @@ class HUD_main(object):
(table_name, max, poker_game, type, site_id, site_name, num_seats, tour_number, tab_number) = \
self.db_connection.get_table_info(new_hand_id)
except Exception, err:
self.log.error("db error: skipping %s" % new_hand_id)
log.error("db error: skipping %s" % new_hand_id)
continue
t1 = time.time()
@ -276,7 +278,7 @@ class HUD_main(object):
if type == "tour":
table_name = "%s %s" % (tour_number, tab_number)
# sys.stderr.write("HUD create: table name "+table_name+" not found, skipping.\n")
self.log.error("HUD create: table name %s not found, skipping." % table_name)
log.error("HUD create: table name %s not found, skipping." % table_name)
else:
tablewindow.max = max
tablewindow.site = site_name

28
pyfpdb/Hand.py Normal file → Executable file
View File

@ -28,12 +28,14 @@ from decimal import Decimal
import operator
import time,datetime
from copy import deepcopy
from Exceptions import *
import pprint
import Configuration
from Exceptions import *
import DerivedStats
import Card
log = logging.getLogger("parser")
log = Configuration.get_logger("logging.conf", "parser")
class Hand(object):
@ -46,7 +48,9 @@ class Hand(object):
SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9, 'Partouche':10, 'Carbon':11 }
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
def __init__(self, config, sitename, gametype, handText, builtFrom = "HHC"):
self.config = config
log = Configuration.get_logger("logging.conf", "db", log_dir=self.config.dir_log)
self.sitename = sitename
self.siteId = self.SITEIDS[sitename]
self.stats = DerivedStats.DerivedStats(self)
@ -617,7 +621,8 @@ Map the tuple self.gametype onto the pokerstars string describing it
class HoldemOmahaHand(Hand):
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
def __init__(self, config, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
self.config = config
if gametype['base'] != 'hold':
pass # or indeed don't pass and complain instead
log.debug("HoldemOmahaHand")
@ -625,7 +630,7 @@ class HoldemOmahaHand(Hand):
self.holeStreets = ['PREFLOP']
self.communityStreets = ['FLOP', 'TURN', 'RIVER']
self.actionStreets = ['BLINDSANTES','PREFLOP','FLOP','TURN','RIVER']
Hand.__init__(self, sitename, gametype, handText, builtFrom = "HHC")
Hand.__init__(self, self.config, sitename, gametype, handText, builtFrom = "HHC")
self.sb = gametype['sb']
self.bb = gametype['bb']
@ -916,7 +921,8 @@ class HoldemOmahaHand(Hand):
print >>fh, "\n\n"
class DrawHand(Hand):
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC"):
def __init__(self, config, hhc, sitename, gametype, handText, builtFrom = "HHC"):
self.config = config
if gametype['base'] != 'draw':
pass # or indeed don't pass and complain instead
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
@ -924,7 +930,7 @@ class DrawHand(Hand):
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
self.actionStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
self.communityStreets = []
Hand.__init__(self, sitename, gametype, handText)
Hand.__init__(self, self.config, sitename, gametype, handText)
self.sb = gametype['sb']
self.bb = gametype['bb']
# Populate the draw hand.
@ -1108,7 +1114,8 @@ class DrawHand(Hand):
class StudHand(Hand):
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC"):
def __init__(self, config, hhc, sitename, gametype, handText, builtFrom = "HHC"):
self.config = config
if gametype['base'] != 'stud':
pass # or indeed don't pass and complain instead
@ -1118,7 +1125,7 @@ class StudHand(Hand):
self.streetList = ['BLINDSANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] # a list of the observed street names in order
self.holeStreets = ['THIRD','FOURTH','FIFTH','SIXTH','SEVENTH']
Hand.__init__(self, sitename, gametype, handText)
Hand.__init__(self, self.config, sitename, gametype, handText)
self.sb = gametype['sb']
self.bb = gametype['bb']
#Populate the StudHand
@ -1511,7 +1518,8 @@ limit 1""", {'handid':handid})
#TODO: siteid should be in hands table - we took the scenic route through players here.
res = c.fetchone()
gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]}
h = HoldemOmahaHand(hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
c = Configuration.Config()
h = HoldemOmahaHand(config = c, hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
cards = map(Card.valueSuitFromCard, res[11:16] )
if cards[0]:
h.setCommunityCards('FLOP', cards[0:3])

19
pyfpdb/HandHistoryConverter.py Normal file → Executable file
View File

@ -16,8 +16,6 @@
#In the "official" distribution you can find the license in
#agpl-3.0.txt in the docs folder of the package.
import Hand
import Tourney
import re
import sys
import traceback
@ -31,13 +29,16 @@ import operator
from xml.dom.minidom import Node
import time
import datetime
import Hand
import Tourney
from Exceptions import FpdbParseError
import Configuration
import gettext
gettext.install('fpdb')
log = Configuration.get_logger("logging.conf")
log = Configuration.get_logger("logging.conf", "parser")
import pygtk
import gtk
@ -57,12 +58,14 @@ class HandHistoryConverter():
codepage = "cp1252"
def __init__(self, in_path = '-', out_path = '-', follow=False, index=0, autostart=True, starsArchive=False):
def __init__(self, config, in_path = '-', out_path = '-', follow=False, index=0, autostart=True, starsArchive=False):
"""\
in_path (default '-' = sys.stdin)
out_path (default '-' = sys.stdout)
follow : whether to tail -f the input"""
self.config = config
log = Configuration.get_logger("logging.conf", "parser", log_dir=self.config.dir_log)
log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) )
self.index = index
@ -283,11 +286,11 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
if l in self.readSupportedGames():
if gametype['base'] == 'hold':
log.debug("hand = Hand.HoldemOmahaHand(self, self.sitename, gametype, handtext)")
hand = Hand.HoldemOmahaHand(self, self.sitename, gametype, handText)
hand = Hand.HoldemOmahaHand(self.config, self, self.sitename, gametype, handText)
elif gametype['base'] == 'stud':
hand = Hand.StudHand(self, self.sitename, gametype, handText)
hand = Hand.StudHand(self.config, self, self.sitename, gametype, handText)
elif gametype['base'] == 'draw':
hand = Hand.DrawHand(self, self.sitename, gametype, handText)
hand = Hand.DrawHand(self.config, self, self.sitename, gametype, handText)
else:
log.info("Unsupported game type: %s" % gametype)
@ -417,7 +420,7 @@ or None if we fail to get the info """
list.pop() #Last entry is empty
for l in list:
# print "'" + l + "'"
hands = hands + [Hand.Hand(self.sitename, self.gametype, l)]
hands = hands + [Hand.Hand(self.config, self.sitename, self.gametype, l)]
# TODO: This looks like it could be replaced with a list comp.. ?
return hands

View File

@ -695,6 +695,7 @@ class fpdb:
def load_profile(self):
"""Loads profile from the provided path name."""
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
log = Configuration.get_logger("logging.conf", "fpdb", log_dir=self.config.dir_log)
self.settings = {}
self.settings['global_lock'] = self.lock
if (os.sep=="/"):

3
pyfpdb/fpdb_import.py Normal file → Executable file
View File

@ -65,6 +65,7 @@ class Importer:
self.config = config
self.sql = sql
log = Configuration.get_logger("logging.conf", "importer", log_dir=self.config.dir_log)
self.filelist = {}
self.dirlist = {}
self.siteIds = {}
@ -429,7 +430,7 @@ class Importer:
idx = self.pos_in_file[file]
else:
self.pos_in_file[file] = 0
hhc = obj(in_path = file, out_path = out_path, index = idx, starsArchive = self.settings['starsArchive'])
hhc = obj(self.config, in_path = file, out_path = out_path, index = idx, starsArchive = self.settings['starsArchive'])
if hhc.getStatus():
handlist = hhc.getProcessedHands()
self.pos_in_file[file] = hhc.getLastCharacterRead()

31
pyfpdb/logging.conf Normal file → Executable file
View File

@ -1,64 +1,69 @@
[loggers]
keys=root,parser,importer,config,db
keys=root,fpdb,logview,parser,importer,config,db,hud
[handlers]
keys=consoleHandler,fileHandler
keys=consoleHandler,rotatingFileHandler
[formatters]
keys=fileFormatter,stderrFormatter
[logger_root]
level=INFO
handlers=consoleHandler,fileHandler
handlers=consoleHandler,rotatingFileHandler
[logger_fpdb]
level=INFO
handlers=consoleHandler,fileHandler
handlers=consoleHandler,rotatingFileHandler
qualname=fpdb
propagate=0
[logger_logview]
level=INFO
handlers=consoleHandler,fileHandler
handlers=consoleHandler,rotatingFileHandler
qualname=logview
propagate=0
[logger_parser]
level=INFO
handlers=consoleHandler,fileHandler
handlers=consoleHandler,rotatingFileHandler
qualname=parser
propagate=0
[logger_importer]
level=DEBUG
handlers=consoleHandler,fileHandler
handlers=consoleHandler,rotatingFileHandler
qualname=importer
propagate=0
[logger_config]
level=INFO
handlers=consoleHandler,fileHandler
handlers=consoleHandler,rotatingFileHandler
qualname=config
propagate=0
[logger_db]
level=DEBUG
handlers=consoleHandler,fileHandler
handlers=consoleHandler,rotatingFileHandler
qualname=db
propagate=0
[logger_hud]
level=DEBUG
handlers=consoleHandler,rotatingFileHandler
qualname=hud
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=ERROR
formatter=stderrFormatter
args=(sys.stderr,)
[handler_fileHandler]
class=FileHandler
[handler_rotatingFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=fileFormatter
args=('logging.out', 'a')
args=('%(logFile)s', 'a', 50000, 5)
[formatter_fileFormatter]
format=%(asctime)s - %(name)-12s %(levelname)-8s %(message)s