From cc5f77e950421dbd708e1e9ba773fc91784a6bf7 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 31 Jan 2010 11:16:42 +0000 Subject: [PATCH 01/10] fix windows problem starting hud --- pyfpdb/GuiAutoImport.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyfpdb/GuiAutoImport.py b/pyfpdb/GuiAutoImport.py index 628f7b7f..339ce968 100755 --- a/pyfpdb/GuiAutoImport.py +++ b/pyfpdb/GuiAutoImport.py @@ -194,7 +194,8 @@ class GuiAutoImport (threading.Thread): widget.set_label(u' _Stop Autoimport ') if self.pipe_to_hud is None: if os.name == 'nt': - command = "python "+sys.path[0]+"\\HUD_main.py " + self.settings['cl_options'] + path = sys.path[0].replace('\\','\\\\') + command = 'python "'+path+'\\HUD_main.py" ' + self.settings['cl_options'] bs = 0 else: command = os.path.join(sys.path[0], 'HUD_main.py') From 5e9486aa3dc16ebd105f976c483d5f44d2b0e65c Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 31 Jan 2010 11:25:24 +0000 Subject: [PATCH 02/10] 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/ --- pyfpdb/Configuration.py | 57 ++++++++++++++++++++++++---------- pyfpdb/Database.py | 12 ++++--- pyfpdb/HUD_main.py | 56 +++++++++++++++++---------------- pyfpdb/Hand.py | 28 +++++++++++------ pyfpdb/HandHistoryConverter.py | 19 +++++++----- pyfpdb/fpdb.py | 1 + pyfpdb/fpdb_import.py | 3 +- pyfpdb/logging.conf | 31 ++++++++++-------- 8 files changed, 126 insertions(+), 81 deletions(-) mode change 100644 => 100755 pyfpdb/Hand.py mode change 100644 => 100755 pyfpdb/HandHistoryConverter.py mode change 100644 => 100755 pyfpdb/fpdb_import.py mode change 100644 => 100755 pyfpdb/logging.conf diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 639007f1..fd40b408 100644 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -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 diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 754af54a..d91681be 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -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() diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index df144e92..c792d802 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -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 diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py old mode 100644 new mode 100755 index 9c7ea23f..0f69121a --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -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]) diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py old mode 100644 new mode 100755 index bec2ebae..45760ee6 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -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 diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index f202698d..12c05d11 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -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=="/"): diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py old mode 100644 new mode 100755 index 859a6bc0..a02d3d99 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -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() diff --git a/pyfpdb/logging.conf b/pyfpdb/logging.conf old mode 100644 new mode 100755 index 1b54b453..4ca06db1 --- a/pyfpdb/logging.conf +++ b/pyfpdb/logging.conf @@ -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 From f7b402bcdb8ec309fa6340e532cb85c499706883 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 31 Jan 2010 11:27:37 +0000 Subject: [PATCH 03/10] remove execute from permissions on some files in last commit --- pyfpdb/Hand.py | 0 pyfpdb/HandHistoryConverter.py | 0 pyfpdb/fpdb_import.py | 0 pyfpdb/logging.conf | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 pyfpdb/Hand.py mode change 100755 => 100644 pyfpdb/HandHistoryConverter.py mode change 100755 => 100644 pyfpdb/fpdb_import.py mode change 100755 => 100644 pyfpdb/logging.conf diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py old mode 100755 new mode 100644 diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py old mode 100755 new mode 100644 diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py old mode 100755 new mode 100644 diff --git a/pyfpdb/logging.conf b/pyfpdb/logging.conf old mode 100755 new mode 100644 From bbc84fef14ebdb6f5d9015746807e43698fc9f68 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 31 Jan 2010 12:22:24 +0000 Subject: [PATCH 04/10] comment out debug message --- pyfpdb/Database.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index d91681be..ebdfceaa 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -788,7 +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) + #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() From 6f0ea2580b4c8e484ef0a0bbc31944986e11b3a5 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 31 Jan 2010 12:24:32 +0000 Subject: [PATCH 05/10] display dialog when .example config has been copied, this could work 'out-of-the-box' if the user already has gtk?? --- pyfpdb/Configuration.py | 19 +++++++++---------- pyfpdb/fpdb.py | 27 ++++++++++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index fd40b408..9c7e44b6 100644 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -67,17 +67,17 @@ def get_config(file_name, fallback = True): 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 + return (config_path,False) # so we use it else: # no file in the cwd, look where it should be in the first place default_dir = get_default_config_path() config_path = os.path.join(default_dir, file_name) # print "config path 2=", config_path if os.path.exists(config_path): - return config_path + return (config_path,False) # No file found if not fallback: - return False + return (False,False) # OK, fall back to the .example file, should be in the start dir if os.path.exists(file_name + ".example"): @@ -85,10 +85,8 @@ def get_config(file_name, fallback = True): print "" 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 \ - + "Edit your screen_name and hand history path in the supported_sites "\ - + "section of the \nPreferences window (Main menu) before trying to import hands." + msg = "No %s found\n in %s\n or %s\n" % (file_name, exec_dir, default_dir) \ + + "Config file has been created at %s.\n" % config_path print msg logging.info(msg) file_name = config_path @@ -101,10 +99,10 @@ def get_config(file_name, fallback = True): 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 + return (file_name,True) def get_logger(file_name, config = "config", fallback = False, log_dir=None): - conf_file = get_config(file_name, fallback = fallback) + (conf_file,copied) = get_config(file_name, fallback = fallback) if conf_file: try: if log_dir is None: @@ -445,6 +443,7 @@ class Config: # 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.example_copy = False if file is not None: # config file path passed in file = os.path.expanduser(file) if not os.path.exists(file): @@ -452,7 +451,7 @@ class Config: sys.stderr.write("Configuration file %s not found. Using defaults." % (file)) file = None - if file is None: file = get_config("HUD_config.xml", True) + if file is None: (file,self.example_copy) = get_config("HUD_config.xml", True) self.file = file self.dir_self = get_exec_path() diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index 12c05d11..58e0128d 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -696,6 +696,11 @@ 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) + if self.config.example_copy: + self.info_box( "Config file" + , "has been created at:\n%s.\n" % self.config.file + + "Edit your screen_name and hand history path in the supported_sites " + + "section of the Preferences window (Main menu) before trying to import hands.") self.settings = {} self.settings['global_lock'] = self.lock if (os.sep=="/"): @@ -963,16 +968,24 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") self.window.show() self.window.present() + def info_box(self, str1, str2): + diapath = gtk.MessageDialog( parent=None, flags=0, type=gtk.MESSAGE_INFO + , buttons=(gtk.BUTTONS_OK), message_format=str1 ) + diapath.format_secondary_text(str2) + response = diapath.run() + diapath.destroy() + return response + def warning_box(self, str, diatitle="FPDB WARNING"): - diaWarning = gtk.Dialog(title=diatitle, parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) + diaWarning = gtk.Dialog(title=diatitle, parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) - label = gtk.Label(str) - diaWarning.vbox.add(label) - label.show() + label = gtk.Label(str) + diaWarning.vbox.add(label) + label.show() - response = diaWarning.run() - diaWarning.destroy() - return response + response = diaWarning.run() + diaWarning.destroy() + return response def validate_config(self): hhbase = self.config.get_import_parameters().get("hhArchiveBase") From 002a84ba5aab269809df1a7a2d5a65735a709eed Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 31 Jan 2010 12:31:49 +0000 Subject: [PATCH 06/10] set rotating logs to max 5 files of 100MB each --- pyfpdb/logging.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/logging.conf b/pyfpdb/logging.conf index 4ca06db1..a7c0323f 100644 --- a/pyfpdb/logging.conf +++ b/pyfpdb/logging.conf @@ -63,7 +63,7 @@ args=(sys.stderr,) class=handlers.RotatingFileHandler level=DEBUG formatter=fileFormatter -args=('%(logFile)s', 'a', 50000, 5) +args=('%(logFile)s', 'a', 100000000, 5) [formatter_fileFormatter] format=%(asctime)s - %(name)-12s %(levelname)-8s %(message)s From 264b75b5b0b155efdfeeb59c57d61cddd3e40d37 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 31 Jan 2010 23:46:51 +0000 Subject: [PATCH 07/10] fix some sqlite and unicode issues (thanks to Gerko) --- pyfpdb/Filters.py | 3 ++- pyfpdb/GuiGraphViewer.py | 2 +- pyfpdb/SQL.py | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py index 7f75cc4e..d5dec059 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -297,7 +297,8 @@ class Filters(threading.Thread): def __set_hero_name(self, w, site): _name = w.get_text() - _guiname = Charset.to_gui(_name) + # 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]) diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index ce9648ae..dcfa979c 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -319,7 +319,7 @@ class GuiGraphViewer (threading.Thread): winnings = self.db.cursor.fetchall() self.db.rollback() - if winnings == (): + if len(winnings) == 0: return (None, None, None) green = map(lambda x:float(x[1]), winnings) diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 43925c01..7a83ac99 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -2021,6 +2021,7 @@ class Sql: elif db_server == 'sqlite': self.query['playerDetailedStats'] = """ select AS hgametypeid + , AS pname ,gt.base ,gt.category AS category ,upper(gt.limitType) AS limittype @@ -2072,6 +2073,7 @@ class Sql: inner join Hands h on (h.id = hp.handId) inner join Gametypes gt on (gt.Id = h.gameTypeId) inner join Sites s on (s.Id = gt.siteId) + inner join Players p on (p.Id = hp.playerId) where hp.playerId in /*and hp.tourneysPlayersId IS NULL*/ From e4c6419074d7ce52b0620c60c0f063448ad0d26d Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Mon, 1 Feb 2010 00:17:55 +0000 Subject: [PATCH 08/10] try to improve tourney handling in filter (now displays buyin, but this is not yet used by playerstats when fetching stats --- pyfpdb/Database.py | 3 ++- pyfpdb/Filters.py | 4 ++-- pyfpdb/GuiPlayerStats.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index ebdfceaa..a987b389 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -788,10 +788,11 @@ 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/Filters.py b/pyfpdb/Filters.py index d5dec059..96245898 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -594,7 +594,7 @@ class Filters(threading.Thread): vbox.pack_start(vbox1, False, False, 0) self.boxes['limits'] = vbox1 - self.cursor.execute(self.sql.query['getLimits2']) + self.cursor.execute(self.sql.query['getLimits3']) # selects limitType, bigBlind result = self.db.cursor.fetchall() found = {'nl':False, 'fl':False, 'pl':False, 'ring':False, 'tour':False} @@ -615,7 +615,7 @@ class Filters(threading.Thread): vbox2.pack_start(hbox, False, False, 0) else: vbox3.pack_start(hbox, False, False, 0) - if line[0] == 'ring': + if True: #line[0] == 'ring': if line[1] == 'fl': name = str(line[2]) found['fl'] = True diff --git a/pyfpdb/GuiPlayerStats.py b/pyfpdb/GuiPlayerStats.py index 11b14274..cb94859d 100644 --- a/pyfpdb/GuiPlayerStats.py +++ b/pyfpdb/GuiPlayerStats.py @@ -526,7 +526,7 @@ class GuiPlayerStats (threading.Thread): if type == 'ring': bbtest = bbtest + " and gt.type = 'ring' " elif type == 'tour': - bbtest = bbtest + " and gt.type = 'tour' " + bbtest = " and gt.type = 'tour' " query = query.replace("", bbtest) if holecards: # re-use level variables for hole card query From 9f3c5924b071eed1b8315a96e103d11de7a6ee42 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Mon, 1 Feb 2010 07:59:09 +0000 Subject: [PATCH 09/10] oops! missed out SQL.py from last release --- pyfpdb/SQL.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 7a83ac99..647bc82c 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1848,6 +1848,15 @@ class Sql: self.query['getLimits2'] = """SELECT DISTINCT type, limitType, bigBlind from Gametypes ORDER by type, limitType DESC, bigBlind DESC""" + self.query['getLimits3'] = """select DISTINCT type + , limittype + , case type + when 'ring' then bigblind + else buyin + end as bb_or_buyin + from gametypes gt + cross join tourneytypes tt + order by type, limitType DESC, bb_or_buyin DESC""" if db_server == 'mysql': self.query['playerDetailedStats'] = """ From a06aac6da870f38f92c1232e0aee85359229868f Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Mon, 1 Feb 2010 08:22:14 +0000 Subject: [PATCH 10/10] correct case in SQL --- pyfpdb/SQL.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 647bc82c..6db24fb4 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1849,13 +1849,13 @@ 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 - cross join tourneytypes tt + from Gametypes gt + cross join TourneyTypes tt order by type, limitType DESC, bb_or_buyin DESC""" if db_server == 'mysql':