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

This commit is contained in:
Worros 2010-02-07 19:56:46 +08:00
commit 55cb03b4f2
9 changed files with 151 additions and 60 deletions

View File

@ -42,6 +42,9 @@ def to_utf8(s):
except UnicodeDecodeError:
sys.stderr.write('Could not convert: "%s"\n' % s)
raise
except UnicodeEncodeError:
sys.stderr.write('Could not encode: "%s"\n' % s)
raise
except TypeError: # TypeError is raised when we give unicode() an already encoded string
return s
@ -54,13 +57,21 @@ def to_db_utf8(s):
except UnicodeDecodeError:
sys.stderr.write('Could not convert: "%s"\n' % s)
raise
except UnicodeEncodeError:
sys.stderr.write('Could not encode: "%s"\n' % s)
raise
def to_gui(s):
if not_needed3: return s
try:
(_out, _len) = encoder_to_sys.encode(s)
# we usually don't want to use 'replace' but this is only for displaying
# in the gui so it doesn't matter if names are missing an accent or two
(_out, _len) = encoder_to_sys.encode(s, 'replace')
return _out
except UnicodeDecodeError:
sys.stderr.write('Could not convert: "%s"\n' % s)
raise
except UnicodeEncodeError:
sys.stderr.write('Could not encode: "%s"\n' % s)
raise

View File

@ -380,8 +380,8 @@ class Database:
import sqlite3
if use_pool:
sqlite3 = pool.manage(sqlite3, pool_size=1)
else:
log.warning("SQLite won't work well without 'sqlalchemy' installed.")
#else:
# log.warning("SQLite won't work well without 'sqlalchemy' installed.")
if database != ":memory:":
if not os.path.isdir(self.config.dir_database):

View File

