Merge branch 'master' of git://git.assembla.com/free_poker_tools
Conflicts: pyfpdb/GuiTableViewer.py
This commit is contained in:
		
						commit
						89dccac169
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | *.pyc | ||||||
|  | *~ | ||||||
							
								
								
									
										334
									
								
								pyfpdb/AbsoluteToFpdb.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								pyfpdb/AbsoluteToFpdb.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,334 @@ | ||||||
|  | #!/usr/bin/env python | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | # | ||||||
|  | #    Copyright 2008, Carl Gherardi | ||||||
|  | #     | ||||||
|  | #    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; either version 2 of the License, or | ||||||
|  | #    (at your option) any later version. | ||||||
|  | #     | ||||||
|  | #    This program is distributed in the hope that it will be useful, | ||||||
|  | #    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | #    GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | #    You should have received a copy of the GNU General Public License | ||||||
|  | #    along with this program; if not, write to the Free Software | ||||||
|  | #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
|  | ######################################################################## | ||||||
|  | 
 | ||||||
|  | # TODO: I have no idea if AP has multi-currency options, i just copied the regex out of Everleaf converter for the currency symbols.. weeeeee - Eric | ||||||
|  | import sys | ||||||
|  | import logging | ||||||
|  | from HandHistoryConverter import * | ||||||
|  | 
 | ||||||
|  | # Class for converting Absolute HH format. | ||||||
|  | 
 | ||||||
|  | class Absolute(HandHistoryConverter): | ||||||
|  |      | ||||||
|  |     # Static regexes | ||||||
|  |     re_SplitHands  = re.compile(r"\n\n\n+") | ||||||
|  |     re_TailSplitHands  = re.compile(r"(\n\n\n+)") | ||||||
|  | #Stage #1571362962: Holdem  No Limit $0.02 - 2009-08-05 15:24:06 (ET) | ||||||
|  | #Table: TORONTO AVE (Real Money) Seat #6 is the dealer | ||||||
|  | #Seat 6 - FETS63 ($0.75 in chips) | ||||||
|  | #Board [10s 5d Kh Qh 8c] | ||||||
|  | 
 | ||||||
|  |     re_GameInfo     = re.compile(ur"^Stage #([0-9]+): (?P<GAME>Holdem|)  (?P<LIMIT>No Limit|) (?P<CURRENCY>\$| €|)(?P<BB>[0-9]*[.0-9]+)", re.MULTILINE) | ||||||
|  |     re_HandInfo     = re.compile(ur"^Stage #(?P<HID>[0-9]+): .*(?P<DATETIME>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).*\nTable: (?P<TABLE>.*) \(Real Money\)", re.MULTILINE) | ||||||
|  |     re_Button       = re.compile(ur"Seat #(?P<BUTTON>[0-9]) is the ?[dead]* dealer$", re.MULTILINE) # TODO: that's not the right way to match for "dead" dealer is it? | ||||||
|  |     re_PlayerInfo   = re.compile(ur"^Seat (?P<SEAT>[0-9]) - (?P<PNAME>.*) \((?:\$| €|)(?P<CASH>[0-9]*[.0-9]+) in chips\)", re.MULTILINE) | ||||||
|  |     re_Board        = re.compile(ur"\[(?P<CARDS>[^\]]*)\]? *$", re.MULTILINE) | ||||||
|  | #    re_GameInfo    = re.compile(ur"^(Blinds )?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/(?:\$| €)?(?P<BB>[.0-9]+) (?P<LIMIT>NL|PL|) ?(?P<GAME>(Holdem|Omaha|7 Card Stud))", re.MULTILINE) | ||||||
|  |                      #re.compile(ur"^(Blinds )?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/(?:\$| €)?(?P<BB>[.0-9]+) (?P<LIMIT>NL|PL|) (?P<GAME>(Hold\'em|Omaha|7 Card Stud))", re.MULTILINE) | ||||||
|  | #    re_HandInfo    = re.compile(ur".*#(?P<HID>[0-9]+)\n.*\n(Blinds )?(?:\$| €|)(?P<SB>[.0-9]+)/(?:\$| €|)(?P<BB>[.0-9]+) (?P<GAMETYPE>.*) - (?P<DATETIME>\d\d\d\d/\d\d/\d\d - \d\d:\d\d:\d\d)\nTable (?P<TABLE>.+$)", re.MULTILINE) | ||||||
|  | #    re_Button      = re.compile(ur"^Seat (?P<BUTTON>\d+) is the button", re.MULTILINE) | ||||||
|  | #    re_PlayerInfo  = re.compile(ur"^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+((?:\$| €|) (?P<CASH>[.0-9]+) (USD|EUR|)|new player|All-in) \)", re.MULTILINE) | ||||||
|  | #    re_Board       = re.compile(ur"\[ (?P<CARDS>.+) \]") | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True, debugging=False, index=0): | ||||||
|  |         """\ | ||||||
|  | in_path   (default '-' = sys.stdin) | ||||||
|  | out_path  (default '-' = sys.stdout) | ||||||
|  | follow :  whether to tail -f the input | ||||||
|  | autostart: whether to run the thread (or you can call start() yourself) | ||||||
|  | debugging: if False, pass on partially supported game types. If true, have a go and error...""" | ||||||
|  |         #print "DEBUG: XXXXXXXXXXXXXXX" | ||||||
|  |         HandHistoryConverter.__init__(self, in_path, out_path, sitename="Absolute", follow=follow, index=index) | ||||||
|  |         logging.info("Initialising Absolute converter class") | ||||||
|  |         self.filetype = "text" | ||||||
|  |         self.codepage = "cp1252" | ||||||
|  |         self.siteId   = 8 # Needs to match id entry in Sites database | ||||||
|  |         self.debugging = debugging | ||||||
|  |         if autostart: | ||||||
|  |             self.start() | ||||||
|  |             # otherwise you need to call start yourself. | ||||||
|  | 
 | ||||||
|  |     def compilePlayerRegexs(self, hand): | ||||||
|  |         players = set([player[1] for player in hand.players]) | ||||||
|  |         if not players <= self.compiledPlayers: # x <= y means 'x is subset of y' | ||||||
|  |             # we need to recompile the player regexs. | ||||||
|  |             self.compiledPlayers = players | ||||||
|  |             player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")" | ||||||
|  |             logging.debug("player_re: "+ player_re) | ||||||
|  |             #(?P<CURRENCY>\$| €|)(?P<BB>[0-9]*[.0-9]+) | ||||||
|  |             self.re_PostSB          = re.compile(ur"^%s - Posts small blind (?:\$| €|)(?P<SB>[0-9]*[.0-9]+)" % player_re, re.MULTILINE) | ||||||
|  |             self.re_PostBB          = re.compile(ur"^%s - Posts big blind (?:\$| €|)(?P<BB>[0-9]*[.0-9]+)" % player_re, re.MULTILINE) | ||||||
|  |             # TODO: Absolute posting when coming in new: %s - Posts $0.02 .. should that be a new Post line? where do we need to add support for that? *confused* | ||||||
|  |             self.re_PostBoth        = re.compile(ur"^%s - Posts dead (?:\$| €|)(?P<SBBB>[0-9]*[.0-9]+)" % player_re, re.MULTILINE) | ||||||
|  |             self.re_Action          = re.compile(ur"^%s - (?P<ATYPE>Bets |Raises |All-In |All-In\(Raise\) |Calls |Folds|Checks)?\$?(?P<BET>[0-9]*[.0-9]+)?" % player_re, re.MULTILINE) | ||||||
|  | #            print "^%s - (?P<ATYPE>Bets |Raises |All-In |All-In\(Raise\) |Calls |Folds|Checks)?\$?(?P<BET>[0-9]*[.0-9]+)?" % player_re | ||||||
|  |             self.re_ShowdownAction  = re.compile(ur"^%s - Shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE) | ||||||
|  |             self.re_CollectPot      = re.compile(ur"^Seat [0-9]: %s(?: \(dealer\)| \(big blind\)| \(small blind\)|) (?:won|collected) Total \((?:\$| €|)(?P<POT>[0-9]*[.0-9]+)\)" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_PostSB          = re.compile(ur"^%s: posts small blind \[(?:\$| €|) (?P<SB>[.0-9]+)" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_PostBB          = re.compile(ur"^%s: posts big blind \[(?:\$| €|) (?P<BB>[.0-9]+)" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_PostBoth        = re.compile(ur"^%s: posts both blinds \[(?:\$| €|) (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_Antes           = re.compile(ur"^%s: posts ante \[(?:\$| €|) (?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_BringIn         = re.compile(ur"^%s posts bring-in (?:\$| €|)(?P<BRINGIN>[.0-9]+)\." % player_re, re.MULTILINE) | ||||||
|  |             self.re_HeroCards       = re.compile(ur"^Dealt to %s \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_Action          = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[(?:\$| €|) (?P<BET>[.\d]+) (USD|EUR|)\])?" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_Action          = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds| complete to)(\s\[?(?:\$| €|) ?(?P<BET>\d+\.?\d*)\.?\s?(USD|EUR|)\]?)?" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_ShowdownAction  = re.compile(ur"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_CollectPot      = re.compile(ur"^%s wins (?:\$| €|) (?P<POT>[.\d]+) (USD|EUR|chips)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE) | ||||||
|  |             #self.re_SitsOut         = re.compile(ur"^%s sits out" % player_re, re.MULTILINE) | ||||||
|  | 
 | ||||||
|  |     def readSupportedGames(self): | ||||||
|  |         return [["ring", "hold", "nl"], | ||||||
|  |                 ["ring", "hold", "pl"], | ||||||
|  |                 ["ring", "hold", "fl"], | ||||||
|  |                 ["ring", "studhi", "fl"], | ||||||
|  |                 ["ring", "omahahi", "pl"] | ||||||
|  |                ] | ||||||
|  | 
 | ||||||
|  |     def determineGameType(self, handText): | ||||||
|  |         """return dict with keys/values: | ||||||
|  |     'type'       in ('ring', 'tour') | ||||||
|  |     'limitType'  in ('nl', 'cn', 'pl', 'cp', 'fl') | ||||||
|  |     'base'       in ('hold', 'stud', 'draw') | ||||||
|  |     'category'   in ('holdem', 'omahahi', omahahilo', 'razz', 'studhi', 'studhilo', 'fivedraw', '27_1draw', '27_3draw', 'badugi') | ||||||
|  |     'hilo'       in ('h','l','s') | ||||||
|  |     'smallBlind' int? | ||||||
|  |     'bigBlind'   int? | ||||||
|  |     'smallBet' | ||||||
|  |     'bigBet' | ||||||
|  |     'currency'  in ('USD', 'EUR', 'T$', <countrycode>) | ||||||
|  | or None if we fail to get the info """ | ||||||
|  |         info = {'type':'ring'} | ||||||
|  |          | ||||||
|  |         m = self.re_GameInfo.search(handText) | ||||||
|  |         if not m: | ||||||
|  |             return None | ||||||
|  |          | ||||||
|  |         mg = m.groupdict() | ||||||
|  |          | ||||||
|  |         # translations from captured groups to our info strings | ||||||
|  |         limits = { 'No Limit':'nl', 'PL':'pl', '':'fl' } | ||||||
|  |         games = {              # base, category | ||||||
|  |                   "Holdem" : ('hold','holdem'),  | ||||||
|  |                     'Omaha' : ('hold','omahahi'),  | ||||||
|  |                      'Razz' : ('stud','razz'),  | ||||||
|  |               '7 Card Stud' : ('stud','studhi') | ||||||
|  |                } | ||||||
|  |         currencies = { u' €':'EUR', '$':'USD', '':'T$' } | ||||||
|  |         if 'LIMIT' in mg: | ||||||
|  |             info['limitType'] = limits[mg['LIMIT']] | ||||||
|  |         if 'GAME' in mg: | ||||||
|  |             (info['base'], info['category']) = games[mg['GAME']] | ||||||
|  |         if 'SB' in mg: | ||||||
|  |             info['sb'] = mg['SB'] | ||||||
|  |         else: | ||||||
|  |             info['sb'] = str(float(mg['BB']) * 0.5) # TODO: Apparently AP doesn't provide small blind info!? must search to see if it's posted, I guess | ||||||
|  |         if 'BB' in mg: | ||||||
|  |             info['bb'] = mg['BB'] | ||||||
|  |         if 'CURRENCY' in mg: | ||||||
|  |             info['currency'] = currencies[mg['CURRENCY']] | ||||||
|  |             if info['currency'] == 'T$': | ||||||
|  |                 info['type'] = 'tour' | ||||||
|  |         # NB: SB, BB must be interpreted as blinds or bets depending on limit type. | ||||||
|  |          | ||||||
|  |         return info | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def readHandInfo(self, hand): | ||||||
|  |         m = self.re_HandInfo.search(hand.handText) | ||||||
|  |         if(m == None): | ||||||
|  |             logging.info("Didn't match re_HandInfo") | ||||||
|  |             logging.info(hand.handText) | ||||||
|  |             return None | ||||||
|  |         logging.debug("HID %s, Table %s" % (m.group('HID'),  m.group('TABLE'))) | ||||||
|  |         hand.handid =  m.group('HID') | ||||||
|  |         hand.tablename = m.group('TABLE') | ||||||
|  |         hand.maxseats = 6     # assume 6-max unless we have proof it's a larger/smaller game, since absolute doesn't give seat max info | ||||||
|  | 
 | ||||||
|  |         hand.starttime = datetime.datetime.strptime(m.group('DATETIME'), "%Y-%m-%d %H:%M:%S") | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     def readPlayerStacks(self, hand): | ||||||
|  |         m = self.re_PlayerInfo.finditer(hand.handText) | ||||||
|  |         for a in m: | ||||||
|  |             seatnum = int(a.group('SEAT')) | ||||||
|  |             hand.addPlayer(seatnum, a.group('PNAME'), a.group('CASH')) | ||||||
|  |             if seatnum > 6: | ||||||
|  |                 hand.maxseats = 10 # absolute does 2/4/6/8/10 games  | ||||||
|  |                 # TODO: implement lookup list by table-name to determine maxes, then fall back to 6 default/10 here, if there's no entry in the list? | ||||||
|  |              | ||||||
|  |          | ||||||
|  |     def markStreets(self, hand): | ||||||
|  |         # PREFLOP = ** Dealing down cards ** | ||||||
|  |         # This re fails if,  say, river is missing; then we don't get the ** that starts the river. | ||||||
|  |         #m = re.search('(\*\* Dealing down cards \*\*\n)(?P<PREFLOP>.*?\n\*\*)?( Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \])?(?P<FLOP>.*?\*\*)?( Dealing Turn \*\* \[ (?P<TURN1>\S\S) \])?(?P<TURN>.*?\*\*)?( Dealing River \*\* \[ (?P<RIVER1>\S\S) \])?(?P<RIVER>.*)', hand.handText,re.DOTALL) | ||||||
|  |         if hand.gametype['base'] == 'hold': | ||||||
|  |             m = re.search(r"\*\*\* POCKET CARDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP \*\*\*)|.+)" | ||||||
|  |                     r"(\*\*\* FLOP \*\*\*(?P<FLOP>.+(?=\*\*\* TURN \*\*\*)|.+))?" | ||||||
|  |                     r"(\*\*\* TURN \*\*\*(?P<TURN>.+(?=\*\*\* RIVER \*\*\*)|.+))?" | ||||||
|  |                     r"(\*\*\* RIVER \*\*\*(?P<RIVER>.+))?", hand.handText, re.DOTALL) | ||||||
|  |              | ||||||
|  |         elif hand.gametype['base'] == 'stud': # TODO: Not implemented yet | ||||||
|  |             m =     re.search(r"(?P<ANTES>.+(?=\*\* Dealing down cards \*\*)|.+)" | ||||||
|  |                            r"(\*\* Dealing down cards \*\*(?P<THIRD>.+(?=\*\*\*\* dealing 4th street \*\*\*\*)|.+))?" | ||||||
|  |                            r"(\*\*\*\* dealing 4th street \*\*\*\*(?P<FOURTH>.+(?=\*\*\*\* dealing 5th street \*\*\*\*)|.+))?" | ||||||
|  |                            r"(\*\*\*\* dealing 5th street \*\*\*\*(?P<FIFTH>.+(?=\*\*\*\* dealing 6th street \*\*\*\*)|.+))?" | ||||||
|  |                            r"(\*\*\*\* dealing 6th street \*\*\*\*(?P<SIXTH>.+(?=\*\*\*\* dealing river \*\*\*\*)|.+))?" | ||||||
|  |                            r"(\*\*\*\* dealing river \*\*\*\*(?P<SEVENTH>.+))?", hand.handText,re.DOTALL) | ||||||
|  |         hand.addStreets(m) | ||||||
|  | 
 | ||||||
|  |     def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand | ||||||
|  |         # If this has been called, street is a street which gets dealt community cards by type hand | ||||||
|  |         # but it might be worth checking somehow. | ||||||
|  | #        if street in ('FLOP','TURN','RIVER'):   # a list of streets which get dealt community cards (i.e. all but PREFLOP) | ||||||
|  |         logging.debug("readCommunityCards (%s)" % street) | ||||||
|  |         m = self.re_Board.search(hand.streets[street]) | ||||||
|  |         cards = m.group('CARDS') | ||||||
|  |         cards = [validCard(card) for card in cards.split(' ')] | ||||||
|  |         hand.setCommunityCards(street=street, cards=cards) | ||||||
|  | 
 | ||||||
|  |     def readAntes(self, hand): | ||||||
|  |         logging.debug("reading antes") | ||||||
|  |         m = self.re_Antes.finditer(hand.handText) | ||||||
|  |         for player in m: | ||||||
|  |             logging.debug("hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE'))) | ||||||
|  |             hand.addAnte(player.group('PNAME'), player.group('ANTE')) | ||||||
|  | 
 | ||||||
|  |     def readBringIn(self, hand): | ||||||
|  |         m = self.re_BringIn.search(hand.handText,re.DOTALL) | ||||||
|  |         if m: | ||||||
|  |             logging.debug("Player bringing in: %s for %s" %(m.group('PNAME'),  m.group('BRINGIN')))         | ||||||
|  |             hand.addBringIn(m.group('PNAME'),  m.group('BRINGIN')) | ||||||
|  |         else: | ||||||
|  |             logging.warning("No bringin found.") | ||||||
|  | 
 | ||||||
|  |     def readBlinds(self, hand): | ||||||
|  |         m = self.re_PostSB.search(hand.handText) | ||||||
|  |         if m is not None: | ||||||
|  |             hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB')) | ||||||
|  |         else: | ||||||
|  |             logging.debug("No small blind") | ||||||
|  |             hand.addBlind(None, None, None) | ||||||
|  |         for a in self.re_PostBB.finditer(hand.handText): | ||||||
|  |             hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB')) | ||||||
|  |         for a in self.re_PostBoth.finditer(hand.handText): | ||||||
|  |             hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB')) | ||||||
|  | 
 | ||||||
|  |     def readButton(self, hand): | ||||||
|  |         hand.buttonpos = int(self.re_Button.search(hand.handText).group('BUTTON')) | ||||||
|  | 
 | ||||||
|  |     def readHeroCards(self, hand): | ||||||
|  |         m = self.re_HeroCards.search(hand.handText) | ||||||
|  |         if m: | ||||||
|  |             hand.hero = m.group('PNAME') | ||||||
|  |             # "2c, qh" -> ["2c","qc"] | ||||||
|  |             # Also works with Omaha hands. | ||||||
|  |             cards = m.group('CARDS') | ||||||
|  |             cards = [validCard(card) for card in cards.split(' ')] | ||||||
|  | #            hand.addHoleCards(cards, m.group('PNAME')) | ||||||
|  |             hand.addHoleCards('PREFLOP', hand.hero, closed=cards, shown=False, mucked=False, dealt=True) | ||||||
|  | 
 | ||||||
|  |         else: | ||||||
|  |             #Not involved in hand | ||||||
|  |             hand.involved = False | ||||||
|  |      | ||||||
|  |     def readStudPlayerCards(self, hand, street): | ||||||
|  |         # lol. see Plymouth.txt | ||||||
|  |         logging.warning("Absolute readStudPlayerCards is only a stub.") | ||||||
|  |         #~ if street in ('THIRD', 'FOURTH',  'FIFTH',  'SIXTH'): | ||||||
|  |             #~ hand.addPlayerCards(player = player.group('PNAME'), street = street,  closed = [],  open = []) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def readAction(self, hand, street): | ||||||
|  |         logging.debug("readAction (%s)" % street) | ||||||
|  |         m = self.re_Action.finditer(hand.streets[street]) | ||||||
|  |         for action in m: | ||||||
|  |             logging.debug("%s %s" % (action.group('ATYPE'), action.groupdict())) | ||||||
|  |             if action.group('ATYPE') == 'Raises ' or action.group('ATYPE') == 'All-In(Raise) ': | ||||||
|  |                 hand.addCallandRaise( street, action.group('PNAME'), action.group('BET') ) | ||||||
|  |             elif action.group('ATYPE') == 'Calls ': | ||||||
|  |                 hand.addCall( street, action.group('PNAME'), action.group('BET') ) | ||||||
|  |             elif action.group('ATYPE') == 'Bets ' or action.group('ATYPE') == 'All-In ': | ||||||
|  |                 hand.addBet( street, action.group('PNAME'), action.group('BET') ) | ||||||
|  |             elif action.group('ATYPE') == 'Folds': | ||||||
|  |                 hand.addFold( street, action.group('PNAME')) | ||||||
|  |             elif action.group('ATYPE') == 'Checks': | ||||||
|  |                 hand.addCheck( street, action.group('PNAME')) | ||||||
|  |             elif action.group('ATYPE') == ' complete to': # TODO: not supported yet ? | ||||||
|  |                 hand.addComplete( street, action.group('PNAME'), action.group('BET')) | ||||||
|  |             else: | ||||||
|  |                 logging.debug("Unimplemented readAction: %s %s" %(action.group('PNAME'),action.group('ATYPE'),)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def readShowdownActions(self, hand): | ||||||
|  |         """Reads lines where holecards are reported in a showdown""" | ||||||
|  |         logging.debug("readShowdownActions") | ||||||
|  |         for shows in self.re_ShowdownAction.finditer(hand.handText): | ||||||
|  |             cards = shows.group('CARDS') | ||||||
|  |             cards = [validCard(card) for card in cards.split(' ')]             | ||||||
|  |             logging.debug("readShowdownActions %s %s" %(cards, shows.group('PNAME'))) | ||||||
|  |             hand.addShownCards(cards, shows.group('PNAME')) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def readCollectPot(self,hand): | ||||||
|  |         for m in self.re_CollectPot.finditer(hand.handText): | ||||||
|  |             hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT')) | ||||||
|  | 
 | ||||||
|  |     def readShownCards(self,hand): | ||||||
|  |         """Reads lines where hole & board cards are mixed to form a hand (summary lines)""" | ||||||
|  |         for m in self.re_CollectPot.finditer(hand.handText): | ||||||
|  |             try: | ||||||
|  |                 if m.group('CARDS') is not None: | ||||||
|  |                     cards = m.group('CARDS') | ||||||
|  |                     cards = [validCard(card) for card in cards.split(' ')] | ||||||
|  |                     player = m.group('PNAME') | ||||||
|  |                     logging.debug("readShownCards %s cards=%s" % (player, cards)) | ||||||
|  |     #                hand.addShownCards(cards=None, player=m.group('PNAME'), holeandboard=cards) | ||||||
|  |                     hand.addShownCards(cards=cards, player=m.group('PNAME')) | ||||||
|  |             except IndexError: | ||||||
|  |                 pass # there's no "PLAYER - Mucks" at AP that I can see | ||||||
|  | 
 | ||||||
|  | def validCard(card): | ||||||
|  |     card = card.strip() | ||||||
|  |     if card == '10s': card = 'Ts' | ||||||
|  |     if card == '10h': card = 'Th' | ||||||
|  |     if card == '10d': card = 'Td' | ||||||
|  |     if card == '10c': card = 'Tc' | ||||||
|  |     return card | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     parser = OptionParser() | ||||||
|  |     parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="-") | ||||||
|  |     parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-") | ||||||
|  |     parser.add_option("-f", "--follow", dest="follow", help="follow (tail -f) the input", action="store_true", default=False) | ||||||
|  |     parser.add_option("-q", "--quiet", | ||||||
|  |                   action="store_const", const=logging.CRITICAL, dest="verbosity", default=logging.INFO) | ||||||
|  |     parser.add_option("-v", "--verbose", | ||||||
|  |                   action="store_const", const=logging.INFO, dest="verbosity") | ||||||
|  |     parser.add_option("--vv", | ||||||
|  |                   action="store_const", const=logging.DEBUG, dest="verbosity") | ||||||
|  | 
 | ||||||
|  |     (options, args) = parser.parse_args() | ||||||
|  | 
 | ||||||
|  |     LOG_FILENAME = './logging.out' | ||||||
|  |     logging.basicConfig(filename=LOG_FILENAME,level=options.verbosity) | ||||||
|  | 
 | ||||||
|  |     e = Absolute(in_path = options.ipath, out_path = options.opath, follow = options.follow, autostart=True, debugging=True) | ||||||
|  | 
 | ||||||
|  | @ -584,19 +584,20 @@ class Config: | ||||||
|         return paths |         return paths | ||||||
|      |      | ||||||
|     def get_frames(self, site = "PokerStars"): |     def get_frames(self, site = "PokerStars"): | ||||||
|  |         if site not in self.supported_sites: return False | ||||||
|         return self.supported_sites[site].use_frames == True |         return self.supported_sites[site].use_frames == True | ||||||
| 
 | 
 | ||||||
|     def get_default_colors(self, site = "PokerStars"): |     def get_default_colors(self, site = "PokerStars"): | ||||||
|         colors = {} |         colors = {} | ||||||
|         if self.supported_sites[site].hudopacity == "": |         if site not in self.supported_sites or self.supported_sites[site].hudopacity == "": | ||||||
|             colors['hudopacity'] = 0.90 |             colors['hudopacity'] = 0.90 | ||||||
|         else: |         else: | ||||||
|             colors['hudopacity'] = float(self.supported_sites[site].hudopacity) |             colors['hudopacity'] = float(self.supported_sites[site].hudopacity) | ||||||
|         if self.supported_sites[site].hudbgcolor == "": |         if site not in self.supported_sites or self.supported_sites[site].hudbgcolor == "": | ||||||
|             colors['hudbgcolor'] = "#FFFFFF" |             colors['hudbgcolor'] = "#FFFFFF" | ||||||
|         else: |         else: | ||||||
|             colors['hudbgcolor'] = self.supported_sites[site].hudbgcolor |             colors['hudbgcolor'] = self.supported_sites[site].hudbgcolor | ||||||
|         if self.supported_sites[site].hudfgcolor == "": |         if site not in self.supported_sites or self.supported_sites[site].hudfgcolor == "": | ||||||
|             colors['hudfgcolor'] = "#000000" |             colors['hudfgcolor'] = "#000000" | ||||||
|         else: |         else: | ||||||
|             colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor |             colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor | ||||||
|  | @ -604,6 +605,8 @@ class Config: | ||||||
|      |      | ||||||
|     def get_default_font(self, site = 'PokerStars'): |     def get_default_font(self, site = 'PokerStars'): | ||||||
|         (font, font_size) = ("Sans", "8") |         (font, font_size) = ("Sans", "8") | ||||||
|  |         if site not in self.supported_sites: | ||||||
|  |             return ("Sans", "8") | ||||||
|         if self.supported_sites[site].font == "": |         if self.supported_sites[site].font == "": | ||||||
|             font = "Sans" |             font = "Sans" | ||||||
|         else: |         else: | ||||||
|  |  | ||||||
|  | @ -98,7 +98,7 @@ class Database: | ||||||
|     foreignKeys = [ |     foreignKeys = [ | ||||||
|                     [ ] # no db with index 0 |                     [ ] # no db with index 0 | ||||||
|                   , [ ] # no db with index 1 |                   , [ ] # no db with index 1 | ||||||
|                   , [ # foreign keys for mysql |                   , [ # foreign keys for mysql (index 2) | ||||||
|                       {'fktab':'Hands',        'fkcol':'gametypeId',    'rtab':'Gametypes',     'rcol':'id', 'drop':1} |                       {'fktab':'Hands',        'fkcol':'gametypeId',    'rtab':'Gametypes',     'rcol':'id', 'drop':1} | ||||||
|                     , {'fktab':'HandsPlayers', 'fkcol':'handId',        'rtab':'Hands',         'rcol':'id', 'drop':1} |                     , {'fktab':'HandsPlayers', 'fkcol':'handId',        'rtab':'Hands',         'rcol':'id', 'drop':1} | ||||||
|                     , {'fktab':'HandsPlayers', 'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':1} |                     , {'fktab':'HandsPlayers', 'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':1} | ||||||
|  | @ -107,7 +107,7 @@ class Database: | ||||||
|                     , {'fktab':'HudCache',     'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':0} |                     , {'fktab':'HudCache',     'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':0} | ||||||
|                     , {'fktab':'HudCache',     'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes',  'rcol':'id', 'drop':1} |                     , {'fktab':'HudCache',     'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes',  'rcol':'id', 'drop':1} | ||||||
|                     ] |                     ] | ||||||
|                   , [ # foreign keys for postgres |                   , [ # foreign keys for postgres (index 3) | ||||||
|                       {'fktab':'Hands',        'fkcol':'gametypeId',    'rtab':'Gametypes',     'rcol':'id', 'drop':1} |                       {'fktab':'Hands',        'fkcol':'gametypeId',    'rtab':'Gametypes',     'rcol':'id', 'drop':1} | ||||||
|                     , {'fktab':'HandsPlayers', 'fkcol':'handId',        'rtab':'Hands',         'rcol':'id', 'drop':1} |                     , {'fktab':'HandsPlayers', 'fkcol':'handId',        'rtab':'Hands',         'rcol':'id', 'drop':1} | ||||||
|                     , {'fktab':'HandsPlayers', 'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':1} |                     , {'fktab':'HandsPlayers', 'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':1} | ||||||
|  | @ -116,6 +116,8 @@ class Database: | ||||||
|                     , {'fktab':'HudCache',     'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':0} |                     , {'fktab':'HudCache',     'fkcol':'playerId',      'rtab':'Players',       'rcol':'id', 'drop':0} | ||||||
|                     , {'fktab':'HudCache',     'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes',  'rcol':'id', 'drop':1} |                     , {'fktab':'HudCache',     'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes',  'rcol':'id', 'drop':1} | ||||||
|                     ] |                     ] | ||||||
|  |                   , [ # no foreign keys in sqlite (index 4) | ||||||
|  |                     ] | ||||||
|                   ] |                   ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -233,9 +235,15 @@ class Database: | ||||||
|         self.fdb.reconnect(due_to_error=False) |         self.fdb.reconnect(due_to_error=False) | ||||||
|      |      | ||||||
|     def get_backend_name(self): |     def get_backend_name(self): | ||||||
|         """Reconnects the DB""" |         """Returns the name of the currently used backend""" | ||||||
|         return self.fdb.get_backend_name() |         if self.backend==2: | ||||||
|          |             return "MySQL InnoDB" | ||||||
|  |         elif self.backend==3: | ||||||
|  |             return "PostgreSQL" | ||||||
|  |         elif self.backend==4: | ||||||
|  |             return "SQLite" | ||||||
|  |         else: | ||||||
|  |             raise fpdb_simple.FpdbError("invalid backend") | ||||||
| 
 | 
 | ||||||
|     def get_table_name(self, hand_id): |     def get_table_name(self, hand_id): | ||||||
|         c = self.connection.cursor() |         c = self.connection.cursor() | ||||||
|  | @ -465,11 +473,39 @@ class Database: | ||||||
|         result = c.fetchall() |         result = c.fetchall() | ||||||
|         return result |         return result | ||||||
| 
 | 
 | ||||||
|     def get_last_insert_id(self): |     def get_last_insert_id(self, cursor=None): | ||||||
|  |         ret = None | ||||||
|         try: |         try: | ||||||
|             ret = self.fdb.getLastInsertId() |             if self.backend == self.MYSQL_INNODB: | ||||||
|  |                 ret = self.connection.insert_id() | ||||||
|  |                 if ret < 1 or ret > 999999999: | ||||||
|  |                     print "getLastInsertId(): problem fetching insert_id? ret=", ret | ||||||
|  |                     ret = -1 | ||||||
|  |             elif self.backend == self.PGSQL: | ||||||
|  |                 # some options: | ||||||
|  |                 # currval(hands_id_seq) - use name of implicit seq here | ||||||
|  |                 # lastval() - still needs sequences set up? | ||||||
|  |                 # insert ... returning  is useful syntax (but postgres specific?) | ||||||
|  |                 # see rules (fancy trigger type things) | ||||||
|  |                 c = self.get_cursor() | ||||||
|  |                 ret = c.execute ("SELECT lastval()") | ||||||
|  |                 row = c.fetchone() | ||||||
|  |                 if not row: | ||||||
|  |                     print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row | ||||||
|  |                     ret = -1 | ||||||
|  |                 else: | ||||||
|  |                     ret = row[0] | ||||||
|  |             elif self.backend == self.SQLITE: | ||||||
|  |                 ret = cursor.lastrowid | ||||||
|  |             else: | ||||||
|  |                 print "getLastInsertId(): unknown backend ", self.backend | ||||||
|  |                 ret = -1 | ||||||
|         except: |         except: | ||||||
|             print "get_last_insert_id error:", str(sys.exc_value) |             ret = -1 | ||||||
|  |             err = traceback.extract_tb(sys.exc_info()[2]) | ||||||
|  |             print "***get_last_insert_id error: " + str(sys.exc_info()[1]) | ||||||
|  |             print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] ) | ||||||
|  |             raise | ||||||
|         return ret |         return ret | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -847,6 +883,7 @@ class Database: | ||||||
| 
 | 
 | ||||||
|             self.commit() |             self.commit() | ||||||
|         except: |         except: | ||||||
|  |             err = traceback.extract_tb(sys.exc_info()[2])[-1] | ||||||
|             print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) |             print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) | ||||||
|             self.rollback() |             self.rollback() | ||||||
|             raise |             raise | ||||||
|  | @ -914,12 +951,17 @@ class Database: | ||||||
|     #end def dropAllIndexes |     #end def dropAllIndexes | ||||||
|      |      | ||||||
|     def fillDefaultData(self): |     def fillDefaultData(self): | ||||||
|         c = self.get_cursor() |         c = self.get_cursor()  | ||||||
|         c.execute("INSERT INTO Settings (version) VALUES (118);") |         c.execute("INSERT INTO Settings (version) VALUES (118);") | ||||||
|         c.execute("INSERT INTO Sites (name,currency) VALUES ('Full Tilt Poker', 'USD')") |         c.execute("INSERT INTO Sites (name,currency) VALUES ('Full Tilt Poker', 'USD')") | ||||||
|         c.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')") |         c.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')") | ||||||
|         c.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')") |         c.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')") | ||||||
|         c.execute("INSERT INTO Sites (name,currency) VALUES ('Win2day', 'USD')") |         c.execute("INSERT INTO Sites (name,currency) VALUES ('Win2day', 'USD')") | ||||||
|  |         c.execute("INSERT INTO Sites (name,currency) VALUES ('OnGame', 'USD')") | ||||||
|  |         c.execute("INSERT INTO Sites (name,currency) VALUES ('UltimateBet', 'USD')") | ||||||
|  |         c.execute("INSERT INTO Sites (name,currency) VALUES ('Betfair', 'USD')") | ||||||
|  |         c.execute("INSERT INTO Sites (name,currency) VALUES ('Absolute', 'USD')") | ||||||
|  |         c.execute("INSERT INTO Sites (name,currency) VALUES ('PartyPoker', 'USD')") | ||||||
|         if self.backend == self.SQLITE: |         if self.backend == self.SQLITE: | ||||||
|             c.execute("INSERT INTO TourneyTypes VALUES (NULL, 1, 0, 0, 0, 0);") |             c.execute("INSERT INTO TourneyTypes VALUES (NULL, 1, 0, 0, 0, 0);") | ||||||
|         else: |         else: | ||||||
|  | @ -934,12 +976,14 @@ class Database: | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             stime = time() |             stime = time() | ||||||
|             self.connection.cursor().execute(self.sql.query['clearHudCache']) |             self.get_cursor().execute(self.sql.query['clearHudCache']) | ||||||
|             self.connection.cursor().execute(self.sql.query['rebuildHudCache']) |             self.get_cursor().execute(self.sql.query['rebuildHudCache']) | ||||||
|             self.commit() |             self.commit() | ||||||
|             print "Rebuild hudcache took %.1f seconds" % (time() - stime,) |             print "Rebuild hudcache took %.1f seconds" % (time() - stime,) | ||||||
|         except: |         except: | ||||||
|  |             err = traceback.extract_tb(sys.exc_info()[2])[-1] | ||||||
|             print "Error rebuilding hudcache:", str(sys.exc_value) |             print "Error rebuilding hudcache:", str(sys.exc_value) | ||||||
|  |             print err | ||||||
|     #end def rebuild_hudcache |     #end def rebuild_hudcache | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -996,15 +1040,26 @@ class Database: | ||||||
|     def insertPlayer(self, name, site_id): |     def insertPlayer(self, name, site_id): | ||||||
|         result = None |         result = None | ||||||
|         c = self.get_cursor() |         c = self.get_cursor() | ||||||
|         c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) |         q = "SELECT name, id FROM Players WHERE siteid=%s and name=%s" | ||||||
|         tmp=c.fetchall() |         q = q.replace('%s', self.sql.query['placeholder']) | ||||||
|         if (len(tmp)==0): #new player |  | ||||||
|             c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (name, site_id)) |  | ||||||
|             #Get last id might be faster here. |  | ||||||
|             c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) |  | ||||||
|             tmp=c.fetchall() |  | ||||||
|         return tmp[0][0] |  | ||||||
| 
 | 
 | ||||||
