cb99327fd9
Discovered that I didn't have an easy way to report that info back to the gtk widget and got bored. Maybe someone else will take it up.
390 lines
16 KiB
Python
Executable File
390 lines
16 KiB
Python
Executable File
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#Copyright 2008-2010 Steffen Schaumburg
|
|
#This program is free software: you can redistribute it and/or modify
|
|
#it under the terms of the GNU Affero General Public License as published by
|
|
#the Free Software Foundation, version 3 of the License.
|
|
#
|
|
#This program is distributed in the hope that it will be useful,
|
|
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
#GNU General Public License for more details.
|
|
#
|
|
#You should have received a copy of the GNU Affero General Public License
|
|
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#In the "official" distribution you can find the license in agpl-3.0.txt.
|
|
|
|
import L10n
|
|
_ = L10n.get_translation()
|
|
|
|
import threading
|
|
import subprocess
|
|
import traceback
|
|
|
|
import pygtk
|
|
pygtk.require('2.0')
|
|
import gtk
|
|
import gobject
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
import logging
|
|
# logging has been set up in fpdb.py or HUD_main.py, use their settings:
|
|
log = logging.getLogger("importer")
|
|
|
|
|
|
import fpdb_import
|
|
from optparse import OptionParser
|
|
import Configuration
|
|
import string
|
|
|
|
if os.name == "nt":
|
|
import win32console
|
|
|
|
|
|
class GuiAutoImport (threading.Thread):
|
|
def __init__(self, settings, config, sql = None, parent = None, cli = False):
|
|
self.importtimer = 0
|
|
self.settings = settings
|
|
self.config = config
|
|
self.sql = sql
|
|
self.parent = parent
|
|
|
|
imp = self.config.get_import_parameters()
|
|
|
|
self.input_settings = {}
|
|
self.pipe_to_hud = None
|
|
|
|
self.importer = fpdb_import.Importer(self, self.settings, self.config, self.sql)
|
|
self.importer.setCallHud(True)
|
|
self.importer.setQuiet(False)
|
|
self.importer.setFailOnError(False)
|
|
self.importer.setHandCount(0)
|
|
|
|
self.server = settings['db-host']
|
|
self.user = settings['db-user']
|
|
self.password = settings['db-password']
|
|
self.database = settings['db-databaseName']
|
|
|
|
if cli == False:
|
|
self.setupGui()
|
|
else:
|
|
# TODO: Separate the code that grabs the directories from config
|
|
# Separate the calls to the Importer API
|
|
# Create a timer interface that doesn't rely on GTK
|
|
pass
|
|
|
|
def setupGui(self):
|
|
self.mainVBox = gtk.VBox(False,1)
|
|
|
|
hbox = gtk.HBox(True, 0) # contains 2 equal vboxes
|
|
self.mainVBox.pack_start(hbox, False, False, 0)
|
|
|
|
vbox1 = gtk.VBox(True, 0)
|
|
hbox.pack_start(vbox1, True, True, 0)
|
|
vbox2 = gtk.VBox(True, 0)
|
|
hbox.pack_start(vbox2, True, True, 0)
|
|
|
|
self.intervalLabel = gtk.Label(_("Time between imports in seconds:"))
|
|
self.intervalLabel.set_alignment(xalign=1.0, yalign=0.5)
|
|
vbox1.pack_start(self.intervalLabel, False, True, 0)
|
|
|
|
hbox = gtk.HBox(False, 0)
|
|
vbox2.pack_start(hbox, False, True, 0)
|
|
self.intervalEntry = gtk.Entry()
|
|
self.intervalEntry.set_text(str(self.config.get_import_parameters().get("interval")))
|
|
hbox.pack_start(self.intervalEntry, False, False, 0)
|
|
lbl1 = gtk.Label()
|
|
hbox.pack_start(lbl1, expand=False, fill=True)
|
|
|
|
lbl = gtk.Label('')
|
|
vbox1.pack_start(lbl, expand=False, fill=True)
|
|
lbl = gtk.Label('')
|
|
vbox2.pack_start(lbl, expand=False, fill=True)
|
|
|
|
self.addSites(vbox1, vbox2)
|
|
self.textbuffer = gtk.TextBuffer()
|
|
self.textview = gtk.TextView(self.textbuffer)
|
|
|
|
hbox = gtk.HBox(False, 0)
|
|
self.mainVBox.pack_start(hbox, expand=True, padding=3)
|
|
|
|
hbox = gtk.HBox(False, 0)
|
|
self.mainVBox.pack_start(hbox, expand=False, padding=3)
|
|
|
|
lbl1 = gtk.Label()
|
|
hbox.pack_start(lbl1, expand=True, fill=False)
|
|
|
|
self.doAutoImportBool = False
|
|
self.startButton = gtk.ToggleButton(_(" Start _Auto Import "))
|
|
self.startButton.connect("clicked", self.startClicked, "start clicked")
|
|
hbox.pack_start(self.startButton, expand=False, fill=False)
|
|
|
|
self.DetectButton = gtk.Button(_("Detect Directories"))
|
|
self.DetectButton.connect("clicked", self.detect_hh_dirs, "detect")
|
|
#hbox.pack_start(self.DetectButton, expand=False, fill=False)
|
|
|
|
|
|
lbl2 = gtk.Label()
|
|
hbox.pack_start(lbl2, expand=True, fill=False)
|
|
|
|
hbox = gtk.HBox(False, 0)
|
|
hbox.show()
|
|
|
|
self.mainVBox.pack_start(hbox, expand=True, padding=3)
|
|
|
|
scrolledwindow = gtk.ScrolledWindow()
|
|
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
|
self.mainVBox.pack_end(scrolledwindow, expand=True)
|
|
scrolledwindow.add(self.textview)
|
|
|
|
self.mainVBox.show_all()
|
|
self.addText(_("Auto Import Ready."))
|
|
|
|
def addText(self, text):
|
|
end_iter = self.textbuffer.get_end_iter()
|
|
self.textbuffer.insert(end_iter, text)
|
|
self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0)
|
|
|
|
|
|
#end of GuiAutoImport.__init__
|
|
def browseClicked(self, widget, data):
|
|
"""runs when user clicks one of the browse buttons in the auto import tab"""
|
|
current_path=data[1].get_text()
|
|
|
|
dia_chooser = gtk.FileChooserDialog(title=_("Please choose the path that you want to Auto Import"),
|
|
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
|
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
|
#dia_chooser.set_current_folder(pathname)
|
|
dia_chooser.set_filename(current_path)
|
|
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
|
|
dia_chooser.set_destroy_with_parent(True)
|
|
dia_chooser.set_transient_for(self.parent)
|
|
|
|
response = dia_chooser.run()
|
|
if response == gtk.RESPONSE_OK:
|
|
#print dia_chooser.get_filename(), 'selected'
|
|
data[1].set_text(dia_chooser.get_filename())
|
|
self.input_settings[data[0]][0] = dia_chooser.get_filename()
|
|
elif response == gtk.RESPONSE_CANCEL:
|
|
#print 'Closed, no files selected'
|
|
pass
|
|
dia_chooser.destroy()
|
|
#end def GuiAutoImport.browseClicked
|
|
|
|
def do_import(self):
|
|
"""Callback for timer to do an import iteration."""
|
|
if self.doAutoImportBool:
|
|
self.startButton.set_label(_(u' _Auto Import Running '))
|
|
self.importer.runUpdated()
|
|
self.addText(".")
|
|
#sys.stdout.write(".")
|
|
#sys.stdout.flush()
|
|
gobject.timeout_add(1000, self.reset_startbutton)
|
|
return True
|
|
return False
|
|
|
|
def reset_startbutton(self):
|
|
if self.pipe_to_hud is not None:
|
|
self.startButton.set_label(_(u' Stop _Auto Import '))
|
|
else:
|
|
self.startButton.set_label(_(u' Start _Auto Import '))
|
|
|
|
return False
|
|
|
|
def detect_hh_dirs(self, widget, data):
|
|
"""Attempt to find user hand history directories for enabled sites"""
|
|
the_sites = self.config.get_supported_sites()
|
|
for site in the_sites:
|
|
params = self.config.get_site_parameters(site)
|
|
if params['enabled'] == True:
|
|
print "DEBUG: Detecting hh directory for site: '%s'" % site
|
|
if os.name == 'posix':
|
|
if self.posix_detect_hh_dirs(site):
|
|
#data[1].set_text(dia_chooser.get_filename())
|
|
self.input_settings[site][0]
|
|
pass
|
|
elif os.name == 'nt':
|
|
# Sorry
|
|
pass
|
|
|
|
def posix_detect_hh_dirs(self, site):
|
|
defaults = {
|
|
'PokerStars': '~/.wine/drive_c/Program Files/PokerStars/HandHistory',
|
|
}
|
|
if site == 'PokerStars':
|
|
directory = os.path.expanduser(defaults[site])
|
|
for file in [file for file in os.listdir(directory) if not file in [".",".."]]:
|
|
print file
|
|
return False
|
|
|
|
def startClicked(self, widget, data):
|
|
"""runs when user clicks start on auto import tab"""
|
|
|
|
# Check to see if we have an open file handle to the HUD and open one if we do not.
|
|
# bufsize = 1 means unbuffered
|
|
# We need to close this file handle sometime.
|
|
|
|
# TODO: Allow for importing from multiple dirs - REB 29AUG2008
|
|
# As presently written this function does nothing if there is already a pipe open.
|
|
# 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
|
|
# to watch.
|
|
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?
|
|
# (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
|
|
# kind of exception - is this possible?
|
|
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.doAutoImportBool = True
|
|
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 Configuration.FROZEN: # if py2exe, run hud_main.exe
|
|
path = Configuration.EXEC_PATH
|
|
command = "HUD_main.exe"
|
|
bs = 0
|
|
elif os.name == 'nt':
|
|
path = sys.path[0].replace('\\','\\\\')
|
|
if win32console.GetConsoleWindow() == 0:
|
|
command = 'pythonw "'+path+'\\HUD_main.pyw" ' + self.settings['cl_options']
|
|
else:
|
|
command = 'python "'+path+'\\HUD_main.pyw" ' + self.settings['cl_options']
|
|
bs = 0
|
|
else:
|
|
command = os.path.join(sys.path[0], 'HUD_main.pyw')
|
|
command = [command, ] + string.split(self.settings['cl_options'])
|
|
bs = 1
|
|
|
|
print _("opening pipe to HUD")
|
|
try:
|
|
if Configuration.FROZEN or (os.name == "nt" and win32console.GetConsoleWindow()) == 0:
|
|
self.pipe_to_hud = subprocess.Popen(command, bufsize=bs,
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE, # needed for pythonw / py2exe
|
|
stderr=subprocess.PIPE, # needed for pythonw / py2exe
|
|
universal_newlines=True
|
|
)
|
|
else:
|
|
self.pipe_to_hud = subprocess.Popen(command, bufsize=bs, stdin=subprocess.PIPE, 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: ") + 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])
|
|
self.addText("\n * Add "+ site+ " import directory "+ str(self.input_settings[site][0]))
|
|
self.do_import()
|
|
interval = int(self.intervalEntry.get_text())
|
|
if self.importtimer != 0:
|
|
gobject.source_remove(self.importtimer)
|
|
self.importtimer = gobject.timeout_add(interval * 1000, self.do_import)
|
|
|
|
else:
|
|
self.addText(_("\nAuto Import aborted - global lock not available"))
|
|
else: # toggled off
|
|
gobject.source_remove(self.importtimer)
|
|
self.settings['global_lock'].release()
|
|
self.doAutoImportBool = False # do_import will return this and stop the gobject callback timer
|
|
self.addText(_("\nStopping Auto Import - global lock released."))
|
|
if self.pipe_to_hud.poll() is not None:
|
|
self.addText(_("\n * Stop Auto Import: HUD already terminated"))
|
|
else:
|
|
self.pipe_to_hud.terminate()
|
|
#print >>self.pipe_to_hud.stdin, "\n"
|
|
# self.pipe_to_hud.communicate('\n') # waits for process to terminate
|
|
self.pipe_to_hud = None
|
|
self.startButton.set_label(_(u' Start _Auto Import '))
|
|
|
|
#end def GuiAutoImport.startClicked
|
|
|
|
def get_vbox(self):
|
|
"""returns the vbox of this thread"""
|
|
return self.mainVBox
|
|
#end def get_vbox
|
|
|
|
#Create the site line given required info and setup callbacks
|
|
#enabling and disabling sites from this interface not possible
|
|
#expects a box to layout the line horizontally
|
|
def createSiteLine(self, hbox1, hbox2, site, iconpath, hhpath, filter_name, active = True):
|
|
label = gtk.Label("%s auto-import:" % site)
|
|
hbox1.pack_start(label, False, False, 3)
|
|
label.show()
|
|
|
|
dirPath=gtk.Entry()
|
|
dirPath.set_text(hhpath)
|
|
hbox1.pack_start(dirPath, True, True, 3)
|
|
dirPath.show()
|
|
|
|
browseButton=gtk.Button(_("Browse..."))
|
|
browseButton.connect("clicked", self.browseClicked, [site] + [dirPath])
|
|
hbox2.pack_start(browseButton, False, False, 3)
|
|
browseButton.show()
|
|
|
|
label = gtk.Label("%s filter:" % site)
|
|
hbox2.pack_start(label, False, False, 3)
|
|
label.show()
|
|
|
|
filter=gtk.Entry()
|
|
filter.set_text(filter_name)
|
|
hbox2.pack_start(filter, True, True, 3)
|
|
filter.show()
|
|
|
|
def addSites(self, vbox1, vbox2):
|
|
the_sites = self.config.get_supported_sites()
|
|
#log.debug("addSites: the_sites="+str(the_sites))
|
|
for site in the_sites:
|
|
pathHBox1 = gtk.HBox(False, 0)
|
|
vbox1.pack_start(pathHBox1, False, True, 0)
|
|
pathHBox2 = gtk.HBox(False, 0)
|
|
vbox2.pack_start(pathHBox2, False, True, 0)
|
|
|
|
params = self.config.get_site_parameters(site)
|
|
paths = self.config.get_default_paths(site)
|
|
self.createSiteLine(pathHBox1, pathHBox2, site, False, paths['hud-defaultPath'], params['converter'], params['enabled'])
|
|
self.input_settings[site] = [paths['hud-defaultPath']] + [params['converter']]
|
|
#log.debug("addSites: input_settings="+str(self.input_settings))
|
|
|
|
if __name__== "__main__":
|
|
def destroy(*args): # call back for terminating the main eventloop
|
|
gtk.main_quit()
|
|
|
|
# settings = {}
|
|
# settings['db-host'] = "192.168.1.100"
|
|
# settings['db-user'] = "mythtv"
|
|
# settings['db-password'] = "mythtv"
|
|
# settings['db-databaseName'] = "fpdb"
|
|
# settings['hud-defaultInterval'] = 10
|
|
# settings['hud-defaultPath'] = 'C:/Program Files/PokerStars/HandHistory/nutOmatic'
|
|
# settings['callFpdbHud'] = True
|
|
|
|
parser = OptionParser()
|
|
parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui")
|
|
(options, argv) = parser.parse_args()
|
|
|
|
config = Configuration.Config()
|
|
|
|
settings = {}
|
|
if os.name == 'nt': settings['os'] = 'windows'
|
|
else: settings['os'] = 'linuxmac'
|
|
|
|
settings.update(config.get_db_parameters())
|
|
settings.update(config.get_import_parameters())
|
|
settings.update(config.get_default_paths())
|
|
|
|
if(options.gui == True):
|
|
i = GuiAutoImport(settings, config, None, None)
|
|
main_window = gtk.Window()
|
|
main_window.connect('destroy', destroy)
|
|
main_window.add(i.mainVBox)
|
|
main_window.show()
|
|
gtk.main()
|
|
else:
|
|
i = GuiAutoImport(settings, config, cli = True)
|