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

This commit is contained in:
Worros 2010-12-05 02:53:16 +08:00
commit f6b97ab532
11 changed files with 162 additions and 155 deletions

View File

@ -66,7 +66,7 @@ class Carbon(HandHistoryConverter):
# Static regexes # Static regexes
re_SplitHands = re.compile(r'</game>\n+(?=<game)') re_SplitHands = re.compile(r'</game>\n+(?=<game)')
re_TailSplitHands = re.compile(r'(</game>)') re_TailSplitHands = re.compile(r'(</game>)')
re_GameInfo = re.compile(r'<description type="(?P<GAME>[a-zA-Z ]+)" stakes="(?P<LIMIT>[a-zA-Z ]+) ?\(\$(?P<SB>[.0-9]+)/\$(?P<BB>[.0-9]+)?\)"/>', re.MULTILINE) re_GameInfo = re.compile(r'<description type="(?P<GAME>[a-zA-Z ]+)" stakes="(?P<LIMIT>[a-zA-Z ]+) \(\$(?P<SB>[.0-9]+)/\$(?P<BB>[.0-9]+)\)"/>', re.MULTILINE)
re_HandInfo = re.compile(r'<game id="(?P<HID1>[0-9]+)-(?P<HID2>[0-9]+)" starttime="(?P<DATETIME>[0-9]+)" numholecards="2" gametype="2" realmoney="true" data="[0-9]+\|(?P<TABLE>[^\(]+)', re.MULTILINE) re_HandInfo = re.compile(r'<game id="(?P<HID1>[0-9]+)-(?P<HID2>[0-9]+)" starttime="(?P<DATETIME>[0-9]+)" numholecards="2" gametype="2" realmoney="true" data="[0-9]+\|(?P<TABLE>[^\(]+)', re.MULTILINE)
re_Button = re.compile(r'<players dealer="(?P<BUTTON>[0-9]+)">') re_Button = re.compile(r'<players dealer="(?P<BUTTON>[0-9]+)">')
re_PlayerInfo = re.compile(r'<player seat="(?P<SEAT>[0-9]+)" nickname="(?P<PNAME>.+)" balance="\$(?P<CASH>[.0-9]+)" dealtin="(?P<DEALTIN>(true|false))" />', re.MULTILINE) re_PlayerInfo = re.compile(r'<player seat="(?P<SEAT>[0-9]+)" nickname="(?P<PNAME>.+)" balance="\$(?P<CASH>[.0-9]+)" dealtin="(?P<DEALTIN>(true|false))" />', re.MULTILINE)

View File