|  |         #print "DEBUG: name: %s site: %s" %(name, site_id) | ||||||
|  | 
 | ||||||
|  |         c.execute (q, (site_id, name)) | ||||||
|  | 
 | ||||||
|  |         tmp = c.fetchone() | ||||||
|  |         if (tmp == None): #new player | ||||||
|  |             c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)".replace('%s',self.sql.query['placeholder']) | ||||||
|  |                       ,(name, site_id)) | ||||||
|  |             #Get last id might be faster here. | ||||||
|  |             #c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) | ||||||
|  |             tmp = [self.get_last_insert_id(c)] | ||||||
|  |         return tmp[0] | ||||||
|  | 
 | ||||||
|  |     def insertGameTypes(self, row): | ||||||
|  |         c = self.get_cursor() | ||||||
|  |         c.execute( self.sql.query['insertGameTypes'], row ) | ||||||
|  |         return [self.get_last_insert_id(c)] | ||||||
| 
 | 
 | ||||||
|     def store_the_hand(self, h): |     def store_the_hand(self, h): | ||||||
|         """Take a HandToWrite object and store it in the db""" |         """Take a HandToWrite object and store it in the db""" | ||||||
|  | @ -1064,6 +1119,76 @@ class Database: | ||||||
|         return result |         return result | ||||||
|     #end def store_the_hand |     #end def store_the_hand | ||||||
| 
 | 
 | ||||||
|  |     def storeHand(self, p): | ||||||
|  |         #stores into table hands: | ||||||
|  |         q = """INSERT INTO Hands (  | ||||||
|  |             tablename,  | ||||||
|  |             gametypeid,  | ||||||
|  |             sitehandno, | ||||||
|  |             handstart,  | ||||||
|  |             importtime, | ||||||
|  |             maxseats, | ||||||
|  |             boardcard1,  | ||||||
|  |             boardcard2,  | ||||||
|  |             boardcard3,  | ||||||
|  |             boardcard4,  | ||||||
|  |             boardcard5 | ||||||
|  |              )  | ||||||
|  |              VALUES  | ||||||
|  |               (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" | ||||||
|  | #---            texture, | ||||||
|  | #--            playersVpi, | ||||||
|  | #--            playersAtStreet1,  | ||||||
|  | #--            playersAtStreet2, | ||||||
|  | #--            playersAtStreet3,  | ||||||
|  | #--            playersAtStreet4,  | ||||||
|  | #--            playersAtShowdown, | ||||||
|  | #--            street0Raises, | ||||||
|  | #--            street1Raises, | ||||||
|  | #--            street2Raises, | ||||||
|  | #--            street3Raises, | ||||||
|  | #--            street4Raises, | ||||||
|  | #--            street1Pot, | ||||||
|  | #--            street2Pot, | ||||||
|  | #--            street3Pot, | ||||||
|  | #--            street4Pot, | ||||||
|  | #--            showdownPot | ||||||
|  | #--            seats,  | ||||||
|  | 
 | ||||||
|  |         q = q.replace('%s', self.sql.query['placeholder']) | ||||||
|  |         self.cursor.execute(q, ( | ||||||
|  |                 p['tableName'],  | ||||||
|  |                 p['siteHandNo'],  | ||||||
|  |                 p['gametypeid'],  | ||||||
|  |                 p['handStart'],  | ||||||
|  |                 datetime.today(), #importtime | ||||||
|  | #                len(p['names']), #seats | ||||||
|  |                 p['maxSeats'], | ||||||
|  |                 p['boardcard1'],  | ||||||
|  |                 p['boardcard2'],  | ||||||
|  |                 p['boardcard3'],  | ||||||
|  |                 p['boardcard4'],  | ||||||
|  |                 p['boardcard5']) | ||||||
|  | #                hudCache['playersVpi'],  | ||||||
|  | #                hudCache['playersAtStreet1'],  | ||||||
|  | #                hudCache['playersAtStreet2'], | ||||||
|  | #                hudCache['playersAtStreet3'],  | ||||||
|  | #                hudCache['playersAtStreet4'],  | ||||||
|  | #                hudCache['playersAtShowdown'], | ||||||
|  | #                hudCache['street0Raises'],  | ||||||
|  | #                hudCache['street1Raises'],  | ||||||
|  | #                hudCache['street2Raises'], | ||||||
|  | #                hudCache['street3Raises'],  | ||||||
|  | #                hudCache['street4Raises'],  | ||||||
|  | #                hudCache['street1Pot'], | ||||||
|  | #                hudCache['street2Pot'],  | ||||||
|  | #                hudCache['street3Pot'], | ||||||
|  | #                hudCache['street4Pot'], | ||||||
|  | #                hudCache['showdownPot'] | ||||||
|  |         ) | ||||||
|  |         #return getLastInsertId(backend, conn, cursor) | ||||||
|  |     # def storeHand | ||||||
|  | 
 | ||||||
|     def storeHands(self, backend, site_hand_no, gametype_id |     def storeHands(self, backend, site_hand_no, gametype_id | ||||||
|                   ,hand_start_time, names, tableName, maxSeats, hudCache |                   ,hand_start_time, names, tableName, maxSeats, hudCache | ||||||
|                   ,board_values, board_suits): |                   ,board_values, board_suits): | ||||||
|  | @ -1071,30 +1196,31 @@ class Database: | ||||||
|         cards = [Card.cardFromValueSuit(v,s) for v,s in zip(board_values,board_suits)] |         cards = [Card.cardFromValueSuit(v,s) for v,s in zip(board_values,board_suits)] | ||||||
|         #stores into table hands: |         #stores into table hands: | ||||||
|         try: |         try: | ||||||
|             self.get_cursor().execute ("""INSERT INTO Hands  |             c = self.get_cursor() | ||||||
|                                           (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats |             c.execute ("""INSERT INTO Hands  | ||||||
|                                           ,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5 |                           (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats | ||||||
|                                           ,playersVpi, playersAtStreet1, playersAtStreet2 |                           ,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5 | ||||||
|                                           ,playersAtStreet3, playersAtStreet4, playersAtShowdown |                           ,playersVpi, playersAtStreet1, playersAtStreet2 | ||||||
|                                           ,street0Raises, street1Raises, street2Raises |                           ,playersAtStreet3, playersAtStreet4, playersAtShowdown | ||||||
|                                           ,street3Raises, street4Raises, street1Pot |                           ,street0Raises, street1Raises, street2Raises | ||||||
|                                           ,street2Pot, street3Pot, street4Pot |                           ,street3Raises, street4Raises, street1Pot | ||||||
|                                           ,showdownPot |                           ,street2Pot, street3Pot, street4Pot | ||||||
|                                           )  |                           ,showdownPot | ||||||
|                                           VALUES  |                           )  | ||||||
|                                           (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, |                           VALUES  | ||||||
|                                           %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) |                           (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||||||
|                                        """ |                           %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) | ||||||
|                                       ,   (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats |                        """.replace('%s', self.sql.query['placeholder']) | ||||||
|                                           ,cards[0], cards[1], cards[2], cards[3], cards[4] |                       ,   (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats | ||||||
|                                           ,hudCache['playersVpi'], hudCache['playersAtStreet1'], hudCache['playersAtStreet2'] |                           ,cards[0], cards[1], cards[2], cards[3], cards[4] | ||||||
|                                           ,hudCache['playersAtStreet3'], hudCache['playersAtStreet4'], hudCache['playersAtShowdown'] |                           ,hudCache['playersVpi'], hudCache['playersAtStreet1'], hudCache['playersAtStreet2'] | ||||||
|                                           ,hudCache['street0Raises'], hudCache['street1Raises'], hudCache['street2Raises'] |                           ,hudCache['playersAtStreet3'], hudCache['playersAtStreet4'], hudCache['playersAtShowdown'] | ||||||
|                                           ,hudCache['street3Raises'], hudCache['street4Raises'], hudCache['street1Pot'] |                           ,hudCache['street0Raises'], hudCache['street1Raises'], hudCache['street2Raises'] | ||||||
|                                           ,hudCache['street2Pot'], hudCache['street3Pot'], hudCache['street4Pot'] |                           ,hudCache['street3Raises'], hudCache['street4Raises'], hudCache['street1Pot'] | ||||||
|                                           ,hudCache['showdownPot'] |                           ,hudCache['street2Pot'], hudCache['street3Pot'], hudCache['street4Pot'] | ||||||
|                                           )) |                           ,hudCache['showdownPot'] | ||||||
|             ret = self.get_last_insert_id() |                           )) | ||||||
|  |             ret = self.get_last_insert_id(c) | ||||||
|         except: |         except: | ||||||
|             ret = -1 |             ret = -1 | ||||||
|             raise fpdb_simple.FpdbError( "storeHands error: " + str(sys.exc_value) ) |             raise fpdb_simple.FpdbError( "storeHands error: " + str(sys.exc_value) ) | ||||||
|  | @ -1163,7 +1289,8 @@ class Database: | ||||||
|                                  hudCache['street0Calls'][i], hudCache['street1Calls'][i], hudCache['street2Calls'][i], hudCache['street3Calls'][i], hudCache['street4Calls'][i], |                                  hudCache['street0Calls'][i], hudCache['street1Calls'][i], hudCache['street2Calls'][i], hudCache['street3Calls'][i], hudCache['street4Calls'][i], | ||||||
|                                  hudCache['street0Bets'][i], hudCache['street1Bets'][i], hudCache['street2Bets'][i], hudCache['street3Bets'][i], hudCache['street4Bets'][i] |                                  hudCache['street0Bets'][i], hudCache['street1Bets'][i], hudCache['street2Bets'][i], hudCache['street3Bets'][i], hudCache['street4Bets'][i] | ||||||
|                                 ) ) |                                 ) ) | ||||||
|             self.get_cursor().executemany (""" |             c = self.get_cursor() | ||||||
|  |             c.executemany (""" | ||||||
|         INSERT INTO HandsPlayers |         INSERT INTO HandsPlayers | ||||||
|         (handId, playerId, startCash, position, tourneyTypeId, |         (handId, playerId, startCash, position, tourneyTypeId, | ||||||
|          card1, card2, card3, card4, startCards, winnings, rake, seatNo, totalProfit, |          card1, card2, card3, card4, startCards, winnings, rake, seatNo, totalProfit, | ||||||
|  | @ -1186,13 +1313,9 @@ class Database: | ||||||
|         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, |         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, |          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,  |          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,  | ||||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" |          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) | ||||||
|                                           ,inserts ) |                                           ,inserts ) | ||||||
|             result.append( self.get_last_insert_id() ) |             result.append( self.get_last_insert_id(c) ) # wrong? not used currently | ||||||
|                  |  | ||||||
|             #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) |  | ||||||
|             #result.append(cursor.fetchall()[0][0]) |  | ||||||
|             result.append( self.get_last_insert_id() ) |  | ||||||
|         except: |         except: | ||||||
|             raise fpdb_simple.FpdbError( "store_hands_players_holdem_omaha error: " + str(sys.exc_value) ) |             raise fpdb_simple.FpdbError( "store_hands_players_holdem_omaha error: " + str(sys.exc_value) ) | ||||||
| 
 | 
 | ||||||
|  | @ -1215,13 +1338,14 @@ class Database: | ||||||
|                 card6 = Card.cardFromValueSuit(card_values[i][5], card_suits[i][5]) |                 card6 = Card.cardFromValueSuit(card_values[i][5], card_suits[i][5]) | ||||||
|                 card7 = Card.cardFromValueSuit(card_values[i][6], card_suits[i][6]) |                 card7 = Card.cardFromValueSuit(card_values[i][6], card_suits[i][6]) | ||||||
| 
 | 
 | ||||||
|                 self.get_cursor().execute ("""INSERT INTO HandsPlayers |                 c = self.get_cursor() | ||||||
|  |                 c.execute ("""INSERT INTO HandsPlayers | ||||||
|         (handId, playerId, startCash, ante, tourneyTypeId, |         (handId, playerId, startCash, ante, tourneyTypeId, | ||||||
|         card1, card2, |         card1, card2, | ||||||
|         card3, card4, |         card3, card4, | ||||||
|         card5, card6, |         card5, card6, | ||||||
|         card7, winnings, rake, seatNo) |         card7, winnings, rake, seatNo) | ||||||
|         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", |         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']), | ||||||
|                 (hands_id, player_ids[i], start_cashes[i], antes[i], 1,  |                 (hands_id, player_ids[i], start_cashes[i], antes[i], 1,  | ||||||
|                 card1, card2, |                 card1, card2, | ||||||
|                 card3, card4, |                 card3, card4, | ||||||
|  | @ -1229,7 +1353,7 @@ class Database: | ||||||
|                 card7, winnings[i], rakes[i], seatNos[i])) |                 card7, winnings[i], rakes[i], seatNos[i])) | ||||||
|                 #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) |                 #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) | ||||||
|                 #result.append(cursor.fetchall()[0][0]) |                 #result.append(cursor.fetchall()[0][0]) | ||||||
|                 result.append( self.get_last_insert_id() ) |                 result.append( self.get_last_insert_id(c) ) | ||||||
|         except: |         except: | ||||||
|             raise fpdb_simple.FpdbError( "store_hands_players_stud error: " + str(sys.exc_value) ) |             raise fpdb_simple.FpdbError( "store_hands_players_stud error: " + str(sys.exc_value) ) | ||||||
| 
 | 
 | ||||||
|  | @ -1292,7 +1416,8 @@ class Database: | ||||||
|                                  hudCache['street3Bets'][i], hudCache['street4Bets'][i] |                                  hudCache['street3Bets'][i], hudCache['street4Bets'][i] | ||||||
|                                 ) ) |                                 ) ) | ||||||
| 
 | 
 | ||||||
|             self.get_cursor().executemany (""" |             c = self.get_cursor() | ||||||
|  |             c.executemany (""" | ||||||
|         INSERT INTO HandsPlayers |         INSERT INTO HandsPlayers | ||||||
|         (handId, playerId, startCash, position, tourneyTypeId, |         (handId, playerId, startCash, position, tourneyTypeId, | ||||||
|          card1, card2, card3, card4, startCards, winnings, rake, tourneysPlayersId, seatNo, totalProfit, |          card1, card2, card3, card4, startCards, winnings, rake, tourneysPlayersId, seatNo, totalProfit, | ||||||
|  | @ -1316,10 +1441,10 @@ class Database: | ||||||
|         (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, |         (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, |          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,  |          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,  | ||||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" |          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) | ||||||
|                                           ,inserts ) |                                           ,inserts ) | ||||||
| 
 | 
 | ||||||
|             result.append( self.get_last_insert_id() ) |             result.append( self.get_last_insert_id(c) ) | ||||||
|             #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) |             #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) | ||||||
|             #result.append(cursor.fetchall()[0][0]) |             #result.append(cursor.fetchall()[0][0]) | ||||||
|         except: |         except: | ||||||
|  | @ -1335,14 +1460,15 @@ class Database: | ||||||
|         try: |         try: | ||||||
|             result=[] |             result=[] | ||||||
|             for i in xrange(len(player_ids)): |             for i in xrange(len(player_ids)): | ||||||
|                 self.get_cursor().execute ("""INSERT INTO HandsPlayers |                 c = self.get_cursor() | ||||||
|  |                 c.execute ("""INSERT INTO HandsPlayers | ||||||
|         (handId, playerId, startCash, ante, |         (handId, playerId, startCash, ante, | ||||||
|         card1Value, card1Suit, card2Value, card2Suit, |         card1Value, card1Suit, card2Value, card2Suit, | ||||||
|         card3Value, card3Suit, card4Value, card4Suit, |         card3Value, card3Suit, card4Value, card4Suit, | ||||||
|         card5Value, card5Suit, card6Value, card6Suit, |         card5Value, card5Suit, card6Value, card6Suit, | ||||||
|         card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo) |         card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo) | ||||||
|         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, |         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||||||
|         %s, %s, %s, %s, %s, %s)""", |         %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']), | ||||||
|                 (hands_id, player_ids[i], start_cashes[i], antes[i], |                 (hands_id, player_ids[i], start_cashes[i], antes[i], | ||||||
|                 card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1], |                 card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1], | ||||||
|                 card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3], |                 card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3], | ||||||
|  | @ -1350,7 +1476,7 @@ class Database: | ||||||
|                 card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i])) |                 card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i])) | ||||||
|                 #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) |                 #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) | ||||||
|                 #result.append(cursor.fetchall()[0][0]) |                 #result.append(cursor.fetchall()[0][0]) | ||||||
|                 result.append( self.get_last_insert_id() ) |                 result.append( self.get_last_insert_id(c) ) | ||||||
|         except: |         except: | ||||||
|             raise fpdb_simple.FpdbError( "store_hands_players_stud_tourney error: " + str(sys.exc_value) ) |             raise fpdb_simple.FpdbError( "store_hands_players_stud_tourney error: " + str(sys.exc_value) ) | ||||||
|          |          | ||||||
|  | @ -1488,24 +1614,28 @@ class Database: | ||||||
|     AND   position=%s  |     AND   position=%s  | ||||||
|     AND   tourneyTypeId+0=%s |     AND   tourneyTypeId+0=%s | ||||||
|     AND   styleKey=%s |     AND   styleKey=%s | ||||||
|                           """, (row[6], row[7], row[8], row[9], row[10], |                                      """.replace('%s', self.sql.query['placeholder']) | ||||||
|                                 row[11], row[12], row[13], row[14], row[15], |                                     ,(row[6], row[7], row[8], row[9], row[10], | ||||||
|                                 row[16], row[17], row[18], row[19], row[20], |                                       row[11], row[12], row[13], row[14], row[15], | ||||||
|                                 row[21], row[22], row[23], row[24], row[25], |                                       row[16], row[17], row[18], row[19], row[20], | ||||||
|                                 row[26], row[27], row[28], row[29], row[30], |                                       row[21], row[22], row[23], row[24], row[25], | ||||||
|                                 row[31], row[32], row[33], row[34], row[35], |                                       row[26], row[27], row[28], row[29], row[30], | ||||||
|                                 row[36], row[37], row[38], row[39], row[40], |                                       row[31], row[32], row[33], row[34], row[35], | ||||||
|                                 row[41], row[42], row[43], row[44], row[45], |                                       row[36], row[37], row[38], row[39], row[40], | ||||||
|                                 row[46], row[47], row[48], row[49], row[50], |                                       row[41], row[42], row[43], row[44], row[45], | ||||||
|                                 row[51], row[52], row[53], row[54], row[55], |                                       row[46], row[47], row[48], row[49], row[50], | ||||||
|                                 row[56], row[57], row[58], row[59], row[60], |                                       row[51], row[52], row[53], row[54], row[55], | ||||||
|                                 row[1], row[2], row[3], str(row[4]), row[5], styleKey)) |                                       row[56], row[57], row[58], row[59], row[60], | ||||||
|  |                                       row[1], row[2], row[3], str(row[4]), row[5], styleKey)) | ||||||
|                 # Test statusmessage to see if update worked, do insert if not |                 # Test statusmessage to see if update worked, do insert if not | ||||||
|                 #print "storehud2, upd num =", num |                 #print "storehud2, upd num =", num.rowcount | ||||||
|  |                 # num is a cursor in sqlite | ||||||
|                 if (   (backend == self.PGSQL and cursor.statusmessage != "UPDATE 1") |                 if (   (backend == self.PGSQL and cursor.statusmessage != "UPDATE 1") | ||||||
|                     or (backend == self.MYSQL_INNODB and num == 0) ): |                     or (backend == self.MYSQL_INNODB and num == 0)  | ||||||
|  |                     or (backend == self.SQLITE and num.rowcount == 0)  | ||||||
|  |                    ): | ||||||
|                     #print "playerid before insert:",row[2]," num = ", num |                     #print "playerid before insert:",row[2]," num = ", num | ||||||
|                     cursor.execute("""INSERT INTO HudCache |                     num = cursor.execute("""INSERT INTO HudCache | ||||||
|     (gametypeId, playerId, activeSeats, position, tourneyTypeId, styleKey, |     (gametypeId, playerId, activeSeats, position, tourneyTypeId, styleKey, | ||||||
|     HDs, street0VPI, street0Aggr, street0_3BChance, street0_3BDone, |     HDs, street0VPI, street0Aggr, street0_3BChance, street0_3BDone, | ||||||
|     street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown, |     street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown, | ||||||
|  | @ -1529,14 +1659,14 @@ class Database: | ||||||
|     %s, %s, %s, %s, %s, |     %s, %s, %s, %s, %s, | ||||||
|     %s, %s, %s, %s, %s, |     %s, %s, %s, %s, %s, | ||||||
|     %s, %s, %s, %s, %s, |     %s, %s, %s, %s, %s, | ||||||
|     %s, %s, %s, %s, %s)""" |     %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) | ||||||
|                                   , (row[1], row[2], row[3], row[4], row[5], styleKey, row[6], row[7], row[8], row[9], row[10] |                                   , (row[1], row[2], row[3], row[4], row[5], styleKey, row[6], row[7], row[8], row[9], row[10] | ||||||
|                                     ,row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20] |                                     ,row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20] | ||||||
|                                     ,row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30] |                                     ,row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30] | ||||||
|                                     ,row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40] |                                     ,row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40] | ||||||
|                                     ,row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50] |                                     ,row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50] | ||||||
|                                     ,row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60]) ) |                                     ,row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60]) ) | ||||||
|                     #print "hopefully inserted hud data line: ", cursor.statusmessage |                     #print "hopefully inserted hud data line: ", cursor.rowcount | ||||||
|                     # message seems to be "INSERT 0 1" |                     # message seems to be "INSERT 0 1" | ||||||
|                 else: |                 else: | ||||||
|                     #print "updated(2) hud data line" |                     #print "updated(2) hud data line" | ||||||
|  | @ -1552,7 +1682,8 @@ class Database: | ||||||
|     def store_tourneys(self, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime): |     def store_tourneys(self, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime): | ||||||
|         try: |         try: | ||||||
|             cursor = self.get_cursor() |             cursor = self.get_cursor() | ||||||
|             cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId)) |             cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s".replace('%s', self.sql.query['placeholder']) | ||||||
|  |                           , (siteTourneyNo, tourneyTypeId)) | ||||||
|             tmp=cursor.fetchone() |             tmp=cursor.fetchone() | ||||||
|             #print "tried SELECTing tourneys.id, result:",tmp |             #print "tried SELECTing tourneys.id, result:",tmp | ||||||
|              |              | ||||||
|  | @ -1561,7 +1692,8 @@ class Database: | ||||||
|             except TypeError:#means we have to create new one |             except TypeError:#means we have to create new one | ||||||
|                 cursor.execute("""INSERT INTO Tourneys |                 cursor.execute("""INSERT INTO Tourneys | ||||||
|         (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime) |         (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime) | ||||||
|         VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)) |         VALUES (%s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) | ||||||
|  |                               ,(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)) | ||||||
|                 cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId)) |                 cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId)) | ||||||
|                 tmp=cursor.fetchone() |                 tmp=cursor.fetchone() | ||||||
|                 #print "created new tourneys.id:",tmp |                 #print "created new tourneys.id:",tmp | ||||||
|  | @ -1581,7 +1713,8 @@ class Database: | ||||||
|             #print "ranks:",ranks |             #print "ranks:",ranks | ||||||
|             #print "winnings:",winnings |             #print "winnings:",winnings | ||||||
|             for i in xrange(len(player_ids)): |             for i in xrange(len(player_ids)): | ||||||
|                 cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i])) |                 cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s".replace('%s', self.sql.query['placeholder']) | ||||||
|  |                               ,(tourney_id, player_ids[i])) | ||||||
|                 tmp=cursor.fetchone() |                 tmp=cursor.fetchone() | ||||||
|                 #print "tried SELECTing tourneys_players.id:",tmp |                 #print "tried SELECTing tourneys_players.id:",tmp | ||||||
|                  |                  | ||||||
|  | @ -1589,10 +1722,10 @@ class Database: | ||||||
|                     len(tmp) |                     len(tmp) | ||||||
|                 except TypeError: |                 except TypeError: | ||||||
|                     cursor.execute("""INSERT INTO TourneysPlayers |                     cursor.execute("""INSERT INTO TourneysPlayers | ||||||
|         (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""", |         (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']), | ||||||
|                     (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i])) |                     (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i])) | ||||||
|                      |                      | ||||||
|                     cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", |                     cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s".replace('%s', self.sql.query['placeholder']), | ||||||
|                                    (tourney_id, player_ids[i])) |                                    (tourney_id, player_ids[i])) | ||||||
|                     tmp=cursor.fetchone() |                     tmp=cursor.fetchone() | ||||||
|                     #print "created new tourneys_players.id:",tmp |                     #print "created new tourneys_players.id:",tmp | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| 
 | 
 | ||||||