@ -194,8 +194,11 @@ class GuiAutoImport (threading.Thread):
widget.set_label(u' _Stop Autoimport ')
if self.pipe_to_hud is None:
if os.name == 'nt':
path = sys.path[0].replace('\\','\\\\')
command = 'python "'+path+'\\HUD_main.py" ' + self.settings['cl_options']
if sys.argv[0] == 'fpdb.exe':
command = 'HUD_main.exe'
else:
path = sys.path[0].replace('\\','\\\\')
command = 'python "'+path+'\\HUD_main.py" ' + self.settings['cl_options']
bs = 0
else:
command = os.path.join(sys.path[0], 'HUD_main.py')
@ -208,7 +211,8 @@ class GuiAutoImport (threading.Thread):
universal_newlines=True)
except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
self.addText( "\n*** GuiAutoImport Error opening pipe: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]))
#self.addText( "\n*** GuiAutoImport Error opening pipe: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]))
self.addText( "\n*** GuiAutoImport Error opening pipe: " + traceback.format_exc() )
else:
for site in self.input_settings:
self.importer.addImportDirectory(self.input_settings[site][0], True, site, self.input_settings[site][1])

View File

@ -69,17 +69,16 @@ class HUD_main(object):
# This class mainly provides state for controlling the multiple HUDs.
def __init__(self, db_name = 'fpdb'):
try:
print "HUD_main: starting ..."
self.db_name = db_name
self.config = Configuration.Config(file=options.config, dbname=db_name)
log = Configuration.get_logger("logging.conf", "hud", log_dir=self.config.dir_log)
log.info("HUD_main starting")
log.info("Using db name = %s" % (db_name))
print "\nHUD_main: starting ..."
self.db_name = db_name
self.config = Configuration.Config(file=options.config, dbname=db_name)
log = Configuration.get_logger("logging.conf", "hud", log_dir=self.config.dir_log)
log.info("HUD_main starting: using db name = %s" % (db_name))
try:
if not options.errorsToConsole:
fileName = os.path.join(self.config.dir_log, 'HUD-errors.txt')
print "Note: error output is being diverted to\n"+fileName \
print "Note: error output is being diverted to:\n"+fileName \
+ "\nAny major error will be reported there _only_.\n"
errorFile = open(fileName, 'w', 0)
sys.stderr = errorFile
@ -101,8 +100,9 @@ class HUD_main(object):
self.main_window.set_title("HUD Main Window")
self.main_window.show_all()
except:
log.debug("commit "+str(i)+" failed: info=" + str(sys.exc_info())
+ " value=" + str(sys.exc_value))
log.error( "*** Exception in HUD_main.init() *** " )
for e in traceback.format_tb(sys.exc_info()[2]):
log.error(e)
def destroy(self, *args): # call back for terminating the main eventloop
@ -139,8 +139,9 @@ class HUD_main(object):
self.hud_dict[table_name].update(new_hand_id, self.config)
self.hud_dict[table_name].reposition_windows()
except:
print "*** Exception in HUD_main::idle_func() *** "
traceback.print_stack()
log.error( "*** Exception in HUD_main::idle_func() *** " )
for e in traceback.format_tb(sys.exc_info()[2]):
log.error(e)
finally:
gtk.gdk.threads_leave()
return False
@ -247,8 +248,8 @@ class HUD_main(object):
try:
self.hud_dict[temp_key].stat_dict = stat_dict
except KeyError: # HUD instance has been killed off, key is stale
sys.stderr.write('hud_dict[%s] was not found\n' % temp_key)
sys.stderr.write('will not send hand\n')
log.error('hud_dict[%s] was not found\n' % temp_key)
log.error('will not send hand\n')
# Unlocks table, copied from end of function
self.db_connection.connection.rollback()
return
@ -282,7 +283,7 @@ class HUD_main(object):
# If no client window is found on the screen, complain and continue
if type == "tour":
table_name = "%s %s" % (tour_number, tab_number)
# sys.stderr.write("HUD create: table name "+table_name+" not found, skipping.\n")
# log.error("HUD create: table name "+table_name+" not found, skipping.\n")
log.error("HUD create: table name %s not found, skipping." % table_name)
else:
tablewindow.max = max
@ -291,7 +292,7 @@ class HUD_main(object):
if hasattr(tablewindow, 'number'):
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
else:
sys.stderr.write('Table "%s" no longer exists\n' % table_name)
log.error('Table "%s" no longer exists\n' % table_name)
t6 = time.time()
log.info("HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f,%4.3f,%4.3f)"

View File

@ -26,6 +26,10 @@ Create and manage the hud overlays.
import os
import sys
import logging
# logging has been set up in fpdb.py or HUD_main.py, use their settings:
log = logging.getLogger("hud")
# pyGTK modules
import pygtk
import gtk
@ -365,7 +369,7 @@ class Hud:
self.create(*self.creation_attrs)
self.update(self.hand, self.config)
except Exception, e:
print "Exception:",str(e)
log.error("Exception:",str(e))
pass
def set_aggregation(self, widget, val):
@ -377,7 +381,7 @@ class Hud:
if self.hud_params['h_agg_bb_mult'] != num \
and getattr(self, 'h_aggBBmultItem'+str(num)).get_active():
print 'set_player_aggregation', num
log.debug('set_player_aggregation', num)
self.hud_params['h_agg_bb_mult'] = num
for mult in ('1', '2', '3', '10', '10000'):
if mult != str(num):
@ -388,7 +392,7 @@ class Hud:
if self.hud_params['agg_bb_mult'] != num \
and getattr(self, 'aggBBmultItem'+str(num)).get_active():
print 'set_opponent_aggregation', num
log.debug('set_opponent_aggregation', num)
self.hud_params['agg_bb_mult'] = num
for mult in ('1', '2', '3', '10', '10000'):
if mult != str(num):
@ -415,7 +419,7 @@ class Hud:
self.hud_params[param] = 'E'
getattr(self, prefix+'seatsStyleOptionA').set_active(False)
getattr(self, prefix+'seatsStyleOptionC').set_active(False)
print "setting self.hud_params[%s] = %s" % (param, style)
log.debug("setting self.hud_params[%s] = %s" % (param, style))
def set_hud_style(self, widget, val):
(player_opp, style) = val
@ -438,7 +442,7 @@ class Hud:
self.hud_params[param] = 'T'
getattr(self, prefix+'hudStyleOptionA').set_active(False)
getattr(self, prefix+'hudStyleOptionS').set_active(False)
print "setting self.hud_params[%s] = %s" % (param, style)
log.debug("setting self.hud_params[%s] = %s" % (param, style))
def update_table_position(self):
if os.name == 'nt':
@ -515,7 +519,7 @@ class Hud:
# ask each aux to save its layout back to the config object
[aux.save_layout() for aux in self.aux_windows]
# save the config object back to the file
print "saving new xml file"
print "Updating config file"
self.config.save()
def adj_seats(self, hand, config):
@ -611,8 +615,8 @@ class Hud:
try:
statd = self.stat_dict[s]
except KeyError:
print "KeyError at the start of the for loop in update in hud_main. How this can possibly happen is totally beyond my comprehension. Your HUD may be about to get really weird. -Eric"
print "(btw, the key was ", s, " and statd is...", statd
log.error("KeyError at the start of the for loop in update in hud_main. How this can possibly happen is totally beyond my comprehension. Your HUD may be about to get really weird. -Eric")
log.error("(btw, the key was ", s, " and statd is...", statd)
continue
try:
self.stat_windows[statd['seat']].player_id = statd['player_id']

View File

@ -24,6 +24,10 @@ Routines for detecting and handling poker client windows for MS Windows.
# Standard Library modules
import re
import logging
# logging has been set up in fpdb.py or HUD_main.py, use their settings:
log = logging.getLogger("hud")
# pyGTK modules
import pygtk
import gtk
@ -62,19 +66,19 @@ class Table(Table_Window):
try:
if self.window == None:
print "Window %s not found. Skipping." % search_string
log.error( "Window %s not found. Skipping." % search_string )
return None
except AttributeError:
print "self.window doesn't exist? why?"
log.error( "self.window doesn't exist? why?" )
return None
(x, y, width, height) = win32gui.GetWindowRect(hwnd)
print "x = %s y = %s width = %s height = %s" % (x, y, width, height)
log.debug("x = %s y = %s width = %s height = %s" % (x, y, width, height))
self.x = int(x) + b_width
self.y = int(y) + tb_height
self.width = width - x
self.height = height - y
print "x = %s y = %s width = %s height = %s" % (self.x, self.y, self.width, self.height)
log.debug("x = %s y = %s width = %s height = %s" % (self.x, self.y, self.width, self.height))
#self.height = int(height) - b_width - tb_height
#self.width = int(width) - 2*b_width

View File

@ -906,14 +906,16 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
if not options.errorsToConsole:
fileName = os.path.join(self.config.dir_log, 'fpdb-errors.txt')
print "\nNote: error output is being diverted to fpdb-errors.txt and HUD-errors.txt in\n" \
+ self.config.dir_log + "Any major error will be reported there _only_.\n"
print "\nNote: error output is being diverted to fpdb-errors.txt and HUD-errors.txt in:\n" \
+ self.config.dir_log + "\nAny major error will be reported there _only_.\n"
errorFile = open(fileName, 'w', 0)
sys.stderr = errorFile
self.statusIcon = gtk.StatusIcon()
if os.path.exists(os.path.join(sys.path[0], '../gfx/fpdb-cards.png')):
self.statusIcon.set_from_file(os.path.join(sys.path[0], '../gfx/fpdb-cards.png'))
# use getcwd() here instead of sys.path[0] so that py2exe works:
cards = os.path.join(os.getcwd(), '..','gfx','fpdb-cards.png')
if os.path.exists(cards):
self.statusIcon.set_from_file(cards)
elif os.path.exists('/usr/share/pixmaps/fpdb-cards.png'):
self.statusIcon.set_from_file('/usr/share/pixmaps/fpdb-cards.png')
else:

View File

@ -22,29 +22,78 @@ Py2exe script for fpdb.
########################################################################
#TODO: change GuiAutoImport so that it knows to start HUD_main.exe, when appropriate
#TODO:
# include the lib needed to handle png files in mucked
# get rid of all the uneeded libraries (e.g., pyQT)
# think about an installer
# done: change GuiAutoImport so that it knows to start HUD_main.exe, when appropriate
#HOW TO USE this script:
#
# cd to the folder where this script is stored, usually .../pyfpdb.
# If there are build and dist subfolders present , delete them to get
# rid of earlier builds.
# Run the script with "py2exe_setup.py py2exe"
# You will frequently get messages about missing .dll files. E. g.,
#- cd to the folder where this script is stored, usually .../pyfpdb.
# [If there are build and dist subfolders present , delete them to get
# rid of earlier builds. Update: script now does this for you]
#- Run the script with "py2exe_setup.py py2exe"
#- You will frequently get messages about missing .dll files. E. g.,
# MSVCP90.dll. These are somewhere in your windows install, so you
# can just copy them to your working folder.
# If it works, you'll have 2 new folders, build and dist. Build is
# working space and should be deleted. Dist contains the files to be
# distributed. Last, you must copy the etc/, lib/ and share/ folders
# from your gtk/bin/ folder to the dist folder. (the whole folders, not
# just the contents) You can (should) then prune the etc/, lib/ and
# share/ folders to remove components we don't need.
# can just copy them to your working folder. (or just assume other
# person will have them? any copyright issues with including them?)
#- If it works, you'll have 3 new folders, build and dist and gfx. Build is
# working space and should be deleted. Dist and gfx contain the files to be
# distributed.
#- Last, you must copy the etc/, lib/ and share/ folders from your
# gtk/bin/ (just /gtk/?) folder to the dist folder. (the whole folders,
# not just the contents)
#- You can (should) then prune the etc/, lib/ and share/ folders to
# remove components we don't need.
import os
import sys
from distutils.core import setup
import py2exe
import glob
import matplotlib
from datetime import date
def remove_tree(top):
# Delete everything reachable from the directory named in 'top',
# assuming there are no symbolic links.
# CAUTION: This is dangerous! For example, if top == '/', it
# could delete all your disk files.
# sc: Nicked this from somewhere, added the if statement to try
# make it a bit safer
if top in ('build','dist','gfx') and os.path.basename(os.getcwd()) == 'pyfpdb':
#print "removing directory '"+top+"' ..."
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(top)
def test_and_remove(top):
if os.path.exists(top):
if os.path.isdir(top):
remove_tree(top)
else:
print "Unexpected file '"+top+"' found. Exiting."
exit()
# remove build and dist dirs if they exist
test_and_remove('dist')
test_and_remove('build')
test_and_remove('gfx')
today = date.today().strftime('%Y%m%d')
print "\n" + r"Output will be created in \dist\ and \fpdb_XXX_"+today+'\\'
print "Enter value for XXX (any length): ", # the comma means no newline
xxx = sys.stdin.readline().rstrip()
dist_dir = r'..\fpdb-' + xxx + '-' + today + '-exe'
print
setup(
name = 'fpdb',
@ -57,17 +106,26 @@ setup(
],
options = {'py2exe': {
'packages' :'encodings',
'includes' : 'cairo, pango, pangocairo, atk, gobject, PokerStarsToFpdb',
'excludes' : '_tkagg, _agg2, cocoaagg, fltkagg',
'dll_excludes': 'libglade-2.0-0.dll',
'packages' : ['encodings', 'matplotlib'],
'includes' : ['cairo', 'pango', 'pangocairo', 'atk', 'gobject'
,'PokerStarsToFpdb', 'matplotlib.numerix.random_array'],
'excludes' : ['_gtkagg', '_tkagg', '_agg2', 'cocoaagg', 'fltkagg'],
'dll_excludes': ['libglade-2.0-0.dll', 'libgdk-win32-2.0-0.dll'
,'libgobject-2.0-0.dll'],
}
},
data_files = ['HUD_config.xml.example',
'Cards01.png',
'logging.conf',
(r'matplotlibdata', glob.glob(r'c:\python26\Lib\site-packages\matplotlib\mpl-data\*'))
]
# files in 2nd value in tuple are moved to dir named in 1st value
data_files = [('', ['HUD_config.xml.example', 'Cards01.png', 'logging.conf'])
,(dist_dir, [r'..\run_fpdb.bat'])
,( dist_dir + r'\gfx', glob.glob(r'..\gfx\*.*') )
# line below has problem with fonts subdir ('not a regular file')
#,(r'matplotlibdata', glob.glob(r'c:\python25\Lib\site-packages\matplotlib\mpl-data\*'))
] + matplotlib.get_py2exe_datafiles()
)
print '\n' + r'If py2exe was successful move the \dist\ directory '
print 'into \\'+dist_dir+'\\ and rename it as \\pyfpdb\\'
print "Don't forget to add the \\etc \\lib and \\share dirs from your gtk dir\n"

7
run_fpdb.bat Executable file
View File

@ -0,0 +1,7 @@
rem .bat script to run fpdb
cd pyfpdb
fpdb.exe