@ -204,15 +204,18 @@ class GuiAutoImport (threading.Thread):
# That is not correct. It should open another dir for importing while piping the # That is not correct. It should open another dir for importing while piping the
# results to the same pipe. This means that self.path should be a a list of dirs # results to the same pipe. This means that self.path should be a a list of dirs
# to watch. # to watch.
if widget.get_active(): # toggled on if data == "autostart" or (widget == self.startButton and self.startButton.get_active()):
self.startButton.set_active(True)
# - Does the lock acquisition need to be more sophisticated for multiple dirs? # - Does the lock acquisition need to be more sophisticated for multiple dirs?
# (see comment above about what to do if pipe already open) # (see comment above about what to do if pipe already open)
# - Ideally we want to release the lock if the auto-import is killed by some # - Ideally we want to release the lock if the auto-import is killed by some
# kind of exception - is this possible? # kind of exception - is this possible?
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired if self.settings['global_lock'].acquire(wait=False, source="AutoImport"): # returns false immediately if lock not acquired
self.addText(_("\nGlobal lock taken ... Auto Import Started.\n")) self.addText(_("\nGlobal lock taken ... Auto Import Started.\n"))
self.doAutoImportBool = True self.doAutoImportBool = True
widget.set_label(_(u' _Stop Auto Import ')) self.startButton.set_label(_(u' _Stop Auto Import '))
while gtk.events_pending(): # change the label NOW don't wait for the pipe to open
gtk.main_iteration(False)
if self.pipe_to_hud is None: if self.pipe_to_hud is None:
if Configuration.FROZEN: # if py2exe, run hud_main.exe if Configuration.FROZEN: # if py2exe, run hud_main.exe
path = Configuration.EXEC_PATH path = Configuration.EXEC_PATH
@ -224,15 +227,14 @@ class GuiAutoImport (threading.Thread):
command = 'pythonw "'+path+'\\HUD_main.pyw" ' + self.settings['cl_options'] command = 'pythonw "'+path+'\\HUD_main.pyw" ' + self.settings['cl_options']
else: else:
command = 'python "'+path+'\\HUD_main.pyw" ' + self.settings['cl_options'] command = 'python "'+path+'\\HUD_main.pyw" ' + self.settings['cl_options']
# uncomment above line if you want hud_main stdout to work ... and make sure you are running fpdb.py using python.exe not pythonw.exe
bs = 0 bs = 0
else: else:
command = os.path.join(sys.path[0], 'HUD_main.pyw') command = os.path.join(sys.path[0], 'HUD_main.pyw')
command = [command, ] + string.split(self.settings['cl_options']) command = [command, ] + string.split(self.settings['cl_options'])
bs = 1 bs = 1
try:
print _("opening pipe to HUD") print _("opening pipe to HUD")
try:
if Configuration.FROZEN or (os.name == "nt" and win32console.GetConsoleWindow()) == 0: if Configuration.FROZEN or (os.name == "nt" and win32console.GetConsoleWindow()) == 0:
self.pipe_to_hud = subprocess.Popen(command, bufsize=bs, self.pipe_to_hud = subprocess.Popen(command, bufsize=bs,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
@ -242,8 +244,6 @@ class GuiAutoImport (threading.Thread):
) )
else: else:
self.pipe_to_hud = subprocess.Popen(command, bufsize=bs, stdin=subprocess.PIPE, universal_newlines=True) self.pipe_to_hud = subprocess.Popen(command, bufsize=bs, stdin=subprocess.PIPE, universal_newlines=True)
#self.pipe_to_hud.stdout.close()
#self.pipe_to_hud.stderr.close()
except: except:
err = traceback.extract_tb(sys.exc_info()[2])[-1] 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]))
@ -268,8 +268,9 @@ class GuiAutoImport (threading.Thread):
if self.pipe_to_hud.poll() is not None: if self.pipe_to_hud.poll() is not None:
self.addText(_("\n * Stop Auto Import: HUD already terminated")) self.addText(_("\n * Stop Auto Import: HUD already terminated"))
else: else:
self.pipe_to_hud.terminate()
#print >>self.pipe_to_hud.stdin, "\n" #print >>self.pipe_to_hud.stdin, "\n"
self.pipe_to_hud.communicate('\n') # waits for process to terminate # self.pipe_to_hud.communicate('\n') # waits for process to terminate
self.pipe_to_hud = None self.pipe_to_hud = None
self.startButton.set_label(_(u' Start _Auto Import ')) self.startButton.set_label(_(u' Start _Auto Import '))

View File

