Merge branch 'carl'
This commit is contained in:
commit
68f7ae1347
|
@ -243,33 +243,20 @@ class DerivedStats():
|
||||||
first betting round is 0
|
first betting round is 0
|
||||||
NOTE: HU, both values are negative for non-stud games
|
NOTE: HU, both values are negative for non-stud games
|
||||||
NOTE2: I've never seen a HU stud match"""
|
NOTE2: I've never seen a HU stud match"""
|
||||||
# The position calculation must be done differently for Stud and other games as
|
|
||||||
# Stud the 'blind' acts first - in all other games they act last.
|
|
||||||
#
|
|
||||||
#This function is going to get it wrong when there in situations where there
|
|
||||||
# is no small blind. I can live with that.
|
|
||||||
actions = hand.actions[hand.holeStreets[0]]
|
actions = hand.actions[hand.holeStreets[0]]
|
||||||
# Note: pfbao list may not include big blind if all others folded
|
# Note: pfbao list may not include big blind if all others folded
|
||||||
players = self.pfbao(actions)
|
players = self.pfbao(actions)
|
||||||
|
|
||||||
if hand.gametype['base'] == 'stud':
|
|
||||||
positions = [7, 6, 5, 4, 3, 2, 1, 0, 'S', 'B']
|
|
||||||
seats = len(players)
|
|
||||||
map = []
|
|
||||||
# Could posibly change this to be either -2 or -1 depending if they complete or bring-in
|
|
||||||
# First player to act is -1, last player is 0 for 6 players it should look like:
|
|
||||||
# ['S', 4, 3, 2, 1, 0]
|
|
||||||
map = positions[-seats-1:-1] # Copy required positions from postions array anding in -1
|
|
||||||
map = map[-1:] + map[0:-1] # and move the -1 to the start of that array
|
|
||||||
|
|
||||||
for i, player in enumerate(players):
|
|
||||||
#print "player %s in posn %s" % (player, str(map[i]))
|
|
||||||
self.handsplayers[player]['position'] = map[i]
|
|
||||||
else:
|
|
||||||
# set blinds first, then others from pfbao list, avoids problem if bb
|
# set blinds first, then others from pfbao list, avoids problem if bb
|
||||||
# is missing from pfbao list or if there is no small blind
|
# is missing from pfbao list or if there is no small blind
|
||||||
|
sb, bb, bi = False, False, False
|
||||||
|
if hand.gametype['base'] == 'stud':
|
||||||
|
# Stud position is determined after cards are dealt
|
||||||
|
bi = [x[0] for x in hand.actions[hand.actionStreets[1]] if x[1] == 'bringin']
|
||||||
|
else:
|
||||||
bb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[1] == 'big blind']
|
bb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[1] == 'big blind']
|
||||||
sb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[1] == 'small blind']
|
sb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[1] == 'small blind']
|
||||||
|
|
||||||
# if there are > 1 sb or bb only the first is used!
|
# if there are > 1 sb or bb only the first is used!
|
||||||
if bb:
|
if bb:
|
||||||
self.handsplayers[bb[0]]['position'] = 'B'
|
self.handsplayers[bb[0]]['position'] = 'B'
|
||||||
|
@ -277,8 +264,11 @@ class DerivedStats():
|
||||||
if sb:
|
if sb:
|
||||||
self.handsplayers[sb[0]]['position'] = 'S'
|
self.handsplayers[sb[0]]['position'] = 'S'
|
||||||
if sb[0] in players: players.remove(sb[0])
|
if sb[0] in players: players.remove(sb[0])
|
||||||
|
if bi:
|
||||||
|
self.handsplayers[bi[0]]['position'] = 'S'
|
||||||
|
if bi[0] in players: players.remove(bi[0])
|
||||||
|
|
||||||
#print "bb =", bb, "sb =", sb, "players =", players
|
#print "DEBUG: bb: '%s' sb: '%s' bi: '%s' plyrs: '%s'" %(bb, sb, bi, players)
|
||||||
for i,player in enumerate(reversed(players)):
|
for i,player in enumerate(reversed(players)):
|
||||||
self.handsplayers[player]['position'] = i
|
self.handsplayers[player]['position'] = i
|
||||||
|
|
||||||
|
@ -289,7 +279,7 @@ class DerivedStats():
|
||||||
def vpip(self, hand):
|
def vpip(self, hand):
|
||||||
vpipers = set()
|
vpipers = set()
|
||||||
for act in hand.actions[hand.actionStreets[1]]:
|
for act in hand.actions[hand.actionStreets[1]]:
|
||||||
if act[1] in ('calls','bets', 'raises'):
|
if act[1] in ('calls','bets', 'raises', 'completes'):
|
||||||
vpipers.add(act[0])
|
vpipers.add(act[0])
|
||||||
|
|
||||||
self.hands['playersVpi'] = len(vpipers)
|
self.hands['playersVpi'] = len(vpipers)
|
||||||
|
@ -387,9 +377,9 @@ class DerivedStats():
|
||||||
if steal_attempt and act != 'folds':
|
if steal_attempt and act != 'folds':
|
||||||
break
|
break
|
||||||
|
|
||||||
if not steal_attempt and not raised: # if posn in steal_positions and not steal_attempt:
|
if not steal_attempt and not raised and not act in ('bringin'):
|
||||||
self.handsplayers[pname]['raiseFirstInChance'] = True
|
self.handsplayers[pname]['raiseFirstInChance'] = True
|
||||||
if act in ('bets', 'raises'):
|
if act in ('bets', 'raises', 'completes'):
|
||||||
self.handsplayers[pname]['raisedFirstIn'] = True
|
self.handsplayers[pname]['raisedFirstIn'] = True
|
||||||
raised = True
|
raised = True
|
||||||
if posn in steal_positions:
|
if posn in steal_positions:
|
||||||
|
@ -397,7 +387,7 @@ class DerivedStats():
|
||||||
if act == 'calls':
|
if act == 'calls':
|
||||||
break
|
break
|
||||||
|
|
||||||
if posn not in steal_positions and act != 'folds':
|
if posn not in steal_positions and act not in ('folds', 'bringin'):
|
||||||
break
|
break
|
||||||
|
|
||||||
def calc34BetStreet0(self, hand):
|
def calc34BetStreet0(self, hand):
|
||||||
|
|
|
@ -73,3 +73,6 @@ class FpdbHandDuplicate(FpdbHandError):
|
||||||
|
|
||||||
class FpdbHandPartial(FpdbHandError):
|
class FpdbHandPartial(FpdbHandError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class FpdbEndOfFile(FpdbHandError):
|
||||||
|
pass
|
||||||
|
|
|
@ -1014,6 +1014,25 @@ class Filters(threading.Thread):
|
||||||
|
|
||||||
vb = gtk.VBox()
|
vb = gtk.VBox()
|
||||||
cal = gtk.Calendar()
|
cal = gtk.Calendar()
|
||||||
|
|
||||||
|
if entry == self.start_date:
|
||||||
|
cal_date = self.start_date.get_text()
|
||||||
|
if cal_date == '':
|
||||||
|
self.cursor.execute(self.sql.query['get_first_date'])
|
||||||
|
result = self.db.cursor.fetchall()
|
||||||
|
cal_date = result[0][0].split()[0]
|
||||||
|
self.start_date.set_text(cal_date)
|
||||||
|
elif entry == self.end_date:
|
||||||
|
cal_date = self.end_date.get_text()
|
||||||
|
if cal_date == '':
|
||||||
|
self.cursor.execute(self.sql.query['get_last_date'])
|
||||||
|
result = self.db.cursor.fetchall()
|
||||||
|
cal_date = result[0][0].split()[0]
|
||||||
|
self.end_date.set_text(cal_date)
|
||||||
|
|
||||||
|
(year,month,day)=cal_date.split('-')
|
||||||
|
cal.select_month(int(month)-1, int(year))
|
||||||
|
cal.select_day(int(day))
|
||||||
vb.pack_start(cal, expand=False, padding=0)
|
vb.pack_start(cal, expand=False, padding=0)
|
||||||
|
|
||||||
btn = gtk.Button(_('Done'))
|
btn = gtk.Button(_('Done'))
|
||||||
|
@ -1039,9 +1058,16 @@ class Filters(threading.Thread):
|
||||||
t2 = self.end_date.get_text()
|
t2 = self.end_date.get_text()
|
||||||
|
|
||||||
if t1 == '':
|
if t1 == '':
|
||||||
t1 = '1970-01-02'
|
self.cursor.execute(self.sql.query['get_first_date'])
|
||||||
|
result = self.db.cursor.fetchall()
|
||||||
|
t1 = result[0][0].split()[0]
|
||||||
|
self.start_date.set_text(t1)
|
||||||
|
|
||||||
if t2 == '':
|
if t2 == '':
|
||||||
t2 = '2020-12-12'
|
self.cursor.execute(self.sql.query['get_last_date'])
|
||||||
|
result = self.db.cursor.fetchall()
|
||||||
|
t2 = result[0][0].split()[0]
|
||||||
|
self.end_date.set_text(t2)
|
||||||
|
|
||||||
s1 = strptime(t1, "%Y-%m-%d") # make time_struct
|
s1 = strptime(t1, "%Y-%m-%d") # make time_struct
|
||||||
s2 = strptime(t2, "%Y-%m-%d")
|
s2 = strptime(t2, "%Y-%m-%d")
|
||||||
|
|
|
@ -85,9 +85,9 @@ class DemoTips(TreeViewTooltips):
|
||||||
def get_tooltip(self, view, column, path):
|
def get_tooltip(self, view, column, path):
|
||||||
model = view.get_model()
|
model = view.get_model()
|
||||||
cards = model[path][0]
|
cards = model[path][0]
|
||||||
|
|
||||||
title=column.get_title()
|
title=column.get_title()
|
||||||
display='<big>%s</big>\n<i>%s</i>' % (title,onlinehelp[title])
|
if (title == 'Hand' or title == 'Game'): display='' #no tooltips on headers
|
||||||
|
else: display='<big>%s for %s</big>\n<i>%s</i>' % (title,cards,onlinehelp[title])
|
||||||
return (display)
|
return (display)
|
||||||
|
|
||||||
def location(self, x, y, w, h):
|
def location(self, x, y, w, h):
|
||||||
|
|
|
@ -574,7 +574,6 @@ Left-Drag to Move"
|
||||||
<hhc site="PartyPoker" converter="PartyPokerToFpdb"/>
|
<hhc site="PartyPoker" converter="PartyPokerToFpdb"/>
|
||||||
<hhc site="Betfair" converter="BetfairToFpdb"/>
|
<hhc site="Betfair" converter="BetfairToFpdb"/>
|
||||||
<hhc site="OnGame" converter="OnGameToFpdb"/>
|
<hhc site="OnGame" converter="OnGameToFpdb"/>
|
||||||
<hhc site="Partouche" converter="PartoucheToFpdb"/>
|
|
||||||
<hhc site="Carbon" converter="CarbonToFpdb"/>
|
<hhc site="Carbon" converter="CarbonToFpdb"/>
|
||||||
<hhc site="PKR" converter="PkrToFpdb"/>
|
<hhc site="PKR" converter="PkrToFpdb"/>
|
||||||
<hhc site="iPoker" converter="iPokerToFpdb"/>
|
<hhc site="iPoker" converter="iPokerToFpdb"/>
|
||||||
|
|
|
@ -772,7 +772,6 @@ Left-Drag to Move"
|
||||||
<hhc site="Absolute" converter="AbsoluteToFpdb"/>
|
<hhc site="Absolute" converter="AbsoluteToFpdb"/>
|
||||||
<hhc site="PartyPoker" converter="PartyPokerToFpdb"/>
|
<hhc site="PartyPoker" converter="PartyPokerToFpdb"/>
|
||||||
<hhc site="Betfair" converter="BetfairToFpdb"/>
|
<hhc site="Betfair" converter="BetfairToFpdb"/>
|
||||||
<hhc site="Partouche" converter="PartoucheToFpdb"/>
|
|
||||||
<hhc site="Carbon" converter="CarbonToFpdb"/>
|
<hhc site="Carbon" converter="CarbonToFpdb"/>
|
||||||
<hhc site="OnGame" converter="OnGameToFpdb"/>
|
<hhc site="OnGame" converter="OnGameToFpdb"/>
|
||||||
<hhc site="PKR" converter="PkrToFpdb"/>
|
<hhc site="PKR" converter="PkrToFpdb"/>
|
||||||
|
|
276
pyfpdb/Hand.py
276
pyfpdb/Hand.py
|
@ -281,9 +281,143 @@ db: a connected Database object"""
|
||||||
|
|
||||||
def select(self, handId):
|
def select(self, handId):
|
||||||
""" Function to create Hand object from database """
|
""" Function to create Hand object from database """
|
||||||
|
c = cnxn.cursor()
|
||||||
|
|
||||||
|
# We need at least sitename, gametype, handid
|
||||||
|
# for the Hand.__init__
|
||||||
|
c.execute("""SELECT
|
||||||
|
s.name,
|
||||||
|
g.category,
|
||||||
|
g.base,
|
||||||
|
g.type,
|
||||||
|
g.limitType,
|
||||||
|
g.hilo,
|
||||||
|
round(g.smallBlind / 100.0,2),
|
||||||
|
round(g.bigBlind / 100.0,2),
|
||||||
|
round(g.smallBet / 100.0,2),
|
||||||
|
round(g.bigBet / 100.0,2),
|
||||||
|
s.currency,
|
||||||
|
h.boardcard1,
|
||||||
|
h.boardcard2,
|
||||||
|
h.boardcard3,
|
||||||
|
h.boardcard4,
|
||||||
|
h.boardcard5
|
||||||
|
FROM
|
||||||
|
hands as h,
|
||||||
|
sites as s,
|
||||||
|
gametypes as g,
|
||||||
|
handsplayers as hp,
|
||||||
|
players as p
|
||||||
|
WHERE
|
||||||
|
h.id = %(handid)s
|
||||||
|
and g.id = h.gametypeid
|
||||||
|
and hp.handid = h.id
|
||||||
|
and p.id = hp.playerid
|
||||||
|
and s.id = p.siteid
|
||||||
|
limit 1""", {'handid':handid})
|
||||||
|
#TODO: siteid should be in hands table - we took the scenic route through players here.
|
||||||
|
res = c.fetchone()
|
||||||
|
gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]}
|
||||||
|
c = Configuration.Config()
|
||||||
|
h = HoldemOmahaHand(config = c, hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
|
||||||
|
cards = map(Card.valueSuitFromCard, res[11:16] )
|
||||||
|
if cards[0]:
|
||||||
|
h.setCommunityCards('FLOP', cards[0:3])
|
||||||
|
if cards[3]:
|
||||||
|
h.setCommunityCards('TURN', [cards[3]])
|
||||||
|
if cards[4]:
|
||||||
|
h.setCommunityCards('RIVER', [cards[4]])
|
||||||
|
#[Card.valueSuitFromCard(x) for x in cards]
|
||||||
|
|
||||||
|
# HandInfo : HID, TABLE
|
||||||
|
# BUTTON - why is this treated specially in Hand?
|
||||||
|
# answer: it is written out in hand histories
|
||||||
|
# still, I think we should record all the active seat positions in a seat_order array
|
||||||
|
c.execute("""SELECT
|
||||||
|
h.sitehandno as hid,
|
||||||
|
h.tablename as table,
|
||||||
|
h.startTime as startTime
|
||||||
|
FROM
|
||||||
|
hands as h
|
||||||
|
WHERE h.id = %(handid)s
|
||||||
|
""", {'handid':handid})
|
||||||
|
res = c.fetchone()
|
||||||
|
h.handid = res[0]
|
||||||
|
h.tablename = res[1]
|
||||||
|
h.startTime = res[2] # automatically a datetime
|
||||||
|
|
||||||
|
# PlayerStacks
|
||||||
|
c.execute("""SELECT
|
||||||
|
hp.seatno,
|
||||||
|
round(hp.winnings / 100.0,2) as winnings,
|
||||||
|
p.name,
|
||||||
|
round(hp.startcash / 100.0,2) as chips,
|
||||||
|
hp.card1,hp.card2,
|
||||||
|
hp.position
|
||||||
|
FROM
|
||||||
|
handsplayers as hp,
|
||||||
|
players as p
|
||||||
|
WHERE
|
||||||
|
hp.handid = %(handid)s
|
||||||
|
and p.id = hp.playerid
|
||||||
|
""", {'handid':handid})
|
||||||
|
for (seat, winnings, name, chips, card1,card2, position) in c.fetchall():
|
||||||
|
h.addPlayer(seat,name,chips)
|
||||||
|
if card1 and card2:
|
||||||
|
h.addHoleCards(map(Card.valueSuitFromCard, (card1,card2)), name, dealt=True)
|
||||||
|
if winnings > 0:
|
||||||
|
h.addCollectPot(name, winnings)
|
||||||
|
if position == 'B':
|
||||||
|
h.buttonpos = seat
|
||||||
|
|
||||||
|
|
||||||
|
# actions
|
||||||
|
c.execute("""SELECT
|
||||||
|
(ha.street,ha.actionno) as actnum,
|
||||||
|
p.name,
|
||||||
|
ha.street,
|
||||||
|
ha.action,
|
||||||
|
ha.allin,
|
||||||
|
round(ha.amount / 100.0,2)
|
||||||
|
FROM
|
||||||
|
handsplayers as hp,
|
||||||
|
handsactions as ha,
|
||||||
|
players as p
|
||||||
|
WHERE
|
||||||
|
hp.handid = %(handid)s
|
||||||
|
and ha.handsplayerid = hp.id
|
||||||
|
and p.id = hp.playerid
|
||||||
|
ORDER BY
|
||||||
|
ha.street,ha.actionno
|
||||||
|
""", {'handid':handid})
|
||||||
|
res = c.fetchall()
|
||||||
|
for (actnum,player, streetnum, act, allin, amount) in res:
|
||||||
|
act=act.strip()
|
||||||
|
street = h.allStreets[streetnum+1]
|
||||||
|
if act==u'blind':
|
||||||
|
h.addBlind(player, 'big blind', amount)
|
||||||
|
# TODO: The type of blind is not recorded in the DB.
|
||||||
|
# TODO: preflop street name anomalies in Hand
|
||||||
|
elif act==u'fold':
|
||||||
|
h.addFold(street,player)
|
||||||
|
elif act==u'call':
|
||||||
|
h.addCall(street,player,amount)
|
||||||
|
elif act==u'bet':
|
||||||
|
h.addBet(street,player,amount)
|
||||||
|
elif act==u'check':
|
||||||
|
h.addCheck(street,player)
|
||||||
|
elif act==u'unbet':
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print act, player, streetnum, allin, amount
|
||||||
|
# TODO : other actions
|
||||||
|
|
||||||
|
#hhc.readShowdownActions(self)
|
||||||
|
#hc.readShownCards(self)
|
||||||
|
h.totalPot()
|
||||||
|
h.rake = h.totalpot - h.totalcollected
|
||||||
|
|
||||||
|
return h
|
||||||
|
|
||||||
def addPlayer(self, seat, name, chips):
|
def addPlayer(self, seat, name, chips):
|
||||||
"""\
|
"""\
|
||||||
|
@ -1540,146 +1674,4 @@ class Pot(object):
|
||||||
|
|
||||||
return ret + ''.join([ (" Side pot %s%.2f." % (self.sym, self.pots[x]) ) for x in xrange(1, len(self.pots)) ])
|
return ret + ''.join([ (" Side pot %s%.2f." % (self.sym, self.pots[x]) ) for x in xrange(1, len(self.pots)) ])
|
||||||
|
|
||||||
def assemble(cnxn, handid):
|
|
||||||
c = cnxn.cursor()
|
|
||||||
|
|
||||||
# We need at least sitename, gametype, handid
|
|
||||||
# for the Hand.__init__
|
|
||||||
c.execute("""
|
|
||||||
select
|
|
||||||
s.name,
|
|
||||||
g.category,
|
|
||||||
g.base,
|
|
||||||
g.type,
|
|
||||||
g.limitType,
|
|
||||||
g.hilo,
|
|
||||||
round(g.smallBlind / 100.0,2),
|
|
||||||
round(g.bigBlind / 100.0,2),
|
|
||||||
round(g.smallBet / 100.0,2),
|
|
||||||
round(g.bigBet / 100.0,2),
|
|
||||||
s.currency,
|
|
||||||
h.boardcard1,
|
|
||||||
h.boardcard2,
|
|
||||||
h.boardcard3,
|
|
||||||
h.boardcard4,
|
|
||||||
h.boardcard5
|
|
||||||
from
|
|
||||||
hands as h,
|
|
||||||
sites as s,
|
|
||||||
gametypes as g,
|
|
||||||
handsplayers as hp,
|
|
||||||
players as p
|
|
||||||
where
|
|
||||||
h.id = %(handid)s
|
|
||||||
and g.id = h.gametypeid
|
|
||||||
and hp.handid = h.id
|
|
||||||
and p.id = hp.playerid
|
|
||||||
and s.id = p.siteid
|
|
||||||
limit 1""", {'handid':handid})
|
|
||||||
#TODO: siteid should be in hands table - we took the scenic route through players here.
|
|
||||||
res = c.fetchone()
|
|
||||||
gametype = {'category':res[1],'base':res[2],'type':res[3],'limitType':res[4],'hilo':res[5],'sb':res[6],'bb':res[7], 'currency':res[10]}
|
|
||||||
c = Configuration.Config()
|
|
||||||
h = HoldemOmahaHand(config = c, hhc = None, sitename=res[0], gametype = gametype, handText=None, builtFrom = "DB", handid=handid)
|
|
||||||
cards = map(Card.valueSuitFromCard, res[11:16] )
|
|
||||||
if cards[0]:
|
|
||||||
h.setCommunityCards('FLOP', cards[0:3])
|
|
||||||
if cards[3]:
|
|
||||||
h.setCommunityCards('TURN', [cards[3]])
|
|
||||||
if cards[4]:
|
|
||||||
h.setCommunityCards('RIVER', [cards[4]])
|
|
||||||
#[Card.valueSuitFromCard(x) for x in cards]
|
|
||||||
|
|
||||||
# HandInfo : HID, TABLE
|
|
||||||
# BUTTON - why is this treated specially in Hand?
|
|
||||||
# answer: it is written out in hand histories
|
|
||||||
# still, I think we should record all the active seat positions in a seat_order array
|
|
||||||
c.execute("""
|
|
||||||
SELECT
|
|
||||||
h.sitehandno as hid,
|
|
||||||
h.tablename as table,
|
|
||||||
h.startTime as startTime
|
|
||||||
FROM
|
|
||||||
hands as h
|
|
||||||
WHERE h.id = %(handid)s
|
|
||||||
""", {'handid':handid})
|
|
||||||
res = c.fetchone()
|
|
||||||
h.handid = res[0]
|
|
||||||
h.tablename = res[1]
|
|
||||||
h.startTime = res[2] # automatically a datetime
|
|
||||||
|
|
||||||
# PlayerStacks
|
|
||||||
c.execute("""
|
|
||||||
SELECT
|
|
||||||
hp.seatno,
|
|
||||||
round(hp.winnings / 100.0,2) as winnings,
|
|
||||||
p.name,
|
|
||||||
round(hp.startcash / 100.0,2) as chips,
|
|
||||||
hp.card1,hp.card2,
|
|
||||||
hp.position
|
|
||||||
FROM
|
|
||||||
handsplayers as hp,
|
|
||||||
players as p
|
|
||||||
WHERE
|
|
||||||
hp.handid = %(handid)s
|
|
||||||
and p.id = hp.playerid
|
|
||||||
""", {'handid':handid})
|
|
||||||
for (seat, winnings, name, chips, card1,card2, position) in c.fetchall():
|
|
||||||
h.addPlayer(seat,name,chips)
|
|
||||||
if card1 and card2:
|
|
||||||
h.addHoleCards(map(Card.valueSuitFromCard, (card1,card2)), name, dealt=True)
|
|
||||||
if winnings > 0:
|
|
||||||
h.addCollectPot(name, winnings)
|
|
||||||
if position == 'B':
|
|
||||||
h.buttonpos = seat
|
|
||||||
|
|
||||||
|
|
||||||
# actions
|
|
||||||
c.execute("""
|
|
||||||
SELECT
|
|
||||||
(ha.street,ha.actionno) as actnum,
|
|
||||||
p.name,
|
|
||||||
ha.street,
|
|
||||||
ha.action,
|
|
||||||
ha.allin,
|
|
||||||
round(ha.amount / 100.0,2)
|
|
||||||
FROM
|
|
||||||
handsplayers as hp,
|
|
||||||
handsactions as ha,
|
|
||||||
players as p
|
|
||||||
WHERE
|
|
||||||
hp.handid = %(handid)s
|
|
||||||
and ha.handsplayerid = hp.id
|
|
||||||
and p.id = hp.playerid
|
|
||||||
ORDER BY
|
|
||||||
ha.street,ha.actionno
|
|
||||||
""", {'handid':handid})
|
|
||||||
res = c.fetchall()
|
|
||||||
for (actnum,player, streetnum, act, allin, amount) in res:
|
|
||||||
act=act.strip()
|
|
||||||
street = h.allStreets[streetnum+1]
|
|
||||||
if act==u'blind':
|
|
||||||
h.addBlind(player, 'big blind', amount)
|
|
||||||
# TODO: The type of blind is not recorded in the DB.
|
|
||||||
# TODO: preflop street name anomalies in Hand
|
|
||||||
elif act==u'fold':
|
|
||||||
h.addFold(street,player)
|
|
||||||
elif act==u'call':
|
|
||||||
h.addCall(street,player,amount)
|
|
||||||
elif act==u'bet':
|
|
||||||
h.addBet(street,player,amount)
|
|
||||||
elif act==u'check':
|
|
||||||
h.addCheck(street,player)
|
|
||||||
elif act==u'unbet':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print act, player, streetnum, allin, amount
|
|
||||||
# TODO : other actions
|
|
||||||
|
|
||||||
#hhc.readShowdownActions(self)
|
|
||||||
#hc.readShownCards(self)
|
|
||||||
h.totalPot()
|
|
||||||
h.rake = h.totalpot - h.totalcollected
|
|
||||||
|
|
||||||
|
|
||||||
return h
|
|
||||||
|
|
|
@ -393,7 +393,7 @@ class Hud:
|
||||||
|
|
||||||
if self.hud_params['h_agg_bb_mult'] != num \
|
if self.hud_params['h_agg_bb_mult'] != num \
|
||||||
and getattr(self, 'h_aggBBmultItem'+str(num)).get_active():
|
and getattr(self, 'h_aggBBmultItem'+str(num)).get_active():
|
||||||
log.debug('set_player_aggregation', num)
|
log.debug('set_player_aggregation %d', num)
|
||||||
self.hud_params['h_agg_bb_mult'] = num
|
self.hud_params['h_agg_bb_mult'] = num
|
||||||
for mult in ('1', '2', '3', '10', '10000'):
|
for mult in ('1', '2', '3', '10', '10000'):
|
||||||
if mult != str(num):
|
if mult != str(num):
|
||||||
|
@ -404,7 +404,7 @@ class Hud:
|
||||||
|
|
||||||
if self.hud_params['agg_bb_mult'] != num \
|
if self.hud_params['agg_bb_mult'] != num \
|
||||||
and getattr(self, 'aggBBmultItem'+str(num)).get_active():
|
and getattr(self, 'aggBBmultItem'+str(num)).get_active():
|
||||||
log.debug('set_opponent_aggregation', num)
|
log.debug('set_opponent_aggregation %d', num)
|
||||||
self.hud_params['agg_bb_mult'] = num
|
self.hud_params['agg_bb_mult'] = num
|
||||||
for mult in ('1', '2', '3', '10', '10000'):
|
for mult in ('1', '2', '3', '10', '10000'):
|
||||||
if mult != str(num):
|
if mult != str(num):
|
||||||
|
|
122
pyfpdb/IdentifySite.py
Normal file
122
pyfpdb/IdentifySite.py
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#Copyright 2010 Chaz Littlejohn
|
||||||
|
#This program is free software: you can redistribute it and/or modify
|
||||||
|
#it under the terms of the GNU Affero General Public License as published by
|
||||||
|
#the Free Software Foundation, version 3 of the License.
|
||||||
|
#
|
||||||
|
#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 Affero General Public License
|
||||||
|
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#In the "official" distribution you can find the license in agpl-3.0.txt.
|
||||||
|
|
||||||
|
import L10n
|
||||||
|
_ = L10n.get_translation()
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
from optparse import OptionParser
|
||||||
|
import codecs
|
||||||
|
import Configuration
|
||||||
|
import Database
|
||||||
|
|
||||||
|
__ARCHIVE_PRE_HEADER_REGEX='^Hand #(\d+)\s*$|\*{20}\s#\s\d+\s\*+\s+'
|
||||||
|
re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX)
|
||||||
|
|
||||||
|
|
||||||
|
class IdentifySite:
|
||||||
|
def __init__(self, config, in_path = '-'):
|
||||||
|
self.in_path = in_path
|
||||||
|
self.config = config
|
||||||
|
self.db = Database.Database(config)
|
||||||
|
self.sitelist = {}
|
||||||
|
self.filelist = {}
|
||||||
|
self.generateSiteList()
|
||||||
|
self.walkDirectory(self.in_path, self.sitelist)
|
||||||
|
|
||||||
|
def generateSiteList(self):
|
||||||
|
"""Generates a ordered dictionary of site, filter and filter name for each site in hhcs"""
|
||||||
|
for site, hhc in self.config.hhcs.iteritems():
|
||||||
|
filter = hhc.converter
|
||||||
|
filter_name = filter.replace("ToFpdb", "")
|
||||||
|
result = self.db.get_site_id(site)
|
||||||
|
if len(result) == 1:
|
||||||
|
self.sitelist[result[0][0]] = (site, filter, filter_name)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def walkDirectory(self, dir, sitelist):
|
||||||
|
"""Walks a directory, and executes a callback on each file"""
|
||||||
|
dir = os.path.abspath(dir)
|
||||||
|
for file in [file for file in os.listdir(dir) if not file in [".",".."]]:
|
||||||
|
nfile = os.path.join(dir,file)
|
||||||
|
if os.path.isdir(nfile):
|
||||||
|
self.walkDirectory(nfile, sitelist)
|
||||||
|
else:
|
||||||
|
self.idSite(nfile, sitelist)
|
||||||
|
|
||||||
|
def __listof(self, x):
|
||||||
|
if isinstance(x, list) or isinstance(x, tuple):
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
return [x]
|
||||||
|
|
||||||
|
def idSite(self, file, sitelist):
|
||||||
|
"""Identifies the site the hh file originated from"""
|
||||||
|
if file.endswith('.txt'):
|
||||||
|
self.filelist[file] = ''
|
||||||
|
archive = False
|
||||||
|
for site, info in sitelist.iteritems():
|
||||||
|
mod = __import__(info[1])
|
||||||
|
obj = getattr(mod, info[2], None)
|
||||||
|
|
||||||
|
for kodec in self.__listof(obj.codepage):
|
||||||
|
try:
|
||||||
|
in_fh = codecs.open(file, 'r', kodec)
|
||||||
|
whole_file = in_fh.read()
|
||||||
|
in_fh.close()
|
||||||
|
|
||||||
|
if info[2] in ('OnGame', 'Winamax'):
|
||||||
|
m = obj.re_HandInfo.search(whole_file)
|
||||||
|
elif info[2] in ('PartyPoker'):
|
||||||
|
m = obj.re_GameInfoRing.search(whole_file)
|
||||||
|
if not m:
|
||||||
|
m = obj.re_GameInfoTrny.search(whole_file)
|
||||||
|
else:
|
||||||
|
m = obj.re_GameInfo.search(whole_file)
|
||||||
|
if re_SplitArchive.search(whole_file):
|
||||||
|
archive = True
|
||||||
|
if m:
|
||||||
|
self.filelist[file] = [info[0]] + [info[1]] + [kodec] + [archive]
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def main(argv=None):
|
||||||
|
if argv is None:
|
||||||
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
|
config = Configuration.Config(file = "HUD_config.test.xml")
|
||||||
|
in_path = 'regression-test-files/'
|
||||||
|
IdSite = IdentifySite(config, in_path)
|
||||||
|
|
||||||
|
print "\n----------- SITE LIST -----------"
|
||||||
|
for site, info in IdSite.sitelist.iteritems():
|
||||||
|
print site, info
|
||||||
|
print "----------- END SITE LIST -----------"
|
||||||
|
|
||||||
|
print "\n----------- ID REGRESSION FILES -----------"
|
||||||
|
for file, site in IdSite.filelist.iteritems():
|
||||||
|
print file, site
|
||||||
|
print "----------- END ID REGRESSION FILES -----------"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
|
@ -53,6 +53,15 @@ def fpdb_options():
|
||||||
help = _("Print version information and exit."))
|
help = _("Print version information and exit."))
|
||||||
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
||||||
help=_("Print some useful one liners"))
|
help=_("Print some useful one liners"))
|
||||||
|
# The following options are used for SplitHandHistory.py
|
||||||
|
parser.add_option("-f", "--file", dest="filename", metavar="FILE", default=None,
|
||||||
|
help=_("Input file in quiet mode"))
|
||||||
|
parser.add_option("-o", "--outpath", dest="outpath", metavar="FILE", default=None,
|
||||||
|
help=_("Input out path in quiet mode"))
|
||||||
|
parser.add_option("-a", "--archive", action="store_true", dest="archive", default=False,
|
||||||
|
help=_("File to be split is a PokerStars or Full Tilt Poker archive file"))
|
||||||
|
parser.add_option("-n", "--numhands", dest="hands", default="100", type="int",
|
||||||
|
help=_("How many hands do you want saved to each file. Default is 100"))
|
||||||
|
|
||||||
|
|
||||||
(options, argv) = parser.parse_args()
|
(options, argv) = parser.parse_args()
|
||||||
|
|
|
@ -39,7 +39,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
siteId = 2 # Needs to match id entry in Sites database
|
siteId = 2 # Needs to match id entry in Sites database
|
||||||
|
|
||||||
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games
|
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games
|
||||||
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE
|
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3", "play": ""} # ADD Euro, Sterling, etc HERE
|
||||||
substitutions = {
|
substitutions = {
|
||||||
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
|
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
|
||||||
'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8)
|
'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8)
|
||||||
|
|
|
@ -1397,6 +1397,10 @@ class Sql:
|
||||||
|
|
||||||
self.query['get_last_hand'] = "select max(id) from Hands"
|
self.query['get_last_hand'] = "select max(id) from Hands"
|
||||||
|
|
||||||
|
self.query['get_last_date'] = "SELECT MAX(startTime) FROM Hands"
|
||||||
|
|
||||||
|
self.query['get_first_date'] = "SELECT MIN(startTime) FROM Hands"
|
||||||
|
|
||||||
self.query['get_player_id'] = """
|
self.query['get_player_id'] = """
|
||||||
select Players.id AS player_id
|
select Players.id AS player_id
|
||||||
from Players, Sites
|
from Players, Sites
|
||||||
|
|
207
pyfpdb/SplitHandHistory.py
Normal file
207
pyfpdb/SplitHandHistory.py
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#Copyright 2010 Chaz Littlejohn
|
||||||
|
#This program is free software: you can redistribute it and/or modify
|
||||||
|
#it under the terms of the GNU Affero General Public License as published by
|
||||||
|
#the Free Software Foundation, version 3 of the License.
|
||||||
|
#
|
||||||
|
#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 Affero General Public License
|
||||||
|
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#In the "official" distribution you can find the license in agpl-3.0.txt.
|
||||||
|
|
||||||
|
import L10n
|
||||||
|
_ = L10n.get_translation()
|
||||||
|
|
||||||
|
# This code is based heavily on stars-support-hh-split.py by Mika Boström
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import codecs
|
||||||
|
import Options
|
||||||
|
import Configuration
|
||||||
|
from Exceptions import *
|
||||||
|
from cStringIO import StringIO
|
||||||
|
|
||||||
|
(options, argv) = Options.fpdb_options()
|
||||||
|
|
||||||
|
__ARCHIVE_PRE_HEADER_REGEX='^Hand #(\d+)\s*$|\*{20}\s#\s\d+\s\*+\s+'
|
||||||
|
re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX)
|
||||||
|
codepage = ["utf-16", "utf-8", "cp1252"]
|
||||||
|
|
||||||
|
|
||||||
|
class SplitHandHistory:
|
||||||
|
def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False):
|
||||||
|
self.config = config
|
||||||
|
self.in_path = in_path
|
||||||
|
self.out_path = out_path
|
||||||
|
if not self.out_path:
|
||||||
|
self.out_path = os.path.dirname(self.in_path)
|
||||||
|
self.hands = hands
|
||||||
|
self.archive = archive
|
||||||
|
self.re_SplitHands = None
|
||||||
|
self.line_delimiter = None
|
||||||
|
self.line_addendum = None
|
||||||
|
self.filedone = False
|
||||||
|
|
||||||
|
#Acquire re_SplitHands for this hh
|
||||||
|
filter_name = filter.replace("ToFpdb", "")
|
||||||
|
mod = __import__(filter)
|
||||||
|
obj = getattr(mod, filter_name, None)
|
||||||
|
self.re_SplitHands = obj.re_SplitHands
|
||||||
|
|
||||||
|
#Determine line delimiter type if any
|
||||||
|
if self.re_SplitHands.match('\n\n'):
|
||||||
|
self.line_delimiter = '\n\n'
|
||||||
|
if self.re_SplitHands.match('\n\n\n'):
|
||||||
|
self.line_delimiter = '\n\n\n'
|
||||||
|
|
||||||
|
#Add new line addendum for sites which match SplitHand to next line as well
|
||||||
|
if filter_name == 'OnGame':
|
||||||
|
self.line_addendum = '*'
|
||||||
|
if filter_name == 'Carbon':
|
||||||
|
self.line_addendum = '<game'
|
||||||
|
|
||||||
|
#Open the gargantuan file
|
||||||
|
for kodec in self.__listof(codepage):
|
||||||
|
try:
|
||||||
|
infile = codecs.open(self.in_path, 'r', kodec)
|
||||||
|
except IOError:
|
||||||
|
print _('File not found')
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
#Split with do_hands_per_file if archive and paragraphs if a regular hh
|
||||||
|
if self.archive:
|
||||||
|
nn = 0
|
||||||
|
while True:
|
||||||
|
nn += 1
|
||||||
|
check = self.do_hands_per_file(infile, nn)
|
||||||
|
if check is None:
|
||||||
|
print _('%s processed' % self.in_path)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
filenum = 0
|
||||||
|
while not self.filedone:
|
||||||
|
filenum += 1
|
||||||
|
outfile = self.new_file(filenum)
|
||||||
|
handnum = 0
|
||||||
|
for hand in self.paragraphs(infile, None, self.line_addendum):
|
||||||
|
outfile.write(hand)
|
||||||
|
if self.line_delimiter:
|
||||||
|
outfile.write(self.line_delimiter)
|
||||||
|
handnum += 1
|
||||||
|
if handnum >= self.hands:
|
||||||
|
break
|
||||||
|
outfile.close()
|
||||||
|
|
||||||
|
def new_file(self, fileno=-1):
|
||||||
|
if fileno < 1:
|
||||||
|
print _('Nope, will not work (fileno=%d)' % fileno)
|
||||||
|
sys.exit(2)
|
||||||
|
basename = os.path.splitext(os.path.basename(self.in_path))[0]
|
||||||
|
name = os.path.join(self.out_path, basename+'-%06d.txt' % fileno)
|
||||||
|
print '-> %s' % name
|
||||||
|
newfile = file(name, 'w')
|
||||||
|
return newfile
|
||||||
|
|
||||||
|
#Archive Hand Splitter
|
||||||
|
def do_hands_per_file(self, infile, num=-1):
|
||||||
|
done = False
|
||||||
|
n = 0
|
||||||
|
outfile = self.new_file(num)
|
||||||
|
while n < self.hands:
|
||||||
|
try:
|
||||||
|
infile = self.next_hand(infile)
|
||||||
|
infile = self.process_hand(infile, outfile)
|
||||||
|
except FpdbEndOfFile:
|
||||||
|
done = True
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
print _("Unexpected error processing file")
|
||||||
|
sys.exit(2)
|
||||||
|
n += 1
|
||||||
|
outfile.close()
|
||||||
|
if not done:
|
||||||
|
return infile
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
#Non-Archive Hand Splitter
|
||||||
|
def paragraphs(self, file, separator=None, addendum=None):
|
||||||
|
if not callable(separator) and self.line_delimiter:
|
||||||
|
def separator(line): return line == '\n'
|
||||||
|
else:
|
||||||
|
def separator(line): return self.re_SplitHands.search(line)
|
||||||
|
file_str = StringIO()
|
||||||
|
print file_str.getvalue()
|
||||||
|
for line in file:
|
||||||
|
if separator(line+addendum):
|
||||||
|
if file_str.getvalue():
|
||||||
|
if not self.line_delimiter:
|
||||||
|
file_str.write(line)
|
||||||
|
yield file_str.getvalue()
|
||||||
|
file_str = None
|
||||||
|
file_str = StringIO()
|
||||||
|
else:
|
||||||
|
file_str.write(line)
|
||||||
|
if file_str.getvalue(): yield file_str.getvalue()
|
||||||
|
self.filedone = True
|
||||||
|
|
||||||
|
|
||||||
|
# Finds pre-hand header (Hand #<num>)
|
||||||
|
def next_hand(self, infile):
|
||||||
|
m = None
|
||||||
|
while not m:
|
||||||
|
l = infile.readline()
|
||||||
|
#print l, len(l)
|
||||||
|
# Catch EOF
|
||||||
|
if len(l) == 0:
|
||||||
|
raise FpdbEndOfFile(_("End of file reached"))
|
||||||
|
m = re_SplitArchive.search(l)
|
||||||
|
# There is an empty line after pre-hand header and actual HH entry
|
||||||
|
l = infile.readline()
|
||||||
|
|
||||||
|
return infile
|
||||||
|
|
||||||
|
# Each individual hand is written separately
|
||||||
|
def process_hand(self, infile=None, outfile=None):
|
||||||
|
l = infile.readline()
|
||||||
|
l = l.replace('\r\n', '\n')
|
||||||
|
outfile.write(l)
|
||||||
|
l = infile.readline()
|
||||||
|
|
||||||
|
while len(l) < 3:
|
||||||
|
l = infile.readline()
|
||||||
|
|
||||||
|
while len(l) > 2:
|
||||||
|
l = l.replace('\r\n', '\n')
|
||||||
|
outfile.write(l)
|
||||||
|
l = infile.readline()
|
||||||
|
outfile.write(self.line_delimiter)
|
||||||
|
return infile
|
||||||
|
|
||||||
|
def __listof(self, x):
|
||||||
|
if isinstance(x, list) or isinstance(x, tuple):
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
return [x]
|
||||||
|
|
||||||
|
def main(argv=None):
|
||||||
|
if argv is None:
|
||||||
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
|
if not options.config:
|
||||||
|
options.config = Configuration.Config(file = "HUD_config.test.xml")
|
||||||
|
|
||||||
|
if options.filename:
|
||||||
|
SplitHH = SplitHandHistory(options.config, options.filename, options.outpath, options.hands,
|
||||||
|
options.hhc, options.archive)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
|
@ -184,9 +184,13 @@ class Table_Window(object):
|
||||||
if new_title is None:
|
if new_title is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
mo = re.search(self.tableno_re, new_title)
|
mo = re.search(self.tableno_re, new_title)
|
||||||
|
except AttributeError: #'Table' object has no attribute 'tableno_re'
|
||||||
|
return False
|
||||||
|
|
||||||
if mo is not None:
|
if mo is not None:
|
||||||
print "get_table_no: mo=",mo.groups()
|
#print "get_table_no: mo=",mo.groups()
|
||||||
return mo.group(1)
|
return mo.group(1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ from TableWindow import Table_Window
|
||||||
b_width = 3
|
b_width = 3
|
||||||
tb_height = 29
|
tb_height = 29
|
||||||
|
|
||||||
|
|
||||||
class Table(Table_Window):
|
class Table(Table_Window):
|
||||||
|
|
||||||
def find_table_parameters(self):
|
def find_table_parameters(self):
|
||||||
|
@ -56,15 +57,17 @@ class Table(Table_Window):
|
||||||
titles = {}
|
titles = {}
|
||||||
win32gui.EnumWindows(win_enum_handler, titles)
|
win32gui.EnumWindows(win_enum_handler, titles)
|
||||||
for hwnd in titles:
|
for hwnd in titles:
|
||||||
if titles[hwnd] == "": continue
|
if titles[hwnd] == "":
|
||||||
|
continue
|
||||||
if re.search(self.search_string, titles[hwnd]):
|
if re.search(self.search_string, titles[hwnd]):
|
||||||
if self.check_bad_words(titles[hwnd]): continue
|
if self.check_bad_words(titles[hwnd]):
|
||||||
|
continue
|
||||||
self.window = hwnd
|
self.window = hwnd
|
||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.window == None:
|
if self.window == None:
|
||||||
log.error( "Window %s not found. Skipping." % self.search_string )
|
log.error(_("Window %s not found. Skipping." % self.search_string))
|
||||||
return None
|
return None
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
log.error(_("self.window doesn't exist? why?"))
|
log.error(_("self.window doesn't exist? why?"))
|
||||||
|
@ -75,24 +78,29 @@ class Table(Table_Window):
|
||||||
self.number = hwnd
|
self.number = hwnd
|
||||||
|
|
||||||
def get_geometry(self):
|
def get_geometry(self):
|
||||||
if not win32gui.IsWindow(self.number): # window closed
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if win32gui.IsWindow(self.number):
|
||||||
(x, y, width, height) = win32gui.GetWindowRect(self.number)
|
(x, y, width, height) = win32gui.GetWindowRect(self.number)
|
||||||
#print "x=",x,"y=",y,"width=",width,"height=",height
|
# this apparently returns x = far left side of window, width = far right side of window, y = top of window, height = bottom of window
|
||||||
|
# so apparently we have to subtract x from "width" to get actual width, and y from "height" to get actual height ?
|
||||||
|
# it definitely gives slightly different results than the GTK code that does the same thing.
|
||||||
|
#print "x=", x, "y=", y, "width=", width, "height=", height
|
||||||
width = width - x
|
width = width - x
|
||||||
height = height - y
|
height = height - y
|
||||||
return {'x' : int(x) + b_width,
|
return {
|
||||||
|
'x' : int(x) + b_width,
|
||||||
'y' : int(y) + tb_height,
|
'y' : int(y) + tb_height,
|
||||||
'height' : int(height) - y,
|
'height' : int(height) - y,
|
||||||
'width' : int(width) - x
|
'width' : int(width) - x
|
||||||
}
|
}
|
||||||
except:
|
except AttributeError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_window_title(self):
|
def get_window_title(self):
|
||||||
|
try: # after window is destroyed, self.window = attribute error
|
||||||
return win32gui.GetWindowText(self.window)
|
return win32gui.GetWindowText(self.window)
|
||||||
|
except AttributeError:
|
||||||
|
return ""
|
||||||
|
|
||||||
# def get_nt_exe(self, hwnd):
|
# def get_nt_exe(self, hwnd):
|
||||||
# """Finds the name of the executable that the given window handle belongs to."""
|
# """Finds the name of the executable that the given window handle belongs to."""
|
||||||
|
@ -145,5 +153,6 @@ class Table(Table_Window):
|
||||||
|
|
||||||
# hud.main_window.set_title(real_name)
|
# hud.main_window.set_title(real_name)
|
||||||
|
|
||||||
|
|
||||||
def win_enum_handler(hwnd, titles):
|
def win_enum_handler(hwnd, titles):
|
||||||
titles[hwnd] = win32gui.GetWindowText(hwnd)
|
titles[hwnd] = win32gui.GetWindowText(hwnd)
|
||||||
|
|
|
@ -962,6 +962,7 @@ class fpdb:
|
||||||
if self.db!=None:
|
if self.db!=None:
|
||||||
if self.db.backend==self.db.MYSQL_INNODB:
|
if self.db.backend==self.db.MYSQL_INNODB:
|
||||||
try:
|
try:
|
||||||
|
import _mysql_exceptions
|
||||||
if self.db is not None and self.db.is_connected():
|
if self.db is not None and self.db.is_connected():
|
||||||
self.db.disconnect()
|
self.db.disconnect()
|
||||||
except _mysql_exceptions.OperationalError: # oh, damn, we're already disconnected
|
except _mysql_exceptions.OperationalError: # oh, damn, we're already disconnected
|
||||||
|
|
|
@ -312,7 +312,7 @@
|
||||||
'otherRaisedStreet3': False,
|
'otherRaisedStreet3': False,
|
||||||
'otherRaisedStreet4': False,
|
'otherRaisedStreet4': False,
|
||||||
'position': 'S',
|
'position': 'S',
|
||||||
'raiseFirstInChance': True,
|
'raiseFirstInChance': False,
|
||||||
'raisedFirstIn': False,
|
'raisedFirstIn': False,
|
||||||
'rake': 0,
|
'rake': 0,
|
||||||
'sawShowdown': False,
|
'sawShowdown': False,
|
||||||
|
@ -594,7 +594,7 @@
|
||||||
'otherRaisedStreet3': True,
|
'otherRaisedStreet3': True,
|
||||||
'otherRaisedStreet4': True,
|
'otherRaisedStreet4': True,
|
||||||
'position': 6,
|
'position': 6,
|
||||||
'raiseFirstInChance': False,
|
'raiseFirstInChance': True,
|
||||||
'raisedFirstIn': False,
|
'raisedFirstIn': False,
|
||||||
'rake': 2,
|
'rake': 2,
|
||||||
'sawShowdown': True,
|
'sawShowdown': True,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user