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 | ||||
|      | ||||
|     def get_frames(self, site = "PokerStars"): | ||||
|         if site not in self.supported_sites: return False | ||||
|         return self.supported_sites[site].use_frames == True | ||||
| 
 | ||||
|     def get_default_colors(self, site = "PokerStars"): | ||||
|         colors = {} | ||||
|         if self.supported_sites[site].hudopacity == "": | ||||
|         if site not in self.supported_sites or self.supported_sites[site].hudopacity == "": | ||||
|             colors['hudopacity'] = 0.90 | ||||
|         else: | ||||
|             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" | ||||
|         else: | ||||
|             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" | ||||
|         else: | ||||
|             colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor | ||||
|  | @ -604,6 +605,8 @@ class Config: | |||
|      | ||||
|     def get_default_font(self, site = 'PokerStars'): | ||||
|         (font, font_size) = ("Sans", "8") | ||||
|         if site not in self.supported_sites: | ||||
|             return ("Sans", "8") | ||||
|         if self.supported_sites[site].font == "": | ||||
|             font = "Sans" | ||||
|         else: | ||||
|  |  | |||
|  | @ -98,7 +98,7 @@ class Database: | |||
|     foreignKeys = [ | ||||
|                     [ ] # no db with index 0 | ||||
|                   , [ ] # 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':'HandsPlayers', 'fkcol':'handId',        'rtab':'Hands',         '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':'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':'HandsPlayers', 'fkcol':'handId',        'rtab':'Hands',         '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':'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) | ||||
|      | ||||
|     def get_backend_name(self): | ||||
|         """Reconnects the DB""" | ||||
|         return self.fdb.get_backend_name() | ||||
|          | ||||
|         """Returns the name of the currently used backend""" | ||||
|         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): | ||||
|         c = self.connection.cursor() | ||||
|  | @ -465,11 +473,39 @@ class Database: | |||
|         result = c.fetchall() | ||||
|         return result | ||||
| 
 | ||||
|     def get_last_insert_id(self): | ||||
|     def get_last_insert_id(self, cursor=None): | ||||
|         ret = None | ||||
|         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: | ||||
|             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 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -847,6 +883,7 @@ class Database: | |||
| 
 | ||||
|             self.commit() | ||||
|         except: | ||||
|             err = traceback.extract_tb(sys.exc_info()[2])[-1] | ||||
|             print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) | ||||
|             self.rollback() | ||||
|             raise | ||||
|  | @ -914,12 +951,17 @@ class Database: | |||
|     #end def dropAllIndexes | ||||
|      | ||||
|     def fillDefaultData(self): | ||||
|         c = self.get_cursor() | ||||
|         c = self.get_cursor()  | ||||
|         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 ('PokerStars', '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 ('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: | ||||
|             c.execute("INSERT INTO TourneyTypes VALUES (NULL, 1, 0, 0, 0, 0);") | ||||
|         else: | ||||
|  | @ -934,12 +976,14 @@ class Database: | |||
| 
 | ||||
|         try: | ||||
|             stime = time() | ||||
|             self.connection.cursor().execute(self.sql.query['clearHudCache']) | ||||
|             self.connection.cursor().execute(self.sql.query['rebuildHudCache']) | ||||
|             self.get_cursor().execute(self.sql.query['clearHudCache']) | ||||
|             self.get_cursor().execute(self.sql.query['rebuildHudCache']) | ||||
|             self.commit() | ||||
|             print "Rebuild hudcache took %.1f seconds" % (time() - stime,) | ||||
|         except: | ||||
|             err = traceback.extract_tb(sys.exc_info()[2])[-1] | ||||
|             print "Error rebuilding hudcache:", str(sys.exc_value) | ||||
|             print err | ||||
|     #end def rebuild_hudcache | ||||
| 
 | ||||
| 
 | ||||
|  | @ -996,15 +1040,26 @@ class Database: | |||
|     def insertPlayer(self, name, site_id): | ||||
|         result = None | ||||
|         c = self.get_cursor() | ||||
|         c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) | ||||
|         tmp=c.fetchall() | ||||
|         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] | ||||
|         q = "SELECT name, id FROM Players WHERE siteid=%s and name=%s" | ||||
|         q = q.replace('%s', self.sql.query['placeholder']) | ||||
| 
 | ||||
|         #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): | ||||
|         """Take a HandToWrite object and store it in the db""" | ||||
|  | @ -1064,6 +1119,76 @@ class Database: | |||
|         return result | ||||
|     #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 | ||||
|                   ,hand_start_time, names, tableName, maxSeats, hudCache | ||||
|                   ,board_values, board_suits): | ||||
|  | @ -1071,30 +1196,31 @@ class Database: | |||
|         cards = [Card.cardFromValueSuit(v,s) for v,s in zip(board_values,board_suits)] | ||||
|         #stores into table hands: | ||||
|         try: | ||||
|             self.get_cursor().execute ("""INSERT INTO Hands  | ||||
|                                           (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats | ||||
|                                           ,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5 | ||||
|                                           ,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, %s, %s, %s, %s, %s) | ||||
|                                        """ | ||||
|                                       ,   (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats | ||||
|                                           ,cards[0], cards[1], cards[2], cards[3], cards[4] | ||||
|                                           ,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'] | ||||
|                                           )) | ||||
|             ret = self.get_last_insert_id() | ||||
|             c = self.get_cursor() | ||||
|             c.execute ("""INSERT INTO Hands  | ||||
|                           (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats | ||||
|                           ,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5 | ||||
|                           ,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, %s, %s, %s, %s, %s) | ||||
|                        """.replace('%s', self.sql.query['placeholder']) | ||||
|                       ,   (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats | ||||
|                           ,cards[0], cards[1], cards[2], cards[3], cards[4] | ||||
|                           ,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'] | ||||
|                           )) | ||||
|             ret = self.get_last_insert_id(c) | ||||
|         except: | ||||
|             ret = -1 | ||||
|             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['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 | ||||
|         (handId, playerId, startCash, position, tourneyTypeId, | ||||
|          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, | ||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||||
|          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %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 ) | ||||
|             result.append( self.get_last_insert_id() ) | ||||
|                  | ||||
|             #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() ) | ||||
|             result.append( self.get_last_insert_id(c) ) # wrong? not used currently | ||||
|         except: | ||||
|             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]) | ||||
|                 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, | ||||
|         card1, card2, | ||||
|         card3, card4, | ||||
|         card5, card6, | ||||
|         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,  | ||||
|                 card1, card2, | ||||
|                 card3, card4, | ||||
|  | @ -1229,7 +1353,7 @@ class Database: | |||
|                 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])) | ||||
|                 #result.append(cursor.fetchall()[0][0]) | ||||
|                 result.append( self.get_last_insert_id() ) | ||||
|                 result.append( self.get_last_insert_id(c) ) | ||||
|         except: | ||||
|             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] | ||||
|                                 ) ) | ||||
| 
 | ||||