@ -102,6 +102,17 @@ class HUD_main(object):
# a main window # a main window
self.main_window = gtk.Window() self.main_window = gtk.Window()
if options.minimized:
self.main_window.iconify()
if options.hidden:
self.main_window.hide()
if options.xloc is not None or options.yloc is not None:
if options.xloc is None:
options.xloc = 0
if options.yloc is None:
options.yloc = 0
self.main_window.move(options.xloc,options.yloc)
self.main_window.connect("client_moved", self.client_moved) self.main_window.connect("client_moved", self.client_moved)
self.main_window.connect("client_resized", self.client_resized) self.main_window.connect("client_resized", self.client_resized)
self.main_window.connect("client_destroyed", self.client_destroyed) self.main_window.connect("client_destroyed", self.client_destroyed)
@ -120,6 +131,7 @@ class HUD_main(object):
self.main_window.set_icon_from_file('/usr/share/pixmaps/fpdb-cards.png') self.main_window.set_icon_from_file('/usr/share/pixmaps/fpdb-cards.png')
else: else:
self.main_window.set_icon_stock(gtk.STOCK_HOME) self.main_window.set_icon_stock(gtk.STOCK_HOME)
if not options.hidden:
self.main_window.show_all() self.main_window.show_all()
gobject.timeout_add(100, self.check_tables) gobject.timeout_add(100, self.check_tables)
@ -356,6 +368,7 @@ class HUD_main(object):
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards) self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
else: else:
log.error(_('Table "%s" no longer exists\n') % table_name) log.error(_('Table "%s" no longer exists\n') % table_name)
return
t6 = time.time() 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)") log.info(_("HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f,%4.3f,%4.3f)")
@ -363,7 +376,10 @@ class HUD_main(object):
self.db_connection.connection.rollback() self.db_connection.connection.rollback()
if type == "tour": if type == "tour":
try:
self.hud_dict[temp_key].table.check_table_no(self.hud_dict[temp_key]) self.hud_dict[temp_key].table.check_table_no(self.hud_dict[temp_key])
except KeyError:
pass
if __name__== "__main__": if __name__== "__main__":

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#Copyright 2010 Chaz Littlejohn #Copyright 2010 Chaz Littlejohn
@ -28,21 +28,18 @@ import Configuration
import Database import Database
__ARCHIVE_PRE_HEADER_REGEX='^Hand #(\d+)\s*$|\*{20}\s#\s\d+\s\*+\s+' __ARCHIVE_PRE_HEADER_REGEX='^Hand #(\d+)\s*$|\*{20}\s#\s\d+\s\*+\s+'
re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX, re.MULTILINE) re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX)
class IdentifySite: class IdentifySite:
def __init__(self, config, in_path = '-'): def __init__(self, config, in_path = '-'):
self.in_path = in_path self.in_path = in_path
self.config = config self.config = config
self.db = Database.Database(self.config) self.db = Database.Database(config)
self.sitelist = {} self.sitelist = {}
self.filelist = {} self.filelist = {}
self.generateSiteList() self.generateSiteList()
if os.path.isdir(self.in_path):
self.walkDirectory(self.in_path, self.sitelist) self.walkDirectory(self.in_path, self.sitelist)
else:
self.idSite(self.in_path, self.sitelist)
def generateSiteList(self): def generateSiteList(self):
"""Generates a ordered dictionary of site, filter and filter name for each site in hhcs""" """Generates a ordered dictionary of site, filter and filter name for each site in hhcs"""
@ -83,7 +80,7 @@ class IdentifySite:
for kodec in self.__listof(obj.codepage): for kodec in self.__listof(obj.codepage):
try: try:
in_fh = codecs.open(file, 'r', kodec) in_fh = codecs.open(file, 'r', kodec)
whole_file = in_fh.read(2000) whole_file = in_fh.read()
in_fh.close() in_fh.close()
if info[2] in ('OnGame', 'Winamax'): if info[2] in ('OnGame', 'Winamax'):
@ -97,7 +94,7 @@ class IdentifySite:
if re_SplitArchive.search(whole_file): if re_SplitArchive.search(whole_file):
archive = True archive = True
if m: if m:
self.filelist[file] = [info[1]] + [kodec] + [archive] self.filelist[file] = [info[0]] + [info[1]] + [kodec] + [archive]
break break
except: except:
pass pass

View File

@ -59,8 +59,16 @@ def fpdb_options():
help=_("File to be split is a PokerStars or Full Tilt Poker archive file")) help=_("File to be split is a PokerStars or Full Tilt Poker archive file"))
parser.add_option("-n", "--numhands", dest="hands", default="100", type="int", parser.add_option("-n", "--numhands", dest="hands", default="100", type="int",
help=_("How many hands do you want saved to each file. Default is 100")) help=_("How many hands do you want saved to each file. Default is 100"))
parser.add_option("-w", "--workerid", dest="workerid", default="0", type="int", parser.add_option("--xloc", dest="xloc", default=None, type="int",
help=_("Specifies the worker id running the script")) help=_("X location to open window"))
parser.add_option("--yloc", dest="yloc", default=None, type="int",
help=_("Y location to open Window"))
parser.add_option("--autoimport", action="store_true", dest="autoimport",
help=_("Auto-start Auto-import"))
parser.add_option("--minimized", action="store_true", dest="minimized",
help=_("Start Minimized"))
parser.add_option("--hidden", action="store_true", dest="hidden",
help=_("Start Hidden"))
(options, argv) = parser.parse_args() (options, argv) = parser.parse_args()

View File

@ -298,7 +298,7 @@ class PokerStars(HandHistoryConverter):
if key == 'BUTTON': if key == 'BUTTON':
hand.buttonpos = info[key] hand.buttonpos = info[key]
if key == 'MAX': if key == 'MAX':
if info[key]: hand.maxseats = int(info[key]) hand.maxseats = int(info[key])
if key == 'MIXED': if key == 'MIXED':
hand.mixed = self.mixes[info[key]] if info[key] is not None else None hand.mixed = self.mixes[info[key]] if info[key] is not None else None

View File