| import threading | import threading | ||||||
| import subprocess | import subprocess | ||||||
|  | import traceback | ||||||
| 
 | 
 | ||||||
| import pygtk | import pygtk | ||||||
| pygtk.require('2.0') | pygtk.require('2.0') | ||||||
|  |  | ||||||
|  | @ -74,7 +74,10 @@ class GuiBulkImport(): | ||||||
|                 cb_hmodel = self.cb_drophudcache.get_model() |                 cb_hmodel = self.cb_drophudcache.get_model() | ||||||
|                 cb_hindex = self.cb_drophudcache.get_active() |                 cb_hindex = self.cb_drophudcache.get_active() | ||||||
| 
 | 
 | ||||||
|                 self.lab_info.set_text("Importing") # doesn't display :-( |                 self.lab_info.set_markup('<span foreground="blue">Importing ...</span>') # uses pango markup! | ||||||
|  |                 while gtk.events_pending(): # see http://faq.pygtk.org/index.py?req=index for more hints (3.7) | ||||||
|  |                     gtk.main_iteration(False) | ||||||
|  | 
 | ||||||
|                 if cb_index: |                 if cb_index: | ||||||
|                     self.importer.setDropIndexes(cb_model[cb_index][0]) |                     self.importer.setDropIndexes(cb_model[cb_index][0]) | ||||||
|                 else: |                 else: | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ import pygtk | ||||||
| pygtk.require('2.0') | pygtk.require('2.0') | ||||||
| import gtk | import gtk | ||||||
| import os | import os | ||||||
|  | import traceback | ||||||
| from time import * | from time import * | ||||||
| #import pokereval | #import pokereval | ||||||
| 
 | 
 | ||||||
|  | @ -72,20 +73,19 @@ class GuiGraphViewer (threading.Thread): | ||||||
|         self.mainHBox.show() |         self.mainHBox.show() | ||||||
| 
 | 
 | ||||||
|         self.leftPanelBox = self.filters.get_vbox() |         self.leftPanelBox = self.filters.get_vbox() | ||||||
|         self.graphBox = gtk.VBox(False, 0) |  | ||||||
|         self.graphBox.show() |  | ||||||
| 
 | 
 | ||||||
|         self.hpane = gtk.HPaned() |         self.hpane = gtk.HPaned() | ||||||
|         self.hpane.pack1(self.leftPanelBox) |         self.hpane.pack1(self.leftPanelBox) | ||||||
|  |         self.mainHBox.add(self.hpane) | ||||||
|  |         # hierarchy:  self.mainHBox / self.hpane / self.graphBox / self.canvas / self.fig / self.ax | ||||||
|  | 
 | ||||||
|  |         self.graphBox = gtk.VBox(False, 0) | ||||||
|  |         self.graphBox.show() | ||||||
|         self.hpane.pack2(self.graphBox) |         self.hpane.pack2(self.graphBox) | ||||||
|         self.hpane.show() |         self.hpane.show() | ||||||
| 
 | 
 | ||||||
|         self.mainHBox.add(self.hpane) |  | ||||||
| 
 |  | ||||||
|         self.fig = None |         self.fig = None | ||||||
|         #self.exportButton.set_sensitive(False) |         #self.exportButton.set_sensitive(False) | ||||||
| 
 |  | ||||||
|         self.fig = Figure(figsize=(5,4), dpi=100) |  | ||||||
|         self.canvas = None |         self.canvas = None | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -125,79 +125,103 @@ class GuiGraphViewer (threading.Thread): | ||||||
|     #end def get_vbox |     #end def get_vbox | ||||||
| 
 | 
 | ||||||
|     def clearGraphData(self): |     def clearGraphData(self): | ||||||
|         self.fig.clear() |  | ||||||
|         if self.canvas is not None: |  | ||||||
|             self.canvas.destroy() |  | ||||||
| 
 | 
 | ||||||
|         self.canvas = FigureCanvas(self.fig)  # a gtk.DrawingArea |         try: | ||||||
|  |             try: | ||||||
|  |                 if self.canvas: | ||||||
|  |                     self.graphBox.remove(self.canvas) | ||||||
|  |             except: | ||||||
|  |                 pass | ||||||
|  | 
 | ||||||
|  |             if self.fig != None: | ||||||
|  |                 self.fig.clear() | ||||||
|  |             self.fig = Figure(figsize=(5,4), dpi=100) | ||||||
|  |             if self.canvas is not None: | ||||||
|  |                 self.canvas.destroy() | ||||||
|  | 
 | ||||||
|  |             self.canvas = FigureCanvas(self.fig)  # a gtk.DrawingArea | ||||||
|  |         except: | ||||||
|  |             err = traceback.extract_tb(sys.exc_info()[2])[-1] | ||||||
|  |             print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) | ||||||
|  |             raise | ||||||
| 
 | 
 | ||||||
|     def generateGraph(self, widget, data): |     def generateGraph(self, widget, data): | ||||||
|         self.clearGraphData() |         print "generateGraph: start" | ||||||
|  |         try: | ||||||
|  |             self.clearGraphData() | ||||||
|  |             print "after cleardata" | ||||||
| 
 | 
 | ||||||
|         sitenos = [] |             sitenos = [] | ||||||
|         playerids = [] |             playerids = [] | ||||||
| 
 | 
 | ||||||
|         sites   = self.filters.getSites() |             sites   = self.filters.getSites() | ||||||
|         heroes  = self.filters.getHeroes() |             heroes  = self.filters.getHeroes() | ||||||
|         siteids = self.filters.getSiteIds() |             siteids = self.filters.getSiteIds() | ||||||
|         limits  = self.filters.getLimits() |             limits  = self.filters.getLimits() | ||||||
|         # Which sites are selected? |             print "got filter data" | ||||||
|         for site in sites: |             # Which sites are selected? | ||||||
|             if sites[site] == True: |             for site in sites: | ||||||
|                 sitenos.append(siteids[site]) |                 if sites[site] == True: | ||||||
|                 self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],)) |                     sitenos.append(siteids[site]) | ||||||
|                 result = self.db.cursor.fetchall() |                     self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],)) | ||||||
|                 if len(result) == 1: |                     result = self.db.cursor.fetchall() | ||||||
|                     playerids.append(result[0][0]) |                     if len(result) == 1: | ||||||
|  |                         playerids.append(result[0][0]) | ||||||
| 
 | 
 | ||||||
|         if not sitenos: |             if not sitenos: | ||||||
|             #Should probably pop up here. |                 #Should probably pop up here. | ||||||
|             print "No sites selected - defaulting to PokerStars" |                 print "No sites selected - defaulting to PokerStars" | ||||||
|             return |                 return | ||||||
| 
 | 
 | ||||||
|         if not playerids: |             if not playerids: | ||||||
|             print "No player ids found" |                 print "No player ids found" | ||||||
|             return |                 return | ||||||
| 
 | 
 | ||||||
|         if not limits: |             if not limits: | ||||||
|             print "No limits found" |                 print "No limits found" | ||||||
|             return |                 return | ||||||
| 
 | 
 | ||||||
|         #Set graph properties |             #Set graph properties | ||||||
|         self.ax = self.fig.add_subplot(111) |             print "add_subplot" | ||||||
|  |             self.ax = self.fig.add_subplot(111) | ||||||
| 
 | 
 | ||||||
|         #Get graph data from DB |             #Get graph data from DB | ||||||
|         starttime = time() |             starttime = time() | ||||||
|         line = self.getRingProfitGraph(playerids, sitenos, limits) |             print "get line: playerids =", playerids, "sitenos =", sitenos, "limits =", limits | ||||||
|         print "Graph generated in: %s" %(time() - starttime) |             line = self.getRingProfitGraph(playerids, sitenos, limits) | ||||||
|  |             print "Graph generated in: %s" %(time() - starttime) | ||||||
| 
 | 
 | ||||||
|         self.ax.set_title("Profit graph for ring games") |             self.ax.set_title("Profit graph for ring games") | ||||||
| 
 | 
 | ||||||
|         #Set axis labels and grid overlay properites |             #Set axis labels and grid overlay properites | ||||||
|         self.ax.set_xlabel("Hands", fontsize = 12) |             self.ax.set_xlabel("Hands", fontsize = 12) | ||||||
|         self.ax.set_ylabel("$", fontsize = 12) |             self.ax.set_ylabel("$", fontsize = 12) | ||||||
|         self.ax.grid(color='g', linestyle=':', linewidth=0.2) |             self.ax.grid(color='g', linestyle=':', linewidth=0.2) | ||||||
|         if line == None or line == []: |             if line == None or line == []: | ||||||
| 
 | 
 | ||||||
|             #TODO: Do something useful like alert user |                 #TODO: Do something useful like alert user | ||||||
|             print "No hands returned by graph query" |                 print "No hands returned by graph query" | ||||||
|         else: |             else: | ||||||
| #            text = "All Hands, " + sitename + str(name) + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line)) |     #            text = "All Hands, " + sitename + str(name) + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line)) | ||||||
|             text = "All Hands, " + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line)) |                 text = "All Hands, " + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line)) | ||||||
| 
 | 
 | ||||||
|             self.ax.annotate(text, |                 self.ax.annotate(text, | ||||||
|                              xy=(10, -10), |                                  xy=(10, -10), | ||||||
|                              xycoords='axes points', |                                  xycoords='axes points', | ||||||
|                              horizontalalignment='left', verticalalignment='top', |                                  horizontalalignment='left', verticalalignment='top', | ||||||
|                              fontsize=10) |                                  fontsize=10) | ||||||
| 
 | 
 | ||||||
|             #Draw plot |                 #Draw plot | ||||||
|             self.ax.plot(line,) |                 self.ax.plot(line,) | ||||||
|  | 
 | ||||||
|  |                 self.graphBox.add(self.canvas) | ||||||
|  |                 self.canvas.show() | ||||||
|  |                 self.canvas.draw() | ||||||
|  |                 #self.exportButton.set_sensitive(True) | ||||||
|  |         except: | ||||||
|  |             err = traceback.extract_tb(sys.exc_info()[2])[-1] | ||||||
|  |             print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) | ||||||
| 
 | 
 | ||||||
|             self.graphBox.add(self.canvas) |  | ||||||
|             self.canvas.show() |  | ||||||
|             self.canvas.draw() |  | ||||||
|             #self.exportButton.set_sensitive(True) |  | ||||||
|     #end of def showClicked |     #end of def showClicked | ||||||
| 
 | 
 | ||||||
|     def getRingProfitGraph(self, names, sites, limits): |     def getRingProfitGraph(self, names, sites, limits): | ||||||
|  |  | ||||||
|  | @ -81,7 +81,7 @@ class GuiPlayerStats (threading.Thread): | ||||||
|                        , ["hand",       False, "Hand",     0.0, "%s"]   # true not allowed for this line |                        , ["hand",       False, "Hand",     0.0, "%s"]   # true not allowed for this line | ||||||
|                        , ["plposition", False, "Posn",     1.0, "%s"]   # true not allowed for this line (set in code) |                        , ["plposition", False, "Posn",     1.0, "%s"]   # true not allowed for this line (set in code) | ||||||
|                        , ["n",          True,  "Hds",      1.0, "%d"] |                        , ["n",          True,  "Hds",      1.0, "%d"] | ||||||
|                        , ["avgseats",   True,  "Seats",    1.0, "%3.1f"] |                        , ["avgseats",   False,  "Seats",    1.0, "%3.1f"] | ||||||
|                        , ["vpip",       True,  "VPIP",     1.0, "%3.1f"] |                        , ["vpip",       True,  "VPIP",     1.0, "%3.1f"] | ||||||
|                        , ["pfr",        True,  "PFR",      1.0, "%3.1f"] |                        , ["pfr",        True,  "PFR",      1.0, "%3.1f"] | ||||||
|                        , ["pf3",        True,  "PF3",      1.0, "%3.1f"] |                        , ["pf3",        True,  "PF3",      1.0, "%3.1f"] | ||||||
|  | @ -132,7 +132,7 @@ class GuiPlayerStats (threading.Thread): | ||||||
|         self.stats_vbox = gtk.VBox(False, 0) |         self.stats_vbox = gtk.VBox(False, 0) | ||||||
|         self.stats_vbox.show() |         self.stats_vbox.show() | ||||||
|         self.stats_frame.add(self.stats_vbox) |         self.stats_frame.add(self.stats_vbox) | ||||||
|         self.fillStatsFrame(self.stats_vbox) |         # self.fillStatsFrame(self.stats_vbox) | ||||||
| 
 | 
 | ||||||
|         self.main_hbox.pack_start(self.filters.get_vbox()) |         self.main_hbox.pack_start(self.filters.get_vbox()) | ||||||
|         self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True) |         self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True) | ||||||
|  | @ -167,7 +167,9 @@ class GuiPlayerStats (threading.Thread): | ||||||
|         for site in sites: |         for site in sites: | ||||||
|             if sites[site] == True: |             if sites[site] == True: | ||||||
|                 sitenos.append(siteids[site]) |                 sitenos.append(siteids[site]) | ||||||
|                 self.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],)) |                 # Nasty hack to deal with multiple sites + same player name -Eric | ||||||
|  |                 que = self.sql.query['getPlayerId'] + " AND siteId=%d" % siteids[site] | ||||||
|  |                 self.cursor.execute(que, (heroes[site],)) | ||||||
|                 result = self.db.cursor.fetchall() |                 result = self.db.cursor.fetchall() | ||||||
|                 if len(result) == 1: |                 if len(result) == 1: | ||||||
|                     playerids.append(result[0][0]) |                     playerids.append(result[0][0]) | ||||||
|  |  | ||||||
|  | @ -22,280 +22,269 @@ import gtk | ||||||
| import os | import os | ||||||
| import fpdb_simple | import fpdb_simple | ||||||
| 
 | 
 | ||||||
