Merge branch 'master' of git://git.assembla.com/fpdb-sql

This commit is contained in:
Worros 2010-08-29 14:05:06 +08:00
commit 93be69858a
8 changed files with 613 additions and 227 deletions

View File

@ -1,6 +1,7 @@
# Copyright 1999-2010 Gentoo Foundation # Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2 # Distributed under the terms of the GNU General Public License v2
# created by Steffen Schaumburg, steffen@schaumburger.info and Erki Ferenc, erkiferenc@gmail.com # $Header: $
EAPI="2" EAPI="2"
inherit eutils inherit eutils

View File

@ -1,6 +1,7 @@
# Copyright 1999-2010 Gentoo Foundation # Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2 # Distributed under the terms of the GNU General Public License v2
# created by Steffen Schaumburg, steffen@schaumburger.info and Erki Ferenc, erkiferenc@gmail.com # $Header: $
EAPI="2" EAPI="2"
inherit eutils inherit eutils
@ -17,49 +18,53 @@ SLOT="0"
KEYWORDS="~amd64 ~x86" KEYWORDS="~amd64 ~x86"
#note: this should work on other architectures too, please send me your experiences #note: this should work on other architectures too, please send me your experiences
IUSE="graph mysql postgres sqlite linguas_hu" IUSE="graph mysql postgres sqlite linguas_hu linguas_it"
RDEPEND=" RDEPEND="
mysql? ( virtual/mysql mysql? ( virtual/mysql
dev-python/mysql-python ) dev-python/mysql-python )
postgres? ( dev-db/postgresql-server postgres? ( dev-db/postgresql-server
dev-python/psycopg ) dev-python/psycopg )
sqlite? ( dev-lang/python[sqlite] sqlite? ( dev-lang/python[sqlite]
dev-python/numpy ) dev-python/numpy )
>=x11-libs/gtk+-2.10 >=x11-libs/gtk+-2.10
dev-python/pygtk dev-python/pygtk
graph? ( dev-python/numpy graph? ( dev-python/numpy
dev-python/matplotlib[gtk] ) dev-python/matplotlib[gtk] )
dev-python/python-xlib dev-python/python-xlib
dev-python/pytz" dev-python/pytz"
DEPEND="${RDEPEND}" DEPEND="${RDEPEND}"
src_install() { src_install() {
insinto "${GAMES_DATADIR}"/${PN} insinto "${GAMES_DATADIR}"/${PN}
doins -r gfx doins -r gfx
doins -r pyfpdb doins -r pyfpdb
if use linguas_hu; then if use linguas_hu; then
dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/hu/LC_MESSAGES/${PN}.mo /usr/share/locale/hu/LC_MESSAGES/${PN}.mo dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/hu/LC_MESSAGES/${PN}.mo /usr/share/locale/hu/LC_MESSAGES/${PN}.mo
fi fi
doins readme.txt if use linguas_it; then
dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/it/LC_MESSAGES/${PN}.mo /usr/share/locale/it/LC_MESSAGES/${PN}.mo
fi
exeinto "${GAMES_DATADIR}"/${PN} doins readme.txt
doexe run_fpdb.py
dodir "${GAMES_BINDIR}" exeinto "${GAMES_DATADIR}"/${PN}
dosym "${GAMES_DATADIR}"/${PN}/run_fpdb.py "${GAMES_BINDIR}"/${PN} doexe run_fpdb.py
newicon gfx/fpdb-icon.png ${PN}.png dodir "${GAMES_BINDIR}"
make_desktop_entry ${PN} dosym "${GAMES_DATADIR}"/${PN}/run_fpdb.py "${GAMES_BINDIR}"/${PN}
chmod +x "${D}/${GAMES_DATADIR}"/${PN}/pyfpdb/*.pyw newicon gfx/fpdb-icon.png ${PN}.png
prepgamesdirs make_desktop_entry ${PN}
chmod +x "${D}/${GAMES_DATADIR}"/${PN}/pyfpdb/*.pyw
prepgamesdirs
} }
pkg_postinst() { pkg_postinst() {
games_pkg_postinst games_pkg_postinst
elog "Note that if you really want to use mysql or postgresql you will have to create" elog "Note that if you really want to use mysql or postgresql you will have to create"
elog "the database and user yourself and enter it into the fpdb config." elog "the database and user yourself and enter it into the fpdb config."
elog "You can find the instructions on the project's website." elog "You can find the instructions on the project's website."
} }

View File

@ -1,6 +1,7 @@
# Copyright 1999-2010 Gentoo Foundation # Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2 # Distributed under the terms of the GNU General Public License v2
# created by Steffen Schaumburg, steffen@schaumburger.info and Erki Ferenc, erkiferenc@gmail.com # $Header: $
EAPI="2" EAPI="2"
inherit eutils inherit eutils
@ -18,53 +19,57 @@ SLOT="0"
KEYWORDS="" KEYWORDS=""
#note: this should work on other architectures too, please send me your experiences #note: this should work on other architectures too, please send me your experiences
IUSE="graph mysql postgres sqlite linguas_hu" IUSE="graph mysql postgres sqlite linguas_hu linguas_it"
RDEPEND=" RDEPEND="
mysql? ( virtual/mysql mysql? ( virtual/mysql
dev-python/mysql-python ) dev-python/mysql-python )
postgres? ( dev-db/postgresql-server postgres? ( dev-db/postgresql-server
dev-python/psycopg ) dev-python/psycopg )
sqlite? ( dev-lang/python[sqlite] sqlite? ( dev-lang/python[sqlite]
dev-python/numpy ) dev-python/numpy )
>=x11-libs/gtk+-2.10 >=x11-libs/gtk+-2.10
dev-python/pygtk dev-python/pygtk
graph? ( dev-python/numpy graph? ( dev-python/numpy
dev-python/matplotlib[gtk] ) dev-python/matplotlib[gtk] )
dev-python/python-xlib dev-python/python-xlib
dev-python/pytz" dev-python/pytz"
DEPEND="${RDEPEND}" DEPEND="${RDEPEND}"
src_unpack() { src_unpack() {
git_src_unpack git_src_unpack
} }
src_install() { src_install() {
insinto "${GAMES_DATADIR}"/${PN} insinto "${GAMES_DATADIR}"/${PN}
doins -r gfx doins -r gfx
doins -r pyfpdb doins -r pyfpdb
if use linguas_hu; then if use linguas_hu; then
dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/hu/LC_MESSAGES/${PN}.mo /usr/share/locale/hu/LC_MESSAGES/${PN}.mo dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/hu/LC_MESSAGES/${PN}.mo /usr/share/locale/hu/LC_MESSAGES/${PN}.mo
fi fi
doins readme.txt if use linguas_it; then
dosym "${GAMES_DATADIR}"/${PN}/pyfpdb/locale/it/LC_MESSAGES/${PN}.mo /usr/share/locale/it/LC_MESSAGES/${PN}.mo
fi
exeinto "${GAMES_DATADIR}"/${PN} doins readme.txt
doexe run_fpdb.py
dodir "${GAMES_BINDIR}" exeinto "${GAMES_DATADIR}"/${PN}
dosym "${GAMES_DATADIR}"/${PN}/run_fpdb.py "${GAMES_BINDIR}"/${PN} doexe run_fpdb.py
newicon gfx/fpdb-icon.png ${PN}.png dodir "${GAMES_BINDIR}"
make_desktop_entry ${PN} dosym "${GAMES_DATADIR}"/${PN}/run_fpdb.py "${GAMES_BINDIR}"/${PN}
chmod +x "${D}/${GAMES_DATADIR}"/${PN}/pyfpdb/*.pyw newicon gfx/fpdb-icon.png ${PN}.png
prepgamesdirs make_desktop_entry ${PN}
chmod +x "${D}/${GAMES_DATADIR}"/${PN}/pyfpdb/*.pyw
prepgamesdirs
} }
pkg_postinst() { pkg_postinst() {
games_pkg_postinst games_pkg_postinst
elog "Note that if you really want to use mysql or postgresql you will have to create" elog "Note that if you really want to use mysql or postgresql you will have to create"
elog "the database and user yourself and enter it into the fpdb config." elog "the database and user yourself and enter it into the fpdb config."
elog "You can find the instructions on the project's website." elog "You can find the instructions on the project's website."
} }

View File

@ -749,6 +749,7 @@ class Config:
raise ValueError("Database names must be unique") raise ValueError("Database names must be unique")
if self.db_selected is None or db.db_selected: if self.db_selected is None or db.db_selected:
self.db_selected = db.db_name self.db_selected = db.db_name
db_node.setAttribute("default", "True")
self.supported_databases[db.db_name] = db self.supported_databases[db.db_name] = db
#TODO: if the user may passes '' (empty string) as database name via command line, his choice is ignored #TODO: if the user may passes '' (empty string) as database name via command line, his choice is ignored
# ..when we parse the xml we allow for ''. there has to be a decission if to allow '' or not # ..when we parse the xml we allow for ''. there has to be a decission if to allow '' or not
@ -1039,7 +1040,11 @@ class Config:
if db_user is not None: db_node.setAttribute("db_user", db_user) if db_user is not None: db_node.setAttribute("db_user", db_user)
if db_pass is not None: db_node.setAttribute("db_pass", db_pass) if db_pass is not None: db_node.setAttribute("db_pass", db_pass)
if db_server is not None: db_node.setAttribute("db_server", db_server) if db_server is not None: db_node.setAttribute("db_server", db_server)
if defaultb: db_node.setAttribute("default", default) if defaultb or self.db_selected == db_name:
db_node.setAttribute("default", "True")
for dbn in self.doc.getElementsByTagName("database"):
if dbn.getAttribute('db_name') != db_name and dbn.hasAttribute("default"):
dbn.removeAttribute("default")
elif db_node.hasAttribute("default"): elif db_node.hasAttribute("default"):
db_node.removeAttribute("default") db_node.removeAttribute("default")
if self.supported_databases.has_key(db_name): if self.supported_databases.has_key(db_name):
@ -1052,6 +1057,64 @@ class Config:
if defaultb: if defaultb:
self.db_selected = db_name self.db_selected = db_name
return return
def add_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None,
db_pass = None, db_desc = None, db_server = None,
default = "False"):
default = default.lower()
defaultb = string_to_bool(default, False)
if db_name in self.supported_databases:
raise ValueError("Database names must be unique")
db_node = self.get_db_node(db_name)
if db_node is None:
for db_node in self.doc.getElementsByTagName("supported_databases"):
# should only be one supported_databases element, use last one if there are several
suppdb_node = db_node
t_node = self.doc.createTextNode(" ")
suppdb_node.appendChild(t_node)
db_node = self.doc.createElement("database")
suppdb_node.appendChild(db_node)
t_node = self.doc.createTextNode("\r\n ")
suppdb_node.appendChild(t_node)
db_node.setAttribute("db_name", db_name)
if db_desc is not None: db_node.setAttribute("db_desc", db_desc)
if db_ip is not None: db_node.setAttribute("db_ip", db_ip)
if db_user is not None: db_node.setAttribute("db_user", db_user)
if db_pass is not None: db_node.setAttribute("db_pass", db_pass)
if db_server is not None: db_node.setAttribute("db_server", db_server)
if defaultb:
db_node.setAttribute("default", "True")
for dbn in self.doc.getElementsByTagName("database"):
if dbn.getAttribute('db_name') != db_name and dbn.hasAttribute("default"):
dbn.removeAttribute("default")
elif db_node.hasAttribute("default"):
db_node.removeAttribute("default")
else:
if db_desc is not None: db_node.setAttribute("db_desc", db_desc)
if db_ip is not None: db_node.setAttribute("db_ip", db_ip)
if db_user is not None: db_node.setAttribute("db_user", db_user)
if db_pass is not None: db_node.setAttribute("db_pass", db_pass)
if db_server is not None: db_node.setAttribute("db_server", db_server)
if defaultb or self.db_selected == db_name:
db_node.setAttribute("default", "True")
elif db_node.hasAttribute("default"):
db_node.removeAttribute("default")
if self.supported_databases.has_key(db_name):
if db_desc is not None: self.supported_databases[db_name].dp_desc = db_desc
if db_ip is not None: self.supported_databases[db_name].dp_ip = db_ip
if db_user is not None: self.supported_databases[db_name].dp_user = db_user
if db_pass is not None: self.supported_databases[db_name].dp_pass = db_pass
if db_server is not None: self.supported_databases[db_name].dp_server = db_server
self.supported_databases[db_name].db_selected = defaultb
else:
db = Database(node=db_node)
self.supported_databases[db.db_name] = db
if defaultb:
self.db_selected = db_name
return
def get_backend(self, name): def get_backend(self, name):
"""Returns the number of the currently used backend""" """Returns the number of the currently used backend"""

View File

@ -19,6 +19,7 @@ import os
import sys import sys
import traceback import traceback
import Queue import Queue
import re
import pygtk import pygtk
pygtk.require('2.0') pygtk.require('2.0')
@ -32,6 +33,7 @@ log = logging.getLogger("maintdbs")
import Exceptions import Exceptions
import Configuration
import Database import Database
import SQL import SQL
@ -79,8 +81,17 @@ class GuiDatabase:
try: try:
#self.dia.set_modal(True) #self.dia.set_modal(True)
self.vbox = self.dia.vbox self.vbox = self.dia.vbox
self.action_area = self.dia.action_area
#gtk.Widget.set_size_request(self.vbox, 700, 400); #gtk.Widget.set_size_request(self.vbox, 700, 400);
h = gtk.HBox(False, spacing=3)
h.show()
self.vbox.pack_start(h, padding=3)
vbtn = gtk.VBox(True, spacing=3)
vbtn.show()
h.pack_start(vbtn, expand=False, fill=False, padding=2)
# list of databases in self.config.supported_databases: # list of databases in self.config.supported_databases:
self.liststore = gtk.ListStore(str, str, str, str, str self.liststore = gtk.ListStore(str, str, str, str, str
,str, str, str, str, str) ,str, str, str, str, str)
@ -101,12 +112,15 @@ class GuiDatabase:
self.scrolledwindow = gtk.ScrolledWindow() self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.scrolledwindow.add(self.listview) self.scrolledwindow.add(self.listview)
self.vbox.pack_start(self.scrolledwindow, expand=True, fill=True, padding=0) h.pack_start(self.scrolledwindow, expand=True, fill=True, padding=0)
refreshbutton = gtk.Button(_("Refresh")) add_button = SideButton(_("_Add"), gtk.STOCK_ADD)
refreshbutton.connect("clicked", self.refresh, None) add_button.connect("clicked", self.addDB, None)
self.vbox.pack_start(refreshbutton, False, False, 3) vbtn.pack_start(add_button, False, False, 3)
refreshbutton.show()
refresh_button = SideButton(_("_Refresh"), gtk.STOCK_REFRESH)
refresh_button.connect("clicked", self.refresh, None)
vbtn.pack_start(refresh_button, False, False, 3)
col = self.addTextColumn(_("Type"), 0, False) col = self.addTextColumn(_("Type"), 0, False)
col = self.addTextColumn(_("Name"), 1, False) col = self.addTextColumn(_("Name"), 1, False)
@ -114,7 +128,7 @@ class GuiDatabase:
col = self.addTextColumn(_("Username"), 3, True) col = self.addTextColumn(_("Username"), 3, True)
col = self.addTextColumn(_("Password"), 4, True) col = self.addTextColumn(_("Password"), 4, True)
col = self.addTextColumn(_("Host"), 5, True) col = self.addTextColumn(_("Host"), 5, True)
col = self.addTextObjColumn(_("Default"), 6, 6) col = self.addTextObjColumn(_("Open"), 6, 6)
col = self.addTextObjColumn(_("Status"), 7, 8) col = self.addTextObjColumn(_("Status"), 7, 8)
#self.listview.get_selection().set_mode(gtk.SELECTION_SINGLE) #self.listview.get_selection().set_mode(gtk.SELECTION_SINGLE)
@ -122,6 +136,7 @@ class GuiDatabase:
self.listview.add_events(gtk.gdk.BUTTON_PRESS_MASK) self.listview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
self.listview.connect('button_press_event', self.selectTest) self.listview.connect('button_press_event', self.selectTest)
self.dia.show_all()
self.loadDbs() self.loadDbs()
#self.dia.connect('response', self.dialog_response_cb) #self.dia.connect('response', self.dialog_response_cb)
@ -248,9 +263,9 @@ class GuiDatabase:
self.liststore.clear() self.liststore.clear()
#self.listcols = [] #self.listcols = []
dia = self.info_box2(None, _('Testing database connections ... '), "", False, False) dia = InfoBox( parent=self.dia, str1=_('Testing database connections ... ') )
while gtk.events_pending(): while gtk.events_pending():
gtk.mainiteration() gtk.main_iteration()
try: try:
# want to fill: dbms, name, comment, user, passwd, host, default, status, icon # want to fill: dbms, name, comment, user, passwd, host, default, status, icon
@ -268,57 +283,14 @@ class GuiDatabase:
default = (name == self.config.db_selected) default = (name == self.config.db_selected)
default_icon = None default_icon = None
if default: default_icon = gtk.STOCK_APPLY if default: default_icon = gtk.STOCK_APPLY
status = ""
icon = None
err_msg = ""
sql = SQL.Sql(db_server=dbms) status, err_msg, icon = GuiDatabase.testDB(self.config, dbms, dbms_num, name, user, passwd, host)
db = Database.Database(self.config, sql = sql, autoconnect = False)
# try to connect to db, set status and err_msg if it fails
try:
# is creating empty db for sqlite ... mod db.py further?
# add noDbTables flag to db.py?
log.debug(_("loaddbs: trying to connect to: %s/%s, %s, %s/%s") % (str(dbms_num),dbms,name,user,passwd))
db.connect(backend=dbms_num, host=host, database=name, user=user, password=passwd, create=False)
if db.connected:
log.debug(_(" connected ok"))
status = 'ok'
icon = gtk.STOCK_APPLY
if db.wrongDbVersion:
status = 'old'
icon = gtk.STOCK_INFO
else:
log.debug(_(" not connected but no exception"))
except Exceptions.FpdbMySQLAccessDenied:
err_msg = _("MySQL Server reports: Access denied. Are your permissions set correctly?")
status = "failed"
icon = gtk.STOCK_CANCEL
except Exceptions.FpdbMySQLNoDatabase:
err_msg = _("MySQL client reports: 2002 or 2003 error. Unable to connect - Please check that the MySQL service has been started")
status = "failed"
icon = gtk.STOCK_CANCEL
except Exceptions.FpdbPostgresqlAccessDenied:
err_msg = _("Postgres Server reports: Access denied. Are your permissions set correctly?")
status = "failed"
except Exceptions.FpdbPostgresqlNoDatabase:
err_msg = _("Postgres client reports: Unable to connect - Please check that the Postgres service has been started")
status = "failed"
icon = gtk.STOCK_CANCEL
except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
log.info( 'db connection to '+str(dbms_num)+','+host+','+name+','+user+','+passwd+' failed: '
+ err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]) )#TODO Gettextify
status = "failed"
icon = gtk.STOCK_CANCEL
if err_msg:
log.info( 'db connection to '+str(dbms_num)+','+host+','+name+','+user+','+passwd+' failed: '
+ err_msg )#TODO Gettextify
b = gtk.Button(name) b = gtk.Button(name)
b.show() b.show()
iter = self.liststore.append( (dbms, name, comment, user, passwd, host, "", default_icon, status, icon) ) iter = self.liststore.append( (dbms, name, comment, user, passwd, host, "", default_icon, status, icon) )
self.info_box2(dia[0], _("finished."), "", False, True) dia.add_msg( _("finished."), False, True )
self.listview.show() self.listview.show()
self.scrolledwindow.show() self.scrolledwindow.show()
self.vbox.show() self.vbox.show()
@ -356,64 +328,368 @@ class GuiDatabase:
def refresh(self, widget, data): def refresh(self, widget, data):
self.loadDbs() self.loadDbs()
def info_box(self, dia, str1, str2, run, destroy): def addDB(self, widget, data):
if dia is None: adb = AddDB(self.config, self.dia)
#if run: (status, err_msg, icon, dbms, dbms_num, name, comment, user, passwd, host) = adb.run()
btns = gtk.BUTTONS_NONE adb.destroy()
btns = gtk.BUTTONS_OK
dia = gtk.MessageDialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT
, type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 )
# try to remove buttons!
# (main message is in inverse video if no buttons, so try removing them after
# creating dialog)
# NO! message just goes back to inverse video :-( use info_box2 instead
for c in dia.vbox.get_children():
if isinstance(c, gtk.HButtonBox):
for d in c.get_children():
log.info('child: '+str(d)+' is a '+str(d.__class__))
if isinstance(d, gtk.Button):
log.info(_('removing button %s'% str(d)))
c.remove(d)
if str2:
dia.format_secondary_text(str2)
else:
dia.set_markup(str1)
if str2:
dia.format_secondary_text(str2)
dia.show()
response = None
if run: response = dia.run()
if destroy: dia.destroy()
return (dia, response)
def info_box2(self, dia, str1, str2, run, destroy): # save in liststore
if dia is None: if status == 'ok':
# create dialog and add icon and label iter = self.liststore.append( (dbms, name, comment, user, passwd, host, "", None, status, icon) )
btns = (gtk.BUTTONS_OK)
btns = None # keep config save code in line with edited_cb()? call common routine?
# messagedialog puts text in inverse colors if no buttons are displayed??
#dia = gtk.MessageDialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT valid = True
# , type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 ) # Validate new value (only for dbms so far, but dbms now not updateable so no validation at all!)
dia = gtk.Dialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT #if col == self.COL_DBMS:
, title="" ) # , buttons=btns # if new_text not in Configuration.DATABASE_TYPES:
vbox = dia.vbox # valid = False
if valid:
self.config.add_db_parameters( db_server = dbms
, db_name = name
, db_desc = comment
, db_ip = host
, db_user = user
, db_pass = passwd )
self.config.save()
self.changes = False
@staticmethod
def testDB(config, dbms, dbms_num, name, user, passwd, host):
status = ""
icon = None
err_msg = ""
sql = SQL.Sql(db_server=dbms)
db = Database.Database(config, sql = sql, autoconnect = False)
# try to connect to db, set status and err_msg if it fails
try:
# is creating empty db for sqlite ... mod db.py further?
# add noDbTables flag to db.py?
log.debug(_("loaddbs: trying to connect to: %s/%s, %s, %s/%s") % (str(dbms_num),dbms,name,user,passwd))
db.connect(backend=dbms_num, host=host, database=name, user=user, password=passwd, create=False)
if db.connected:
log.debug(_(" connected ok"))
status = 'ok'
icon = gtk.STOCK_APPLY
if db.wrongDbVersion:
status = 'old'
icon = gtk.STOCK_INFO
else:
log.debug(_(" not connected but no exception"))
except Exceptions.FpdbMySQLAccessDenied:
err_msg = _("MySQL Server reports: Access denied. Are your permissions set correctly?")
status = "failed"
icon = gtk.STOCK_CANCEL
except Exceptions.FpdbMySQLNoDatabase:
err_msg = _("MySQL client reports: 2002 or 2003 error. Unable to connect - Please check that the MySQL service has been started")
status = "failed"
icon = gtk.STOCK_CANCEL
except Exceptions.FpdbPostgresqlAccessDenied:
err_msg = _("Postgres Server reports: Access denied. Are your permissions set correctly?")
status = "failed"
except Exceptions.FpdbPostgresqlNoDatabase:
err_msg = _("Postgres client reports: Unable to connect - Please check that the Postgres service has been started")
status = "failed"
icon = gtk.STOCK_CANCEL
except:
# add more specific exceptions here if found (e.g. for sqlite?)
err = traceback.extract_tb(sys.exc_info()[2])[-1]
err_msg = err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
status = "failed"
icon = gtk.STOCK_CANCEL
if err_msg:
log.info( _('db connection to ') + str(dbms_num)+','+host+','+name+','+user+','+passwd+' failed: '
+ err_msg )
return( status, err_msg, icon )
class AddDB(gtk.Dialog):
def __init__(self, config, parent):
log.debug("AddDB starting")
self.dbnames = { 'Sqlite' : Configuration.DATABASE_TYPE_SQLITE
, 'MySQL' : Configuration.DATABASE_TYPE_MYSQL
, 'PostgreSQL' : Configuration.DATABASE_TYPE_POSTGRESQL
}
self.config = config
# create dialog and add icon and label
super(AddDB,self).__init__( parent=parent
, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
, title="Add New Database"
, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT
,gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)
) # , buttons=btns
self.set_default_size(450, 280)
#self.connect('response', self.response_cb)
t = gtk.Table(5, 3, True)
self.vbox.pack_start(t, expand=False, fill=False, padding=3)
l = gtk.Label( _("DB Type") )
l.set_alignment(1.0, 0.5)
t.attach(l, 0, 1, 0, 1, xpadding=3)
self.cb_dbms = gtk.combo_box_new_text()
for s in ('Sqlite',): # keys(self.dbnames):
self.cb_dbms.append_text(s)
self.cb_dbms.set_active(0)
t.attach(self.cb_dbms, 1, 3, 0, 1, xpadding=3)
self.cb_dbms.connect("changed", self.db_type_changed, None)
l = gtk.Label( _("DB Name") )
l.set_alignment(1.0, 0.5)
t.attach(l, 0, 1, 1, 2, xpadding=3)
self.e_db_name = gtk.Entry()
self.e_db_name.set_width_chars(15)
t.attach(self.e_db_name, 1, 3, 1, 2, xpadding=3)
self.e_db_name.connect("focus-out-event", self.db_name_changed, None)
l = gtk.Label( _("DB Description") )
l.set_alignment(1.0, 0.5)
t.attach(l, 0, 1, 2, 3, xpadding=3)
self.e_db_desc = gtk.Entry()
self.e_db_desc.set_width_chars(15)
t.attach(self.e_db_desc, 1, 3, 2, 3, xpadding=3)
self.l_username = gtk.Label( _("Username") )
self.l_username.set_alignment(1.0, 0.5)
t.attach(self.l_username, 0, 1, 3, 4, xpadding=3)
self.e_username = gtk.Entry()
self.e_username.set_width_chars(15)
t.attach(self.e_username, 1, 3, 3, 4, xpadding=3)
self.l_password = gtk.Label( _("Password") )
self.l_password.set_alignment(1.0, 0.5)
t.attach(self.l_password, 0, 1, 4, 5, xpadding=3)
self.e_password = gtk.Entry()
self.e_password.set_width_chars(15)
t.attach(self.e_password, 1, 3, 4, 5, xpadding=3)
self.l_host = gtk.Label( _("Host Computer") )
self.l_host.set_alignment(1.0, 0.5)
t.attach(self.l_host, 0, 1, 5, 6, xpadding=3)
self.e_host = gtk.Entry()
self.e_host.set_width_chars(15)
self.e_host.set_text("localhost")
t.attach(self.e_host, 1, 3, 5, 6, xpadding=3)
parent.show_all()
self.show_all()
# hide username/password fields as not used by sqlite
self.l_username.hide()
self.e_username.hide()
self.l_password.hide()
self.e_password.hide()
def run(self):
response = super(AddDB,self).run()
log.debug("adddb.run: response is "+str(response)+" accept is "+str(int(gtk.RESPONSE_ACCEPT)))
ok,retry = False,True
while response == gtk.RESPONSE_ACCEPT:
ok,retry = self.check_fields()
if retry:
response = super(AddDB,self).run()
else:
response = gtk.RESPONSE_REJECT
(status, err_msg, icon, dbms, dbms_num
,name, db_desc, user, passwd, host) = ("error", "error", None, None, None
,None, None, None, None, None)
if ok:
log.debug("start creating new db")
# add a new db
master_password = None
dbms = self.dbnames[ self.cb_dbms.get_active_text() ]
dbms_num = self.config.get_backend(dbms)
name = self.e_db_name.get_text()
db_desc = self.e_db_desc.get_text()
user = self.e_username.get_text()
passwd = self.e_password.get_text()
host = self.e_host.get_text()
h = gtk.HBox(False, 2) # TODO:
i = gtk.Image() # if self.cb_dbms.get_active_text() == 'Postgres':
i.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG) # <ask for postgres master password>
l = gtk.Label(str1)
h.pack_start(i, padding=5) # create_db() in Database.py or here? ... TODO
h.pack_start(l, padding=5)
vbox.pack_start(h) # test db after creating?
status, err_msg, icon = GuiDatabase.testDB(self.config, dbms, dbms_num, name, user, passwd, host)
log.debug('tested new db, result='+str((status,err_msg)))
if status == 'ok':
#dia = InfoBox( parent=self, str1=_('Database created') )
str1 = _('Database created')
else:
#dia = InfoBox( parent=self, str1=_('Database creation failed') )
str1 = _('Database creation failed')
#dia.add_msg("", True, True)
btns = (gtk.BUTTONS_OK)
dia = gtk.MessageDialog( parent=self, flags=gtk.DIALOG_DESTROY_WITH_PARENT
, type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 )
dia.run()
return( (status, err_msg, icon, dbms, dbms_num, name, db_desc, user, passwd, host) )
def check_fields(self):
"""check fields and return true/false according to whether user wants to try again
return False if fields are ok
"""
log.debug("check_fields: starting")
try_again = False
ok = True
# checks for all db's
if self.e_db_name.get_text() == "":
msg = _("No Database Name given")
ok = False
elif self.e_db_desc.get_text() is None or self.e_db_desc.get_text() == "":
msg = _("No Database Description given")
ok = False
elif self.cb_dbms.get_active_text() != 'Sqlite' and self.e_username.get_text() == "":
msg = _("No Username given")
ok = False
elif self.cb_dbms.get_active_text() != 'Sqlite' and self.e_password.get_text() == "":
msg = _("No Password given")
ok = False
elif self.e_host.get_text() == "":
msg = _("No Host given")
ok = False
if ok:
if self.cb_dbms.get_active_text() == 'Sqlite':
# checks for sqlite
pass
elif self.cb_dbms.get_active_text() == 'MySQL':
# checks for mysql
pass
elif self.cb_dbms.get_active_text() == 'Postgres':
# checks for postgres
pass
else:
msg = "Unknown Database Type selected"
ok = False
if not ok:
log.debug("check_fields: open dialog")
dia = gtk.MessageDialog( parent=self
, flags=gtk.DIALOG_DESTROY_WITH_PARENT
, type=gtk.MESSAGE_ERROR
, message_format=msg
, buttons = gtk.BUTTONS_YES_NO
)
#l = gtk.Label(msg)
#dia.vbox.add(l)
l = gtk.Label( _("Do you want to try again?") )
dia.vbox.add(l)
dia.show_all()
ret = dia.run()
log.debug("check_fields: ret is "+str(ret)+" cancel is "+str(int(gtk.RESPONSE_CANCEL)))
if ret == gtk.RESPONSE_YES:
try_again = True
log.debug("check_fields: destroy dialog")
dia.hide()
dia.destroy()
log.debug("check_fields: returning ok as "+str(ok)+", try_again as "+str(try_again))
return(ok,try_again)
def db_type_changed(self, widget, data):
if self.cb_dbms.get_active_text() == 'Sqlite':
self.l_username.hide()
self.e_username.hide()
self.e_username.set_text("")
self.l_password.hide()
self.e_password.hide()
self.e_password.set_text("")
else: else:
# add extra label self.l_username.show()
vbox = dia.vbox self.e_username.show()
vbox.pack_start( gtk.Label(str1) ) self.l_password.show()
dia.show_all() self.e_password.show()
return(response)
def db_name_changed(self, widget, event, data):
log.debug('db_name_changed: text='+widget.get_text())
if not re.match('\....$', widget.get_text()):
widget.set_text(widget.get_text()+'.db3')
widget.show()
#def response_cb(self, dialog, data):
# dialog.destroy()
# return(data)
class InfoBox(gtk.Dialog):
def __init__(self, parent, str1):
# create dialog and add icon and label
btns = (gtk.BUTTONS_OK)
btns = None
# messagedialog puts text in inverse colors if no buttons are displayed??
#dia = gtk.MessageDialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT
# , type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 )
# so just use Dialog instead
super(InfoBox,self).__init__( parent=parent
, flags=gtk.DIALOG_DESTROY_WITH_PARENT
, title="" ) # , buttons=btns
h = gtk.HBox(False, 2)
i = gtk.Image()
i.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG)
l = gtk.Label(str1)
h.pack_start(i, padding=5)
h.pack_start(l, padding=5)
self.vbox.pack_start(h)
parent.show_all()
self.show_all()
def add_msg(self, str1, run, destroy):
# add extra label
self.vbox.pack_start( gtk.Label(str1) )
self.show_all()
response = None response = None
if run: response = dia.run() if run: response = self.run()
if destroy: dia.destroy() if destroy: self.destroy()
return (dia, response) return (response)
class SideButton(gtk.Button):
"""Create a button with the label below the icon"""
# to change label on buttons:
# ( see http://faq.pygtk.org/index.py?req=show&file=faq09.005.htp )
# gtk.stock_add([(gtk.STOCK_ADD, _("Add"), 0, 0, "")])
# alternatively:
# button = gtk.Button(stock=gtk.STOCK_CANCEL)
# button.show()
# alignment = button.get_children()[0]
# hbox = alignment.get_children()[0]
# image, label = hbox.get_children()
# label.set_text('Hide')
def __init__(self, label=None, stock=None, use_underline=True):
gtk.stock_add([(stock, label, 0, 0, "")])
super(SideButton, self).__init__(label=label, stock=stock, use_underline=True)
alignment = self.get_children()[0]
hbox = alignment.get_children()[0]
image, label = hbox.get_children()
#label.set_text('Hide')
hbox.remove(image)
hbox.remove(label)
v = gtk.VBox(False, spacing=3)
v.pack_start(image, 3)
v.pack_start(label, 3)
alignment.remove(hbox)
alignment.add(v)
self.show_all()
if __name__=="__main__": if __name__=="__main__":

View File

@ -62,6 +62,7 @@ class Hand(object):
def __init__(self, config, sitename, gametype, handText, builtFrom = "HHC"): def __init__(self, config, sitename, gametype, handText, builtFrom = "HHC"):
#log.debug( _("Hand.init(): handText is ") + str(handText) )
self.config = config self.config = config
#log = Configuration.get_logger("logging.conf", "db", log_dir=self.config.dir_log) #log = Configuration.get_logger("logging.conf", "db", log_dir=self.config.dir_log)
self.sitename = sitename self.sitename = sitename
@ -314,7 +315,7 @@ If a player has None chips he won't be added."""
log.debug("markStreets:\n"+ str(self.streets)) log.debug("markStreets:\n"+ str(self.streets))
else: else:
tmp = self.handText[0:100] tmp = self.handText[0:100]
log.error(_("markstreets didn't match - Assuming hand cancelled")) log.error(_("markstreets didn't match - Assuming hand %s was cancelled") % self.handid)
self.cancelled = True self.cancelled = True
raise FpdbParseError(_("FpdbParseError: markStreets appeared to fail: First 100 chars: '%s'") % tmp) raise FpdbParseError(_("FpdbParseError: markStreets appeared to fail: First 100 chars: '%s'") % tmp)

View File

@ -19,6 +19,13 @@
######################################################################## ########################################################################
import sys import sys
import exceptions
import logging
# logging has been set up in fpdb.py or HUD_main.py, use their settings:
log = logging.getLogger("parser")
import Configuration import Configuration
from HandHistoryConverter import * from HandHistoryConverter import *
from decimal import Decimal from decimal import Decimal
@ -65,7 +72,6 @@ class OnGame(HandHistoryConverter):
# '5 Card Draw' : ('draw','fivedraw') # '5 Card Draw' : ('draw','fivedraw')
} }
#self.rexx.setGameInfoRegex('.*Blinds \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)')
# Static regexes # Static regexes
# ***** End of hand R5-75443872-57 ***** # ***** End of hand R5-75443872-57 *****
re_SplitHands = re.compile(u'\*\*\*\*\*\sEnd\sof\shand\s[-A-Z\d]+.*\n(?=\*)') re_SplitHands = re.compile(u'\*\*\*\*\*\sEnd\sof\shand\s[-A-Z\d]+.*\n(?=\*)')
@ -73,6 +79,18 @@ class OnGame(HandHistoryConverter):
# ***** History for hand R5-75443872-57 ***** # ***** History for hand R5-75443872-57 *****
# Start hand: Wed Aug 18 19:29:10 GMT+0100 2010 # Start hand: Wed Aug 18 19:29:10 GMT+0100 2010
# Table: someplace [75443872] (LIMIT TEXAS_HOLDEM 0.50/1, Real money) # Table: someplace [75443872] (LIMIT TEXAS_HOLDEM 0.50/1, Real money)
#***** History for hand R5-78042004-262 *****
#Start hand: Fri Aug 27 21:40:46 GMT+0100 2010
#Table: Bamako [78042004] (LIMIT TEXAS_HOLDEM $0.25/$0.50, Real money)
#User: sagi34
#{ u'BB': None
#, u'DATETIME': u'Fri Aug 27 22:38:26 GMT+0100 2010\\n'
#, u'GAME': None
#, u'HID': u'R5-78042004-346'
#, u'TABLE': u'Bamako'
#, u'LIMIT': None
#, u'SB': None
#}
re_HandInfo = re.compile(u""" re_HandInfo = re.compile(u"""
\*\*\*\*\*\sHistory\sfor\shand\s(?P<HID>[-A-Z\d]+).* \*\*\*\*\*\sHistory\sfor\shand\s(?P<HID>[-A-Z\d]+).*
Start\shand:\s(?P<DATETIME>.*) Start\shand:\s(?P<DATETIME>.*)
@ -80,8 +98,8 @@ class OnGame(HandHistoryConverter):
( (
(?P<LIMIT>NO_LIMIT|Limit|LIMIT|Pot\sLimit)\s (?P<LIMIT>NO_LIMIT|Limit|LIMIT|Pot\sLimit)\s
(?P<GAME>TEXAS_HOLDEM|RAZZ)\s (?P<GAME>TEXAS_HOLDEM|RAZZ)\s
(?P<SB>[.0-9]+)/ (%(LS)s)?(?P<SB>[.0-9]+)/
(?P<BB>[.0-9]+) (%(LS)s)?(?P<BB>[.0-9]+)
)? )?
""" % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE) """ % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE)
@ -102,7 +120,9 @@ class OnGame(HandHistoryConverter):
# self.rexx.button_re = re.compile('#SUMMARY\nDealer: (?P<BUTTONPNAME>.*)\n') # self.rexx.button_re = re.compile('#SUMMARY\nDealer: (?P<BUTTONPNAME>.*)\n')
#Seat 1: .Lucchess ($4.17 in chips) #Seat 1: .Lucchess ($4.17 in chips)
re_PlayerInfo = re.compile(u'Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \((?P<CASH>[.0-9]+)\)') #Seat 1: phantomaas ($27.11)
#Seat 5: mleo17 ($9.37)
re_PlayerInfo = re.compile(u'Seat (?P<SEAT>[0-9]+):\s(?P<PNAME>.*)\s\((%(LS)s)?(?P<CASH>[.0-9]+)\)' % substitutions)
def compilePlayerRegexs(self, hand): def compilePlayerRegexs(self, hand):
players = set([player[1] for player in hand.players]) players = set([player[1] for player in hand.players])
@ -117,23 +137,28 @@ class OnGame(HandHistoryConverter):
#helander2222 posts blind ($0.25), lopllopl posts blind ($0.50). #helander2222 posts blind ($0.25), lopllopl posts blind ($0.50).
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")" player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]} subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]}
self.re_PostSB = re.compile('(?P<PNAME>.*) posts small blind \(\$?(?P<SB>[.0-9]+)\)') self.re_PostSB = re.compile('(?P<PNAME>.*) posts small blind \((%(CUR)s)?(?P<SB>[\.0-9]+)\)' % subst, re.MULTILINE)
self.re_PostBB = re.compile('\), (?P<PNAME>.*) posts big blind \(\$?(?P<BB>[.0-9]+)\)') self.re_PostBB = re.compile('\), (?P<PNAME>.*) posts big blind \((%(CUR)s)?(?P<BB>[\.0-9]+)\)' % subst, re.MULTILINE)
self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante %(CUR)s(?P<ANTE>[.0-9]+)" % subst, re.MULTILINE) self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante (%(CUR)s)?(?P<ANTE>[\.0-9]+)" % subst, re.MULTILINE)
self.re_BringIn = re.compile(r"^%(PLYR)s: brings[- ]in( low|) for %(CUR)s(?P<BRINGIN>[.0-9]+)" % subst, re.MULTILINE) self.re_BringIn = re.compile(r"^%(PLYR)s: brings[- ]in( low|) for (%(CUR)s)?(?P<BRINGIN>[\.0-9]+)" % subst, re.MULTILINE)
self.re_PostBoth = re.compile('.*\n(?P<PNAME>.*): posts small \& big blinds \(\$? (?P<SBBB>[.0-9]+)\)') self.re_PostBoth = re.compile('.*\n(?P<PNAME>.*): posts small \& big blinds \( (%(CUR)s)?(?P<SBBB>[\.0-9]+)\)' % subst)
self.re_HeroCards = re.compile('Dealing\sto\s%(PLYR)s:\s\[(?P<CARDS>.*)\]' % subst) self.re_HeroCards = re.compile('Dealing\sto\s%(PLYR)s:\s\[(?P<CARDS>.*)\]' % subst)
#lopllopl checks, Eurolll checks, .Lucchess checks. #lopllopl checks, Eurolll checks, .Lucchess checks.
self.re_Action = re.compile('(, )?(?P<PNAME>.*?)(?P<ATYPE> bets| checks| raises| calls| folds)( (?P<BET>\d*\.?\d*))?( and is all-in)?') #chumley. calls $0.25
self.re_Action = re.compile('(, )?(?P<PNAME>.*?)(?P<ATYPE> bets| checks| raises| calls| folds)( (%(CUR)s)?(?P<BET>[\d\.]+))?( and is all-in)?' % subst)
#self.re_Board = re.compile(r"\[board cards (?P<CARDS>.+) \]") #self.re_Board = re.compile(r"\[board cards (?P<CARDS>.+) \]")
#Uchilka shows [ KC,JD ] #Uchilka shows [ KC,JD ]
self.re_ShowdownAction = re.compile('(?P<PNAME>.*) shows \[ (?P<CARDS>.+) \]') self.re_ShowdownAction = re.compile('(?P<PNAME>.*) shows \[ (?P<CARDS>.+) \]')
# TODO: read SUMMARY correctly for collected pot stuff. #Main pot: $3.57 won by mleo17 ($3.40)
# Main pot: 6.75 won by player3 (6.45) #Side pot 1: $3.26 won by maac_5 ($3.10)
self.re_CollectPot = re.compile('Main pot: (?P<POT>\d*\.?\d*) won by %(PLYR)s' % subst) #Main pot: $2.87 won by maac_5 ($1.37), sagi34 ($1.36)
self.re_Pot = re.compile('(Main|Side)\spot(\s\d+)?:\s.*won\sby\s(?P<POT>.*$)', re.MULTILINE)
self.re_CollectPot = re.compile('\s*(?P<PNAME>.*)\s\((%(CUR)s)?(?P<POT>[\.\d]+)\)' % subst)
#Seat 5: mleo17 ($3.40), net: +$2.57, [Jd, Qd] (TWO_PAIR QUEEN, JACK)
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(.*\), net:.* \[(?P<CARDS>.*)\].*" % subst, re.MULTILINE)
self.re_sitsOut = re.compile('(?P<PNAME>.*) sits out') self.re_sitsOut = re.compile('(?P<PNAME>.*) sits out')
def readSupportedGames(self): def readSupportedGames(self):
@ -160,7 +185,13 @@ class OnGame(HandHistoryConverter):
info['currency'] = 'USD' info['currency'] = 'USD'
if 'LIMIT' in mg: if 'LIMIT' in mg:
info['limitType'] = self.limits[mg['LIMIT']] if mg['LIMIT'] in self.limits:
info['limitType'] = self.limits[mg['LIMIT']]
else:
tmp = handText[0:100]
log.error(_("determineGameType: limit not found in self.limits(%s). hand: '%s'") % (str(mg),tmp))
log.error(_("determineGameType: Raising FpdbParseError"))
raise FpdbParseError(_("limit not found in self.limits(%s). hand: '%s'") % (str(mg),tmp))
if 'GAME' in mg: if 'GAME' in mg:
(info['base'], info['category']) = self.games[mg['GAME']] (info['base'], info['category']) = self.games[mg['GAME']]
if 'SB' in mg: if 'SB' in mg:
@ -168,6 +199,7 @@ class OnGame(HandHistoryConverter):
if 'BB' in mg: if 'BB' in mg:
info['bb'] = mg['BB'] info['bb'] = mg['BB']
#log.debug("determinegametype: returning "+str(info))
return info return info
def readHandInfo(self, hand): def readHandInfo(self, hand):
@ -177,7 +209,7 @@ class OnGame(HandHistoryConverter):
if m: if m:
info.update(m.groupdict()) info.update(m.groupdict())
log.debug("readHandInfo: %s" % info) #log.debug("readHandInfo: %s" % info)
for key in info: for key in info:
if key == 'DATETIME': if key == 'DATETIME':
#'Wed Aug 18 19:45:30 GMT+0100 2010 #'Wed Aug 18 19:45:30 GMT+0100 2010
@ -203,6 +235,7 @@ class OnGame(HandHistoryConverter):
hand.mixed = None hand.mixed = None
def readPlayerStacks(self, hand): def readPlayerStacks(self, hand):
#log.debug("readplayerstacks: re is '%s'" % self.re_PlayerInfo)
m = self.re_PlayerInfo.finditer(hand.handText) m = self.re_PlayerInfo.finditer(hand.handText)
for a in m: for a in m:
hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH')) hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
@ -247,15 +280,13 @@ class OnGame(HandHistoryConverter):
hand.setCommunityCards(street, m.group('CARDS').split(', ')) hand.setCommunityCards(street, m.group('CARDS').split(', '))
def readBlinds(self, hand): def readBlinds(self, hand):
log.debug( _("readBlinds starting") ) #log.debug( _("readBlinds starting, hand=") + "\n["+hand.handText+"]" )
try: try:
m = self.re_PostSB.search(hand.handText) m = self.re_PostSB.search(hand.handText)
if m is None:
log.debug( _("re_postSB failed, hand=") + hand.handText )
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB')) hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
except: # no small blind except exceptions.AttributeError: # no small blind
log.debug( _("readBlinds in noSB exception")+str(sys.exc_info()) ) log.debug( _("readBlinds in noSB exception - no SB created")+str(sys.exc_info()) )
hand.addBlind(None, None, None) #hand.addBlind(None, None, None)
for a in self.re_PostBB.finditer(hand.handText): for a in self.re_PostBB.finditer(hand.handText):
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB')) hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
for a in self.re_PostBoth.finditer(hand.handText): for a in self.re_PostBoth.finditer(hand.handText):
@ -289,7 +320,7 @@ class OnGame(HandHistoryConverter):
m = self.re_Action.finditer(hand.streets[street]) m = self.re_Action.finditer(hand.streets[street])
for action in m: for action in m:
acts = action.groupdict() acts = action.groupdict()
#print "DEBUG: acts: %s" %acts #log.debug("readaction: acts: %s" %acts)
if action.group('ATYPE') == ' raises': if action.group('ATYPE') == ' raises':
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') ) hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
elif action.group('ATYPE') == ' calls': elif action.group('ATYPE') == ' calls':
@ -314,18 +345,22 @@ class OnGame(HandHistoryConverter):
hand.addShownCards(cards, shows.group('PNAME')) hand.addShownCards(cards, shows.group('PNAME'))
def readCollectPot(self,hand): def readCollectPot(self,hand):
for m in self.re_CollectPot.finditer(hand.handText): for m in self.re_Pot.finditer(hand.handText):
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT')) for splitpot in m.group('POT').split(','):
for m in self.re_CollectPot.finditer(splitpot):
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT'))
def readShownCards(self,hand): def readShownCards(self,hand):
return for m in self.re_ShownCards.finditer(hand.handText):
#for m in self.rexx.collect_pot_re.finditer(hand.string): cards = m.group('CARDS')
#if m.group('CARDS') is not None: cards = cards.split(', ') # needs to be a list, not a set--stud needs the order
#cards = m.group('CARDS')
#cards = set(cards.split(',')) (shown, mucked) = (False, False)
#hand.addShownCards(cards=None, player=m.group('PNAME'), holeandboard=cards) if m.group('CARDS') is not None:
shown = True
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.20.905 plus git\n" "Project-Id-Version: 0.20.905 plus git\n"
"POT-Creation-Date: 2010-08-26 18:52+CEST\n" "POT-Creation-Date: 2010-08-26 18:52+CEST\n"
"PO-Revision-Date: 2010-08-26 01:40+0200\n" "PO-Revision-Date: 2010-08-28 12:32+0200\n"
"Last-Translator: Ferenc Erki <erkiferenc@gmail.com>\n" "Last-Translator: Ferenc Erki <erkiferenc@gmail.com>\n"
"Language-Team: Hungarian <erkiferenc@gmail.com>\n" "Language-Team: Hungarian <erkiferenc@gmail.com>\n"
"Language: hu\n" "Language: hu\n"
@ -156,7 +156,7 @@ msgstr "A %s konfigurációs fájl nem található. Alapértelmezések használa
#: Configuration.py:690 #: Configuration.py:690
msgid "Reading configuration file %s" msgid "Reading configuration file %s"
msgstr "%s konfigurációs fájl használata" msgstr "%s konfigurációs fájl olvasása"
#: Configuration.py:691 #: Configuration.py:691
msgid "" msgid ""
@ -164,11 +164,11 @@ msgid ""
"Reading configuration file %s\n" "Reading configuration file %s\n"
msgstr "" msgstr ""
"\n" "\n"
"%s konfigurációs fájl használata\n" "%s konfigurációs fájl olvasása\n"
#: Configuration.py:696 #: Configuration.py:696
msgid "Error parsing %s. See error log file." msgid "Error parsing %s. See error log file."
msgstr "Hiba a(z) %s olvasása közben. Nézz bele a naplófájlba." msgstr "Hiba a(z) %s értelmezése közben. Nézz bele a hibanaplóba."
#: Database.py:74 #: Database.py:74
msgid "Not using sqlalchemy connection pool." msgid "Not using sqlalchemy connection pool."
@ -232,11 +232,11 @@ msgstr "ERROR: a(z) %s lekérdezés eredményének nem a player_id az első oszl
#: Database.py:907 #: Database.py:907
msgid "getLastInsertId(): problem fetching insert_id? ret=%d" msgid "getLastInsertId(): problem fetching insert_id? ret=%d"
msgstr "getLastInsertId(): probléma insert_id lekérdezése közben? ret=%d" msgstr "getLastInsertId(): probléma az insert_id lekérdezése közben? ret=%d"
#: Database.py:919 #: Database.py:919
msgid "getLastInsertId(%s): problem fetching lastval? row=%d" msgid "getLastInsertId(%s): problem fetching lastval? row=%d"
msgstr "getLastInsertId(%s): probléma lastval lekérdezése közben? sor=%d" msgstr "getLastInsertId(%s): probléma a lastval lekérdezése közben? sor=%d"
#: Database.py:926 #: Database.py:926
msgid "getLastInsertId(): unknown backend: %d" msgid "getLastInsertId(): unknown backend: %d"
@ -398,7 +398,7 @@ msgstr "Hiba analyze közben:"
#: Database.py:1563 #: Database.py:1563
msgid "Analyze took %.1f seconds" msgid "Analyze took %.1f seconds"
msgstr "Analyze %1.f másodpercig tartott" msgstr "Analyze %.1f másodpercig tartott"
#: Database.py:1573 Database.py:1579 #: Database.py:1573 Database.py:1579
msgid "Error during vacuum:" msgid "Error during vacuum:"
@ -854,8 +854,8 @@ msgid ""
"GuiBulkImport done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d " "GuiBulkImport done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d "
"in %s seconds - %.0f/sec" "in %s seconds - %.0f/sec"
msgstr "" msgstr ""
"GuiBulkImport kész: Tárolt: %d \tDuplikáció: %d \tRészleges: %d \tHibák: %d " "GuiBulkImport kész: Tárolt: %d \tDuplikáció: %d \tRészleges: %d \tHibák: %d %"
"%s másodperc alatt - %.0f/mp" "s másodperc alatt - %.0f/mp"
#: GuiDatabase.py:106 GuiLogView.py:96 #: GuiDatabase.py:106 GuiLogView.py:96
msgid "Refresh" msgid "Refresh"
@ -1242,7 +1242,7 @@ msgstr "A naplófájl "
#: HUD_main.pyw:90 #: HUD_main.pyw:90
msgid "HUD_main starting: using db name = %s" msgid "HUD_main starting: using db name = %s"
msgstr "HUD_main indítás: " msgstr "HUD_main indítás: %s adatbázis használata"
#: HUD_main.pyw:95 #: HUD_main.pyw:95
msgid "Note: error output is being diverted to:\n" msgid "Note: error output is being diverted to:\n"
@ -1306,15 +1306,15 @@ msgstr "\"%s\" nevű asztal már nem létezik\n"
#: HUD_main.pyw:321 #: HUD_main.pyw:321
msgid "" msgid ""
"HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f," "HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f,%"
"%4.3f,%4.3f)" "4.3f,%4.3f)"
msgstr "" msgstr ""
"HUD_main.read_stdin: leosztás beolvasva %4.3f mp alatt (%4.3f,%4.3f,%4.3f," "HUD_main.read_stdin: leosztás beolvasva %4.3f mp alatt (%4.3f,%4.3f,%4.3f,%"
"%4.3f,%4.3f,%4.3f)" "4.3f,%4.3f,%4.3f)"
#: HUD_run_me.py:45 #: HUD_run_me.py:45
msgid "HUD_main starting\n" msgid "HUD_main starting\n"
msgstr "HUD_main indítása\n" msgstr "HUD_main indítás\n"
#: HUD_run_me.py:51 TournamentTracker.py:317 #: HUD_run_me.py:51 TournamentTracker.py:317
msgid "Using db name = %s\n" msgid "Using db name = %s\n"
@ -1772,7 +1772,7 @@ msgstr "utcTime:"
#: HandHistoryConverter.py:685 #: HandHistoryConverter.py:685
msgid "Unable to create output directory %s for HHC!" msgid "Unable to create output directory %s for HHC!"
msgstr "A %s kimeneti könyvtár nem hozható létre a feldolgozó számára'" msgstr "A %s kimeneti könyvtár nem hozható létre a feldolgozó számára!"
#: HandHistoryConverter.py:686 #: HandHistoryConverter.py:686
msgid "*** ERROR: UNABLE TO CREATE OUTPUT DIRECTORY" msgid "*** ERROR: UNABLE TO CREATE OUTPUT DIRECTORY"
@ -3136,8 +3136,8 @@ msgstr ""
"GPL2 vagy újabb licensszel.\n" "GPL2 vagy újabb licensszel.\n"
"A Windows telepítő csomag tartalmaz MIT licensz hatálya alá eső részeket " "A Windows telepítő csomag tartalmaz MIT licensz hatálya alá eső részeket "
"is.\n" "is.\n"
"A licenszek szövegét megtalálod az fpdb főkönyvtárában az agpl-3.0.txt, " "A licenszek szövegét megtalálod az fpdb főkönyvtárában az agpl-3.0.txt, gpl-"
"gpl-2.0.txt, gpl-3.0.txt és mit.txt fájlokban." "2.0.txt, gpl-3.0.txt és mit.txt fájlokban."
#: fpdb.pyw:1078 #: fpdb.pyw:1078
msgid "Help" msgid "Help"
@ -3265,7 +3265,7 @@ msgid ""
"Error No.%s please send the hand causing this to fpdb-main@lists.sourceforge." "Error No.%s please send the hand causing this to fpdb-main@lists.sourceforge."
"net so we can fix the problem." "net so we can fix the problem."
msgstr "" msgstr ""
"%s számú hiba. Kérlek küldd el az ezt okozo leosztást az fpdb-main@lists." "%s számú hiba. Kérlek küldd el az ezt okozó leosztást az fpdb-main@lists."
"sourceforge.net címre, hogy ki tudjuk javítani a hibát." "sourceforge.net címre, hogy ki tudjuk javítani a hibát."
#: fpdb_import.py:520 #: fpdb_import.py:520