You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
16 KiB
389 lines
16 KiB
#!/usr/bin/env python |
|
# -*- coding: utf-8 -*- |
|
|
|
#Copyright 2008-2011 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)
|
|
|