| try: |  | ||||||
| 	import MySQLdb |  | ||||||
| except: # Try to make postgres case cleaner, and kill the error note |  | ||||||
|     try: |  | ||||||
|         import psycopg2 |  | ||||||
|     except ImportError: |  | ||||||
|         pass |  | ||||||
| 	 |  | ||||||
| import fpdb_import | import fpdb_import | ||||||
| import fpdb_db | import fpdb_db | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| class GuiTableViewer (threading.Thread): | class GuiTableViewer (threading.Thread): | ||||||
| 	def hudDivide (self, a, b): |     def hudDivide (self, a, b): | ||||||
| 		if b==0: |         if b==0: | ||||||
| 			return "n/a" |             return "n/a" | ||||||
| 		else: |         else: | ||||||
| 			return str(int((a/float(b))*100))+"%" |             return str(int((a/float(b))*100))+"%" | ||||||
| 	#end def hudDivide |     #end def hudDivide | ||||||
| 	 |      | ||||||
| 	def browse_clicked(self, widget, data): |     def browse_clicked(self, widget, data): | ||||||
| 		"""runs when user clicks browse on tv tab""" |         """runs when user clicks browse on tv tab""" | ||||||
| 		#print "start of table_viewer.browser_clicked" |         #print "start of table_viewer.browser_clicked" | ||||||
| 		current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) |         current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) | ||||||
| 		 |  | ||||||
| 		dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer", |  | ||||||
| 				action=gtk.FILE_CHOOSER_ACTION_OPEN, |  | ||||||
| 				buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) |  | ||||||
| 		#dia_chooser.set_current_folder(pathname) |  | ||||||
| 		dia_chooser.set_filename(current_path) |  | ||||||
| 		#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import |  | ||||||
| 		 |  | ||||||
| 		response = dia_chooser.run() |  | ||||||
| 		if response == gtk.RESPONSE_OK: |  | ||||||
| 			#print dia_chooser.get_filename(), 'selected' |  | ||||||
| 			self.filename_tbuffer.set_text(dia_chooser.get_filename()) |  | ||||||
| 		elif response == gtk.RESPONSE_CANCEL: |  | ||||||
| 			print 'Closed, no files selected' |  | ||||||
| 		dia_chooser.destroy()		 |  | ||||||
| 	#end def table_viewer.browse_clicked |  | ||||||
| 	 |  | ||||||
| 	def prepare_data(self): |  | ||||||
| 		"""prepares the data for display by refresh_clicked, returns a 2D array""" |  | ||||||
| 		#print "start of prepare_data" |  | ||||||
| 		arr=[] |  | ||||||
| 		#first prepare the header row |  | ||||||
| 		if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"): |  | ||||||
| 			tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST") |  | ||||||
| 			 |  | ||||||
| 			tmp+=("FS", "FB") |  | ||||||
| 			 |  | ||||||
| 			tmp+=("CB", ) |  | ||||||
| 			 |  | ||||||
| 			tmp+=("2B", "3B") |  | ||||||
| 			 |  | ||||||
| 			tmp+=("AF", "FF", "AT", "FT", "AR", "FR") |  | ||||||
| 			 |  | ||||||
| 			tmp+=("WtSD", "W$wsF", "W$SD") |  | ||||||
| 		else: |  | ||||||
| 			raise fpdb_simple.FpdbError("reimplement stud") |  | ||||||
| 		arr.append(tmp) |  | ||||||
| 		 |  | ||||||
| 		#then the data rows |  | ||||||
| 		for player in range(len(self.player_names)): |  | ||||||
| 			tmp=[] |  | ||||||
| 			tmp.append(self.player_names[player][0]) |  | ||||||
| 			 |  | ||||||
| 			seatCount=len(self.player_names) |  | ||||||
| 			if seatCount>=8: |  | ||||||
| 				minSeats,maxSeats=7,10 |  | ||||||
| 			elif seatCount==7: |  | ||||||
| 				minSeats,maxSeats=6,10 |  | ||||||
| 			elif seatCount==6 or seatCount==5: |  | ||||||
| 				minSeats,maxSeats=seatCount-1,seatCount+1 |  | ||||||
| 			elif seatCount==4: |  | ||||||
| 				minSeats,maxSeats=4,5 |  | ||||||
| 			elif seatCount==2 or seatCount==3: |  | ||||||
| 				minSeats,maxSeats=seatCount,seatCount |  | ||||||
| 			else: |  | ||||||
| 				fpdb_simple.FpdbError("invalid seatCount") |  | ||||||
| 			 |  | ||||||
| 			self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats)) |  | ||||||
| 			rows=self.cursor.fetchall() |  | ||||||
| 			 |  | ||||||
| 			row=[] |  | ||||||
| 			for field_no in range(len(rows[0])): |  | ||||||
| 				row.append(rows[0][field_no]) |  | ||||||
| 			 |  | ||||||
| 			for row_no in range(len(rows)): |  | ||||||
| 				if row_no==0: |  | ||||||
| 					pass |  | ||||||
| 				else: |  | ||||||
| 					for field_no in range(len(rows[row_no])): |  | ||||||
| 						if field_no<=3: |  | ||||||
| 							pass |  | ||||||
| 						else: |  | ||||||
| 							#print "in prep data, row_no:",row_no,"field_no:",field_no |  | ||||||
| 							row[field_no]+=rows[row_no][field_no] |  | ||||||
| 			 |  | ||||||
| 			tmp.append(str(row[6]))#Hands |  | ||||||
| 			tmp.append(self.hudDivide(row[7],row[6])) #VPIP |  | ||||||
| 			tmp.append(self.hudDivide(row[8],row[6])) #PFR |  | ||||||
| 			tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B |  | ||||||
| 			 |  | ||||||
| 			tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST |  | ||||||
| 			 |  | ||||||
| 			tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS |  | ||||||
| 			tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB |  | ||||||
| 			 |  | ||||||
| 			tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB |  | ||||||
| 			 |  | ||||||
| 			tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B |  | ||||||
| 			tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B |  | ||||||
| 			 |  | ||||||
| 			tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF |  | ||||||
| 			tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF |  | ||||||
| 			tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT |  | ||||||
| 			tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT |  | ||||||
| 			tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR |  | ||||||
| 			tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR |  | ||||||
| 			 |  | ||||||
| 			tmp.append(self.hudDivide(row[15],row[11])) #WtSD |  | ||||||
| 			tmp.append(self.hudDivide(row[28],row[11])) #W$wSF |  | ||||||
| 			tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD |  | ||||||
| 			 |  | ||||||
| 			arr.append(tmp) |  | ||||||
| 		return arr |  | ||||||
| 	#end def table_viewer.prepare_data |  | ||||||
| 	 |  | ||||||
| 	def refresh_clicked(self, widget, data): |  | ||||||
| 		"""runs when user clicks refresh""" |  | ||||||
| 		#print "start of table_viewer.refresh_clicked" |  | ||||||
| 		arr=self.prepare_data() |  | ||||||
| 		 |  | ||||||
| 		try: self.data_table.destroy() |  | ||||||
| 		except AttributeError: pass |  | ||||||
| 		self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False) |  | ||||||
| 		self.main_vbox.pack_start(self.data_table) |  | ||||||
| 		self.data_table.show() |  | ||||||
| 		 |  | ||||||
| 		for row in range(len(arr)): |  | ||||||
| 			for column in range (len(arr[row])): |  | ||||||
| 				eventBox=gtk.EventBox() |  | ||||||
| 				new_label=gtk.Label(arr[row][column]) |  | ||||||
| 				if row%2==0: # |  | ||||||
| 					bg_col="white" |  | ||||||
| 					if column==0 or (column>=5 and column<=10): |  | ||||||
| 						bg_col="lightgrey" |  | ||||||
| 				else: |  | ||||||
| 					bg_col="lightgrey" |  | ||||||
| 					if column==0 or (column>=5 and column<=10): |  | ||||||
| 						bg_col="grey" |  | ||||||
| 				#style = eventBox.get_style() |  | ||||||
| 				#style.font.height=8 |  | ||||||
| 				#eventBox.set_style(style) |  | ||||||
| 
 |  | ||||||
| 				eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col)) |  | ||||||
| 				eventBox.add(new_label) |  | ||||||
| 				self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1) |  | ||||||
| 				eventBox.show() |  | ||||||
| 				new_label.show() |  | ||||||
| 	#end def table_viewer.refresh_clicked |  | ||||||
| 
 |  | ||||||
| 	def read_names_clicked(self, widget, data): |  | ||||||
| 		"""runs when user clicks read names""" |  | ||||||
| 		#print "start of table_viewer.read_names_clicked" |  | ||||||
| 		self.db.reconnect() |  | ||||||
| 		self.cursor=self.db.cursor |  | ||||||
| 		#self.hands_id=self.last_read_hand_id |  | ||||||
| 
 |  | ||||||
| 		self.db.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, )) |  | ||||||
| 		self.gametype_id=self.db.cursor.fetchone()[0] |  | ||||||
| 		self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, )) |  | ||||||
| 		self.category=self.db.cursor.fetchone()[0] |  | ||||||
| 		#print "self.gametype_id", self.gametype_id,"  category:", self.category, "  self.hands_id:", self.hands_id |  | ||||||
| 		 |  | ||||||
| 		self.db.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers |  | ||||||
| 				INNER JOIN Players ON HandsPlayers.playerId=Players.id |  | ||||||
| 				WHERE handId=%s""", (self.hands_id, )) |  | ||||||
| 		self.player_ids=self.db.cursor.fetchall() |  | ||||||
| 		#print "self.player_ids:",self.player_ids |  | ||||||
| 		 |  | ||||||
| 		self.db.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers |  | ||||||
| 				INNER JOIN Players ON HandsPlayers.playerId=Players.id |  | ||||||
| 				WHERE handId=%s""", (self.hands_id, )) |  | ||||||
| 		self.player_names=self.db.cursor.fetchall() |  | ||||||
| 		#print "self.player_names:",self.player_names |  | ||||||
| 	#end def table_viewer.read_names_clicked |  | ||||||
| 
 |  | ||||||
| 	def import_clicked(self, widget, data): |  | ||||||
| 		"""runs when user clicks import""" |  | ||||||
| 		#print "start of table_viewer.import_clicked" |  | ||||||
| 		self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) |  | ||||||
| 		 |  | ||||||
| 		self.server=self.db.host |  | ||||||
| 		self.database=self.db.database |  | ||||||
| 		self.user=self.db.user |  | ||||||
| 		self.password=self.db.password |  | ||||||
| 
 |  | ||||||
| 		self.importer = fpdb_import.Importer(self, self.settings) |  | ||||||
| 		self.importer.setMinPrint(0) |  | ||||||
| 		self.importer.setQuiet(False) |  | ||||||
| 		self.importer.setFailOnError(False) |  | ||||||
| 		self.importer.setHandCount(0) |  | ||||||
| 		 |  | ||||||
| 		self.importer.addImportFile(self.inputFile) |  | ||||||
| 		self.importer.runImport() |  | ||||||
| 		self.hands_id=self.importer.handsId |  | ||||||
| 	#end def table_viewer.import_clicked |  | ||||||
| 
 |  | ||||||
| 	def all_clicked(self, widget, data): |  | ||||||
| 		"""runs when user clicks all""" |  | ||||||
| 		#print "start of table_viewer.all_clicked" |  | ||||||
| 		self.import_clicked(widget, data) |  | ||||||
| 		self.read_names_clicked(widget, data) |  | ||||||
| 		self.refresh_clicked(widget, data) |  | ||||||
| 	#end def table_viewer.all_clicked |  | ||||||
| 
 |  | ||||||
| 	def get_vbox(self): |  | ||||||
| 		"""returns the vbox of this thread""" |  | ||||||
| 		return self.main_vbox |  | ||||||
| 	#end def get_vbox |  | ||||||
| 	 |  | ||||||
| 	def __init__(self, db, settings, debug=True): |  | ||||||
| 		"""Constructor for table_viewer""" |  | ||||||
| 		self.debug=debug |  | ||||||
| 		#print "start of table_viewer constructor" |  | ||||||
| 		self.db=db |  | ||||||
| 		self.cursor=db.cursor |  | ||||||
| 		self.settings=settings |  | ||||||
|          |          | ||||||
| 		self.main_vbox = gtk.VBox(False, 0) |         dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer", | ||||||
| 		self.main_vbox.show() |                 action=gtk.FILE_CHOOSER_ACTION_OPEN, | ||||||
| 
 |                 buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) | ||||||
| 		self.settings_hbox = gtk.HBox(False, 0) |         #dia_chooser.set_current_folder(pathname) | ||||||
| 		self.main_vbox.pack_end(self.settings_hbox, False, True, 0) |         dia_chooser.set_filename(current_path) | ||||||
| 		self.settings_hbox.show() |         #dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import | ||||||
| 		 |  | ||||||
| 		self.filename_label = gtk.Label("Path of history file") |  | ||||||
| 		self.settings_hbox.pack_start(self.filename_label, False, False) |  | ||||||
| 		self.filename_label.show() |  | ||||||
| 		 |  | ||||||
| 		self.filename_tbuffer=gtk.TextBuffer() |  | ||||||
| 		self.filename_tbuffer.set_text(self.settings['hud-defaultPath']) |  | ||||||
| 		self.filename_tview=gtk.TextView(self.filename_tbuffer) |  | ||||||
| 		self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5) |  | ||||||
| 		self.filename_tview.show() |  | ||||||
| 		 |  | ||||||
| 		self.browse_button=gtk.Button("Browse...") |  | ||||||
| 		self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked") |  | ||||||
| 		self.settings_hbox.pack_start(self.browse_button, False, False) |  | ||||||
|  		self.browse_button.show() |  | ||||||
| 		 |  | ||||||
| 
 |  | ||||||
| 		self.button_hbox = gtk.HBox(False, 0) |  | ||||||
| 		self.main_vbox.pack_end(self.button_hbox, False, True, 0) |  | ||||||
| 		self.button_hbox.show() |  | ||||||
| 		 |  | ||||||
| 		#self.import_button = gtk.Button("Import") |  | ||||||
| 		#self.import_button.connect("clicked", self.import_clicked, "Import clicked") |  | ||||||
| 		#self.button_hbox.add(self.import_button) |  | ||||||
|  		#self.import_button.show() |  | ||||||
|          |          | ||||||
| 		#self.read_names_button = gtk.Button("Read Names") |         response = dia_chooser.run() | ||||||
| 		#self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked") |         if response == gtk.RESPONSE_OK: | ||||||
| 		#self.button_hbox.add(self.read_names_button) |             #print dia_chooser.get_filename(), 'selected' | ||||||
| 		#self.read_names_button.show() |             self.filename_tbuffer.set_text(dia_chooser.get_filename()) | ||||||
| 		 |         elif response == gtk.RESPONSE_CANCEL: | ||||||
| 		#self.refresh_button = gtk.Button("Show/Refresh data") |             print 'Closed, no files selected' | ||||||
| 		#self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked") |         dia_chooser.destroy()         | ||||||
| 		#self.button_hbox.add(self.refresh_button) |     #end def table_viewer.browse_clicked | ||||||
| 		#self.refresh_button.show() |      | ||||||
| 		 |     def prepare_data(self): | ||||||
| 		self.all_button = gtk.Button("Import&Read&Refresh") |         """prepares the data for display by refresh_clicked, returns a 2D array""" | ||||||
| 		self.all_button.connect("clicked", self.all_clicked, "All clicked") |         #print "start of prepare_data" | ||||||
| 		self.button_hbox.add(self.all_button) |         arr=[] | ||||||
| 		self.all_button.show() |         #first prepare the header row | ||||||
| 	#end of table_viewer.__init__ |         if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"): | ||||||
|  |             tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST") | ||||||
|  |              | ||||||
|  |             tmp+=("FS", "FB") | ||||||
|  |              | ||||||
|  |             tmp+=("CB", ) | ||||||
|  |              | ||||||
|  |             tmp+=("2B", "3B") | ||||||
|  |              | ||||||
|  |             tmp+=("AF", "FF", "AT", "FT", "AR", "FR") | ||||||
|  |              | ||||||
|  |             tmp+=("WtSD", "W$wsF", "W$SD") | ||||||
|  |         else: | ||||||
|  |             raise fpdb_simple.FpdbError("reimplement stud") | ||||||
|  |         arr.append(tmp) | ||||||
|  |          | ||||||
|  |         #then the data rows | ||||||
|  |         for player in range(len(self.player_names)): | ||||||
|  |             tmp=[] | ||||||
|  |             tmp.append(self.player_names[player][0]) | ||||||
|  |              | ||||||
|  |             seatCount=len(self.player_names) | ||||||
|  |             if seatCount>=8: | ||||||
|  |                 minSeats,maxSeats=7,10 | ||||||
|  |             elif seatCount==7: | ||||||
|  |                 minSeats,maxSeats=6,10 | ||||||
|  |             elif seatCount==6 or seatCount==5: | ||||||
|  |                 minSeats,maxSeats=seatCount-1,seatCount+1 | ||||||
|  |             elif seatCount==4: | ||||||
|  |                 minSeats,maxSeats=4,5 | ||||||
|  |             elif seatCount==2 or seatCount==3: | ||||||
|  |                 minSeats,maxSeats=seatCount,seatCount | ||||||
|  |             else: | ||||||
|  |                 fpdb_simple.FpdbError("invalid seatCount") | ||||||
|  |              | ||||||
|  |             self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats)) | ||||||
|  |             rows=self.cursor.fetchall() | ||||||
|  |              | ||||||
|  |             row=[] | ||||||
|  |             for field_no in range(len(rows[0])): | ||||||
|  |                 row.append(rows[0][field_no]) | ||||||
|  |              | ||||||
|  |             for row_no in range(len(rows)): | ||||||
|  |                 if row_no==0: | ||||||
|  |                     pass | ||||||
|  |                 else: | ||||||
|  |                     for field_no in range(len(rows[row_no])): | ||||||
|  |                         if field_no<=3: | ||||||
|  |                             pass | ||||||
|  |                         else: | ||||||
|  |                             #print "in prep data, row_no:",row_no,"field_no:",field_no | ||||||
|  |                             row[field_no]+=rows[row_no][field_no] | ||||||
|  |              | ||||||
|  |             tmp.append(str(row[6]))#Hands | ||||||
|  |             tmp.append(self.hudDivide(row[7],row[6])) #VPIP | ||||||
|  |             tmp.append(self.hudDivide(row[8],row[6])) #PFR | ||||||
|  |             tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B | ||||||
|  |              | ||||||
|  |             tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST | ||||||
|  |              | ||||||
|  |             tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS | ||||||
|  |             tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB | ||||||
|  |              | ||||||
|  |             tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB | ||||||
|  |              | ||||||
|  |             tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B | ||||||
|  |             tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B | ||||||
|  |              | ||||||
|  |             tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF | ||||||
|  |             tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF | ||||||
|  |             tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT | ||||||
|  |             tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT | ||||||
|  |             tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR | ||||||
|  |             tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR | ||||||
|  |              | ||||||
|  |             tmp.append(self.hudDivide(row[15],row[11])) #WtSD | ||||||
|  |             tmp.append(self.hudDivide(row[28],row[11])) #W$wSF | ||||||
|  |             tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD | ||||||
|  |              | ||||||
|  |             arr.append(tmp) | ||||||
|  |         return arr | ||||||
|  |     #end def table_viewer.prepare_data | ||||||
|  |      | ||||||
|  |     def refresh_clicked(self, widget, data): | ||||||
|  |         """runs when user clicks refresh""" | ||||||
|  |         #print "start of table_viewer.refresh_clicked" | ||||||
|  |         arr=self.prepare_data() | ||||||
|  |          | ||||||
|  |         try: self.data_table.destroy() | ||||||
|  |         except AttributeError: pass | ||||||
|  |         self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False) | ||||||
|  |         self.main_vbox.pack_start(self.data_table) | ||||||
|  |         self.data_table.show() | ||||||
|  |          | ||||||
|  |         for row in range(len(arr)): | ||||||
|  |             for column in range (len(arr[row])): | ||||||
|  |                 eventBox=gtk.EventBox() | ||||||
|  |                 new_label=gtk.Label(arr[row][column]) | ||||||
|  |                 if row%2==0: # | ||||||
|  |                     bg_col="white" | ||||||
|  |                     if column==0 or (column>=5 and column<=10): | ||||||
|  |                         bg_col="lightgrey" | ||||||
|  |                 else: | ||||||
|  |                     bg_col="lightgrey" | ||||||
|  |                     if column==0 or (column>=5 and column<=10): | ||||||
|  |                         bg_col="grey" | ||||||
|  |                 #style = eventBox.get_style() | ||||||
|  |                 #style.font.height=8 | ||||||
|  |                 #eventBox.set_style(style) | ||||||
|  | 
 | ||||||
|  |                 eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col)) | ||||||
|  |                 eventBox.add(new_label) | ||||||
|  |                 self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1) | ||||||
|  |                 eventBox.show() | ||||||
|  |                 new_label.show() | ||||||
|  |     #end def table_viewer.refresh_clicked | ||||||
|  | 
 | ||||||
|  |     def read_names_clicked(self, widget, data): | ||||||
|  |         """runs when user clicks read names""" | ||||||
|  |         #print "start of table_viewer.read_names_clicked" | ||||||
|  |         self.db.reconnect() | ||||||
|  |         self.cursor=self.db.get_cursor() | ||||||
|  |         #self.hands_id=self.last_read_hand_id | ||||||
|  | 
 | ||||||
|  |         self.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, )) | ||||||
|  |         self.gametype_id=self.cursor.fetchone()[0] | ||||||
|  |         self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, )) | ||||||
|  |         self.category=self.cursor.fetchone()[0] | ||||||
|  |         #print "self.gametype_id", self.gametype_id,"  category:", self.category, "  self.hands_id:", self.hands_id | ||||||
|  |          | ||||||
|  |         self.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers | ||||||
|  |                 INNER JOIN Players ON HandsPlayers.playerId=Players.id | ||||||
|  |                 WHERE handId=%s""", (self.hands_id, )) | ||||||
|  |         self.player_ids=self.cursor.fetchall() | ||||||
|  |         #print "self.player_ids:",self.player_ids | ||||||
|  |          | ||||||
|  |         self.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers | ||||||
|  |                 INNER JOIN Players ON HandsPlayers.playerId=Players.id | ||||||
|  |                 WHERE handId=%s""", (self.hands_id, )) | ||||||
|  |         self.player_names=self.cursor.fetchall() | ||||||
|  |         #print "self.player_names:",self.player_names | ||||||
|  |     #end def table_viewer.read_names_clicked | ||||||
|  | 
 | ||||||
|  |     def import_clicked(self, widget, data): | ||||||
|  |         """runs when user clicks import""" | ||||||
|  |         #print "start of table_viewer.import_clicked" | ||||||
|  |         self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) | ||||||
|  | 
 | ||||||
|  |         self.importer = fpdb_import.Importer(self, self.settings, self.config) | ||||||
|  |         self.importer.setMinPrint(0) | ||||||
|  |         self.importer.setQuiet(False) | ||||||
|  |         self.importer.setFailOnError(False) | ||||||
|  |         self.importer.setHandCount(0) | ||||||
|  | 
 | ||||||
|  |         self.importer.addImportFile(self.inputFile) | ||||||
|  |         self.importer.runImport() | ||||||
|  |         self.hands_id=self.importer.handsId | ||||||
|  |     #end def table_viewer.import_clicked | ||||||
|  | 
 | ||||||
|  |     def all_clicked(self, widget, data): | ||||||
|  |         """runs when user clicks all""" | ||||||
|  |         #print "start of table_viewer.all_clicked" | ||||||
|  |         self.import_clicked(widget, data) | ||||||
|  |         self.read_names_clicked(widget, data) | ||||||
|  |         self.refresh_clicked(widget, data) | ||||||
|  |     #end def table_viewer.all_clicked | ||||||
|  | 
 | ||||||
|  |     def get_vbox(self): | ||||||
|  |         """returns the vbox of this thread""" | ||||||
|  |         return self.main_vbox | ||||||
|  |     #end def get_vbox | ||||||
|  |      | ||||||
|  |     def __init__(self, db, settings, config=None, debug=True): | ||||||
|  |         """Constructor for table_viewer""" | ||||||
|  |         self.debug=debug | ||||||
|  |         #print "start of table_viewer constructor" | ||||||
|  |         self.db = db | ||||||
|  |         self.cursor = db.get_cursor() | ||||||
|  |         self.settings = settings | ||||||
|  |         self.config = config | ||||||
|  |          | ||||||
|  |         self.main_vbox = gtk.VBox(False, 0) | ||||||
|  |         self.main_vbox.show() | ||||||
|  | 
 | ||||||
|  |         self.settings_hbox = gtk.HBox(False, 0) | ||||||
|  |         self.main_vbox.pack_end(self.settings_hbox, False, True, 0) | ||||||
|  |         self.settings_hbox.show() | ||||||
|  |          | ||||||
|  |         self.filename_label = gtk.Label("Path of history file") | ||||||
|  |         self.settings_hbox.pack_start(self.filename_label, False, False) | ||||||
|  |         self.filename_label.show() | ||||||
|  |          | ||||||
|  |         self.filename_tbuffer=gtk.TextBuffer() | ||||||
|  |         self.filename_tbuffer.set_text(self.settings['hud-defaultPath']) | ||||||
|  |         self.filename_tview=gtk.TextView(self.filename_tbuffer) | ||||||
|  |         self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5) | ||||||
|  |         self.filename_tview.show() | ||||||
|  |          | ||||||
|  |         self.browse_button=gtk.Button("Browse...") | ||||||
|  |         self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked") | ||||||
|  |         self.settings_hbox.pack_start(self.browse_button, False, False) | ||||||
|  |         self.browse_button.show() | ||||||
|  |          | ||||||
|  | 
 | ||||||
