Merge branch 'stats' of git://git.assembla.com/fpdboz into newstats
This commit is contained in:
commit
cdd7e6dce2
116
pyfpdb/AlchemyFacilities.py
Normal file
116
pyfpdb/AlchemyFacilities.py
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
from sqlalchemy import types
|
||||||
|
from sqlalchemy.orm.exc import NoResultFound
|
||||||
|
from sqlalchemy.exc import IntegrityError
|
||||||
|
|
||||||
|
import Card
|
||||||
|
|
||||||
|
class CardColumn(types.TypeDecorator):
|
||||||
|
"""Stores cards as smallints
|
||||||
|
|
||||||
|
Automatically converts values like '9h' to smallint
|
||||||
|
|
||||||
|
>>> CardColumn().process_bind_param( 'Td', '' )
|
||||||
|
22
|
||||||
|
>>> CardColumn().process_bind_param( u'Td', '' )
|
||||||
|
22
|
||||||
|
>>> CardColumn().process_bind_param( 22, '' )
|
||||||
|
22
|
||||||
|
>>> CardColumn().process_result_value( 22, '' )
|
||||||
|
'Td'
|
||||||
|
"""
|
||||||
|
|
||||||
|
impl = types.SmallInteger
|
||||||
|
|
||||||
|
def process_bind_param(self, value, dialect):
|
||||||
|
if value is None or isinstance(value, int):
|
||||||
|
return value
|
||||||
|
elif isinstance(value, basestring) and len(value) == 2:
|
||||||
|
return Card.encodeCard(str(value))
|
||||||
|
else:
|
||||||
|
raise Exception, "Incorrect card value: " + repr(value)
|
||||||
|
|
||||||
|
def process_result_value(self, value, dialect):
|
||||||
|
return Card.valueSuitFromCard( value )
|
||||||
|
|
||||||
|
|
||||||
|
class MoneyColumn(types.TypeDecorator):
|
||||||
|
"""Stores money: bets, pots, etc
|
||||||
|
|
||||||
|
Understands:
|
||||||
|
Decimal as real amount
|
||||||
|
int as amount mupliplied by 100
|
||||||
|
string as decimal
|
||||||
|
Returns Decimal
|
||||||
|
>>> MoneyColumn().process_bind_param( 230, '' )
|
||||||
|
230
|
||||||
|
>>> MoneyColumn().process_bind_param( Decimal('2.30'), '' )
|
||||||
|
230
|
||||||
|
>>> MoneyColumn().process_bind_param( '2.30', '' )
|
||||||
|
230
|
||||||
|
>>> MoneyColumn().process_result_value( 230, '' )
|
||||||
|
Decimal('2.3')
|
||||||
|
"""
|
||||||
|
|
||||||
|
impl = types.Integer
|
||||||
|
|
||||||
|
def process_bind_param(self, value, dialect):
|
||||||
|
if value is None or isinstance(value, int):
|
||||||
|
return value
|
||||||
|
elif isinstance(value, basestring) or isinstance(value, Decimal):
|
||||||
|
return int(Decimal(value)*100)
|
||||||
|
else:
|
||||||
|
raise Exception, "Incorrect amount:" + repr(value)
|
||||||
|
|
||||||
|
def process_result_value(self, value, dialect):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
return Decimal(value)/100
|
||||||
|
|
||||||
|
|
||||||
|
class BigIntColumn(types.TypeDecorator, types.Integer):
|
||||||
|
"""Representing db-independent big integer """
|
||||||
|
# Integer inheritance required for auto_increment flag
|
||||||
|
|
||||||
|
impl = types.Integer
|
||||||
|
|
||||||
|
def load_dialect_impl(self, dialect):
|
||||||
|
from sqlalchemy import databases
|
||||||
|
if dialect.name == 'mysql':
|
||||||
|
return databases.mysql.MSBigInteger()
|
||||||
|
elif dialect.name == 'postgres':
|
||||||
|
return databases.mysql.PGBigInteger()
|
||||||
|
return types.Integer()
|
||||||
|
|
||||||
|
|
||||||
|
class MappedBase(object):
|
||||||
|
"""Provide dummy contrcutor"""
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
for k, v in kwargs.iteritems():
|
||||||
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
def get_columns_names(self):
|
||||||
|
return [i.name for i in self._sa_class_manager.mapper.c]
|
||||||
|
|
||||||
|
def get_or_create(klass, session, **kwargs):
|
||||||
|
"""
|
||||||
|
Looks up an object with the given kwargs, creating one if necessary.
|
||||||
|
Returns a tuple of (object, created), where created is a boolean
|
||||||
|
specifying whether an object was created.
|
||||||
|
"""
|
||||||
|
assert kwargs, \
|
||||||
|
'get_or_create() must be passed at least one keyword argument'
|
||||||
|
try:
|
||||||
|
return session.query(klass).filter_by(**kwargs).one(), False
|
||||||
|
except NoResultFound:
|
||||||
|
try:
|
||||||
|
obj = klass(**kwargs)
|
||||||
|
session.add(obj)
|
||||||
|
session.flush()
|
||||||
|
return obj, True
|
||||||
|
except IntegrityError:
|
||||||
|
return session.query(klass).filter_by(**kwargs).one(), False
|
||||||
|
|
464
pyfpdb/AlchemyMappings.py
Normal file
464
pyfpdb/AlchemyMappings.py
Normal file
|
@ -0,0 +1,464 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""@package AlchemyMappings
|
||||||
|
This package contains all classes to be mapped and mappers themselves
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
from decimal import Decimal
|
||||||
|
from sqlalchemy.orm import mapper, relation, reconstructor
|
||||||
|
from sqlalchemy.sql import select
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
|
from AlchemyTables import *
|
||||||
|
from AlchemyFacilities import get_or_create, MappedBase
|
||||||
|
from DerivedStats import DerivedStats
|
||||||
|
from Exceptions import IncompleteHandError, FpdbError
|
||||||
|
|
||||||
|
|
||||||
|
class Player(MappedBase):
|
||||||
|
"""Class reflecting Players db table"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_or_create(session, siteId, name):
|
||||||
|
return get_or_create(Player, session, siteId=siteId, name=name)[0]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '<Player "%s" on %s>' % (self.name, self.site and self.site.name)
|
||||||
|
|
||||||
|
|
||||||
|
class Gametype(MappedBase):
|
||||||
|
"""Class reflecting Gametypes db table"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_or_create(session, siteId, gametype):
|
||||||
|
map = zip(
|
||||||
|
['type', 'base', 'category', 'limitType', 'smallBlind', 'bigBlind', 'smallBet', 'bigBet'],
|
||||||
|
['type', 'base', 'category', 'limitType', 'sb', 'bb', 'dummy', 'dummy', ])
|
||||||
|
gametype = dict([(new, gametype.get(old)) for new, old in map ])
|
||||||
|
|
||||||
|
hilo = "h"
|
||||||
|
if gametype['category'] in ('studhilo', 'omahahilo'):
|
||||||
|
hilo = "s"
|
||||||
|
elif gametype['category'] in ('razz','27_3draw','badugi'):
|
||||||
|
hilo = "l"
|
||||||
|
gametype['hiLo'] = hilo
|
||||||
|
|
||||||
|
for f in ['smallBlind', 'bigBlind', 'smallBet', 'bigBet']:
|
||||||
|
if gametype[f] is None:
|
||||||
|
gametype[f] = 0
|
||||||
|
gametype[f] = int(Decimal(gametype[f])*100)
|
||||||
|
|
||||||
|
gametype['siteId'] = siteId
|
||||||
|
return get_or_create(Gametype, session, **gametype)[0]
|
||||||
|
|
||||||
|
|
||||||
|
class HandActions(object):
|
||||||
|
"""Class reflecting HandsActions db table"""
|
||||||
|
def initFromImportedHand(self, hand, actions):
|
||||||
|
self.hand = hand
|
||||||
|
self.actions = {}
|
||||||
|
for street, street_actions in actions.iteritems():
|
||||||
|
self.actions[street] = []
|
||||||
|
for v in street_actions:
|
||||||
|
hp = hand.handplayers_by_name[v[0]]
|
||||||
|
self.actions[street].append({'street': street, 'pid': hp.id, 'seat': hp.seatNo, 'action':v})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def flat_actions(self):
|
||||||
|
actions = []
|
||||||
|
for street in self.hand.allStreets:
|
||||||
|
actions += self.actions[street]
|
||||||
|
return actions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HandInternal(DerivedStats):
|
||||||
|
"""Class reflecting Hands db table"""
|
||||||
|
|
||||||
|
def parseImportedHandStep1(self, hand):
|
||||||
|
"""Extracts values to insert into from hand returned by HHC. No db is needed he"""
|
||||||
|
hand.players = hand.getAlivePlayers()
|
||||||
|
|
||||||
|
# also save some data for step2. Those fields aren't in Hands table
|
||||||
|
self.siteId = hand.siteId
|
||||||
|
self.gametype_dict = hand.gametype
|
||||||
|
|
||||||
|
self.attachHandPlayers(hand)
|
||||||
|
self.attachActions(hand)
|
||||||
|
|
||||||
|
self.assembleHands(hand)
|
||||||
|
self.assembleHandsPlayers(hand)
|
||||||
|
|
||||||
|
def parseImportedHandStep2(self, session):
|
||||||
|
"""Fetching ids for gametypes and players"""
|
||||||
|
gametype = Gametype.get_or_create(session, self.siteId, self.gametype_dict)
|
||||||
|
self.gametypeId = gametype.id
|
||||||
|
for hp in self.handPlayers:
|
||||||
|
hp.playerId = Player.get_or_create(session, self.siteId, hp.name).id
|
||||||
|
|
||||||
|
def getPlayerByName(self, name):
|
||||||
|
if not hasattr(self, 'handplayers_by_name'):
|
||||||
|
self.handplayers_by_name = {}
|
||||||
|
for hp in self.handPlayers:
|
||||||
|
pname = getattr(hp, 'name', None) or hp.player.name
|
||||||
|
self.handplayers_by_name[pname] = hp
|
||||||
|
return self.handplayers_by_name[name]
|
||||||
|
|
||||||
|
def attachHandPlayers(self, hand):
|
||||||
|
"""Fill HandInternal.handPlayers list. Create self.handplayers_by_name"""
|
||||||
|
hand.noSb = getattr(hand, 'noSb', None)
|
||||||
|
if hand.noSb is None and self.gametype_dict['base']=='hold':
|
||||||
|
saw_sb = False
|
||||||
|
for action in hand.actions[hand.actionStreets[0]]: # blindsantes
|
||||||
|
if action[1] == 'posts' and action[2] == 'small blind' and action[0] is not None:
|
||||||
|
saw_sb = True
|
||||||
|
hand.noSb = saw_sb
|
||||||
|
|
||||||
|
self.handplayers_by_name = {}
|
||||||
|
for seat, name, chips in hand.players:
|
||||||
|
p = HandPlayer(hand = self, imported_hand=hand, seatNo=seat,
|
||||||
|
name=name, startCash=chips)
|
||||||
|
self.handplayers_by_name[name] = p
|
||||||
|
|
||||||
|
def attachActions(self, hand):
|
||||||
|
"""Create HandActions object"""
|
||||||
|
a = HandActions()
|
||||||
|
a.initFromImportedHand(self, hand.actions)
|
||||||
|
|
||||||
|
def parseImportedTournament(self, hand, session):
|
||||||
|
"""Fetching tourney, its type and players
|
||||||
|
|
||||||
|
Must be called after Step2
|
||||||
|
"""
|
||||||
|
if self.gametype_dict['type'] != 'tour': return
|
||||||
|
|
||||||
|
# check for consistense
|
||||||
|
for i in ('buyin', 'tourNo'):
|
||||||
|
if not hasattr(hand, i):
|
||||||
|
raise IncompleteHandError(
|
||||||
|
"Field '%s' required for tournaments" % i, self.id, hand )
|
||||||
|
|
||||||
|
# repair old-style buyin value
|
||||||
|
m = re.match('\$(\d+)\+\$(\d+)', hand.buyin)
|
||||||
|
if m is not None:
|
||||||
|
hand.buyin, self.fee = m.groups()
|
||||||
|
|
||||||
|
# fetch tourney type
|
||||||
|
tour_type_hand2db = {
|
||||||
|
'buyin': 'buyin',
|
||||||
|
'fee': 'fee',
|
||||||
|
'speed': 'speed',
|
||||||
|
'maxSeats': 'maxseats',
|
||||||
|
'knockout': 'isKO',
|
||||||
|
'rebuyOrAddon': 'isRebuy',
|
||||||
|
'headsUp': 'isHU',
|
||||||
|
'shootout': 'isShootout',
|
||||||
|
'matrix': 'isMatrix',
|
||||||
|
'sng': 'isSNG',
|
||||||
|
}
|
||||||
|
tour_type_index = dict([
|
||||||
|
( i_db, getattr(hand, i_hand, None) )
|
||||||
|
for i_db, i_hand in tour_type_hand2db.iteritems()
|
||||||
|
])
|
||||||
|
tour_type_index['siteId'] = self.siteId
|
||||||
|
tour_type = TourneyType.get_or_create(session, **tour_type_index)
|
||||||
|
|
||||||
|
# fetch and update tourney
|
||||||
|
tour = Tourney.get_or_create(session, hand.tourNo, tour_type.id)
|
||||||
|
cols = tour.get_columns_names()
|
||||||
|
for col in cols:
|
||||||
|
hand_val = getattr(hand, col, None)
|
||||||
|
if col in ('id', 'tourneyTypeId', 'comment', 'commentTs') or hand_val is None:
|
||||||
|
continue
|
||||||
|
db_val = getattr(tour, col, None)
|
||||||
|
if db_val is None:
|
||||||
|
setattr(tour, col, hand_val)
|
||||||
|
elif col == 'koBounty':
|
||||||
|
setattr(tour, col, max(db_val, hand_val))
|
||||||
|
elif col == 'tourStartTime' and hand.handStart:
|
||||||
|
setattr(tour, col, min(db_val, hand.handStart))
|
||||||
|
|
||||||
|
if tour.entries is None and tour_type.sng:
|
||||||
|
tour.entries = tour_type.maxSeats
|
||||||
|
|
||||||
|
# fetch and update tourney players
|
||||||
|
for hp in self.handPlayers:
|
||||||
|
tp = TourneyPlayer.get_or_create(session, tour.id, hp.playerId)
|
||||||
|
# FIXME: other TourneysPlayers should be added here
|
||||||
|
|
||||||
|
session.flush()
|
||||||
|
|
||||||
|
def isDuplicate(self, session):
|
||||||
|
"""Checks if current hand already exists in db
|
||||||
|
|
||||||
|
siteHandNo ans gameTypeId have to be setted
|
||||||
|
"""
|
||||||
|
return session.query(HandInternal).filter_by(
|
||||||
|
siteHandNo=self.siteHandNo, gametypeId=self.gametypeId).count()!=0
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
s = list()
|
||||||
|
for i in self._sa_class_manager.mapper.c:
|
||||||
|
s.append('%25s %s' % (i, getattr(self, i.name)))
|
||||||
|
|
||||||
|
s+=['', '']
|
||||||
|
for i,p in enumerate(self.handPlayers):
|
||||||
|
s.append('%d. %s' % (i, p.name or '???'))
|
||||||
|
s.append(str(p))
|
||||||
|
return '\n'.join(s)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def boardcards(self):
|
||||||
|
cards = []
|
||||||
|
for i in range(5):
|
||||||
|
cards.append(getattr(self, 'boardcard%d' % (i+1), None))
|
||||||
|
return filter(bool, cards)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def HandClass(self):
|
||||||
|
"""Return HoldemOmahaHand or something like this"""
|
||||||
|
import Hand
|
||||||
|
if self.gametype.base == 'hold':
|
||||||
|
return Hand.HoldemOmahaHand
|
||||||
|
elif self.gametype.base == 'draw':
|
||||||
|
return Hand.DrawHand
|
||||||
|
elif self.gametype.base == 'stud':
|
||||||
|
return Hand.StudHand
|
||||||
|
raise Exception("Unknow gametype.base: '%s'" % self.gametype.base)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def allStreets(self):
|
||||||
|
return self.HandClass.allStreets
|
||||||
|
|
||||||
|
@property
|
||||||
|
def actionStreets(self):
|
||||||
|
return self.HandClass.actionStreets
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HandPlayer(MappedBase):
|
||||||
|
"""Class reflecting HandsPlayers db table"""
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
if 'imported_hand' in kwargs and 'seatNo' in kwargs:
|
||||||
|
imported_hand = kwargs.pop('imported_hand')
|
||||||
|
self.position = self.getPosition(imported_hand, kwargs['seatNo'])
|
||||||
|
super(HandPlayer, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
@reconstructor
|
||||||
|
def init_on_load(self):
|
||||||
|
self.name = self.player.name
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getPosition(hand, seat):
|
||||||
|
"""Returns position value like 'B', 'S', '0', '1', ...
|
||||||
|
|
||||||
|
>>> class A(object): pass
|
||||||
|
...
|
||||||
|
>>> A.noSb = False
|
||||||
|
>>> A.maxseats = 6
|
||||||
|
>>> A.buttonpos = 2
|
||||||
|
>>> A.gametype = {'base': 'hold'}
|
||||||
|
>>> A.players = [(i, None, None) for i in (2, 4, 5, 6)]
|
||||||
|
>>> HandPlayer.getPosition(A, 6) # cut off
|
||||||
|
'1'
|
||||||
|
>>> HandPlayer.getPosition(A, 2) # button
|
||||||
|
'0'
|
||||||
|
>>> HandPlayer.getPosition(A, 4) # SB
|
||||||
|
'S'
|
||||||
|
>>> HandPlayer.getPosition(A, 5) # BB
|
||||||
|
'B'
|
||||||
|
>>> A.noSb = True
|
||||||
|
>>> HandPlayer.getPosition(A, 5) # MP3
|
||||||
|
'2'
|
||||||
|
>>> HandPlayer.getPosition(A, 6) # cut off
|
||||||
|
'1'
|
||||||
|
>>> HandPlayer.getPosition(A, 2) # button
|
||||||
|
'0'
|
||||||
|
>>> HandPlayer.getPosition(A, 4) # BB
|
||||||
|
'B'
|
||||||
|
"""
|
||||||
|
from itertools import chain
|
||||||
|
if hand.gametype['base'] == 'stud':
|
||||||
|
# FIXME: i've never played stud so plz check & del comment \\grindi
|
||||||
|
bringin = None
|
||||||
|
for action in chain(*[self.actions[street] for street in hand.allStreets]):
|
||||||
|
if action[1]=='bringin':
|
||||||
|
bringin = action[0]
|
||||||
|
break
|
||||||
|
if bringin is None:
|
||||||
|
raise Exception, "Cannot find bringin"
|
||||||
|
# name -> seat
|
||||||
|
bringin = int(filter(lambda p: p[1]==bringin, bringin)[0])
|
||||||
|
seat = (int(seat) - int(bringin))%int(hand.maxseats)
|
||||||
|
return str(seat)
|
||||||
|
else:
|
||||||
|
seats_occupied = sorted([seat_ for seat_, name, chips in hand.players], key=int)
|
||||||
|
if hand.buttonpos not in seats_occupied:
|
||||||
|
# i.e. something like
|
||||||
|
# Seat 3: PlayerX ($0), is sitting out
|
||||||
|
# The button is in seat #3
|
||||||
|
hand.buttonpos = max(seats_occupied,
|
||||||
|
key = lambda s: int(s)
|
||||||
|
if int(s) <= int(hand.buttonpos)
|
||||||
|
else int(s) - int(hand.maxseats)
|
||||||
|
)
|
||||||
|
seats_occupied = sorted(seats_occupied,
|
||||||
|
key = lambda seat_: (
|
||||||
|
- seats_occupied.index(seat_)
|
||||||
|
+ seats_occupied.index(hand.buttonpos)
|
||||||
|
+ 2) % len(seats_occupied)
|
||||||
|
)
|
||||||
|
# now (if SB presents) seats_occupied contains seats in order: BB, SB, BU, CO, MP3, ...
|
||||||
|
if hand.noSb:
|
||||||
|
# fix order in the case nosb
|
||||||
|
seats_occupied = seats_occupied[1:] + seats_occupied[0:1]
|
||||||
|
seats_occupied.insert(1, -1)
|
||||||
|
seat = seats_occupied.index(seat)
|
||||||
|
if seat == 0:
|
||||||
|
return 'B'
|
||||||
|
elif seat == 1:
|
||||||
|
return 'S'
|
||||||
|
else:
|
||||||
|
return str(seat-2)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cards(self):
|
||||||
|
cards = []
|
||||||
|
for i in range(7):
|
||||||
|
cards.append(getattr(self, 'card%d' % (i+1), None))
|
||||||
|
return filter(bool, cards)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
s = list()
|
||||||
|
for i in self._sa_class_manager.mapper.c:
|
||||||
|
s.append('%45s %s' % (i, getattr(self, i.name)))
|
||||||
|
return '\n'.join(s)
|
||||||
|
|
||||||
|
|
||||||
|
class Site(object):
|
||||||
|
"""Class reflecting Players db table"""
|
||||||
|
INITIAL_DATA = [
|
||||||
|
(1 , 'Full Tilt Poker','USD'),
|
||||||
|
(2 , 'PokerStars', 'USD'),
|
||||||
|
(3 , 'Everleaf', 'USD'),
|
||||||
|
(4 , 'Win2day', 'USD'),
|
||||||
|
(5 , 'OnGame', 'USD'),
|
||||||
|
(6 , 'UltimateBet', 'USD'),
|
||||||
|
(7 , 'Betfair', 'USD'),
|
||||||
|
(8 , 'Absolute', 'USD'),
|
||||||
|
(9 , 'PartyPoker', 'USD'),
|
||||||
|
(10, 'Partouche', 'EUR'),
|
||||||
|
]
|
||||||
|
INITIAL_DATA_KEYS = ('id', 'name', 'currency')
|
||||||
|
|
||||||
|
INITIAL_DATA_DICTS = [ dict(zip(INITIAL_DATA_KEYS, datum)) for datum in INITIAL_DATA ]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def insert_initial(cls, connection):
|
||||||
|
connection.execute(sites_table.insert(), cls.INITIAL_DATA_DICTS)
|
||||||
|
|
||||||
|
|
||||||
|
class Tourney(MappedBase):
|
||||||
|
"""Class reflecting Tourneys db table"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_or_create(cls, session, siteTourneyNo, tourneyTypeId):
|
||||||
|
"""Fetch tourney by index or creates one if none. """
|
||||||
|
return get_or_create(cls, session, siteTourneyNo=siteTourneyNo,
|
||||||
|
tourneyTypeId=tourneyTypeId)[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TourneyType(MappedBase):
|
||||||
|
"""Class reflecting TourneysType db table"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_or_create(cls, session, **kwargs):
|
||||||
|
"""Fetch tourney type by index or creates one if none
|
||||||
|
|
||||||
|
Required kwargs:
|
||||||
|
buyin fee speed maxSeats knockout
|
||||||
|
rebuyOrAddon headsUp shootout matrix sng
|
||||||
|
"""
|
||||||
|
return get_or_create(cls, session, **kwargs)[0]
|
||||||
|
|
||||||
|
|
||||||
|
class TourneyPlayer(MappedBase):
|
||||||
|
"""Class reflecting TourneysPlayers db table"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_or_create(cls, session, tourneyId, playerId):
|
||||||
|
"""Fetch tourney player by index or creates one if none """
|
||||||
|
return get_or_create(cls, session, tourneyId=tourneyId, playerId=playerId)
|
||||||
|
|
||||||
|
|
||||||
|
class Version(object):
|
||||||
|
"""Provides read/write access for version var"""
|
||||||
|
CURRENT_VERSION = 120 # db version for current release
|
||||||
|
# 119 - first alchemy version
|
||||||
|
# 120 - add m_factor
|
||||||
|
|
||||||
|
conn = None
|
||||||
|
ver = None
|
||||||
|
def __init__(self, connection=None):
|
||||||
|
if self.__class__.conn is None:
|
||||||
|
self.__class__.conn = connection
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_wrong(cls):
|
||||||
|
return cls.get() != cls.CURRENT_VERSION
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get(cls):
|
||||||
|
if cls.ver is None:
|
||||||
|
try:
|
||||||
|
cls.ver = cls.conn.execute(select(['version'], settings_table)).fetchone()[0]
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
return cls.ver
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set(cls, value):
|
||||||
|
if cls.conn.execute(settings_table.select()).rowcount==0:
|
||||||
|
cls.conn.execute(settings_table.insert(), version=value)
|
||||||
|
else:
|
||||||
|
cls.conn.execute(settings_table.update().values(version=value))
|
||||||
|
cls.ver = value
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_initial(cls):
|
||||||
|
cls.set(cls.CURRENT_VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
mapper (Gametype, gametypes_table, properties={
|
||||||
|
'hands': relation(HandInternal, backref='gametype'),
|
||||||
|
})
|
||||||
|
mapper (Player, players_table, properties={
|
||||||
|
'playerHands': relation(HandPlayer, backref='player'),
|
||||||
|
'playerTourney': relation(TourneyPlayer, backref='player'),
|
||||||
|
})
|
||||||
|
mapper (Site, sites_table, properties={
|
||||||
|
'gametypes': relation(Gametype, backref = 'site'),
|
||||||
|
'players': relation(Player, backref = 'site'),
|
||||||
|
'tourneyTypes': relation(TourneyType, backref = 'site'),
|
||||||
|
})
|
||||||
|
mapper (HandActions, hands_actions_table, properties={})
|
||||||
|
mapper (HandInternal, hands_table, properties={
|
||||||
|
'handPlayers': relation(HandPlayer, backref='hand'),
|
||||||
|
'actions_all': relation(HandActions, backref='hand', uselist=False),
|
||||||
|
})
|
||||||
|
mapper (HandPlayer, hands_players_table, properties={})
|
||||||
|
|
||||||
|
mapper (Tourney, tourneys_table)
|
||||||
|
mapper (TourneyType, tourney_types_table, properties={
|
||||||
|
'tourneys': relation(Tourney, backref='type'),
|
||||||
|
})
|
||||||
|
mapper (TourneyPlayer, tourneys_players_table)
|
||||||
|
|
||||||
|
class LambdaKeyDict(defaultdict):
|
||||||
|
"""Operates like defaultdict but passes key argument to the factory function"""
|
||||||
|
def __missing__(key):
|
||||||
|
return self.default_factory(key)
|
||||||
|
|
438
pyfpdb/AlchemyTables.py
Normal file
438
pyfpdb/AlchemyTables.py
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""@package AlchemyTables
|
||||||
|
Contains all sqlalchemy tables
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sqlalchemy import Table, Float, Column, Integer, String, MetaData, \
|
||||||
|
ForeignKey, Boolean, SmallInteger, DateTime, Text, Index, CHAR, \
|
||||||
|
PickleType, Unicode
|
||||||
|
|
||||||
|
from AlchemyFacilities import CardColumn, MoneyColumn, BigIntColumn
|
||||||
|
|
||||||
|
|
||||||
|
metadata = MetaData()
|
||||||
|
|
||||||
|
|
||||||
|
autorates_table = Table('Autorates', metadata,
|
||||||
|
Column('id', Integer, primary_key=True, nullable=False),
|
||||||
|
Column('playerId', Integer, ForeignKey("Players.id"), nullable=False),
|
||||||
|
Column('gametypeId', SmallInteger, ForeignKey("Gametypes.id"), nullable=False),
|
||||||
|
Column('description', String(50), nullable=False),
|
||||||
|
Column('shortDesc', CHAR(8), nullable=False),
|
||||||
|
Column('ratingTime', DateTime, nullable=False),
|
||||||
|
Column('handCount', Integer, nullable=False),
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
gametypes_table = Table('Gametypes', metadata,
|
||||||
|
Column('id', SmallInteger, primary_key=True),
|
||||||
|
Column('siteId', SmallInteger, ForeignKey("Sites.id"), nullable=False), # SMALLINT
|
||||||
|
Column('type', String(4), nullable=False), # char(4) NOT NULL
|
||||||
|
Column('base', String(4), nullable=False), # char(4) NOT NULL
|
||||||
|
Column('category', String(9), nullable=False), # varchar(9) NOT NULL
|
||||||
|
Column('limitType', CHAR(2), nullable=False), # char(2) NOT NULL
|
||||||
|
Column('hiLo', CHAR(1), nullable=False), # char(1) NOT NULL
|
||||||
|
Column('smallBlind', Integer(3)), # int
|
||||||
|
Column('bigBlind', Integer(3)), # int
|
||||||
|
Column('smallBet', Integer(3), nullable=False), # int NOT NULL
|
||||||
|
Column('bigBet', Integer(3), nullable=False), # int NOT NULL
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
hands_table = Table('Hands', metadata,
|
||||||
|
Column('id', BigIntColumn, primary_key=True),
|
||||||
|
Column('tableName', String(30), nullable=False),
|
||||||
|
Column('siteHandNo', BigIntColumn, nullable=False),
|
||||||
|
Column('gametypeId', SmallInteger, ForeignKey('Gametypes.id'), nullable=False),
|
||||||
|
Column('handStart', DateTime, nullable=False),
|
||||||
|
Column('importTime', DateTime, nullable=False),
|
||||||
|
Column('seats', SmallInteger, nullable=False),
|
||||||
|
Column('maxSeats', SmallInteger, nullable=False),
|
||||||
|
|
||||||
|
Column('boardcard1', CardColumn),
|
||||||
|
Column('boardcard2', CardColumn),
|
||||||
|
Column('boardcard3', CardColumn),
|
||||||
|
Column('boardcard4', CardColumn),
|
||||||
|
Column('boardcard5', CardColumn),
|
||||||
|
Column('texture', SmallInteger),
|
||||||
|
Column('playersVpi', SmallInteger, nullable=False),
|
||||||
|
Column('playersAtStreet1', SmallInteger, nullable=False, default=0),
|
||||||
|
Column('playersAtStreet2', SmallInteger, nullable=False, default=0),
|
||||||
|
Column('playersAtStreet3', SmallInteger, nullable=False, default=0),
|
||||||
|
Column('playersAtStreet4', SmallInteger, nullable=False, default=0),
|
||||||
|
Column('playersAtShowdown',SmallInteger, nullable=False),
|
||||||
|
Column('street0Raises', SmallInteger, nullable=False),
|
||||||
|
Column('street1Raises', SmallInteger, nullable=False),
|
||||||
|
Column('street2Raises', SmallInteger, nullable=False),
|
||||||
|
Column('street3Raises', SmallInteger, nullable=False),
|
||||||
|
Column('street4Raises', SmallInteger, nullable=False),
|
||||||
|
Column('street1Pot', MoneyColumn),
|
||||||
|
Column('street2Pot', MoneyColumn),
|
||||||
|
Column('street3Pot', MoneyColumn),
|
||||||
|
Column('street4Pot', MoneyColumn),
|
||||||
|
Column('showdownPot', MoneyColumn),
|
||||||
|
Column('comment', Text),
|
||||||
|
Column('commentTs', DateTime),
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
Index('siteHandNo', hands_table.c.siteHandNo, hands_table.c.gametypeId, unique=True)
|
||||||
|
|
||||||
|
|
||||||
|
hands_actions_table = Table('HandsActions', metadata,
|
||||||
|
Column('id', BigIntColumn, primary_key=True, nullable=False),
|
||||||
|
Column('handId', BigIntColumn, ForeignKey("Hands.id"), nullable=False),
|
||||||
|
Column('actions', PickleType, nullable=False),
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
hands_players_table = Table('HandsPlayers', metadata,
|
||||||
|
Column('id', BigIntColumn, primary_key=True),
|
||||||
|
Column('handId', BigIntColumn, ForeignKey("Hands.id"), nullable=False),
|
||||||
|
Column('playerId', Integer, ForeignKey("Players.id"), nullable=False),
|
||||||
|
Column('startCash', MoneyColumn),
|
||||||
|
Column('position', CHAR(1)), #CHAR(1)
|
||||||
|
Column('seatNo', SmallInteger, nullable=False), #SMALLINT NOT NULL
|
||||||
|
|
||||||
|
Column('card1', CardColumn), #smallint NOT NULL,
|
||||||
|
Column('card2', CardColumn), #smallint NOT NULL
|
||||||
|
Column('card3', CardColumn), #smallint
|
||||||
|
Column('card4', CardColumn), #smallint
|
||||||
|
Column('card5', CardColumn), #smallint
|
||||||
|
Column('card6', CardColumn), #smallint
|
||||||
|
Column('card7', CardColumn), #smallint
|
||||||
|
Column('startCards', SmallInteger), #smallint
|
||||||
|
|
||||||
|
Column('m_factor', Integer), # null for ring games
|
||||||
|
Column('ante', MoneyColumn), #INT
|
||||||
|
Column('winnings', MoneyColumn, nullable=False, default=0), #int NOT NULL
|
||||||
|
Column('rake', MoneyColumn, nullable=False, default=0), #int NOT NULL
|
||||||
|
Column('totalProfit', MoneyColumn), #INT
|
||||||
|
Column('comment', Text), #text
|
||||||
|
Column('commentTs', DateTime), #DATETIME
|
||||||
|
Column('tourneysPlayersId', BigIntColumn, ForeignKey("TourneysPlayers.id"),), #BIGINT UNSIGNED
|
||||||
|
Column('tourneyTypeId', Integer, ForeignKey("TourneyTypes.id"),), #SMALLINT UNSIGNED
|
||||||
|
|
||||||
|
Column('wonWhenSeenStreet1',Float), #FLOAT
|
||||||
|
Column('wonWhenSeenStreet2',Float), #FLOAT
|
||||||
|
Column('wonWhenSeenStreet3',Float), #FLOAT
|
||||||
|
Column('wonWhenSeenStreet4',Float), #FLOAT
|
||||||
|
Column('wonAtSD', Float), #FLOAT
|
||||||
|
|
||||||
|
Column('street0VPI', Boolean), #BOOLEAN
|
||||||
|
Column('street0Aggr', Boolean), #BOOLEAN
|
||||||
|
Column('street0_3BChance', Boolean), #BOOLEAN
|
||||||
|
Column('street0_3BDone', Boolean), #BOOLEAN
|
||||||
|
Column('street0_4BChance', Boolean), #BOOLEAN
|
||||||
|
Column('street0_4BDone', Boolean), #BOOLEAN
|
||||||
|
Column('other3BStreet0', Boolean), #BOOLEAN
|
||||||
|
Column('other4BStreet0', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('street1Seen', Boolean), #BOOLEAN
|
||||||
|
Column('street2Seen', Boolean), #BOOLEAN
|
||||||
|
Column('street3Seen', Boolean), #BOOLEAN
|
||||||
|
Column('street4Seen', Boolean), #BOOLEAN
|
||||||
|
Column('sawShowdown', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('street1Aggr', Boolean), #BOOLEAN
|
||||||
|
Column('street2Aggr', Boolean), #BOOLEAN
|
||||||
|
Column('street3Aggr', Boolean), #BOOLEAN
|
||||||
|
Column('street4Aggr', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('otherRaisedStreet0',Boolean), #BOOLEAN
|
||||||
|
Column('otherRaisedStreet1',Boolean), #BOOLEAN
|
||||||
|
Column('otherRaisedStreet2',Boolean), #BOOLEAN
|
||||||
|
Column('otherRaisedStreet3',Boolean), #BOOLEAN
|
||||||
|
Column('otherRaisedStreet4',Boolean), #BOOLEAN
|
||||||
|
Column('foldToOtherRaisedStreet0', Boolean), #BOOLEAN
|
||||||
|
Column('foldToOtherRaisedStreet1', Boolean), #BOOLEAN
|
||||||
|
Column('foldToOtherRaisedStreet2', Boolean), #BOOLEAN
|
||||||
|
Column('foldToOtherRaisedStreet3', Boolean), #BOOLEAN
|
||||||
|
Column('foldToOtherRaisedStreet4', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('stealAttemptChance', Boolean), #BOOLEAN
|
||||||
|
Column('stealAttempted', Boolean), #BOOLEAN
|
||||||
|
Column('foldBbToStealChance', Boolean), #BOOLEAN
|
||||||
|
Column('foldedBbToSteal', Boolean), #BOOLEAN
|
||||||
|
Column('foldSbToStealChance', Boolean), #BOOLEAN
|
||||||
|
Column('foldedSbToSteal', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('street1CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('street1CBDone', Boolean), #BOOLEAN
|
||||||
|
Column('street2CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('street2CBDone', Boolean), #BOOLEAN
|
||||||
|
Column('street3CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('street3CBDone', Boolean), #BOOLEAN
|
||||||
|
Column('street4CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('street4CBDone', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('foldToStreet1CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('foldToStreet1CBDone', Boolean), #BOOLEAN
|
||||||
|
Column('foldToStreet2CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('foldToStreet2CBDone', Boolean), #BOOLEAN
|
||||||
|
Column('foldToStreet3CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('foldToStreet3CBDone', Boolean), #BOOLEAN
|
||||||
|
Column('foldToStreet4CBChance', Boolean), #BOOLEAN
|
||||||
|
Column('foldToStreet4CBDone', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('street1CheckCallRaiseChance',Boolean), #BOOLEAN
|
||||||
|
Column('street1CheckCallRaiseDone', Boolean), #BOOLEAN
|
||||||
|
Column('street2CheckCallRaiseChance',Boolean), #BOOLEAN
|
||||||
|
Column('street2CheckCallRaiseDone', Boolean), #BOOLEAN
|
||||||
|
Column('street3CheckCallRaiseChance',Boolean), #BOOLEAN
|
||||||
|
Column('street3CheckCallRaiseDone', Boolean), #BOOLEAN
|
||||||
|
Column('street4CheckCallRaiseChance',Boolean), #BOOLEAN
|
||||||
|
Column('street4CheckCallRaiseDone', Boolean), #BOOLEAN
|
||||||
|
|
||||||
|
Column('street0Calls', SmallInteger), #TINYINT
|
||||||
|
Column('street1Calls', SmallInteger), #TINYINT
|
||||||
|
Column('street2Calls', SmallInteger), #TINYINT
|
||||||
|
Column('street3Calls', SmallInteger), #TINYINT
|
||||||
|
Column('street4Calls', SmallInteger), #TINYINT
|
||||||
|
Column('street0Bets', SmallInteger), #TINYINT
|
||||||
|
Column('street1Bets', SmallInteger), #TINYINT
|
||||||
|
Column('street2Bets', SmallInteger), #TINYINT
|
||||||
|
Column('street3Bets', SmallInteger), #TINYINT
|
||||||
|
Column('street4Bets', SmallInteger), #TINYINT
|
||||||
|
Column('street0Raises', SmallInteger), #TINYINT
|
||||||
|
Column('street1Raises', SmallInteger), #TINYINT
|
||||||
|
Column('street2Raises', SmallInteger), #TINYINT
|
||||||
|
Column('street3Raises', SmallInteger), #TINYINT
|
||||||
|
Column('street4Raises', SmallInteger), #TINYINT
|
||||||
|
|
||||||
|
Column('actionString', String(15)), #VARCHAR(15)
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
hud_cache_table = Table('HudCache', metadata,
|
||||||
|
Column('id', BigIntColumn, primary_key=True),
|
||||||
|
Column('gametypeId', SmallInteger, ForeignKey("Gametypes.id"), nullable=False), # SMALLINT
|
||||||
|
Column('playerId', Integer, ForeignKey("Players.id"), nullable=False), # SMALLINT
|
||||||
|
Column('activeSeats', SmallInteger, nullable=False), # SMALLINT NOT NULL
|
||||||
|
Column('position', CHAR(1)), # CHAR(1)
|
||||||
|
Column('tourneyTypeId', Integer, ForeignKey("TourneyTypes.id") ), # SMALLINT
|
||||||
|
Column('styleKey', CHAR(7), nullable=False), # CHAR(7) NOT NULL
|
||||||
|
Column('m_factor', Integer),
|
||||||
|
Column('HDs', Integer, nullable=False), # INT NOT NULL
|
||||||
|
|
||||||
|
Column('wonWhenSeenStreet1', Float), # FLOAT
|
||||||
|
Column('wonWhenSeenStreet2', Float), # FLOAT
|
||||||
|
Column('wonWhenSeenStreet3', Float), # FLOAT
|
||||||
|
Column('wonWhenSeenStreet4', Float), # FLOAT
|
||||||
|
Column('wonAtSD', Float), # FLOAT
|
||||||
|
|
||||||
|
Column('street0VPI', Integer), # INT
|
||||||
|
Column('street0Aggr', Integer), # INT
|
||||||
|
Column('street0_3BChance', Integer), # INT
|
||||||
|
Column('street0_3BDone', Integer), # INT
|
||||||
|
Column('street0_4BChance', Integer), # INT
|
||||||
|
Column('street0_4BDone', Integer), # INT
|
||||||
|
Column('other3BStreet0', Integer), # INT
|
||||||
|
Column('other4BStreet0', Integer), # INT
|
||||||
|
|
||||||
|
Column('street1Seen', Integer), # INT
|
||||||
|
Column('street2Seen', Integer), # INT
|
||||||
|
Column('street3Seen', Integer), # INT
|
||||||
|
Column('street4Seen', Integer), # INT
|
||||||
|
Column('sawShowdown', Integer), # INT
|
||||||
|
|
||||||
|
Column('street1Aggr', Integer), # INT
|
||||||
|
Column('street2Aggr', Integer), # INT
|
||||||
|
Column('street3Aggr', Integer), # INT
|
||||||
|
Column('street4Aggr', Integer), # INT
|
||||||
|
|
||||||
|
Column('otherRaisedStreet0', Integer), # INT
|
||||||
|
Column('otherRaisedStreet1', Integer), # INT
|
||||||
|
Column('otherRaisedStreet2', Integer), # INT
|
||||||
|
Column('otherRaisedStreet3', Integer), # INT
|
||||||
|
Column('otherRaisedStreet4', Integer), # INT
|
||||||
|
Column('foldToOtherRaisedStreet0', Integer), # INT
|
||||||
|
Column('foldToOtherRaisedStreet1', Integer), # INT
|
||||||
|
Column('foldToOtherRaisedStreet2', Integer), # INT
|
||||||
|
Column('foldToOtherRaisedStreet3', Integer), # INT
|
||||||
|
Column('foldToOtherRaisedStreet4', Integer), # INT
|
||||||
|
|
||||||
|
Column('stealAttemptChance', Integer), # INT
|
||||||
|
Column('stealAttempted', Integer), # INT
|
||||||
|
Column('foldBbToStealChance', Integer), # INT
|
||||||
|
Column('foldedBbToSteal', Integer), # INT
|
||||||
|
Column('foldSbToStealChance', Integer), # INT
|
||||||
|
Column('foldedSbToSteal', Integer), # INT
|
||||||
|
|
||||||
|
Column('street1CBChance', Integer), # INT
|
||||||
|
Column('street1CBDone', Integer), # INT
|
||||||
|
Column('street2CBChance', Integer), # INT
|
||||||
|
Column('street2CBDone', Integer), # INT
|
||||||
|
Column('street3CBChance', Integer), # INT
|
||||||
|
Column('street3CBDone', Integer), # INT
|
||||||
|
Column('street4CBChance', Integer), # INT
|
||||||
|
Column('street4CBDone', Integer), # INT
|
||||||
|
|
||||||
|
Column('foldToStreet1CBChance', Integer), # INT
|
||||||
|
Column('foldToStreet1CBDone', Integer), # INT
|
||||||
|
Column('foldToStreet2CBChance', Integer), # INT
|
||||||
|
Column('foldToStreet2CBDone', Integer), # INT
|
||||||
|
Column('foldToStreet3CBChance', Integer), # INT
|
||||||
|
Column('foldToStreet3CBDone', Integer), # INT
|
||||||
|
Column('foldToStreet4CBChance', Integer), # INT
|
||||||
|
Column('foldToStreet4CBDone', Integer), # INT
|
||||||
|
|
||||||
|
Column('totalProfit', Integer), # INT
|
||||||
|
|
||||||
|
Column('street1CheckCallRaiseChance', Integer), # INT
|
||||||
|
Column('street1CheckCallRaiseDone', Integer), # INT
|
||||||
|
Column('street2CheckCallRaiseChance', Integer), # INT
|
||||||
|
Column('street2CheckCallRaiseDone', Integer), # INT
|
||||||
|
Column('street3CheckCallRaiseChance', Integer), # INT
|
||||||
|
Column('street3CheckCallRaiseDone', Integer), # INT
|
||||||
|
Column('street4CheckCallRaiseChance', Integer), # INT
|
||||||
|
Column('street4CheckCallRaiseDone', Integer), # INT
|
||||||
|
|
||||||
|
Column('street0Calls', Integer), # INT
|
||||||
|
Column('street1Calls', Integer), # INT
|
||||||
|
Column('street2Calls', Integer), # INT
|
||||||
|
Column('street3Calls', Integer), # INT
|
||||||
|
Column('street4Calls', Integer), # INT
|
||||||
|
Column('street0Bets', Integer), # INT
|
||||||
|
Column('street1Bets', Integer), # INT
|
||||||
|
Column('street2Bets', Integer), # INT
|
||||||
|
Column('street3Bets', Integer), # INT
|
||||||
|
Column('street4Bets', Integer), # INT
|
||||||
|
Column('street0Raises', Integer), # INT
|
||||||
|
Column('street1Raises', Integer), # INT
|
||||||
|
Column('street2Raises', Integer), # INT
|
||||||
|
Column('street3Raises', Integer), # INT
|
||||||
|
Column('street4Raises', Integer), # INT
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
players_table = Table('Players', metadata,
|
||||||
|
Column('id', Integer, primary_key=True),
|
||||||
|
Column('name', Unicode(32), nullable=False), # VARCHAR(32) CHARACTER SET utf8 NOT NULL
|
||||||
|
Column('siteId', SmallInteger, ForeignKey("Sites.id"), nullable=False), # SMALLINT
|
||||||
|
Column('comment', Text), # text
|
||||||
|
Column('commentTs', DateTime), # DATETIME
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
Index('name', players_table.c.name, players_table.c.siteId, unique=True)
|
||||||
|
|
||||||
|
|
||||||
|
settings_table = Table('Settings', metadata,
|
||||||
|
Column('version', SmallInteger, nullable=False),
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
sites_table = Table('Sites', metadata,
|
||||||
|
Column('id', SmallInteger, primary_key=True),
|
||||||
|
Column('name', String(32), nullable=False), # varchar(32) NOT NULL
|
||||||
|
Column('currency', String(3), nullable=False), # char(3) NOT NULL
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
tourneys_table = Table('Tourneys', metadata,
|
||||||
|
Column('id', Integer, primary_key=True),
|
||||||
|
Column('tourneyTypeId', Integer, ForeignKey("TourneyTypes.id"), nullable=False, default=1),
|
||||||
|
Column('siteTourneyNo', BigIntColumn, nullable=False), # BIGINT NOT NULL
|
||||||
|
Column('entries', Integer), # INT NOT NULL
|
||||||
|
Column('prizepool', Integer), # INT NOT NULL
|
||||||
|
Column('tourStartTime', DateTime), # DATETIME NOT NULL
|
||||||
|
Column('tourEndTime', DateTime), # DATETIME
|
||||||
|
Column('buyinChips', Integer), # INT
|
||||||
|
Column('tourneyName', String(40)), # varchar(40)
|
||||||
|
# Mask use : 1=Positionnal Winnings|2=Match1|4=Match2|...|pow(2,n)=Matchn
|
||||||
|
Column('matrixIdProcessed',SmallInteger, default=0), # TINYINT UNSIGNED DEFAULT 0
|
||||||
|
Column('rebuyChips', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('addonChips', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('rebuyAmount', MoneyColumn, default=0), # INT DEFAULT 0
|
||||||
|
Column('addonAmount', MoneyColumn, default=0), # INT DEFAULT 0
|
||||||
|
Column('totalRebuys', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('totalAddons', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('koBounty', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('comment', Text), # TEXT
|
||||||
|
Column('commentTs', DateTime), # DATETIME
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
Index('siteTourneyNo', tourneys_table.c.siteTourneyNo, tourneys_table.c.tourneyTypeId, unique=True)
|
||||||
|
|
||||||
|
|
||||||
|
tourney_types_table = Table('TourneyTypes', metadata,
|
||||||
|
Column('id', Integer, primary_key=True),
|
||||||
|
Column('siteId', SmallInteger, ForeignKey("Sites.id"), nullable=False),
|
||||||
|
Column('buyin', Integer, nullable=False), # INT NOT NULL
|
||||||
|
Column('fee', Integer, nullable=False, default=0), # INT NOT NULL
|
||||||
|
Column('maxSeats', Boolean, nullable=False, default=-1), # INT NOT NULL DEFAULT -1
|
||||||
|
Column('knockout', Boolean, nullable=False, default=False), # BOOLEAN NOT NULL DEFAULT False
|
||||||
|
Column('rebuyOrAddon', Boolean, nullable=False, default=False), # BOOLEAN NOT NULL DEFAULT False
|
||||||
|
Column('speed', String(10)), # varchar(10)
|
||||||
|
Column('headsUp', Boolean, nullable=False, default=False), # BOOLEAN NOT NULL DEFAULT False
|
||||||
|
Column('shootout', Boolean, nullable=False, default=False), # BOOLEAN NOT NULL DEFAULT False
|
||||||
|
Column('matrix', Boolean, nullable=False, default=False), # BOOLEAN NOT NULL DEFAULT False
|
||||||
|
Column('sng', Boolean, nullable=False, default=False), # BOOLEAN NOT NULL DEFAULT False
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
Index('tourneyTypes_all',
|
||||||
|
tourney_types_table.c.siteId, tourney_types_table.c.buyin, tourney_types_table.c.fee,
|
||||||
|
tourney_types_table.c.maxSeats, tourney_types_table.c.knockout, tourney_types_table.c.rebuyOrAddon,
|
||||||
|
tourney_types_table.c.speed, tourney_types_table.c.headsUp, tourney_types_table.c.shootout,
|
||||||
|
tourney_types_table.c.matrix, tourney_types_table.c.sng)
|
||||||
|
|
||||||
|
|
||||||
|
tourneys_players_table = Table('TourneysPlayers', metadata,
|
||||||
|
Column('id', BigIntColumn, primary_key=True),
|
||||||
|
Column('tourneyId', Integer, ForeignKey("Tourneys.id"), nullable=False),
|
||||||
|
Column('playerId', Integer, ForeignKey("Players.id"), nullable=False),
|
||||||
|
Column('payinAmount', Integer), # INT NOT NULL
|
||||||
|
Column('rank', Integer), # INT NOT NULL
|
||||||
|
Column('winnings', Integer), # INT NOT NULL
|
||||||
|
Column('nbRebuys', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('nbAddons', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('nbKO', Integer, default=0), # INT DEFAULT 0
|
||||||
|
Column('comment', Text), # TEXT
|
||||||
|
Column('commentTs', DateTime), # DATETIME
|
||||||
|
mysql_charset='utf8',
|
||||||
|
mysql_engine='InnoDB',
|
||||||
|
)
|
||||||
|
Index('tourneyId', tourneys_players_table.c.tourneyId, tourneys_players_table.c.playerId, unique=True)
|
||||||
|
|
||||||
|
|
||||||
|
def sss():
|
||||||
|
"Debug function. Returns (config, sql, db)"
|
||||||
|
|
||||||
|
import Configuration, SQL, Database, os
|
||||||
|
class Dummy(object):
|
||||||
|
pass
|
||||||
|
self = Dummy()
|
||||||
|
self.config = Configuration.Config()
|
||||||
|
self.settings = {}
|
||||||
|
if (os.sep=="/"):
|
||||||
|
self.settings['os']="linuxmac"
|
||||||
|
else:
|
||||||
|
self.settings['os']="windows"
|
||||||
|
|
||||||
|
self.settings.update(self.config.get_db_parameters())
|
||||||
|
self.settings.update(self.config.get_tv_parameters())
|
||||||
|
self.settings.update(self.config.get_import_parameters())
|
||||||
|
self.settings.update(self.config.get_default_paths())
|
||||||
|
|
||||||
|
self.sql = SQL.Sql( db_server = self.settings['db-server'])
|
||||||
|
self.db = Database.Database(self.config, sql = self.sql)
|
||||||
|
|
||||||
|
return self.config, self.sql, self.db
|
||||||
|
|
|
@ -269,6 +269,10 @@ class Game:
|
||||||
stat.hudprefix = stat_node.getAttribute("hudprefix")
|
stat.hudprefix = stat_node.getAttribute("hudprefix")
|
||||||
stat.hudsuffix = stat_node.getAttribute("hudsuffix")
|
stat.hudsuffix = stat_node.getAttribute("hudsuffix")
|
||||||
stat.hudcolor = stat_node.getAttribute("hudcolor")
|
stat.hudcolor = stat_node.getAttribute("hudcolor")
|
||||||
|
stat.stat_loth = stat_node.getAttribute("stat_loth")
|
||||||
|
stat.stat_hith = stat_node.getAttribute("stat_hith")
|
||||||
|
stat.stat_locolor = stat_node.getAttribute("stat_locolor")
|
||||||
|
stat.stat_hicolor = stat_node.getAttribute("stat_hicolor")
|
||||||
|
|
||||||
self.stats[stat.stat_name] = stat
|
self.stats[stat.stat_name] = stat
|
||||||
|
|
||||||
|
|
|
@ -621,69 +621,6 @@ class Database:
|
||||||
rows = c.fetchall()
|
rows = c.fetchall()
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
#returns the SQL ids of the names given in an array
|
|
||||||
# TODO: if someone gets industrious, they should make the parts that use the output of this function deal with a dict
|
|
||||||
# { playername: id } instead of depending on it's relation to the positions list
|
|
||||||
# then this can be reduced in complexity a bit
|
|
||||||
|
|
||||||
#def recognisePlayerIDs(cursor, names, site_id):
|
|
||||||
# result = []
|
|
||||||
# for i in xrange(len(names)):
|
|
||||||
# cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
|
|
||||||
# tmp=cursor.fetchall()
|
|
||||||
# if (len(tmp)==0): #new player
|
|
||||||
# cursor.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (names[i], site_id))
|
|
||||||
# #print "Number of players rows inserted: %d" % cursor.rowcount
|
|
||||||
# cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
|
|
||||||
# tmp=cursor.fetchall()
|
|
||||||
# #print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
|
|
||||||
# result.append(tmp[0][0])
|
|
||||||
# return result
|
|
||||||
|
|
||||||
def recognisePlayerIDs(self, names, site_id):
|
|
||||||
c = self.get_cursor()
|
|
||||||
q = "SELECT name,id FROM Players WHERE siteid=%d and (name=%s)" %(site_id, " OR name=".join([self.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
|
|
||||||
q_ins = "INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")"
|
|
||||||
q_ins = q_ins.replace('%s', self.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', self.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
|
|
||||||
return [ids[n] for n in names]
|
|
||||||
#end def recognisePlayerIDs
|
|
||||||
|
|
||||||
# Here's a version that would work if it wasn't for the fact that it needs to have the output in the same order as input
|
|
||||||
# this version could also be improved upon using list comprehensions, etc
|
|
||||||
|
|
||||||
#def recognisePlayerIDs(cursor, names, site_id):
|
|
||||||
# result = []
|
|
||||||
# notfound = []
|
|
||||||
# cursor.execute("SELECT name,id FROM Players WHERE name='%s'" % "' OR name='".join(names))
|
|
||||||
# tmp = dict(cursor.fetchall())
|
|
||||||
# for n in names:
|
|
||||||
# if n not in tmp:
|
|
||||||
# notfound.append(n)
|
|
||||||
# else:
|
|
||||||
# result.append(tmp[n])
|
|
||||||
# if notfound:
|
|
||||||
# cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", (notfound))
|
|
||||||
# cursor.execute("SELECT id FROM Players WHERE name='%s'" % "' OR name='".join(notfound))
|
|
||||||
# tmp = cursor.fetchall()
|
|
||||||
# for n in tmp:
|
|
||||||
# result.append(n[0])
|
|
||||||
#
|
|
||||||
# return result
|
|
||||||
|
|
||||||
|
|
||||||
def get_site_id(self, site):
|
def get_site_id(self, site):
|
||||||
c = self.get_cursor()
|
c = self.get_cursor()
|
||||||
c.execute(self.sql.query['getSiteId'], (site,))
|
c.execute(self.sql.query['getSiteId'], (site,))
|
||||||
|
@ -1571,7 +1508,7 @@ class Database:
|
||||||
line[55] = gid # gametypeId
|
line[55] = gid # gametypeId
|
||||||
line[56] = pids[p] # playerId
|
line[56] = pids[p] # playerId
|
||||||
line[57] = len(pids) # activeSeats
|
line[57] = len(pids) # activeSeats
|
||||||
pos = {-2:'B', -1:'S', 0:'D', 1:'C', 2:'M', 3:'M', 4:'M', 5:'E', 6:'E', 7:'E', 8:'E', 9:'E' }
|
pos = {'B':'B', 'S':'S', 0:'D', 1:'C', 2:'M', 3:'M', 4:'M', 5:'E', 6:'E', 7:'E', 8:'E', 9:'E' }
|
||||||
line[58] = pos[pdata[p]['position']]
|
line[58] = pos[pdata[p]['position']]
|
||||||
line[59] = pdata[p]['tourneyTypeId']
|
line[59] = pdata[p]['tourneyTypeId']
|
||||||
line[60] = styleKey # styleKey
|
line[60] = styleKey # styleKey
|
||||||
|
@ -1683,45 +1620,6 @@ class Database:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def storeHands(self, backend, site_hand_no, gametype_id
|
|
||||||
,hand_start_time, names, tableName, maxSeats, hudCache
|
|
||||||
,board_values, board_suits):
|
|
||||||
|
|
||||||
cards = [Card.cardFromValueSuit(v,s) for v,s in zip(board_values,board_suits)]
|
|
||||||
#stores into table hands:
|
|
||||||
try:
|
|
||||||
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 FpdbError( "storeHands error: " + str(sys.exc_value) )
|
|
||||||
|
|
||||||
return ret
|
|
||||||
#end def storeHands
|
|
||||||
|
|
||||||
def store_tourneys_players(self, tourney_id, player_ids, payin_amounts, ranks, winnings):
|
def store_tourneys_players(self, tourney_id, player_ids, payin_amounts, ranks, winnings):
|
||||||
try:
|
try:
|
||||||
result=[]
|
result=[]
|
||||||
|
|
|
@ -48,18 +48,11 @@ class DerivedStats():
|
||||||
self.handsplayers[player[1]]['sawShowdown'] = False
|
self.handsplayers[player[1]]['sawShowdown'] = False
|
||||||
self.handsplayers[player[1]]['wonAtSD'] = 0.0
|
self.handsplayers[player[1]]['wonAtSD'] = 0.0
|
||||||
self.handsplayers[player[1]]['startCards'] = 0
|
self.handsplayers[player[1]]['startCards'] = 0
|
||||||
for i in range(5):
|
|
||||||
self.handsplayers[player[1]]['street%dCalls' % i] = 0
|
|
||||||
self.handsplayers[player[1]]['street%dBets' % i] = 0
|
|
||||||
for i in range(1,5):
|
|
||||||
self.handsplayers[player[1]]['street%dCBChance' %i] = False
|
|
||||||
self.handsplayers[player[1]]['street%dCBDone' %i] = False
|
|
||||||
|
|
||||||
#FIXME - Everything below this point is incomplete.
|
|
||||||
self.handsplayers[player[1]]['position'] = 2
|
self.handsplayers[player[1]]['position'] = 2
|
||||||
self.handsplayers[player[1]]['tourneyTypeId'] = 1
|
|
||||||
self.handsplayers[player[1]]['street0_3BChance'] = False
|
self.handsplayers[player[1]]['street0_3BChance'] = False
|
||||||
self.handsplayers[player[1]]['street0_3BDone'] = False
|
self.handsplayers[player[1]]['street0_3BDone'] = False
|
||||||
|
self.handsplayers[player[1]]['street0_4BChance'] = False
|
||||||
|
self.handsplayers[player[1]]['street0_4BDone'] = False
|
||||||
self.handsplayers[player[1]]['stealAttemptChance'] = False
|
self.handsplayers[player[1]]['stealAttemptChance'] = False
|
||||||
self.handsplayers[player[1]]['stealAttempted'] = False
|
self.handsplayers[player[1]]['stealAttempted'] = False
|
||||||
self.handsplayers[player[1]]['foldBbToStealChance'] = False
|
self.handsplayers[player[1]]['foldBbToStealChance'] = False
|
||||||
|
@ -67,13 +60,22 @@ class DerivedStats():
|
||||||
self.handsplayers[player[1]]['foldSbToStealChance'] = False
|
self.handsplayers[player[1]]['foldSbToStealChance'] = False
|
||||||
self.handsplayers[player[1]]['foldedSbToSteal'] = False
|
self.handsplayers[player[1]]['foldedSbToSteal'] = False
|
||||||
self.handsplayers[player[1]]['foldedBbToSteal'] = False
|
self.handsplayers[player[1]]['foldedBbToSteal'] = False
|
||||||
|
for i in range(5):
|
||||||
|
self.handsplayers[player[1]]['street%dCalls' % i] = 0
|
||||||
|
self.handsplayers[player[1]]['street%dBets' % i] = 0
|
||||||
|
for i in range(1,5):
|
||||||
|
self.handsplayers[player[1]]['street%dCBChance' %i] = False
|
||||||
|
self.handsplayers[player[1]]['street%dCBDone' %i] = False
|
||||||
|
self.handsplayers[player[1]]['street%dCheckCallRaiseChance' %i] = False
|
||||||
|
self.handsplayers[player[1]]['street%dCheckCallRaiseDone' %i] = False
|
||||||
|
|
||||||
|
#FIXME - Everything below this point is incomplete.
|
||||||
|
self.handsplayers[player[1]]['tourneyTypeId'] = 1
|
||||||
for i in range(1,5):
|
for i in range(1,5):
|
||||||
self.handsplayers[player[1]]['otherRaisedStreet%d' %i] = False
|
self.handsplayers[player[1]]['otherRaisedStreet%d' %i] = False
|
||||||
self.handsplayers[player[1]]['foldToOtherRaisedStreet%d' %i] = False
|
self.handsplayers[player[1]]['foldToOtherRaisedStreet%d' %i] = False
|
||||||
self.handsplayers[player[1]]['foldToStreet%dCBChance' %i] = False
|
self.handsplayers[player[1]]['foldToStreet%dCBChance' %i] = False
|
||||||
self.handsplayers[player[1]]['foldToStreet%dCBDone' %i] = False
|
self.handsplayers[player[1]]['foldToStreet%dCBDone' %i] = False
|
||||||
self.handsplayers[player[1]]['street%dCheckCallRaiseChance' %i] = False
|
|
||||||
self.handsplayers[player[1]]['street%dCheckCallRaiseDone' %i] = False
|
|
||||||
|
|
||||||
self.assembleHands(self.hand)
|
self.assembleHands(self.hand)
|
||||||
self.assembleHandsPlayers(self.hand)
|
self.assembleHandsPlayers(self.hand)
|
||||||
|
@ -174,31 +176,44 @@ class DerivedStats():
|
||||||
self.handsplayers[player[1]]['card%s' % (i+1)] = Card.encodeCard(card)
|
self.handsplayers[player[1]]['card%s' % (i+1)] = Card.encodeCard(card)
|
||||||
self.handsplayers[player[1]]['startCards'] = Card.calcStartCards(hand, player[1])
|
self.handsplayers[player[1]]['startCards'] = Card.calcStartCards(hand, player[1])
|
||||||
|
|
||||||
# position,
|
self.setPositions(hand)
|
||||||
#Stud 3rd street card test
|
self.calcCheckCallRaise(hand)
|
||||||
# denny501: brings in for $0.02
|
self.calc34BetStreet0(hand)
|
||||||
# s0rrow: calls $0.02
|
self.calcSteals(hand)
|
||||||
# TomSludge: folds
|
|
||||||
# Soroka69: calls $0.02
|
|
||||||
# rdiezchang: calls $0.02 (Seat 8)
|
|
||||||
# u.pressure: folds (Seat 1)
|
|
||||||
# 123smoothie: calls $0.02
|
|
||||||
# gashpor: calls $0.02
|
|
||||||
|
|
||||||
# Additional stats
|
# Additional stats
|
||||||
# 3betSB, 3betBB
|
# 3betSB, 3betBB
|
||||||
# Squeeze, Ratchet?
|
# Squeeze, Ratchet?
|
||||||
|
|
||||||
|
|
||||||
def getPosition(hand, seat):
|
def setPositions(self, hand):
|
||||||
"""Returns position value like 'B', 'S', 0, 1, ..."""
|
"""Sets the position for each player in HandsPlayers
|
||||||
# Flop/Draw games with blinds
|
any blinds are negative values, and the last person to act on the
|
||||||
# Need a better system???
|
first betting round is 0
|
||||||
# -2 BB - B (all)
|
NOTE: HU, both values are negative for non-stud games
|
||||||
# -1 SB - S (all)
|
NOTE2: I've never seen a HU stud match"""
|
||||||
# 0 Button
|
# The position calculation must be done differently for Stud and other games as
|
||||||
# 1 Cutoff
|
# Stud the 'blind' acts first - in all other games they act last.
|
||||||
# 2 Hijack
|
#
|
||||||
|
#This function is going to get it wrong when there in situations where there
|
||||||
|
# is no small blind. I can live with that.
|
||||||
|
positions = [7, 6, 5, 4, 3, 2, 1, 0, 'S', 'B']
|
||||||
|
actions = hand.actions[hand.holeStreets[0]]
|
||||||
|
players = self.pfbao(actions)
|
||||||
|
seats = len(players)
|
||||||
|
map = []
|
||||||
|
if hand.gametype['base'] == 'stud':
|
||||||
|
# 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
|
||||||
|
else:
|
||||||
|
# For 6 players is should look like:
|
||||||
|
# [3, 2, 1, 0, 'S', 'B']
|
||||||
|
map = positions[-seats:] # Copy required positions from array ending in -2
|
||||||
|
|
||||||
|
for i, player in enumerate(players):
|
||||||
|
self.handsplayers[player]['position'] = map[i]
|
||||||
|
|
||||||
def assembleHudCache(self, hand):
|
def assembleHudCache(self, hand):
|
||||||
# No real work to be done - HandsPlayers data already contains the correct info
|
# No real work to be done - HandsPlayers data already contains the correct info
|
||||||
|
@ -269,28 +284,29 @@ class DerivedStats():
|
||||||
Steal attemp - open raise on positions 2 1 0 S - i.e. MP3, CO, BU, SB
|
Steal attemp - open raise on positions 2 1 0 S - i.e. MP3, CO, BU, SB
|
||||||
Fold to steal - folding blind after steal attemp wo any other callers or raisers
|
Fold to steal - folding blind after steal attemp wo any other callers or raisers
|
||||||
"""
|
"""
|
||||||
if self.gametype_dict['base'] != 'hold':
|
|
||||||
# FIXME: add support for other games //grindi
|
|
||||||
return
|
|
||||||
steal_attemp = False
|
steal_attemp = False
|
||||||
|
steal_positions = ('2', '1', '0', 'S')
|
||||||
|
if hand.gametype['base'] == 'stud':
|
||||||
|
steal_positions = ('2', '1', '0')
|
||||||
for action in hand.actions[hand.actionStreets[1]]:
|
for action in hand.actions[hand.actionStreets[1]]:
|
||||||
hp, act = self.handplayers_by_name[action[0]], action[1]
|
pname, act = action[0], action[1]
|
||||||
#print action[0], hp.position, steal_attemp, act
|
#print action[0], hp.position, steal_attemp, act
|
||||||
if hp.position == 'B':
|
if self.handsplayers[pname]['position'] == 'B':
|
||||||
hp.foldBbToStealChance = steal_attemp
|
#NOTE: Stud games will never hit this section
|
||||||
hp.foldBbToSteal = hp.foldBbToStealChance and act == 'folds'
|
self.handsplayers[pname]['foldBbToStealChance'] = steal_attemp
|
||||||
|
self.handsplayers[pname]['foldBbToSteal'] = self.handsplayers[pname]['foldBbToStealChance'] and act == 'folds'
|
||||||
break
|
break
|
||||||
elif hp.position == 'S':
|
elif self.handsplayers[pname]['position'] == 'S':
|
||||||
hp.foldSbToStealChance = steal_attemp
|
self.handsplayers[pname]['foldSbToStealChance'] = steal_attemp
|
||||||
hp.foldSbToSteal = hp.foldSbToStealChance and act == 'folds'
|
self.handsplayers[pname]['foldSbToSteal'] = self.handsplayers[pname]['foldSbToStealChance'] and act == 'folds'
|
||||||
|
|
||||||
if steal_attemp and act != 'folds':
|
if steal_attemp and act != 'folds':
|
||||||
break
|
break
|
||||||
|
|
||||||
if hp.position in ('2', '1', '0', 'S') and not steal_attemp:
|
if self.handsplayers[pname]['position'] in steal_positions and not steal_attemp:
|
||||||
hp.stealAttemptChance = True
|
self.handsplayers[pname]['stealAttemptChance'] = True
|
||||||
if act in ('bets', 'raises'):
|
if act in ('bets', 'raises'):
|
||||||
hp.stealAttempted = True
|
self.handsplayers[pname]['stealAttempted'] = True
|
||||||
steal_attemp = True
|
steal_attemp = True
|
||||||
|
|
||||||
def calc34BetStreet0(self, hand):
|
def calc34BetStreet0(self, hand):
|
||||||
|
@ -298,11 +314,11 @@ class DerivedStats():
|
||||||
bet_level = 1 # bet_level after 3-bet is equal to 3
|
bet_level = 1 # bet_level after 3-bet is equal to 3
|
||||||
for action in hand.actions[hand.actionStreets[1]]:
|
for action in hand.actions[hand.actionStreets[1]]:
|
||||||
# FIXME: fill other(3|4)BStreet0 - i have no idea what does it mean
|
# FIXME: fill other(3|4)BStreet0 - i have no idea what does it mean
|
||||||
hp, aggr = self.handplayers_by_name[action[0]], action[1] in ('raises', 'bets')
|
pname, aggr = action[0], action[1] in ('raises', 'bets')
|
||||||
hp.street0_3BChance = bet_level == 2
|
self.handsplayers[pname]['street0_3BChance'] = bet_level == 2
|
||||||
hp.street0_4BChance = bet_level == 3
|
self.handsplayers[pname]['street0_4BChance'] = bet_level == 3
|
||||||
hp.street0_3BDone = aggr and (hp.street0_3BChance)
|
self.handsplayers[pname]['street0_3BDone'] = aggr and (self.handsplayers[pname]['street0_3BChance'])
|
||||||
hp.street0_4BDone = aggr and (hp.street0_4BChance)
|
self.handsplayers[pname]['street0_4BDone'] = aggr and (self.handsplayers[pname]['street0_4BChance'])
|
||||||
if aggr:
|
if aggr:
|
||||||
bet_level += 1
|
bet_level += 1
|
||||||
|
|
||||||
|
@ -342,12 +358,11 @@ class DerivedStats():
|
||||||
pname, act = action[0], action[1]
|
pname, act = action[0], action[1]
|
||||||
if act in ('bets', 'raises') and initial_raiser is None:
|
if act in ('bets', 'raises') and initial_raiser is None:
|
||||||
initial_raiser = pname
|
initial_raiser = pname
|
||||||
elif act == 'check' and initial_raiser is None:
|
elif act == 'checks' and initial_raiser is None:
|
||||||
checkers.add(pname)
|
checkers.add(pname)
|
||||||
elif initial_raiser is not None and pname in checkers:
|
elif initial_raiser is not None and pname in checkers:
|
||||||
hp = self.handplayers_by_name[pname]
|
self.handsplayers[pname]['street%dCheckCallRaiseChance' % i] = True
|
||||||
setattr(hp, 'street%dCheckCallRaiseChance' % i, True)
|
self.handsplayers[pname]['street%dCheckCallRaiseDone' % i] = act!='folds'
|
||||||
setattr(hp, 'street%dCheckCallRaiseDone' % i, act!='folds')
|
|
||||||
|
|
||||||
def seen(self, hand, i):
|
def seen(self, hand, i):
|
||||||
pas = set()
|
pas = set()
|
||||||
|
@ -362,11 +377,13 @@ class DerivedStats():
|
||||||
|
|
||||||
def aggr(self, hand, i):
|
def aggr(self, hand, i):
|
||||||
aggrers = set()
|
aggrers = set()
|
||||||
for act in hand.actions[hand.actionStreets[i]]:
|
# Growl - actionStreets contains 'BLINDSANTES', which isn't actually an action street
|
||||||
if act[1] in ('completes', 'raises'):
|
for act in hand.actions[hand.actionStreets[i+1]]:
|
||||||
|
if act[1] in ('completes', 'bets', 'raises'):
|
||||||
aggrers.add(act[0])
|
aggrers.add(act[0])
|
||||||
|
|
||||||
for player in hand.players:
|
for player in hand.players:
|
||||||
|
#print "DEBUG: actionStreet[%s]: %s" %(hand.actionStreets[i+1], i)
|
||||||
if player[1] in aggrers:
|
if player[1] in aggrers:
|
||||||
self.handsplayers[player[1]]['street%sAggr' % i] = True
|
self.handsplayers[player[1]]['street%sAggr' % i] = True
|
||||||
else:
|
else:
|
||||||
|
@ -402,6 +419,23 @@ class DerivedStats():
|
||||||
players.add(action[0])
|
players.add(action[0])
|
||||||
return players
|
return players
|
||||||
|
|
||||||
|
def pfbao(self, actions, f=None, l=None, unique=True):
|
||||||
|
"""Helper method. Returns set of PlayersFilteredByActionsOrdered
|
||||||
|
|
||||||
|
f - forbidden actions
|
||||||
|
l - limited to actions
|
||||||
|
"""
|
||||||
|
# Note, this is an adaptation of function 5 from:
|
||||||
|
# http://www.peterbe.com/plog/uniqifiers-benchmark
|
||||||
|
seen = {}
|
||||||
|
players = []
|
||||||
|
for action in actions:
|
||||||
|
if l is not None and action[1] not in l: continue
|
||||||
|
if f is not None and action[1] in f: continue
|
||||||
|
if action[0] in seen and unique: continue
|
||||||
|
seen[action[0]] = 1
|
||||||
|
players.append(action[0])
|
||||||
|
return players
|
||||||
|
|
||||||
def firstsBetOrRaiser(self, actions):
|
def firstsBetOrRaiser(self, actions):
|
||||||
"""Returns player name that placed the first bet or raise.
|
"""Returns player name that placed the first bet or raise.
|
||||||
|
|
|
@ -448,59 +448,61 @@ Left-Drag to Move"
|
||||||
</supported_sites>
|
</supported_sites>
|
||||||
|
|
||||||
<supported_games>
|
<supported_games>
|
||||||
|
<game aux="mucked" cols="3" db="fpdb" game_name="holdem" rows="3">
|
||||||
<game cols="3" db="fpdb" game_name="holdem" rows="2" aux="mucked">
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" stat_loth="25" stat_locolor ="#408000" stat_hith="40" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" stat_loth="20" stat_locolor ="#408000" stat_hith="35" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="three_B" stat_loth="4" stat_locolor ="#408000" stat_hith="13" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" hudcolor="#98FFB0" hudprefix="" hudsuffix="" popup="default" row="1" stat_name="playername" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="cb1" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="2" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="2" stat_name="steal" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="2" stat_name="totalprofit" stat_loth="0" stat_locolor ="#F05000" stat_hith="0" stat_hicolor ="#408000" tip="tip1"> </stat>
|
||||||
</game>
|
</game>
|
||||||
|
|
||||||
<game cols="3" db="fpdb" game_name="razz" rows="2" aux="stud_mucked">
|
<game aux="stud_mucked" cols="2" db="fpdb" game_name="razz" rows="3">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" hudcolor="#98FFB0" hudprefix="" hudsuffix="" popup="default" row="0" stat_name="playername" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="vpip" stat_loth="20" stat_locolor ="#408000" stat_hith="40" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="2" stat_name="saw_f" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="2" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
</game>
|
</game>
|
||||||
|
|
||||||
<game cols="3" db="fpdb" game_name="omahahi" rows="2" aux="mucked">
|
<game aux="mucked" cols="2" db="fpdb" game_name="omahahi" rows="3">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" hudcolor="#98FFB0" hudprefix="" hudsuffix="" popup="default" row="0" stat_name="playername" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="vpip" stat_loth="20" stat_locolor ="#408000" stat_hith="40" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="2" stat_name="saw_f" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="2" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
</game>
|
</game>
|
||||||
|
|
||||||
<game cols="3" db="fpdb" game_name="omahahilo" rows="2" aux="mucked">
|
<game aux="mucked" cols="2" db="fpdb" game_name="omahahilo" rows="3">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" hudcolor="#98FFB0" hudprefix="" hudsuffix="" popup="default" row="0" stat_name="playername" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="vpip" stat_loth="20" stat_locolor ="#408000" stat_hith="40" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="2" stat_name="saw_f" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="2" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
</game>
|
</game>
|
||||||
|
|
||||||
<game cols="3" db="fpdb" game_name="studhi" rows="2" aux="stud_mucked">
|
<game aux="stud_mucked" cols="2" db="fpdb" game_name="studhi" rows="3">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" hudcolor="#98FFB0" hudprefix="" hudsuffix="" popup="default" row="0" stat_name="playername" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="vpip" stat_loth="20" stat_locolor ="#408000" stat_hith="40" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="2" stat_name="saw_f" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="2" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
</game>
|
</game>
|
||||||
|
|
||||||
<game cols="3" db="fpdb" game_name="studhilo" rows="2" aux="stud_mucked">
|
<game aux="stud_mucked" cols="2" db="fpdb" game_name="studhilo" rows="3">
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" hudcolor="#98FFB0" hudprefix="" hudsuffix="" popup="default" row="0" stat_name="playername" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="n" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="vpip" stat_loth="20" stat_locolor ="#408000" stat_hith="40" stat_hicolor ="#F05000" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="pfr" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="0" popup="default" row="2" stat_name="saw_f" tip="tip1"> </stat>
|
||||||
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
<stat click="tog_decorate" col="1" popup="default" row="2" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
</game>
|
</game>
|
||||||
</supported_games>
|
</supported_games>
|
||||||
|
|
||||||
|
|
|
@ -512,7 +512,7 @@ or None if we fail to get the info """
|
||||||
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
|
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
|
||||||
"Returns string to search in windows titles"
|
"Returns string to search in windows titles"
|
||||||
if type=="tour":
|
if type=="tour":
|
||||||
return "%s.+Table\s%s" % (tournament, table_number)
|
return "%s.+Table.+%s" % (tournament, table_number)
|
||||||
else:
|
else:
|
||||||
return table_name
|
return table_name
|
||||||
|
|
||||||
|
|
|
@ -606,6 +606,7 @@ class Hud:
|
||||||
if self.update_table_position() == False: # we got killed by finding our table was gone
|
if self.update_table_position() == False: # we got killed by finding our table was gone
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
|
||||||
for s in self.stat_dict:
|
for s in self.stat_dict:
|
||||||
try:
|
try:
|
||||||
statd = self.stat_dict[s]
|
statd = self.stat_dict[s]
|
||||||
|
@ -629,8 +630,17 @@ class Hud:
|
||||||
window = self.stat_windows[statd['seat']]
|
window = self.stat_windows[statd['seat']]
|
||||||
|
|
||||||
if this_stat.hudcolor != "":
|
if this_stat.hudcolor != "":
|
||||||
self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
|
|
||||||
window.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor))
|
window.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor))
|
||||||
|
else:
|
||||||
|
window.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
|
||||||
|
|
||||||
|
if this_stat.stat_loth != "":
|
||||||
|
if number[0] < (float(this_stat.stat_loth)/100):
|
||||||
|
window.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.stat_locolor))
|
||||||
|
|
||||||
|
if this_stat.stat_hith != "":
|
||||||
|
if number[0] > (float(this_stat.stat_hith)/100):
|
||||||
|
window.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.stat_hicolor))
|
||||||
|
|
||||||
window.label[r][c].set_text(statstring)
|
window.label[r][c].set_text(statstring)
|
||||||
if statstring != "xxx": # is there a way to tell if this particular stat window is visible already, or no?
|
if statstring != "xxx": # is there a way to tell if this particular stat window is visible already, or no?
|
||||||
|
|
|
@ -160,7 +160,7 @@ def discover_posix_by_name(c, tablename):
|
||||||
|
|
||||||
def discover_posix_tournament(c, t_number, s_number):
|
def discover_posix_tournament(c, t_number, s_number):
|
||||||
"""Finds the X window for a client, given tournament and table nos."""
|
"""Finds the X window for a client, given tournament and table nos."""
|
||||||
search_string = "%s.+Table\s%s" % (t_number, s_number)
|
search_string = "%s.+Table.+%s" % (t_number, s_number)
|
||||||
for listing in os.popen('xwininfo -root -tree').readlines():
|
for listing in os.popen('xwininfo -root -tree').readlines():
|
||||||
if re.search(search_string, listing):
|
if re.search(search_string, listing):
|
||||||
return decode_xwininfo(c, listing)
|
return decode_xwininfo(c, listing)
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
PokerStars Game #37165169101: Hold'em No Limit ($0.10/$0.25 USD) - 2009/12/25 9:50:09 ET
|
||||||
|
Table 'Lucretia IV' 6-max Seat #2 is the button
|
||||||
|
Seat 1: Blåveis ($55.10 in chips)
|
||||||
|
Seat 2: Kinewma ($31.40 in chips)
|
||||||
|
Seat 3: AAALISAAAA ($20.20 in chips)
|
||||||
|
Seat 4: Arbaz ($25 in chips)
|
||||||
|
Seat 5: s0rrow ($29.85 in chips)
|
||||||
|
Seat 6: bys7 ($41.35 in chips)
|
||||||
|
AAALISAAAA: posts small blind $0.10
|
||||||
|
Arbaz: posts big blind $0.25
|
||||||
|
*** HOLE CARDS ***
|
||||||
|
Dealt to s0rrow [Ac As]
|
||||||
|
s0rrow: raises $0.50 to $0.75
|
||||||
|
bys7: calls $0.75
|
||||||
|
Blåveis: folds
|
||||||
|
Kinewma: folds
|
||||||
|
AAALISAAAA: raises $1.50 to $2.25
|
||||||
|
Arbaz: folds
|
||||||
|
s0rrow: raises $3.50 to $5.75
|
||||||
|
bys7: folds
|
||||||
|
AAALISAAAA: raises $14.45 to $20.20 and is all-in
|
||||||
|
s0rrow: calls $14.45
|
||||||
|
*** FLOP *** [3d 7h Kh]
|
||||||
|
*** TURN *** [3d 7h Kh] [Ts]
|
||||||
|
*** RIVER *** [3d 7h Kh Ts] [5c]
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
AAALISAAAA: shows [Kd 5d] (two pair, Kings and Fives)
|
||||||
|
s0rrow: shows [Ac As] (a pair of Aces)
|
||||||
|
AAALISAAAA collected $39.35 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $41.40 | Rake $2.05
|
||||||
|
Board [3d 7h Kh Ts 5c]
|
||||||
|
Seat 1: Blåveis folded before Flop (didn't bet)
|
||||||
|
Seat 2: Kinewma (button) folded before Flop (didn't bet)
|
||||||
|
Seat 3: AAALISAAAA (small blind) showed [Kd 5d] and won ($39.35) with two pair, Kings and Fives
|
||||||
|
Seat 4: Arbaz (big blind) folded before Flop
|
||||||
|
Seat 5: s0rrow showed [Ac As] and lost with a pair of Aces
|
||||||
|
Seat 6: bys7 folded before Flop
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -82,18 +82,21 @@ def testFlopImport():
|
||||||
# River: hero (continuation bets?) all-in and is not called
|
# River: hero (continuation bets?) all-in and is not called
|
||||||
importer.addBulkImportImportFileOrDir(
|
importer.addBulkImportImportFileOrDir(
|
||||||
"""regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Stats-comparision.txt""", site="PokerStars")
|
"""regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Stats-comparision.txt""", site="PokerStars")
|
||||||
|
importer.addBulkImportImportFileOrDir(
|
||||||
|
"""regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Allin-pre.txt""", site="PokerStars")
|
||||||
importer.setCallHud(False)
|
importer.setCallHud(False)
|
||||||
(stored, dups, partial, errs, ttime) = importer.runImport()
|
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||||
print "DEBUG: stored: %s dups: %s partial: %s errs: %s ttime: %s" %(stored, dups, partial, errs, ttime)
|
print "DEBUG: stored: %s dups: %s partial: %s errs: %s ttime: %s" %(stored, dups, partial, errs, ttime)
|
||||||
importer.clearFileList()
|
importer.clearFileList()
|
||||||
|
|
||||||
col = { 'sawShowdown': 2
|
col = { 'sawShowdown': 2, 'street0Aggr':3
|
||||||
}
|
}
|
||||||
|
|
||||||
q = """SELECT
|
q = """SELECT
|
||||||
s.name,
|
s.name,
|
||||||
p.name,
|
p.name,
|
||||||
hp.sawShowdown
|
hp.sawShowdown,
|
||||||
|
hp.street0Aggr
|
||||||
FROM
|
FROM
|
||||||
Hands as h,
|
Hands as h,
|
||||||
Sites as s,
|
Sites as s,
|
||||||
|
@ -114,6 +117,33 @@ and s.id = p.siteid"""
|
||||||
# Assert if any sawShowdown = True
|
# Assert if any sawShowdown = True
|
||||||
assert result[row][col['sawShowdown']] == 0
|
assert result[row][col['sawShowdown']] == 0
|
||||||
|
|
||||||
|
q = """SELECT
|
||||||
|
s.name,
|
||||||
|
p.name,
|
||||||
|
hp.sawShowdown,
|
||||||
|
hp.street0Aggr
|
||||||
|
FROM
|
||||||
|
Hands as h,
|
||||||
|
Sites as s,
|
||||||
|
Gametypes as g,
|
||||||
|
HandsPlayers as hp,
|
||||||
|
Players as p
|
||||||
|
WHERE
|
||||||
|
h.siteHandNo = 37165169101
|
||||||
|
and g.id = h.gametypeid
|
||||||
|
and hp.handid = h.id
|
||||||
|
and p.id = hp.playerid
|
||||||
|
and s.id = p.siteid"""
|
||||||
|
c = db.get_cursor()
|
||||||
|
c.execute(q)
|
||||||
|
result = c.fetchall()
|
||||||
|
pstats = { u'Kinewma':0, u'Arbaz':0, u's0rrow':1, u'bys7':0, u'AAALISAAAA':1, u'Bl\xe5veis':0 }
|
||||||
|
for row, data in enumerate(result):
|
||||||
|
print "DEBUG: result[%s]: %s == %s" %(row, result[row], pstats[data[1]])
|
||||||
|
assert result[row][col['sawShowdown']] == pstats[data[1]]
|
||||||
|
|
||||||
|
assert 0 == 1
|
||||||
|
|
||||||
def testStudImport():
|
def testStudImport():
|
||||||
db.recreate_tables()
|
db.recreate_tables()
|
||||||
importer = fpdb_import.Importer(False, settings, config)
|
importer = fpdb_import.Importer(False, settings, config)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user