diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py old mode 100644 new mode 100755 index 9c7e44b6..ec4c621e --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -38,6 +38,10 @@ from xml.dom.minidom import Node import logging, logging.config import ConfigParser +# logging has been set up in fpdb.py or HUD_main.py, use their settings: +log = logging.getLogger("config") + + ############################################################################## # Functions for finding config files and setting up logging # Also used in other modules that use logging. @@ -138,8 +142,6 @@ def check_dir(path, create = True): else: return False -# find a logging.conf file and set up logging -log = get_logger("logging.conf", "config") ######################################################################## # application wide consts @@ -458,6 +460,7 @@ class Config: 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') + self.log_file = os.path.join(self.dir_log, 'logging.out') 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 diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 4b672733..e0649b78 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -41,6 +41,10 @@ import Queue import codecs import math +import logging +# logging has been set up in fpdb.py or HUD_main.py, use their settings: +log = logging.getLogger("db") + # pyGTK modules @@ -52,7 +56,6 @@ import Tourney import Charset from Exceptions import * import Configuration -log = Configuration.get_logger("logging.conf","db") # Other library modules @@ -224,8 +227,8 @@ 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) + #log = Configuration.get_logger("logging.conf", "db", log_dir=c.dir_log) + log.debug("Creating Database instance, sql = %s" % sql) self.config = c self.__connected = False self.settings = {} @@ -236,6 +239,7 @@ class Database: self.db_server = db_params['db-server'] self.database = db_params['db-databaseName'] self.host = db_params['db-host'] + self.db_path = '' # where possible avoid creating new SQL instance by using the global one passed in if sql is None: @@ -385,9 +389,9 @@ class 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 ) + self.db_path = database + log.info("Connecting to SQLite: %(database)s" % {'database':self.db_path}) + self.connection = sqlite3.connect(self.db_path, detect_types=sqlite3.PARSE_DECLTYPES ) sqlite3.register_converter("bool", lambda x: bool(int(x))) sqlite3.register_adapter(bool, lambda x: "1" if x else "0") self.connection.create_function("floor", 1, math.floor) @@ -788,11 +792,10 @@ 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) + #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() - print "player id =", row if row: return row[0] else: diff --git a/pyfpdb/DerivedStats.py b/pyfpdb/DerivedStats.py index 88bb6407..23f1f99c 100644 --- a/pyfpdb/DerivedStats.py +++ b/pyfpdb/DerivedStats.py @@ -56,7 +56,6 @@ class DerivedStats(): self.handsplayers[player[1]]['stealAttemptChance'] = False self.handsplayers[player[1]]['stealAttempted'] = False self.handsplayers[player[1]]['foldBbToStealChance'] = False - self.handsplayers[player[1]]['foldBbToStealChance'] = False self.handsplayers[player[1]]['foldSbToStealChance'] = False self.handsplayers[player[1]]['foldedSbToSteal'] = False self.handsplayers[player[1]]['foldedBbToSteal'] = False @@ -281,33 +280,37 @@ class DerivedStats(): def calcSteals(self, hand): """Fills stealAttempt(Chance|ed, fold(Bb|Sb)ToSteal(Chance|) - Steal attemp - open raise on positions 2 1 0 S - i.e. MP3, CO, BU, SB + Steal attempt - open raise on positions 1 0 S - i.e. MP3, CO, BU, SB Fold to steal - folding blind after steal attemp wo any other callers or raisers """ - steal_attemp = False - steal_positions = ('2', '1', '0', 'S') + steal_attempt = False + steal_positions = (1, 0, 'S') if hand.gametype['base'] == 'stud': - steal_positions = ('2', '1', '0') + steal_positions = (2, 1, 0) for action in hand.actions[hand.actionStreets[1]]: pname, act = action[0], action[1] - #print action[0], hp.position, steal_attemp, act - if self.handsplayers[pname]['position'] == 'B': + posn = self.handsplayers[pname]['position'] + #print "\naction:", action[0], posn, type(posn), steal_attempt, act + if posn == 'B': #NOTE: Stud games will never hit this section - self.handsplayers[pname]['foldBbToStealChance'] = steal_attemp - self.handsplayers[pname]['foldBbToSteal'] = self.handsplayers[pname]['foldBbToStealChance'] and act == 'folds' + self.handsplayers[pname]['foldBbToStealChance'] = steal_attempt + self.handsplayers[pname]['foldedBbToSteal'] = steal_attempt and act == 'folds' break - elif self.handsplayers[pname]['position'] == 'S': - self.handsplayers[pname]['foldSbToStealChance'] = steal_attemp - self.handsplayers[pname]['foldSbToSteal'] = self.handsplayers[pname]['foldSbToStealChance'] and act == 'folds' + elif posn == 'S': + self.handsplayers[pname]['foldSbToStealChance'] = steal_attempt + self.handsplayers[pname]['foldedSbToSteal'] = steal_attempt and act == 'folds' - if steal_attemp and act != 'folds': + if steal_attempt and act != 'folds': break - if self.handsplayers[pname]['position'] in steal_positions and not steal_attemp: + if posn in steal_positions and not steal_attempt: self.handsplayers[pname]['stealAttemptChance'] = True if act in ('bets', 'raises'): self.handsplayers[pname]['stealAttempted'] = True - steal_attemp = True + steal_attempt = True + + if posn not in steal_positions and act != 'folds': + break def calc34BetStreet0(self, hand): """Fills street0_(3|4)B(Chance|Done), other(3|4)BStreet0""" diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py index 96245898..27e5a49d 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -26,16 +26,21 @@ from time import * import gobject #import pokereval +import logging +# logging has been set up in fpdb.py or HUD_main.py, use their settings: +log = logging.getLogger("filter") + + import Configuration import Database import SQL import Charset + class Filters(threading.Thread): def __init__(self, db, config, qdict, display = {}, debug=True): # config and qdict are now redundant self.debug = debug - #print "start of GraphViewer constructor" self.db = db self.cursor = db.cursor self.sql = db.sql @@ -268,10 +273,10 @@ class Filters(threading.Thread): self.callback['button2'] = callback def cardCallback(self, widget, data=None): - print "DEBUG: %s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()]) + log.debug( "%s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()]) ) def createPlayerLine(self, hbox, site, player): - print 'DEBUG :: add:"%s"' % player + log.debug('add:"%s"' % player) label = gtk.Label(site +" id:") hbox.pack_start(label, False, False, 3) @@ -300,14 +305,14 @@ class Filters(threading.Thread): # get_text() returns a str but we want internal variables to be unicode: _guiname = unicode(_name) self.heroes[site] = _guiname -# print "DEBUG: setting heroes[%s]: %s"%(site, self.heroes[site]) +# log.debug("setting heroes[%s]: %s"%(site, self.heroes[site])) def __set_num_hands(self, w, val): try: self.numHands = int(w.get_text()) except: self.numHands = 0 -# print "DEBUG: setting numHands:", self.numHands +# log.debug("setting numHands:", self.numHands) def createSiteLine(self, hbox, site): cb = gtk.CheckButton(site) @@ -332,17 +337,17 @@ class Filters(threading.Thread): def __set_site_select(self, w, site): #print w.get_active() self.sites[site] = w.get_active() - print "self.sites[%s] set to %s" %(site, self.sites[site]) + log.debug("self.sites[%s] set to %s" %(site, self.sites[site])) def __set_game_select(self, w, game): #print w.get_active() self.games[game] = w.get_active() - print "self.games[%s] set to %s" %(game, self.games[game]) + log.debug("self.games[%s] set to %s" %(game, self.games[game])) def __set_limit_select(self, w, limit): #print w.get_active() self.limits[limit] = w.get_active() - print "self.limit[%s] set to %s" %(limit, self.limits[limit]) + log.debug("self.limit[%s] set to %s" %(limit, self.limits[limit])) if limit.isdigit() or (len(limit) > 2 and (limit[-2:] == 'nl' or limit[-2:] == 'fl' or limit[-2:] == 'pl')): if self.limits[limit]: if self.cbNoLimits is not None: @@ -428,9 +433,11 @@ class Filters(threading.Thread): if self.limits[limit]: if not found[self.type]: if self.type == 'ring': - self.rb['tour'].set_active(True) + if 'tour' in self.rb: + self.rb['tour'].set_active(True) elif self.type == 'tour': - self.rb['ring'].set_active(True) + if 'ring' in self.rb: + self.rb['ring'].set_active(True) elif limit == "pl": if not self.limits[limit]: # only toggle all nl limits off if they are all currently on @@ -452,11 +459,13 @@ class Filters(threading.Thread): if self.limits[limit]: if not found[self.type]: if self.type == 'ring': - self.rb['tour'].set_active(True) + if 'tour' in self.rb: + self.rb['tour'].set_active(True) elif self.type == 'tour': - self.rb['ring'].set_active(True) + if 'ring' in self.rb: + self.rb['ring'].set_active(True) elif limit == "ring": - print "set", limit, "to", self.limits[limit] + log.debug("set", limit, "to", self.limits[limit]) if self.limits[limit]: self.type = "ring" for cb in self.cbLimits.values(): @@ -464,7 +473,7 @@ class Filters(threading.Thread): if self.types[cb.get_children()[0].get_text()] == 'tour': cb.set_active(False) elif limit == "tour": - print "set", limit, "to", self.limits[limit] + log.debug( "set", limit, "to", self.limits[limit] ) if self.limits[limit]: self.type = "tour" for cb in self.cbLimits.values(): @@ -475,12 +484,12 @@ class Filters(threading.Thread): def __set_seat_select(self, w, seat): #print "__set_seat_select: seat =", seat, "active =", w.get_active() self.seats[seat] = w.get_active() - print "self.seats[%s] set to %s" %(seat, self.seats[seat]) + log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) ) def __set_group_select(self, w, group): #print "__set_seat_select: seat =", seat, "active =", w.get_active() self.groups[group] = w.get_active() - print "self.groups[%s] set to %s" %(group, self.groups[group]) + log.debug( "self.groups[%s] set to %s" %(group, self.groups[group]) ) def fillPlayerFrame(self, vbox, display): top_hbox = gtk.HBox(False, 0) @@ -579,6 +588,7 @@ class Filters(threading.Thread): self.createGameLine(hbox, line[0]) else: print "INFO: No games returned from database" + log.info("No games returned from database") def fillLimitsFrame(self, vbox, display): top_hbox = gtk.HBox(False, 0) @@ -660,6 +670,7 @@ class Filters(threading.Thread): dest = vbox2 # for ring/tour buttons else: print "INFO: No games returned from database" + log.info("No games returned from database") if "Type" in display and display["Type"] == True and found['ring'] and found['tour']: rb1 = gtk.RadioButton(None, self.filterText['ring']) diff --git a/pyfpdb/GuiLogView.py b/pyfpdb/GuiLogView.py index 29385fa0..9dcb9588 100755 --- a/pyfpdb/GuiLogView.py +++ b/pyfpdb/GuiLogView.py @@ -26,13 +26,13 @@ import gtk import gobject import pango -import Configuration +import logging +# logging has been set up in fpdb.py or HUD_main.py, use their settings: +log = logging.getLogger("logview") -log = Configuration.get_logger("logging.conf", "logview") MAX_LINES = 100000 # max lines to display in window EST_CHARS_PER_LINE = 150 # used to guesstimate number of lines in log file -logfile = 'logging.out' # name of logfile class GuiLogView: @@ -41,6 +41,7 @@ class GuiLogView: self.main_window = mainwin self.closeq = closeq + self.logfile = self.config.log_file # name of logfile self.dia = gtk.Dialog(title="Log Messages" ,parent=None ,flags=gtk.DIALOG_DESTROY_WITH_PARENT @@ -117,10 +118,10 @@ class GuiLogView: self.listcols = [] # guesstimate number of lines in file - if os.path.exists(logfile): - stat_info = os.stat(logfile) + if os.path.exists(self.logfile): + stat_info = os.stat(self.logfile) lines = stat_info.st_size / EST_CHARS_PER_LINE - print "logview: size =", stat_info.st_size, "lines =", lines + #print "logview: size =", stat_info.st_size, "lines =", lines # set startline to line number to start display from startline = 0 @@ -129,7 +130,7 @@ class GuiLogView: startline = lines - MAX_LINES l = 0 - for line in open(logfile): + for line in open(self.logfile): # eg line: # 2009-12-02 15:23:21,716 - config DEBUG config logger initialised l = l + 1 diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index c792d802..bae58825 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -35,9 +35,6 @@ import traceback (options, argv) = Options.fpdb_options() -if not options.errorsToConsole: - print "Note: error output is being logged. Any major error will be reported there _only_." - import thread import time import string @@ -51,9 +48,6 @@ import gobject # FreePokerTools modules import Configuration -log = Configuration.get_logger("logging.conf", config = 'hud') -log.debug("%s logger initialized." % "hud") - import Database from HandHistoryConverter import getTableTitleRe @@ -66,6 +60,10 @@ elif os.name == 'nt': import Hud +# logger is set up in __init__, create temp logger here +log = Configuration.get_logger("logging.conf", config = 'hud') + + 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. @@ -74,9 +72,18 @@ class HUD_main(object): try: print "HUD_main: starting ..." self.db_name = db_name - self.config = Configuration.Config(file=options.config, dbname=options.dbname) + self.config = Configuration.Config(file=options.config, dbname=db_name) log = Configuration.get_logger("logging.conf", "hud", log_dir=self.config.dir_log) - log.debug("starting ...") + log.info("HUD_main starting") + log.info("Using db name = %s" % (db_name)) + + if not options.errorsToConsole: + fileName = os.path.join(self.config.dir_log, 'HUD-errors.txt') + print "Note: error output is being diverted to\n"+fileName \ + + "\nAny major error will be reported there _only_.\n" + errorFile = open(fileName, 'w', 0) + sys.stderr = errorFile + self.hud_dict = {} self.hud_params = self.config.get_hud_ui_parameters() @@ -295,9 +302,6 @@ class HUD_main(object): if __name__== "__main__": - log.info("HUD_main starting") - log.info("Using db name = %s" % (options.dbname)) - # start the HUD_main object hm = HUD_main(db_name = options.dbname) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 0f69121a..9bec209b 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -21,7 +21,6 @@ import re import sys import traceback -import logging import os import os.path from decimal import Decimal @@ -30,12 +29,16 @@ import time,datetime from copy import deepcopy import pprint +import logging +# logging has been set up in fpdb.py or HUD_main.py, use their settings: +log = logging.getLogger("parser") + + import Configuration from Exceptions import * import DerivedStats import Card -log = Configuration.get_logger("logging.conf", "parser") class Hand(object): @@ -50,7 +53,7 @@ class Hand(object): 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) + #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) diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index 45760ee6..fa1805e0 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -30,6 +30,11 @@ from xml.dom.minidom import Node import time import datetime +import logging +# logging has been set up in fpdb.py or HUD_main.py, use their settings: +log = logging.getLogger("parser") + + import Hand import Tourney from Exceptions import FpdbParseError @@ -38,7 +43,6 @@ import Configuration import gettext gettext.install('fpdb') -log = Configuration.get_logger("logging.conf", "parser") import pygtk import gtk @@ -65,7 +69,7 @@ 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 = 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 diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 36a908d2..6db24fb4 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1849,9 +1849,9 @@ class Sql: from Gametypes ORDER by type, limitType DESC, bigBlind DESC""" self.query['getLimits3'] = """select DISTINCT type - , limittype + , limitType , case type - when 'ring' then bigblind + when 'ring' then bigBlind else buyin end as bb_or_buyin from Gametypes gt diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index 58e0128d..d5e0350d 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -53,7 +53,7 @@ if os.name == 'nt': raw_input("Press ENTER to continue.") exit() -print "Python " + sys.version[0:3] + '...\n' +print "Python " + sys.version[0:3] + '...' import traceback import threading @@ -62,12 +62,6 @@ import string cl_options = string.join(sys.argv[1:]) (options, argv) = Options.fpdb_options() -if not options.errorsToConsole: - print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_." - errorFile = open('fpdb-error-log.txt', 'w', 0) - sys.stderr = errorFile - -#import logging import logging, logging.config try: @@ -117,7 +111,6 @@ import Exceptions VERSION = "0.12" -log = Configuration.get_logger("logging.conf", "fpdb") class fpdb: def tab_clicked(self, widget, tab_name): @@ -696,6 +689,7 @@ class fpdb: """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) + print "Logfile is " + os.path.join(self.config.dir_log, 'logging.out') + "\n" if self.config.example_copy: self.info_box( "Config file" , "has been created at:\n%s.\n" % self.config.file @@ -721,6 +715,9 @@ class fpdb: err_msg = None try: self.db = Database.Database(self.config, sql = self.sql) + if self.db.get_backend_name() == 'SQLite': + # tell sqlite users where the db file is + print "Connected to SQLite: %(database)s" % {'database':self.db.db_path} except Exceptions.FpdbMySQLAccessDenied: err_msg = "MySQL Server reports: Access denied. Are your permissions set correctly?" except Exceptions.FpdbMySQLNoDatabase: @@ -907,6 +904,13 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") self.window.show() self.load_profile() + if not options.errorsToConsole: + fileName = os.path.join(self.config.dir_log, 'fpdb-errors.txt') + print "\nNote: error output is being diverted to fpdb-errors.txt and HUD-errors.txt in\n" \ + + self.config.dir_log + "Any major error will be reported there _only_.\n" + errorFile = open(fileName, 'w', 0) + sys.stderr = errorFile + self.statusIcon = gtk.StatusIcon() if os.path.exists(os.path.join(sys.path[0], '../gfx/fpdb-cards.png')): self.statusIcon.set_from_file(os.path.join(sys.path[0], '../gfx/fpdb-cards.png')) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py old mode 100644 new mode 100755 index a02d3d99..95ffd525 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -30,6 +30,10 @@ import Queue from collections import deque # using Queue for now import threading +import logging +# logging has been set up in fpdb.py or HUD_main.py, use their settings: +log = logging.getLogger("importer") + import pygtk import gtk @@ -39,7 +43,6 @@ import Database import Configuration import Exceptions -log = Configuration.get_logger("logging.conf", "importer") # database interface modules try: @@ -65,7 +68,7 @@ class Importer: self.config = config self.sql = sql - log = Configuration.get_logger("logging.conf", "importer", log_dir=self.config.dir_log) + #log = Configuration.get_logger("logging.conf", "importer", log_dir=self.config.dir_log) self.filelist = {} self.dirlist = {} self.siteIds = {} @@ -448,14 +451,14 @@ class Importer: to_hud.append(hand.dbid_hands) else: # TODO: Treat empty as an error, or just ignore? log.error("Hand processed but empty") - self.database.commit() + # Call hudcache update if not in bulk import mode # FIXME: Need to test for bulk import that isn't rebuilding the cache if self.callHud: for hand in handlist: if hand is not None: hand.updateHudCache(self.database) - self.database.commit() + self.database.commit() #pipe the Hands.id out to the HUD for hid in to_hud: diff --git a/pyfpdb/logging.conf b/pyfpdb/logging.conf index a7c0323f..ecd74fcc 100644 --- a/pyfpdb/logging.conf +++ b/pyfpdb/logging.conf @@ -1,5 +1,5 @@ [loggers] -keys=root,fpdb,logview,parser,importer,config,db,hud +keys=root,fpdb,logview,parser,importer,config,db,hud,filter [handlers] keys=consoleHandler,rotatingFileHandler @@ -53,6 +53,12 @@ handlers=consoleHandler,rotatingFileHandler qualname=hud propagate=0 +[logger_filter] +level=INFO +handlers=consoleHandler,rotatingFileHandler +qualname=filter +propagate=0 + [handler_consoleHandler] class=StreamHandler level=ERROR