|             self.get_cursor().executemany (""" | ||||
|             c = self.get_cursor() | ||||
|             c.executemany (""" | ||||
|         INSERT INTO HandsPlayers | ||||
|         (handId, playerId, startCash, position, tourneyTypeId, | ||||
|          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)""".replace('%s', self.sql.query['placeholder']) | ||||
|                                           ,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])) | ||||
|             #result.append(cursor.fetchall()[0][0]) | ||||
|         except: | ||||
|  | @ -1335,14 +1460,15 @@ class Database: | |||
|         try: | ||||
|             result=[] | ||||
|             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, | ||||
|         card1Value, card1Suit, card2Value, card2Suit, | ||||
|         card3Value, card3Suit, card4Value, card4Suit, | ||||
|         card5Value, card5Suit, card6Value, card6Suit, | ||||
|         card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo) | ||||
|         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], | ||||
|                 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], | ||||
|  | @ -1350,7 +1476,7 @@ class Database: | |||
|                 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])) | ||||
|                 #result.append(cursor.fetchall()[0][0]) | ||||
|                 result.append( self.get_last_insert_id() ) | ||||
|                 result.append( self.get_last_insert_id(c) ) | ||||
|         except: | ||||
|             raise fpdb_simple.FpdbError( "store_hands_players_stud_tourney error: " + str(sys.exc_value) ) | ||||
|          | ||||
|  | @ -1488,24 +1614,28 @@ class Database: | |||
|     AND   position=%s  | ||||
|     AND   tourneyTypeId+0=%s | ||||
|     AND   styleKey=%s | ||||
|                           """, (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[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[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[1], row[2], row[3], str(row[4]), row[5], styleKey)) | ||||
|                                      """.replace('%s', self.sql.query['placeholder']) | ||||
|                                     ,(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[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[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[1], row[2], row[3], str(row[4]), row[5], styleKey)) | ||||
|                 # 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") | ||||
|                     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 | ||||
|                     cursor.execute("""INSERT INTO HudCache | ||||
|                     num = cursor.execute("""INSERT INTO HudCache | ||||
|     (gametypeId, playerId, activeSeats, position, tourneyTypeId, styleKey, | ||||
|     HDs, street0VPI, street0Aggr, street0_3BChance, street0_3BDone, | ||||
|     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)""".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[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[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[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" | ||||
|                 else: | ||||
|                     #print "updated(2) hud data line" | ||||
|  | @ -1552,7 +1682,8 @@ class Database: | |||
|     def store_tourneys(self, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime): | ||||
|         try: | ||||
|             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() | ||||
|             #print "tried SELECTing tourneys.id, result:",tmp | ||||
|              | ||||
|  | @ -1561,7 +1692,8 @@ class Database: | |||
|             except TypeError:#means we have to create new one | ||||
|                 cursor.execute("""INSERT INTO Tourneys | ||||
|         (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)) | ||||
|                 tmp=cursor.fetchone() | ||||
|                 #print "created new tourneys.id:",tmp | ||||
|  | @ -1581,7 +1713,8 @@ class Database: | |||
|             #print "ranks:",ranks | ||||
|             #print "winnings:",winnings | ||||
|             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() | ||||
|                 #print "tried SELECTing tourneys_players.id:",tmp | ||||
|                  | ||||
|  | @ -1589,10 +1722,10 @@ class Database: | |||
|                     len(tmp) | ||||
|                 except TypeError: | ||||
|                     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])) | ||||
|                      | ||||
|                     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])) | ||||
|                     tmp=cursor.fetchone() | ||||
|                     #print "created new tourneys_players.id:",tmp | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| 
 | ||||
| import threading | ||||
| import subprocess | ||||
| import traceback | ||||
| 
 | ||||
| import pygtk | ||||
| pygtk.require('2.0') | ||||
|  |  | |||
|  | @ -74,7 +74,10 @@ class GuiBulkImport(): | |||
|                 cb_hmodel = self.cb_drophudcache.get_model() | ||||
|                 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: | ||||
|                     self.importer.setDropIndexes(cb_model[cb_index][0]) | ||||
|                 else: | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import pygtk | |||
| pygtk.require('2.0') | ||||
| import gtk | ||||
| import os | ||||
| import traceback | ||||
| from time import * | ||||
| #import pokereval | ||||
| 
 | ||||
|  | @ -72,20 +73,19 @@ class GuiGraphViewer (threading.Thread): | |||
|         self.mainHBox.show() | ||||
| 
 | ||||
|         self.leftPanelBox = self.filters.get_vbox() | ||||
|         self.graphBox = gtk.VBox(False, 0) | ||||
|         self.graphBox.show() | ||||
| 
 | ||||
|         self.hpane = gtk.HPaned() | ||||
|         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.show() | ||||
| 
 | ||||
|         self.mainHBox.add(self.hpane) | ||||
| 
 | ||||
|         self.fig = None | ||||
|         #self.exportButton.set_sensitive(False) | ||||
| 
 | ||||
|         self.fig = Figure(figsize=(5,4), dpi=100) | ||||
|         self.canvas = None | ||||
| 
 | ||||
| 
 | ||||
|  | @ -125,79 +125,103 @@ class GuiGraphViewer (threading.Thread): | |||
|     #end def get_vbox | ||||
| 
 | ||||
|     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): | ||||
|         self.clearGraphData() | ||||
|         print "generateGraph: start" | ||||
|         try: | ||||
|             self.clearGraphData() | ||||
|             print "after cleardata" | ||||
| 
 | ||||
|         sitenos = [] | ||||
|         playerids = [] | ||||
|             sitenos = [] | ||||
|             playerids = [] | ||||
| 
 | ||||
|         sites   = self.filters.getSites() | ||||
|         heroes  = self.filters.getHeroes() | ||||
|         siteids = self.filters.getSiteIds() | ||||
|         limits  = self.filters.getLimits() | ||||
|         # Which sites are selected? | ||||
|         for site in sites: | ||||
|             if sites[site] == True: | ||||
|                 sitenos.append(siteids[site]) | ||||
|                 self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],)) | ||||
|                 result = self.db.cursor.fetchall() | ||||
|                 if len(result) == 1: | ||||
|                     playerids.append(result[0][0]) | ||||
|             sites   = self.filters.getSites() | ||||
|             heroes  = self.filters.getHeroes() | ||||
|             siteids = self.filters.getSiteIds() | ||||
|             limits  = self.filters.getLimits() | ||||
|             print "got filter data" | ||||
|             # Which sites are selected? | ||||
|             for site in sites: | ||||
|                 if sites[site] == True: | ||||
|                     sitenos.append(siteids[site]) | ||||
|                     self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],)) | ||||
|                     result = self.db.cursor.fetchall() | ||||
|                     if len(result) == 1: | ||||
|                         playerids.append(result[0][0]) | ||||
| 
 | ||||
|         if not sitenos: | ||||
|             #Should probably pop up here. | ||||
|             print "No sites selected - defaulting to PokerStars" | ||||
|             return | ||||
|             if not sitenos: | ||||
|                 #Should probably pop up here. | ||||
|                 print "No sites selected - defaulting to PokerStars" | ||||
|                 return | ||||
| 
 | ||||
|         if not playerids: | ||||
|             print "No player ids found" | ||||
|             return | ||||
|             if not playerids: | ||||
|                 print "No player ids found" | ||||
|                 return | ||||
| 
 | ||||
|         if not limits: | ||||
|             print "No limits found" | ||||
|             return | ||||
|             if not limits: | ||||
|                 print "No limits found" | ||||
|                 return | ||||
| 
 | ||||
|         #Set graph properties | ||||
|         self.ax = self.fig.add_subplot(111) | ||||
|             #Set graph properties | ||||
|             print "add_subplot" | ||||
|             self.ax = self.fig.add_subplot(111) | ||||
| 
 | ||||
|         #Get graph data from DB | ||||
|         starttime = time() | ||||
|         line = self.getRingProfitGraph(playerids, sitenos, limits) | ||||
|         print "Graph generated in: %s" %(time() - starttime) | ||||
|             #Get graph data from DB | ||||
|             starttime = time() | ||||
|             print "get line: playerids =", playerids, "sitenos =", sitenos, "limits =", limits | ||||
|             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 | ||||
|         self.ax.set_xlabel("Hands", fontsize = 12) | ||||
|         self.ax.set_ylabel("$", fontsize = 12) | ||||
|         self.ax.grid(color='g', linestyle=':', linewidth=0.2) | ||||
|         if line == None or line == []: | ||||
|             #Set axis labels and grid overlay properites | ||||
|             self.ax.set_xlabel("Hands", fontsize = 12) | ||||
|             self.ax.set_ylabel("$", fontsize = 12) | ||||
|             self.ax.grid(color='g', linestyle=':', linewidth=0.2) | ||||
|             if line == None or line == []: | ||||
| 
 | ||||
|             #TODO: Do something useful like alert user | ||||
|             print "No hands returned by graph query" | ||||
|         else: | ||||
| #            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)) | ||||
|                 #TODO: Do something useful like alert user | ||||
|                 print "No hands returned by graph query" | ||||
|             else: | ||||
|     #            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)) | ||||
| 
 | ||||
|             self.ax.annotate(text, | ||||
|                              xy=(10, -10), | ||||
|                              xycoords='axes points', | ||||
|                              horizontalalignment='left', verticalalignment='top', | ||||
|                              fontsize=10) | ||||
|                 self.ax.annotate(text, | ||||
|                                  xy=(10, -10), | ||||
|                                  xycoords='axes points', | ||||
|                                  horizontalalignment='left', verticalalignment='top', | ||||
|                                  fontsize=10) | ||||
| 
 | ||||
|             #Draw plot | ||||
|             self.ax.plot(line,) | ||||
|                 #Draw plot | ||||
|                 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 | ||||
| 
 | ||||
|     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 | ||||
|                        , ["plposition", False, "Posn",     1.0, "%s"]   # true not allowed for this line (set in code) | ||||
|                        , ["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"] | ||||
|                        , ["pfr",        True,  "PFR",      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.show() | ||||
|         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.stats_frame, expand=True, fill=True) | ||||
|  | @ -167,7 +167,9 @@ class GuiPlayerStats (threading.Thread): | |||
|         for site in sites: | ||||
|             if sites[site] == True: | ||||
|                 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() | ||||
|                 if len(result) == 1: | ||||
|                     playerids.append(result[0][0]) | ||||
|  |  | |||
|  | @ -22,280 +22,269 @@ import gtk | |||
| import os | ||||
| 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_db | ||||
| 
 | ||||
| 
 | ||||
| class GuiTableViewer (threading.Thread): | ||||
| 	def hudDivide (self, a, b): | ||||
| 		if b==0: | ||||
| 			return "n/a" | ||||
| 		else: | ||||
| 			return str(int((a/float(b))*100))+"%" | ||||
| 	#end def hudDivide | ||||
| 	 | ||||
| 	def browse_clicked(self, widget, data): | ||||
| 		"""runs when user clicks browse on tv tab""" | ||||
| 		#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()) | ||||
| 		 | ||||
| 		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 | ||||
|     def hudDivide (self, a, b): | ||||
|         if b==0: | ||||
|             return "n/a" | ||||
|         else: | ||||
|             return str(int((a/float(b))*100))+"%" | ||||
|     #end def hudDivide | ||||
|      | ||||
|     def browse_clicked(self, widget, data): | ||||
|         """runs when user clicks browse on tv tab""" | ||||
|         #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()) | ||||
|          | ||||
| 		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() | ||||
|         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 | ||||
|          | ||||
| 		#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__ | ||||
|         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.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> | ||||
| 	        </layout> | ||||
| 	    </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_games> | ||||
|  | @ -337,10 +427,13 @@ | |||
|         <hhc site="Full Tilt Poker" converter="FulltiltToFpdb"/> | ||||
|         <hhc site="Everleaf" converter="EverleafToFpdb"/> | ||||
|         <hhc site="Win2day" converter="Win2dayToFpdb"/> | ||||
|         <hhc site="Absolute" converter="AbsoluteToFpdb"/> | ||||
|         <hhc site="PartyPoker" converter="PartyPokerToFpdb"/> | ||||
|     </hhcs> | ||||
| 
 | ||||
|     <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> | ||||
| 
 | ||||
| </FreePokerToolsConfig> | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ import traceback | |||
| 
 | ||||
| if not options.errorsToConsole: | ||||
|     print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_." | ||||
|     errorFile = open('fpdb-error-log.txt', 'w', 0) | ||||
|     errorFile = open('HUD-error.txt', 'w', 0) | ||||
|     sys.stderr = errorFile | ||||
| 
 | ||||
| import thread | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ class Hand(object): | |||
|     LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'} | ||||
|     SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''} | ||||
|     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"): | ||||
|  | @ -185,31 +185,49 @@ db: a connected fpdb_db object""" | |||
|         # TODO: | ||||
|         # Players - base playerid and siteid tuple | ||||
|         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 | ||||
|         # 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 | ||||
|              #hh['siteHandNo'] =  self.handid | ||||
|              # gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), | ||||
|                 # | ||||
|              #hh['handStart'] = self.starttime | ||||
|              # seats TINYINT NOT NULL, | ||||
|                 # | ||||
|              #hh['tableName'] = self.tablenam | ||||
|              #hh['maxSeats'] = self.maxseats | ||||
|         #This should be moved to prepInsert | ||||
|         hh = {} | ||||
|         hh['siteHandNo'] =  self.handid | ||||
|         hh['handStart'] = self.starttime | ||||
|         # seats TINYINT NOT NULL, | ||||
|         hh['tableName'] = self.tablename | ||||
|         hh['maxSeats'] = self.maxseats | ||||
|              # boardcard1 smallint,  /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */ | ||||
|              # boardcard2 smallint, | ||||
|              # boardcard3 smallint, | ||||
|              # boardcard4 smallint, | ||||
|              # boardcard5 smallint, | ||||
|                  # 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'] | ||||
|                  # cards = [Card.cardFromValueSuit(v,s) for v,s in boardcards[0:4]] | ||||
|                  # hh['boardcard1'] = cards[0] | ||||
|                  # hh['boardcard2'] = cards[1] | ||||
|                  # hh['boardcard3'] = cards[2] | ||||
|                  # hh['boardcard4'] = cards[3] | ||||
|                  # hh['boardcard5'] = cards[4] | ||||
|         # Flop turn and river may all be empty - add (likely) too many elements and trim with range | ||||
|         boardcards = self.board['FLOP'] + self.board['TURN'] + self.board['RIVER'] + [u'0x', u'0x', u'0x', u'0x', u'0x'] | ||||
|         cards = [Card.encodeCard(c) for c in boardcards[0:5]] | ||||
|         hh['boardcard1'] = cards[0] | ||||
|         hh['boardcard2'] = cards[1] | ||||
|         hh['boardcard3'] = cards[2] | ||||
|         hh['boardcard4'] = cards[3] | ||||
|         hh['boardcard5'] = cards[4] | ||||
| 
 | ||||
|         print hh | ||||
|              # texture smallint, | ||||
|              # playersVpi SMALLINT NOT NULL,         /* num of players vpi */ | ||||
|                 # Needs to be recorded | ||||
|  | @ -244,7 +262,7 @@ db: a connected fpdb_db object""" | |||
|              # showdownPot INT,                 /* pot size at sd/street7 */ | ||||
|              # comment TEXT, | ||||
|              # commentTs DATETIME | ||||
|         # handid = db.storeHand(hh) | ||||
|         handid = db.storeHand(hh) | ||||
|         # HandsPlayers - ? ... Do we fix winnings? | ||||
|         # Tourneys ? | ||||
|         # TourneysPlayers | ||||
|  | @ -453,6 +471,7 @@ Add a raise on [street] by [player] to [amountTo] | |||
| 
 | ||||
|     def addCheck(self, street, player): | ||||
|         #print "DEBUG: %s %s checked" % (street, player) | ||||
|         logging.debug("%s %s checks" % (street, player)) | ||||
|         self.checkPlayerExists(player) | ||||
|         self.actions[street].append((player, 'checks')) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #!/usr/bin/python | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| #Copyright 2008 Carl Gherardi | ||||
| #This program is free software: you can redistribute it and/or modify | ||||
|  | @ -58,10 +59,10 @@ class HandHistoryConverter(): | |||
|         else: | ||||
|             # TODO: out_path should be sanity checked. | ||||
|             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) | ||||
|                 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.follow = follow | ||||
|  | @ -95,9 +96,14 @@ Otherwise, finish at eof. | |||
|         else: | ||||
|             handsList = self.allHandsAsList() | ||||
|             logging.info("Parsing %d hands" % len(handsList)) | ||||
|             nBadHangs = 0 | ||||
|             for handText in handsList: | ||||
|                 self.processedHands.append(self.processHand(handText)) | ||||
|             numHands=  len(handsList) | ||||
|                 try: | ||||
|                     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() | ||||
|         print "read %d hands in %.3f seconds" % (numHands, endtime - starttime) | ||||
|         if self.out_fh != sys.stdout: | ||||
|  |  | |||
|  | @ -60,6 +60,8 @@ class Hud: | |||
|     def __init__(self, parent, table, max, poker_game, config, db_connection): | ||||
| #    __init__ is (now) intended to be called from the stdin thread, so it | ||||
| #    cannot touch the gui | ||||
|         if parent == None: # running from cli .. | ||||
|             self.parent = self | ||||
|         self.parent        = parent | ||||
|         self.table         = table | ||||
|         self.config        = config | ||||
|  | @ -125,7 +127,8 @@ class Hud: | |||
|         self.menu = gtk.Menu() | ||||
|         self.item1 = gtk.MenuItem('Kill this HUD') | ||||
|         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.item2 = gtk.MenuItem('Save Layout') | ||||
|  | @ -233,7 +236,7 @@ class Hud: | |||
| #        Need range here, not xrange -> need the actual list         | ||||
|         adj = range(0, self.max + 1) # default seat adjustments = no adjustment | ||||
| #    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: | ||||
|                 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) | ||||
|  | @ -600,15 +603,17 @@ if __name__== "__main__": | |||
|      | ||||
|     c = Configuration.Config() | ||||
|     #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: | ||||
|         print "Table not found." | ||||
|     db = Database.Database(c, 'fpdb', 'holdem') | ||||
|      | ||||
|     stat_dict = db.get_stats_from_hand(1) | ||||
| 
 | ||||
| #    for t in tables: | ||||
|     win = Hud(t, 10, 'holdem', c, db) | ||||
|     win.create(1, c) | ||||
|     win = Hud(None, t, 10, 'holdem', c, db) # parent, table, max, poker_game, config, db_connection | ||||
|     win.create(1, c, stat_dict, None) # hand, config, stat_dict, cards): | ||||
| #        t.get_details() | ||||
|     win.update(8300, db, c) | ||||
|     win.update(8300, c) # self, hand, config): | ||||
| 
 | ||||
|     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 | ||||
|     sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\x80", "GBP": "\xa3"}         # ADD Euro, Sterling, etc HERE | ||||
|     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 | ||||
|                     } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										500
									
								
								pyfpdb/SQL.py
									
									
									
									
									
								
							
							
						
						
									
										500
									
								
								pyfpdb/SQL.py
									
									
									
									
									
								
							|  | @ -1,9 +1,7 @@ | |||
| #!/usr/bin/env python | ||||
| """SQL.py | ||||
| 
 | ||||
| Set up all of the SQL statements for a given game and database type. | ||||
| """Returns a dict of SQL statements used in fpdb. | ||||
| """ | ||||
| #    Copyright 2008, Ray E. Barker | ||||
| #    Copyright 2008-2009, Ray E. Barker | ||||
| #    | ||||
| #    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 | ||||
|  | @ -35,134 +33,8 @@ import re | |||
| 
 | ||||
| class Sql: | ||||
|     | ||||
|     def __init__(self, game = 'holdem', type = 'PT3', db_server = 'mysql'): | ||||
|     def __init__(self, game = 'holdem', type = 'fpdb', db_server = 'mysql'): | ||||
|         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 | ||||
| #    Support for the Free Poker DataBase = fpdb   http://fpdb.sourceforge.net/ | ||||
| # | ||||
|  | @ -410,16 +282,37 @@ class Sql: | |||
|             elif db_server == 'sqlite': | ||||
|                 self.query['createHandsTable'] = """CREATE TABLE Hands ( | ||||
|                                 id INTEGER PRIMARY KEY, | ||||
|                                 tableName TEXT(20), | ||||
|                                 siteHandNo INTEGER, | ||||
|                                 gametypeId INTEGER, | ||||
|                                 handStart REAL, | ||||
|                                 importTime REAL, | ||||
|                                 seats INTEGER, | ||||
|                                 maxSeats INTEGER, | ||||
|                                 tableName TEXT(20) NOT NULL, | ||||
|                                 siteHandNo INT NOT NULL, | ||||
|                                 gametypeId INT NOT NULL, | ||||
|                                 handStart REAL NOT NULL, | ||||
|                                 importTime REAL NOT NULL, | ||||
|                                 seats INT NOT NULL, | ||||
|                                 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, | ||||
|                                 commentTs REAL, | ||||
|                                 FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)""" | ||||
|                                 commentTs REAL)""" | ||||
| 
 | ||||
| 
 | ||||
|             ################################ | ||||
|  | @ -919,78 +812,78 @@ class Sql: | |||
|                             styleKey CHAR(7) NOT NULL,  /* 1st char is style (A/T/H/S), other 6 are the key */ | ||||
|                             HDs INT NOT NULL, | ||||
| 
 | ||||
|                             wonWhenSeenStreet1 FLOAT NOT NULL, | ||||
|                             wonWhenSeenStreet1 FLOAT, | ||||
|                             wonWhenSeenStreet2 FLOAT, | ||||
|                             wonWhenSeenStreet3 FLOAT, | ||||
|                             wonWhenSeenStreet4 FLOAT, | ||||
|                             wonAtSD FLOAT NOT NULL, | ||||
|                             wonAtSD FLOAT, | ||||
| 
 | ||||
|                             street0VPI INT NOT NULL, | ||||
|                             street0Aggr INT NOT NULL, | ||||
|                             street0_3BChance INT NOT NULL, | ||||
|                             street0_3BDone INT NOT NULL, | ||||
|                             street0VPI INT, | ||||
|                             street0Aggr INT, | ||||
|                             street0_3BChance INT, | ||||
|                             street0_3BDone INT, | ||||
|                             street0_4BChance INT, | ||||
|                             street0_4BDone INT, | ||||
|                             other3BStreet0 INT, | ||||
|                             other4BStreet0 INT, | ||||
| 
 | ||||
|                             street1Seen INT NOT NULL, | ||||
|                             street2Seen INT NOT NULL, | ||||
|                             street3Seen INT NOT NULL, | ||||
|                             street4Seen INT NOT NULL, | ||||
|                             sawShowdown INT NOT NULL, | ||||
|                             street1Seen INT, | ||||
|                             street2Seen INT, | ||||
|                             street3Seen INT, | ||||
|                             street4Seen INT, | ||||
|                             sawShowdown INT, | ||||
|                              | ||||
|                             street1Aggr INT NOT NULL, | ||||
|                             street2Aggr INT NOT NULL, | ||||
|                             street3Aggr INT NOT NULL, | ||||
|                             street4Aggr INT NOT NULL, | ||||
|                             street1Aggr INT, | ||||
|                             street2Aggr INT, | ||||
|                             street3Aggr INT, | ||||
|                             street4Aggr INT, | ||||
| 
 | ||||
|                             otherRaisedStreet0 INT, | ||||
|                             otherRaisedStreet1 INT NOT NULL, | ||||
|                             otherRaisedStreet2 INT NOT NULL, | ||||
|                             otherRaisedStreet3 INT NOT NULL, | ||||
|                             otherRaisedStreet4 INT NOT NULL, | ||||
|                             otherRaisedStreet1 INT, | ||||
|                             otherRaisedStreet2 INT, | ||||
|                             otherRaisedStreet3 INT, | ||||
|                             otherRaisedStreet4 INT, | ||||
|                             foldToOtherRaisedStreet0 INT, | ||||
|                             foldToOtherRaisedStreet1 INT NOT NULL, | ||||
|                             foldToOtherRaisedStreet2 INT NOT NULL, | ||||
|                             foldToOtherRaisedStreet3 INT NOT NULL, | ||||
|                             foldToOtherRaisedStreet4 INT NOT NULL, | ||||
|                             foldToOtherRaisedStreet1 INT, | ||||
|                             foldToOtherRaisedStreet2 INT, | ||||
|                             foldToOtherRaisedStreet3 INT, | ||||
|                             foldToOtherRaisedStreet4 INT, | ||||
|                              | ||||
|                             stealAttemptChance INT NOT NULL, | ||||
|                             stealAttempted INT NOT NULL, | ||||
|                             foldBbToStealChance INT NOT NULL, | ||||
|                             foldedBbToSteal INT NOT NULL, | ||||
|                             foldSbToStealChance INT NOT NULL, | ||||
|                             foldedSbToSteal INT NOT NULL, | ||||
|                             stealAttemptChance INT, | ||||
|                             stealAttempted INT, | ||||
|                             foldBbToStealChance INT, | ||||
|                             foldedBbToSteal INT, | ||||
|                             foldSbToStealChance INT, | ||||
|                             foldedSbToSteal INT, | ||||
| 
 | ||||
|                             street1CBChance INT NOT NULL, | ||||
|                             street1CBDone INT NOT NULL, | ||||
|                             street2CBChance INT NOT NULL, | ||||
|                             street2CBDone INT NOT NULL, | ||||
|                             street3CBChance INT NOT NULL, | ||||
|                             street3CBDone INT NOT NULL, | ||||
|                             street4CBChance INT NOT NULL, | ||||
|                             street4CBDone INT NOT NULL, | ||||
|                             street1CBChance INT, | ||||
|                             street1CBDone INT, | ||||
|                             street2CBChance INT, | ||||
|                             street2CBDone INT, | ||||
|                             street3CBChance INT, | ||||
|                             street3CBDone INT, | ||||
|                             street4CBChance INT, | ||||
|                             street4CBDone INT, | ||||
|                              | ||||
|                             foldToStreet1CBChance INT NOT NULL, | ||||
|                             foldToStreet1CBDone INT NOT NULL, | ||||
|                             foldToStreet2CBChance INT NOT NULL, | ||||
|                             foldToStreet2CBDone INT NOT NULL, | ||||
|                             foldToStreet3CBChance INT NOT NULL, | ||||
|                             foldToStreet3CBDone INT NOT NULL, | ||||
|                             foldToStreet4CBChance INT NOT NULL, | ||||
|                             foldToStreet4CBDone INT NOT NULL, | ||||
|                             foldToStreet1CBChance INT, | ||||
|                             foldToStreet1CBDone INT, | ||||
|                             foldToStreet2CBChance INT, | ||||
|                             foldToStreet2CBDone INT, | ||||
|                             foldToStreet3CBChance INT, | ||||
|                             foldToStreet3CBDone INT, | ||||
|                             foldToStreet4CBChance INT, | ||||
|                             foldToStreet4CBDone INT, | ||||
|                              | ||||
|                             totalProfit INT NOT NULL, | ||||
|                             totalProfit INT, | ||||
|                              | ||||
|                             street1CheckCallRaiseChance INT NOT NULL, | ||||
|                             street1CheckCallRaiseDone INT NOT NULL, | ||||
|                             street2CheckCallRaiseChance INT NOT NULL, | ||||
|                             street2CheckCallRaiseDone INT NOT NULL, | ||||
|                             street3CheckCallRaiseChance INT NOT NULL, | ||||
|                             street3CheckCallRaiseDone INT NOT NULL, | ||||
|                             street4CheckCallRaiseChance INT NOT NULL, | ||||
|                             street4CheckCallRaiseDone INT NOT NULL, | ||||
|                             street1CheckCallRaiseChance INT, | ||||
|                             street1CheckCallRaiseDone INT, | ||||
|                             street2CheckCallRaiseChance INT, | ||||
|                             street2CheckCallRaiseDone INT, | ||||
|                             street3CheckCallRaiseChance INT, | ||||
|                             street3CheckCallRaiseDone INT, | ||||
|                             street4CheckCallRaiseChance INT, | ||||
|                             street4CheckCallRaiseDone INT, | ||||
| 
 | ||||
|                             street0Calls 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 */ | ||||
|                             HDs INT, | ||||
| 
 | ||||
|                             wonWhenSeenStreet1 FLOAT NOT NULL, | ||||
|                             wonWhenSeenStreet1 FLOAT, | ||||
|                             wonWhenSeenStreet2 FLOAT, | ||||
|                             wonWhenSeenStreet3 FLOAT, | ||||
|                             wonWhenSeenStreet4 FLOAT, | ||||
|                             wonAtSD FLOAT NOT NULL, | ||||
|                             wonAtSD FLOAT, | ||||
| 
 | ||||
|                             street0VPI INT NOT NULL, | ||||
|                             street0VPI INT, | ||||
|                             street0Aggr INT, | ||||
|                             street0_3BChance INT NOT NULL, | ||||
|                             street0_3BDone INT NOT NULL, | ||||
|                             street0_3BChance INT, | ||||
|                             street0_3BDone INT, | ||||
|                             street0_4BChance INT, | ||||
|                             street0_4BDone 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 */ | ||||
|                             HDs INT, | ||||
| 
 | ||||
|                             wonWhenSeenStreet1 REAL NOT NULL, | ||||
|                             wonWhenSeenStreet1 REAL, | ||||
|                             wonWhenSeenStreet2 REAL, | ||||
|                             wonWhenSeenStreet3 REAL, | ||||
|                             wonWhenSeenStreet4 REAL, | ||||
|                             wonAtSD REAL NOT NULL, | ||||
|                             wonAtSD REAL, | ||||
| 
 | ||||
|                             street0VPI INT NOT NULL, | ||||
|                             street0VPI INT, | ||||
|                             street0Aggr INT, | ||||
|                             street0_3BChance INT NOT NULL, | ||||
|                             street0_3BDone INT NOT NULL, | ||||
|                             street0_3BChance INT, | ||||
|                             street0_3BDone INT, | ||||
|                             street0_4BChance INT, | ||||
|                             street0_4BDone INT, | ||||
|                             other3BStreet0 INT, | ||||
|  | @ -1646,6 +1539,11 @@ class Sql: | |||
|                     select coalesce(max(id),0) | ||||
|                     from Hands | ||||
|                     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 ... | ||||
|             # 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 =  2 then 'MP' | ||||
|                                when stats.PlPosition =  5 then 'EP' | ||||
|                                else '??' | ||||
|                                else 'xx' | ||||
|                           end                                                          AS PlPosition | ||||
|                          ,stats.n | ||||
|                          ,stats.vpip | ||||
|  | @ -2218,7 +2116,7 @@ class Sql: | |||
|                                 when stats.PlPosition =  1 then 'CO' | ||||
|                                 when stats.PlPosition =  2 then 'MP' | ||||
|                                 when stats.PlPosition =  5 then 'EP' | ||||
|                                 else '??' | ||||
|                                 else 'xx' | ||||
|                            end                                                          AS PlPosition | ||||
|                           ,stats.n | ||||
|                           ,stats.vpip | ||||
|  | @ -2515,7 +2413,7 @@ class Sql: | |||
|                             ,hp.tourneyTypeId | ||||
|                             ,date_format(h.handStart, 'd%y%m%d') | ||||
| """ | ||||
|             else:   # assume postgres | ||||
|             elif db_server == 'postgresql': | ||||
|                 self.query['rebuildHudCache'] = """ | ||||
|                     INSERT INTO HudCache | ||||
|                     (gametypeId | ||||
|  | @ -2663,6 +2561,154 @@ class Sql: | |||
|                             ,hp.tourneyTypeId | ||||
|                             ,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': | ||||
|                 self.query['analyze'] = """ | ||||
|  | @ -2681,13 +2727,51 @@ class Sql: | |||
|             else:  # assume postgres | ||||
|                 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': | ||||
|                 for k,q in self.query.iteritems(): | ||||
|                     self.query[k] = re.sub('%s','?',q) | ||||
| 
 | ||||
| if __name__== "__main__": | ||||
| #    just print the default queries and exit | ||||
|     s = Sql(game = 'razz', type = 'ptracks') | ||||
|     s = Sql() | ||||
|     for key in s.query: | ||||
|         print "For query " + key + ", sql =" | ||||
|         print s.query[key] | ||||
|  |  | |||
|  | @ -234,7 +234,7 @@ def discover_nt_by_name(c, tablename): | |||
|         #print "Tables.py: tablename =", tablename, "title =", titles[hwnd] | ||||
|         try: | ||||
|             # this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html | ||||
|             if not tablename in titles[hwnd]: continue | ||||
|             if not tablename.lower() in titles[hwnd].lower(): continue | ||||
|         except: | ||||
|             continue | ||||
|         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 | ||||
| 
 | ||||
| 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. | ||||
|  |  | |||
|  | @ -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): | ||||
|         """opens a table viewer tab""" | ||||
|         #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) | ||||
|         tv_tab=new_tv_thread.get_vbox() | ||||
|         self.add_and_display_tab(tv_tab, "Table Viewer") | ||||
|  |  | |||
|  | @ -64,7 +64,7 @@ class fpdb_db: | |||
|         if backend==fpdb_db.MYSQL_INNODB: | ||||
|             import MySQLdb | ||||
|             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: | ||||
|                 raise fpdb_simple.FpdbError("MySQL connection failed") | ||||
|         elif backend==fpdb_db.PGSQL: | ||||
|  | @ -155,105 +155,4 @@ class fpdb_db: | |||
|         return (self.host, self.database, self.user, self.password) | ||||
|     #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 | ||||
|  |  | |||
|  | @ -85,6 +85,8 @@ class Importer: | |||
|         #self.settings.setdefault("forceThreads", 2)            # NOT USED NOW | ||||
|         self.settings.setdefault("writeQSize", 1000)           # no need to change | ||||
|         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.database = Database.Database(self.config, sql = self.sql) | ||||
|  | @ -130,6 +132,9 @@ class Importer: | |||
| #       self.updated = time() | ||||
| 
 | ||||
|     def clearFileList(self): | ||||
|         self.updatedsize = {} | ||||
|         self.updatetime = {} | ||||
|         self.pos_in_file = {} | ||||
|         self.filelist = {} | ||||
| 
 | ||||
|     def closeDBs(self): | ||||
|  | @ -197,7 +202,7 @@ class Importer: | |||
|         print "Started at", start, "--", len(self.filelist), "files to import.", self.settings['dropIndexes'] | ||||
|         if self.settings['dropIndexes'] == 'auto': | ||||
|             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" | ||||
| 
 | ||||
|         if self.settings['dropIndexes'] == 'drop': | ||||
|  | @ -239,7 +244,7 @@ class Importer: | |||
|             self.database.afterBulkImport() | ||||
|         else: | ||||
|             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() | ||||
|         else: | ||||
|             print "No need to rebuild hudcache." | ||||
|  | @ -377,7 +382,7 @@ class Importer: | |||
| 
 | ||||
|         # 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()) + ")" | ||||
|         else: | ||||
|             print "\nConverting " + file | ||||
|  |  | |||
|  | @ -79,7 +79,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non | |||
|         rebuyOrAddon    = -1 | ||||
| 
 | ||||
|         tourneyTypeId   = 1 | ||||
|     fpdb_simple.isAlreadyInDB(db.get_cursor(), gametypeID, siteHandNo) | ||||
|     fpdb_simple.isAlreadyInDB(db, gametypeID, siteHandNo) | ||||
|      | ||||
|     hand = fpdb_simple.filterCrap(hand, isTourney) | ||||
|      | ||||
|  | @ -93,7 +93,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non | |||
|             seatLines.append(line) | ||||
| 
 | ||||
|     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) | ||||
|     startCashes = tmp['startCashes'] | ||||
|     seatNos     = tmp['seatNos'] | ||||
|  | @ -141,7 +141,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non | |||
|         fpdb_simple.checkPositions(positions) | ||||
|          | ||||
|     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] | ||||
|     fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts) | ||||
|      | ||||
|  |  | |||
|  | @ -403,10 +403,11 @@ def isActionLine(line): | |||
| #end def isActionLine | ||||
|   | ||||
| #returns whether this is a duplicate | ||||
| def isAlreadyInDB(cursor, gametypeID, siteHandNo): | ||||
| def isAlreadyInDB(db, gametypeID, siteHandNo): | ||||
|     #print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo | ||||
|     cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo)) | ||||
|     result=cursor.fetchall() | ||||
|     c = db.get_cursor() | ||||
|     c.execute( db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo)) | ||||
|     result = c.fetchall() | ||||
|     if (len(result)>=1): | ||||
|         raise DuplicateError ("dupl") | ||||
| #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 | ||||
|     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: | ||||
|         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() | ||||
|     #print "recgt1 result=",result | ||||
|     #ret=result[0] | ||||
|  | @ -938,25 +941,16 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c | |||
|                     small_blind=float2int(smallBlindLine[pos:]) | ||||
|             else: | ||||
|                 small_blind=0 | ||||
|             cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType | ||||
|                                                     ,hiLo, smallBlind, bigBlind, smallBet, bigBet) | ||||
|                                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) ) | ||||
|             result = db.insertGameTypes( (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  | ||||
|             #AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) | ||||
|         else: | ||||
|             cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType | ||||
|                                                     ,hiLo, smallBlind, bigBlind, smallBet, bigBet) | ||||
|                                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 | ||||
|             result = db.insertGameTypes( (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 | ||||
|             #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] | ||||
| #end def recogniseGametypeID | ||||
|   | ||||
|  | @ -993,17 +987,21 @@ def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon): | |||
| #        result.append(tmp[0][0]) | ||||
| #    return result | ||||
| 
 | ||||
| def recognisePlayerIDs(cursor, names, site_id): | ||||
|     q = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in names]) | ||||
|     cursor.execute(q, names) # get all playerids by the names passed in | ||||
|     ids = dict(cursor.fetchall()) # convert to dict | ||||
| def recognisePlayerIDs(db, names, site_id): | ||||
|     c = db.get_cursor() | ||||
|     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])) | ||||
|     c.execute(q, names) # get all playerids by the names passed in | ||||
|     ids = dict(c.fetchall()) # convert to dict | ||||
|     if len(ids) != len(names): | ||||
|         notfound = [n for n in names if n not in ids] # make list of names not in database | ||||
|         if notfound: # insert them into database | ||||
|             cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", [(n,) for n in notfound]) | ||||
|             q2 = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in notfound]) | ||||
|             cursor.execute(q2, notfound) # get their new ids | ||||
|             tmp = cursor.fetchall() | ||||
|             q_ins = "INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")" | ||||
|             q_ins = q_ins.replace('%s', db.sql.query['placeholder']) | ||||
|             c.executemany(q_ins, [(n,) for n in notfound]) | ||||
|             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 | ||||
|                 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 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user