diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index d3abfa06..904d7eb2 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -32,62 +32,22 @@ import string # pyGTK modules # FreePokerTools modules +import fpdb_db import Configuration import SQL import Card class Database: def __init__(self, c, db_name, game): + self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql + self.fdb.do_connect(c) + self.connection = self.fdb.db + db_params = c.get_db_parameters() - if (string.lower(db_params['db-server']) == 'postgresql' or - string.lower(db_params['db-server']) == 'postgres'): - import psycopg2 # posgres via DB-API - import psycopg2.extensions - psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) - - try: - if db_params['db-host'] == 'localhost' or db_params['db-host'] == '127.0.0.1': - self.connection = psycopg2.connect(database = db_params['db-databaseName']) - else: - self.connection = psycopg2.connect(host = db_params['db-host'], - user = db_params['db-user'], - password = db_params['db-password'], - database = db_params['db-databaseName']) - except: - print "Error opening database connection %s. See error log file." % (file) - traceback.print_exc(file=sys.stderr) - print "press enter to continue" - sys.stdin.readline() - sys.exit() - - elif string.lower(db_params['db-server']) == 'mysql': - import MySQLdb # mysql bindings - try: - self.connection = MySQLdb.connect(host = db_params['db-host'], - user = db_params['db-user'], - passwd = db_params['db-password'], - db = db_params['db-databaseName']) - cur_iso = self.connection.cursor() - cur_iso.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED') - cur_iso.close() - - except: - print "Error opening database connection %s. See error log file." % (file) - traceback.print_exc(file=sys.stderr) - print "press enter to continue" - sys.stdin.readline() - sys.exit() - - else: - print "Database = %s not recognized." % (c.supported_databases[db_name].db_server) - sys.stderr.write("Database not recognized, exiting.\n") - print "press enter to continue" - sys.exit() - self.type = db_params['db-type'] - self.sql = SQL.Sql(game = game, type = self.type) + self.sql = SQL.Sql(game = game, type = self.type, db_server = db_params['db-server']) self.connection.rollback() - + # To add to config: self.hud_style = 'T' # A=All-time # S=Session @@ -199,7 +159,7 @@ class Database: def get_action_from_hand(self, hand_no): action = [ [], [], [], [], [] ] c = self.connection.cursor() - c.execute(self.sql.query['get_action_from_hand'], (hand_no, )) + c.execute(self.sql.query['get_action_from_hand'], (hand_no,)) for row in c.fetchall(): street = row[0] act = row[1:] @@ -210,7 +170,7 @@ class Database: """Returns a hash of winners:amount won, given a hand number.""" winners = {} c = self.connection.cursor() - c.execute(self.sql.query['get_winners_from_hand'], (hand, )) + c.execute(self.sql.query['get_winners_from_hand'], (hand,)) for row in c.fetchall(): winners[row[0]] = row[1] return winners @@ -321,10 +281,10 @@ if __name__=="__main__": for p in stat_dict.keys(): print p, " ", stat_dict[p] -# print "nutOmatics stats:" -# stat_dict = db_connection.get_stats_from_hand(h, hero) -# for p in stat_dict.keys(): -# print p, " ", stat_dict[p] + #print "nutOmatics stats:" + #stat_dict = db_connection.get_stats_from_hand(h, hero) + #for p in stat_dict.keys(): + # print p, " ", stat_dict[p] print "cards =", db_connection.get_cards(u'1') db_connection.close_connection diff --git a/pyfpdb/FpdbRegex.py b/pyfpdb/FpdbRegex.py deleted file mode 100644 index 8bfb9362..00000000 --- a/pyfpdb/FpdbRegex.py +++ /dev/null @@ -1,161 +0,0 @@ -# pokerstars_cash.py -# -*- coding: iso-8859-15 -# -# PokerStats, an online poker statistics tracking software for Linux -# Copyright (C) 2007-2008 Mika Boström -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, version 3 of the License. -# - -# Modified for use in fpdb by Carl Gherardi - -import re - -# These are PokerStars specific; -# More importantly, they are currently valid for cash game only. -##### -# XXX: There was a weird problem with saved hand histories in PokerStars -# client 2.491; if a user was present on the table (and thus anywhere in -# the hand history), with non-standard characters in their username, the -# client would prepend a literal Ctrl-P (ASCII 16, 0x10) character to -# the hand history title line. Hence, to allow these strangely saved -# hands to be parsed and imported, there is a conditional "one extra -# character" allowed at the start of the new hand regex. - - -class FpdbRegex: - def __init__(self): - self.__GAME_INFO_REGEX='' - self.__SPLIT_HAND_REGEX='\n\n\n' - self.__NEW_HAND_REGEX='^.?PokerStars Game #\d+:\s+Hold\'em' - self.__HAND_INFO_REGEX='^.*#(\d+):\s+(\S+)\s([\s\S]+)\s\(\$?([.0-9]+)/\$?([.0-9]+)\)\s-\s(\S+)\s-?\s?(\S+)\s\(?(\w+)\)?' - self.__TABLE_INFO_REGEX='^\S+\s+\'.*\'\s+(\d+)-max\s+Seat\s#(\d+)' - self.__PLAYER_INFO_REGEX='^Seat\s(\d+):\s(.*)\s\(\$?([.\d]+)\s' - self.__POST_SB_REGEX='^(.*):\sposts small blind' - self.__POST_BB_REGEX='^(.*):\sposts big blind' - self.__POST_BOTH_REGEX='^(.*):\sposts small & big blinds' - self.__HAND_STAGE_REGEX='^\*{3}\s(.*)\s\*{3}' - self.__HOLE_CARD_REGEX='^\*{3}\sHOLE CARDS' - self.__FLOP_CARD_REGEX='^\*{3}\sFLOP\s\*{3}\s\[(\S{2})\s(\S{2})\s(\S{2})\]' - self.__TURN_CARD_REGEX='^\*{3}\sTURN\s\*{3}\s\[\S{2}\s\S{2}\s\S{2}\]\s\[(\S{2})\]' - self.__RIVER_CARD_REGEX='^\*{3}\sRIVER\s\*{3}\s\[\S{2}\s\S{2}\s\S{2}\s\S{2}\]\s\[(\S{2})\]' - self.__SHOWDOWN_REGEX='^\*{3}\sSHOW DOWN' - self.__SUMMARY_REGEX='^\*{3}\sSUMMARY' - self.__UNCALLED_BET_REGEX='^Uncalled bet \(\$([.\d]+)\) returned to (.*)' - self.__POT_AND_RAKE_REGEX='^Total\spot\s\$([.\d]+).*\|\sRake\s\$([.\d]+)' - self.__COLLECT_POT_REGEX='^(.*)\scollected\s\$([.\d]+)\sfrom\s((main|side)\s)?pot' - self.__HERO_CARDS_REGEX='^Dealt\sto\s(.*)\s\[(\S{2})\s(\S{2})\]' - self.__SHOWN_CARDS_REGEX='^(.*):\sshows\s\[(\S{2})\s(\S{2})\]' - self.__ACTION_STEP_REGEX='^(.*):\s(bets|checks|raises|calls|folds)((\s\$([.\d]+))?(\sto\s\$([.\d]+))?)?' - - self.__SHOWDOWN_ACTION_REGEX='^(.*):\s(shows|mucks)' - self.__SUMMARY_CARDS_REGEX='^Seat\s\d+:\s(.*)\s(showed|mucked)\s\[(\S{2})\s(\S{2})\]' - self.__SUMMARY_CARDS_EXTRA_REGEX='^Seat\s\d+:\s(.*)\s(\(.*\)\s)(showed|mucked)\s\[(\S{2})\s(\S{2})\]' - - def compileRegexes(self): - ### Compile the regexes - self.game_info_re = re.compile(self.__GAME_INFO_REGEX) - self.split_hand_re = re.compile(self.__SPLIT_HAND_REGEX) - self.hand_start_re = re.compile(self.__NEW_HAND_REGEX) - self.hand_info_re = re.compile(self.__HAND_INFO_REGEX) - self.table_info_re = re.compile(self.__TABLE_INFO_REGEX) - self.player_info_re = re.compile(self.__PLAYER_INFO_REGEX) - self.small_blind_re = re.compile(self.__POST_SB_REGEX) - self.big_blind_re = re.compile(self.__POST_BB_REGEX) - self.both_blinds_re = re.compile(self.__POST_BOTH_REGEX) - self.hand_stage_re = re.compile(self.__HAND_STAGE_REGEX) - self.hole_cards_re = re.compile(self.__HOLE_CARD_REGEX) - self.flop_cards_re = re.compile(self.__FLOP_CARD_REGEX) - self.turn_card_re = re.compile(self.__TURN_CARD_REGEX) - self.river_card_re = re.compile(self.__RIVER_CARD_REGEX) - self.showdown_re = re.compile(self.__SHOWDOWN_REGEX) - self.summary_re = re.compile(self.__SUMMARY_REGEX) - self.uncalled_bet_re = re.compile(self.__UNCALLED_BET_REGEX) - self.collect_pot_re = re.compile(self.__COLLECT_POT_REGEX) - self.hero_cards_re = re.compile(self.__HERO_CARDS_REGEX) - self.cards_shown_re = re.compile(self.__SHOWN_CARDS_REGEX) - self.summary_cards_re = re.compile(self.__SUMMARY_CARDS_REGEX) - self.summary_cards_extra_re = re.compile(self.__SUMMARY_CARDS_EXTRA_REGEX) - self.action_re = re.compile(self.__ACTION_STEP_REGEX) - self.rake_re = re.compile(self.__POT_AND_RAKE_REGEX) - self.showdown_action_re = re.compile(self.__SHOWDOWN_ACTION_REGEX) - - # Set methods for plugins to override - - def setGameInfoRegex(self, string): - self.__GAME_INFO_REGEX = string - - def setSplitHandRegex(self, string): - self.__SPLIT_HAND_REGEX = string - - def setNewHandRegex(self, string): - self.__NEW_HAND_REGEX = string - - def setHandInfoRegex(self, string): - self.__HAND_INFO_REGEX = string - - def setTableInfoRegex(self, string): - self.__TABLE_INFO_REGEX = string - - def setPlayerInfoRegex(self, string): - self.__PLAYER_INFO_REGEX = string - - def setPostSbRegex(self, string): - self.__POST_SB_REGEX = string - - def setPostBbRegex(self, string): - self.__POST_BB_REGEX = string - - def setPostBothRegex(self, string): - self.__POST_BOTH_REGEX = string - - def setHandStageRegex(self, string): - self.__HAND_STAGE_REGEX = string - - def setHoleCardRegex(self, string): - self.__HOLE_CARD_REGEX = string - - def setFlopCardRegex(self, string): - self.__FLOP_CARD_REGEX = string - - def setTurnCardRegex(self, string): - self.__TURN_CARD_REGEX = string - - def setRiverCardRegex(self, string): - self.__RIVER_CARD_REGEX = string - - def setShowdownRegex(self, string): - self.__SHOWDOWN_REGEX = string - - def setSummaryRegex(self, string): - self.__SUMMARY_REGEX = string - - def setUncalledBetRegex(self, string): - self.__UNCALLED_BET_REGEX = string - - def setCollectPotRegex(self, string): - self.__COLLECT_POT_REGEX = string - - def setHeroCardsRegex(self, string): - self.__HERO_CARDS_REGEX = string - - def setShownCardsRegex(self, string): - self.__SHOWN_CARDS_REGEX = string - - def setSummaryCardsRegex(self, string): - self.__SUMMARY_CARDS_REGEX = string - - def setSummaryCardsExtraRegex(self, string): - self.__SUMMARY_CARDS_EXTRA_REGEX = string - - def setActionStepRegex(self, string): - self.__ACTION_STEP_REGEX = string - - def setPotAndRakeRegex(self, string): - self.__POT_AND_RAKE_REGEX = string - - def setShowdownActionRegex(self, string): - self.__SHOWDOWN_ACTION_REGEX = string - diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index 58da2690..5884e81e 100755 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -231,7 +231,12 @@ def discover_nt_by_name(c, tablename): titles = {} win32gui.EnumWindows(win_enum_handler, titles) for hwnd in titles: - if not tablename in titles[hwnd]: continue + print "Tbales.py: tablename =", tablename, "title =", titles[hwnd] + try: + # this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html + if not tablename in titles[hwnd]: continue + except: + continue if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window if 'HUD:' in titles[hwnd]: continue # FPDB HUD window if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py index 7c1fc800..86776b82 100644 --- a/pyfpdb/fpdb_db.py +++ b/pyfpdb/fpdb_db.py @@ -578,7 +578,7 @@ class fpdb_db: self.cursor.execute( "lock tables Hands write" ) except: # Table 'fpdb.hands' doesn't exist - if str(sys.exc_value).find(".hands' doesn't exist") >= 0: + if str(sys.exc_value).find(".Hands' doesn't exist") >= 0: return(2) print "Error! failed to obtain global lock. Close all programs accessing " \ + "database (including fpdb) and try again (%s)." \ diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 3fa20b40..99330bb9 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -394,7 +394,7 @@ class Importer: self.hand=hand try: - handsId = fpdb_parse_logic.mainParser(self.settings, self.fdb.db + handsId = fpdb_parse_logic.mainParser(self.settings['db-backend'], self.fdb.db ,self.fdb.cursor, self.siteIds[site], category, hand, self.config) self.fdb.db.commit() diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py index 2d93b69f..ee5d9c40 100644 --- a/pyfpdb/fpdb_parse_logic.py +++ b/pyfpdb/fpdb_parse_logic.py @@ -35,6 +35,7 @@ def mainParser(settings, db, cursor, siteID, category, hand, config): #part 1: read hand no and check for duplicate siteHandNo = fpdb_simple.parseSiteHandNo(hand[0]) + #print "siteHandNo =", siteHandNo handStartTime = fpdb_simple.parseHandStartTime(hand[0]) isTourney = fpdb_simple.isTourney(hand[0]) @@ -127,6 +128,7 @@ def mainParser(settings, db, cursor, siteID, category, hand, config): totalWinnings = sum(winnings) # if hold'em, use positions and not antes, if stud do not use positions, use antes + # this is used for handsplayers inserts, so still needed even if hudcache update is being skipped if base == "hold": hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes , allIns, actionTypeByNo, winnings, totalWinnings, positions diff --git a/pyfpdb/fpdb_save_to_db.py b/pyfpdb/fpdb_save_to_db.py index b6e8686c..e612a166 100644 --- a/pyfpdb/fpdb_save_to_db.py +++ b/pyfpdb/fpdb_save_to_db.py @@ -34,12 +34,11 @@ saveActions = True # set this to False to avoid storing action data # variance not available on stats page # : No graphs #stores a stud/razz hand into the database -def ring_stud(config, settings, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time +def ring_stud(config, backend, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time ,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes ,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName ,seatNos): - backend = settings['db-backend'] import_options = config.get_import_parameters() saveActions = False if import_options['saveActions'] == False else True @@ -55,8 +54,7 @@ def ring_stud(config, settings, db, cursor, base, category, site_hand_no, gamety ,start_cashes, antes, card_values ,card_suits, winnings, rakes, seatNos) - if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop': - fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) + fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) if saveActions: fpdb_simple.storeActions(cursor, hands_players_ids, action_types @@ -64,13 +62,12 @@ def ring_stud(config, settings, db, cursor, base, category, site_hand_no, gamety return hands_id #end def ring_stud -def ring_holdem_omaha(config, settings, db, cursor, base, category, site_hand_no, gametype_id +def ring_holdem_omaha(config, backend, db, cursor, base, category, site_hand_no, gametype_id ,hand_start_time, names, player_ids, start_cashes, positions, card_values ,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns ,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos): """stores a holdem/omaha hand into the database""" - backend = settings['db-backend'] import_options = config.get_import_parameters() saveActions = False if import_options['saveActions'] == False else True fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False @@ -93,11 +90,10 @@ def ring_holdem_omaha(config, settings, db, cursor, base, category, site_hand_no , positions, card_values, card_suits, winnings, rakes, seatNos, hudImportData) t4 = time() #print "ring holdem, backend=%d" % backend - if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop': - if fastStoreHudCache: - fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) - else: - fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) + if fastStoreHudCache: + fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) + else: + fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) t5 = time() fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits) t6 = time() @@ -108,7 +104,7 @@ def ring_holdem_omaha(config, settings, db, cursor, base, category, site_hand_no return hands_id #end def ring_holdem_omaha -def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout +def tourney_holdem_omaha(config, backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout ,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId ,siteId #end of tourney specific params ,site_hand_no, gametype_id, hand_start_time, names, player_ids @@ -117,7 +113,6 @@ def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourn ,actionNos, hudImportData, maxSeats, tableName, seatNos): """stores a tourney holdem/omaha hand into the database""" - backend = settings['db-backend'] import_options = config.get_import_parameters() saveActions = True if import_options['saveActions'] == True else False fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False @@ -136,11 +131,10 @@ def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourn , card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids) #print "tourney holdem, backend=%d" % backend - if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop': - if fastStoreHudCache: - fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) - else: - fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) + if fastStoreHudCache: + fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) + else: + fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits) @@ -149,14 +143,13 @@ def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourn return hands_id #end def tourney_holdem_omaha -def tourney_stud(config, settings, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries +def tourney_stud(config, backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries ,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId ,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes ,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts ,actionNos, hudImportData, maxSeats, tableName, seatNos): #stores a tourney stud/razz hand into the database - backend = settings['db-backend'] import_options = config.get_import_parameters() saveActions = True if import_options['saveActions'] == True else False fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False @@ -173,8 +166,7 @@ def tourney_stud(config, settings, db, cursor, base, category, siteTourneyNo, bu , playerIds, startCashes, antes, cardValues, cardSuits , winnings, rakes, seatNos, tourneys_players_ids) - if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop': - fpdb_simple.storeHudCache(backend, cursor, base, category, gametypeId, hand_start_time, playerIds, hudImportData) + fpdb_simple.storeHudCache(backend, cursor, base, category, gametypeId, hand_start_time, playerIds, hudImportData) if saveActions: fpdb_simple.storeActions(cursor, hands_players_ids, actionTypes, allIns, actionAmounts, actionNos) diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py index db201405..398a20e5 100644 --- a/pyfpdb/fpdb_simple.py +++ b/pyfpdb/fpdb_simple.py @@ -2393,7 +2393,7 @@ def storeHudCache2(backend, cursor, base, category, gametypeId, hand_start_time, # Try to do the update first: num = cursor.execute("""UPDATE HudCache SET HDs=HDs+%s, street0VPI=street0VPI+%s, street0Aggr=street0Aggr+%s, - street0_3B4BChance=street0_3B4BChance+%s, street0_3B4BDone=street0_3B4BDone+%s, + street0_3BChance=street0_3BChance+%s, street0_3BDone=street0_3BDone+%s, street1Seen=street1Seen+%s, street2Seen=street2Seen+%s, street3Seen=street3Seen+%s, street4Seen=street4Seen+%s, sawShowdown=sawShowdown+%s, street1Aggr=street1Aggr+%s, street2Aggr=street2Aggr+%s, street3Aggr=street3Aggr+%s,