@ -1,22 +1,19 @@
#!/usr/bin/env python #!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2010, Chaz Littlejohn #Copyright 2010 Chaz Littlejohn
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU Affero General Public License as published by
#the Free Software Foundation, version 3 of the License.
# #
# This program is free software; you can redistribute it and/or modify #This program is distributed in the hope that it will be useful,
# it under the terms of the GNU General Public License as published by #but WITHOUT ANY WARRANTY; without even the implied warranty of
# the Free Software Foundation; either version 2 of the License, or #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# (at your option) any later version. #GNU General Public License for more details.
# #
# This program is distributed in the hope that it will be useful, #You should have received a copy of the GNU Affero General Public License
# but WITHOUT ANY WARRANTY; without even the implied warranty of #along with this program. If not, see <http://www.gnu.org/licenses/>.
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #In the "official" distribution you can find the license in agpl-3.0.txt.
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
########################################################################
import L10n import L10n
_ = L10n.get_translation() _ = L10n.get_translation()
@ -31,7 +28,6 @@ import Options
import Configuration import Configuration
from Exceptions import * from Exceptions import *
from cStringIO import StringIO from cStringIO import StringIO
import time
(options, argv) = Options.fpdb_options() (options, argv) = Options.fpdb_options()
@ -41,7 +37,7 @@ codepage = ["utf-16", "utf-8", "cp1252"]
class SplitHandHistory: class SplitHandHistory:
def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False, workerid = 0): def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False):
self.config = config self.config = config
self.in_path = in_path self.in_path = in_path
self.out_path = out_path self.out_path = out_path
@ -54,25 +50,22 @@ class SplitHandHistory:
self.line_addendum = None self.line_addendum = None
self.filedone = False self.filedone = False
self.timestamp = str(time.time())
self.workerid = '%02d' % workerid
#Acquire re_SplitHands for this hh #Acquire re_SplitHands for this hh
self.filter_name = filter.replace("ToFpdb", "") filter_name = filter.replace("ToFpdb", "")
mod = __import__(filter) mod = __import__(filter)
obj = getattr(mod, self.filter_name, None) obj = getattr(mod, filter_name, None)
self.re_SplitHands = obj.re_SplitHands self.re_SplitHands = obj.re_SplitHands
#Determine line delimiter type if any #Determine line delimiter type if any
if self.re_SplitHands.match('\n\n\n'):
self.line_delimiter = '\n\n\n'
if self.re_SplitHands.match('\n\n'): if self.re_SplitHands.match('\n\n'):
self.line_delimiter = '\n\n' self.line_delimiter = '\n\n'
if self.re_SplitHands.match('\n\n\n'):
self.line_delimiter = '\n\n\n'
#Add new line addendum for sites which match SplitHand to next line as well #Add new line addendum for sites which match SplitHand to next line as well
if self.filter_name == 'OnGame': if filter_name == 'OnGame':
self.line_addendum = '*' self.line_addendum = '*'
if self.filter_name == 'Carbon': if filter_name == 'Carbon':
self.line_addendum = '<game' self.line_addendum = '<game'
#Open the gargantuan file #Open the gargantuan file
@ -82,7 +75,6 @@ class SplitHandHistory:
except IOError: except IOError:
print _('File not found') print _('File not found')
sys.exit(2) sys.exit(2)
self.kodec = kodec
#Split with do_hands_per_file if archive and paragraphs if a regular hh #Split with do_hands_per_file if archive and paragraphs if a regular hh
if self.archive: if self.archive:
@ -113,10 +105,9 @@ class SplitHandHistory:
print _('Nope, will not work (fileno=%d)' % fileno) print _('Nope, will not work (fileno=%d)' % fileno)
sys.exit(2) sys.exit(2)
basename = os.path.splitext(os.path.basename(self.in_path))[0] basename = os.path.splitext(os.path.basename(self.in_path))[0]
name = os.path.join(self.out_path, self.filter_name+'-'+basename+'_'+self.workerid+'_'+self.timestamp+'_%06d.txt' % fileno) name = os.path.join(self.out_path, basename+'-%06d.txt' % fileno)
print '-> %s' % name print '-> %s' % name
newfile = file(name, 'w') newfile = file(name, 'w')
os.chmod(name, 0775)
return newfile return newfile
#Archive Hand Splitter #Archive Hand Splitter
@ -131,11 +122,8 @@ class SplitHandHistory:
except FpdbEndOfFile: except FpdbEndOfFile:
done = True done = True
break break
except UnicodeEncodeError:
print _('Absurd character done messed you up')
sys.exit(2)
except: except:
print _('Unexpected error processing file') print _("Unexpected error processing file")
sys.exit(2) sys.exit(2)
n += 1 n += 1
outfile.close() outfile.close()
@ -186,7 +174,7 @@ class SplitHandHistory:
l = infile.readline() l = infile.readline()
l = l.replace('\r\n', '\n') l = l.replace('\r\n', '\n')
outfile.write(l) outfile.write(l)
l = infile.readline().encode(self.kodec) l = infile.readline()
while len(l) < 3: while len(l) < 3:
l = infile.readline() l = infile.readline()
@ -194,7 +182,7 @@ class SplitHandHistory:
while len(l) > 2: while len(l) > 2:
l = l.replace('\r\n', '\n') l = l.replace('\r\n', '\n')
outfile.write(l) outfile.write(l)
l = infile.readline().encode(self.kodec) l = infile.readline()
outfile.write(self.line_delimiter) outfile.write(self.line_delimiter)
return infile return infile
@ -208,18 +196,12 @@ def main(argv=None):
if argv is None: if argv is None:
argv = sys.argv[1:] argv = sys.argv[1:]
if not options.filename:
options.filename = sys.argv[1]
if not options.config: if not options.config:
options.config = sys.argv[2] options.config = Configuration.Config(file = "HUD_config.test.xml")
if sys.argv[3] == "True":
options.archive = True
if options.filename: if options.filename:
SplitHH = SplitHandHistory(options.config, options.filename, options.outpath, options.hands, SplitHH = SplitHandHistory(options.config, options.filename, options.outpath, options.hands,
options.hhc, options.archive, options.workerid) options.hhc, options.archive)
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View File

