Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
@@ -110,7 +110,7 @@ class Site:
|
||||
self.xpad = node.getAttribute("xpad")
|
||||
self.ypad = node.getAttribute("ypad")
|
||||
self.layout = {}
|
||||
|
||||
|
||||
print self.site_name, self.HH_path
|
||||
|
||||
for layout_node in node.getElementsByTagName('layout'):
|
||||
|
||||
@@ -0,0 +1,390 @@
|
||||
|
||||
import os
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
|
||||
#*******************************************************************************************************
|
||||
class DatabaseManager(object):
|
||||
DatabaseTypes = {}
|
||||
|
||||
def __init__(self, defaultDatabaseType=None):
|
||||
self._defaultDatabaseType = defaultDatabaseType
|
||||
def set_default_database_type(self, databaseType):
|
||||
self._defaultDatabaseType = defaultDatabaseType
|
||||
def get_default_database_type(self):
|
||||
return self._defaultDatabaseType
|
||||
|
||||
class DatabaseTypeMeta(type):
|
||||
def __new__(klass, name, bases, kws):
|
||||
newKlass = type.__new__(klass, name, bases, kws)
|
||||
if newKlass.Type is not None:
|
||||
if newKlass.Type in DatabaseManager.DatabaseTypes:
|
||||
raise ValueError('data base type already registered for: %s' % newKlass.Type)
|
||||
DatabaseManager.DatabaseTypes[newKlass.Type] = newKlass
|
||||
return newKlass
|
||||
|
||||
class DatabaseTypeBase(object):
|
||||
__metaclass__ = DatabaseTypeMeta
|
||||
Type = None
|
||||
|
||||
DBHasHost = 0x1
|
||||
DBHasFile = 0x2
|
||||
DBHasPort = 0x4
|
||||
DBHasUser = 0x8
|
||||
DBHasPassword = 0x10
|
||||
DBHasDatabase = 0x20
|
||||
DBHasName = 0x40
|
||||
|
||||
DBFlagsFileSystem = DBHasFile|DBHasName
|
||||
DBFlagsServer = DBHasHost|DBHasPort|DBHasUser|DBHasPassword|DBHasDatabase|DBHasName
|
||||
|
||||
def __init__(self, host='', file='', port=0, user='', password='', database='', table='', name=''):
|
||||
self.host = host
|
||||
self.file = file
|
||||
self.port = port
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.database = database
|
||||
self.name = name
|
||||
@classmethod
|
||||
def display_name(klass):
|
||||
raise NotImplementedError()
|
||||
|
||||
class DatabaseTypePostgres(DatabaseTypeBase):
|
||||
Type = 'postgres'
|
||||
Flags = DatabaseTypeBase.DBFlagsServer
|
||||
@classmethod
|
||||
def display_name(klass):
|
||||
return 'Postgres'
|
||||
def __init__(self, host='localhost', file='', port=5432, user='postgres', password='', database='fpdb', name=''):
|
||||
DatabaseTypeBase.__init__(self, host=host, file=file, port=port, user=user, password=password, database=database, name=name)
|
||||
|
||||
class DatabaseTypeMysql(DatabaseTypeBase):
|
||||
Type = 'mysql'
|
||||
Flags = DatabaseTypeBase.DBFlagsServer
|
||||
@classmethod
|
||||
def display_name(klass):
|
||||
return 'MySql'
|
||||
def __init__(self, host='localhost', file='root', port=3306, user='', password='', database='fpdb', name=''):
|
||||
DatabaseTypeBase.__init__(self, host=host, file=file, port=port, user=user, password=password, database=database, name=name)
|
||||
|
||||
class DatabaseTypeSqLite(DatabaseTypeBase):
|
||||
Type = 'sqlie'
|
||||
Flags = DatabaseTypeBase.DBFlagsFileSystem
|
||||
@classmethod
|
||||
def display_name(klass):
|
||||
return 'SqLite'
|
||||
def __init__(self, host='', file='/home/me2/winetricks', port=0, user='', password='',database='', name=''):
|
||||
DatabaseTypeBase.__init__(self, host=host, file=file, port=port, user=user, password=password, database=database, name=name)
|
||||
|
||||
#***************************************************************************************************************************
|
||||
class MyFileChooserButton(gtk.HBox):
|
||||
#NOTE: for some weird reason it is impossible to let the user choose a non exiting filename with gtk.FileChooserButton, so impl our own on the fly
|
||||
def __init__(self):
|
||||
gtk.HBox.__init__(self)
|
||||
self.set_homogeneous(False)
|
||||
|
||||
self.entry = gtk.Entry()
|
||||
self.button = gtk.Button('...')
|
||||
self.button.connect('clicked', self.on_button_clicked)
|
||||
|
||||
# layout widgets
|
||||
self.pack_start(self.entry, True, True)
|
||||
self.pack_start(self.button, False, False)
|
||||
|
||||
def get_filename(self):
|
||||
return self.entry.get_text()
|
||||
|
||||
def set_filename(self, name):
|
||||
self.entry.set_text(name)
|
||||
|
||||
#TODO: we got three possible actions here
|
||||
# 1. user types in a new filename. easy one, create the file
|
||||
# 2. user selectes a file with the intention to overwrite it
|
||||
# 3. user selects a file with the intention to plug an existing database file in
|
||||
#IDEA: impl open_existing as plug in, never overwrite, cos we can not guess
|
||||
#PROBLEMS: how to validate an existing file is a database?
|
||||
def on_button_clicked(self, button):
|
||||
dlg = gtk.FileChooserDialog(
|
||||
title='Choose an exiting database file or type in name of a new one',
|
||||
parent=None,
|
||||
action=gtk.FILE_CHOOSER_ACTION_SAVE,
|
||||
buttons=(
|
||||
gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_OK,
|
||||
),
|
||||
backend=None
|
||||
)
|
||||
dlg.connect('confirm-overwrite', self.on_dialog_confirm_overwrite)
|
||||
dlg.set_default_response(gtk.RESPONSE_OK)
|
||||
dlg.set_do_overwrite_confirmation(True)
|
||||
if dlg.run() == gtk.RESPONSE_OK:
|
||||
self.set_filename(dlg.get_filename())
|
||||
dlg.destroy()
|
||||
|
||||
def on_dialog_confirm_overwrite(self, dlg):
|
||||
print dlg.get_filename()
|
||||
|
||||
gtk.FILE_CHOOSER_CONFIRMATION_CONFIRM
|
||||
#The file chooser will present its stock dialog to confirm overwriting an existing file.
|
||||
|
||||
gtk.FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME
|
||||
#The file chooser will terminate and accept the user's choice of a file name.
|
||||
|
||||
gtk.FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class DialogDatabaseProperties(gtk.Dialog):
|
||||
def __init__(self, databaseManager, database=None,parent=None):
|
||||
gtk.Dialog.__init__(self,
|
||||
title="My dialog",
|
||||
parent=parent,
|
||||
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
buttons=(
|
||||
gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,
|
||||
)
|
||||
)
|
||||
self.connect('response', self.on_dialog_response)
|
||||
|
||||
# setup widget
|
||||
self.widgetDatabaseProperties = WidgetDatabaseProperties(databaseManager,database=database)
|
||||
self.vbox.pack_start(self.widgetDatabaseProperties, True, True)
|
||||
self.widgetDatabaseProperties.show_all()
|
||||
|
||||
def on_dialog_response(self, dlg, responseId):
|
||||
if responseId == gtk.RESPONSE_REJECT:
|
||||
pass
|
||||
elif responseId == gtk.RESPONSE_ACCEPT:
|
||||
pass
|
||||
|
||||
|
||||
class WidgetDatabaseProperties(gtk.VBox):
|
||||
def __init__(self, databaseManager, database=None):
|
||||
gtk.VBox.__init__(self)
|
||||
|
||||
self.fieldWidgets = ( #fieldName--> fieldHandler
|
||||
{
|
||||
'label': gtk.Label('Name:'),
|
||||
'widget': gtk.Entry(),
|
||||
'getter': lambda widget, database: setattr(database, 'name', widget.get_text() ),
|
||||
'setter': lambda widget, database: widget.set_text(database.name),
|
||||
'isSensitive': lambda database: bool(database.Flags & database.DBHasName),
|
||||
'tooltip': '',
|
||||
},
|
||||
{
|
||||
'label': gtk.Label('File:'),
|
||||
'widget': MyFileChooserButton(),
|
||||
'getter': lambda widget: lambda widget, database: setattr(database, 'file', widget.get_filename() ),
|
||||
'setter': lambda widget, database: widget.set_filename(database.file),
|
||||
'isSensitive': lambda database: bool(database.Flags & database.DBHasFile),
|
||||
'tooltip': '',
|
||||
},
|
||||
{
|
||||
'label': gtk.Label('Host:'),
|
||||
'widget': gtk.Entry(),
|
||||
'getter': lambda widget, database: setattr(database, 'host', widget.get_text() ),
|
||||
'setter': lambda widget, database: widget.set_text(database.host),
|
||||
'isSensitive': lambda database: bool(database.Flags & database.DBHasHost),
|
||||
'tooltip': '',
|
||||
},
|
||||
{
|
||||
'label': gtk.Label('Port:'),
|
||||
'widget': gtk.SpinButton(adjustment=gtk.Adjustment(value=0, lower=0, upper=999999, step_incr=1, page_incr=10) ),
|
||||
'getter': lambda widget, database: setattr(database, 'port', widget.get_value() ),
|
||||
'setter': lambda widget, database: widget.set_value(database.port),
|
||||
'isSensitive': lambda database: bool(database.Flags & database.DBHasPort),
|
||||
'tooltip': '',
|
||||
},
|
||||
{
|
||||
'label': gtk.Label('User:'),
|
||||
'widget': gtk.Entry(),
|
||||
'getter': lambda widget, database: setattr(database, 'user', widget.get_text() ),
|
||||
'setter': lambda widget, database: widget.set_text(database.user),
|
||||
'isSensitive': lambda database: bool(database.Flags & database.DBHasUser),
|
||||
'tooltip': '',
|
||||
},
|
||||
{
|
||||
'label': gtk.Label('Pwd:'),
|
||||
'widget': gtk.Entry(),
|
||||
'getter': lambda widget, database: setattr(database, 'password', widget.get_text() ),
|
||||
'setter': lambda widget, database: widget.set_text(database.password),
|
||||
'isSensitive': lambda database: bool(database.Flags & database.DBHasPassword),
|
||||
'tooltip': '',
|
||||
},
|
||||
{
|
||||
'label': gtk.Label('DB:'),
|
||||
'widget': gtk.Entry(),
|
||||
'getter': lambda widget, database: setattr(database, 'database', widget.get_text() ),
|
||||
'setter': lambda widget, database: widget.set_text(database.database),
|
||||
'isSensitive': lambda database: bool(database.Flags & database.DBHasDatabase),
|
||||
'tooltip': 'enter name of the database to create',
|
||||
},
|
||||
)
|
||||
|
||||
# setup database type combo
|
||||
self.comboType = gtk.ComboBox()
|
||||
listStore= gtk.ListStore(str, str)
|
||||
self.comboType.set_model(listStore)
|
||||
cell = gtk.CellRendererText()
|
||||
self.comboType.pack_start(cell, True)
|
||||
self.comboType.add_attribute(cell, 'text', 0)
|
||||
# fill out combo with database type. we store (displayName, databaseType) in our model for later lookup
|
||||
for dbType, dbDisplayName in sorted([(klass.Type, klass.display_name()) for klass in databaseManager.DatabaseTypes.values()]):
|
||||
listStore.append( (dbDisplayName, dbType) )
|
||||
self.comboType.connect('changed', self.on_combo_type_changed)
|
||||
|
||||
# init and layout field widgets
|
||||
self.pack_start(self.comboType, False, False, 2)
|
||||
table = gtk.Table(rows=len(self.fieldWidgets) +1, columns=2, homogeneous=False)
|
||||
self.pack_start(table, False, False, 2)
|
||||
for i,fieldWidget in enumerate(self.fieldWidgets):
|
||||
fieldWidget['widget'].set_tooltip_text(fieldWidget['tooltip'])
|
||||
|
||||
table.attach(fieldWidget['label'], 0, 1, i, i+1, xoptions=gtk.FILL)
|
||||
table.attach(fieldWidget['widget'], 1, 2, i, i+1)
|
||||
|
||||
# init widget
|
||||
|
||||
# if a database has been passed user is not allowed to change database type
|
||||
if database is None:
|
||||
self.comboType.set_button_sensitivity(gtk.SENSITIVITY_ON)
|
||||
else:
|
||||
self.comboType.set_button_sensitivity(gtk.SENSITIVITY_OFF)
|
||||
|
||||
# set current database
|
||||
self.databaseManager = databaseManager
|
||||
self.database= None
|
||||
if database is None:
|
||||
databaseType = self.databaseManager.get_default_database_type()
|
||||
if databaseType is not None:
|
||||
database = databaseType()
|
||||
if database is not None:
|
||||
self.set_database(database)
|
||||
|
||||
def on_combo_type_changed(self, combo):
|
||||
i = self.comboType.get_active()
|
||||
if i > -1:
|
||||
# change database if necessary
|
||||
currentDatabaseType = self.comboType.get_model()[i][1]
|
||||
if currentDatabaseType != self.database.Type:
|
||||
newDatabase = self.databaseManager.DatabaseTypes[currentDatabaseType]()
|
||||
self.set_database(newDatabase)
|
||||
|
||||
def set_database(self, database):
|
||||
self.database = database
|
||||
|
||||
# adjust database type combo if necessary
|
||||
i = self.comboType.get_active()
|
||||
if i == -1:
|
||||
currentDatabaseType = None
|
||||
else:
|
||||
currentDatabaseType = self.comboType.get_model()[i][1]
|
||||
if currentDatabaseType != self.database.Type:
|
||||
for i, row in enumerate(self.comboType.get_model()):
|
||||
if row[1] == self.database.Type:
|
||||
self.comboType.set_active(i)
|
||||
break
|
||||
else:
|
||||
raise ValueError('unknown database type')
|
||||
|
||||
# adjust field widgets to database
|
||||
for fieldWidget in self.fieldWidgets:
|
||||
isSensitive = fieldWidget['isSensitive'](self.database)
|
||||
fieldWidget['widget'].set_sensitive(isSensitive)
|
||||
fieldWidget['label'].set_sensitive(isSensitive)
|
||||
fieldWidget['setter'](fieldWidget['widget'], self.database)
|
||||
|
||||
def get_database(self):
|
||||
return self.database
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#TODO: just boilerplate code
|
||||
class DialogDatabase(gtk.Dialog):
|
||||
def __init__(self, databaseManager, parent=None):
|
||||
gtk.Dialog.__init__(self,
|
||||
title="My dialog",
|
||||
parent=parent,
|
||||
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
buttons=(
|
||||
gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,
|
||||
))
|
||||
#self.set_size_request(260, 250)
|
||||
|
||||
self.databaseManager = databaseManager
|
||||
|
||||
label = gtk.Label('database stuff')
|
||||
label.set_line_wrap(True)
|
||||
label.set_selectable(True)
|
||||
label.set_single_line_mode(False)
|
||||
label.set_alignment(0, 0)
|
||||
self.vbox.pack_start(label, False, False, 2)
|
||||
self.vbox.pack_start(gtk.HSeparator(), False, False, 2)
|
||||
|
||||
hbox = gtk.HBox()
|
||||
self.vbox.add(hbox)
|
||||
hbox.set_homogeneous(False)
|
||||
|
||||
|
||||
# database management buttons
|
||||
vbox = gtk.VBox()
|
||||
hbox.pack_start(vbox, False, False, 2)
|
||||
self.buttonDatabaseNew = gtk.Button("New...")
|
||||
self.buttonDatabaseNew.connect('clicked', self.onButtonDatabaseNewClicked)
|
||||
vbox.pack_start(self.buttonDatabaseNew, False, False, 2)
|
||||
self.buttonDatabaseEdit = gtk.Button("Edit...")
|
||||
vbox.pack_start(self.buttonDatabaseEdit, False, False, 2)
|
||||
self.buttonDatabaseDelete = gtk.Button("Delete")
|
||||
vbox.pack_start(self.buttonDatabaseDelete, False, False, 2)
|
||||
box = gtk.VBox()
|
||||
vbox.pack_start(box, True, True, 0)
|
||||
|
||||
hbox.pack_start(gtk.VSeparator(), False, False, 2)
|
||||
|
||||
# database tree
|
||||
self.treeDatabases = gtk.TreeView()
|
||||
hbox.pack_end(self.treeDatabases, True, True, 2)
|
||||
|
||||
self.show_all()
|
||||
|
||||
# fill database tree
|
||||
store = gtk.ListStore(str, str)
|
||||
self.treeDatabases.set_model(store)
|
||||
columns = ('Name', 'Status', 'Type')
|
||||
for column in columns:
|
||||
col = gtk.TreeViewColumn(column)
|
||||
self.treeDatabases.append_column(col)
|
||||
|
||||
|
||||
def onButtonDatabaseNewClicked(self, button):
|
||||
dlg = DialogDatabaseProperties(self.databaseManager, parent=self)
|
||||
if dlg.run() == gtk.RESPONSE_REJECT:
|
||||
pass
|
||||
if dlg.run() == gtk.RESPONSE_ACCEPT:
|
||||
pass
|
||||
|
||||
dlg.destroy()
|
||||
|
||||
|
||||
#**************************************************************************************************
|
||||
if __name__ == '__main__':
|
||||
d = DialogDatabaseProperties(
|
||||
DatabaseManager(defaultDatabaseType=DatabaseTypeSqLite),
|
||||
#database=DatabaseTypePostgres(),
|
||||
database=None,
|
||||
)
|
||||
#d = DialogDatabase(DatabaseManager(defaultDatabaseType=DatabaseTypeSqLite))
|
||||
d.connect("destroy", gtk.main_quit)
|
||||
d.run()
|
||||
#gtk.main()
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
# pokerstars_cash.py
|
||||
# -*- coding: iso-8859-15
|
||||
#
|
||||
# PokerStats, an online poker statistics tracking software for Linux
|
||||
# Copyright (C) 2007-2008 Mika Boström <bostik@iki.fi>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
|
||||
# Modified for use in fpdb by Carl Gherardi
|
||||
|
||||
import re
|
||||
|
||||
# These are PokerStars specific;
|
||||
# More importantly, they are currently valid for cash game only.
|
||||
#####
|
||||
# XXX: There was a weird problem with saved hand histories in PokerStars
|
||||
# client 2.491; if a user was present on the table (and thus anywhere in
|
||||
# the hand history), with non-standard characters in their username, the
|
||||
# client would prepend a literal Ctrl-P (ASCII 16, 0x10) character to
|
||||
# the hand history title line. Hence, to allow these strangely saved
|
||||
# hands to be parsed and imported, there is a conditional "one extra
|
||||
# character" allowed at the start of the new hand regex.
|
||||
|
||||
|
||||
class FpdbRegex:
|
||||
def __init__(self):
|
||||
self.__GAME_INFO_REGEX=''
|
||||
self.__SPLIT_HAND_REGEX='\n\n\n'
|
||||
self.__NEW_HAND_REGEX='^.?PokerStars Game #\d+:\s+Hold\'em'
|
||||
self.__HAND_INFO_REGEX='^.*#(\d+):\s+(\S+)\s([\s\S]+)\s\(\$?([.0-9]+)/\$?([.0-9]+)\)\s-\s(\S+)\s-?\s?(\S+)\s\(?(\w+)\)?'
|
||||
self.__TABLE_INFO_REGEX='^\S+\s+\'.*\'\s+(\d+)-max\s+Seat\s#(\d+)'
|
||||
self.__PLAYER_INFO_REGEX='^Seat\s(\d+):\s(.*)\s\(\$?([.\d]+)\s'
|
||||
self.__POST_SB_REGEX='^(.*):\sposts small blind'
|
||||
self.__POST_BB_REGEX='^(.*):\sposts big blind'
|
||||
self.__POST_BOTH_REGEX='^(.*):\sposts small & big blinds'
|
||||
self.__HAND_STAGE_REGEX='^\*{3}\s(.*)\s\*{3}'
|
||||
self.__HOLE_CARD_REGEX='^\*{3}\sHOLE CARDS'
|
||||
self.__FLOP_CARD_REGEX='^\*{3}\sFLOP\s\*{3}\s\[(\S{2})\s(\S{2})\s(\S{2})\]'
|
||||
self.__TURN_CARD_REGEX='^\*{3}\sTURN\s\*{3}\s\[\S{2}\s\S{2}\s\S{2}\]\s\[(\S{2})\]'
|
||||
self.__RIVER_CARD_REGEX='^\*{3}\sRIVER\s\*{3}\s\[\S{2}\s\S{2}\s\S{2}\s\S{2}\]\s\[(\S{2})\]'
|
||||
self.__SHOWDOWN_REGEX='^\*{3}\sSHOW DOWN'
|
||||
self.__SUMMARY_REGEX='^\*{3}\sSUMMARY'
|
||||
self.__UNCALLED_BET_REGEX='^Uncalled bet \(\$([.\d]+)\) returned to (.*)'
|
||||
self.__POT_AND_RAKE_REGEX='^Total\spot\s\$([.\d]+).*\|\sRake\s\$([.\d]+)'
|
||||
self.__COLLECT_POT_REGEX='^(.*)\scollected\s\$([.\d]+)\sfrom\s((main|side)\s)?pot'
|
||||
self.__HERO_CARDS_REGEX='^Dealt\sto\s(.*)\s\[(\S{2})\s(\S{2})\]'
|
||||
self.__SHOWN_CARDS_REGEX='^(.*):\sshows\s\[(\S{2})\s(\S{2})\]'
|
||||
self.__ACTION_STEP_REGEX='^(.*):\s(bets|checks|raises|calls|folds)((\s\$([.\d]+))?(\sto\s\$([.\d]+))?)?'
|
||||
|
||||
self.__SHOWDOWN_ACTION_REGEX='^(.*):\s(shows|mucks)'
|
||||
self.__SUMMARY_CARDS_REGEX='^Seat\s\d+:\s(.*)\s(showed|mucked)\s\[(\S{2})\s(\S{2})\]'
|
||||
self.__SUMMARY_CARDS_EXTRA_REGEX='^Seat\s\d+:\s(.*)\s(\(.*\)\s)(showed|mucked)\s\[(\S{2})\s(\S{2})\]'
|
||||
|
||||
def compileRegexes(self):
|
||||
### Compile the regexes
|
||||
self.game_info_re = re.compile(self.__GAME_INFO_REGEX)
|
||||
self.split_hand_re = re.compile(self.__SPLIT_HAND_REGEX)
|
||||
self.hand_start_re = re.compile(self.__NEW_HAND_REGEX)
|
||||
self.hand_info_re = re.compile(self.__HAND_INFO_REGEX)
|
||||
self.table_info_re = re.compile(self.__TABLE_INFO_REGEX)
|
||||
self.player_info_re = re.compile(self.__PLAYER_INFO_REGEX)
|
||||
self.small_blind_re = re.compile(self.__POST_SB_REGEX)
|
||||
self.big_blind_re = re.compile(self.__POST_BB_REGEX)
|
||||
self.both_blinds_re = re.compile(self.__POST_BOTH_REGEX)
|
||||
self.hand_stage_re = re.compile(self.__HAND_STAGE_REGEX)
|
||||
self.hole_cards_re = re.compile(self.__HOLE_CARD_REGEX)
|
||||
self.flop_cards_re = re.compile(self.__FLOP_CARD_REGEX)
|
||||
self.turn_card_re = re.compile(self.__TURN_CARD_REGEX)
|
||||
self.river_card_re = re.compile(self.__RIVER_CARD_REGEX)
|
||||
self.showdown_re = re.compile(self.__SHOWDOWN_REGEX)
|
||||
self.summary_re = re.compile(self.__SUMMARY_REGEX)
|
||||
self.uncalled_bet_re = re.compile(self.__UNCALLED_BET_REGEX)
|
||||
self.collect_pot_re = re.compile(self.__COLLECT_POT_REGEX)
|
||||
self.hero_cards_re = re.compile(self.__HERO_CARDS_REGEX)
|
||||
self.cards_shown_re = re.compile(self.__SHOWN_CARDS_REGEX)
|
||||
self.summary_cards_re = re.compile(self.__SUMMARY_CARDS_REGEX)
|
||||
self.summary_cards_extra_re = re.compile(self.__SUMMARY_CARDS_EXTRA_REGEX)
|
||||
self.action_re = re.compile(self.__ACTION_STEP_REGEX)
|
||||
self.rake_re = re.compile(self.__POT_AND_RAKE_REGEX)
|
||||
self.showdown_action_re = re.compile(self.__SHOWDOWN_ACTION_REGEX)
|
||||
|
||||
# Set methods for plugins to override
|
||||
|
||||
def setGameInfoRegex(self, string):
|
||||
self.__GAME_INFO_REGEX = string
|
||||
|
||||
def setSplitHandRegex(self, string):
|
||||
self.__SPLIT_HAND_REGEX = string
|
||||
|
||||
def setNewHandRegex(self, string):
|
||||
self.__NEW_HAND_REGEX = string
|
||||
|
||||
def setHandInfoRegex(self, string):
|
||||
self.__HAND_INFO_REGEX = string
|
||||
|
||||
def setTableInfoRegex(self, string):
|
||||
self.__TABLE_INFO_REGEX = string
|
||||
|
||||
def setPlayerInfoRegex(self, string):
|
||||
self.__PLAYER_INFO_REGEX = string
|
||||
|
||||
def setPostSbRegex(self, string):
|
||||
self.__POST_SB_REGEX = string
|
||||
|
||||
def setPostBbRegex(self, string):
|
||||
self.__POST_BB_REGEX = string
|
||||
|
||||
def setPostBothRegex(self, string):
|
||||
self.__POST_BOTH_REGEX = string
|
||||
|
||||
def setHandStageRegex(self, string):
|
||||
self.__HAND_STAGE_REGEX = string
|
||||
|
||||
def setHoleCardRegex(self, string):
|
||||
self.__HOLE_CARD_REGEX = string
|
||||
|
||||
def setFlopCardRegex(self, string):
|
||||
self.__FLOP_CARD_REGEX = string
|
||||
|
||||
def setTurnCardRegex(self, string):
|
||||
self.__TURN_CARD_REGEX = string
|
||||
|
||||
def setRiverCardRegex(self, string):
|
||||
self.__RIVER_CARD_REGEX = string
|
||||
|
||||
def setShowdownRegex(self, string):
|
||||
self.__SHOWDOWN_REGEX = string
|
||||
|
||||
def setSummaryRegex(self, string):
|
||||
self.__SUMMARY_REGEX = string
|
||||
|
||||
def setUncalledBetRegex(self, string):
|
||||
self.__UNCALLED_BET_REGEX = string
|
||||
|
||||
def setCollectPotRegex(self, string):
|
||||
self.__COLLECT_POT_REGEX = string
|
||||
|
||||
def setHeroCardsRegex(self, string):
|
||||
self.__HERO_CARDS_REGEX = string
|
||||
|
||||
def setShownCardsRegex(self, string):
|
||||
self.__SHOWN_CARDS_REGEX = string
|
||||
|
||||
def setSummaryCardsRegex(self, string):
|
||||
self.__SUMMARY_CARDS_REGEX = string
|
||||
|
||||
def setSummaryCardsExtraRegex(self, string):
|
||||
self.__SUMMARY_CARDS_EXTRA_REGEX = string
|
||||
|
||||
def setActionStepRegex(self, string):
|
||||
self.__ACTION_STEP_REGEX = string
|
||||
|
||||
def setPotAndRakeRegex(self, string):
|
||||
self.__POT_AND_RAKE_REGEX = string
|
||||
|
||||
def setShowdownActionRegex(self, string):
|
||||
self.__SHOWDOWN_ACTION_REGEX = string
|
||||
|
||||
+56
-19
@@ -15,6 +15,7 @@
|
||||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
import traceback
|
||||
import threading
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
@@ -29,7 +30,11 @@ import Database
|
||||
import fpdb_db
|
||||
import Filters
|
||||
|
||||
colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5
|
||||
ranks = {'x':0, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
|
||||
|
||||
class GuiPlayerStats (threading.Thread):
|
||||
|
||||
def __init__(self, config, querylist, mainwin, debug=True):
|
||||
self.debug = debug
|
||||
self.conf = config
|
||||
@@ -252,22 +257,56 @@ class GuiPlayerStats (threading.Thread):
|
||||
|
||||
return
|
||||
|
||||
def sortnums(self, model, iter1, iter2, n):
|
||||
try:
|
||||
ret = 0
|
||||
a = self.liststore.get_value(iter1, n)
|
||||
b = self.liststore.get_value(iter2, n)
|
||||
if 'f' in self.cols_to_show[n][4]:
|
||||
try: a = float(a)
|
||||
except: a = 0.0
|
||||
try: b = float(b)
|
||||
except: b = 0.0
|
||||
if n == 0:
|
||||
a1,a2,a3 = ranks[a[0]], ranks[a[1]], (a+'o')[2]
|
||||
b1,b2,b3 = ranks[b[0]], ranks[b[1]], (b+'o')[2]
|
||||
if a1 > b1 or ( a1 == b1 and (a2 > b2 or (a2 == b2 and a3 > b3) ) ):
|
||||
ret = 1
|
||||
else:
|
||||
ret = -1
|
||||
else:
|
||||
if a < b:
|
||||
ret = -1
|
||||
elif a == b:
|
||||
ret = 0
|
||||
else:
|
||||
ret = 1
|
||||
#print "n =", n, "iter1[n] =", self.liststore.get_value(iter1,n), "iter2[n] =", self.liststore.get_value(iter2,n), "ret =", ret
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])
|
||||
print "***sortnums error: " + str(sys.exc_info()[1])
|
||||
print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
|
||||
|
||||
return(ret)
|
||||
|
||||
def sortcols(self, col, n):
|
||||
#This doesn't actually work yet
|
||||
if n == 0:
|
||||
# Card values can stay the same for the moment.
|
||||
return
|
||||
if col.get_sort_order() == gtk.SORT_ASCENDING:
|
||||
col.set_sort_order(gtk.SORT_DESCENDING)
|
||||
else:
|
||||
col.set_sort_order(gtk.SORT_ASCENDING)
|
||||
self.liststore.set_sort_column_id(n, col.get_sort_order())
|
||||
try:
|
||||
#This doesn't actually work yet - clicking heading in top section sorts bottom section :-(
|
||||
if col.get_sort_order() == gtk.SORT_ASCENDING:
|
||||
col.set_sort_order(gtk.SORT_DESCENDING)
|
||||
else:
|
||||
col.set_sort_order(gtk.SORT_ASCENDING)
|
||||
self.liststore.set_sort_column_id(n, col.get_sort_order())
|
||||
self.liststore.set_sort_func(n, self.sortnums, n)
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])
|
||||
print "***sortcols error: " + str(sys.exc_info()[1])
|
||||
print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
|
||||
|
||||
def addTable(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates):
|
||||
counter = 0
|
||||
row = 0
|
||||
sqlrow = 0
|
||||
colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5
|
||||
if not flags: holecards = False
|
||||
else: holecards = flags[0]
|
||||
|
||||
@@ -278,10 +317,10 @@ class GuiPlayerStats (threading.Thread):
|
||||
colnames = [desc[0].lower() for desc in self.cursor.description]
|
||||
|
||||
# pre-fetch some constant values:
|
||||
cols_to_show = [x for x in self.columns if x[colshow]]
|
||||
self.cols_to_show = [x for x in self.columns if x[colshow]]
|
||||
hgametypeid_idx = colnames.index('hgametypeid')
|
||||
|
||||
self.liststore = gtk.ListStore(*([str] * len(cols_to_show)))
|
||||
self.liststore = gtk.ListStore(*([str] * len(self.cols_to_show)))
|
||||
view = gtk.TreeView(model=self.liststore)
|
||||
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
|
||||
#vbox.pack_start(view, expand=False, padding=3)
|
||||
@@ -292,19 +331,15 @@ class GuiPlayerStats (threading.Thread):
|
||||
numcell = gtk.CellRendererText()
|
||||
numcell.set_property('xalign', 1.0)
|
||||
listcols = []
|
||||
idx = 0
|
||||
|
||||
# Create header row eg column: ("game", True, "Game", 0.0, "%s")
|
||||
for col, column in enumerate(cols_to_show):
|
||||
for col, column in enumerate(self.cols_to_show):
|
||||
if column[colalias] == 'game' and holecards:
|
||||
s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading]
|
||||
else:
|
||||
s = column[colheading]
|
||||
listcols.append(gtk.TreeViewColumn(s))
|
||||
view.append_column(listcols[col])
|
||||
#listcols[col].set_clickable(True)
|
||||
#listcols[col].set_sort_indicator(True)
|
||||
#listcols[col].connect("clicked", self.sortcols, idx)
|
||||
if column[colformat] == '%s':
|
||||
if column[colxalign] == 0.0:
|
||||
listcols[col].pack_start(textcell, expand=True)
|
||||
@@ -319,16 +354,18 @@ class GuiPlayerStats (threading.Thread):
|
||||
listcols[col].set_expand(True)
|
||||
#listcols[col].set_alignment(column[colxalign]) # no effect?
|
||||
if column[coltype] == 'cash':
|
||||
listcols[col].set_clickable(True)
|
||||
listcols[col].set_sort_indicator(True)
|
||||
listcols[col].connect("clicked", self.sortcols, col)
|
||||
listcols[col].set_cell_data_func(numcell, self.ledger_style_render_func)
|
||||
else:
|
||||
listcols[col].set_cell_data_func(numcell, self.reset_style_render_func)
|
||||
idx = idx+1
|
||||
|
||||
rows = len(result) # +1 for title row
|
||||
|
||||
while sqlrow < rows:
|
||||
treerow = []
|
||||
for col,column in enumerate(cols_to_show):
|
||||
for col,column in enumerate(self.cols_to_show):
|
||||
if column[colalias] in colnames:
|
||||
value = result[sqlrow][colnames.index(column[colalias])]
|
||||
if column[colalias] == 'plposition':
|
||||
|
||||
@@ -235,22 +235,9 @@ class GuiSessionViewer (threading.Thread):
|
||||
|
||||
def generateDatasets(self, playerids, sitenos, limits, seats):
|
||||
# Get a list of all handids and their timestampts
|
||||
# FIXME: Will probably want to be able to filter this list eventually
|
||||
# FIXME: Join on handsplayers for Hero to get other useful stuff like total profit?
|
||||
#FIXME: Query still need to filter on blind levels
|
||||
|
||||
|
||||
# Postgres version requires - EXTRACT(epoch from h.handStart)
|
||||
q = """
|
||||
select UNIX_TIMESTAMP(h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||
from HandsPlayers hp
|
||||
inner join Hands h on (h.id = hp.handId)
|
||||
inner join Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
inner join Sites s on (s.Id = gt.siteId)
|
||||
inner join Players p on (p.Id = hp.playerId)
|
||||
where hp.playerId in <player_test>
|
||||
and date_format(h.handStart, '%Y-%m-%d') <datestest>
|
||||
order by time
|
||||
"""
|
||||
q = self.sql.query['sessionStats']
|
||||
start_date, end_date = self.filters.getDates()
|
||||
q = q.replace("<datestest>", " between '" + start_date + "' and '" + end_date + "'")
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
<<<<<<< HEAD:pyfpdb/HandHistoryConverter.py
|
||||
# -*- coding: utf-8 -*-
|
||||
=======
|
||||
>>>>>>> 1efdd7fc68d3c9ce013f4d42730bece8075e2272:pyfpdb/HandHistoryConverter.py
|
||||
|
||||
#Copyright 2008 Carl Gherardi
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#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 in the docs folder of the package.
|
||||
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# File for Regression Testing fpdb
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import datetime
|
||||
import Configuration
|
||||
import fpdb_db
|
||||
import fpdb_import
|
||||
import fpdb_simple
|
||||
import FpdbSQLQueries
|
||||
|
||||
import unittest
|
||||
|
||||
class TestSequenceFunctions(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Configure MySQL settings/database and establish connection"""
|
||||
self.c = Configuration.Config()
|
||||
self.mysql_settings={ 'db-host':"localhost",
|
||||
'db-backend':2,
|
||||
'db-databaseName':"fpdbtest",
|
||||
'db-user':"fpdb",
|
||||
'db-password':"fpdb"}
|
||||
self.mysql_db = fpdb_db.fpdb_db()
|
||||
self.mysql_db.connect(self.mysql_settings['db-backend'], self.mysql_settings['db-host'],
|
||||
self.mysql_settings['db-databaseName'], self.mysql_settings['db-user'],
|
||||
self.mysql_settings['db-password'])
|
||||
self.mysqldict = FpdbSQLQueries.FpdbSQLQueries('MySQL InnoDB')
|
||||
self.mysqlimporter = fpdb_import.Importer(self, self.mysql_settings, self.c)
|
||||
self.mysqlimporter.setCallHud(False)
|
||||
|
||||
# """Configure Postgres settings/database and establish connection"""
|
||||
# self.pg_settings={ 'db-host':"localhost", 'db-backend':3, 'db-databaseName':"fpdbtest", 'db-user':"fpdb", 'db-password':"fpdb"}
|
||||
# self.pg_db = fpdb_db.fpdb_db()
|
||||
# self.pg_db.connect(self.pg_settings['db-backend'], self.pg_settings['db-host'],
|
||||
# self.pg_settings['db-databaseName'], self.pg_settings['db-user'],
|
||||
# self.pg_settings['db-password'])
|
||||
# self.pgdict = FpdbSQLQueries.FpdbSQLQueries('PostgreSQL')
|
||||
|
||||
|
||||
def testDatabaseConnection(self):
|
||||
"""Test all supported DBs"""
|
||||
self.result = self.mysql_db.cursor.execute(self.mysqldict.query['list_tables'])
|
||||
self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
|
||||
|
||||
# self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
|
||||
# self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
|
||||
|
||||
def testMySQLRecreateTables(self):
|
||||
"""Test droping then recreating fpdb table schema"""
|
||||
self.mysql_db.recreate_tables()
|
||||
self.result = self.mysql_db.cursor.execute("SHOW TABLES")
|
||||
self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
|
||||
|
||||
def testPokerStarsHHDate(self):
|
||||
latest = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]"
|
||||
previous = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/08/17 - 01:14:43 (ET)"
|
||||
older1 = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/09/07 06:23:14 ET"
|
||||
|
||||
result = fpdb_simple.parseHandStartTime(older1, "ps")
|
||||
self.failUnless(result==datetime.datetime(2008,9,7,11,23,14),
|
||||
"Date incorrect, expected: 2008-09-07 11:23:14 got: " + str(result))
|
||||
result = fpdb_simple.parseHandStartTime(latest, "ps")
|
||||
self.failUnless(result==datetime.datetime(2008,11,12,15,00,48),
|
||||
"Date incorrect, expected: 2008-11-12 15:00:48 got: " + str(result))
|
||||
result = fpdb_simple.parseHandStartTime(previous, "ps")
|
||||
self.failUnless(result==datetime.datetime(2008,8,17,6,14,43),
|
||||
"Date incorrect, expected: 2008-08-17 01:14:43 got: " + str(result))
|
||||
|
||||
def testImportHandHistoryFiles(self):
|
||||
"""Test import of single HH file"""
|
||||
self.mysqlimporter.addImportFile("regression-test-files/hand-histories/ps-lhe-ring-3hands.txt")
|
||||
self.mysqlimporter.runImport()
|
||||
self.mysqlimporter.addImportDirectory("regression-test-files/hand-histories")
|
||||
self.mysqlimporter.runImport()
|
||||
|
||||
# def testPostgresSQLRecreateTables(self):
|
||||
# """Test droping then recreating fpdb table schema"""
|
||||
# self.pg_db.recreate_tables()
|
||||
# self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
|
||||
# self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -2475,6 +2475,33 @@ class Sql:
|
||||
GROUP BY h.handStart, hp.handId, hp.totalProfit
|
||||
ORDER BY h.handStart"""
|
||||
|
||||
####################################
|
||||
# Session stats query
|
||||
####################################
|
||||
if db_server == 'mysql':
|
||||
self.query['sessionStats'] = """
|
||||
SELECT UNIX_TIMESTAMP(h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Hands h on (h.id = hp.handId)
|
||||
INNER JOIN Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
INNER JOIN Sites s on (s.Id = gt.siteId)
|
||||
INNER JOIN Players p on (p.Id = hp.playerId)
|
||||
WHERE hp.playerId in <player_test>
|
||||
AND date_format(h.handStart, '%Y-%m-%d') <datestest>
|
||||
ORDER by time"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['sessionStats'] = """
|
||||
SELECT EXTRACT(epoch from h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Hands h on (h.id = hp.handId)
|
||||
INNER JOIN Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
INNER JOIN Sites s on (s.Id = gt.siteId)
|
||||
INNER JOIN Players p on (p.Id = hp.playerId)
|
||||
WHERE hp.playerId in <player_test>
|
||||
AND date_format(h.handStart, '%Y-%m-%d') <datestest>
|
||||
ORDER by time"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['sessionStats'] = """ """
|
||||
|
||||
####################################
|
||||
# Queries to rebuild/modify hudcache
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ def discover_posix(c):
|
||||
# xwininfo -root -tree -id 0xnnnnn gets the info on a single window
|
||||
for s in c.get_supported_sites():
|
||||
params = c.get_site_parameters(s)
|
||||
|
||||
|
||||
# TODO: We need to make a list of phrases, shared between the WIndows and Unix code!!!!!!
|
||||
if re.search(params['table_finder'], listing):
|
||||
if 'Lobby' in listing: continue
|
||||
|
||||
+1
-2
@@ -162,7 +162,7 @@ class fpdb_db:
|
||||
#print "started fpdb_db.reconnect"
|
||||
self.disconnect(due_to_error)
|
||||
self.connect(self.backend, self.host, self.database, self.user, self.password)
|
||||
|
||||
|
||||
def get_backend_name(self):
|
||||
"""Returns the name of the currently used backend"""
|
||||
if self.backend==2:
|
||||
@@ -178,5 +178,4 @@ class fpdb_db:
|
||||
def get_db_info(self):
|
||||
return (self.host, self.database, self.user, self.password)
|
||||
#end def get_db_info
|
||||
|
||||
#end class fpdb_db
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#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 in the docs folder of the package.
|
||||
|
||||
#This file contains methods to store hands into the db. decides to move this
|
||||
#into a seperate file since its ugly, fairly long and just generally in the way.
|
||||
|
||||
from time import time
|
||||
|
||||
import fpdb_simple
|
||||
|
||||
#stores a stud/razz hand into the database
|
||||
def ring_stud(backend, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time
|
||||
,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes
|
||||
,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName
|
||||
,seatNos):
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||
|
||||
hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
|
||||
,hand_start_time, names, tableName, maxSeats)
|
||||
|
||||
#print "before calling store_hands_players_stud, antes:", antes
|
||||
hands_players_ids=fpdb_simple.store_hands_players_stud(backend, db, cursor, hands_id, player_ids
|
||||
,start_cashes, antes, card_values
|
||||
,card_suits, winnings, rakes, seatNos)
|
||||
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
|
||||
|
||||
fpdb_simple.storeActions(cursor, hands_players_ids, action_types
|
||||
,allIns, action_amounts, actionNos)
|
||||
return hands_id
|
||||
#end def ring_stud
|
||||
|
||||
def ring_holdem_omaha(backend, db, cursor, base, category, site_hand_no, gametype_id
|
||||
,hand_start_time, names, player_ids, start_cashes, positions, card_values
|
||||
,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns
|
||||
,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
"""stores a holdem/omaha hand into the database"""
|
||||
t0 = time()
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||
t1 = time()
|
||||
fpdb_simple.fill_board_cards(board_values, board_suits)
|
||||
t2 = time()
|
||||
|
||||
hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
|
||||
,hand_start_time, names, tableName, maxSeats)
|
||||
t3 = time()
|
||||
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(
|
||||
backend, db, cursor, category, hands_id, player_ids, start_cashes
|
||||
, positions, card_values, card_suits, winnings, rakes, seatNos)
|
||||
t4 = time()
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
|
||||
t5 = time()
|
||||
fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
|
||||
t6 = time()
|
||||
fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
|
||||
t7 = time()
|
||||
print "cards=%4.3f board=%4.3f hands=%4.3f plyrs=%4.3f hudcache=%4.3f board=%4.3f actions=%4.3f" \
|
||||
% (t1-t0, t2-t1, t3-t2, t4-t3, t5-t4, t6-t5, t7-t6)
|
||||
return hands_id
|
||||
#end def ring_holdem_omaha
|
||||
|
||||
def tourney_holdem_omaha(backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout
|
||||
,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId
|
||||
,siteId #end of tourney specific params
|
||||
,site_hand_no, gametype_id, hand_start_time, names, player_ids
|
||||
,start_cashes, positions, card_values, card_suits, board_values
|
||||
,board_suits, winnings, rakes, action_types, allIns, action_amounts
|
||||
,actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
"""stores a tourney holdem/omaha hand into the database"""
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||
fpdb_simple.fill_board_cards(board_values, board_suits)
|
||||
|
||||
tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start)
|
||||
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings)
|
||||
|
||||
hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
|
||||
,hand_start_time, names, tableName, maxSeats)
|
||||
|
||||
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(
|
||||
backend, db, cursor, category, hands_id, player_ids, start_cashes, positions
|
||||
, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
|
||||
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
|
||||
|
||||
fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
|
||||
|
||||
fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
|
||||
return hands_id
|
||||
#end def tourney_holdem_omaha
|
||||
|
||||
def tourney_stud(backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries
|
||||
,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId
|
||||
,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes
|
||||
,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts
|
||||
,actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
#stores a tourney stud/razz hand into the database
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
|
||||
|
||||
tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime)
|
||||
|
||||
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings)
|
||||
|
||||
hands_id=fpdb_simple.storeHands(backend, db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
|
||||
|
||||
hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(backend, db, cursor, hands_id
|
||||
, playerIds, startCashes, antes, cardValues, cardSuits
|
||||
, winnings, rakes, seatNos, tourneys_players_ids)
|
||||
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData)
|
||||
|
||||
fpdb_simple.storeActions(cursor, hands_players_ids, actionTypes, allIns, actionAmounts, actionNos)
|
||||
return hands_id
|
||||
#end def tourney_stud
|
||||
Reference in New Issue
Block a user