|  |         self.button_hbox = gtk.HBox(False, 0) | ||||||
|  |         self.main_vbox.pack_end(self.button_hbox, False, True, 0) | ||||||
|  |         self.button_hbox.show() | ||||||
|  |          | ||||||
|  |         #self.import_button = gtk.Button("Import") | ||||||
|  |         #self.import_button.connect("clicked", self.import_clicked, "Import clicked") | ||||||
|  |         #self.button_hbox.add(self.import_button) | ||||||
|  |         #self.import_button.show() | ||||||
|  |          | ||||||
|  |         #self.read_names_button = gtk.Button("Read Names") | ||||||
|  |         #self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked") | ||||||
|  |         #self.button_hbox.add(self.read_names_button) | ||||||
|  |         #self.read_names_button.show() | ||||||
|  |          | ||||||
|  |         #self.refresh_button = gtk.Button("Show/Refresh data") | ||||||
|  |         #self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked") | ||||||
|  |         #self.button_hbox.add(self.refresh_button) | ||||||
|  |         #self.refresh_button.show() | ||||||
|  |          | ||||||
|  |         self.all_button = gtk.Button("Import&Read&Refresh") | ||||||
|  |         self.all_button.connect("clicked", self.all_clicked, "All clicked") | ||||||
|  |         self.button_hbox.add(self.all_button) | ||||||
|  |         self.all_button.show() | ||||||
|  |     #end of table_viewer.__init__ | ||||||
|  |  | ||||||
|  | @ -203,6 +203,96 @@ | ||||||
| 	        	<location seat="9" x="70" y="53">  </location> | 	        	<location seat="9" x="70" y="53">  </location> | ||||||
| 	        </layout> | 	        </layout> | ||||||
| 	    </site> | 	    </site> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	    <site enabled="False" | ||||||
|  | 	          site_name="Absolute" | ||||||
|  | 	          table_finder="AbsolutePoker.exe" | ||||||
|  | 	          screen_name="YOUR SCREEN NAME HERE" | ||||||
|  | 	          site_path="" | ||||||
|  | 	          HH_path="" | ||||||
|  | 	          decoder="everleaf_decode_table" | ||||||
|  |               converter="AbsoluteToFpdb" | ||||||
|  | 	          supported_games="holdem"> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="8" width="794"> | ||||||
|  | 	        	<location seat="1" x="640" y="64">  </location> | ||||||
|  | 	        	<location seat="2" x="650" y="230"> </location> | ||||||
|  | 	        	<location seat="3" x="650" y="385"> </location> | ||||||
|  | 	        	<location seat="4" x="588" y="425"> </location> | ||||||
|  | 	        	<location seat="5" x="92" y="425"> </location> | ||||||
|  | 	        	<location seat="6" x="0" y="373"> </location> | ||||||
|  | 	        	<location seat="7" x="0" y="223"> </location> | ||||||
|  | 	        	<location seat="8" x="25" y="50">  </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="6" width="794"> | ||||||
|  | 	        	<location seat="1" x="640" y="58"> </location> | ||||||
|  | 	        	<location seat="2" x="654" y="288"> </location> | ||||||
|  | 	        	<location seat="3" x="615" y="424"> </location> | ||||||
|  | 	        	<location seat="4" x="70" y="421"> </location> | ||||||
|  | 	        	<location seat="5" x="0" y="280"> </location> | ||||||
|  | 	        	<location seat="6" x="70" y="58"> </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="2" width="794"> | ||||||
|  | 	        	<location seat="1" x="651" y="288"> </location> | ||||||
|  | 	        	<location seat="2" x="10"  y="288"> </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="9" width="794"> | ||||||
|  | 	        	<location seat="1" x="634" y="38">  </location> | ||||||
|  | 	        	<location seat="2" x="667" y="184"> </location> | ||||||
|  | 	        	<location seat="3" x="667" y="321"> </location> | ||||||
|  | 	        	<location seat="4" x="667" y="445"> </location> | ||||||
|  | 	        	<location seat="5" x="337" y="459"> </location> | ||||||
|  | 	        	<location seat="6" x="0" y="400"> </location> | ||||||
|  | 	        	<location seat="7" x="0" y="322"> </location> | ||||||
|  | 	        	<location seat="8" x="0" y="181">  </location> | ||||||
|  | 	        	<location seat="9" x="70" y="53">  </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	    </site> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	    <site enabled="False" | ||||||
|  | 	          site_name="PartyPoker" | ||||||
|  | 	          table_finder="PartyPoker.exe" | ||||||
|  | 	          screen_name="YOUR SCREEN NAME HERE" | ||||||
|  | 	          site_path="" | ||||||
|  | 	          HH_path="" | ||||||
|  | 	          decoder="everleaf_decode_table" | ||||||
|  |               converter="PartyPokerToFpdb" | ||||||
|  | 	          supported_games="holdem"> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="8" width="794"> | ||||||
|  | 	        	<location seat="1" x="640" y="64">  </location> | ||||||
|  | 	        	<location seat="2" x="650" y="230"> </location> | ||||||
|  | 	        	<location seat="3" x="650" y="385"> </location> | ||||||
|  | 	        	<location seat="4" x="588" y="425"> </location> | ||||||
|  | 	        	<location seat="5" x="92" y="425"> </location> | ||||||
|  | 	        	<location seat="6" x="0" y="373"> </location> | ||||||
|  | 	        	<location seat="7" x="0" y="223"> </location> | ||||||
|  | 	        	<location seat="8" x="25" y="50">  </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="6" width="794"> | ||||||
|  | 	        	<location seat="1" x="640" y="58"> </location> | ||||||
|  | 	        	<location seat="2" x="654" y="288"> </location> | ||||||
|  | 	        	<location seat="3" x="615" y="424"> </location> | ||||||
|  | 	        	<location seat="4" x="70" y="421"> </location> | ||||||
|  | 	        	<location seat="5" x="0" y="280"> </location> | ||||||
|  | 	        	<location seat="6" x="70" y="58"> </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="2" width="794"> | ||||||
|  | 	        	<location seat="1" x="651" y="288"> </location> | ||||||
|  | 	        	<location seat="2" x="10"  y="288"> </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	        <layout fav_seat="0" height="547" max="9" width="794"> | ||||||
|  | 	        	<location seat="1" x="634" y="38">  </location> | ||||||
|  | 	        	<location seat="2" x="667" y="184"> </location> | ||||||
|  | 	        	<location seat="3" x="667" y="321"> </location> | ||||||
|  | 	        	<location seat="4" x="667" y="445"> </location> | ||||||
|  | 	        	<location seat="5" x="337" y="459"> </location> | ||||||
|  | 	        	<location seat="6" x="0" y="400"> </location> | ||||||
|  | 	        	<location seat="7" x="0" y="322"> </location> | ||||||
|  | 	        	<location seat="8" x="0" y="181">  </location> | ||||||
|  | 	        	<location seat="9" x="70" y="53">  </location> | ||||||
|  | 	        </layout> | ||||||
|  | 	    </site> | ||||||
|     </supported_sites> |     </supported_sites> | ||||||
| 
 | 
 | ||||||
|     <supported_games> |     <supported_games> | ||||||
|  | @ -337,10 +427,13 @@ | ||||||
|         <hhc site="Full Tilt Poker" converter="FulltiltToFpdb"/> |         <hhc site="Full Tilt Poker" converter="FulltiltToFpdb"/> | ||||||
|         <hhc site="Everleaf" converter="EverleafToFpdb"/> |         <hhc site="Everleaf" converter="EverleafToFpdb"/> | ||||||
|         <hhc site="Win2day" converter="Win2dayToFpdb"/> |         <hhc site="Win2day" converter="Win2dayToFpdb"/> | ||||||
|  |         <hhc site="Absolute" converter="AbsoluteToFpdb"/> | ||||||
|  |         <hhc site="PartyPoker" converter="PartyPokerToFpdb"/> | ||||||
|     </hhcs> |     </hhcs> | ||||||
| 
 | 
 | ||||||
|     <supported_databases> |     <supported_databases> | ||||||
|     	<database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD" db_type="fpdb"></database> |         <database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD" db_type="fpdb"></database> | ||||||
|  |         <!-- <database db_ip="localhost" db_name="fpdb" db_pass="fpdb" db_server="sqlite" db_type="fpdb" db_user="fpdb"/> --> | ||||||
|     </supported_databases> |     </supported_databases> | ||||||
| 
 | 
 | ||||||
| </FreePokerToolsConfig> | </FreePokerToolsConfig> | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ import traceback | ||||||
| 
 | 
 | ||||||
| if not options.errorsToConsole: | 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_." |     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) |     errorFile = open('HUD-error.txt', 'w', 0) | ||||||
|     sys.stderr = errorFile |     sys.stderr = errorFile | ||||||
| 
 | 
 | ||||||
| import thread | import thread | ||||||
|  |  | ||||||
|  | @ -40,7 +40,7 @@ class Hand(object): | ||||||
|     LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'} |     LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'} | ||||||
|     SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''} |     SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''} | ||||||
|     MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose'  : 'HOSE', 'ha': 'HA'} |     MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose'  : 'HOSE', 'ha': 'HA'} | ||||||
|     SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7} |     SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9 } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def __init__(self, sitename, gametype, handText, builtFrom = "HHC"): |     def __init__(self, sitename, gametype, handText, builtFrom = "HHC"): | ||||||
|  | @ -185,31 +185,49 @@ db: a connected fpdb_db object""" | ||||||
|         # TODO: |         # TODO: | ||||||
|         # Players - base playerid and siteid tuple |         # Players - base playerid and siteid tuple | ||||||
|         sqlids = db.getSqlPlayerIDs([p[1] for p in self.players], self.siteId) |         sqlids = db.getSqlPlayerIDs([p[1] for p in self.players], self.siteId) | ||||||
|  | 
 | ||||||
|  |         #Gametypes | ||||||
|  | 
 | ||||||
|  |         print "DEBUG: self.gametype %s" % self.gametype | ||||||
|  |         #Nice way to discover if the game is already listed in the db? | ||||||
|  |         #Also this is using an old method from fpdb_simple - should probably conform to the rest of the inserts | ||||||
|  | 
 | ||||||
|  |         hilo = "h" | ||||||
|  |         if self.gametype['category'] in ['studhilo', 'omahahilo']: | ||||||
|  |             hilo = "s" | ||||||
|  |         elif self.gametype['category'] in ['razz','27_3draw','badugi']: | ||||||
|  |             hilo = "l" | ||||||
|  |         #FIXME - the two zeros are small_bet and big_bet for limit | ||||||
|  |         gtid = db.insertGameTypes( (self.siteId, self.gametype['type'], self.gametype['base'],  | ||||||
|  |                                     self.gametype['category'], self.gametype['limitType'], hilo, | ||||||
|  |                                     self.gametype['sb'], self.gametype['bb'], 0, 0) ) | ||||||
|  |          | ||||||
|  | 
 | ||||||
|         # HudCache data to come from DerivedStats class |         # HudCache data to come from DerivedStats class | ||||||
|         # HandsActions - all actions for all players for all streets - self.actions |         # HandsActions - all actions for all players for all streets - self.actions | ||||||
|         # BoardCards - Skip - no longer necessary |  | ||||||
|         # Hands - Summary information of hand indexed by handId - gameinfo |         # Hands - Summary information of hand indexed by handId - gameinfo | ||||||
|              #hh['siteHandNo'] =  self.handid |         #This should be moved to prepInsert | ||||||
|              # gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), |         hh = {} | ||||||
|                 # |         hh['siteHandNo'] =  self.handid | ||||||
|              #hh['handStart'] = self.starttime |         hh['handStart'] = self.starttime | ||||||
|              # seats TINYINT NOT NULL, |         # seats TINYINT NOT NULL, | ||||||
|                 # |         hh['tableName'] = self.tablename | ||||||
|              #hh['tableName'] = self.tablenam |         hh['maxSeats'] = self.maxseats | ||||||
|              #hh['maxSeats'] = self.maxseats |  | ||||||
|              # boardcard1 smallint,  /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */ |              # boardcard1 smallint,  /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */ | ||||||
|              # boardcard2 smallint, |              # boardcard2 smallint, | ||||||
|              # boardcard3 smallint, |              # boardcard3 smallint, | ||||||
|              # boardcard4 smallint, |              # boardcard4 smallint, | ||||||
|              # boardcard5 smallint, |              # boardcard5 smallint, | ||||||
|                  # Flop turn and river may all be empty - add (likely) too many elements and trim with range |         # Flop turn and river may all be empty - add (likely) too many elements and trim with range | ||||||
|                  # boardcards = board['FLOP'] + board['TURN'] + board['RIVER'] + [u'0x', u'0x', u'0x', u'0x', u'0x'] |         boardcards = self.board['FLOP'] + self.board['TURN'] + self.board['RIVER'] + [u'0x', u'0x', u'0x', u'0x', u'0x'] | ||||||
|                  # cards = [Card.cardFromValueSuit(v,s) for v,s in boardcards[0:4]] |         cards = [Card.encodeCard(c) for c in boardcards[0:5]] | ||||||
|                  # hh['boardcard1'] = cards[0] |         hh['boardcard1'] = cards[0] | ||||||
|                  # hh['boardcard2'] = cards[1] |         hh['boardcard2'] = cards[1] | ||||||
|                  # hh['boardcard3'] = cards[2] |         hh['boardcard3'] = cards[2] | ||||||
|                  # hh['boardcard4'] = cards[3] |         hh['boardcard4'] = cards[3] | ||||||
|                  # hh['boardcard5'] = cards[4] |         hh['boardcard5'] = cards[4] | ||||||
|  | 
 | ||||||
|  |         print hh | ||||||
|              # texture smallint, |              # texture smallint, | ||||||
|              # playersVpi SMALLINT NOT NULL,         /* num of players vpi */ |              # playersVpi SMALLINT NOT NULL,         /* num of players vpi */ | ||||||
|                 # Needs to be recorded |                 # Needs to be recorded | ||||||
|  | @ -244,7 +262,7 @@ db: a connected fpdb_db object""" | ||||||
|              # showdownPot INT,                 /* pot size at sd/street7 */ |              # showdownPot INT,                 /* pot size at sd/street7 */ | ||||||
|              # comment TEXT, |              # comment TEXT, | ||||||
|              # commentTs DATETIME |              # commentTs DATETIME | ||||||
|         # handid = db.storeHand(hh) |         handid = db.storeHand(hh) | ||||||
|         # HandsPlayers - ? ... Do we fix winnings? |         # HandsPlayers - ? ... Do we fix winnings? | ||||||
|         # Tourneys ? |         # Tourneys ? | ||||||
|         # TourneysPlayers |         # TourneysPlayers | ||||||
|  | @ -453,6 +471,7 @@ Add a raise on [street] by [player] to [amountTo] | ||||||
| 
 | 
 | ||||||
|     def addCheck(self, street, player): |     def addCheck(self, street, player): | ||||||
|         #print "DEBUG: %s %s checked" % (street, player) |         #print "DEBUG: %s %s checked" % (street, player) | ||||||
|  |         logging.debug("%s %s checks" % (street, player)) | ||||||
|         self.checkPlayerExists(player) |         self.checkPlayerExists(player) | ||||||
|         self.actions[street].append((player, 'checks')) |         self.actions[street].append((player, 'checks')) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #!/usr/bin/python | #!/usr/bin/python | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
| 
 | 
 | ||||||
| #Copyright 2008 Carl Gherardi | #Copyright 2008 Carl Gherardi | ||||||
| #This program is free software: you can redistribute it and/or modify | #This program is free software: you can redistribute it and/or modify | ||||||
|  | @ -58,10 +59,10 @@ class HandHistoryConverter(): | ||||||
|         else: |         else: | ||||||
|             # TODO: out_path should be sanity checked. |             # TODO: out_path should be sanity checked. | ||||||
|             out_dir = os.path.dirname(self.out_path) |             out_dir = os.path.dirname(self.out_path) | ||||||
|             if not os.path.isdir(out_dir): |             if not os.path.isdir(out_dir) and out_dir != '': | ||||||
|                 logging.info("Creatin directory '%s'" % out_dir) |                 logging.info("Creatin directory '%s'" % out_dir) | ||||||
|                 os.makedirs(out_dir) |                 os.makedirs(out_dir) | ||||||
|             self.out_fh = open(self.out_path, 'w') |             self.out_fh = codecs.open(self.out_path, 'w', 'cp1252') | ||||||
| 
 | 
 | ||||||
|         self.sitename  = sitename |         self.sitename  = sitename | ||||||
|         self.follow = follow |         self.follow = follow | ||||||
|  | @ -95,9 +96,14 @@ Otherwise, finish at eof. | ||||||
|         else: |         else: | ||||||
|             handsList = self.allHandsAsList() |             handsList = self.allHandsAsList() | ||||||
|             logging.info("Parsing %d hands" % len(handsList)) |             logging.info("Parsing %d hands" % len(handsList)) | ||||||
|  |             nBadHangs = 0 | ||||||
|             for handText in handsList: |             for handText in handsList: | ||||||
|                 self.processedHands.append(self.processHand(handText)) |                 try: | ||||||
|             numHands=  len(handsList) |                     self.processedHands.append(self.processHand(handText)) | ||||||
|  |                 except Exception, e: # TODO: it's better to replace it with s-t like HhcEception | ||||||
|  |                     nBadHangs += 1 | ||||||
|  |                     logging.error("Caught exception while parsing hand: %s" % str(e)) | ||||||
|  |             numHands =  len(handsList) - nBadHangs | ||||||
|         endtime = time.time() |         endtime = time.time() | ||||||
|         print "read %d hands in %.3f seconds" % (numHands, endtime - starttime) |         print "read %d hands in %.3f seconds" % (numHands, endtime - starttime) | ||||||
|         if self.out_fh != sys.stdout: |         if self.out_fh != sys.stdout: | ||||||
|  |  | ||||||
|  | @ -60,6 +60,8 @@ class Hud: | ||||||
|     def __init__(self, parent, table, max, poker_game, config, db_connection): |     def __init__(self, parent, table, max, poker_game, config, db_connection): | ||||||
| #    __init__ is (now) intended to be called from the stdin thread, so it | #    __init__ is (now) intended to be called from the stdin thread, so it | ||||||
| #    cannot touch the gui | #    cannot touch the gui | ||||||
|  |         if parent == None: # running from cli .. | ||||||
|  |             self.parent = self | ||||||
|         self.parent        = parent |         self.parent        = parent | ||||||
|         self.table         = table |         self.table         = table | ||||||
|         self.config        = config |         self.config        = config | ||||||
|  | @ -125,7 +127,8 @@ class Hud: | ||||||
|         self.menu = gtk.Menu() |         self.menu = gtk.Menu() | ||||||
|         self.item1 = gtk.MenuItem('Kill this HUD') |         self.item1 = gtk.MenuItem('Kill this HUD') | ||||||
|         self.menu.append(self.item1) |         self.menu.append(self.item1) | ||||||
|         self.item1.connect("activate", self.parent.kill_hud, self.table_name) |         if self.parent != None: | ||||||
|  |             self.item1.connect("activate", self.parent.kill_hud, self.table_name) | ||||||
|         self.item1.show() |         self.item1.show() | ||||||
|          |          | ||||||
|         self.item2 = gtk.MenuItem('Save Layout') |         self.item2 = gtk.MenuItem('Save Layout') | ||||||
|  | @ -233,7 +236,7 @@ class Hud: | ||||||
| #        Need range here, not xrange -> need the actual list         | #        Need range here, not xrange -> need the actual list         | ||||||
|         adj = range(0, self.max + 1) # default seat adjustments = no adjustment |         adj = range(0, self.max + 1) # default seat adjustments = no adjustment | ||||||
| #    does the user have a fav_seat? | #    does the user have a fav_seat? | ||||||
|         if int(config.supported_sites[self.table.site].layout[self.max].fav_seat) > 0: |         if self.table.site != None and int(config.supported_sites[self.table.site].layout[self.max].fav_seat) > 0: | ||||||
|             try: |             try: | ||||||
|                 fav_seat = config.supported_sites[self.table.site].layout[self.max].fav_seat |                 fav_seat = config.supported_sites[self.table.site].layout[self.max].fav_seat | ||||||
|                 actual_seat = self.get_actual_seat(config.supported_sites[self.table.site].screen_name) |                 actual_seat = self.get_actual_seat(config.supported_sites[self.table.site].screen_name) | ||||||
|  | @ -600,15 +603,17 @@ if __name__== "__main__": | ||||||
|      |      | ||||||
|     c = Configuration.Config() |     c = Configuration.Config() | ||||||
|     #tables = Tables.discover(c) |     #tables = Tables.discover(c) | ||||||
|     t = Tables.discover_table_by_name(c, "Motorway") |     t = Tables.discover_table_by_name(c, "Patriot Dr") | ||||||
|     if t is None: |     if t is None: | ||||||
|         print "Table not found." |         print "Table not found." | ||||||
|     db = Database.Database(c, 'fpdb', 'holdem') |     db = Database.Database(c, 'fpdb', 'holdem') | ||||||
|  |      | ||||||
|  |     stat_dict = db.get_stats_from_hand(1) | ||||||
| 
 | 
 | ||||||
| #    for t in tables: | #    for t in tables: | ||||||
|     win = Hud(t, 10, 'holdem', c, db) |     win = Hud(None, t, 10, 'holdem', c, db) # parent, table, max, poker_game, config, db_connection | ||||||
|     win.create(1, c) |     win.create(1, c, stat_dict, None) # hand, config, stat_dict, cards): | ||||||
| #        t.get_details() | #        t.get_details() | ||||||
|     win.update(8300, db, c) |     win.update(8300, c) # self, hand, config): | ||||||
| 
 | 
 | ||||||
|     gtk.main() |     gtk.main() | ||||||
|  |  | ||||||
							
								
								
									
										460
									
								
								pyfpdb/PartyPokerToFpdb.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										460
									
								
								pyfpdb/PartyPokerToFpdb.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,460 @@ | ||||||
|  | #!/usr/bin/env python | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | # | ||||||
|  | #    Copyright 2009, Grigorij Indigirkin | ||||||
|  | #     | ||||||
|  | #    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; either version 2 of the License, or | ||||||
|  | #    (at your option) any later version. | ||||||
|  | #     | ||||||
|  | #    This program is distributed in the hope that it will be useful, | ||||||
|  | #    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | #    GNU General Public License for more details. | ||||||
|  | #     | ||||||
|  | #    You should have received a copy of the GNU General Public License | ||||||
|  | #    along with this program; if not, write to the Free Software | ||||||
|  | #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
|  | ######################################################################## | ||||||
|  | 
 | ||||||
|  | import sys | ||||||
|  | from collections import defaultdict | ||||||
|  | 
 | ||||||
|  | from HandHistoryConverter import * | ||||||
|  | 
 | ||||||
|  | # PartyPoker HH Format | ||||||
|  | 
 | ||||||
|  | class PartyPoker(HandHistoryConverter): | ||||||
|  |     class ParsingException(Exception): | ||||||
|  |         "Usage: raise ParsingException(<msg>[, hh=<hh>])" | ||||||
|  |         def __init__(self, *args, **kwargs): | ||||||
|  |             if len(args)==0: args=[''] + list(args) | ||||||
|  |             msg, args = args[0], args[1:] | ||||||
|  |             if 'hh' in kwargs: | ||||||
|  |                 msg += self.wrapHh(kwargs['hh']) | ||||||
|  |                 del kwargs['hh'] | ||||||
|  |             return Exception.__init__(self, msg, *args, **kwargs) | ||||||
|  |         def wrapHh(self, hh): | ||||||
|  |             return ("\n\nHand history attached below:\n" | ||||||
|  |                     "%(DELIMETER)s\n%(HH)s\n%(DELIMETER)s") % \ | ||||||
|  |                     {'DELIMETER': '#'*50, 'HH': hh} | ||||||
|  |                      | ||||||
|  | ############################################################ | ||||||
|  | #    Class Variables | ||||||
|  | 
 | ||||||
|  |     sym = {'USD': "\$", } | ||||||
|  | 
 | ||||||
|  |     # Static regexes | ||||||
|  |     # $5 USD NL Texas Hold'em - Saturday, July 25, 07:53:52 EDT 2009 | ||||||
|  |     # NL Texas Hold'em $1 USD Buy-in Trny:45685440 Level:8  Blinds-Antes(600/1 200 -50) - Sunday, May 17, 11:25:07 MSKS 2009 | ||||||
|  |     re_GameInfoRing     = re.compile(""" | ||||||
|  |             (?P<CURRENCY>\$|)\s*(?P<RINGLIMIT>\d+)\s*(?:USD)?\s* | ||||||
|  |             (?P<LIMIT>(NL))\s+ | ||||||
|  |             (?P<GAME>(Texas\ Hold\'em)) | ||||||
|  |             \s*\-\s* | ||||||
|  |             (?P<DATETIME>.+) | ||||||
|  |             """, re.VERBOSE) | ||||||
|  |     re_GameInfoTrny     = re.compile(""" | ||||||
|  |             (?P<LIMIT>(NL))\s+ | ||||||
|  |             (?P<GAME>(Texas\ Hold\'em))\s+ | ||||||
|  |             (?P<BUYIN>\$?[.0-9]+)\s*(?P<BUYIN_CURRENCY>USD)?\s*Buy-in\s+ | ||||||
|  |             Trny:\s?(?P<TOURNO>\d+)\s+ | ||||||
|  |             Level:\s*(?P<LEVEL>\d+)\s+ | ||||||
|  |             Blinds(?:-Antes)?\( | ||||||
|  |                 (?P<SB>[.0-9 ]+)\s* | ||||||
|  |                 /(?P<BB>[.0-9 ]+) | ||||||
|  |                 (?:\s*-\s*(?P<ANTE>[.0-9 ]+)\$?)? | ||||||
|  |             \) | ||||||
|  |             \s*\-\s* | ||||||
|  |             (?P<DATETIME>.+) | ||||||
|  |             """, re.VERBOSE) | ||||||
|  |     re_Hid          = re.compile("^Game \#(?P<HID>\d+) starts.") | ||||||
|  | 
 | ||||||
|  |     re_PlayerInfo   = re.compile(""" | ||||||
|  |           Seat\s(?P<SEAT>\d+):\s | ||||||
|  |           (?P<PNAME>.*)\s | ||||||
|  |           \(\s*\$?(?P<CASH>[0-9,.]+)\s*(?:USD|)\s*\) | ||||||
|  |           """ ,  | ||||||
|  |           re.VERBOSE) | ||||||
|  | 
 | ||||||
|  |     re_HandInfo     = re.compile(""" | ||||||
|  |             ^Table\s+ | ||||||
|  |             (?P<TTYPE>[a-zA-Z0-9 ]+)\s+ | ||||||
|  |             (?: \#|\(|)(?P<TABLE>\d+)\)?\s+ | ||||||
|  |             (?:[^ ]+\s+\#(?P<MTTTABLE>\d+).+)? # table number for mtt | ||||||
|  |             \((?P<PLAY>Real|Play)\s+Money\)\s+ # FIXME: check if play money is correct | ||||||
|  |             Seat\s+(?P<BUTTON>\d+)\sis\sthe\sbutton | ||||||
|  |             """,  | ||||||
|  |           re.MULTILINE|re.VERBOSE) | ||||||
|  | 
 | ||||||
|  |     re_SplitHands   = re.compile('\x00+') | ||||||
|  |     re_TailSplitHands   = re.compile('(\x00+)') | ||||||
|  |     lineSplitter    = '\n' | ||||||
|  |     re_Button       = re.compile('Seat (?P<BUTTON>\d+) is the button', re.MULTILINE) | ||||||
|  |     re_Board        = re.compile(r"\[(?P<CARDS>.+)\]") | ||||||
|  |     re_NoSmallBlind = re.compile('^There is no Small Blind in this hand as the Big Blind of the previous hand left the table') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True, index=0): | ||||||
|  |         """\ | ||||||
|  | in_path   (default '-' = sys.stdin) | ||||||
|  | out_path  (default '-' = sys.stdout) | ||||||
|  | follow :  whether to tail -f the input""" | ||||||
|  |         HandHistoryConverter.__init__(self, in_path, out_path, sitename="PartyPoker", follow=follow, index=index) | ||||||
|  |         logging.info("Initialising PartyPoker converter class") | ||||||
|  |         self.filetype = "text" | ||||||
|  |         self.codepage = "cp1252" # FIXME: wtf? | ||||||
|  |         self.siteId   = 9 # Needs to match id entry in Sites database | ||||||
|  |         self._gameType = None # cached reg-parse result | ||||||
|  |         if autostart:  | ||||||
|  |             self.start() | ||||||
|  | 
 | ||||||
|  |     def allHandsAsList(self): | ||||||
|  |         list = HandHistoryConverter.allHandsAsList(self) | ||||||
|  |         return filter(lambda text: len(text.strip()), list) | ||||||
|  | 
 | ||||||