@ -58,7 +58,7 @@ limit_game_names = { #fpdb name Stars Name FTP Name
# A window title might have our table name + one of these words/ # A window title might have our table name + one of these words/
# phrases. If it has this word in the title, it is not a table. # phrases. If it has this word in the title, it is not a table.
bad_words = ('History for table:', 'HUD:', 'Chat:', 'FPDBHUD', 'Instant Replay') bad_words = ('History for table:', 'HUD:', 'Chat:', 'FPDBHUD')
# Here are the custom signals we define for allowing the 'client watcher' # Here are the custom signals we define for allowing the 'client watcher'
# thread to communicate with the gui thread. Any time a poker client is # thread to communicate with the gui thread. Any time a poker client is
@ -104,14 +104,12 @@ gobject.signal_new("table_changed", gtk.Window,
# title bar and window borders. To put it another way, this is the # title bar and window borders. To put it another way, this is the
# screen location of (0, 0) in the working window. # screen location of (0, 0) in the working window.
# tournament = Tournament number for a tournament or None for a cash game. # tournament = Tournament number for a tournament or None for a cash game.
# tw.table = tournament: Table number for the tournament. # table = Table number for a tournament.
# cash: full Table name as given by the poker site # gdkhandle =
# tw.gdkhandle = gdk handle for the poker client window - used to nail the hud to the window # window =
# tw.window = is this still used? # parent =
# tw.parent = window object of the parent of the client window, only used in Linux # game =
# tw.game = the poker game being played at the table, only used in mixed games # search_string =
# tw.search_string = regular expression used to find the table, supplied by XToFpdb.py
# tw.key = a string formulated to be a unique id for this table window, used in the hud main window
class Table_Window(object): class Table_Window(object):
def __init__(self, config, site, table_name = None, tournament = None, table_number = None): def __init__(self, config, site, table_name = None, tournament = None, table_number = None):
@ -126,13 +124,13 @@ class Table_Window(object):
self.type = "tour" self.type = "tour"
table_kwargs = dict(tournament = self.tournament, table_number = self.table) table_kwargs = dict(tournament = self.tournament, table_number = self.table)
self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament) self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament)
self.key = "%s Table %s" % (tournament, str(self.table)) self.key = tournament # used as key for the hud_dict in HUD_main
elif table_name is not None: elif table_name is not None:
self.name = table_name self.name = table_name
self.type = "cash" self.type = "cash"
self.tournament = None self.tournament = None
table_kwargs = dict(table_name = table_name) table_kwargs = dict(table_name = table_name)
self.key = table_name # used as key for the hud_dict in HUD_main self.key = table_name
else: else:
return None return None
@ -140,7 +138,10 @@ class Table_Window(object):
self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs) self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs)
self.find_table_parameters() self.find_table_parameters()
# self.gdkhandle = gtk.gdk.window_foreign_new(self.number) try:
self.gdkhandle = gtk.gdk.window_foreign_new(self.number)
except AttributeError: # self.number does not exist, table was closed
return None
geo = self.get_geometry() geo = self.get_geometry()
if geo is None: return None if geo is None: return None
self.width = geo['width'] self.width = geo['width']

View File

