diff --git a/pyfpdb/GuiTableViewer.py b/pyfpdb/GuiTableViewer.py index 35dbb797..8d25366a 100644 --- a/pyfpdb/GuiTableViewer.py +++ b/pyfpdb/GuiTableViewer.py @@ -22,288 +22,270 @@ import gtk import os import fpdb_simple -try: - import MySQLdb -except: - diaSQLLibMissing = gtk.Dialog(title="Fatal Error - SQL interface library missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK)) - - label = gtk.Label("Please note that the table viewer only works with MySQL, if you use PostgreSQL this error is expected.") - diaSQLLibMissing.vbox.add(label) - label.show() - - label = gtk.Label("Since the HUD now runs on all supported plattforms I do not see any point in table viewer anymore, if you disagree please send a message to steffen@sycamoretest.info") - diaSQLLibMissing.vbox.add(label) - label.show() - - response = diaSQLLibMissing.run() - #sys.exit(1) - + import fpdb_import import fpdb_db + class GuiTableViewer (threading.Thread): - def hudDivide (self, a, b): - if b==0: - return "n/a" - else: - return str(int((a/float(b))*100))+"%" - #end def hudDivide - - def browse_clicked(self, widget, data): - """runs when user clicks browse on tv tab""" - #print "start of table_viewer.browser_clicked" - current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) - - dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer", - action=gtk.FILE_CHOOSER_ACTION_OPEN, - 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 - - response = dia_chooser.run() - if response == gtk.RESPONSE_OK: - #print dia_chooser.get_filename(), 'selected' - self.filename_tbuffer.set_text(dia_chooser.get_filename()) - elif response == gtk.RESPONSE_CANCEL: - print 'Closed, no files selected' - dia_chooser.destroy() - #end def table_viewer.browse_clicked - - def prepare_data(self): - """prepares the data for display by refresh_clicked, returns a 2D array""" - #print "start of prepare_data" - arr=[] - #first prepare the header row - if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"): - tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST") - - tmp+=("FS", "FB") - - tmp+=("CB", ) - - tmp+=("2B", "3B") - - tmp+=("AF", "FF", "AT", "FT", "AR", "FR") - - tmp+=("WtSD", "W$wsF", "W$SD") - else: - raise fpdb_simple.FpdbError("reimplement stud") - arr.append(tmp) - - #then the data rows - for player in range(len(self.player_names)): - tmp=[] - tmp.append(self.player_names[player][0]) - - seatCount=len(self.player_names) - if seatCount>=8: - minSeats,maxSeats=7,10 - elif seatCount==7: - minSeats,maxSeats=6,10 - elif seatCount==6 or seatCount==5: - minSeats,maxSeats=seatCount-1,seatCount+1 - elif seatCount==4: - minSeats,maxSeats=4,5 - elif seatCount==2 or seatCount==3: - minSeats,maxSeats=seatCount,seatCount - else: - fpdb_simple.FpdbError("invalid seatCount") - - self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats)) - rows=self.cursor.fetchall() - - row=[] - for field_no in range(len(rows[0])): - row.append(rows[0][field_no]) - - for row_no in range(len(rows)): - if row_no==0: - pass - else: - for field_no in range(len(rows[row_no])): - if field_no<=3: - pass - else: - #print "in prep data, row_no:",row_no,"field_no:",field_no - row[field_no]+=rows[row_no][field_no] - - tmp.append(str(row[6]))#Hands - tmp.append(self.hudDivide(row[7],row[6])) #VPIP - tmp.append(self.hudDivide(row[8],row[6])) #PFR - tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B - - tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST - - tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS - tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB - - tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB - - tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B - tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B - - tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF - tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF - tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT - tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT - tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR - tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR - - tmp.append(self.hudDivide(row[15],row[11])) #WtSD - tmp.append(self.hudDivide(row[28],row[11])) #W$wSF - tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD - - arr.append(tmp) - return arr - #end def table_viewer.prepare_data - - def refresh_clicked(self, widget, data): - """runs when user clicks refresh""" - #print "start of table_viewer.refresh_clicked" - arr=self.prepare_data() - - try: self.data_table.destroy() - except AttributeError: pass - self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False) - self.main_vbox.pack_start(self.data_table) - self.data_table.show() - - for row in range(len(arr)): - for column in range (len(arr[row])): - eventBox=gtk.EventBox() - new_label=gtk.Label(arr[row][column]) - if row%2==0: # - bg_col="white" - if column==0 or (column>=5 and column<=10): - bg_col="lightgrey" - else: - bg_col="lightgrey" - if column==0 or (column>=5 and column<=10): - bg_col="grey" - #style = eventBox.get_style() - #style.font.height=8 - #eventBox.set_style(style) - - eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col)) - eventBox.add(new_label) - self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1) - eventBox.show() - new_label.show() - #end def table_viewer.refresh_clicked - - def read_names_clicked(self, widget, data): - """runs when user clicks read names""" - #print "start of table_viewer.read_names_clicked" - self.db.reconnect() - self.cursor=self.db.cursor - #self.hands_id=self.last_read_hand_id - - self.db.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, )) - self.gametype_id=self.db.cursor.fetchone()[0] - self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, )) - self.category=self.db.cursor.fetchone()[0] - #print "self.gametype_id", self.gametype_id," category:", self.category, " self.hands_id:", self.hands_id - - self.db.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers - INNER JOIN Players ON HandsPlayers.playerId=Players.id - WHERE handId=%s""", (self.hands_id, )) - self.player_ids=self.db.cursor.fetchall() - #print "self.player_ids:",self.player_ids - - self.db.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers - INNER JOIN Players ON HandsPlayers.playerId=Players.id - WHERE handId=%s""", (self.hands_id, )) - self.player_names=self.db.cursor.fetchall() - #print "self.player_names:",self.player_names - #end def table_viewer.read_names_clicked - - def import_clicked(self, widget, data): - """runs when user clicks import""" - #print "start of table_viewer.import_clicked" - self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) - - self.server=self.db.host - self.database=self.db.database - self.user=self.db.user - self.password=self.db.password - - self.importer = fpdb_import.Importer(self, self.settings) - self.importer.setMinPrint(0) - self.importer.setQuiet(False) - self.importer.setFailOnError(False) - self.importer.setHandCount(0) - - self.importer.addImportFile(self.inputFile) - self.importer.runImport() - self.hands_id=self.importer.handsId - #end def table_viewer.import_clicked - - def all_clicked(self, widget, data): - """runs when user clicks all""" - #print "start of table_viewer.all_clicked" - self.import_clicked(widget, data) - self.read_names_clicked(widget, data) - self.refresh_clicked(widget, data) - #end def table_viewer.all_clicked - - def get_vbox(self): - """returns the vbox of this thread""" - return self.main_vbox - #end def get_vbox - - def __init__(self, db, settings, debug=True): - """Constructor for table_viewer""" - self.debug=debug - #print "start of table_viewer constructor" - self.db=db - self.cursor=db.cursor - self.settings=settings + def hudDivide (self, a, b): + if b==0: + return "n/a" + else: + return str(int((a/float(b))*100))+"%" + #end def hudDivide + + def browse_clicked(self, widget, data): + """runs when user clicks browse on tv tab""" + #print "start of table_viewer.browser_clicked" + current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) - self.main_vbox = gtk.VBox(False, 0) - self.main_vbox.show() - - self.settings_hbox = gtk.HBox(False, 0) - self.main_vbox.pack_end(self.settings_hbox, False, True, 0) - self.settings_hbox.show() - - self.filename_label = gtk.Label("Path of history file") - self.settings_hbox.pack_start(self.filename_label, False, False) - self.filename_label.show() - - self.filename_tbuffer=gtk.TextBuffer() - self.filename_tbuffer.set_text(self.settings['hud-defaultPath']) - self.filename_tview=gtk.TextView(self.filename_tbuffer) - self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5) - self.filename_tview.show() - - self.browse_button=gtk.Button("Browse...") - self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked") - self.settings_hbox.pack_start(self.browse_button, False, False) - self.browse_button.show() - - - self.button_hbox = gtk.HBox(False, 0) - self.main_vbox.pack_end(self.button_hbox, False, True, 0) - self.button_hbox.show() - - #self.import_button = gtk.Button("Import") - #self.import_button.connect("clicked", self.import_clicked, "Import clicked") - #self.button_hbox.add(self.import_button) - #self.import_button.show() + dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer", + action=gtk.FILE_CHOOSER_ACTION_OPEN, + 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 - #self.read_names_button = gtk.Button("Read Names") - #self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked") - #self.button_hbox.add(self.read_names_button) - #self.read_names_button.show() - - #self.refresh_button = gtk.Button("Show/Refresh data") - #self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked") - #self.button_hbox.add(self.refresh_button) - #self.refresh_button.show() - - self.all_button = gtk.Button("Import&Read&Refresh") - self.all_button.connect("clicked", self.all_clicked, "All clicked") - self.button_hbox.add(self.all_button) - self.all_button.show() - #end of table_viewer.__init__ + response = dia_chooser.run() + if response == gtk.RESPONSE_OK: + #print dia_chooser.get_filename(), 'selected' + self.filename_tbuffer.set_text(dia_chooser.get_filename()) + elif response == gtk.RESPONSE_CANCEL: + print 'Closed, no files selected' + dia_chooser.destroy() + #end def table_viewer.browse_clicked + + def prepare_data(self): + """prepares the data for display by refresh_clicked, returns a 2D array""" + #print "start of prepare_data" + arr=[] + #first prepare the header row + if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"): + tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST") + + tmp+=("FS", "FB") + + tmp+=("CB", ) + + tmp+=("2B", "3B") + + tmp+=("AF", "FF", "AT", "FT", "AR", "FR") + + tmp+=("WtSD", "W$wsF", "W$SD") + else: + raise fpdb_simple.FpdbError("reimplement stud") + arr.append(tmp) + + #then the data rows + for player in range(len(self.player_names)): + tmp=[] + tmp.append(self.player_names[player][0]) + + seatCount=len(self.player_names) + if seatCount>=8: + minSeats,maxSeats=7,10 + elif seatCount==7: + minSeats,maxSeats=6,10 + elif seatCount==6 or seatCount==5: + minSeats,maxSeats=seatCount-1,seatCount+1 + elif seatCount==4: + minSeats,maxSeats=4,5 + elif seatCount==2 or seatCount==3: + minSeats,maxSeats=seatCount,seatCount + else: + fpdb_simple.FpdbError("invalid seatCount") + + self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats)) + rows=self.cursor.fetchall() + + row=[] + for field_no in range(len(rows[0])): + row.append(rows[0][field_no]) + + for row_no in range(len(rows)): + if row_no==0: + pass + else: + for field_no in range(len(rows[row_no])): + if field_no<=3: + pass + else: + #print "in prep data, row_no:",row_no,"field_no:",field_no + row[field_no]+=rows[row_no][field_no] + + tmp.append(str(row[6]))#Hands + tmp.append(self.hudDivide(row[7],row[6])) #VPIP + tmp.append(self.hudDivide(row[8],row[6])) #PFR + tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B + + tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST + + tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS + tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB + + tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB + + tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B + tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B + + tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF + tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF + tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT + tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT + tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR + tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR + + tmp.append(self.hudDivide(row[15],row[11])) #WtSD + tmp.append(self.hudDivide(row[28],row[11])) #W$wSF + tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD + + arr.append(tmp) + return arr + #end def table_viewer.prepare_data + + def refresh_clicked(self, widget, data): + """runs when user clicks refresh""" + #print "start of table_viewer.refresh_clicked" + arr=self.prepare_data() + + try: self.data_table.destroy() + except AttributeError: pass + self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False) + self.main_vbox.pack_start(self.data_table) + self.data_table.show() + + for row in range(len(arr)): + for column in range (len(arr[row])): + eventBox=gtk.EventBox() + new_label=gtk.Label(arr[row][column]) + if row%2==0: # + bg_col="white" + if column==0 or (column>=5 and column<=10): + bg_col="lightgrey" + else: + bg_col="lightgrey" + if column==0 or (column>=5 and column<=10): + bg_col="grey" + #style = eventBox.get_style() + #style.font.height=8 + #eventBox.set_style(style) + + eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col)) + eventBox.add(new_label) + self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1) + eventBox.show() + new_label.show() + #end def table_viewer.refresh_clicked + + def read_names_clicked(self, widget, data): + """runs when user clicks read names""" + #print "start of table_viewer.read_names_clicked" + self.db.reconnect() + self.cursor=self.db.get_cursor() + #self.hands_id=self.last_read_hand_id + + self.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, )) + self.gametype_id=self.cursor.fetchone()[0] + self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, )) + self.category=self.cursor.fetchone()[0] + #print "self.gametype_id", self.gametype_id," category:", self.category, " self.hands_id:", self.hands_id + + self.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers + INNER JOIN Players ON HandsPlayers.playerId=Players.id + WHERE handId=%s""", (self.hands_id, )) + self.player_ids=self.cursor.fetchall() + #print "self.player_ids:",self.player_ids + + self.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers + INNER JOIN Players ON HandsPlayers.playerId=Players.id + WHERE handId=%s""", (self.hands_id, )) + self.player_names=self.cursor.fetchall() + #print "self.player_names:",self.player_names + #end def table_viewer.read_names_clicked + + def import_clicked(self, widget, data): + """runs when user clicks import""" + #print "start of table_viewer.import_clicked" + self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) + + self.importer = fpdb_import.Importer(self, self.settings, self.config) + self.importer.setMinPrint(0) + self.importer.setQuiet(False) + self.importer.setFailOnError(False) + self.importer.setHandCount(0) + + self.importer.addImportFile(self.inputFile) + self.importer.runImport() + self.hands_id=self.importer.handsId + #end def table_viewer.import_clicked + + def all_clicked(self, widget, data): + """runs when user clicks all""" + #print "start of table_viewer.all_clicked" + self.import_clicked(widget, data) + self.read_names_clicked(widget, data) + self.refresh_clicked(widget, data) + #end def table_viewer.all_clicked + + def get_vbox(self): + """returns the vbox of this thread""" + return self.main_vbox + #end def get_vbox + + def __init__(self, db, settings, config=None, debug=True): + """Constructor for table_viewer""" + self.debug=debug + #print "start of table_viewer constructor" + self.db = db + self.cursor = db.get_cursor() + self.settings = settings + self.config = config + + self.main_vbox = gtk.VBox(False, 0) + self.main_vbox.show() + + self.settings_hbox = gtk.HBox(False, 0) + self.main_vbox.pack_end(self.settings_hbox, False, True, 0) + self.settings_hbox.show() + + self.filename_label = gtk.Label("Path of history file") + self.settings_hbox.pack_start(self.filename_label, False, False) + self.filename_label.show() + + self.filename_tbuffer=gtk.TextBuffer() + self.filename_tbuffer.set_text(self.settings['hud-defaultPath']) + self.filename_tview=gtk.TextView(self.filename_tbuffer) + self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5) + self.filename_tview.show() + + self.browse_button=gtk.Button("Browse...") + self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked") + self.settings_hbox.pack_start(self.browse_button, False, False) + self.browse_button.show() + + + self.button_hbox = gtk.HBox(False, 0) + self.main_vbox.pack_end(self.button_hbox, False, True, 0) + self.button_hbox.show() + + #self.import_button = gtk.Button("Import") + #self.import_button.connect("clicked", self.import_clicked, "Import clicked") + #self.button_hbox.add(self.import_button) + #self.import_button.show() + + #self.read_names_button = gtk.Button("Read Names") + #self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked") + #self.button_hbox.add(self.read_names_button) + #self.read_names_button.show() + + #self.refresh_button = gtk.Button("Show/Refresh data") + #self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked") + #self.button_hbox.add(self.refresh_button) + #self.refresh_button.show() + + self.all_button = gtk.Button("Import&Read&Refresh") + self.all_button.connect("clicked", self.all_clicked, "All clicked") + self.button_hbox.add(self.all_button) + self.all_button.show() + #end of table_viewer.__init__ diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index 37907397..23bb4495 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -531,7 +531,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") def tab_table_viewer(self, widget, data=None): """opens a table viewer tab""" #print "start of tab_table_viewer" - new_tv_thread=GuiTableViewer.GuiTableViewer(self.db.fdb, self.settings) + new_tv_thread = GuiTableViewer.GuiTableViewer(self.db, self.settings, self.config) self.threads.append(new_tv_thread) tv_tab=new_tv_thread.get_vbox() self.add_and_display_tab(tv_tab, "Table Viewer") diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index a1457557..f0ec73aa 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -85,6 +85,8 @@ class Importer: #self.settings.setdefault("forceThreads", 2) # NOT USED NOW self.settings.setdefault("writeQSize", 1000) # no need to change self.settings.setdefault("writeQMaxWait", 10) # not used + self.settings.setdefault("dropIndexes", "don't drop") + self.settings.setdefault("dropHudCache", "don't drop") self.writeq = None self.database = Database.Database(self.config, sql = self.sql)