rendered paste body""" wopohaco.py 1. Place in directory with .xml draw hand history 2. Run 3. Observe converted .txt hand history 4. ??? 5. Profit!"""anon = 0 # 0: unanonymous # 1: anonymousimport os, xml.etree.ElementTree as ETround_tl = {'PRE_FIRST_DRAW':'Pre Draw', 'FIRST_DRAW':'First Draw', 'SECOND_DRAW':'Second Draw', 'THIRD_DRAW':'Third Draw', 'END_OF_FOLDED_GAME':'Final Pot', 'SHOWDOWN':'Final Pot'}event_tl = {'CHECK':'%s checks', 'FOLD':'%s folds', 'CALL':'%s calls %s', 'BET':'[color=red]%s bets %s[/color]', 'RAISE':'[color=red]%s raises to %s[/color]', 'MUCK':'%s mucks', 'SHOWN':'%s shows %s'}def draw_string(name, amt): if int(amt): return '[i]%s draws %s[/i]' % (name, amt) return '[i]%s stands pat[/i]' % namedef ff(s): # pretty betsizes if float(int(float(s))) == float(s): return '$%d' % int(float(s)) else: return '$%.2f' % float(s)position_tl = ([],[], ('SB/BTN', 'BB'), ('SB', 'BB', 'BTN'), ('SB', 'BB', 'CO', 'BTN'), ('SB', 'BB', 'UTG', 'CO', 'BTN'), ('SB', 'BB', 'UTG', 'MP', 'CO', 'BTN'), ('SB', 'BB', 'UTG', 'UTG+1', 'MP', 'CO', 'BTN'), ('SB', 'BB', 'UTG', 'UTG+1', 'MP1', 'MP2', 'CO', 'BTN'), ('SB', 'BB', 'UTG', 'UTG+1', 'UTG+2', 'MP1', 'MP2', 'CO', 'BTN'))no_print = ('BLINDS', 'POST_FIRST_DRAW', 'POST_SECOND_DRAW', 'POST_THIRD_DRAW', 'END_OF_GAME')# find hand historiesfns = []for dir, dirs, fl in os.walk('.'): for fn in fl: if fn[-4:] == '.xml': fns.append(fn)for fn in fns: donk = open(fn, 'r').read() # fix merge xml fuckup desc = donk.split('\n')[0] # <description> header donk = '<container>' + ''.join(donk.split('\n')[1:]) + '</container>' # wrap up <game>s header = ET.XML(desc) hh = ET.XML(donk) # let's write out = '' hand_count = 0 for game in hh: # a hand of internet pokers # some infos on the game is_bigbet = 1 if(header.get('stakes').find('Pot Limit') == -1 and header.get('stakes').find('No Limit') == -1): is_bigbet = 0 class Player: def __init__(self): self.id = '' self.pos = '' self.nick = '' self.name = '' self.balance = '' self.inv_hand = 0.0 self.inv_st = 0.0 self.dealt_in = 0 player = {} for p in game.find('players'): # get / set info on players pid = p.get('seat') player[pid] = Player() player[pid].id = pid player[pid].nick = p.get('nickname') # unanonymous player[pid].balance = p.get('balance') player[pid].dealt_in = p.get('dealtin') == 'true' player[pid].inv_hand = 0.0 # invested in hand sb_id = 0 for r in game.findall('round'): # find small blind if r.get('id') == 'BLINDS': sb_id = r[0].get('player') player[sb_id].pos = position_tl[len(player)][0] set_pos = 0 i = 0 for key in sorted(player.keys()): # set positions after SB (requires sorted dictionary) p = player[key] if p.id == sb_id: set_pos = 1 if set_pos and p.dealt_in: p.pos = position_tl[len(player)][i] i += 1 set_pos = 0 i = 0 for key in reversed(sorted(player.keys())): # set positions before SB p = player[key] if p.id == sb_id: set_pos = 1 if set_pos and p.dealt_in: p.pos = position_tl[len(player)][i] i -= 1 hero_exists = hero_id = 0 # find hero hero_seat = -1 for r in game.findall('round'): if hero_exists: continue for c in r.findall('cards'): if c.get('type') == 'HOLE': hero_exists = 1 hero_id = c.get('player') player_count = 0 for p in player.values(): if p.dealt_in: player_count += 1 out += 'Merge %s %s %s - %d players\n[url=http://forumserver.twoplustwo.com/21/draw-other-poker/official-draw-merge-thread-1033340/]Wombat Poker Hand Converter 0.2[/url]\n\n' % ( # print header ''.join(header.get('stakes').rpartition(' ')[-1:]), ''.join(header.get('stakes').rpartition(' ')[:-2]), header.get('type'), player_count) for key in sorted(player.keys()): # print players / set player names p = player[key] if anon: p.name = p.pos if p.id != hero_id else 'Hero' out += '%s: %s%s\n' % ( p.pos if p.id != hero_id else 'Hero (%s)' % p.pos, p.balance, '' if p.dealt_in else ' (sitting out)') else: p.name = p.nick if p.id != hero_id else 'Hero' out += '%s (%s): %s%s\n' % ( p.name, p.pos, p.balance, '' if p.dealt_in else ' (sitting out)') potsize = 0.0 # count pot imo for round in game.findall('round'): # a street or something for p in player.values(): # reset street specific stats p.inv_st = 0.0 shit_happened = 0 # useful flags try: # print pretty name title = round_tl[round.get('id')] if title == 'Pre Draw': # pre draw out += '\n[b]%s:[/b] (%s)\n' % (title, ff(potsize)) elif title.find('Draw') != -1: # other draw out += '\n[b]%s:[/b] (%s) [color=blue](%d players)[/color]\n' % (title, ff(potsize), player_count) else: # other (final pot i think) out += '\n[b]%s:[/b] %s\n' % (title, ff(potsize)) except: # or ugly if not no_print.__contains__(round.get('id')): # omit non printed streets out += '\n[b]%s:[/b]\n' % round.get('id') for event in round.findall('event'): # line 1: cards drawn try: if event.get('type') == 'DRAW': # print action out += draw_string(player[event.get('player')].name, event.get('text')) + ', ' shit_happened = 1 except: print 'missing player in game %s in %s' % (game.get('id'), fn) # stupid game out += '**FUCK**' if shit_happened: # delete last comma out = out[:-2] + '\n' shit_happened = 0 for event in round.findall('cards'): # line 2: cards dealt or shown def tptcards(s): # pretty cards tpts = {'s':':spade:', 'h':':heart:', 'd':':diamond:', 'c':':club:', 'X':':laugh:', 'x':'', ',':' '} for c in tpts.keys(): if(s.rpartition(c)[0:2] != ('', '')): return tptcards(s.rpartition(c)[0]) + tpts[c] + tptcards(s.rpartition(c)[2]) return s if event.get('type') == 'SHOWN': out += event_tl['SHOWN'] % (player[event.get('player')].name, tptcards(event.get('cards'))) + '\n' elif event.get('player') == hero_id: # pretty print hero cards out += 'Hand: %s\n' % tptcards(event.get('cards')) else: try: # ugly print other cards out += player[event.get('player')].name + ' ' + event.get('type') + ' ' + tptcards(event.get('cards')) + '\n' except: print 'probably community cards in game %s in %s' % (game.get('id'), fn) # stupid game for event in round.findall('event'): # line 3: all non draw actions if event.get('type') == 'SMALL_BLIND' or event.get('type') == 'BIG_BLIND': # blinds: don't print anything, just count pot amt = float(event.get('amount')) potsize += amt player[event.get('player')].inv_hand += amt continue try: if not event.get('type') == 'DRAW': # print action try: out += event_tl[event.get('type')] % (player[event.get('player')].name, ff(event.get('amount'))) + ', ' shit_happened = 1 except: try: out += event_tl[event.get('type')] % player[event.get('player')].name + ', ' shit_happened = 1 except: []#print 'WTF? %s %s in %s, %s' % (event.get('player'), event.get('type'), game.get('id'), fn) if event.get('type') == 'FOLD': # count players player_count -= 1 if event.get('amount'): # count pot / invested by player amt = float(event.get('amount')) if event.get('type') == 'RAISE': # merge logs raise by total, reduce it amt -= player[event.get('player')].inv_st player[event.get('player')].inv_st += amt player[event.get('player')].inv_hand += amt potsize += amt except: print 'missing player in game %s in %s' % (game.get('id'), fn) # stupid game out += '**FUCK**' if shit_happened: # delete last comma out = out[:-2] + '\n' for winner in round.findall('winner'): # winnar out += '%s wins %s%s\n' % (player[winner.get('player')].name, ff(winner.get('amount')), '' if not winner.get('hand') else ' (%s)' % winner.get('hand')) potsize -= float(winner.get('amount')) # end round out += '(Rake: %s)\n' % ff(potsize) out += '\n\n********\n\n\n' hand_count += 1 #end game print 'converted %d hands from table %s' % (hand_count, fn[:-4]) open(fn[:-4] + '.txt', 'w').write(out) # end filetry: input('\nsuccess, hopefully. press enter')except: []