@ -14,7 +14,6 @@
#You should have received a copy of the GNU Affero General Public License #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/>. #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 "official" distribution you can find the license in agpl-3.0.txt.
import L10n import L10n
_ = L10n.get_translation() _ = L10n.get_translation()
@ -76,7 +75,7 @@ try:
pygtk.require('2.0') pygtk.require('2.0')
import gtk import gtk
import pango import pango
except: except ImportError:
print _("Unable to load PyGTK modules required for GUI. Please install PyCairo, PyGObject, and PyGTK from www.pygtk.org.") print _("Unable to load PyGTK modules required for GUI. Please install PyCairo, PyGObject, and PyGTK from www.pygtk.org.")
raw_input(_("Press ENTER to continue.")) raw_input(_("Press ENTER to continue."))
exit() exit()
@ -87,18 +86,18 @@ import interlocks
try: try:
import matplotlib import matplotlib
matplotlib_version = matplotlib.__version__ matplotlib_version = matplotlib.__version__
except: except ImportError:
matplotlib_version = 'not found' matplotlib_version = 'not found'
try: try:
import numpy import numpy
numpy_version = numpy.__version__ numpy_version = numpy.__version__
except: except ImportError:
numpy_version = 'not found' numpy_version = 'not found'
try: try:
import sqlite3 import sqlite3
sqlite3_version = sqlite3.version sqlite3_version = sqlite3.version
sqlite_version = sqlite3.sqlite_version sqlite_version = sqlite3.sqlite_version
except: except ImportError:
sqlite3_version = 'not found' sqlite3_version = 'not found'
sqlite_version = 'not found' sqlite_version = 'not found'
@ -205,7 +204,7 @@ class fpdb:
gtk.Button.set_relief(button, gtk.RELIEF_NONE) gtk.Button.set_relief(button, gtk.RELIEF_NONE)
settings = gtk.Widget.get_settings(button); settings = gtk.Widget.get_settings(button);
(w,h) = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_SMALL_TOOLBAR); (w,h) = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_SMALL_TOOLBAR);
gtk.Widget.set_size_request (button, w + 4, h + 4); gtk.Widget.set_size_request(button, w + 4, h + 4);
image.show() image.show()
iconBox.pack_start(image, True, False, 0) iconBox.pack_start(image, True, False, 0)
button.add(iconBox) button.add(iconBox)
@ -935,6 +934,7 @@ class fpdb:
response = diaDbVersionWarning.run() response = diaDbVersionWarning.run()
diaDbVersionWarning.destroy() diaDbVersionWarning.destroy()
# TODO: This should probably be setup in GUI Init
if self.status_bar is None: if self.status_bar is None:
self.status_bar = gtk.Label("") self.status_bar = gtk.Label("")
self.main_vbox.pack_end(self.status_bar, False, True, 0) self.main_vbox.pack_end(self.status_bar, False, True, 0)
@ -968,8 +968,8 @@ class fpdb:
self.quitting = True self.quitting = True
# TODO: check if current settings differ from profile, if so offer to save or abort # TODO: check if current settings differ from profile, if so offer to save or abort
if self.db!=None: if self.db is not None:
if self.db.backend==self.db.MYSQL_INNODB: if self.db.backend == self.db.MYSQL_INNODB:
try: try:
import _mysql_exceptions import _mysql_exceptions
if self.db is not None and self.db.is_connected(): if self.db is not None and self.db.is_connected():
@ -995,8 +995,11 @@ class fpdb:
"""opens the auto import tab""" """opens the auto import tab"""
new_aimp_thread = GuiAutoImport.GuiAutoImport(self.settings, self.config, self.sql, self.window) new_aimp_thread = GuiAutoImport.GuiAutoImport(self.settings, self.config, self.sql, self.window)
self.threads.append(new_aimp_thread) self.threads.append(new_aimp_thread)
aimp_tab=new_aimp_thread.get_vbox() aimp_tab = new_aimp_thread.get_vbox()
self.add_and_display_tab(aimp_tab, _("Auto Import")) self.add_and_display_tab(aimp_tab, _("Auto Import"))
if options.autoimport:
new_aimp_thread.startClicked(new_aimp_thread.startButton, "autostart")
options.autoimport = False
def tab_bulk_import(self, widget, data=None): def tab_bulk_import(self, widget, data=None):
"""opens a tab for bulk importing""" """opens a tab for bulk importing"""
@ -1103,12 +1106,24 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0.txt an
self.db = None self.db = None
self.status_bar = None self.status_bar = None
self.quitting = False self.quitting = False
self.visible = False self.visible = False
self.threads = [] # objects used by tabs - no need for threads, gtk handles it
self.closeq = Queue.Queue(20) # used to signal ending of a thread (only logviewer for now)
# create window, move it to specific location on command line
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
if options.xloc is not None or options.yloc is not None:
if options.xloc is None:
options.xloc = 0
if options.yloc is None:
options.yloc = 0
self.window.move(options.xloc,options.yloc)
# connect to required events
self.window.connect("delete_event", self.delete_event) self.window.connect("delete_event", self.delete_event)
self.window.connect("destroy", self.destroy) self.window.connect("destroy", self.destroy)
self.window.set_title("Free Poker DB - v%s" % (VERSION, )) self.window.set_title("Free Poker DB - v%s" % (VERSION, ))
# set a default x/y size for the window
self.window.set_border_width(1) self.window.set_border_width(1)
defx, defy = 900, 720 defx, defy = 900, 720
sx, sy = gtk.gdk.screen_width(), gtk.gdk.screen_height() sx, sy = gtk.gdk.screen_width(), gtk.gdk.screen_height()
@ -1117,34 +1132,43 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0.txt an
self.window.set_default_size(defx, defy) self.window.set_default_size(defx, defy)
self.window.set_resizable(True) self.window.set_resizable(True)
# main area of window
self.main_vbox = gtk.VBox(False, 1) self.main_vbox = gtk.VBox(False, 1)
self.main_vbox.set_border_width(1) self.main_vbox.set_border_width(1)
self.window.add(self.main_vbox) self.window.add(self.main_vbox)
self.main_vbox.show() self.main_vbox.show()
# create our Main Menu Bar
menubar = self.get_menu(self.window) menubar = self.get_menu(self.window)
self.main_vbox.pack_start(menubar, False, True, 0) self.main_vbox.pack_start(menubar, False, True, 0)
menubar.show() menubar.show()
#done menubar
self.threads = [] # objects used by tabs - no need for threads, gtk handles it
self.closeq = Queue.Queue(20) # used to signal ending of a thread (only logviewer for now)
# create a tab bar
self.nb = gtk.Notebook() self.nb = gtk.Notebook()
self.nb.set_show_tabs(True) self.nb.set_show_tabs(True)
self.nb.show() self.nb.show()
self.main_vbox.pack_start(self.nb, True, True, 0) self.main_vbox.pack_start(self.nb, True, True, 0)
self.tabs=[] # the event_boxes forming the actual tabs self.tabs = [] # the event_boxes forming the actual tabs
self.tab_names=[] # names of tabs used since program started, not removed if tab is closed self.tab_names = [] # names of tabs used since program started, not removed if tab is closed
self.pages=[] # the contents of the page, not removed if tab is closed self.pages = [] # the contents of the page, not removed if tab is closed
self.nb_tab_names=[] # list of tab names currently displayed in notebook self.nb_tab_names = [] # list of tab names currently displayed in notebook
# create the first tab
self.tab_main_help(None, None) self.tab_main_help(None, None)
# determine window visibility from command line options
if options.minimized:
self.window.iconify()
if options.hidden:
self.window.hide()
if not options.hidden:
self.window.show() self.window.show()
self.visible = True # Flip on self.visible = True # Flip on
self.load_profile(create_db = True) self.load_profile(create_db = True)
# setup error logging
if not options.errorsToConsole: if not options.errorsToConsole:
fileName = os.path.join(self.config.dir_log, 'fpdb-errors.txt') 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: %s") % self.config.dir_log) \ print (_("\nNote: error output is being diverted to fpdb-errors.txt and HUD-errors.txt in: %s") % self.config.dir_log) \
@ -1152,6 +1176,7 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0.txt an
errorFile = open(fileName, 'w', 0) errorFile = open(fileName, 'w', 0)
sys.stderr = errorFile sys.stderr = errorFile
# set up tray-icon and menu
self.statusIcon = gtk.StatusIcon() self.statusIcon = gtk.StatusIcon()
# use getcwd() here instead of sys.path[0] so that py2exe works: # use getcwd() here instead of sys.path[0] so that py2exe works:
cards = os.path.join(os.getcwd(), '..','gfx','fpdb-cards.png') cards = os.path.join(os.getcwd(), '..','gfx','fpdb-cards.png')
@ -1167,13 +1192,10 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0.txt an
self.statusIcon.set_tooltip("Free Poker Database") self.statusIcon.set_tooltip("Free Poker Database")
self.statusIcon.connect('activate', self.statusicon_activate) self.statusIcon.connect('activate', self.statusicon_activate)
self.statusMenu = gtk.Menu() self.statusMenu = gtk.Menu()
menuItem = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
menuItem.connect('activate', self.dia_about)
self.statusMenu.append(menuItem)
menuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT) # set default menu options
menuItem.connect('activate', self.quit) self.addImageToTrayMenu(gtk.STOCK_ABOUT, self.dia_about)
self.statusMenu.append(menuItem) self.addImageToTrayMenu(gtk.STOCK_QUIT, self.quit)
self.statusIcon.connect('popup-menu', self.statusicon_menu, self.statusMenu) self.statusIcon.connect('popup-menu', self.statusicon_menu, self.statusMenu)
self.statusIcon.set_visible(True) self.statusIcon.set_visible(True)
@ -1181,6 +1203,28 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0.txt an
self.window.connect('window-state-event', self.window_state_event_cb) self.window.connect('window-state-event', self.window_state_event_cb)
sys.stderr.write(_("fpdb starting ...")) sys.stderr.write(_("fpdb starting ..."))
if options.autoimport:
self.tab_auto_import(None)
def addImageToTrayMenu(self, image, event=None):
menuItem = gtk.ImageMenuItem(image)
if event is not None:
menuItem.connect('activate', event)
self.statusMenu.append(menuItem)
menuItem.show()
return menuItem
def addLabelToTrayMenu(self, label, event=None):
menuItem = gtk.MenuItem(label)
if event is not None:
menuItem.connect('activate', event)
self.statusMenu.append(menuItem)
menuItem.show()
return menuItem
def removeFromTrayMenu(self, menuItem):
menuItem.destroy()
menuItem = None
def __iconify(self): def __iconify(self):
self.visible = False self.visible = False