|  |     def compilePlayerRegexs(self,  hand): | ||||||
|  |         players = set([player[1] for player in hand.players]) | ||||||
|  |         if not players <= self.compiledPlayers: # x <= y means 'x is subset of y' | ||||||
|  |             self.compiledPlayers = players | ||||||
|  |             player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")" | ||||||
|  |             subst = {'PLYR': player_re, 'CUR_SYM': hand.SYMBOL[hand.gametype['currency']], | ||||||
|  |                 'CUR': hand.gametype['currency'] if hand.gametype['currency']!='T$' else ''} | ||||||
|  |             for key in ('CUR_SYM', 'CUR'): | ||||||
|  |                 subst[key] = re.escape(subst[key]) | ||||||
|  |             logging.debug("player_re: " + subst['PLYR']) | ||||||
|  |             logging.debug("CUR_SYM: " + subst['CUR_SYM']) | ||||||
|  |             logging.debug("CUR: " + subst['CUR']) | ||||||
|  |             self.re_PostSB = re.compile( | ||||||
|  |                 r"^%(PLYR)s posts small blind \[%(CUR_SYM)s(?P<SB>[.0-9]+) ?%(CUR)s\]\." %  subst,  | ||||||
|  |                 re.MULTILINE) | ||||||
|  |             self.re_PostBB = re.compile( | ||||||
|  |                 r"^%(PLYR)s posts big blind \[%(CUR_SYM)s(?P<BB>[.0-9]+) ?%(CUR)s\]\." %  subst,  | ||||||
|  |                 re.MULTILINE) | ||||||
|  |             self.re_Antes = re.compile( | ||||||
|  |                 r"^%(PLYR)s posts ante \[%(CUR_SYM)s(?P<ANTE>[.0-9]+) ?%(CUR)s\]\." %  subst, | ||||||
|  |                 re.MULTILINE) | ||||||
|  |             self.re_HeroCards = re.compile( | ||||||
|  |                 r"^Dealt to %(PLYR)s \[\s*(?P<NEWCARDS>.+)\s*\]" % subst, | ||||||
|  |                 re.MULTILINE) | ||||||
|  |             self.re_Action = re.compile(r""" | ||||||
|  |                 ^%(PLYR)s\s+(?P<ATYPE>bets|checks|raises|calls|folds|is\sall-In) | ||||||
|  |                 (?:\s+\[%(CUR_SYM)s(?P<BET>[.,\d]+)\s*%(CUR)s\])? | ||||||
|  |                 """ %  subst,  | ||||||
|  |                 re.MULTILINE|re.VERBOSE) | ||||||
|  |             self.re_ShownCards = re.compile( | ||||||
|  |                 r"^%s (?P<SHOWED>(?:doesn\'t )?shows?) "  %  player_re +  | ||||||
|  |                 r"\[ *(?P<CARDS>.+) *\](?P<COMBINATION>.+)\.",  | ||||||
|  |                 re.MULTILINE) | ||||||
|  |             self.re_CollectPot = re.compile( | ||||||
|  |                 r""""^%(PLYR)s \s+ wins \s+ | ||||||
|  |                 %(CUR_SYM)s(?P<POT>[.\d]+)\s*%(CUR)s""" %  subst,  | ||||||
|  |                 re.MULTILINE|re.VERBOSE) | ||||||
|  | 
 | ||||||
|  |     def readSupportedGames(self): | ||||||
|  |         return [["ring", "hold", "nl"], | ||||||
|  |                 #["ring", "hold", "pl"], | ||||||
|  |                 #["ring", "hold", "fl"], | ||||||
|  | 
 | ||||||
|  |                 ["tour", "hold", "nl"], | ||||||
|  |                 #["tour", "hold", "pl"], | ||||||
|  |                 #["tour", "hold", "fl"], | ||||||
|  |                ] | ||||||
|  | 
 | ||||||
|  |     def _getGameType(self, handText): | ||||||
|  |         if self._gameType is None: | ||||||
|  |             # let's determine whether hand is trny | ||||||
|  |             # and whether 5-th line contains head line | ||||||
|  |             headLine = handText.split(self.lineSplitter)[4] | ||||||
|  |             for headLineContainer in headLine, handText: | ||||||
|  |                 for regexp in self.re_GameInfoTrny, self.re_GameInfoRing: | ||||||
|  |                     m = regexp.search(headLineContainer) | ||||||
|  |                     if m is not None: | ||||||
|  |                         self._gameType = m | ||||||
|  |                         return self._gameType | ||||||
|  |         return self._gameType | ||||||
|  |      | ||||||
|  |     def determineGameType(self, handText): | ||||||
|  |         """inspect the handText and return the gametype dict | ||||||
|  |          | ||||||
|  |         gametype dict is: | ||||||
|  |         {'limitType': xxx, 'base': xxx, 'category': xxx}""" | ||||||
|  | 
 | ||||||
|  |         logging.debug(self.ParsingException().wrapHh( handText )) | ||||||
|  |          | ||||||
|  |         info = {} | ||||||
|  |         m = self._getGameType(handText) | ||||||
|  |         if m is None: | ||||||
|  |             return None | ||||||
|  |          | ||||||
|  |         mg = m.groupdict() | ||||||
|  |         # translations from captured groups to fpdb info strings | ||||||
|  |         limits = { 'NL':'nl',  | ||||||
|  | #            'Pot Limit':'pl', 'Limit':'fl'  | ||||||
|  |             } | ||||||
|  |         games = {                          # base, category | ||||||
|  |                          "Texas Hold'em" : ('hold','holdem'),  | ||||||
|  |                                 #'Omaha' : ('hold','omahahi'), | ||||||
|  |                } | ||||||
|  |         currencies = { '$':'USD', '':'T$' } | ||||||
|  | 
 | ||||||
|  |         for expectedField in ['LIMIT', 'GAME']: | ||||||
|  |             if mg[expectedField] is None: | ||||||
|  |                 raise self.ParsingException( | ||||||
|  |                     "Cannot fetch field '%s'" % expectedField, | ||||||
|  |                     hh = handText) | ||||||
|  |         try: | ||||||
|  |             info['limitType'] = limits[mg['LIMIT']] | ||||||
|  |         except: | ||||||
|  |             raise self.ParsingException( | ||||||
|  |                 "Unknown limit '%s'" % mg['LIMIT'], | ||||||
|  |                 hh = handText) | ||||||
|  | 
 | ||||||
|  |         try: | ||||||
|  |             (info['base'], info['category']) = games[mg['GAME']] | ||||||
|  |         except: | ||||||
|  |             raise self.ParsingException( | ||||||
|  |                 "Unknown game type '%s'" % mg['GAME'], | ||||||
|  |                 hh = handText) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         if 'TOURNO' in mg: | ||||||
|  |             info['type'] = 'tour' | ||||||
|  |         else: | ||||||
|  |             info['type'] = 'ring' | ||||||
|  |          | ||||||
|  |         if info['type'] == 'ring': | ||||||
|  |             info['sb'], info['bb'] = ringBlinds(mg['RINGLIMIT']) | ||||||
|  |             # FIXME: there are only $ and play money availible for cash | ||||||
|  |             info['currency'] = currencies[mg['CURRENCY']] | ||||||
|  |         else: | ||||||
|  |             info['sb'] = renderTrnyMoney(mg['SB']) | ||||||
|  |             info['bb'] = renderTrnyMoney(mg['BB']) | ||||||
|  |             info['currency'] = 'T$' | ||||||
|  |              | ||||||
|  |         # NB: SB, BB must be interpreted as blinds or bets depending on limit type. | ||||||
|  |         return info | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def readHandInfo(self, hand): | ||||||
|  |         info = {} | ||||||
|  |         m = self.re_HandInfo.search(hand.handText,re.DOTALL) | ||||||
|  |         if m: | ||||||
|  |             info.update(m.groupdict()) | ||||||
|  |         else: | ||||||
|  |             raise self.ParsingException("Cannot read Handinfo for current hand", hh=hand.handText) | ||||||
|  |         m = self._getGameType(hand.handText) | ||||||
|  |         if m: info.update(m.groupdict()) | ||||||
|  |         m = self.re_Hid.search(hand.handText) | ||||||
|  |         if m: info.update(m.groupdict()) | ||||||
|  | 
 | ||||||
|  |         # FIXME: it's a hack cause party doesn't supply hand.maxseats info | ||||||
|  |         #hand.maxseats = ??? | ||||||
|  |         hand.mixed = None | ||||||
|  |          | ||||||
|  |         logging.debug("readHandInfo: %s" % info) | ||||||
|  |         for key in info: | ||||||
|  |             if key == 'DATETIME': | ||||||
|  |                 #Saturday, July 25, 07:53:52 EDT 2009 | ||||||
|  |                 #Thursday, July 30, 21:40:41 MSKS 2009 | ||||||
|  |                 m2 = re.search("\w+, (?P<M>\w+) (?P<D>\d+), (?P<H>\d+):(?P<MIN>\d+):(?P<S>\d+) (?P<TZ>[A-Z]+) (?P<Y>\d+)", info[key]) | ||||||
|  |                 # we cant use '%B' due to locale problems | ||||||
|  |                 months = ['January', 'February', 'March', 'April','May', 'June', | ||||||
|  |                     'July','August','September','October','November','December'] | ||||||
|  |                 month = months.index(m2.group('M')) + 1 | ||||||
|  |                 datetimestr = "%s/%s/%s %s:%s:%s" % (m2.group('Y'), month,m2.group('D'),m2.group('H'),m2.group('MIN'),m2.group('S')) | ||||||
|  |                 hand.starttime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") | ||||||
|  |                 # FIXME: some timezone correction required | ||||||
|  |                 #tzShift = defaultdict(lambda:0, {'EDT': -5, 'EST': -6, 'MSKS': 3}) | ||||||
|  |                 #hand.starttime -= datetime.timedelta(hours=tzShift[m2.group('TZ')]) | ||||||
|  |                    | ||||||
|  |             if key == 'HID': | ||||||
|  |                 hand.handid = info[key] | ||||||
|  |             if key == 'TABLE': | ||||||
|  |                 hand.tablename = info[key] | ||||||
|  |             if key == 'BUTTON': | ||||||
|  |                 hand.buttonpos = info[key] | ||||||
|  |             if key == 'TOURNO': | ||||||
|  |                 hand.tourNo = info[key] | ||||||
|  |             if key == 'BUYIN': | ||||||
|  |                 #FIXME: it's dirty hack T_T | ||||||
|  |                 cur = info[key][0] if info[key][0] not in '0123456789' else '' | ||||||
|  |                 hand.buyin = info[key] + '+%s0' % cur | ||||||
|  |             if key == 'LEVEL': | ||||||
|  |                 hand.level = info[key] | ||||||
|  |             if key == 'PLAY' and info['PLAY'] != 'Real': | ||||||
|  |                 # TODO: play money wasn't tested | ||||||
|  | #                hand.currency = 'play' # overrides previously set value | ||||||
|  |                 hand.gametype['currency'] = 'play' | ||||||
|  | 
 | ||||||
|  |     def readButton(self, hand): | ||||||
|  |         m = self.re_Button.search(hand.handText) | ||||||
|  |         if m: | ||||||
|  |             hand.buttonpos = int(m.group('BUTTON')) | ||||||
|  |         else: | ||||||
|  |             logging.info('readButton: not found') | ||||||
|  | 
 | ||||||
|  |     def readPlayerStacks(self, hand): | ||||||
|  |         logging.debug("readPlayerStacks") | ||||||
|  |         m = self.re_PlayerInfo.finditer(hand.handText) | ||||||
|  |         players = [] | ||||||
|  |         for a in m: | ||||||
|  |             hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), | ||||||
|  |                            renderTrnyMoney(a.group('CASH'))) | ||||||
|  | 
 | ||||||
|  |     def markStreets(self, hand): | ||||||
|  |         # PREFLOP = ** Dealing down cards ** | ||||||
|  |         # This re fails if,  say, river is missing; then we don't get the ** that starts the river. | ||||||
|  |         assert hand.gametype['base'] == "hold", \ | ||||||
|  |             "wtf! There're no %s games on party" % hand.gametype['base'] | ||||||
|  |         m =  re.search( | ||||||
|  |             r"\*{2} Dealing down cards \*{2}" | ||||||
|  |             r"(?P<PREFLOP>.+?)" | ||||||
|  |             r"(?:\*{2} Dealing Flop \*{2} (?P<FLOP>\[ \S\S, \S\S, \S\S \].+?))?" | ||||||
|  |             r"(?:\*{2} Dealing Turn \*{2} (?P<TURN>\[ \S\S \].+?))?" | ||||||
|  |             r"(?:\*{2} Dealing River \*{2} (?P<RIVER>\[ \S\S \].+?))?$" | ||||||
|  |             , hand.handText,re.DOTALL) | ||||||
|  |         hand.addStreets(m) | ||||||
|  | 
 | ||||||
|  |     def readCommunityCards(self, hand, street):  | ||||||
|  |         if street in ('FLOP','TURN','RIVER'):    | ||||||
|  |             m = self.re_Board.search(hand.streets[street]) | ||||||
|  |             hand.setCommunityCards(street, renderCards(m.group('CARDS'))) | ||||||
|  | 
 | ||||||
|  |     def readAntes(self, hand): | ||||||
|  |         logging.debug("reading antes") | ||||||
|  |         m = self.re_Antes.finditer(hand.handText) | ||||||
|  |         for player in m: | ||||||
|  |             hand.addAnte(player.group('PNAME'), player.group('ANTE')) | ||||||
|  |      | ||||||
|  |     def readBringIn(self, hand): | ||||||
|  |         m = self.re_BringIn.search(hand.handText,re.DOTALL) | ||||||
|  |         if m: | ||||||
|  |             hand.addBringIn(m.group('PNAME'),  m.group('BRINGIN')) | ||||||
|  |          | ||||||
|  |     def readBlinds(self, hand): | ||||||
|  |         noSmallBlind = bool(self.re_NoSmallBlind.search(hand.handText)) | ||||||
|  |         if hand.gametype['type'] == 'ring': | ||||||
|  |             try: | ||||||
|  |                 assert noSmallBlind==False | ||||||
|  |                 m = self.re_PostSB.search(hand.handText) | ||||||
|  |                 hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB')) | ||||||
|  |             except: # no small blind | ||||||
|  |                 hand.addBlind(None, None, None) | ||||||
|  |                | ||||||
|  |             for a in self.re_PostBB.finditer(hand.handText): | ||||||
|  |                 hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB')) | ||||||
|  |         else:  | ||||||
|  |             # party doesn't track blinds for tournaments | ||||||
|  |             # so there're some cra^Wcaclulations | ||||||
|  |             if hand.buttonpos == 0: | ||||||
|  |                 self.readButton(hand) | ||||||
|  |             # NOTE: code below depends on Hand's implementation | ||||||
|  |             # playersMap - dict {seat: (pname,stack)} | ||||||
|  |             playersMap = dict([(f[0], f[1:3]) for f in hand.players])  | ||||||
|  |             maxSeat = max(playersMap) | ||||||
|  |              | ||||||
|  |             def findFirstNonEmptySeat(startSeat): | ||||||
|  |                 while startSeat not in playersMap: | ||||||
|  |                     if startSeat >= maxSeat:  | ||||||
|  |                         startSeat = 0 | ||||||
|  |                     startSeat += 1 | ||||||
|  |                 return startSeat | ||||||
|  |             smartMin = lambda A,B: A if float(A) <= float(B) else B | ||||||
|  |              | ||||||
|  |             if noSmallBlind: | ||||||
|  |                 hand.addBlind(None, None, None) | ||||||
|  |             else: | ||||||
|  |                 smallBlindSeat = findFirstNonEmptySeat(int(hand.buttonpos) + 1) | ||||||
|  |                 blind = smartMin(hand.sb, playersMap[smallBlindSeat][1]) | ||||||
|  |                 hand.addBlind(playersMap[smallBlindSeat][0], 'small blind', blind) | ||||||
|  |                      | ||||||
|  |             bigBlindSeat = findFirstNonEmptySeat(smallBlindSeat + 1) | ||||||
|  |             blind = smartMin(hand.bb, playersMap[bigBlindSeat][1]) | ||||||
|  |             hand.addBlind(playersMap[bigBlindSeat][0], 'small blind', blind) | ||||||
|  |              | ||||||
|  |                  | ||||||
|  | 
 | ||||||
|  |     def readHeroCards(self, hand): | ||||||
|  |         # we need to grab hero's cards | ||||||
|  |         for street in ('PREFLOP',): | ||||||
|  |             if street in hand.streets.keys(): | ||||||
|  |                 m = self.re_HeroCards.finditer(hand.streets[street]) | ||||||
|  |                 for found in m: | ||||||
|  |                     hand.hero = found.group('PNAME') | ||||||
|  |                     newcards = renderCards(found.group('NEWCARDS')) | ||||||
|  |                     hand.addHoleCards(street, hand.hero, closed=newcards, shown=False, mucked=False, dealt=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def readAction(self, hand, street): | ||||||
|  |         m = self.re_Action.finditer(hand.streets[street]) | ||||||
|  |         for action in m: | ||||||
|  |             acts = action.groupdict() | ||||||
|  |             if action.group('ATYPE') in ('raises','is all-In'): | ||||||
|  |                 hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') ) | ||||||
|  |             elif action.group('ATYPE') == 'calls': | ||||||
|  |                 hand.addCall( street, action.group('PNAME'), action.group('BET') ) | ||||||
|  |             elif action.group('ATYPE') == 'bets': | ||||||
|  |                 hand.addBet( street, action.group('PNAME'), action.group('BET') ) | ||||||
|  |             elif action.group('ATYPE') == 'folds': | ||||||
|  |                 hand.addFold( street, action.group('PNAME')) | ||||||
|  |             elif action.group('ATYPE') == 'checks': | ||||||
|  |                 hand.addCheck( street, action.group('PNAME')) | ||||||
|  |             else: | ||||||
|  |                 print "DEBUG: unimplemented readAction: '%s' '%s'" %(action.group('PNAME'),action.group('ATYPE'),) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def readShowdownActions(self, hand): | ||||||
|  |         # all action in readShownCards | ||||||
|  |         pass | ||||||
|  | 
 | ||||||
|  |     def readCollectPot(self,hand): | ||||||
|  |         for m in self.re_CollectPot.finditer(hand.handText): | ||||||
|  |             hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT')) | ||||||
|  | 
 | ||||||
|  |     def readShownCards(self,hand): | ||||||
|  |         for m in self.re_ShownCards.finditer(hand.handText): | ||||||
|  |             if m.group('CARDS') is not None: | ||||||
|  |                 cards = renderCards(m.group('CARDS')) | ||||||
|  | 
 | ||||||
|  |                 (shown, mucked) = (False, False) | ||||||
|  |                 if m.group('SHOWED') == "show": shown = True | ||||||
|  |                 else: mucked = True | ||||||
|  | 
 | ||||||
|  |                 hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked) | ||||||
|  |                  | ||||||
|  | def ringBlinds(ringLimit): | ||||||
|  |     "Returns blinds for current limit" | ||||||
|  |     ringLimit = float(ringLimit) | ||||||
|  |     if ringLimit == 5.: ringLimit = 4. | ||||||
|  |     return ('%.2f' % (ringLimit/200.), '%.2f' % (ringLimit/100.)  ) | ||||||
|  | 
 | ||||||
|  | def renderTrnyMoney(money): | ||||||
|  |     "renders 'numbers' like '1 200' and '2,000'" | ||||||
|  |     return money.replace(' ', '').replace(',', '') | ||||||
|  | 
 | ||||||
|  | def renderCards(string): | ||||||
|  |     "splits strings like ' Js, 4d '" | ||||||
|  |     cards = string.strip().split(' ') | ||||||
|  |     return filter(len, map(lambda x: x.strip(' ,'), cards)) | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     parser = OptionParser() | ||||||
|  |     parser.add_option("-i", "--input", dest="ipath", help="parse input hand history") | ||||||
|  |     parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-") | ||||||
|  |     parser.add_option("-f", "--follow", dest="follow", help="follow (tail -f) the input", action="store_true", default=False) | ||||||
|  |     parser.add_option("-q", "--quiet", | ||||||
|  |                   action="store_const", const=logging.CRITICAL, dest="verbosity", default=logging.INFO) | ||||||
|  |     parser.add_option("-v", "--verbose", | ||||||
|  |                   action="store_const", const=logging.INFO, dest="verbosity") | ||||||
|  |     parser.add_option("--vv", | ||||||
|  |                   action="store_const", const=logging.DEBUG, dest="verbosity") | ||||||
|  | 
 | ||||||
|  |     (options, args) = parser.parse_args() | ||||||
|  | 
 | ||||||
|  |     #LOG_FILENAME = './logging.out' | ||||||
|  |     logging.basicConfig(level=options.verbosity) | ||||||
|  | 
 | ||||||
