diff --git a/pyfpdb/Card.py b/pyfpdb/Card.py index f126e1af..6ab9b62d 100755 --- a/pyfpdb/Card.py +++ b/pyfpdb/Card.py @@ -106,8 +106,23 @@ def valueSuitFromCard(card): , '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'Ts', 'Js', 'Qs', 'Ks', 'As' ][card] ) +def encodeCard(cardString): + """Take a card string (Ah) and convert it to the db card code (1).""" + try: + return {'2h': 1, '3h': 2, '4h': 3, '5h': 4, '6h': 5, '7h': 6, '8h': 7, '9h': 8, 'Th': 9, 'Jh': 10, 'Qh': 11, 'Kh': 12, 'Ah': 13, + '2d': 14, '3d': 15, '4d': 16, '5d': 17, '6d': 18, '7d': 19, '8d': 20, '9d': 21, 'Td': 22, 'Jd': 23, 'Qd': 24, 'Kd': 25, 'Ad': 26, + '2c': 27, '3c': 28, '4c': 29, '5c': 30, '6c': 31, '7c': 32, '8c': 33, '9c': 34, 'Tc': 35, 'Jc': 36, 'Qc': 27, 'Kc': 38, 'Ac': 39, + '2s': 40, '3s': 41, '4s': 42, '5s': 43, '6s': 44, '7s': 45, '8s': 46, '9s': 47, 'Ts': 48, 'Js': 49, 'Qs': 50, 'Ks': 51, 'As': 52, + ' ': 0 + }[cardString] + except: + return 0 # everthing that isn't known is a unknown! if __name__ == '__main__': + print "fpdb card encoding(same as pokersource)" for i in xrange(1, 14): print "card %2d = %s card %2d = %s card %2d = %s card %2d = %s" % \ (i, valueSuitFromCard(i), i+13, valueSuitFromCard(i+13), i+26, valueSuitFromCard(i+26), i+39, valueSuitFromCard(i+39)) + + print + print encodeCard('7c') \ No newline at end of file diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index e72c2882..11f9ef17 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -1684,6 +1684,7 @@ class HandToWrite: self.maxSeats = None self.tableName = None self.seatNos = None + self.payin_amounts = None # tourney import was complaining mightily about this missing except: print "htw.init error: " + str(sys.exc_info()) raise diff --git a/pyfpdb/EverleafToFpdb.py b/pyfpdb/EverleafToFpdb.py index a7685f90..9c63bcf0 100755 --- a/pyfpdb/EverleafToFpdb.py +++ b/pyfpdb/EverleafToFpdb.py @@ -44,7 +44,7 @@ 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" + #print "DEBUG: XXXXXXXXXXXXXXX" HandHistoryConverter.__init__(self, in_path, out_path, sitename="Everleaf", follow=follow, index=index) logging.info("Initialising Everleaf converter class") self.filetype = "text" diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 3b8026bf..a68c1cbd 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -140,6 +140,7 @@ follow : whether to tail -f the input""" if mg['TOURNO'] == None: info['type'] = "ring" else: info['type'] = "tour" # NB: SB, BB must be interpreted as blinds or bets depending on limit type. + if info['type'] == "tour": return None # importer is screwed on tournies, pass on those hands so we don't interrupt other autoimporting return info #Following function is a hack, we should be dealing with this in readFile (i think correct codepage....) @@ -176,6 +177,12 @@ follow : whether to tail -f the input""" hand.tourNo = m.group('TOURNO') if m.group('PLAY') != None: hand.gametype['currency'] = 'play' + + # TODO: if there's a way to figure these out, we should.. otherwise we have to stuff it with unknowns + if hand.buyin == None: + hand.buyin = "$0.00+$0.00" + if hand.level == None: + hand.level = "0" # These work, but the info is already in the Hand class - should be used for tourneys though. # m.group('SB') diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 4e7d4bdf..0dbb9674 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -56,6 +56,7 @@ class Hand(object): self.buttonpos = 0 self.tourNo = None self.buyin = None + self.fee = None # the Database code is looking for this one .. ? self.level = None self.mixed = None self.seating = [] @@ -564,7 +565,7 @@ Map the tuple self.gametype onto the pokerstars string describing it def writeGameLine(self): """Return the first HH line for the current hand.""" gs = "PokerStars Game #%s: " % self.handid - + if self.tourNo != None and self.mixed != None: # mixed tournament gs = gs + "Tournament #%s, %s %s (%s) - Level %s (%s) - " % (self.tourNo, self.buyin, self.MS[self.mixed], self.getGameTypeAsString(), self.level, self.getStakesAsString()) elif self.tourNo != None: # all other tournaments diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 888655bc..04b67c7a 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -235,12 +235,8 @@ class Hud: # does the user have a fav_seat? if int(config.supported_sites[self.table.site].layout[self.max].fav_seat) > 0: try: - sys.stderr.write("site = %s, max = %d, fav seat = %d\n" % (self.table.site, self.max, config.supported_sites[self.table.site].layout[self.max].fav_seat)) fav_seat = config.supported_sites[self.table.site].layout[self.max].fav_seat - sys.stderr.write("found fav seat = %d\n" % fav_seat) -# actual_seat = self.db_connection.get_actual_seat(hand, config.supported_sites[self.table.site].screen_name) actual_seat = self.get_actual_seat(config.supported_sites[self.table.site].screen_name) - sys.stderr.write("found actual seat = %d\n" % actual_seat) for i in xrange(0, self.max + 1): j = actual_seat + i if j > self.max: @@ -273,7 +269,6 @@ class Hud: self.cards = cards sys.stderr.write("------------------------------------------------------------\nCreating hud from hand %s\n" % hand) adj = self.adj_seats(hand, config) - sys.stderr.write("adj = %s\n" % adj) loc = self.config.get_locations(self.table.site, self.max) # create the stat windows @@ -282,7 +277,6 @@ class Hud: if i in self.stat_windows: self.stat_windows[i].relocate(x, y) else: - sys.stderr.write("actual seat = %d, x = %d, y= %d\n" % (i, x, y)) self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game], parent = self, table = self.table, diff --git a/pyfpdb/Mucked.py b/pyfpdb/Mucked.py index b3b134c5..3bd84cb7 100755 --- a/pyfpdb/Mucked.py +++ b/pyfpdb/Mucked.py @@ -294,6 +294,7 @@ class Stud_cards: def update_gui(self, new_hand_id): self.clear() for c, cards in self.parent.hud.cards.iteritems(): + if c == 'common': continue self.grid_contents[(1, c - 1)].set_text(self.get_screen_name(c)) for i in ((0, cards[0]), (1, cards[1]), (2, cards[2]), (3, cards[3]), (4, cards[4]), (5, cards[5]), (6, cards[6])): @@ -462,7 +463,6 @@ class Flop_Mucked(Aux_Seats): if n_cards > 0 and i != 'common': n_sd = n_sd + 1 if n_sd < 2: - print "skipping, n_sd =", n_sd return super(Flop_Mucked, self).update_gui(new_hand_id) diff --git a/pyfpdb/PokerStarsToFpdb.py b/pyfpdb/PokerStarsToFpdb.py index 61d4df4c..20ba4319 100755 --- a/pyfpdb/PokerStarsToFpdb.py +++ b/pyfpdb/PokerStarsToFpdb.py @@ -29,18 +29,31 @@ class PokerStars(HandHistoryConverter): ############################################################ # Class Variables + substitutions = { + 'LEGAL_ISO' : "USD|EUR|GBP|CAD", # legal ISO currency codes + 'LS' : "\$" # legal currency symbols + } + # Static regexes - re_GameInfo = re.compile("""PokerStars\sGame\s\#(?P[0-9]+):\s+ - (Tournament\s\#(?P\d+),\s(?P[\$\+\d\.]+)\s)? - (?PHORSE|8\-Game|HOSE)?\s?\(? - (?PHold\'em|Razz|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball)\s - (?PNo\sLimit|Limit|Pot\sLimit)\)?,?\s - (-\sLevel\s(?P[IVXLC]+)\s)?\(? - (?P\$|)? - (?P[.0-9]+)/\$? - (?P[.0-9]+)\)\s-\s - (?P.*$)""", - re.MULTILINE|re.VERBOSE) + re_GameInfo = re.compile(""" + PokerStars\sGame\s\#(?P[0-9]+):\s+ + (Tournament\s\# # open paren of tournament info + (?P\d+),\s + (?P[%(LS)s\+\d\.]+ # here's how I plan to use LS + \s?(?P%(LEGAL_ISO)s)? + )\s)? # close paren of tournament info + (?PHORSE|8\-Game|HOSE)?\s?\(? + (?PHold\'em|Razz|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball)\s + (?PNo\sLimit|Limit|Pot\sLimit)\)?,?\s + (-\sLevel\s(?P[IVXLC]+)\s)? + \(? # open paren of the stakes + (?P%(LS)s|)? + (?P[.0-9]+)/%(LS)s? + (?P[.0-9]+) + \s?(?P%(LEGAL_ISO)s)? + \)\s-\s # close paren of the stakes + (?P.*$)""" % substitutions, + re.MULTILINE|re.VERBOSE) re_SplitHands = re.compile('\n\n+') re_TailSplitHands = re.compile('(\n\n\n+)') re_HandInfo = re.compile("""^Table\s\'(?P[-\ a-zA-Z\d]+)\'\s @@ -270,19 +283,6 @@ follow : whether to tail -f the input""" for a in self.re_PostBoth.finditer(hand.handText): hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB')) -# def readHeroCards(self, hand): -# m = self.re_HeroCards.search(hand.handText) -# if(m == None): -# #Not involved in hand -# hand.involved = False -# else: -# hand.hero = m.group('PNAME') -# # "2c, qh" -> set(["2c","qc"]) -# # Also works with Omaha hands. -# cards = m.group('NEWCARDS') -# cards = set(cards.split(' ')) -# hand.addHoleCards(cards, m.group('PNAME'), shown=False, mucked=False, dealt=True) - def readHeroCards(self, hand): # streets PREFLOP, PREDRAW, and THIRD are special cases beacause # we need to grab hero's cards @@ -318,62 +318,6 @@ follow : whether to tail -f the input""" else: hand.addHoleCards(street, player, open=newcards, closed=oldcards, shown=False, mucked=False, dealt=False) - -# def readDrawCards(self, hand, street): -# logging.debug("readDrawCards") -# m = self.re_HeroCards.finditer(hand.streets[street]) -# if m == None: -# hand.involved = False -# else: -# for player in m: -# hand.hero = player.group('PNAME') # Only really need to do this once -# newcards = player.group('NEWCARDS') -# oldcards = player.group('OLDCARDS') -# if newcards == None: -# newcards = set() -# else: -# newcards = set(newcards.split(' ')) -# if oldcards == None: -# oldcards = set() -# else: -# oldcards = set(oldcards.split(' ')) -# hand.addDrawHoleCards(newcards, oldcards, player.group('PNAME'), street) - - -# def readStudPlayerCards(self, hand, street): -# # See comments of reference implementation in FullTiltToFpdb.py -# logging.debug("readStudPlayerCards") -# m = self.re_HeroCards.finditer(hand.streets[street]) -# for player in m: -# #~ logging.debug(player.groupdict()) -# (pname, oldcards, newcards) = (player.group('PNAME'), player.group('OLDCARDS'), player.group('NEWCARDS')) -# if oldcards: -# oldcards = [c.strip() for c in oldcards.split(' ')] -# if newcards: -# newcards = [c.strip() for c in newcards.split(' ')] -# if street=='ANTES': -# return -# elif street=='THIRD': -# # we'll have observed hero holecards in CARDS and thirdstreet open cards in 'NEWCARDS' -# # hero: [xx][o] -# # others: [o] -# hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = oldcards, open = newcards) -# elif street in ('FOURTH', 'FIFTH', 'SIXTH'): -# # 4th: -# # hero: [xxo] [o] -# # others: [o] [o] -# # 5th: -# # hero: [xxoo] [o] -# # others: [oo] [o] -# # 6th: -# # hero: [xxooo] [o] -# # others: [ooo] [o] -# hand.addPlayerCards(player = player.group('PNAME'), street = street, open = newcards) -# # we may additionally want to check the earlier streets tally with what we have but lets trust it for now. -# elif street=='SEVENTH' and newcards: -# # hero: [xxoooo] [x] -# # others: not reported. -# hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = newcards) def readAction(self, hand, street): m = self.re_Action.finditer(hand.streets[street]) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 8ad617f2..0555b33e 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -336,23 +336,15 @@ class Importer: if os.path.exists(file): stat_info = os.stat(file) #rulog.writelines("path exists ") - try: - lastupdate = self.updated[file] - #rulog.writelines("lastupdate = %d, mtime = %d" % (lastupdate,stat_info.st_mtime)) - if stat_info.st_mtime > lastupdate: + if file in self.updated: + if stat_info.st_size > self.updated[file]: self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1]) - self.updated[file] = time() - except: - self.updated[file] = time() - # If modified in the last minute run an immediate import. - # This codepath only runs first time the file is found. + self.updated[file] = stat_info.st_size + else: if os.path.isdir(file) or (time() - stat_info.st_mtime) < 60: - # TODO attach a HHC thread to the file - # TODO import the output of the HHC thread -- this needs to wait for the HHC to block? - self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None) - # TODO we also test if directory, why? - #if os.path.isdir(file): - #self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1]) + self.updated[file] = 0 + else: + self.updated[file] = stat_info.st_size else: self.removeFromFileList[file] = True self.addToDirList = filter(lambda x: self.addImportDirectory(x, True, self.addToDirList[x][0], self.addToDirList[x][1]), self.addToDirList) @@ -421,7 +413,7 @@ class Importer: last_read_hand = 0 loc = 0 (stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0) - #print "file =", file + # print "file =", file if file == "stdin": inputFile = sys.stdin else: diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py index de21439b..0314b83e 100644 --- a/pyfpdb/fpdb_parse_logic.py +++ b/pyfpdb/fpdb_parse_logic.py @@ -165,7 +165,12 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non except: print "parse: error during commit: " + str(sys.exc_value) - +# HERE's an ugly kludge to keep from failing when positions is undef +# We'll fix this by getting rid of the legacy importer. REB + try: + if positions: pass + except: + positions = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # save data structures in a HandToWrite instance and then insert into database: htw = Database.HandToWrite() htw.set_all( config, settings, base, category, siteTourneyNo, buyin