4
pyfpdb/interlocks.py Normal file → Executable file
View File

@ -45,7 +45,7 @@ class InterProcessLockBase:
def acquire_impl(self, wait): abstract def acquire_impl(self, wait): abstract
def acquire(self, wait=False, retry_time=1, source=None): def acquire(self, source, wait=False, retry_time=1):
if source == None: if source == None:
source="Unknown" source="Unknown"
if self._has_lock: # make sure 2nd acquire in same process fails if self._has_lock: # make sure 2nd acquire in same process fails
@ -108,7 +108,7 @@ class InterProcessLockFcntl(InterProcessLockBase):
self.lockfd = 0 self.lockfd = 0
try: try:
os.unlink(self.lock_file_name) os.unlink(self.lock_file_name)
except OSError: except IOError:
# We don't care about the existence of the file too much here. It's the flock() we care about, # We don't care about the existence of the file too much here. It's the flock() we care about,
# And that should just go away magically. # And that should just go away magically.
pass pass

View File

@ -1,42 +0,0 @@
PokerStars Game #2428142447: Hold'em Limit ($1/$2 USD) - 2005/08/26 16:12:22 ET
Table 'Teucer II' Seat #5 is the button
Seat 1: Frankson34 ($24 in chips)
Seat 2: webb22 ($64 in chips)
Seat 3: eric_mtx ($26 in chips)
Seat 4: sososolid ($147.75 in chips)
Seat 5: DRILHER ($48.25 in chips)
Seat 6: Naughtychic ($60 in chips)
Seat 7: Terps78 ($71.50 in chips)
Seat 8: ChazDazzle ($69.25 in chips)
Seat 9: alekos ($55 in chips)
Seat 10: BigNards84 ($64.25 in chips)
Naughtychic: posts small blind $0.50
Terps78: posts big blind $1
*** HOLE CARDS ***
Dealt to ChazDazzle [8c Kd]
ChazDazzle: folds
alekos: folds
BigNards84: raises $1 to $2
Frankson34: folds
webb22: folds
eric_mtx: folds
ChazDazzle leaves the table
sososolid: folds
DRILHER: folds
cdhender joins the table at seat #8
Naughtychic: folds
Terps78: folds
BigNards84 collected $2.50 from pot
BigNards84: doesn't show hand
*** SUMMARY ***
Total pot $2.50 | Rake $0
Seat 1: Frankson34 folded before Flop (didn't bet)
Seat 2: webb22 folded before Flop (didn't bet)
Seat 3: eric_mtx folded before Flop (didn't bet)
Seat 4: sososolid folded before Flop (didn't bet)
Seat 5: DRILHER (button) folded before Flop (didn't bet)
Seat 6: Naughtychic (small blind) folded before Flop
Seat 7: Terps78 (big blind) folded before Flop
Seat 8: ChazDazzle folded before Flop (didn't bet)
Seat 9: alekos folded before Flop (didn't bet)
Seat 10: BigNards84 collected ($2.50)