|  |     e = PartyPoker(in_path = options.ipath, out_path = options.opath, follow = options.follow) | ||||||
|  | @ -32,7 +32,7 @@ class PokerStars(HandHistoryConverter): | ||||||
|     mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games |     mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games | ||||||
|     sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\x80", "GBP": "\xa3"}         # ADD Euro, Sterling, etc HERE |     sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\x80", "GBP": "\xa3"}         # ADD Euro, Sterling, etc HERE | ||||||
|     substitutions = { |     substitutions = { | ||||||
|                      'LEGAL_ISO' : "USD|EUR|GBP|CAD",    # legal ISO currency codes |                      'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP",    # legal ISO currency codes | ||||||
|                             'LS' : "\$|\x80|\xa3"        # legal currency symbols  ADD Euro, Sterling, etc HERE |                             'LS' : "\$|\x80|\xa3"        # legal currency symbols  ADD Euro, Sterling, etc HERE | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										500
									
								
								pyfpdb/SQL.py
									
									
									
									
									
								
							
							
						
						
									
										500
									
								
								pyfpdb/SQL.py
									
									
									
									
									
								
							|  | @ -1,9 +1,7 @@ | ||||||
| #!/usr/bin/env python | #!/usr/bin/env python | ||||||
| """SQL.py | """Returns a dict of SQL statements used in fpdb. | ||||||
| 
 |  | ||||||
| Set up all of the SQL statements for a given game and database type. |  | ||||||
| """ | """ | ||||||
| #    Copyright 2008, Ray E. Barker | #    Copyright 2008-2009, Ray E. Barker | ||||||
| #    | #    | ||||||
| #    This program is free software; you can redistribute it and/or modify | #    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 | #    it under the terms of the GNU General Public License as published by | ||||||
|  | @ -35,134 +33,8 @@ import re | ||||||
| 
 | 
 | ||||||
| class Sql: | class Sql: | ||||||
|     |     | ||||||
|     def __init__(self, game = 'holdem', type = 'PT3', db_server = 'mysql'): |     def __init__(self, game = 'holdem', type = 'fpdb', db_server = 'mysql'): | ||||||
|         self.query = {} |         self.query = {} | ||||||
| 
 |  | ||||||
| ############################################################################ |  | ||||||
| # |  | ||||||
| #    Support for the ptracks database, a cut down PT2 stud database. |  | ||||||
| #    You can safely ignore this unless you are me. |  | ||||||
| # |  | ||||||
|         if game == 'razz' and type == 'ptracks': |  | ||||||
|             |  | ||||||
|             self.query['get_table_name'] = "select table_name from game where game_id = %s" |  | ||||||
| 
 |  | ||||||
|             self.query['get_last_hand'] = "select max(game_id) from game" |  | ||||||
| 
 |  | ||||||
|             self.query['get_recent_hands'] = "select game_id from game where game_id > %(last_hand)d" |  | ||||||
|             |  | ||||||
|             self.query['get_xml'] = "select xml from hand_history where game_id = %s" |  | ||||||
| 
 |  | ||||||
|             self.query['get_player_id'] = """ |  | ||||||
|                     select player_id from players |  | ||||||
|                     where screen_name = %(player)s |  | ||||||
|                 """ |  | ||||||
|                 |  | ||||||
|             self.query['get_hand_info'] = """ |  | ||||||
|                     SELECT |  | ||||||
|                         game_id, |  | ||||||
|                         CONCAT(hole_card_1, hole_card_2, hole_card_3, hole_card_4, hole_card_5, hole_card_6, hole_card_7) AS hand,  |  | ||||||
|                         total_won-total_bet AS net |  | ||||||
|                     FROM game_players |  | ||||||
|                     WHERE game_id = %s AND player_id = 3 |  | ||||||
|                 """ |  | ||||||
| 
 |  | ||||||
|             self.query['get_cards'] = """ |  | ||||||
|                     select |  | ||||||
|                         seat_number, |  | ||||||
|                         screen_name, |  | ||||||
|                         hole_card_1, |  | ||||||
|                         hole_card_2, |  | ||||||
|                         hole_card_3, |  | ||||||
|                         hole_card_4, |  | ||||||
|                         hole_card_5, |  | ||||||
|                         hole_card_6, |  | ||||||
|                         hole_card_7 |  | ||||||
|                     from game_players, players |  | ||||||
|                     where game_id = %s and game_players.player_id = players.player_id |  | ||||||
|                     order by seat_number |  | ||||||
|                 """ |  | ||||||
|         |  | ||||||
|             self.query['get_stats_from_hand'] = """ |  | ||||||
|                     SELECT player_id, |  | ||||||
|                         count(*)                    AS n, |  | ||||||
|                         sum(pre_fourth_raise_n)     AS pfr, |  | ||||||
|                         sum(fourth_raise_n)         AS raise_n_2, |  | ||||||
|                         sum(fourth_ck_raise_n)      AS cr_n_2, |  | ||||||
|                         sum(fifth_bet_raise_n)      AS br_n_3, |  | ||||||
|                         sum(fifth_bet_ck_raise_n)   AS cr_n_3, |  | ||||||
|                         sum(sixth_bet_raise_n)      AS br_n_4, |  | ||||||
|                         sum(sixth_bet_ck_raise_n)   AS cr_n_4, |  | ||||||
|                         sum(river_bet_raise_n)      AS br_n_5, |  | ||||||
|                         sum(river_bet_ck_raise_n)   AS cr_n_5, |  | ||||||
|                         sum(went_to_showdown_n)     AS sd, |  | ||||||
|                         sum(saw_fourth_n)           AS saw_f, |  | ||||||
|                         sum(raised_first_pf)        AS first_pfr, |  | ||||||
|                         sum(vol_put_money_in_pot)   AS vpip, |  | ||||||
|                         sum(limp_with_prev_callers) AS limp_w_callers, |  | ||||||
| 
 |  | ||||||
|                         sum(ppossible_actions)      AS poss_a_pf, |  | ||||||
|                         sum(pfold)                  AS fold_pf, |  | ||||||
|                         sum(pcheck)                 AS check_pf, |  | ||||||
|                         sum(praise)                 AS raise_pf, |  | ||||||
|                         sum(pcall)                  AS raise_pf, |  | ||||||
|                         sum(limp_call_reraise_pf)   AS limp_call_pf, |  | ||||||
| 
 |  | ||||||
|                         sum(pfr_check)              AS check_after_raise, |  | ||||||
|                         sum(pfr_call)               AS call_after_raise, |  | ||||||
|                         sum(pfr_fold)               AS fold_after_raise, |  | ||||||
|                         sum(pfr_bet)                AS bet_after_raise, |  | ||||||
|                         sum(pfr_raise)              AS raise_after_raise, |  | ||||||
|                         sum(folded_to_river_bet)    AS fold_to_r_bet, |  | ||||||
| 
 |  | ||||||
|                         sum(fpossible_actions)      AS poss_a_2, |  | ||||||
|                         sum(ffold)                  AS fold_2, |  | ||||||
|                         sum(fcheck)                 AS check_2, |  | ||||||
|                         sum(fbet)                   AS bet_2, |  | ||||||
|                         sum(fraise)                 AS raise_2, |  | ||||||
|                         sum(fcall)                  AS raise_2, |  | ||||||
| 
 |  | ||||||
|                         sum(fifpossible_actions)    AS poss_a_3, |  | ||||||
|                         sum(fiffold)                AS fold_3, |  | ||||||
|                         sum(fifcheck)               AS check_3, |  | ||||||
|                         sum(fifbet)                 AS bet_3, |  | ||||||
|                         sum(fifraise)               AS raise_3, |  | ||||||
|                         sum(fifcall)                AS call_3, |  | ||||||
| 
 |  | ||||||
|                         sum(spossible_actions)      AS poss_a_4, |  | ||||||
|                         sum(sfold)                  AS fold_4, |  | ||||||
|                         sum(scheck)                 AS check_4, |  | ||||||
|                         sum(sbet)                   AS bet_4, |  | ||||||
|                         sum(sraise)                 AS raise_4, |  | ||||||
|                         sum(scall)                  AS call_4, |  | ||||||
| 
 |  | ||||||
|                         sum(rpossible_actions)      AS poss_a_5, |  | ||||||
|                         sum(rfold)                  AS fold_5, |  | ||||||
|                         sum(rcheck)                 AS check_5, |  | ||||||
|                         sum(rbet)                   AS bet_5, |  | ||||||
|                         sum(rraise)                 AS raise_5, |  | ||||||
|                         sum(rcall)                  AS call_5, |  | ||||||
| 
 |  | ||||||
|                         sum(cold_call_pf)           AS cc_pf, |  | ||||||
|                         sum(saw_fifth_n)            AS saw_3, |  | ||||||
|                         sum(saw_sixth_n)            AS saw_4, |  | ||||||
|                         sum(saw_river_n)            AS saw_5 |  | ||||||
|                     FROM game_players |  | ||||||
|                     WHERE player_id in |  | ||||||
|                         (SELECT player_id FROM game_players |  | ||||||
|                         WHERE game_id = %s AND NOT player_id = %s) |  | ||||||
|                     GROUP BY player_id |  | ||||||
|                 """ |  | ||||||
| # alternate form of WHERE for above |  | ||||||
| #                        WHERE game_id = %(hand)d AND NOT player_id = %(hero)d) |  | ||||||
| #                        WHERE game_id = %s AND NOT player_id = %s) |  | ||||||
| 
 |  | ||||||
|             self.query['get_players_from_hand'] = """ |  | ||||||
|                     SELECT game_players.player_id, seat_number, screen_name |  | ||||||
|                     FROM game_players INNER JOIN players ON (game_players.player_id = players.player_id) |  | ||||||
|                     WHERE game_id = %s |  | ||||||
|                 """ |  | ||||||
| 
 |  | ||||||
| ###############################################################################3 | ###############################################################################3 | ||||||
| #    Support for the Free Poker DataBase = fpdb   http://fpdb.sourceforge.net/ | #    Support for the Free Poker DataBase = fpdb   http://fpdb.sourceforge.net/ | ||||||
| # | # | ||||||
|  | @ -410,16 +282,37 @@ class Sql: | ||||||
|             elif db_server == 'sqlite': |             elif db_server == 'sqlite': | ||||||
|                 self.query['createHandsTable'] = """CREATE TABLE Hands ( |                 self.query['createHandsTable'] = """CREATE TABLE Hands ( | ||||||
|                                 id INTEGER PRIMARY KEY, |                                 id INTEGER PRIMARY KEY, | ||||||
|                                 tableName TEXT(20), |                                 tableName TEXT(20) NOT NULL, | ||||||
|                                 siteHandNo INTEGER, |                                 siteHandNo INT NOT NULL, | ||||||
|                                 gametypeId INTEGER, |                                 gametypeId INT NOT NULL, | ||||||
|                                 handStart REAL, |                                 handStart REAL NOT NULL, | ||||||
|                                 importTime REAL, |                                 importTime REAL NOT NULL, | ||||||
|                                 seats INTEGER, |                                 seats INT NOT NULL, | ||||||
|                                 maxSeats INTEGER, |                                 maxSeats INT NOT NULL, | ||||||
|  |                                 boardcard1 INT,  /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */ | ||||||
|  |                                 boardcard2 INT, | ||||||
|  |                                 boardcard3 INT, | ||||||
|  |                                 boardcard4 INT, | ||||||
|  |                                 boardcard5 INT, | ||||||
|  |                                 texture INT, | ||||||
|  |                                 playersVpi INT NOT NULL,         /* num of players vpi */ | ||||||
|  |                                 playersAtStreet1 INT NOT NULL,   /* num of players seeing flop/street4 */ | ||||||
|  |                                 playersAtStreet2 INT NOT NULL, | ||||||
|  |                                 playersAtStreet3 INT NOT NULL, | ||||||
|  |                                 playersAtStreet4 INT NOT NULL, | ||||||
|  |                                 playersAtShowdown INT NOT NULL, | ||||||
|  |                                 street0Raises INT NOT NULL, /* num small bets paid to see flop/street4, including blind */ | ||||||
|  |                                 street1Raises INT NOT NULL, /* num small bets paid to see turn/street5 */ | ||||||
|  |                                 street2Raises INT NOT NULL, /* num big bets paid to see river/street6 */ | ||||||
|  |                                 street3Raises INT NOT NULL, /* num big bets paid to see sd/street7 */ | ||||||
|  |                                 street4Raises INT NOT NULL, /* num big bets paid to see showdown */ | ||||||
|  |                                 street1Pot INT,                 /* pot size at flop/street4 */ | ||||||
|  |                                 street2Pot INT,                 /* pot size at turn/street5 */ | ||||||
|  |                                 street3Pot INT,                 /* pot size at river/street6 */ | ||||||
|  |                                 street4Pot INT,                 /* pot size at sd/street7 */ | ||||||
|  |                                 showdownPot INT,                /* pot size at sd/street7 */ | ||||||
|                                 comment TEXT, |                                 comment TEXT, | ||||||
|                                 commentTs REAL, |                                 commentTs REAL)""" | ||||||
|                                 FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)""" |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|             ################################ |             ################################ | ||||||
|  | @ -919,78 +812,78 @@ class Sql: | ||||||
|                             styleKey CHAR(7) NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ |                             styleKey CHAR(7) NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ | ||||||
|                             HDs INT NOT NULL, |                             HDs INT NOT NULL, | ||||||
| 
 | 
 | ||||||
|                             wonWhenSeenStreet1 FLOAT NOT NULL, |                             wonWhenSeenStreet1 FLOAT, | ||||||
|                             wonWhenSeenStreet2 FLOAT, |                             wonWhenSeenStreet2 FLOAT, | ||||||
|                             wonWhenSeenStreet3 FLOAT, |                             wonWhenSeenStreet3 FLOAT, | ||||||
|                             wonWhenSeenStreet4 FLOAT, |                             wonWhenSeenStreet4 FLOAT, | ||||||
|                             wonAtSD FLOAT NOT NULL, |                             wonAtSD FLOAT, | ||||||
| 
 | 
 | ||||||
|                             street0VPI INT NOT NULL, |                             street0VPI INT, | ||||||
|                             street0Aggr INT NOT NULL, |                             street0Aggr INT, | ||||||
|                             street0_3BChance INT NOT NULL, |                             street0_3BChance INT, | ||||||
|                             street0_3BDone INT NOT NULL, |                             street0_3BDone INT, | ||||||
|                             street0_4BChance INT, |                             street0_4BChance INT, | ||||||
|                             street0_4BDone INT, |                             street0_4BDone INT, | ||||||
|                             other3BStreet0 INT, |                             other3BStreet0 INT, | ||||||
|                             other4BStreet0 INT, |                             other4BStreet0 INT, | ||||||
| 
 | 
 | ||||||
|                             street1Seen INT NOT NULL, |                             street1Seen INT, | ||||||
|                             street2Seen INT NOT NULL, |                             street2Seen INT, | ||||||
|                             street3Seen INT NOT NULL, |                             street3Seen INT, | ||||||
|                             street4Seen INT NOT NULL, |                             street4Seen INT, | ||||||
|                             sawShowdown INT NOT NULL, |                             sawShowdown INT, | ||||||
|                              |                              | ||||||
|                             street1Aggr INT NOT NULL, |                             street1Aggr INT, | ||||||
|                             street2Aggr INT NOT NULL, |                             street2Aggr INT, | ||||||
|                             street3Aggr INT NOT NULL, |                             street3Aggr INT, | ||||||
|                             street4Aggr INT NOT NULL, |                             street4Aggr INT, | ||||||
| 
 | 
 | ||||||
|                             otherRaisedStreet0 INT, |                             otherRaisedStreet0 INT, | ||||||
|                             otherRaisedStreet1 INT NOT NULL, |                             otherRaisedStreet1 INT, | ||||||
|                             otherRaisedStreet2 INT NOT NULL, |                             otherRaisedStreet2 INT, | ||||||
|                             otherRaisedStreet3 INT NOT NULL, |                             otherRaisedStreet3 INT, | ||||||
|                             otherRaisedStreet4 INT NOT NULL, |                             otherRaisedStreet4 INT, | ||||||
|                             foldToOtherRaisedStreet0 INT, |                             foldToOtherRaisedStreet0 INT, | ||||||
|                             foldToOtherRaisedStreet1 INT NOT NULL, |                             foldToOtherRaisedStreet1 INT, | ||||||
|                             foldToOtherRaisedStreet2 INT NOT NULL, |                             foldToOtherRaisedStreet2 INT, | ||||||
|                             foldToOtherRaisedStreet3 INT NOT NULL, |                             foldToOtherRaisedStreet3 INT, | ||||||
|                             foldToOtherRaisedStreet4 INT NOT NULL, |                             foldToOtherRaisedStreet4 INT, | ||||||
|                              |                              | ||||||
|                             stealAttemptChance INT NOT NULL, |                             stealAttemptChance INT, | ||||||
|                             stealAttempted INT NOT NULL, |                             stealAttempted INT, | ||||||
|                             foldBbToStealChance INT NOT NULL, |                             foldBbToStealChance INT, | ||||||
|                             foldedBbToSteal INT NOT NULL, |                             foldedBbToSteal INT, | ||||||
|                             foldSbToStealChance INT NOT NULL, |                             foldSbToStealChance INT, | ||||||
|                             foldedSbToSteal INT NOT NULL, |                             foldedSbToSteal INT, | ||||||
| 
 | 
 | ||||||
|                             street1CBChance INT NOT NULL, |                             street1CBChance INT, | ||||||
|                             street1CBDone INT NOT NULL, |                             street1CBDone INT, | ||||||
|                             street2CBChance INT NOT NULL, |                             street2CBChance INT, | ||||||
|                             street2CBDone INT NOT NULL, |                             street2CBDone INT, | ||||||
|                             street3CBChance INT NOT NULL, |                             street3CBChance INT, | ||||||
|                             street3CBDone INT NOT NULL, |                             street3CBDone INT, | ||||||
|                             street4CBChance INT NOT NULL, |                             street4CBChance INT, | ||||||
|                             street4CBDone INT NOT NULL, |                             street4CBDone INT, | ||||||
|                              |                              | ||||||
|                             foldToStreet1CBChance INT NOT NULL, |                             foldToStreet1CBChance INT, | ||||||
|                             foldToStreet1CBDone INT NOT NULL, |                             foldToStreet1CBDone INT, | ||||||
|                             foldToStreet2CBChance INT NOT NULL, |                             foldToStreet2CBChance INT, | ||||||
|                             foldToStreet2CBDone INT NOT NULL, |                             foldToStreet2CBDone INT, | ||||||
|                             foldToStreet3CBChance INT NOT NULL, |                             foldToStreet3CBChance INT, | ||||||
|                             foldToStreet3CBDone INT NOT NULL, |                             foldToStreet3CBDone INT, | ||||||
|                             foldToStreet4CBChance INT NOT NULL, |                             foldToStreet4CBChance INT, | ||||||
|                             foldToStreet4CBDone INT NOT NULL, |                             foldToStreet4CBDone INT, | ||||||
|                              |                              | ||||||
|                             totalProfit INT NOT NULL, |                             totalProfit INT, | ||||||
|                              |                              | ||||||
|                             street1CheckCallRaiseChance INT NOT NULL, |                             street1CheckCallRaiseChance INT, | ||||||
|                             street1CheckCallRaiseDone INT NOT NULL, |                             street1CheckCallRaiseDone INT, | ||||||
|                             street2CheckCallRaiseChance INT NOT NULL, |                             street2CheckCallRaiseChance INT, | ||||||
|                             street2CheckCallRaiseDone INT NOT NULL, |                             street2CheckCallRaiseDone INT, | ||||||
|                             street3CheckCallRaiseChance INT NOT NULL, |                             street3CheckCallRaiseChance INT, | ||||||
|                             street3CheckCallRaiseDone INT NOT NULL, |                             street3CheckCallRaiseDone INT, | ||||||
|                             street4CheckCallRaiseChance INT NOT NULL, |                             street4CheckCallRaiseChance INT, | ||||||
|                             street4CheckCallRaiseDone INT NOT NULL, |                             street4CheckCallRaiseDone INT, | ||||||
| 
 | 
 | ||||||
|                             street0Calls INT, |                             street0Calls INT, | ||||||
|                             street1Calls INT, |                             street1Calls INT, | ||||||
|  | @ -1020,16 +913,16 @@ class Sql: | ||||||
|                             styleKey CHAR(7) NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ |                             styleKey CHAR(7) NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ | ||||||
|                             HDs INT, |                             HDs INT, | ||||||
| 
 | 
 | ||||||
|                             wonWhenSeenStreet1 FLOAT NOT NULL, |                             wonWhenSeenStreet1 FLOAT, | ||||||
|                             wonWhenSeenStreet2 FLOAT, |                             wonWhenSeenStreet2 FLOAT, | ||||||
|                             wonWhenSeenStreet3 FLOAT, |                             wonWhenSeenStreet3 FLOAT, | ||||||
|                             wonWhenSeenStreet4 FLOAT, |                             wonWhenSeenStreet4 FLOAT, | ||||||
|                             wonAtSD FLOAT NOT NULL, |                             wonAtSD FLOAT, | ||||||
| 
 | 
 | ||||||
|                             street0VPI INT NOT NULL, |                             street0VPI INT, | ||||||
|                             street0Aggr INT, |                             street0Aggr INT, | ||||||
|                             street0_3BChance INT NOT NULL, |                             street0_3BChance INT, | ||||||
|                             street0_3BDone INT NOT NULL, |                             street0_3BDone INT, | ||||||
|                             street0_4BChance INT, |                             street0_4BChance INT, | ||||||
|                             street0_4BDone INT, |                             street0_4BDone INT, | ||||||
|                             other3BStreet0 INT, |                             other3BStreet0 INT, | ||||||
|  | @ -1119,16 +1012,16 @@ class Sql: | ||||||
|                             styleKey TEXT NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ |                             styleKey TEXT NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ | ||||||
|                             HDs INT, |                             HDs INT, | ||||||
| 
 | 
 | ||||||
|                             wonWhenSeenStreet1 REAL NOT NULL, |                             wonWhenSeenStreet1 REAL, | ||||||
|                             wonWhenSeenStreet2 REAL, |                             wonWhenSeenStreet2 REAL, | ||||||
|                             wonWhenSeenStreet3 REAL, |                             wonWhenSeenStreet3 REAL, | ||||||
|                             wonWhenSeenStreet4 REAL, |                             wonWhenSeenStreet4 REAL, | ||||||
|                             wonAtSD REAL NOT NULL, |                             wonAtSD REAL, | ||||||
| 
 | 
 | ||||||
|                             street0VPI INT NOT NULL, |                             street0VPI INT, | ||||||
|                             street0Aggr INT, |                             street0Aggr INT, | ||||||
|                             street0_3BChance INT NOT NULL, |                             street0_3BChance INT, | ||||||
|                             street0_3BDone INT NOT NULL, |                             street0_3BDone INT, | ||||||
|                             street0_4BChance INT, |                             street0_4BChance INT, | ||||||
|                             street0_4BDone INT, |                             street0_4BDone INT, | ||||||
|                             other3BStreet0 INT, |                             other3BStreet0 INT, | ||||||
|  | @ -1646,6 +1539,11 @@ class Sql: | ||||||
|                     select coalesce(max(id),0) |                     select coalesce(max(id),0) | ||||||
|                     from Hands |                     from Hands | ||||||
|                     where handStart < now() at time zone 'UTC' - interval '1 day'""" |                     where handStart < now() at time zone 'UTC' - interval '1 day'""" | ||||||
|  |             elif db_server == 'sqlite': | ||||||
|  |                 self.query['get_hand_1day_ago'] = """ | ||||||
|  |                     select coalesce(max(id),0) | ||||||
|  |                     from Hands | ||||||
|  |                     where handStart < strftime('%J', 'now') - 1""" | ||||||
| 
 | 
 | ||||||
|             # not used yet ... |             # not used yet ... | ||||||
|             # gets a date, would need to use handsplayers (not hudcache) to get exact hand Id |             # gets a date, would need to use handsplayers (not hudcache) to get exact hand Id | ||||||
|  | @ -2084,7 +1982,7 @@ class Sql: | ||||||
|                                when stats.PlPosition =  1 then 'CO' |                                when stats.PlPosition =  1 then 'CO' | ||||||
|                                when stats.PlPosition =  2 then 'MP' |                                when stats.PlPosition =  2 then 'MP' | ||||||
|                                when stats.PlPosition =  5 then 'EP' |                                when stats.PlPosition =  5 then 'EP' | ||||||
|                                else '??' |                                else 'xx' | ||||||
|                           end                                                          AS PlPosition |                           end                                                          AS PlPosition | ||||||
|                          ,stats.n |                          ,stats.n | ||||||
|                          ,stats.vpip |                          ,stats.vpip | ||||||
|  | @ -2218,7 +2116,7 @@ class Sql: | ||||||
|                                 when stats.PlPosition =  1 then 'CO' |                                 when stats.PlPosition =  1 then 'CO' | ||||||
|                                 when stats.PlPosition =  2 then 'MP' |                                 when stats.PlPosition =  2 then 'MP' | ||||||
|                                 when stats.PlPosition =  5 then 'EP' |                                 when stats.PlPosition =  5 then 'EP' | ||||||
|                                 else '??' |                                 else 'xx' | ||||||
|                            end                                                          AS PlPosition |                            end                                                          AS PlPosition | ||||||
|                           ,stats.n |                           ,stats.n | ||||||
|                           ,stats.vpip |                           ,stats.vpip | ||||||
|  | @ -2515,7 +2413,7 @@ class Sql: | ||||||
|                             ,hp.tourneyTypeId |                             ,hp.tourneyTypeId | ||||||
|                             ,date_format(h.handStart, 'd%y%m%d') |                             ,date_format(h.handStart, 'd%y%m%d') | ||||||
| """ | """ | ||||||
|             else:   # assume postgres |             elif db_server == 'postgresql': | ||||||
|                 self.query['rebuildHudCache'] = """ |                 self.query['rebuildHudCache'] = """ | ||||||
|                     INSERT INTO HudCache |                     INSERT INTO HudCache | ||||||
|                     (gametypeId |                     (gametypeId | ||||||
|  | @ -2663,6 +2561,154 @@ class Sql: | ||||||
|                             ,hp.tourneyTypeId |                             ,hp.tourneyTypeId | ||||||
|                             ,to_char(h.handStart, 'YYMMDD') |                             ,to_char(h.handStart, 'YYMMDD') | ||||||
| """ | """ | ||||||
|  |             else:   # assume sqlite | ||||||
|  |                 self.query['rebuildHudCache'] = """ | ||||||
|  |                     INSERT INTO HudCache | ||||||
|  |                     (gametypeId | ||||||
|  |                     ,playerId | ||||||
|  |                     ,activeSeats | ||||||
|  |                     ,position | ||||||
|  |                     ,tourneyTypeId | ||||||
|  |                     ,styleKey | ||||||
|  |                     ,HDs | ||||||
|  |                     ,wonWhenSeenStreet1 | ||||||
|  |                     ,wonAtSD | ||||||
|  |                     ,street0VPI | ||||||
|  |                     ,street0Aggr | ||||||
|  |                     ,street0_3BChance | ||||||
|  |                     ,street0_3BDone | ||||||
|  |                     ,street1Seen | ||||||
|  |                     ,street2Seen | ||||||
|  |                     ,street3Seen | ||||||
|  |                     ,street4Seen | ||||||
|  |                     ,sawShowdown | ||||||
|  |                     ,street1Aggr | ||||||
|  |                     ,street2Aggr | ||||||
|  |                     ,street3Aggr | ||||||
|  |                     ,street4Aggr | ||||||
|  |                     ,otherRaisedStreet1 | ||||||
|  |                     ,otherRaisedStreet2 | ||||||
|  |                     ,otherRaisedStreet3 | ||||||
|  |                     ,otherRaisedStreet4 | ||||||
|  |                     ,foldToOtherRaisedStreet1 | ||||||
|  |                     ,foldToOtherRaisedStreet2 | ||||||
|  |                     ,foldToOtherRaisedStreet3 | ||||||
|  |                     ,foldToOtherRaisedStreet4 | ||||||
|  |                     ,stealAttemptChance | ||||||
|  |                     ,stealAttempted | ||||||
|  |                     ,foldBbToStealChance | ||||||
|  |                     ,foldedBbToSteal | ||||||
|  |                     ,foldSbToStealChance | ||||||
|  |                     ,foldedSbToSteal | ||||||
|  |                     ,street1CBChance | ||||||
|  |                     ,street1CBDone | ||||||
|  |                     ,street2CBChance | ||||||
|  |                     ,street2CBDone | ||||||
|  |                     ,street3CBChance | ||||||
|  |                     ,street3CBDone | ||||||
|  |                     ,street4CBChance | ||||||
|  |                     ,street4CBDone | ||||||
|  |                     ,foldToStreet1CBChance | ||||||
|  |                     ,foldToStreet1CBDone | ||||||
|  |                     ,foldToStreet2CBChance | ||||||
|  |                     ,foldToStreet2CBDone | ||||||
|  |                     ,foldToStreet3CBChance | ||||||
|  |                     ,foldToStreet3CBDone | ||||||
|  |                     ,foldToStreet4CBChance | ||||||
|  |                     ,foldToStreet4CBDone | ||||||
|  |                     ,totalProfit | ||||||
|  |                     ,street1CheckCallRaiseChance | ||||||
|  |                     ,street1CheckCallRaiseDone | ||||||
|  |                     ,street2CheckCallRaiseChance | ||||||
|  |                     ,street2CheckCallRaiseDone | ||||||
|  |                     ,street3CheckCallRaiseChance | ||||||
|  |                     ,street3CheckCallRaiseDone | ||||||
|  |                     ,street4CheckCallRaiseChance | ||||||
|  |                     ,street4CheckCallRaiseDone | ||||||
|  |                     ) | ||||||
|  |                     SELECT h.gametypeId | ||||||
|  |                           ,hp.playerId | ||||||
|  |                           ,h.seats | ||||||
|  |                           ,case when hp.position = 'B' then 'B' | ||||||
|  |                                 when hp.position = 'S' then 'S' | ||||||
|  |                                 when hp.position = '0' then 'D' | ||||||
|  |                                 when hp.position = '1' then 'C' | ||||||
|  |                                 when hp.position = '2' then 'M' | ||||||
|  |                                 when hp.position = '3' then 'M' | ||||||
|  |                                 when hp.position = '4' then 'M' | ||||||
|  |                                 when hp.position = '5' then 'E' | ||||||
|  |                                 when hp.position = '6' then 'E' | ||||||
|  |                                 when hp.position = '7' then 'E' | ||||||
|  |                                 when hp.position = '8' then 'E' | ||||||
|  |                                 when hp.position = '9' then 'E' | ||||||
|  |                                 else 'E' | ||||||
|  |                            end                                            AS hc_position | ||||||
|  |                           ,hp.tourneyTypeId | ||||||
|  |                           ,'d' || substr(strftime('%Y%m%d', h.handStart),3,7) | ||||||
|  |                           ,count(1) | ||||||
|  |                           ,sum(wonWhenSeenStreet1) | ||||||
|  |                           ,sum(wonAtSD) | ||||||
|  |                           ,sum(CAST(street0VPI as integer)) | ||||||
|  |                           ,sum(CAST(street0Aggr as integer)) | ||||||
|  |                           ,sum(CAST(street0_3BChance as integer)) | ||||||
|  |                           ,sum(CAST(street0_3BDone as integer)) | ||||||
|  |                           ,sum(CAST(street1Seen as integer)) | ||||||
|  |                           ,sum(CAST(street2Seen as integer)) | ||||||
|  |                           ,sum(CAST(street3Seen as integer)) | ||||||
|  |                           ,sum(CAST(street4Seen as integer)) | ||||||
|  |                           ,sum(CAST(sawShowdown as integer)) | ||||||
|  |                           ,sum(CAST(street1Aggr as integer)) | ||||||
|  |                           ,sum(CAST(street2Aggr as integer)) | ||||||
|  |                           ,sum(CAST(street3Aggr as integer)) | ||||||
|  |                           ,sum(CAST(street4Aggr as integer)) | ||||||
|  |                           ,sum(CAST(otherRaisedStreet1 as integer)) | ||||||
|  |                           ,sum(CAST(otherRaisedStreet2 as integer)) | ||||||
|  |                           ,sum(CAST(otherRaisedStreet3 as integer)) | ||||||
|  |                           ,sum(CAST(otherRaisedStreet4 as integer)) | ||||||
|  |                           ,sum(CAST(foldToOtherRaisedStreet1 as integer)) | ||||||
|  |                           ,sum(CAST(foldToOtherRaisedStreet2 as integer)) | ||||||
|  |                           ,sum(CAST(foldToOtherRaisedStreet3 as integer)) | ||||||
|  |                           ,sum(CAST(foldToOtherRaisedStreet4 as integer)) | ||||||
|  |                           ,sum(CAST(stealAttemptChance as integer)) | ||||||
|  |                           ,sum(CAST(stealAttempted as integer)) | ||||||
|  |                           ,sum(CAST(foldBbToStealChance as integer)) | ||||||
|  |                           ,sum(CAST(foldedBbToSteal as integer)) | ||||||
|  |                           ,sum(CAST(foldSbToStealChance as integer)) | ||||||
|  |                           ,sum(CAST(foldedSbToSteal as integer)) | ||||||
|  |                           ,sum(CAST(street1CBChance as integer)) | ||||||
|  |                           ,sum(CAST(street1CBDone as integer)) | ||||||
|  |                           ,sum(CAST(street2CBChance as integer)) | ||||||
|  |                           ,sum(CAST(street2CBDone as integer)) | ||||||
|  |                           ,sum(CAST(street3CBChance as integer)) | ||||||
|  |                           ,sum(CAST(street3CBDone as integer)) | ||||||
|  |                           ,sum(CAST(street4CBChance as integer)) | ||||||
|  |                           ,sum(CAST(street4CBDone as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet1CBChance as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet1CBDone as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet2CBChance as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet2CBDone as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet3CBChance as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet3CBDone as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet4CBChance as integer)) | ||||||
|  |                           ,sum(CAST(foldToStreet4CBDone as integer)) | ||||||
|  |                           ,sum(CAST(totalProfit as integer)) | ||||||
|  |                           ,sum(CAST(street1CheckCallRaiseChance as integer)) | ||||||
|  |                           ,sum(CAST(street1CheckCallRaiseDone as integer)) | ||||||
|  |                           ,sum(CAST(street2CheckCallRaiseChance as integer)) | ||||||
|  |                           ,sum(CAST(street2CheckCallRaiseDone as integer)) | ||||||
|  |                           ,sum(CAST(street3CheckCallRaiseChance as integer)) | ||||||
|  |                           ,sum(CAST(street3CheckCallRaiseDone as integer)) | ||||||
|  |                           ,sum(CAST(street4CheckCallRaiseChance as integer)) | ||||||
|  |                           ,sum(CAST(street4CheckCallRaiseDone as integer)) | ||||||
|  |                     FROM HandsPlayers hp | ||||||
|  |                     INNER JOIN Hands h ON (h.id = hp.handId) | ||||||
|  |                     GROUP BY h.gametypeId | ||||||
|  |                             ,hp.playerId | ||||||
|  |                             ,h.seats | ||||||
|  |                             ,hc_position | ||||||
|  |                             ,hp.tourneyTypeId | ||||||
|  |                             ,'d' || substr(strftime('%Y%m%d', h.handStart),3,7) | ||||||
|  | """ | ||||||
| 
 | 
 | ||||||
|             if db_server == 'mysql': |             if db_server == 'mysql': | ||||||
|                 self.query['analyze'] = """ |                 self.query['analyze'] = """ | ||||||
|  | @ -2681,13 +2727,51 @@ class Sql: | ||||||
|             else:  # assume postgres |             else:  # assume postgres | ||||||
|                 self.query['lockForInsert'] = "" |                 self.query['lockForInsert'] = "" | ||||||
| 
 | 
 | ||||||
|  |             self.query['getGametypeFL'] = """SELECT id | ||||||
|  |                                                FROM Gametypes | ||||||
|  |                                                WHERE siteId=%s | ||||||
|  |                                                AND   type=%s | ||||||
|  |                                                AND   category=%s | ||||||
|  |                                                AND   limitType=%s | ||||||
|  |                                                AND   smallBet=%s | ||||||
|  |                                                AND   bigBet=%s | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |             self.query['getGametypeNL'] = """SELECT id | ||||||
|  |                                                FROM Gametypes | ||||||
|  |                                                WHERE siteId=%s | ||||||
|  |                                                AND   type=%s | ||||||
|  |                                                AND   category=%s | ||||||
|  |                                                AND   limitType=%s | ||||||
|  |                                                AND   smallBlind=%s | ||||||
|  |                                                AND   bigBlind=%s | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |             self.query['insertGameTypes'] = """INSERT INTO Gametypes | ||||||
|  |                                                   (siteId, type, base, category, limitType | ||||||
|  |                                                   ,hiLo, smallBlind, bigBlind, smallBet, bigBet) | ||||||
|  |                                                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" | ||||||
|  | 
 | ||||||
|  |             self.query['isAlreadyInDB'] = """SELECT id FROM Hands  | ||||||
|  |                                              WHERE gametypeId=%s AND siteHandNo=%s | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |             if db_server == 'mysql': | ||||||
|  |                 self.query['placeholder'] = u'%s' | ||||||
|  |             elif db_server == 'postgresql': | ||||||
|  |                 self.query['placeholder'] = u'%s' | ||||||
|  |             elif db_server == 'sqlite': | ||||||
|  |                 self.query['placeholder'] = u'?' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             # If using sqlite, use the ? placeholder instead of %s | ||||||
|             if db_server == 'sqlite': |             if db_server == 'sqlite': | ||||||
|                 for k,q in self.query.iteritems(): |                 for k,q in self.query.iteritems(): | ||||||
|                     self.query[k] = re.sub('%s','?',q) |                     self.query[k] = re.sub('%s','?',q) | ||||||
| 
 | 
 | ||||||
| if __name__== "__main__": | if __name__== "__main__": | ||||||
| #    just print the default queries and exit | #    just print the default queries and exit | ||||||
|     s = Sql(game = 'razz', type = 'ptracks') |     s = Sql() | ||||||
|     for key in s.query: |     for key in s.query: | ||||||
|         print "For query " + key + ", sql =" |         print "For query " + key + ", sql =" | ||||||
|         print s.query[key] |         print s.query[key] | ||||||
|  |  | ||||||
|  | @ -234,7 +234,7 @@ def discover_nt_by_name(c, tablename): | ||||||
|         #print "Tables.py: tablename =", tablename, "title =", titles[hwnd] |         #print "Tables.py: tablename =", tablename, "title =", titles[hwnd] | ||||||
|         try: |         try: | ||||||
|             # this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html |             # 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 |             if not tablename.lower() in titles[hwnd].lower(): continue | ||||||
|         except: |         except: | ||||||
|             continue |             continue | ||||||
|         if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window |         if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window | ||||||
|  | @ -302,7 +302,9 @@ def decode_windows(c, title, hwnd): | ||||||
|     return info |     return info | ||||||
| 
 | 
 | ||||||
| def win_enum_handler(hwnd, titles): | def win_enum_handler(hwnd, titles): | ||||||
|     titles[hwnd] = win32gui.GetWindowText(hwnd) |     str = win32gui.GetWindowText(hwnd) | ||||||
|  |     if str != "": | ||||||
|  |         titles[hwnd] = win32gui.GetWindowText(hwnd) | ||||||
|    |    | ||||||
| ################################################################### | ################################################################### | ||||||
| #    Utility routines used by all the discoverers. | #    Utility routines used by all the discoverers. | ||||||
|  |  | ||||||
|  | @ -531,7 +531,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") | ||||||
|     def tab_table_viewer(self, widget, data=None): |     def tab_table_viewer(self, widget, data=None): | ||||||
|         """opens a table viewer tab""" |         """opens a table viewer tab""" | ||||||
|         #print "start of tab_table_viewer" |         #print "start of tab_table_viewer" | ||||||
|         new_tv_thread=GuiTableViewer.GuiTableViewer(self.db.fdb, self.settings) |         new_tv_thread = GuiTableViewer.GuiTableViewer(self.db, self.settings, self.config) | ||||||
|         self.threads.append(new_tv_thread) |         self.threads.append(new_tv_thread) | ||||||
|         tv_tab=new_tv_thread.get_vbox() |         tv_tab=new_tv_thread.get_vbox() | ||||||
|         self.add_and_display_tab(tv_tab, "Table Viewer") |         self.add_and_display_tab(tv_tab, "Table Viewer") | ||||||
|  |  | ||||||
|  | @ -64,7 +64,7 @@ class fpdb_db: | ||||||
|         if backend==fpdb_db.MYSQL_INNODB: |         if backend==fpdb_db.MYSQL_INNODB: | ||||||
|             import MySQLdb |             import MySQLdb | ||||||
|             try: |             try: | ||||||
|                 self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True, charset="utf8") |                 self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True) | ||||||
|             except: |             except: | ||||||
|                 raise fpdb_simple.FpdbError("MySQL connection failed") |                 raise fpdb_simple.FpdbError("MySQL connection failed") | ||||||
|         elif backend==fpdb_db.PGSQL: |         elif backend==fpdb_db.PGSQL: | ||||||
|  | @ -155,105 +155,4 @@ class fpdb_db: | ||||||
|         return (self.host, self.database, self.user, self.password) |         return (self.host, self.database, self.user, self.password) | ||||||
|     #end def get_db_info |     #end def get_db_info | ||||||
| 
 | 
 | ||||||
|     def getLastInsertId(self, cursor=None): |  | ||||||
|         try: |  | ||||||
|             if self.backend == self.MYSQL_INNODB: |  | ||||||
|                 ret = self.db.insert_id() |  | ||||||
|                 if ret < 1 or ret > 999999999: |  | ||||||
|                     print "getLastInsertId(): problem fetching insert_id? ret=", ret |  | ||||||
|                     ret = -1 |  | ||||||
|             elif self.backend == self.PGSQL: |  | ||||||
|                 # some options: |  | ||||||
|                 # currval(hands_id_seq) - use name of implicit seq here |  | ||||||
|                 # lastval() - still needs sequences set up? |  | ||||||
|                 # insert ... returning  is useful syntax (but postgres specific?) |  | ||||||
|                 # see rules (fancy trigger type things) |  | ||||||
|                 c = self.db.cursor() |  | ||||||
|                 ret = c.execute ("SELECT lastval()") |  | ||||||
|                 row = c.fetchone() |  | ||||||
|                 if not row: |  | ||||||
|                     print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row |  | ||||||
|                     ret = -1 |  | ||||||
|                 else: |  | ||||||
|                     ret = row[0] |  | ||||||
|             elif self.backend == fpdb_db.SQLITE: |  | ||||||
|                 ret = cursor.lastrowid |  | ||||||
|             else: |  | ||||||
|                 print "getLastInsertId(): unknown backend ", self.backend |  | ||||||
|                 ret = -1 |  | ||||||
|         except: |  | ||||||
|             ret = -1 |  | ||||||
|             print "getLastInsertId error:", str(sys.exc_value), " ret =", ret |  | ||||||
|             raise fpdb_simple.FpdbError( "getLastInsertId error: " + str(sys.exc_value) ) |  | ||||||
| 
 |  | ||||||
|         return ret |  | ||||||
| 
 |  | ||||||
|     def storeHand(self, p): |  | ||||||
|         #stores into table hands: |  | ||||||
|         self.cursor.execute ("""INSERT INTO Hands (  |  | ||||||
|             tablename,  |  | ||||||
|             sitehandno, |  | ||||||
|             gametypeid,  |  | ||||||
|             handstart,  |  | ||||||
|             importtime, |  | ||||||
|             seats,  |  | ||||||
|             maxseats, |  | ||||||
|             boardcard1,  |  | ||||||
|             boardcard2,  |  | ||||||
|             boardcard3,  |  | ||||||
|             boardcard4,  |  | ||||||
|             boardcard5, |  | ||||||
| --            texture, |  | ||||||
|             playersVpi, |  | ||||||
|             playersAtStreet1,  |  | ||||||
|             playersAtStreet2, |  | ||||||
|             playersAtStreet3,  |  | ||||||
|             playersAtStreet4,  |  | ||||||
|             playersAtShowdown, |  | ||||||
|             street0Raises, |  | ||||||
|             street1Raises, |  | ||||||
|             street2Raises, |  | ||||||
|             street3Raises, |  | ||||||
|             street4Raises, |  | ||||||
| --            street1Pot, |  | ||||||
| --            street2Pot, |  | ||||||
| --            street3Pot, |  | ||||||
| --            street4Pot, |  | ||||||
| --            showdownPot |  | ||||||
|              )  |  | ||||||
|              VALUES  |  | ||||||
|               (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, |  | ||||||
|             %s, %s, %s, %s, %s, %s, %s)""", |  | ||||||
|             ( |  | ||||||
|                 p['tablename'],  |  | ||||||
|                 p['sitehandno'],  |  | ||||||
|                 p['gametypeid'],  |  | ||||||
|                 p['handStart'],  |  | ||||||
|                 datetime.datetime.today(),  |  | ||||||
|                 len(p['names']), |  | ||||||
|                 p['maxSeats'], |  | ||||||
|                 p['boardcard1'],  |  | ||||||
|                 p['boardcard2'],  |  | ||||||
|                 p['boardcard3'],  |  | ||||||
|                 p['boardcard4'],  |  | ||||||
|                 p['boardcard5'], |  | ||||||
|                 hudCache['playersVpi'],  |  | ||||||
|                 hudCache['playersAtStreet1'],  |  | ||||||
|                 hudCache['playersAtStreet2'], |  | ||||||
|                 hudCache['playersAtStreet3'],  |  | ||||||
|                 hudCache['playersAtStreet4'],  |  | ||||||
|                 hudCache['playersAtShowdown'], |  | ||||||
|                 hudCache['street0Raises'],  |  | ||||||
|                 hudCache['street1Raises'],  |  | ||||||
|                 hudCache['street2Raises'], |  | ||||||
|                 hudCache['street3Raises'],  |  | ||||||
|                 hudCache['street4Raises'],  |  | ||||||
|                 hudCache['street1Pot'], |  | ||||||
|                 hudCache['street2Pot'],  |  | ||||||
|                 hudCache['street3Pot'], |  | ||||||
|                 hudCache['street4Pot'], |  | ||||||
|                 hudCache['showdownPot'] |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|         #return getLastInsertId(backend, conn, cursor) |  | ||||||
| #end class fpdb_db | #end class fpdb_db | ||||||
|  |  | ||||||
|  | @ -85,6 +85,8 @@ class Importer: | ||||||
|         #self.settings.setdefault("forceThreads", 2)            # NOT USED NOW |         #self.settings.setdefault("forceThreads", 2)            # NOT USED NOW | ||||||
|         self.settings.setdefault("writeQSize", 1000)           # no need to change |         self.settings.setdefault("writeQSize", 1000)           # no need to change | ||||||
|         self.settings.setdefault("writeQMaxWait", 10)          # not used |         self.settings.setdefault("writeQMaxWait", 10)          # not used | ||||||
|  |         self.settings.setdefault("dropIndexes", "don't drop") | ||||||
|  |         self.settings.setdefault("dropHudCache", "don't drop") | ||||||
| 
 | 
 | ||||||
|         self.writeq = None |         self.writeq = None | ||||||
|         self.database = Database.Database(self.config, sql = self.sql) |         self.database = Database.Database(self.config, sql = self.sql) | ||||||
|  | @ -130,6 +132,9 @@ class Importer: | ||||||
| #       self.updated = time() | #       self.updated = time() | ||||||
| 
 | 
 | ||||||
|     def clearFileList(self): |     def clearFileList(self): | ||||||
|  |         self.updatedsize = {} | ||||||
|  |         self.updatetime = {} | ||||||
|  |         self.pos_in_file = {} | ||||||
|         self.filelist = {} |         self.filelist = {} | ||||||
| 
 | 
 | ||||||
|     def closeDBs(self): |     def closeDBs(self): | ||||||
|  | @ -197,7 +202,7 @@ class Importer: | ||||||
|         print "Started at", start, "--", len(self.filelist), "files to import.", self.settings['dropIndexes'] |         print "Started at", start, "--", len(self.filelist), "files to import.", self.settings['dropIndexes'] | ||||||
|         if self.settings['dropIndexes'] == 'auto': |         if self.settings['dropIndexes'] == 'auto': | ||||||
|             self.settings['dropIndexes'] = self.calculate_auto2(self.database, 12.0, 500.0) |             self.settings['dropIndexes'] = self.calculate_auto2(self.database, 12.0, 500.0) | ||||||
|         if self.settings['dropHudCache'] == 'auto': |         if 'dropHudCache' in self.settings and self.settings['dropHudCache'] == 'auto': | ||||||
|             self.settings['dropHudCache'] = self.calculate_auto2(self.database, 25.0, 500.0)    # returns "drop"/"don't drop" |             self.settings['dropHudCache'] = self.calculate_auto2(self.database, 25.0, 500.0)    # returns "drop"/"don't drop" | ||||||
| 
 | 
 | ||||||
|         if self.settings['dropIndexes'] == 'drop': |         if self.settings['dropIndexes'] == 'drop': | ||||||
|  | @ -239,7 +244,7 @@ class Importer: | ||||||
|             self.database.afterBulkImport() |             self.database.afterBulkImport() | ||||||
|         else: |         else: | ||||||
|             print "No need to rebuild indexes." |             print "No need to rebuild indexes." | ||||||
|         if self.settings['dropHudCache'] == 'drop': |         if 'dropHudCache' in self.settings and self.settings['dropHudCache'] == 'drop': | ||||||
|             self.database.rebuild_hudcache() |             self.database.rebuild_hudcache() | ||||||
|         else: |         else: | ||||||
|             print "No need to rebuild hudcache." |             print "No need to rebuild hudcache." | ||||||
|  | @ -377,7 +382,7 @@ class Importer: | ||||||
| 
 | 
 | ||||||
|         # Load filter, process file, pass returned filename to import_fpdb_file |         # Load filter, process file, pass returned filename to import_fpdb_file | ||||||
|              |              | ||||||
|         if self.writeq != None: |         if self.settings['threads'] > 0 and self.writeq != None: | ||||||
|             print "\nConverting " + file + " (" + str(q.qsize()) + ")" |             print "\nConverting " + file + " (" + str(q.qsize()) + ")" | ||||||
|         else: |         else: | ||||||
|             print "\nConverting " + file |             print "\nConverting " + file | ||||||
|  |  | ||||||
|  | @ -79,7 +79,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non | ||||||
|         rebuyOrAddon    = -1 |         rebuyOrAddon    = -1 | ||||||
| 
 | 
 | ||||||
|         tourneyTypeId   = 1 |         tourneyTypeId   = 1 | ||||||
|     fpdb_simple.isAlreadyInDB(db.get_cursor(), gametypeID, siteHandNo) |     fpdb_simple.isAlreadyInDB(db, gametypeID, siteHandNo) | ||||||
|      |      | ||||||
|     hand = fpdb_simple.filterCrap(hand, isTourney) |     hand = fpdb_simple.filterCrap(hand, isTourney) | ||||||
|      |      | ||||||
|  | @ -93,7 +93,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non | ||||||
|             seatLines.append(line) |             seatLines.append(line) | ||||||
| 
 | 
 | ||||||
|     names       = fpdb_simple.parseNames(seatLines) |     names       = fpdb_simple.parseNames(seatLines) | ||||||
|     playerIDs   = fpdb_simple.recognisePlayerIDs(db.get_cursor(), names, siteID)  # inserts players as needed |     playerIDs   = fpdb_simple.recognisePlayerIDs(db, names, siteID)  # inserts players as needed | ||||||
|     tmp         = fpdb_simple.parseCashesAndSeatNos(seatLines) |     tmp         = fpdb_simple.parseCashesAndSeatNos(seatLines) | ||||||
|     startCashes = tmp['startCashes'] |     startCashes = tmp['startCashes'] | ||||||
|     seatNos     = tmp['seatNos'] |     seatNos     = tmp['seatNos'] | ||||||
|  | @ -141,7 +141,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non | ||||||
|         fpdb_simple.checkPositions(positions) |         fpdb_simple.checkPositions(positions) | ||||||
|          |          | ||||||
|     c = db.get_cursor() |     c = db.get_cursor() | ||||||
|     c.execute("SELECT limitType FROM Gametypes WHERE id=%s",(gametypeID, )) |     c.execute("SELECT limitType FROM Gametypes WHERE id=%s" % (db.sql.query['placeholder'],), (gametypeID, )) | ||||||
|     limit_type = c.fetchone()[0] |     limit_type = c.fetchone()[0] | ||||||
|     fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts) |     fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts) | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -403,10 +403,11 @@ def isActionLine(line): | ||||||
| #end def isActionLine | #end def isActionLine | ||||||
|   |   | ||||||
| #returns whether this is a duplicate | #returns whether this is a duplicate | ||||||
| def isAlreadyInDB(cursor, gametypeID, siteHandNo): | def isAlreadyInDB(db, gametypeID, siteHandNo): | ||||||
|     #print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo |     #print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo | ||||||
|     cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo)) |     c = db.get_cursor() | ||||||
|     result=cursor.fetchall() |     c.execute( db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo)) | ||||||
|  |     result = c.fetchall() | ||||||
|     if (len(result)>=1): |     if (len(result)>=1): | ||||||
|         raise DuplicateError ("dupl") |         raise DuplicateError ("dupl") | ||||||
| #end isAlreadyInDB | #end isAlreadyInDB | ||||||
|  | @ -901,9 +902,11 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c | ||||||
|      |      | ||||||
|     #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type |     #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type | ||||||
|     if (limit_type=="fl"): |     if (limit_type=="fl"): | ||||||
|         cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) |         cursor.execute ( db.sql.query['getGametypeFL'] | ||||||
|  |                        , (site_id, type, category, limit_type, small_bet, big_bet)) | ||||||
|     else: |     else: | ||||||
|         cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) |         cursor.execute ( db.sql.query['getGametypeNL'] | ||||||
|  |                        , (site_id, type, category, limit_type, small_bet, big_bet)) | ||||||
|     result=cursor.fetchone() |     result=cursor.fetchone() | ||||||
|     #print "recgt1 result=",result |     #print "recgt1 result=",result | ||||||
|     #ret=result[0] |     #ret=result[0] | ||||||
|  | @ -938,25 +941,16 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c | ||||||
|                     small_blind=float2int(smallBlindLine[pos:]) |                     small_blind=float2int(smallBlindLine[pos:]) | ||||||
|             else: |             else: | ||||||
|                 small_blind=0 |                 small_blind=0 | ||||||
|             cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType |             result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo | ||||||
|                                                     ,hiLo, smallBlind, bigBlind, smallBet, bigBet) |                                          ,small_blind, big_blind, small_bet, big_bet) ) | ||||||
|                                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" |  | ||||||
|                           , (site_id, type, base, category, limit_type, hiLo |  | ||||||
|                             ,small_blind, big_blind, small_bet, big_bet) ) |  | ||||||
|             #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s  |             #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s  | ||||||
|             #AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) |             #AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) | ||||||
|         else: |         else: | ||||||
|             cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType |             result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo | ||||||
|                                                     ,hiLo, smallBlind, bigBlind, smallBet, bigBet) |                                          ,small_bet, big_bet, 0, 0) )#remember, for these bet means blind | ||||||
|                                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" |  | ||||||
|                           , (site_id, type, base, category, limit_type |  | ||||||
|                             ,hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind |  | ||||||
|             #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s |             #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s | ||||||
|             #AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) |             #AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) | ||||||
|   |   | ||||||
|         #result=(db.insert_id(),) |  | ||||||
|         result=(db.get_last_insert_id(),) |  | ||||||
|      |  | ||||||
|     return result[0] |     return result[0] | ||||||
| #end def recogniseGametypeID | #end def recogniseGametypeID | ||||||
|   |   | ||||||
|  | @ -993,17 +987,21 @@ def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon): | ||||||
| #        result.append(tmp[0][0]) | #        result.append(tmp[0][0]) | ||||||
| #    return result | #    return result | ||||||
| 
 | 
 | ||||||
| def recognisePlayerIDs(cursor, names, site_id): | def recognisePlayerIDs(db, names, site_id): | ||||||
|     q = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in names]) |     c = db.get_cursor() | ||||||
|     cursor.execute(q, names) # get all playerids by the names passed in |     q = "SELECT name,id FROM Players WHERE siteid=%d and (name=%s)" %(site_id, " OR name=".join([db.sql.query['placeholder'] for n in names])) | ||||||
|     ids = dict(cursor.fetchall()) # convert to dict |     c.execute(q, names) # get all playerids by the names passed in | ||||||
|  |     ids = dict(c.fetchall()) # convert to dict | ||||||
|     if len(ids) != len(names): |     if len(ids) != len(names): | ||||||
|         notfound = [n for n in names if n not in ids] # make list of names not in database |         notfound = [n for n in names if n not in ids] # make list of names not in database | ||||||
|         if notfound: # insert them into database |         if notfound: # insert them into database | ||||||
|             cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", [(n,) for n in notfound]) |             q_ins = "INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")" | ||||||
|             q2 = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in notfound]) |             q_ins = q_ins.replace('%s', db.sql.query['placeholder']) | ||||||
|             cursor.execute(q2, notfound) # get their new ids |             c.executemany(q_ins, [(n,) for n in notfound]) | ||||||
|             tmp = cursor.fetchall() |             q2 = "SELECT name,id FROM Players WHERE siteid=%d and (name=%s)" % (site_id, " OR name=".join(["%s" for n in notfound])) | ||||||
|  |             q2 = q2.replace('%s', db.sql.query['placeholder']) | ||||||
|  |             c.execute(q2, notfound) # get their new ids | ||||||
|  |             tmp = c.fetchall() | ||||||
|             for n,id in tmp: # put them all into the same dict |             for n,id in tmp: # put them all into the same dict | ||||||
|                 ids[n] = id |                 ids[n] = id | ||||||
|     # return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB |     # return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user