diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py
deleted file mode 100644
index a2420f7f..00000000
--- a/pyfpdb/Filters.py
+++ /dev/null
@@ -1,948 +0,0 @@
-#!/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 .
-#In the "official" distribution you can find the license in agpl-3.0.txt.
-
-import threading
-import pygtk
-pygtk.require('2.0')
-import gtk
-import os
-import sys
-from optparse import OptionParser
-from time import *
-import gobject
-#import pokereval
-
-import logging
-# logging has been set up in fpdb.py or HUD_main.py, use their settings:
-log = logging.getLogger("filter")
-
-
-import Configuration
-import Database
-import SQL
-import Charset
-
-
-class Filters(threading.Thread):
- def __init__(self, db, config, qdict, display = {}, debug=True):
- # config and qdict are now redundant
- self.debug = debug
- self.db = db
- self.cursor = db.cursor
- self.sql = db.sql
- self.conf = db.config
- self.display = display
-
- # text used on screen stored here so that it can be configured
- self.filterText = {'limitsall':'All', 'limitsnone':'None', 'limitsshow':'Show _Limits'
- ,'seatsbetween':'Between:', 'seatsand':'And:', 'seatsshow':'Show Number of _Players'
- ,'playerstitle':'Hero:', 'sitestitle':'Sites:', 'gamestitle':'Games:'
- ,'limitstitle':'Limits:', 'seatstitle':'Number of Players:'
- ,'groupstitle':'Grouping:', 'posnshow':'Show Position Stats:'
- ,'datestitle':'Date:'
- ,'groupsall':'All Players'
- ,'limitsFL':'FL', 'limitsNL':'NL', 'limitsPL':'PL', 'ring':'Ring', 'tour':'Tourney'
- }
-
- gen = self.conf.get_general_params()
- self.day_start = 0
- if 'day_start' in gen:
- self.day_start = float(gen['day_start'])
-
- # Outer Packing box
- self.mainVBox = gtk.VBox(False, 0)
-
- self.label = {}
- self.callback = {}
-
- self.make_filter()
-
- def make_filter(self):
- self.sites = {}
- self.games = {}
- self.limits = {}
- self.seats = {}
- self.groups = {}
- self.siteid = {}
- self.heroes = {}
- self.boxes = {}
-
- for site in self.conf.get_supported_sites():
- #Get db site id for filtering later
- self.cursor.execute(self.sql.query['getSiteId'], (site,))
- result = self.db.cursor.fetchall()
- if len(result) == 1:
- self.siteid[site] = result[0][0]
- else:
- print "Either 0 or more than one site matched (%s) - EEK" % site
-
- # For use in date ranges.
- self.start_date = gtk.Entry(max=12)
- self.end_date = gtk.Entry(max=12)
- self.start_date.set_property('editable', False)
- self.end_date.set_property('editable', False)
-
- # For use in groups etc
- self.sbGroups = {}
- self.numHands = 0
-
- playerFrame = gtk.Frame()
- playerFrame.set_label_align(0.0, 0.0)
- vbox = gtk.VBox(False, 0)
-
- self.fillPlayerFrame(vbox, self.display)
- playerFrame.add(vbox)
-
- sitesFrame = gtk.Frame()
- sitesFrame.set_label_align(0.0, 0.0)
- vbox = gtk.VBox(False, 0)
-
- self.fillSitesFrame(vbox)
- sitesFrame.add(vbox)
-
- # Game types
- gamesFrame = gtk.Frame()
- gamesFrame.set_label_align(0.0, 0.0)
- gamesFrame.show()
- vbox = gtk.VBox(False, 0)
-
- self.fillGamesFrame(vbox)
- gamesFrame.add(vbox)
-
- # Limits
- limitsFrame = gtk.Frame()
- limitsFrame.show()
- vbox = gtk.VBox(False, 0)
- self.cbLimits = {}
- self.cbNoLimits = None
- self.cbAllLimits = None
- self.cbFL = None
- self.cbNL = None
- self.cbPL = None
- self.rb = {} # radio buttons for ring/tour
- self.type = None # ring/tour
- self.types = {} # list of all ring/tour values
-
- self.fillLimitsFrame(vbox, self.display)
- limitsFrame.add(vbox)
-
- # Seats
- seatsFrame = gtk.Frame()
- seatsFrame.show()
- vbox = gtk.VBox(False, 0)
- self.sbSeats = {}
-
- self.fillSeatsFrame(vbox, self.display)
- seatsFrame.add(vbox)
-
- # Groups
- groupsFrame = gtk.Frame()
- groupsFrame.show()
- vbox = gtk.VBox(False, 0)
-
- self.fillGroupsFrame(vbox, self.display)
- groupsFrame.add(vbox)
-
- # Date
- dateFrame = gtk.Frame()
- dateFrame.set_label_align(0.0, 0.0)
- dateFrame.show()
- vbox = gtk.VBox(False, 0)
-
- self.fillDateFrame(vbox)
- dateFrame.add(vbox)
-
- # Buttons
- self.Button1=gtk.Button("Unnamed 1")
- self.Button1.set_sensitive(False)
-
- self.Button2=gtk.Button("Unnamed 2")
- self.Button2.set_sensitive(False)
-
- self.mainVBox.add(playerFrame)
- self.mainVBox.add(sitesFrame)
- self.mainVBox.add(gamesFrame)
- self.mainVBox.add(limitsFrame)
- self.mainVBox.add(seatsFrame)
- self.mainVBox.add(groupsFrame)
- self.mainVBox.add(dateFrame)
- self.mainVBox.add(self.Button1)
- self.mainVBox.add(self.Button2)
-
- self.mainVBox.show_all()
-
- # Should do this cleaner
- if "Heroes" not in self.display or self.display["Heroes"] == False:
- playerFrame.hide()
- if "Sites" not in self.display or self.display["Sites"] == False:
- sitesFrame.hide()
- if "Games" not in self.display or self.display["Games"] == False:
- gamesFrame.hide()
- if "Limits" not in self.display or self.display["Limits"] == False:
- limitsFrame.hide()
- if "Seats" not in self.display or self.display["Seats"] == False:
- seatsFrame.hide()
- if "Groups" not in self.display or self.display["Groups"] == False:
- groupsFrame.hide()
- if "Dates" not in self.display or self.display["Dates"] == False:
- dateFrame.hide()
- if "Button1" not in self.display or self.display["Button1"] == False:
- self.Button1.hide()
- if "Button2" not in self.display or self.display["Button2"] == False:
- self.Button2.hide()
-
- if 'button1' in self.label and self.label['button1']:
- self.Button1.set_label( self.label['button1'] )
- if 'button2' in self.label and self.label['button2']:
- self.Button2.set_label( self.label['button2'] )
- if 'button1' in self.callback and self.callback['button1']:
- self.Button1.connect("clicked", self.callback['button1'], "clicked")
- self.Button1.set_sensitive(True)
- if 'button2' in self.callback and self.callback['button2']:
- self.Button2.connect("clicked", self.callback['button2'], "clicked")
- self.Button2.set_sensitive(True)
-
- # make sure any locks on db are released:
- self.db.rollback()
-
- def get_vbox(self):
- """returns the vbox of this thread"""
- return self.mainVBox
- #end def get_vbox
-
- def getNumHands(self):
- return self.numHands
- #end def getNumHands
-
- def getSites(self):
- return self.sites
- #end def getSites
-
- def getGames(self):
- return self.games
-
- def getSiteIds(self):
- return self.siteid
- #end def getSiteIds
-
- def getHeroes(self):
- return self.heroes
- #end def getHeroes
-
- def getLimits(self):
- ltuple = []
- for l in self.limits:
- if self.limits[l] == True:
- ltuple.append(l)
- return ltuple
-
- def getType(self):
- return(self.type)
-
- def getSeats(self):
- if 'from' in self.sbSeats:
- self.seats['from'] = self.sbSeats['from'].get_value_as_int()
- if 'to' in self.sbSeats:
- self.seats['to'] = self.sbSeats['to'].get_value_as_int()
- return self.seats
- #end def getSeats
-
- def getGroups(self):
- return self.groups
-
- def getDates(self):
- return self.__get_dates()
- #end def getDates
-
- def registerButton1Name(self, title):
- self.Button1.set_label(title)
- self.label['button1'] = title
-
- def registerButton1Callback(self, callback):
- self.Button1.connect("clicked", callback, "clicked")
- self.Button1.set_sensitive(True)
- self.callback['button1'] = callback
-
- def registerButton2Name(self, title):
- self.Button2.set_label(title)
- self.label['button2'] = title
- #end def registerButton2Name
-
- def registerButton2Callback(self, callback):
- self.Button2.connect("clicked", callback, "clicked")
- self.Button2.set_sensitive(True)
- self.callback['button2'] = callback
- #end def registerButton2Callback
-
- def cardCallback(self, widget, data=None):
- log.debug( "%s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()]) )
-
- def createPlayerLine(self, hbox, site, player):
- log.debug('add:"%s"' % player)
- label = gtk.Label(site +" id:")
- hbox.pack_start(label, False, False, 3)
-
- pname = gtk.Entry()
- pname.set_text(player)
- pname.set_width_chars(20)
- hbox.pack_start(pname, False, True, 0)
- pname.connect("changed", self.__set_hero_name, site)
-
- # Added EntryCompletion but maybe comboBoxEntry is more flexible? (e.g. multiple choices)
- completion = gtk.EntryCompletion()
- pname.set_completion(completion)
- liststore = gtk.ListStore(gobject.TYPE_STRING)
- completion.set_model(liststore)
- completion.set_text_column(0)
- names = self.db.get_player_names(self.conf, self.siteid[site]) # (config=self.conf, site_id=None, like_player_name="%")
- for n in names: # list of single-element "tuples"
- _n = Charset.to_gui(n[0])
- _nt = (_n, )
- liststore.append(_nt)
-
- self.__set_hero_name(pname, site)
-
- def __set_hero_name(self, w, site):
- _name = w.get_text()
- # get_text() returns a str but we want internal variables to be unicode:
- _guiname = unicode(_name)
- self.heroes[site] = _guiname
- #log.debug("setting heroes[%s]: %s"%(site, self.heroes[site]))
- #end def __set_hero_name
-
- def __set_num_hands(self, w, val):
- try:
- self.numHands = int(w.get_text())
- except:
- self.numHands = 0
- #log.debug("setting numHands:", self.numHands)
- #end def __set_num_hands
-
- def createSiteLine(self, hbox, site):
- cb = gtk.CheckButton(site)
- cb.connect('clicked', self.__set_site_select, site)
- cb.set_active(True)
- hbox.pack_start(cb, False, False, 0)
-
- def createGameLine(self, hbox, game):
- cb = gtk.CheckButton(game)
- cb.connect('clicked', self.__set_game_select, game)
- hbox.pack_start(cb, False, False, 0)
- cb.set_active(True)
-
- def createLimitLine(self, hbox, limit, ltext):
- cb = gtk.CheckButton(str(ltext))
- cb.connect('clicked', self.__set_limit_select, limit)
- hbox.pack_start(cb, False, False, 0)
- if limit != "none":
- cb.set_active(True)
- return(cb)
-
- def __set_site_select(self, w, site):
- #print w.get_active()
- self.sites[site] = w.get_active()
- log.debug("self.sites[%s] set to %s" %(site, self.sites[site]))
-
- def __set_game_select(self, w, game):
- #print w.get_active()
- self.games[game] = w.get_active()
- log.debug("self.games[%s] set to %s" %(game, self.games[game]))
- #end def __set_game_select
-
- def __set_limit_select(self, w, limit):
- #print w.get_active()
- self.limits[limit] = w.get_active()
- log.debug("self.limit[%s] set to %s" %(limit, self.limits[limit]))
- if limit.isdigit() or (len(limit) > 2 and (limit[-2:] == 'nl' or limit[-2:] == 'fl' or limit[-2:] == 'pl')):
- if self.limits[limit]:
- if self.cbNoLimits is not None:
- self.cbNoLimits.set_active(False)
- else:
- if self.cbAllLimits is not None:
- self.cbAllLimits.set_active(False)
- if not self.limits[limit]:
- if limit.isdigit():
- if self.cbFL is not None:
- self.cbFL.set_active(False)
- elif (len(limit) > 2 and (limit[-2:] == 'nl')):
- if self.cbNL is not None:
- self.cbNL.set_active(False)
- else:
- if self.cbPL is not None:
- self.cbPL.set_active(False)
- elif limit == "all":
- if self.limits[limit]:
- #for cb in self.cbLimits.values():
- # cb.set_active(True)
- if self.cbFL is not None:
- self.cbFL.set_active(True)
- if self.cbNL is not None:
- self.cbNL.set_active(True)
- if self.cbPL is not None:
- self.cbPL.set_active(True)
- elif limit == "none":
- if self.limits[limit]:
- for cb in self.cbLimits.values():
- cb.set_active(False)
- if self.cbNL is not None:
- self.cbNL.set_active(False)
- if self.cbFL is not None:
- self.cbFL.set_active(False)
- if self.cbPL is not None:
- self.cbPL.set_active(False)
- elif limit == "fl":
- if not self.limits[limit]:
- # only toggle all fl limits off if they are all currently on
- # this stops turning one off from cascading into 'fl' box off
- # and then all fl limits being turned off
- all_fl_on = True
- for cb in self.cbLimits.values():
- t = cb.get_children()[0].get_text()
- if t.isdigit():
- if not cb.get_active():
- all_fl_on = False
- found = {'ring':False, 'tour':False}
- for cb in self.cbLimits.values():
- #print "cb label: ", cb.children()[0].get_text()
- t = cb.get_children()[0].get_text()
- if t.isdigit():
- if self.limits[limit] or all_fl_on:
- cb.set_active(self.limits[limit])
- found[self.types[t]] = True
- if self.limits[limit]:
- if not found[self.type]:
- if self.type == 'ring':
- if 'tour' in self.rb:
- self.rb['tour'].set_active(True)
- elif self.type == 'tour':
- if 'ring' in self.rb:
- self.rb['ring'].set_active(True)
- elif limit == "nl":
- if not self.limits[limit]:
- # only toggle all nl limits off if they are all currently on
- # this stops turning one off from cascading into 'nl' box off
- # and then all nl limits being turned off
- all_nl_on = True
- for cb in self.cbLimits.values():
- t = cb.get_children()[0].get_text()
- if "nl" in t and len(t) > 2:
- if not cb.get_active():
- all_nl_on = False
- found = {'ring':False, 'tour':False}
- for cb in self.cbLimits.values():
- t = cb.get_children()[0].get_text()
- if "nl" in t and len(t) > 2:
- if self.limits[limit] or all_nl_on:
- cb.set_active(self.limits[limit])
- found[self.types[t]] = True
- if self.limits[limit]:
- if not found[self.type]:
- if self.type == 'ring':
- if 'tour' in self.rb:
- self.rb['tour'].set_active(True)
- elif self.type == 'tour':
- if 'ring' in self.rb:
- self.rb['ring'].set_active(True)
- elif limit == "pl":
- if not self.limits[limit]:
- # only toggle all nl limits off if they are all currently on
- # this stops turning one off from cascading into 'nl' box off
- # and then all nl limits being turned off
- all_nl_on = True
- for cb in self.cbLimits.values():
- t = cb.get_children()[0].get_text()
- if "pl" in t and len(t) > 2:
- if not cb.get_active():
- all_nl_on = False
- found = {'ring':False, 'tour':False}
- for cb in self.cbLimits.values():
- t = cb.get_children()[0].get_text()
- if "pl" in t and len(t) > 2:
- if self.limits[limit] or all_nl_on:
- cb.set_active(self.limits[limit])
- found[self.types[t]] = True
- if self.limits[limit]:
- if not found[self.type]:
- if self.type == 'ring':
- if 'tour' in self.rb:
- self.rb['tour'].set_active(True)
- elif self.type == 'tour':
- if 'ring' in self.rb:
- self.rb['ring'].set_active(True)
- elif limit == "ring":
- log.debug("set", limit, "to", self.limits[limit])
- if self.limits[limit]:
- self.type = "ring"
- for cb in self.cbLimits.values():
- #print "cb label: ", cb.children()[0].get_text()
- if self.types[cb.get_children()[0].get_text()] == 'tour':
- cb.set_active(False)
- elif limit == "tour":
- log.debug( "set", limit, "to", self.limits[limit] )
- if self.limits[limit]:
- self.type = "tour"
- for cb in self.cbLimits.values():
- #print "cb label: ", cb.children()[0].get_text()
- if self.types[cb.get_children()[0].get_text()] == 'ring':
- cb.set_active(False)
-
- def __set_seat_select(self, w, seat):
- #print "__set_seat_select: seat =", seat, "active =", w.get_active()
- self.seats[seat] = w.get_active()
- log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) )
-
- def __set_group_select(self, w, group):
- #print "__set_seat_select: seat =", seat, "active =", w.get_active()
- self.groups[group] = w.get_active()
- log.debug( "self.groups[%s] set to %s" %(group, self.groups[group]) )
-
- def fillPlayerFrame(self, vbox, display):
- top_hbox = gtk.HBox(False, 0)
- vbox.pack_start(top_hbox, False, False, 0)
- lbl_title = gtk.Label(self.filterText['playerstitle'])
- lbl_title.set_alignment(xalign=0.0, yalign=0.5)
- top_hbox.pack_start(lbl_title, expand=True, padding=3)
- showb = gtk.Button(label="refresh", stock=None, use_underline=True)
- showb.set_alignment(xalign=1.0, yalign=0.5)
- showb.connect('clicked', self.__refresh, 'players')
-
- vbox1 = gtk.VBox(False, 0)
- vbox.pack_start(vbox1, False, False, 0)
- self.boxes['players'] = vbox1
-
- for site in self.conf.get_supported_sites():
- hBox = gtk.HBox(False, 0)
- vbox1.pack_start(hBox, False, True, 0)
-
- player = self.conf.supported_sites[site].screen_name
- _pname = Charset.to_gui(player)
- self.createPlayerLine(hBox, site, _pname)
-
- if "GroupsAll" in display and display["GroupsAll"] == True:
- hbox = gtk.HBox(False, 0)
- vbox1.pack_start(hbox, False, False, 0)
- cb = gtk.CheckButton(self.filterText['groupsall'])
- cb.connect('clicked', self.__set_group_select, 'allplayers')
- hbox.pack_start(cb, False, False, 0)
- self.sbGroups['allplayers'] = cb
- self.groups['allplayers'] = False
-
- lbl = gtk.Label('Min # Hands:')
- lbl.set_alignment(xalign=1.0, yalign=0.5)
- hbox.pack_start(lbl, expand=True, padding=3)
-
- phands = gtk.Entry()
- phands.set_text('0')
- phands.set_width_chars(8)
- hbox.pack_start(phands, False, False, 0)
- phands.connect("changed", self.__set_num_hands, site)
- top_hbox.pack_start(showb, expand=False, padding=1)
-
- def fillSitesFrame(self, vbox):
- top_hbox = gtk.HBox(False, 0)
- top_hbox.show()
- vbox.pack_start(top_hbox, False, False, 0)
-
- lbl_title = gtk.Label(self.filterText['sitestitle'])
- lbl_title.set_alignment(xalign=0.0, yalign=0.5)
- top_hbox.pack_start(lbl_title, expand=True, padding=3)
-
- showb = gtk.Button(label="hide", stock=None, use_underline=True)
- showb.set_alignment(xalign=1.0, yalign=0.5)
- showb.connect('clicked', self.__toggle_box, 'sites')
- showb.show()
- top_hbox.pack_start(showb, expand=False, padding=1)
-
- vbox1 = gtk.VBox(False, 0)
- self.boxes['sites'] = vbox1
- vbox.pack_start(vbox1, False, False, 0)
-
- for site in self.conf.get_supported_sites():
- hbox = gtk.HBox(False, 0)
- vbox1.pack_start(hbox, False, True, 0)
- self.createSiteLine(hbox, site)
- #Get db site id for filtering later
- #self.cursor.execute(self.sql.query['getSiteId'], (site,))
- #result = self.db.cursor.fetchall()
- #if len(result) == 1:
- # self.siteid[site] = result[0][0]
- #else:
- # print "Either 0 or more than one site matched - EEK"
-
- def fillGamesFrame(self, vbox):
- top_hbox = gtk.HBox(False, 0)
- vbox.pack_start(top_hbox, False, False, 0)
- lbl_title = gtk.Label(self.filterText['gamestitle'])
- lbl_title.set_alignment(xalign=0.0, yalign=0.5)
- top_hbox.pack_start(lbl_title, expand=True, padding=3)
- showb = gtk.Button(label="hide", stock=None, use_underline=True)
- showb.set_alignment(xalign=1.0, yalign=0.5)
- showb.connect('clicked', self.__toggle_box, 'games')
- top_hbox.pack_start(showb, expand=False, padding=1)
-
- vbox1 = gtk.VBox(False, 0)
- vbox.pack_start(vbox1, False, False, 0)
- self.boxes['games'] = vbox1
-
- self.cursor.execute(self.sql.query['getGames'])
- result = self.db.cursor.fetchall()
- if len(result) >= 1:
- for line in result:
- hbox = gtk.HBox(False, 0)
- vbox1.pack_start(hbox, False, True, 0)
- self.createGameLine(hbox, line[0])
- else:
- print "INFO: No games returned from database"
- log.info("No games returned from database")
- #end def fillGamesFrame
-
- def fillLimitsFrame(self, vbox, display):
- top_hbox = gtk.HBox(False, 0)
- vbox.pack_start(top_hbox, False, False, 0)
- lbl_title = gtk.Label(self.filterText['limitstitle'])
- lbl_title.set_alignment(xalign=0.0, yalign=0.5)
- top_hbox.pack_start(lbl_title, expand=True, padding=3)
- showb = gtk.Button(label="hide", stock=None, use_underline=True)
- showb.set_alignment(xalign=1.0, yalign=0.5)
- showb.connect('clicked', self.__toggle_box, 'limits')
-
- vbox1 = gtk.VBox(False, 0)
- vbox.pack_start(vbox1, False, False, 0)
- self.boxes['limits'] = vbox1
-
- self.cursor.execute(self.sql.query['getLimits3'])
- # selects limitType, bigBlind
- result = self.db.cursor.fetchall()
- found = {'nl':False, 'fl':False, 'pl':False, 'ring':False, 'tour':False}
-
- if len(result) >= 1:
- hbox = gtk.HBox(True, 0)
- vbox1.pack_start(hbox, False, False, 0)
- vbox2 = gtk.VBox(False, 0)
- hbox.pack_start(vbox2, False, False, 0)
- vbox3 = gtk.VBox(False, 0)
- hbox.pack_start(vbox3, False, False, 0)
- for i, line in enumerate(result):
- if "UseType" in self.display:
- if line[0] != self.display["UseType"]:
- continue
- hbox = gtk.HBox(False, 0)
- if i <= len(result)/2:
- vbox2.pack_start(hbox, False, False, 0)
- else:
- vbox3.pack_start(hbox, False, False, 0)
- if True: #line[0] == 'ring':
- if line[1] == 'fl':
- name = str(line[2])
- found['fl'] = True
- elif line[1] == 'pl':
- name = str(line[2])+line[1]
- found['pl'] = True
- else:
- name = str(line[2])+line[1]
- found['nl'] = True
- self.cbLimits[name] = self.createLimitLine(hbox, name, name)
- self.types[name] = line[0]
- found[line[0]] = True # type is ring/tour
- self.type = line[0] # if only one type, set it now
- if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2:
- hbox = gtk.HBox(True, 0)
- vbox1.pack_start(hbox, False, False, 0)
- vbox2 = gtk.VBox(False, 0)
- hbox.pack_start(vbox2, False, False, 0)
- vbox3 = gtk.VBox(False, 0)
- hbox.pack_start(vbox3, False, False, 0)
-
- hbox = gtk.HBox(False, 0)
- vbox2.pack_start(hbox, False, False, 0)
- self.cbAllLimits = self.createLimitLine(hbox, 'all', self.filterText['limitsall'])
- hbox = gtk.HBox(False, 0)
- vbox2.pack_start(hbox, False, False, 0)
- self.cbNoLimits = self.createLimitLine(hbox, 'none', self.filterText['limitsnone'])
-
- dest = vbox3 # for ring/tour buttons
- if "LimitType" in display and display["LimitType"] == True and found['nl'] and found['fl']:
- #if found['fl']:
- hbox = gtk.HBox(False, 0)
- vbox3.pack_start(hbox, False, False, 0)
- self.cbFL = self.createLimitLine(hbox, 'fl', self.filterText['limitsFL'])
- #if found['nl']:
- hbox = gtk.HBox(False, 0)
- vbox3.pack_start(hbox, False, False, 0)
- self.cbNL = self.createLimitLine(hbox, 'nl', self.filterText['limitsNL'])
- hbox = gtk.HBox(False, 0)
- vbox3.pack_start(hbox, False, False, 0)
- self.cbPL = self.createLimitLine(hbox, 'pl', self.filterText['limitsPL'])
- dest = vbox2 # for ring/tour buttons
- else:
- print "INFO: No games returned from database"
- log.info("No games returned from database")
-
- if "Type" in display and display["Type"] == True and found['ring'] and found['tour']:
- rb1 = gtk.RadioButton(None, self.filterText['ring'])
- rb1.connect('clicked', self.__set_limit_select, 'ring')
- rb2 = gtk.RadioButton(rb1, self.filterText['tour'])
- rb2.connect('clicked', self.__set_limit_select, 'tour')
- top_hbox.pack_start(rb1, False, False, 0) # (child, expand, fill, padding)
- top_hbox.pack_start(rb2, True, True, 0) # child uses expand space if fill is true
-
- self.rb['ring'] = rb1
- self.rb['tour'] = rb2
- #print "about to set ring to true"
- rb1.set_active(True)
- # set_active doesn't seem to call this for some reason so call manually:
- self.__set_limit_select(rb1, 'ring')
- self.type = 'ring'
- top_hbox.pack_start(showb, expand=False, padding=1)
-
- def fillSeatsFrame(self, vbox, display):
- hbox = gtk.HBox(False, 0)
- vbox.pack_start(hbox, False, False, 0)
- lbl_title = gtk.Label(self.filterText['seatstitle'])
- lbl_title.set_alignment(xalign=0.0, yalign=0.5)
- hbox.pack_start(lbl_title, expand=True, padding=3)
- showb = gtk.Button(label="hide", stock=None, use_underline=True)
- showb.set_alignment(xalign=1.0, yalign=0.5)
- showb.connect('clicked', self.__toggle_box, 'seats')
- hbox.pack_start(showb, expand=False, padding=1)
-
- vbox1 = gtk.VBox(False, 0)
- vbox.pack_start(vbox1, False, False, 0)
- self.boxes['seats'] = vbox1
-
- hbox = gtk.HBox(False, 0)
- vbox1.pack_start(hbox, False, True, 0)
-
- lbl_from = gtk.Label(self.filterText['seatsbetween'])
- lbl_to = gtk.Label(self.filterText['seatsand'])
- adj1 = gtk.Adjustment(value=2, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
- sb1 = gtk.SpinButton(adjustment=adj1, climb_rate=0.0, digits=0)
- adj2 = gtk.Adjustment(value=10, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
- sb2 = gtk.SpinButton(adjustment=adj2, climb_rate=0.0, digits=0)
-
- hbox.pack_start(lbl_from, expand=False, padding=3)
- hbox.pack_start(sb1, False, False, 0)
- hbox.pack_start(lbl_to, expand=False, padding=3)
- hbox.pack_start(sb2, False, False, 0)
-
- self.sbSeats['from'] = sb1
- self.sbSeats['to'] = sb2
- #end def fillSeatsFrame
-
- def fillGroupsFrame(self, vbox, display):
- hbox = gtk.HBox(False, 0)
- vbox.pack_start(hbox, False, False, 0)
- lbl_title = gtk.Label(self.filterText['groupstitle'])
- lbl_title.set_alignment(xalign=0.0, yalign=0.5)
- hbox.pack_start(lbl_title, expand=True, padding=3)
- showb = gtk.Button(label="hide", stock=None, use_underline=True)
- showb.set_alignment(xalign=1.0, yalign=0.5)
- showb.connect('clicked', self.__toggle_box, 'groups')
- hbox.pack_start(showb, expand=False, padding=1)
-
- vbox1 = gtk.VBox(False, 0)
- vbox.pack_start(vbox1, False, False, 0)
- self.boxes['groups'] = vbox1
-
- hbox = gtk.HBox(False, 0)
- vbox1.pack_start(hbox, False, False, 0)
- cb = self.createLimitLine(hbox, 'show', self.filterText['limitsshow'])
-
- hbox = gtk.HBox(False, 0)
- vbox1.pack_start(hbox, False, True, 0)
- cb = gtk.CheckButton(self.filterText['posnshow'])
- cb.connect('clicked', self.__set_group_select, 'posn')
- hbox.pack_start(cb, False, False, 0)
- self.sbGroups['posn'] = cb
- self.groups['posn'] = False
-
- if "SeatSep" in display and display["SeatSep"] == True:
- hbox = gtk.HBox(False, 0)
- vbox1.pack_start(hbox, False, True, 0)
- cb = gtk.CheckButton(self.filterText['seatsshow'])
- cb.connect('clicked', self.__set_seat_select, 'show')
- hbox.pack_start(cb, False, False, 0)
- self.sbSeats['show'] = cb
- self.seats['show'] = False
-
- def fillCardsFrame(self, vbox):
- hbox1 = gtk.HBox(True,0)
- hbox1.show()
- vbox.pack_start(hbox1, True, True, 0)
-
- cards = [ "A", "K","Q","J","T","9","8","7","6","5","4","3","2" ]
-
- for j in range(0, len(cards)):
- hbox1 = gtk.HBox(True,0)
- hbox1.show()
- vbox.pack_start(hbox1, True, True, 0)
- for i in range(0, len(cards)):
- if i < (j + 1):
- suit = "o"
- else:
- suit = "s"
- button = gtk.ToggleButton("%s%s%s" %(cards[i], cards[j], suit))
- button.connect("toggled", self.cardCallback, "%s%s%s" %(cards[i], cards[j], suit))
- hbox1.pack_start(button, True, True, 0)
- button.show()
-
- def fillDateFrame(self, vbox):
- # Hat tip to Mika Bostrom - calendar code comes from PokerStats
- top_hbox = gtk.HBox(False, 0)
- vbox.pack_start(top_hbox, False, False, 0)
- lbl_title = gtk.Label(self.filterText['datestitle'])
- lbl_title.set_alignment(xalign=0.0, yalign=0.5)
- top_hbox.pack_start(lbl_title, expand=True, padding=3)
- showb = gtk.Button(label="hide", stock=None, use_underline=True)
- showb.set_alignment(xalign=1.0, yalign=0.5)
- showb.connect('clicked', self.__toggle_box, 'dates')
- top_hbox.pack_start(showb, expand=False, padding=1)
-
- vbox1 = gtk.VBox(False, 0)
- vbox.pack_start(vbox1, False, False, 0)
- self.boxes['dates'] = vbox1
-
- hbox = gtk.HBox()
- vbox1.pack_start(hbox, False, True, 0)
-
- lbl_start = gtk.Label('From:')
-
- btn_start = gtk.Button()
- btn_start.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
- btn_start.connect('clicked', self.__calendar_dialog, self.start_date)
-
- hbox.pack_start(lbl_start, expand=False, padding=3)
- hbox.pack_start(btn_start, expand=False, padding=3)
- hbox.pack_start(self.start_date, expand=False, padding=2)
-
- #New row for end date
- hbox = gtk.HBox()
- vbox1.pack_start(hbox, False, True, 0)
-
- lbl_end = gtk.Label(' To:')
- btn_end = gtk.Button()
- btn_end.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
- btn_end.connect('clicked', self.__calendar_dialog, self.end_date)
-
- btn_clear = gtk.Button(label=' Clear Dates ')
- btn_clear.connect('clicked', self.__clear_dates)
-
- hbox.pack_start(lbl_end, expand=False, padding=3)
- hbox.pack_start(btn_end, expand=False, padding=3)
- hbox.pack_start(self.end_date, expand=False, padding=2)
-
- hbox.pack_start(btn_clear, expand=False, padding=15)
- #end def fillDateFrame
-
- def __refresh(self, widget, entry):
- for w in self.mainVBox.get_children():
- w.destroy()
- self.make_filter()
-
- def __toggle_box(self, widget, entry):
- if self.boxes[entry].props.visible:
- self.boxes[entry].hide()
- widget.set_label("show")
- else:
- self.boxes[entry].show()
- widget.set_label("hide")
- #end def __toggle_box
-
- def __calendar_dialog(self, widget, entry):
- d = gtk.Window(gtk.WINDOW_TOPLEVEL)
- d.set_title('Pick a date')
-
- vb = gtk.VBox()
- cal = gtk.Calendar()
- vb.pack_start(cal, expand=False, padding=0)
-
- btn = gtk.Button('Done')
- btn.connect('clicked', self.__get_date, cal, entry, d)
-
- vb.pack_start(btn, expand=False, padding=4)
-
- d.add(vb)
- d.set_position(gtk.WIN_POS_MOUSE)
- d.show_all()
- #end def __calendar_dialog
-
- def __clear_dates(self, w):
- self.start_date.set_text('')
- self.end_date.set_text('')
- #end def __clear_dates
-
- def __get_dates(self):
- # self.day_start gives user's start of day in hours
- offset = int(self.day_start * 3600) # calc day_start in seconds
-
- t1 = self.start_date.get_text()
- t2 = self.end_date.get_text()
-
- if t1 == '':
- t1 = '1970-01-02'
- if t2 == '':
- t2 = '2020-12-12'
-
- s1 = strptime(t1, "%Y-%m-%d") # make time_struct
- s2 = strptime(t2, "%Y-%m-%d")
- e1 = mktime(s1) + offset # s1 is localtime, but returned time since epoch is UTC, then add the
- e2 = mktime(s2) + offset # s2 is localtime, but returned time since epoch is UTC
- e2 = e2 + 24 * 3600 - 1 # date test is inclusive, so add 23h 59m 59s to e2
-
- adj_t1 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e1)) # make adjusted string including time
- adj_t2 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e2))
- log.info("t1="+t1+" adj_t1="+adj_t1+'.')
-
- return (adj_t1, adj_t2)
- #end def __get_dates
-
- def __get_date(self, widget, calendar, entry, win):
- # year and day are correct, month is 0..11
- (year, month, day) = calendar.get_date()
- month += 1
- ds = '%04d-%02d-%02d' % (year, month, day)
- entry.set_text(ds)
- win.destroy()
-
-def main(argv=None):
- """main can also be called in the python interpreter, by supplying the command line as the argument."""
- if argv is None:
- argv = sys.argv[1:]
-
- def destroy(*args): # call back for terminating the main eventloop
- gtk.main_quit()
-
- parser = OptionParser()
- (options, argv) = parser.parse_args(args = argv)
-
- config = Configuration.Config()
- db = None
-
- db = Database.Database()
- db.do_connect(config)
-
- qdict = SQL.SQL(db.get_backend_name())
-
- i = Filters(db, config, qdict)
- main_window = gtk.Window()
- main_window.connect('destroy', destroy)
- main_window.add(i.get_vbox())
- main_window.show()
- gtk.main()
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py
index 96026864..68cbacc7 100644
--- a/pyfpdb/GuiGraphViewer.py
+++ b/pyfpdb/GuiGraphViewer.py
@@ -44,7 +44,7 @@ except ImportError, inst:
import fpdb_import
import Database
-import Filters
+import RingFilters
import Charset
class GuiGraphViewer (threading.Thread):
@@ -75,7 +75,7 @@ class GuiGraphViewer (threading.Thread):
"Button2" : True
}
- self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
+ self.filters = RingFilters.RingFilters(self.db, self.conf, self.sql, display = filters_display)
self.filters.registerButton1Name("Refresh _Graph")
self.filters.registerButton1Callback(self.generateGraph)
self.filters.registerButton2Name("_Export to File")
diff --git a/pyfpdb/GuiPlayerStats.py b/pyfpdb/GuiPlayerStats.py
deleted file mode 100644
index 80786d76..00000000
--- a/pyfpdb/GuiPlayerStats.py
+++ /dev/null
@@ -1,680 +0,0 @@
-#!/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 .
-#In the "official" distribution you can find the license in agpl-3.0.txt.
-
-import traceback
-import threading
-import pygtk
-pygtk.require('2.0')
-import gtk
-import os
-import sys
-from time import time, strftime
-
-import Card
-import fpdb_import
-import Database
-import Filters
-import Charset
-
-colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5
-ranks = {'x':0, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
-
-class GuiPlayerStats (threading.Thread):
-
- def __init__(self, config, querylist, mainwin, debug=True):
- self.debug = debug
- self.conf = config
- self.main_window = mainwin
- self.sql = querylist
-
- self.liststore = [] # gtk.ListStore[] stores the contents of the grids
- self.listcols = [] # gtk.TreeViewColumn[][] stores the columns in the grids
-
- self.MYSQL_INNODB = 2
- self.PGSQL = 3
- self.SQLITE = 4
-
- # create new db connection to avoid conflicts with other threads
- self.db = Database.Database(self.conf, sql=self.sql)
- self.cursor = self.db.cursor
-
- settings = {}
- settings.update(self.conf.get_db_parameters())
- settings.update(self.conf.get_tv_parameters())
- settings.update(self.conf.get_import_parameters())
- settings.update(self.conf.get_default_paths())
-
- # text used on screen stored here so that it can be configured
- self.filterText = {'handhead':'Hand Breakdown for all levels listed above'
- }
-
- filters_display = { "Heroes" : True,
- "Sites" : True,
- "Games" : True,
- "Limits" : True,
- "LimitSep" : True,
- "LimitType" : True,
- "Type" : True,
- "Seats" : True,
- "SeatSep" : True,
- "Dates" : True,
- "Groups" : True,
- "GroupsAll" : True,
- "Button1" : True,
- "Button2" : True
- }
-
- self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
- self.filters.registerButton1Name("_Filters")
- self.filters.registerButton1Callback(self.showDetailFilter)
- self.filters.registerButton2Name("_Refresh Stats")
- self.filters.registerButton2Callback(self.refreshStats)
-
- # ToDo: store in config
- # ToDo: create popup to adjust column config
- # columns to display, keys match column name returned by sql, values in tuple are:
- # is column displayed, column heading, xalignment, formatting, celltype
- self.columns = [ ["game", True, "Game", 0.0, "%s", "str"]
- , ["hand", False, "Hand", 0.0, "%s", "str"] # true not allowed for this line
- , ["plposition", False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code)
- , ["pname", False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code)
- , ["n", True, "Hds", 1.0, "%1.0f", "str"]
- , ["avgseats", False, "Seats", 1.0, "%3.1f", "str"]
- , ["vpip", True, "VPIP", 1.0, "%3.1f", "str"]
- , ["pfr", True, "PFR", 1.0, "%3.1f", "str"]
- , ["pf3", True, "PF3", 1.0, "%3.1f", "str"]
- , ["aggfac", True, "AggFac", 1.0, "%2.2f", "str"]
- , ["aggfrq", True, "AggFreq", 1.0, "%3.1f", "str"]
- , ["conbet", True, "ContBet", 1.0, "%3.1f", "str"]
- , ["steals", True, "Steals", 1.0, "%3.1f", "str"]
- , ["saw_f", True, "Saw_F", 1.0, "%3.1f", "str"]
- , ["sawsd", True, "SawSD", 1.0, "%3.1f", "str"]
- , ["wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f", "str"]
- , ["wmsd", True, "W$SD", 1.0, "%3.1f", "str"]
- , ["flafq", True, "FlAFq", 1.0, "%3.1f", "str"]
- , ["tuafq", True, "TuAFq", 1.0, "%3.1f", "str"]
- , ["rvafq", True, "RvAFq", 1.0, "%3.1f", "str"]
- , ["pofafq", False, "PoFAFq", 1.0, "%3.1f", "str"]
- , ["net", True, "Net($)", 1.0, "%6.2f", "cash"]
- , ["bbper100", True, "bb/100", 1.0, "%4.2f", "str"]
- , ["rake", True, "Rake($)", 1.0, "%6.2f", "cash"]
- , ["bb100xr", True, "bbxr/100", 1.0, "%4.2f", "str"]
- , ["variance", True, "Variance", 1.0, "%5.2f", "str"]
- ]
-
- # Detail filters: This holds the data used in the popup window, extra values are
- # added at the end of these lists during processing
- # sql test, screen description, min, max
- self.handtests = [ # already in filter class : ['h.seats', 'Number of Players', 2, 10]
- ['h.maxSeats', 'Size of Table', 2, 10]
- ,['h.playersVpi', 'Players who VPI', 0, 10]
- ,['h.playersAtStreet1', 'Players at Flop', 0, 10]
- ,['h.playersAtStreet2', 'Players at Turn', 0, 10]
- ,['h.playersAtStreet3', 'Players at River', 0, 10]
- ,['h.playersAtStreet4', 'Players at Street7', 0, 10]
- ,['h.playersAtShowdown', 'Players at Showdown', 0, 10]
- ,['h.street0Raises', 'Bets to See Flop', 0, 5]
- ,['h.street1Raises', 'Bets to See Turn', 0, 5]
- ,['h.street2Raises', 'Bets to See River', 0, 5]
- ,['h.street3Raises', 'Bets to See Street7', 0, 5]
- ,['h.street4Raises', 'Bets to See Showdown', 0, 5]
- ]
-
- self.stats_frame = None
- self.stats_vbox = None
- self.detailFilters = [] # the data used to enhance the sql select
-
- #self.main_hbox = gtk.HBox(False, 0)
- #self.main_hbox.show()
- self.main_hbox = gtk.HPaned()
-
- self.stats_frame = gtk.Frame()
- self.stats_frame.show()
-
- self.stats_vbox = gtk.VPaned()
- self.stats_vbox.show()
- self.stats_frame.add(self.stats_vbox)
- # self.fillStatsFrame(self.stats_vbox)
-
- #self.main_hbox.pack_start(self.filters.get_vbox())
- #self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True)
- self.main_hbox.pack1(self.filters.get_vbox())
- self.main_hbox.pack2(self.stats_frame)
- self.main_hbox.show()
-
- # make sure Hand column is not displayed
- [x for x in self.columns if x[0] == 'hand'][0][1] = False
- self.last_pos = -1
-
-
- def get_vbox(self):
- """returns the vbox of this thread"""
- return self.main_hbox
- #end def get_vbox
-
- def refreshStats(self, widget, data):
- self.last_pos = self.stats_vbox.get_position()
- try: self.stats_vbox.destroy()
- except AttributeError: pass
- self.liststore = []
- self.listcols = []
- #self.stats_vbox = gtk.VBox(False, 0)
- self.stats_vbox = gtk.VPaned()
- self.stats_vbox.show()
- self.stats_frame.add(self.stats_vbox)
- self.fillStatsFrame(self.stats_vbox)
- if self.last_pos > 0:
- self.stats_vbox.set_position(self.last_pos)
- #end def refreshStats
-
- def fillStatsFrame(self, vbox):
- sites = self.filters.getSites()
- heroes = self.filters.getHeroes()
- siteids = self.filters.getSiteIds()
- limits = self.filters.getLimits()
- type = self.filters.getType()
- seats = self.filters.getSeats()
- groups = self.filters.getGroups()
- dates = self.filters.getDates()
- games = self.filters.getGames()
- sitenos = []
- playerids = []
-
- # Which sites are selected?
- for site in sites:
- if sites[site] == True:
- sitenos.append(siteids[site])
- _hname = Charset.to_utf8(heroes[site])
- result = self.db.get_player_id(self.conf, site, _hname)
- if result is not None:
- playerids.append(int(result))
-
- if not sitenos:
- #Should probably pop up here.
- print "No sites selected - defaulting to PokerStars"
- sitenos = [2]
- if not playerids:
- print "No player ids found"
- return
- if not limits:
- print "No limits found"
- return
-
- self.createStatsTable(vbox, playerids, sitenos, limits, type, seats, groups, dates, games)
- #end def fillStatsFrame
-
- def createStatsTable(self, vbox, playerids, sitenos, limits, type, seats, groups, dates, games):
- startTime = time()
- show_detail = True
-
- # Scrolled window for summary table
- swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
- swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- swin.show()
- vbox.pack1(swin)
-
- # Display summary table at top of page
- # 3rd parameter passes extra flags, currently includes:
- # holecards - whether to display card breakdown (True/False)
- # numhands - min number hands required when displaying all players
- # gridnum - index for grid data structures
- flags = [False, self.filters.getNumHands(), 0]
- self.addGrid(swin, 'playerDetailedStats', flags, playerids
- ,sitenos, limits, type, seats, groups, dates, games)
-
- if 'allplayers' in groups and groups['allplayers']:
- # can't currently do this combination so skip detailed table
- show_detail = False
-
- if show_detail:
- # Separator
- vbox2 = gtk.VBox(False, 0)
- heading = gtk.Label(self.filterText['handhead'])
- heading.show()
- vbox2.pack_start(heading, expand=False, padding=3)
-
- # Scrolled window for detailed table (display by hand)
- swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
- swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- swin.show()
- vbox2.pack_start(swin, expand=True, padding=3)
- vbox.pack2(vbox2)
- vbox2.show()
-
- # Detailed table
- flags[0] = True
- flags[2] = 1
- self.addGrid(swin, 'playerDetailedStats', flags, playerids
- ,sitenos, limits, type, seats, groups, dates, games)
-
- self.db.rollback()
- print "Stats page displayed in %4.2f seconds" % (time() - startTime)
- #end def createStatsTable
-
- def reset_style_render_func(self, treeviewcolumn, cell, model, iter):
- cell.set_property('foreground', 'black')
- #end def reset_style_render_func
-
- def ledger_style_render_func(self, tvcol, cell, model, iter):
- str = cell.get_property('text')
- if '-' in str:
- str = str.replace("-", "")
- str = "(%s)" %(str)
- cell.set_property('text', str)
- cell.set_property('foreground', 'red')
- else:
- cell.set_property('foreground', 'darkgreen')
-
- return
-
- def sortnums(self, model, iter1, iter2, nums):
- try:
- ret = 0
- (n, grid) = nums
- a = self.liststore[grid].get_value(iter1, n)
- b = self.liststore[grid].get_value(iter2, n)
- if 'f' in self.cols_to_show[n][4]:
- try: a = float(a)
- except: a = 0.0
- try: b = float(b)
- except: b = 0.0
- if n == 0 and grid == 1: #make sure it only works on the starting hands
- a1,a2,a3 = ranks[a[0]], ranks[a[1]], (a+'o')[2]
- b1,b2,b3 = ranks[b[0]], ranks[b[1]], (b+'o')[2]
- if a1 > b1 or ( a1 == b1 and (a2 > b2 or (a2 == b2 and a3 > b3) ) ):
- ret = 1
- else:
- ret = -1
- else:
- if a < b:
- ret = -1
- elif a == b:
- ret = 0
- else:
- ret = 1
- #print "n =", n, "iter1[n] =", self.liststore[grid].get_value(iter1,n), "iter2[n] =", self.liststore[grid].get_value(iter2,n), "ret =", ret
- except:
- err = traceback.extract_tb(sys.exc_info()[2])
- print "***sortnums error: " + str(sys.exc_info()[1])
- print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
-
- return(ret)
-
- def sortcols(self, col, nums):
- try:
- #This doesn't actually work yet - clicking heading in top section sorts bottom section :-(
- (n, grid) = nums
- if not col.get_sort_indicator() or col.get_sort_order() == gtk.SORT_ASCENDING:
- col.set_sort_order(gtk.SORT_DESCENDING)
- else:
- col.set_sort_order(gtk.SORT_ASCENDING)
- self.liststore[grid].set_sort_column_id(n, col.get_sort_order())
- self.liststore[grid].set_sort_func(n, self.sortnums, (n,grid))
- for i in xrange(len(self.listcols[grid])):
- self.listcols[grid][i].set_sort_indicator(False)
- self.listcols[grid][n].set_sort_indicator(True)
- # use this listcols[col].set_sort_indicator(True)
- # to turn indicator off for other cols
- except:
- err = traceback.extract_tb(sys.exc_info()[2])
- print "***sortcols error: " + str(sys.exc_info()[1])
- print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
- #end def sortcols
-
- def addGrid(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates, games):
- counter = 0
- row = 0
- sqlrow = 0
- if not flags: holecards,grid = False,0
- else: holecards,grid = flags[0],flags[2]
-
- tmp = self.sql.query[query]
- tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, type, seats, groups, dates, games)
- self.cursor.execute(tmp)
- result = self.cursor.fetchall()
- colnames = [desc[0].lower() for desc in self.cursor.description]
-
- # pre-fetch some constant values:
- self.cols_to_show = [x for x in self.columns if x[colshow]]
- hgametypeid_idx = colnames.index('hgametypeid')
-
- assert len(self.liststore) == grid, "len(self.liststore)="+str(len(self.liststore))+" grid-1="+str(grid)
- self.liststore.append( gtk.ListStore(*([str] * len(self.cols_to_show))) )
- view = gtk.TreeView(model=self.liststore[grid])
- view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
- #vbox.pack_start(view, expand=False, padding=3)
- vbox.add(view)
- textcell = gtk.CellRendererText()
- textcell50 = gtk.CellRendererText()
- textcell50.set_property('xalign', 0.5)
- numcell = gtk.CellRendererText()
- numcell.set_property('xalign', 1.0)
- assert len(self.listcols) == grid
- self.listcols.append( [] )
-
- # Create header row eg column: ("game", True, "Game", 0.0, "%s")
- for col, column in enumerate(self.cols_to_show):
- if column[colalias] == 'game' and holecards:
- s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading]
- else:
- s = column[colheading]
- self.listcols[grid].append(gtk.TreeViewColumn(s))
- view.append_column(self.listcols[grid][col])
- if column[colformat] == '%s':
- if column[colxalign] == 0.0:
- self.listcols[grid][col].pack_start(textcell, expand=True)
- self.listcols[grid][col].add_attribute(textcell, 'text', col)
- cellrend = textcell
- else:
- self.listcols[grid][col].pack_start(textcell50, expand=True)
- self.listcols[grid][col].add_attribute(textcell50, 'text', col)
- cellrend = textcell50
- self.listcols[grid][col].set_expand(True)
- else:
- self.listcols[grid][col].pack_start(numcell, expand=True)
- self.listcols[grid][col].add_attribute(numcell, 'text', col)
- self.listcols[grid][col].set_expand(True)
- cellrend = numcell
- #self.listcols[grid][col].set_alignment(column[colxalign]) # no effect?
- self.listcols[grid][col].set_clickable(True)
- self.listcols[grid][col].connect("clicked", self.sortcols, (col,grid))
- if col == 0:
- self.listcols[grid][col].set_sort_order(gtk.SORT_DESCENDING)
- self.listcols[grid][col].set_sort_indicator(True)
- if column[coltype] == 'cash':
- self.listcols[grid][col].set_cell_data_func(numcell, self.ledger_style_render_func)
- else:
- self.listcols[grid][col].set_cell_data_func(cellrend, self.reset_style_render_func)
-
- rows = len(result) # +1 for title row
-
- while sqlrow < rows:
- treerow = []
- for col,column in enumerate(self.cols_to_show):
- if column[colalias] in colnames:
- value = result[sqlrow][colnames.index(column[colalias])]
- if column[colalias] == 'plposition':
- if value == 'B':
- value = 'BB'
- elif value == 'S':
- value = 'SB'
- elif value == '0':
- value = 'Btn'
- else:
- if column[colalias] == 'game':
- if holecards:
- value = Card.twoStartCardString( result[sqlrow][hgametypeid_idx] )
- else:
- minbb = result[sqlrow][colnames.index('minbigblind')]
- maxbb = result[sqlrow][colnames.index('maxbigblind')]
- value = result[sqlrow][colnames.index('limittype')] + ' ' \
- + result[sqlrow][colnames.index('category')].title() + ' ' \
- + result[sqlrow][colnames.index('name')] + ' $'
- if 100 * int(minbb/100.0) != minbb:
- value += '%.2f' % (minbb/100.0)
- else:
- value += '%.0f' % (minbb/100.0)
- if minbb != maxbb:
- if 100 * int(maxbb/100.0) != maxbb:
- value += ' - $' + '%.2f' % (maxbb/100.0)
- else:
- value += ' - $' + '%.0f' % (maxbb/100.0)
- else:
- continue
- if value and value != -999:
- treerow.append(column[colformat] % value)
- else:
- treerow.append(' ')
- iter = self.liststore[grid].append(treerow)
- #print treerow
- sqlrow += 1
- row += 1
- vbox.show_all()
- #end def addGrid
-
- def refineQuery(self, query, flags, playerids, sitenos, limits, type, seats, groups, dates, games):
- having = ''
- if not flags:
- holecards = False
- numhands = 0
- else:
- holecards = flags[0]
- numhands = flags[1]
-
- if 'allplayers' in groups and groups['allplayers']:
- nametest = "(hp.playerId)"
- if holecards or groups['posn']:
- pname = "'all players'"
- # set flag in self.columns to not show player name column
- [x for x in self.columns if x[0] == 'pname'][0][1] = False
- # can't do this yet (re-write doing more maths in python instead of sql?)
- if numhands:
- nametest = "(-1)"
- else:
- pname = "p.name"
- # set flag in self.columns to show player name column
- [x for x in self.columns if x[0] == 'pname'][0][1] = True
- if numhands:
- having = ' and count(1) > %d ' % (numhands,)
- else:
- if playerids:
- nametest = str(tuple(playerids))
- nametest = nametest.replace("L", "")
- nametest = nametest.replace(",)",")")
- else:
- nametest = "1 = 2"
- pname = "p.name"
- # set flag in self.columns to not show player name column
- [x for x in self.columns if x[0] == 'pname'][0][1] = False
- query = query.replace("", nametest)
- query = query.replace("", pname)
- query = query.replace("", having)
-
- gametest = ""
- q = []
- for m in self.filters.display.items():
- if m[0] == 'Games' and m[1]:
- for n in games:
- if games[n]:
- q.append(n)
- if len(q) > 0:
- gametest = str(tuple(q))
- gametest = gametest.replace("L", "")
- gametest = gametest.replace(",)",")")
- gametest = gametest.replace("u'","'")
- gametest = "and gt.category in %s" % gametest
- else:
- gametest = "and gt.category IS NULL"
- query = query.replace("", gametest)
-
- sitetest = ""
- q = []
- for m in self.filters.display.items():
- if m[0] == 'Sites' and m[1]:
- for n in sitenos:
- q.append(n)
- if len(q) > 0:
- sitetest = str(tuple(q))
- sitetest = sitetest.replace("L", "")
- sitetest = sitetest.replace(",)",")")
- sitetest = sitetest.replace("u'","'")
- sitetest = "and gt.siteId in %s" % sitetest
- else:
- sitetest = "and gt.siteId IS NULL"
- query = query.replace("", sitetest)
-
- if seats:
- query = query.replace('', 'between ' + str(seats['from']) + ' and ' + str(seats['to']))
- if 'show' in seats and seats['show']:
- query = query.replace('', ',h.seats')
- query = query.replace('', ',h.seats')
- else:
- query = query.replace('', '')
- query = query.replace('', '')
- else:
- query = query.replace('', 'between 0 and 100')
- query = query.replace('', '')
- query = query.replace('', '')
-
- lims = [int(x) for x in limits if x.isdigit()]
- potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl']
- nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
- bbtest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
- # and ( (limit and bb in()) or (nolimit and bb in ()) )
- if lims:
- blindtest = str(tuple(lims))
- blindtest = blindtest.replace("L", "")
- blindtest = blindtest.replace(",)",")")
- bbtest = bbtest + blindtest + ' ) '
- else:
- bbtest = bbtest + '(-1) ) '
- bbtest = bbtest + " or (gt.limitType = 'pl' and gt.bigBlind in "
- if potlims:
- blindtest = str(tuple(potlims))
- blindtest = blindtest.replace("L", "")
- blindtest = blindtest.replace(",)",")")
- bbtest = bbtest + blindtest + ' ) '
- else:
- bbtest = bbtest + '(-1) ) '
- bbtest = bbtest + " or (gt.limitType = 'nl' and gt.bigBlind in "
- if nolims:
- blindtest = str(tuple(nolims))
- blindtest = blindtest.replace("L", "")
- blindtest = blindtest.replace(",)",")")
- bbtest = bbtest + blindtest + ' ) )'
- else:
- bbtest = bbtest + '(-1) ) )'
- if type == 'ring':
- bbtest = bbtest + " and gt.type = 'ring' "
- elif type == 'tour':
- bbtest = " and gt.type = 'tour' "
- query = query.replace("", bbtest)
-
- if holecards: # re-use level variables for hole card query
- query = query.replace("", "hp.startcards")
- query = query.replace(""
- , ",case when floor((hp.startcards-1)/13) >= mod((hp.startcards-1),13) then hp.startcards + 0.1 "
- + " else 13*mod((hp.startcards-1),13) + floor((hp.startcards-1)/13) + 1 "
- + " end desc ")
- else:
- query = query.replace("", "")
- groupLevels = "show" not in str(limits)
- if groupLevels:
- query = query.replace("", "p.name") # need to use p.name for sqlite posn stats to work
- else:
- query = query.replace("", "h.gameTypeId")
-
- # process self.detailFilters (a list of tuples)
- flagtest = ''
- #self.detailFilters = [('h.seats', 5, 6)] # for debug
- if self.detailFilters:
- for f in self.detailFilters:
- if len(f) == 3:
- # X between Y and Z
- flagtest += ' and %s between %s and %s ' % (f[0], str(f[1]), str(f[2]))
- query = query.replace("", flagtest)
-
- # allow for differences in sql cast() function:
- if self.db.backend == self.MYSQL_INNODB:
- query = query.replace("", 'signed ')
- else:
- query = query.replace("", '')
-
- # Filter on dates
- query = query.replace("", " between '" + dates[0] + "' and '" + dates[1] + "'")
-
- # Group by position?
- if groups['posn']:
- #query = query.replace("", "case hp.position when '0' then 'Btn' else hp.position end")
- query = query.replace("", "hp.position")
- # set flag in self.columns to show posn column
- [x for x in self.columns if x[0] == 'plposition'][0][1] = True
- else:
- query = query.replace("", "gt.base")
- # unset flag in self.columns to hide posn column
- [x for x in self.columns if x[0] == 'plposition'][0][1] = False
-
- #print "query =\n", query
- return(query)
- #end def refineQuery
-
- def showDetailFilter(self, widget, data):
- detailDialog = gtk.Dialog(title="Detailed Filters", parent=self.main_window
- ,flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
- ,buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
- gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
-
- handbox = gtk.VBox(True, 0)
- detailDialog.vbox.pack_start(handbox, False, False, 0)
- handbox.show()
-
- label = gtk.Label("Hand Filters:")
- handbox.add(label)
- label.show()
-
- betweenFilters = []
- for htest in self.handtests:
- hbox = gtk.HBox(False, 0)
- handbox.pack_start(hbox, False, False, 0)
- hbox.show()
-
- cb = gtk.CheckButton()
- lbl_from = gtk.Label(htest[1])
- lbl_from.set_alignment(xalign=0.0, yalign=0.5)
- lbl_tween = gtk.Label('between')
- lbl_to = gtk.Label('and')
- adj1 = gtk.Adjustment(value=htest[2], lower=0, upper=10, step_incr=1, page_incr=1, page_size=0)
- sb1 = gtk.SpinButton(adjustment=adj1, climb_rate=0.0, digits=0)
- adj2 = gtk.Adjustment(value=htest[3], lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
- sb2 = gtk.SpinButton(adjustment=adj2, climb_rate=0.0, digits=0)
-
- for df in [x for x in self.detailFilters if x[0] == htest[0]]:
- cb.set_active(True)
-
- hbox.pack_start(cb, expand=False, padding=3)
- hbox.pack_start(lbl_from, expand=True, padding=3)
- hbox.pack_start(lbl_tween, expand=False, padding=3)
- hbox.pack_start(sb1, False, False, 0)
- hbox.pack_start(lbl_to, expand=False, padding=3)
- hbox.pack_start(sb2, False, False, 0)
-
- cb.show()
- lbl_from.show()
- lbl_tween.show()
- sb1.show()
- lbl_to.show()
- sb2.show()
-
- htest[4:7] = [cb,sb1,sb2]
-
- response = detailDialog.run()
-
- if response == gtk.RESPONSE_ACCEPT:
- self.detailFilters = []
- for ht in self.handtests:
- if ht[4].get_active():
- self.detailFilters.append( (ht[0], ht[5].get_value_as_int(), ht[6].get_value_as_int()) )
- ht[2],ht[3] = ht[5].get_value_as_int(), ht[6].get_value_as_int()
- print "detailFilters =", self.detailFilters
- self.refreshStats(None, None)
-
- detailDialog.destroy()
-
-
-
-
-
diff --git a/pyfpdb/GuiPositionalStats.py b/pyfpdb/GuiPositionalStats.py
index 724d0f84..1764c5ea 100644
--- a/pyfpdb/GuiPositionalStats.py
+++ b/pyfpdb/GuiPositionalStats.py
@@ -24,7 +24,7 @@ from time import time, strftime
import fpdb_import
import Database
-import Filters
+import RingFilters
import FpdbSQLQueries
class GuiPositionalStats (threading.Thread):
@@ -58,7 +58,7 @@ class GuiPositionalStats (threading.Thread):
"Button2" : False
}
- self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
+ self.filters = RingFilters.RingFilters(self.db, self.conf, self.sql, display = filters_display)
self.filters.registerButton1Name("Refresh")
self.filters.registerButton1Callback(self.refreshStats)
diff --git a/pyfpdb/GuiRingPlayerStats.py b/pyfpdb/GuiRingPlayerStats.py
index 11e8a1b1..68878606 100644
--- a/pyfpdb/GuiRingPlayerStats.py
+++ b/pyfpdb/GuiRingPlayerStats.py
@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-#Copyright 2010 Steffen Schaumburg
+#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.
@@ -15,22 +15,666 @@
#along with this program. If not, see .
#In the "official" distribution you can find the license in agpl-3.0.txt.
-#import traceback
-#import threading
-#import pygtk
-#pygtk.require('2.0')
-#import gtk
-#import os
-#import sys
-#from time import time, strftime
+import traceback
+import threading
+import pygtk
+pygtk.require('2.0')
+import gtk
+import os
+import sys
+from time import time, strftime
-#import Card
-#import fpdb_import
-#import Database
+import Card
+import fpdb_import
+import Database
import RingFilters
-import GuiPlayerStats
-#import Charset
+import Charset
+
+colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5
+ranks = {'x':0, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
+
+class GuiRingPlayerStats (threading.Thread):
+
+ def __init__(self, config, querylist, mainwin, debug=True):
+ self.debug = debug
+ self.conf = config
+ self.main_window = mainwin
+ self.sql = querylist
+
+ self.liststore = [] # gtk.ListStore[] stores the contents of the grids
+ self.listcols = [] # gtk.TreeViewColumn[][] stores the columns in the grids
+
+ self.MYSQL_INNODB = 2
+ self.PGSQL = 3
+ self.SQLITE = 4
+
+ # create new db connection to avoid conflicts with other threads
+ self.db = Database.Database(self.conf, sql=self.sql)
+ self.cursor = self.db.cursor
+
+ settings = {}
+ settings.update(self.conf.get_db_parameters())
+ settings.update(self.conf.get_tv_parameters())
+ settings.update(self.conf.get_import_parameters())
+ settings.update(self.conf.get_default_paths())
+
+ # text used on screen stored here so that it can be configured
+ self.filterText = {'handhead':'Hand Breakdown for all levels listed above'
+ }
+
+ filters_display = { "Heroes" : True,
+ "Sites" : True,
+ "Games" : True,
+ "Limits" : True,
+ "LimitSep" : True,
+ "LimitType" : True,
+ "Type" : True,
+ "Seats" : True,
+ "SeatSep" : True,
+ "Dates" : True,
+ "Groups" : True,
+ "GroupsAll" : True,
+ "Button1" : True,
+ "Button2" : True
+ }
+
+ self.filters = RingFilters.RingFilters(self.db, self.conf, self.sql, display = filters_display)
+ self.filters.registerButton1Name("_Filters")
+ self.filters.registerButton1Callback(self.showDetailFilter)
+ self.filters.registerButton2Name("_Refresh Stats")
+ self.filters.registerButton2Callback(self.refreshStats)
+
+ # ToDo: store in config
+ # ToDo: create popup to adjust column config
+ # columns to display, keys match column name returned by sql, values in tuple are:
+ # is column displayed, column heading, xalignment, formatting, celltype
+ self.columns = [ ["game", True, "Game", 0.0, "%s", "str"]
+ , ["hand", False, "Hand", 0.0, "%s", "str"] # true not allowed for this line
+ , ["plposition", False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code)
+ , ["pname", False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code)
+ , ["n", True, "Hds", 1.0, "%1.0f", "str"]
+ , ["avgseats", False, "Seats", 1.0, "%3.1f", "str"]
+ , ["vpip", True, "VPIP", 1.0, "%3.1f", "str"]
+ , ["pfr", True, "PFR", 1.0, "%3.1f", "str"]
+ , ["pf3", True, "PF3", 1.0, "%3.1f", "str"]
+ , ["aggfac", True, "AggFac", 1.0, "%2.2f", "str"]
+ , ["aggfrq", True, "AggFreq", 1.0, "%3.1f", "str"]
+ , ["conbet", True, "ContBet", 1.0, "%3.1f", "str"]
+ , ["steals", True, "Steals", 1.0, "%3.1f", "str"]
+ , ["saw_f", True, "Saw_F", 1.0, "%3.1f", "str"]
+ , ["sawsd", True, "SawSD", 1.0, "%3.1f", "str"]
+ , ["wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f", "str"]
+ , ["wmsd", True, "W$SD", 1.0, "%3.1f", "str"]
+ , ["flafq", True, "FlAFq", 1.0, "%3.1f", "str"]
+ , ["tuafq", True, "TuAFq", 1.0, "%3.1f", "str"]
+ , ["rvafq", True, "RvAFq", 1.0, "%3.1f", "str"]
+ , ["pofafq", False, "PoFAFq", 1.0, "%3.1f", "str"]
+ , ["net", True, "Net($)", 1.0, "%6.2f", "cash"]
+ , ["bbper100", True, "bb/100", 1.0, "%4.2f", "str"]
+ , ["rake", True, "Rake($)", 1.0, "%6.2f", "cash"]
+ , ["bb100xr", True, "bbxr/100", 1.0, "%4.2f", "str"]
+ , ["variance", True, "Variance", 1.0, "%5.2f", "str"]
+ ]
+
+ # Detail filters: This holds the data used in the popup window, extra values are
+ # added at the end of these lists during processing
+ # sql test, screen description, min, max
+ self.handtests = [ # already in filter class : ['h.seats', 'Number of Players', 2, 10]
+ ['h.maxSeats', 'Size of Table', 2, 10]
+ ,['h.playersVpi', 'Players who VPI', 0, 10]
+ ,['h.playersAtStreet1', 'Players at Flop', 0, 10]
+ ,['h.playersAtStreet2', 'Players at Turn', 0, 10]
+ ,['h.playersAtStreet3', 'Players at River', 0, 10]
+ ,['h.playersAtStreet4', 'Players at Street7', 0, 10]
+ ,['h.playersAtShowdown', 'Players at Showdown', 0, 10]
+ ,['h.street0Raises', 'Bets to See Flop', 0, 5]
+ ,['h.street1Raises', 'Bets to See Turn', 0, 5]
+ ,['h.street2Raises', 'Bets to See River', 0, 5]
+ ,['h.street3Raises', 'Bets to See Street7', 0, 5]
+ ,['h.street4Raises', 'Bets to See Showdown', 0, 5]
+ ]
+
+ self.stats_frame = None
+ self.stats_vbox = None
+ self.detailFilters = [] # the data used to enhance the sql select
+
+ #self.main_hbox = gtk.HBox(False, 0)
+ #self.main_hbox.show()
+ self.main_hbox = gtk.HPaned()
+
+ self.stats_frame = gtk.Frame()
+ self.stats_frame.show()
+
+ self.stats_vbox = gtk.VPaned()
+ self.stats_vbox.show()
+ self.stats_frame.add(self.stats_vbox)
+ # self.fillStatsFrame(self.stats_vbox)
+
+ #self.main_hbox.pack_start(self.filters.get_vbox())
+ #self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True)
+ self.main_hbox.pack1(self.filters.get_vbox())
+ self.main_hbox.pack2(self.stats_frame)
+ self.main_hbox.show()
+
+ # make sure Hand column is not displayed
+ [x for x in self.columns if x[0] == 'hand'][0][1] = False
+ self.last_pos = -1
+
+
+ def get_vbox(self):
+ """returns the vbox of this thread"""
+ return self.main_hbox
+ #end def get_vbox
+
+ def refreshStats(self, widget, data):
+ self.last_pos = self.stats_vbox.get_position()
+ try: self.stats_vbox.destroy()
+ except AttributeError: pass
+ self.liststore = []
+ self.listcols = []
+ #self.stats_vbox = gtk.VBox(False, 0)
+ self.stats_vbox = gtk.VPaned()
+ self.stats_vbox.show()
+ self.stats_frame.add(self.stats_vbox)
+ self.fillStatsFrame(self.stats_vbox)
+ if self.last_pos > 0:
+ self.stats_vbox.set_position(self.last_pos)
+ #end def refreshStats
+
+ def fillStatsFrame(self, vbox):
+ sites = self.filters.getSites()
+ heroes = self.filters.getHeroes()
+ siteids = self.filters.getSiteIds()
+ limits = self.filters.getLimits()
+ type = self.filters.getType()
+ seats = self.filters.getSeats()
+ groups = self.filters.getGroups()
+ dates = self.filters.getDates()
+ games = self.filters.getGames()
+ sitenos = []
+ playerids = []
+
+ # Which sites are selected?
+ for site in sites:
+ if sites[site] == True:
+ sitenos.append(siteids[site])
+ _hname = Charset.to_utf8(heroes[site])
+ result = self.db.get_player_id(self.conf, site, _hname)
+ if result is not None:
+ playerids.append(int(result))
+
+ if not sitenos:
+ #Should probably pop up here.
+ print "No sites selected - defaulting to PokerStars"
+ sitenos = [2]
+ if not playerids:
+ print "No player ids found"
+ return
+ if not limits:
+ print "No limits found"
+ return
+
+ self.createStatsTable(vbox, playerids, sitenos, limits, type, seats, groups, dates, games)
+ #end def fillStatsFrame
+
+ def createStatsTable(self, vbox, playerids, sitenos, limits, type, seats, groups, dates, games):
+ startTime = time()
+ show_detail = True
+
+ # Scrolled window for summary table
+ swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
+ swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ swin.show()
+ vbox.pack1(swin)
+
+ # Display summary table at top of page
+ # 3rd parameter passes extra flags, currently includes:
+ # holecards - whether to display card breakdown (True/False)
+ # numhands - min number hands required when displaying all players
+ # gridnum - index for grid data structures
+ flags = [False, self.filters.getNumHands(), 0]
+ self.addGrid(swin, 'playerDetailedStats', flags, playerids
+ ,sitenos, limits, type, seats, groups, dates, games)
+
+ if 'allplayers' in groups and groups['allplayers']:
+ # can't currently do this combination so skip detailed table
+ show_detail = False
+
+ if show_detail:
+ # Separator
+ vbox2 = gtk.VBox(False, 0)
+ heading = gtk.Label(self.filterText['handhead'])
+ heading.show()
+ vbox2.pack_start(heading, expand=False, padding=3)
+
+ # Scrolled window for detailed table (display by hand)
+ swin = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
+ swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ swin.show()
+ vbox2.pack_start(swin, expand=True, padding=3)
+ vbox.pack2(vbox2)
+ vbox2.show()
+
+ # Detailed table
+ flags[0] = True
+ flags[2] = 1
+ self.addGrid(swin, 'playerDetailedStats', flags, playerids
+ ,sitenos, limits, type, seats, groups, dates, games)
+
+ self.db.rollback()
+ print "Stats page displayed in %4.2f seconds" % (time() - startTime)
+ #end def createStatsTable
+
+ def reset_style_render_func(self, treeviewcolumn, cell, model, iter):
+ cell.set_property('foreground', 'black')
+ #end def reset_style_render_func
+
+ def ledger_style_render_func(self, tvcol, cell, model, iter):
+ str = cell.get_property('text')
+ if '-' in str:
+ str = str.replace("-", "")
+ str = "(%s)" %(str)
+ cell.set_property('text', str)
+ cell.set_property('foreground', 'red')
+ else:
+ cell.set_property('foreground', 'darkgreen')
+
+ return
+
+ def sortnums(self, model, iter1, iter2, nums):
+ try:
+ ret = 0
+ (n, grid) = nums
+ a = self.liststore[grid].get_value(iter1, n)
+ b = self.liststore[grid].get_value(iter2, n)
+ if 'f' in self.cols_to_show[n][4]:
+ try: a = float(a)
+ except: a = 0.0
+ try: b = float(b)
+ except: b = 0.0
+ if n == 0 and grid == 1: #make sure it only works on the starting hands
+ a1,a2,a3 = ranks[a[0]], ranks[a[1]], (a+'o')[2]
+ b1,b2,b3 = ranks[b[0]], ranks[b[1]], (b+'o')[2]
+ if a1 > b1 or ( a1 == b1 and (a2 > b2 or (a2 == b2 and a3 > b3) ) ):
+ ret = 1
+ else:
+ ret = -1
+ else:
+ if a < b:
+ ret = -1
+ elif a == b:
+ ret = 0
+ else:
+ ret = 1
+ #print "n =", n, "iter1[n] =", self.liststore[grid].get_value(iter1,n), "iter2[n] =", self.liststore[grid].get_value(iter2,n), "ret =", ret
+ except:
+ err = traceback.extract_tb(sys.exc_info()[2])
+ print "***sortnums error: " + str(sys.exc_info()[1])
+ print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
+
+ return(ret)
+
+ def sortcols(self, col, nums):
+ try:
+ #This doesn't actually work yet - clicking heading in top section sorts bottom section :-(
+ (n, grid) = nums
+ if not col.get_sort_indicator() or col.get_sort_order() == gtk.SORT_ASCENDING:
+ col.set_sort_order(gtk.SORT_DESCENDING)
+ else:
+ col.set_sort_order(gtk.SORT_ASCENDING)
+ self.liststore[grid].set_sort_column_id(n, col.get_sort_order())
+ self.liststore[grid].set_sort_func(n, self.sortnums, (n,grid))
+ for i in xrange(len(self.listcols[grid])):
+ self.listcols[grid][i].set_sort_indicator(False)
+ self.listcols[grid][n].set_sort_indicator(True)
+ # use this listcols[col].set_sort_indicator(True)
+ # to turn indicator off for other cols
+ except:
+ err = traceback.extract_tb(sys.exc_info()[2])
+ print "***sortcols error: " + str(sys.exc_info()[1])
+ print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
+ #end def sortcols
+
+ def addGrid(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates, games):
+ counter = 0
+ row = 0
+ sqlrow = 0
+ if not flags: holecards,grid = False,0
+ else: holecards,grid = flags[0],flags[2]
+
+ tmp = self.sql.query[query]
+ tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, type, seats, groups, dates, games)
+ self.cursor.execute(tmp)
+ result = self.cursor.fetchall()
+ colnames = [desc[0].lower() for desc in self.cursor.description]
+
+ # pre-fetch some constant values:
+ self.cols_to_show = [x for x in self.columns if x[colshow]]
+ hgametypeid_idx = colnames.index('hgametypeid')
+
+ assert len(self.liststore) == grid, "len(self.liststore)="+str(len(self.liststore))+" grid-1="+str(grid)
+ self.liststore.append( gtk.ListStore(*([str] * len(self.cols_to_show))) )
+ view = gtk.TreeView(model=self.liststore[grid])
+ view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
+ #vbox.pack_start(view, expand=False, padding=3)
+ vbox.add(view)
+ textcell = gtk.CellRendererText()
+ textcell50 = gtk.CellRendererText()
+ textcell50.set_property('xalign', 0.5)
+ numcell = gtk.CellRendererText()
+ numcell.set_property('xalign', 1.0)
+ assert len(self.listcols) == grid
+ self.listcols.append( [] )
+
+ # Create header row eg column: ("game", True, "Game", 0.0, "%s")
+ for col, column in enumerate(self.cols_to_show):
+ if column[colalias] == 'game' and holecards:
+ s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading]
+ else:
+ s = column[colheading]
+ self.listcols[grid].append(gtk.TreeViewColumn(s))
+ view.append_column(self.listcols[grid][col])
+ if column[colformat] == '%s':
+ if column[colxalign] == 0.0:
+ self.listcols[grid][col].pack_start(textcell, expand=True)
+ self.listcols[grid][col].add_attribute(textcell, 'text', col)
+ cellrend = textcell
+ else:
+ self.listcols[grid][col].pack_start(textcell50, expand=True)
+ self.listcols[grid][col].add_attribute(textcell50, 'text', col)
+ cellrend = textcell50
+ self.listcols[grid][col].set_expand(True)
+ else:
+ self.listcols[grid][col].pack_start(numcell, expand=True)
+ self.listcols[grid][col].add_attribute(numcell, 'text', col)
+ self.listcols[grid][col].set_expand(True)
+ cellrend = numcell
+ #self.listcols[grid][col].set_alignment(column[colxalign]) # no effect?
+ self.listcols[grid][col].set_clickable(True)
+ self.listcols[grid][col].connect("clicked", self.sortcols, (col,grid))
+ if col == 0:
+ self.listcols[grid][col].set_sort_order(gtk.SORT_DESCENDING)
+ self.listcols[grid][col].set_sort_indicator(True)
+ if column[coltype] == 'cash':
+ self.listcols[grid][col].set_cell_data_func(numcell, self.ledger_style_render_func)
+ else:
+ self.listcols[grid][col].set_cell_data_func(cellrend, self.reset_style_render_func)
+
+ rows = len(result) # +1 for title row
+
+ while sqlrow < rows:
+ treerow = []
+ for col,column in enumerate(self.cols_to_show):
+ if column[colalias] in colnames:
+ value = result[sqlrow][colnames.index(column[colalias])]
+ if column[colalias] == 'plposition':
+ if value == 'B':
+ value = 'BB'
+ elif value == 'S':
+ value = 'SB'
+ elif value == '0':
+ value = 'Btn'
+ else:
+ if column[colalias] == 'game':
+ if holecards:
+ value = Card.twoStartCardString( result[sqlrow][hgametypeid_idx] )
+ else:
+ minbb = result[sqlrow][colnames.index('minbigblind')]
+ maxbb = result[sqlrow][colnames.index('maxbigblind')]
+ value = result[sqlrow][colnames.index('limittype')] + ' ' \
+ + result[sqlrow][colnames.index('category')].title() + ' ' \
+ + result[sqlrow][colnames.index('name')] + ' $'
+ if 100 * int(minbb/100.0) != minbb:
+ value += '%.2f' % (minbb/100.0)
+ else:
+ value += '%.0f' % (minbb/100.0)
+ if minbb != maxbb:
+ if 100 * int(maxbb/100.0) != maxbb:
+ value += ' - $' + '%.2f' % (maxbb/100.0)
+ else:
+ value += ' - $' + '%.0f' % (maxbb/100.0)
+ else:
+ continue
+ if value and value != -999:
+ treerow.append(column[colformat] % value)
+ else:
+ treerow.append(' ')
+ iter = self.liststore[grid].append(treerow)
+ #print treerow
+ sqlrow += 1
+ row += 1
+ vbox.show_all()
+ #end def addGrid
+
+ def refineQuery(self, query, flags, playerids, sitenos, limits, type, seats, groups, dates, games):
+ having = ''
+ if not flags:
+ holecards = False
+ numhands = 0
+ else:
+ holecards = flags[0]
+ numhands = flags[1]
+
+ if 'allplayers' in groups and groups['allplayers']:
+ nametest = "(hp.playerId)"
+ if holecards or groups['posn']:
+ pname = "'all players'"
+ # set flag in self.columns to not show player name column
+ [x for x in self.columns if x[0] == 'pname'][0][1] = False
+ # can't do this yet (re-write doing more maths in python instead of sql?)
+ if numhands:
+ nametest = "(-1)"
+ else:
+ pname = "p.name"
+ # set flag in self.columns to show player name column
+ [x for x in self.columns if x[0] == 'pname'][0][1] = True
+ if numhands:
+ having = ' and count(1) > %d ' % (numhands,)
+ else:
+ if playerids:
+ nametest = str(tuple(playerids))
+ nametest = nametest.replace("L", "")
+ nametest = nametest.replace(",)",")")
+ else:
+ nametest = "1 = 2"
+ pname = "p.name"
+ # set flag in self.columns to not show player name column
+ [x for x in self.columns if x[0] == 'pname'][0][1] = False
+ query = query.replace("", nametest)
+ query = query.replace("", pname)
+ query = query.replace("", having)
+
+ gametest = ""
+ q = []
+ for m in self.filters.display.items():
+ if m[0] == 'Games' and m[1]:
+ for n in games:
+ if games[n]:
+ q.append(n)
+ if len(q) > 0:
+ gametest = str(tuple(q))
+ gametest = gametest.replace("L", "")
+ gametest = gametest.replace(",)",")")
+ gametest = gametest.replace("u'","'")
+ gametest = "and gt.category in %s" % gametest
+ else:
+ gametest = "and gt.category IS NULL"
+ query = query.replace("", gametest)
+
+ sitetest = ""
+ q = []
+ for m in self.filters.display.items():
+ if m[0] == 'Sites' and m[1]:
+ for n in sitenos:
+ q.append(n)
+ if len(q) > 0:
+ sitetest = str(tuple(q))
+ sitetest = sitetest.replace("L", "")
+ sitetest = sitetest.replace(",)",")")
+ sitetest = sitetest.replace("u'","'")
+ sitetest = "and gt.siteId in %s" % sitetest
+ else:
+ sitetest = "and gt.siteId IS NULL"
+ query = query.replace("", sitetest)
+
+ if seats:
+ query = query.replace('', 'between ' + str(seats['from']) + ' and ' + str(seats['to']))
+ if 'show' in seats and seats['show']:
+ query = query.replace('', ',h.seats')
+ query = query.replace('', ',h.seats')
+ else:
+ query = query.replace('', '')
+ query = query.replace('', '')
+ else:
+ query = query.replace('', 'between 0 and 100')
+ query = query.replace('', '')
+ query = query.replace('', '')
+
+ lims = [int(x) for x in limits if x.isdigit()]
+ potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl']
+ nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
+ bbtest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
+ # and ( (limit and bb in()) or (nolimit and bb in ()) )
+ if lims:
+ blindtest = str(tuple(lims))
+ blindtest = blindtest.replace("L", "")
+ blindtest = blindtest.replace(",)",")")
+ bbtest = bbtest + blindtest + ' ) '
+ else:
+ bbtest = bbtest + '(-1) ) '
+ bbtest = bbtest + " or (gt.limitType = 'pl' and gt.bigBlind in "
+ if potlims:
+ blindtest = str(tuple(potlims))
+ blindtest = blindtest.replace("L", "")
+ blindtest = blindtest.replace(",)",")")
+ bbtest = bbtest + blindtest + ' ) '
+ else:
+ bbtest = bbtest + '(-1) ) '
+ bbtest = bbtest + " or (gt.limitType = 'nl' and gt.bigBlind in "
+ if nolims:
+ blindtest = str(tuple(nolims))
+ blindtest = blindtest.replace("L", "")
+ blindtest = blindtest.replace(",)",")")
+ bbtest = bbtest + blindtest + ' ) )'
+ else:
+ bbtest = bbtest + '(-1) ) )'
+ if type == 'ring':
+ bbtest = bbtest + " and gt.type = 'ring' "
+ elif type == 'tour':
+ bbtest = " and gt.type = 'tour' "
+ query = query.replace("", bbtest)
+
+ if holecards: # re-use level variables for hole card query
+ query = query.replace("", "hp.startcards")
+ query = query.replace(""
+ , ",case when floor((hp.startcards-1)/13) >= mod((hp.startcards-1),13) then hp.startcards + 0.1 "
+ + " else 13*mod((hp.startcards-1),13) + floor((hp.startcards-1)/13) + 1 "
+ + " end desc ")
+ else:
+ query = query.replace("", "")
+ groupLevels = "show" not in str(limits)
+ if groupLevels:
+ query = query.replace("", "p.name") # need to use p.name for sqlite posn stats to work
+ else:
+ query = query.replace("", "h.gameTypeId")
+
+ # process self.detailFilters (a list of tuples)
+ flagtest = ''
+ #self.detailFilters = [('h.seats', 5, 6)] # for debug
+ if self.detailFilters:
+ for f in self.detailFilters:
+ if len(f) == 3:
+ # X between Y and Z
+ flagtest += ' and %s between %s and %s ' % (f[0], str(f[1]), str(f[2]))
+ query = query.replace("", flagtest)
+
+ # allow for differences in sql cast() function:
+ if self.db.backend == self.MYSQL_INNODB:
+ query = query.replace("", 'signed ')
+ else:
+ query = query.replace("", '')
+
+ # Filter on dates
+ query = query.replace("", " between '" + dates[0] + "' and '" + dates[1] + "'")
+
+ # Group by position?
+ if groups['posn']:
+ #query = query.replace("", "case hp.position when '0' then 'Btn' else hp.position end")
+ query = query.replace("", "hp.position")
+ # set flag in self.columns to show posn column
+ [x for x in self.columns if x[0] == 'plposition'][0][1] = True
+ else:
+ query = query.replace("", "gt.base")
+ # unset flag in self.columns to hide posn column
+ [x for x in self.columns if x[0] == 'plposition'][0][1] = False
+
+ #print "query =\n", query
+ return(query)
+ #end def refineQuery
+
+ def showDetailFilter(self, widget, data):
+ detailDialog = gtk.Dialog(title="Detailed Filters", parent=self.main_window
+ ,flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
+ ,buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
+ gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+
+ handbox = gtk.VBox(True, 0)
+ detailDialog.vbox.pack_start(handbox, False, False, 0)
+ handbox.show()
+
+ label = gtk.Label("Hand Filters:")
+ handbox.add(label)
+ label.show()
+
+ betweenFilters = []
+ for htest in self.handtests:
+ hbox = gtk.HBox(False, 0)
+ handbox.pack_start(hbox, False, False, 0)
+ hbox.show()
+
+ cb = gtk.CheckButton()
+ lbl_from = gtk.Label(htest[1])
+ lbl_from.set_alignment(xalign=0.0, yalign=0.5)
+ lbl_tween = gtk.Label('between')
+ lbl_to = gtk.Label('and')
+ adj1 = gtk.Adjustment(value=htest[2], lower=0, upper=10, step_incr=1, page_incr=1, page_size=0)
+ sb1 = gtk.SpinButton(adjustment=adj1, climb_rate=0.0, digits=0)
+ adj2 = gtk.Adjustment(value=htest[3], lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
+ sb2 = gtk.SpinButton(adjustment=adj2, climb_rate=0.0, digits=0)
+
+ for df in [x for x in self.detailFilters if x[0] == htest[0]]:
+ cb.set_active(True)
+
+ hbox.pack_start(cb, expand=False, padding=3)
+ hbox.pack_start(lbl_from, expand=True, padding=3)
+ hbox.pack_start(lbl_tween, expand=False, padding=3)
+ hbox.pack_start(sb1, False, False, 0)
+ hbox.pack_start(lbl_to, expand=False, padding=3)
+ hbox.pack_start(sb2, False, False, 0)
+
+ cb.show()
+ lbl_from.show()
+ lbl_tween.show()
+ sb1.show()
+ lbl_to.show()
+ sb2.show()
+
+ htest[4:7] = [cb,sb1,sb2]
+
+ response = detailDialog.run()
+
+ if response == gtk.RESPONSE_ACCEPT:
+ self.detailFilters = []
+ for ht in self.handtests:
+ if ht[4].get_active():
+ self.detailFilters.append( (ht[0], ht[5].get_value_as_int(), ht[6].get_value_as_int()) )
+ ht[2],ht[3] = ht[5].get_value_as_int(), ht[6].get_value_as_int()
+ print "detailFilters =", self.detailFilters
+ self.refreshStats(None, None)
+
+ detailDialog.destroy()
+
+
+
+
-class GuiRingPlayerStats (GuiPlayerStats.GuiPlayerStats):
- pass
-#end class GuiRingPlayerStats
\ No newline at end of file
diff --git a/pyfpdb/GuiSessionViewer.py b/pyfpdb/GuiSessionViewer.py
index 05249051..38cd7b74 100755
--- a/pyfpdb/GuiSessionViewer.py
+++ b/pyfpdb/GuiSessionViewer.py
@@ -45,7 +45,7 @@ except ImportError, inst:
import Card
import fpdb_import
import Database
-import Filters
+import RingFilters
import FpdbSQLQueries
import Charset
@@ -96,7 +96,7 @@ class GuiSessionViewer (threading.Thread):
"Button2" : False
}
- self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
+ self.filters = RingFilters.RingFilters(self.db, self.conf, self.sql, display = filters_display)
self.filters.registerButton1Name("_Refresh")
self.filters.registerButton1Callback(self.refreshStats)
diff --git a/pyfpdb/RingFilters.py b/pyfpdb/RingFilters.py
index 4780b131..44fc790a 100644
--- a/pyfpdb/RingFilters.py
+++ b/pyfpdb/RingFilters.py
@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-#Copyright 2010 Steffen Schaumburg
+#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.
@@ -15,28 +15,934 @@
#along with this program. If not, see .
#In the "official" distribution you can find the license in agpl-3.0.txt.
-#import threading
-#import pygtk
-#pygtk.require('2.0')
-#import gtk
-#import os
-#import sys
-#from optparse import OptionParser
-#from time import *
-#import gobject
+import threading
+import pygtk
+pygtk.require('2.0')
+import gtk
+import os
+import sys
+from optparse import OptionParser
+from time import *
+import gobject
#import pokereval
-#import logging
+import logging
# logging has been set up in fpdb.py or HUD_main.py, use their settings:
-#log = logging.getLogger("filter")
+log = logging.getLogger("filter")
-#import Configuration
-#import Database
-#import SQL
-#import Charset
-import Filters
+import Configuration
+import Database
+import SQL
+import Charset
-class RingFilters(Filters.Filters):
- pass
-#end class RingFilters
\ No newline at end of file
+
+class RingFilters(threading.Thread):
+ def __init__(self, db, config, qdict, display = {}, debug=True):
+ # config and qdict are now redundant
+ self.debug = debug
+ self.db = db
+ self.cursor = db.cursor
+ self.sql = db.sql
+ self.conf = db.config
+ self.display = display
+
+ # text used on screen stored here so that it can be configured
+ self.filterText = {'limitsall':'All', 'limitsnone':'None', 'limitsshow':'Show _Limits'
+ ,'seatsbetween':'Between:', 'seatsand':'And:', 'seatsshow':'Show Number of _Players'
+ ,'playerstitle':'Hero:', 'sitestitle':'Sites:', 'gamestitle':'Games:'
+ ,'limitstitle':'Limits:', 'seatstitle':'Number of Players:'
+ ,'groupstitle':'Grouping:', 'posnshow':'Show Position Stats:'
+ ,'datestitle':'Date:'
+ ,'groupsall':'All Players'
+ ,'limitsFL':'FL', 'limitsNL':'NL', 'limitsPL':'PL', 'ring':'Ring', 'tour':'Tourney'
+ }
+
+ gen = self.conf.get_general_params()
+ self.day_start = 0
+ if 'day_start' in gen:
+ self.day_start = float(gen['day_start'])
+
+ # Outer Packing box
+ self.mainVBox = gtk.VBox(False, 0)
+
+ self.label = {}
+ self.callback = {}
+
+ self.make_filter()
+
+ def make_filter(self):
+ self.sites = {}
+ self.games = {}
+ self.limits = {}
+ self.seats = {}
+ self.groups = {}
+ self.siteid = {}
+ self.heroes = {}
+ self.boxes = {}
+
+ for site in self.conf.get_supported_sites():
+ #Get db site id for filtering later
+ self.cursor.execute(self.sql.query['getSiteId'], (site,))
+ result = self.db.cursor.fetchall()
+ if len(result) == 1:
+ self.siteid[site] = result[0][0]
+ else:
+ print "Either 0 or more than one site matched (%s) - EEK" % site
+
+ # For use in date ranges.
+ self.start_date = gtk.Entry(max=12)
+ self.end_date = gtk.Entry(max=12)
+ self.start_date.set_property('editable', False)
+ self.end_date.set_property('editable', False)
+
+ # For use in groups etc
+ self.sbGroups = {}
+ self.numHands = 0
+
+ playerFrame = gtk.Frame()
+ playerFrame.set_label_align(0.0, 0.0)
+ vbox = gtk.VBox(False, 0)
+
+ self.fillPlayerFrame(vbox, self.display)
+ playerFrame.add(vbox)
+
+ sitesFrame = gtk.Frame()
+ sitesFrame.set_label_align(0.0, 0.0)
+ vbox = gtk.VBox(False, 0)
+
+ self.fillSitesFrame(vbox)
+ sitesFrame.add(vbox)
+
+ # Game types
+ gamesFrame = gtk.Frame()
+ gamesFrame.set_label_align(0.0, 0.0)
+ gamesFrame.show()
+ vbox = gtk.VBox(False, 0)
+
+ self.fillGamesFrame(vbox)
+ gamesFrame.add(vbox)
+
+ # Limits
+ limitsFrame = gtk.Frame()
+ limitsFrame.show()
+ vbox = gtk.VBox(False, 0)
+ self.cbLimits = {}
+ self.cbNoLimits = None
+ self.cbAllLimits = None
+ self.cbFL = None
+ self.cbNL = None
+ self.cbPL = None
+ self.rb = {} # radio buttons for ring/tour
+ self.type = None # ring/tour
+ self.types = {} # list of all ring/tour values
+
+ self.fillLimitsFrame(vbox, self.display)
+ limitsFrame.add(vbox)
+
+ # Seats
+ seatsFrame = gtk.Frame()
+ seatsFrame.show()
+ vbox = gtk.VBox(False, 0)
+ self.sbSeats = {}
+
+ self.fillSeatsFrame(vbox, self.display)
+ seatsFrame.add(vbox)
+
+ # Groups
+ groupsFrame = gtk.Frame()
+ groupsFrame.show()
+ vbox = gtk.VBox(False, 0)
+
+ self.fillGroupsFrame(vbox, self.display)
+ groupsFrame.add(vbox)
+
+ # Date
+ dateFrame = gtk.Frame()
+ dateFrame.set_label_align(0.0, 0.0)
+ dateFrame.show()
+ vbox = gtk.VBox(False, 0)
+
+ self.fillDateFrame(vbox)
+ dateFrame.add(vbox)
+
+ # Buttons
+ self.Button1=gtk.Button("Unnamed 1")
+ self.Button1.set_sensitive(False)
+
+ self.Button2=gtk.Button("Unnamed 2")
+ self.Button2.set_sensitive(False)
+
+ self.mainVBox.add(playerFrame)
+ self.mainVBox.add(sitesFrame)
+ self.mainVBox.add(gamesFrame)
+ self.mainVBox.add(limitsFrame)
+ self.mainVBox.add(seatsFrame)
+ self.mainVBox.add(groupsFrame)
+ self.mainVBox.add(dateFrame)
+ self.mainVBox.add(self.Button1)
+ self.mainVBox.add(self.Button2)
+
+ self.mainVBox.show_all()
+
+ # Should do this cleaner
+ if "Heroes" not in self.display or self.display["Heroes"] == False:
+ playerFrame.hide()
+ if "Sites" not in self.display or self.display["Sites"] == False:
+ sitesFrame.hide()
+ if "Games" not in self.display or self.display["Games"] == False:
+ gamesFrame.hide()
+ if "Limits" not in self.display or self.display["Limits"] == False:
+ limitsFrame.hide()
+ if "Seats" not in self.display or self.display["Seats"] == False:
+ seatsFrame.hide()
+ if "Groups" not in self.display or self.display["Groups"] == False:
+ groupsFrame.hide()
+ if "Dates" not in self.display or self.display["Dates"] == False:
+ dateFrame.hide()
+ if "Button1" not in self.display or self.display["Button1"] == False:
+ self.Button1.hide()
+ if "Button2" not in self.display or self.display["Button2"] == False:
+ self.Button2.hide()
+
+ if 'button1' in self.label and self.label['button1']:
+ self.Button1.set_label( self.label['button1'] )
+ if 'button2' in self.label and self.label['button2']:
+ self.Button2.set_label( self.label['button2'] )
+ if 'button1' in self.callback and self.callback['button1']:
+ self.Button1.connect("clicked", self.callback['button1'], "clicked")
+ self.Button1.set_sensitive(True)
+ if 'button2' in self.callback and self.callback['button2']:
+ self.Button2.connect("clicked", self.callback['button2'], "clicked")
+ self.Button2.set_sensitive(True)
+
+ # make sure any locks on db are released:
+ self.db.rollback()
+
+ def get_vbox(self):
+ """returns the vbox of this thread"""
+ return self.mainVBox
+ #end def get_vbox
+
+ def getNumHands(self):
+ return self.numHands
+ #end def getNumHands
+
+ def getSites(self):
+ return self.sites
+ #end def getSites
+
+ def getGames(self):
+ return self.games
+
+ def getSiteIds(self):
+ return self.siteid
+ #end def getSiteIds
+
+ def getHeroes(self):
+ return self.heroes
+ #end def getHeroes
+
+ def getLimits(self):
+ ltuple = []
+ for l in self.limits:
+ if self.limits[l] == True:
+ ltuple.append(l)
+ return ltuple
+
+ def getType(self):
+ return(self.type)
+
+ def getSeats(self):
+ if 'from' in self.sbSeats:
+ self.seats['from'] = self.sbSeats['from'].get_value_as_int()
+ if 'to' in self.sbSeats:
+ self.seats['to'] = self.sbSeats['to'].get_value_as_int()
+ return self.seats
+ #end def getSeats
+
+ def getGroups(self):
+ return self.groups
+
+ def getDates(self):
+ return self.__get_dates()
+ #end def getDates
+
+ def registerButton1Name(self, title):
+ self.Button1.set_label(title)
+ self.label['button1'] = title
+
+ def registerButton1Callback(self, callback):
+ self.Button1.connect("clicked", callback, "clicked")
+ self.Button1.set_sensitive(True)
+ self.callback['button1'] = callback
+
+ def registerButton2Name(self, title):
+ self.Button2.set_label(title)
+ self.label['button2'] = title
+ #end def registerButton2Name
+
+ def registerButton2Callback(self, callback):
+ self.Button2.connect("clicked", callback, "clicked")
+ self.Button2.set_sensitive(True)
+ self.callback['button2'] = callback
+ #end def registerButton2Callback
+
+ def cardCallback(self, widget, data=None):
+ log.debug( "%s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()]) )
+
+ def createPlayerLine(self, hbox, site, player):
+ log.debug('add:"%s"' % player)
+ label = gtk.Label(site +" id:")
+ hbox.pack_start(label, False, False, 3)
+
+ pname = gtk.Entry()
+ pname.set_text(player)
+ pname.set_width_chars(20)
+ hbox.pack_start(pname, False, True, 0)
+ pname.connect("changed", self.__set_hero_name, site)
+
+ # Added EntryCompletion but maybe comboBoxEntry is more flexible? (e.g. multiple choices)
+ completion = gtk.EntryCompletion()
+ pname.set_completion(completion)
+ liststore = gtk.ListStore(gobject.TYPE_STRING)
+ completion.set_model(liststore)
+ completion.set_text_column(0)
+ names = self.db.get_player_names(self.conf, self.siteid[site]) # (config=self.conf, site_id=None, like_player_name="%")
+ for n in names: # list of single-element "tuples"
+ _n = Charset.to_gui(n[0])
+ _nt = (_n, )
+ liststore.append(_nt)
+
+ self.__set_hero_name(pname, site)
+
+ def __set_hero_name(self, w, site):
+ _name = w.get_text()
+ # get_text() returns a str but we want internal variables to be unicode:
+ _guiname = unicode(_name)
+ self.heroes[site] = _guiname
+ #log.debug("setting heroes[%s]: %s"%(site, self.heroes[site]))
+ #end def __set_hero_name
+
+ def __set_num_hands(self, w, val):
+ try:
+ self.numHands = int(w.get_text())
+ except:
+ self.numHands = 0
+ #log.debug("setting numHands:", self.numHands)
+ #end def __set_num_hands
+
+ def createSiteLine(self, hbox, site):
+ cb = gtk.CheckButton(site)
+ cb.connect('clicked', self.__set_site_select, site)
+ cb.set_active(True)
+ hbox.pack_start(cb, False, False, 0)
+
+ def createGameLine(self, hbox, game):
+ cb = gtk.CheckButton(game)
+ cb.connect('clicked', self.__set_game_select, game)
+ hbox.pack_start(cb, False, False, 0)
+ cb.set_active(True)
+
+ def createLimitLine(self, hbox, limit, ltext):
+ cb = gtk.CheckButton(str(ltext))
+ cb.connect('clicked', self.__set_limit_select, limit)
+ hbox.pack_start(cb, False, False, 0)
+ if limit != "none":
+ cb.set_active(True)
+ return(cb)
+
+ def __set_site_select(self, w, site):
+ #print w.get_active()
+ self.sites[site] = w.get_active()
+ log.debug("self.sites[%s] set to %s" %(site, self.sites[site]))
+
+ def __set_game_select(self, w, game):
+ #print w.get_active()
+ self.games[game] = w.get_active()
+ log.debug("self.games[%s] set to %s" %(game, self.games[game]))
+ #end def __set_game_select
+
+ def __set_limit_select(self, w, limit):
+ #print w.get_active()
+ self.limits[limit] = w.get_active()
+ log.debug("self.limit[%s] set to %s" %(limit, self.limits[limit]))
+ if limit.isdigit() or (len(limit) > 2 and (limit[-2:] == 'nl' or limit[-2:] == 'fl' or limit[-2:] == 'pl')):
+ if self.limits[limit]:
+ if self.cbNoLimits is not None:
+ self.cbNoLimits.set_active(False)
+ else:
+ if self.cbAllLimits is not None:
+ self.cbAllLimits.set_active(False)
+ if not self.limits[limit]:
+ if limit.isdigit():
+ if self.cbFL is not None:
+ self.cbFL.set_active(False)
+ elif (len(limit) > 2 and (limit[-2:] == 'nl')):
+ if self.cbNL is not None:
+ self.cbNL.set_active(False)
+ else:
+ if self.cbPL is not None:
+ self.cbPL.set_active(False)
+ elif limit == "all":
+ if self.limits[limit]:
+ #for cb in self.cbLimits.values():
+ # cb.set_active(True)
+ if self.cbFL is not None:
+ self.cbFL.set_active(True)
+ if self.cbNL is not None:
+ self.cbNL.set_active(True)
+ if self.cbPL is not None:
+ self.cbPL.set_active(True)
+ elif limit == "none":
+ if self.limits[limit]:
+ for cb in self.cbLimits.values():
+ cb.set_active(False)
+ if self.cbNL is not None:
+ self.cbNL.set_active(False)
+ if self.cbFL is not None:
+ self.cbFL.set_active(False)
+ if self.cbPL is not None:
+ self.cbPL.set_active(False)
+ elif limit == "fl":
+ if not self.limits[limit]:
+ # only toggle all fl limits off if they are all currently on
+ # this stops turning one off from cascading into 'fl' box off
+ # and then all fl limits being turned off
+ all_fl_on = True
+ for cb in self.cbLimits.values():
+ t = cb.get_children()[0].get_text()
+ if t.isdigit():
+ if not cb.get_active():
+ all_fl_on = False
+ found = {'ring':False, 'tour':False}
+ for cb in self.cbLimits.values():
+ #print "cb label: ", cb.children()[0].get_text()
+ t = cb.get_children()[0].get_text()
+ if t.isdigit():
+ if self.limits[limit] or all_fl_on:
+ cb.set_active(self.limits[limit])
+ found[self.types[t]] = True
+ if self.limits[limit]:
+ if not found[self.type]:
+ if self.type == 'ring':
+ if 'tour' in self.rb:
+ self.rb['tour'].set_active(True)
+ elif self.type == 'tour':
+ if 'ring' in self.rb:
+ self.rb['ring'].set_active(True)
+ elif limit == "nl":
+ if not self.limits[limit]:
+ # only toggle all nl limits off if they are all currently on
+ # this stops turning one off from cascading into 'nl' box off
+ # and then all nl limits being turned off
+ all_nl_on = True
+ for cb in self.cbLimits.values():
+ t = cb.get_children()[0].get_text()
+ if "nl" in t and len(t) > 2:
+ if not cb.get_active():
+ all_nl_on = False
+ found = {'ring':False, 'tour':False}
+ for cb in self.cbLimits.values():
+ t = cb.get_children()[0].get_text()
+ if "nl" in t and len(t) > 2:
+ if self.limits[limit] or all_nl_on:
+ cb.set_active(self.limits[limit])
+ found[self.types[t]] = True
+ if self.limits[limit]:
+ if not found[self.type]:
+ if self.type == 'ring':
+ if 'tour' in self.rb:
+ self.rb['tour'].set_active(True)
+ elif self.type == 'tour':
+ if 'ring' in self.rb:
+ self.rb['ring'].set_active(True)
+ elif limit == "pl":
+ if not self.limits[limit]:
+ # only toggle all nl limits off if they are all currently on
+ # this stops turning one off from cascading into 'nl' box off
+ # and then all nl limits being turned off
+ all_nl_on = True
+ for cb in self.cbLimits.values():
+ t = cb.get_children()[0].get_text()
+ if "pl" in t and len(t) > 2:
+ if not cb.get_active():
+ all_nl_on = False
+ found = {'ring':False, 'tour':False}
+ for cb in self.cbLimits.values():
+ t = cb.get_children()[0].get_text()
+ if "pl" in t and len(t) > 2:
+ if self.limits[limit] or all_nl_on:
+ cb.set_active(self.limits[limit])
+ found[self.types[t]] = True
+ if self.limits[limit]:
+ if not found[self.type]:
+ if self.type == 'ring':
+ if 'tour' in self.rb:
+ self.rb['tour'].set_active(True)
+ elif self.type == 'tour':
+ if 'ring' in self.rb:
+ self.rb['ring'].set_active(True)
+ elif limit == "ring":
+ log.debug("set", limit, "to", self.limits[limit])
+ if self.limits[limit]:
+ self.type = "ring"
+ for cb in self.cbLimits.values():
+ #print "cb label: ", cb.children()[0].get_text()
+ if self.types[cb.get_children()[0].get_text()] == 'tour':
+ cb.set_active(False)
+ elif limit == "tour":
+ log.debug( "set", limit, "to", self.limits[limit] )
+ if self.limits[limit]:
+ self.type = "tour"
+ for cb in self.cbLimits.values():
+ #print "cb label: ", cb.children()[0].get_text()
+ if self.types[cb.get_children()[0].get_text()] == 'ring':
+ cb.set_active(False)
+
+ def __set_seat_select(self, w, seat):
+ #print "__set_seat_select: seat =", seat, "active =", w.get_active()
+ self.seats[seat] = w.get_active()
+ log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) )
+
+ def __set_group_select(self, w, group):
+ #print "__set_seat_select: seat =", seat, "active =", w.get_active()
+ self.groups[group] = w.get_active()
+ log.debug( "self.groups[%s] set to %s" %(group, self.groups[group]) )
+
+ def fillPlayerFrame(self, vbox, display):
+ top_hbox = gtk.HBox(False, 0)
+ vbox.pack_start(top_hbox, False, False, 0)
+ lbl_title = gtk.Label(self.filterText['playerstitle'])
+ lbl_title.set_alignment(xalign=0.0, yalign=0.5)
+ top_hbox.pack_start(lbl_title, expand=True, padding=3)
+ showb = gtk.Button(label="refresh", stock=None, use_underline=True)
+ showb.set_alignment(xalign=1.0, yalign=0.5)
+ showb.connect('clicked', self.__refresh, 'players')
+
+ vbox1 = gtk.VBox(False, 0)
+ vbox.pack_start(vbox1, False, False, 0)
+ self.boxes['players'] = vbox1
+
+ for site in self.conf.get_supported_sites():
+ hBox = gtk.HBox(False, 0)
+ vbox1.pack_start(hBox, False, True, 0)
+
+ player = self.conf.supported_sites[site].screen_name
+ _pname = Charset.to_gui(player)
+ self.createPlayerLine(hBox, site, _pname)
+
+ if "GroupsAll" in display and display["GroupsAll"] == True:
+ hbox = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox, False, False, 0)
+ cb = gtk.CheckButton(self.filterText['groupsall'])
+ cb.connect('clicked', self.__set_group_select, 'allplayers')
+ hbox.pack_start(cb, False, False, 0)
+ self.sbGroups['allplayers'] = cb
+ self.groups['allplayers'] = False
+
+ lbl = gtk.Label('Min # Hands:')
+ lbl.set_alignment(xalign=1.0, yalign=0.5)
+ hbox.pack_start(lbl, expand=True, padding=3)
+
+ phands = gtk.Entry()
+ phands.set_text('0')
+ phands.set_width_chars(8)
+ hbox.pack_start(phands, False, False, 0)
+ phands.connect("changed", self.__set_num_hands, site)
+ top_hbox.pack_start(showb, expand=False, padding=1)
+
+ def fillSitesFrame(self, vbox):
+ top_hbox = gtk.HBox(False, 0)
+ top_hbox.show()
+ vbox.pack_start(top_hbox, False, False, 0)
+
+ lbl_title = gtk.Label(self.filterText['sitestitle'])
+ lbl_title.set_alignment(xalign=0.0, yalign=0.5)
+ top_hbox.pack_start(lbl_title, expand=True, padding=3)
+
+ showb = gtk.Button(label="hide", stock=None, use_underline=True)
+ showb.set_alignment(xalign=1.0, yalign=0.5)
+ showb.connect('clicked', self.__toggle_box, 'sites')
+ showb.show()
+ top_hbox.pack_start(showb, expand=False, padding=1)
+
+ vbox1 = gtk.VBox(False, 0)
+ self.boxes['sites'] = vbox1
+ vbox.pack_start(vbox1, False, False, 0)
+
+ for site in self.conf.get_supported_sites():
+ hbox = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox, False, True, 0)
+ self.createSiteLine(hbox, site)
+ #Get db site id for filtering later
+ #self.cursor.execute(self.sql.query['getSiteId'], (site,))
+ #result = self.db.cursor.fetchall()
+ #if len(result) == 1:
+ # self.siteid[site] = result[0][0]
+ #else:
+ # print "Either 0 or more than one site matched - EEK"
+
+ def fillGamesFrame(self, vbox):
+ top_hbox = gtk.HBox(False, 0)
+ vbox.pack_start(top_hbox, False, False, 0)
+ lbl_title = gtk.Label(self.filterText['gamestitle'])
+ lbl_title.set_alignment(xalign=0.0, yalign=0.5)
+ top_hbox.pack_start(lbl_title, expand=True, padding=3)
+ showb = gtk.Button(label="hide", stock=None, use_underline=True)
+ showb.set_alignment(xalign=1.0, yalign=0.5)
+ showb.connect('clicked', self.__toggle_box, 'games')
+ top_hbox.pack_start(showb, expand=False, padding=1)
+
+ vbox1 = gtk.VBox(False, 0)
+ vbox.pack_start(vbox1, False, False, 0)
+ self.boxes['games'] = vbox1
+
+ self.cursor.execute(self.sql.query['getGames'])
+ result = self.db.cursor.fetchall()
+ if len(result) >= 1:
+ for line in result:
+ hbox = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox, False, True, 0)
+ self.createGameLine(hbox, line[0])
+ else:
+ print "INFO: No games returned from database"
+ log.info("No games returned from database")
+ #end def fillGamesFrame
+
+ def fillLimitsFrame(self, vbox, display):
+ top_hbox = gtk.HBox(False, 0)
+ vbox.pack_start(top_hbox, False, False, 0)
+ lbl_title = gtk.Label(self.filterText['limitstitle'])
+ lbl_title.set_alignment(xalign=0.0, yalign=0.5)
+ top_hbox.pack_start(lbl_title, expand=True, padding=3)
+ showb = gtk.Button(label="hide", stock=None, use_underline=True)
+ showb.set_alignment(xalign=1.0, yalign=0.5)
+ showb.connect('clicked', self.__toggle_box, 'limits')
+
+ vbox1 = gtk.VBox(False, 0)
+ vbox.pack_start(vbox1, False, False, 0)
+ self.boxes['limits'] = vbox1
+
+ self.cursor.execute(self.sql.query['getLimits3'])
+ # selects limitType, bigBlind
+ result = self.db.cursor.fetchall()
+ found = {'nl':False, 'fl':False, 'pl':False, 'ring':False, 'tour':False}
+
+ if len(result) >= 1:
+ hbox = gtk.HBox(True, 0)
+ vbox1.pack_start(hbox, False, False, 0)
+ vbox2 = gtk.VBox(False, 0)
+ hbox.pack_start(vbox2, False, False, 0)
+ vbox3 = gtk.VBox(False, 0)
+ hbox.pack_start(vbox3, False, False, 0)
+ for i, line in enumerate(result):
+ if "UseType" in self.display:
+ if line[0] != self.display["UseType"]:
+ continue
+ hbox = gtk.HBox(False, 0)
+ if i <= len(result)/2:
+ vbox2.pack_start(hbox, False, False, 0)
+ else:
+ vbox3.pack_start(hbox, False, False, 0)
+ if True: #line[0] == 'ring':
+ if line[1] == 'fl':
+ name = str(line[2])
+ found['fl'] = True
+ elif line[1] == 'pl':
+ name = str(line[2])+line[1]
+ found['pl'] = True
+ else:
+ name = str(line[2])+line[1]
+ found['nl'] = True
+ self.cbLimits[name] = self.createLimitLine(hbox, name, name)
+ self.types[name] = line[0]
+ found[line[0]] = True # type is ring/tour
+ self.type = line[0] # if only one type, set it now
+ if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2:
+ hbox = gtk.HBox(True, 0)
+ vbox1.pack_start(hbox, False, False, 0)
+ vbox2 = gtk.VBox(False, 0)
+ hbox.pack_start(vbox2, False, False, 0)
+ vbox3 = gtk.VBox(False, 0)
+ hbox.pack_start(vbox3, False, False, 0)
+
+ hbox = gtk.HBox(False, 0)
+ vbox2.pack_start(hbox, False, False, 0)
+ self.cbAllLimits = self.createLimitLine(hbox, 'all', self.filterText['limitsall'])
+ hbox = gtk.HBox(False, 0)
+ vbox2.pack_start(hbox, False, False, 0)
+ self.cbNoLimits = self.createLimitLine(hbox, 'none', self.filterText['limitsnone'])
+
+ dest = vbox3 # for ring/tour buttons
+ if "LimitType" in display and display["LimitType"] == True and found['nl'] and found['fl']:
+ #if found['fl']:
+ hbox = gtk.HBox(False, 0)
+ vbox3.pack_start(hbox, False, False, 0)
+ self.cbFL = self.createLimitLine(hbox, 'fl', self.filterText['limitsFL'])
+ #if found['nl']:
+ hbox = gtk.HBox(False, 0)
+ vbox3.pack_start(hbox, False, False, 0)
+ self.cbNL = self.createLimitLine(hbox, 'nl', self.filterText['limitsNL'])
+ hbox = gtk.HBox(False, 0)
+ vbox3.pack_start(hbox, False, False, 0)
+ self.cbPL = self.createLimitLine(hbox, 'pl', self.filterText['limitsPL'])
+ dest = vbox2 # for ring/tour buttons
+ else:
+ print "INFO: No games returned from database"
+ log.info("No games returned from database")
+
+ if "Type" in display and display["Type"] == True and found['ring'] and found['tour']:
+ rb1 = gtk.RadioButton(None, self.filterText['ring'])
+ rb1.connect('clicked', self.__set_limit_select, 'ring')
+ rb2 = gtk.RadioButton(rb1, self.filterText['tour'])
+ rb2.connect('clicked', self.__set_limit_select, 'tour')
+ top_hbox.pack_start(rb1, False, False, 0) # (child, expand, fill, padding)
+ top_hbox.pack_start(rb2, True, True, 0) # child uses expand space if fill is true
+
+ self.rb['ring'] = rb1
+ self.rb['tour'] = rb2
+ #print "about to set ring to true"
+ rb1.set_active(True)
+ # set_active doesn't seem to call this for some reason so call manually:
+ self.__set_limit_select(rb1, 'ring')
+ self.type = 'ring'
+ top_hbox.pack_start(showb, expand=False, padding=1)
+
+ def fillSeatsFrame(self, vbox, display):
+ hbox = gtk.HBox(False, 0)
+ vbox.pack_start(hbox, False, False, 0)
+ lbl_title = gtk.Label(self.filterText['seatstitle'])
+ lbl_title.set_alignment(xalign=0.0, yalign=0.5)
+ hbox.pack_start(lbl_title, expand=True, padding=3)
+ showb = gtk.Button(label="hide", stock=None, use_underline=True)
+ showb.set_alignment(xalign=1.0, yalign=0.5)
+ showb.connect('clicked', self.__toggle_box, 'seats')
+ hbox.pack_start(showb, expand=False, padding=1)
+
+ vbox1 = gtk.VBox(False, 0)
+ vbox.pack_start(vbox1, False, False, 0)
+ self.boxes['seats'] = vbox1
+
+ hbox = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox, False, True, 0)
+
+ lbl_from = gtk.Label(self.filterText['seatsbetween'])
+ lbl_to = gtk.Label(self.filterText['seatsand'])
+ adj1 = gtk.Adjustment(value=2, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
+ sb1 = gtk.SpinButton(adjustment=adj1, climb_rate=0.0, digits=0)
+ adj2 = gtk.Adjustment(value=10, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
+ sb2 = gtk.SpinButton(adjustment=adj2, climb_rate=0.0, digits=0)
+
+ hbox.pack_start(lbl_from, expand=False, padding=3)
+ hbox.pack_start(sb1, False, False, 0)
+ hbox.pack_start(lbl_to, expand=False, padding=3)
+ hbox.pack_start(sb2, False, False, 0)
+
+ self.sbSeats['from'] = sb1
+ self.sbSeats['to'] = sb2
+ #end def fillSeatsFrame
+
+ def fillGroupsFrame(self, vbox, display):
+ hbox = gtk.HBox(False, 0)
+ vbox.pack_start(hbox, False, False, 0)
+ lbl_title = gtk.Label(self.filterText['groupstitle'])
+ lbl_title.set_alignment(xalign=0.0, yalign=0.5)
+ hbox.pack_start(lbl_title, expand=True, padding=3)
+ showb = gtk.Button(label="hide", stock=None, use_underline=True)
+ showb.set_alignment(xalign=1.0, yalign=0.5)
+ showb.connect('clicked', self.__toggle_box, 'groups')
+ hbox.pack_start(showb, expand=False, padding=1)
+
+ vbox1 = gtk.VBox(False, 0)
+ vbox.pack_start(vbox1, False, False, 0)
+ self.boxes['groups'] = vbox1
+
+ hbox = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox, False, False, 0)
+ cb = self.createLimitLine(hbox, 'show', self.filterText['limitsshow'])
+
+ hbox = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox, False, True, 0)
+ cb = gtk.CheckButton(self.filterText['posnshow'])
+ cb.connect('clicked', self.__set_group_select, 'posn')
+ hbox.pack_start(cb, False, False, 0)
+ self.sbGroups['posn'] = cb
+ self.groups['posn'] = False
+
+ if "SeatSep" in display and display["SeatSep"] == True:
+ hbox = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox, False, True, 0)
+ cb = gtk.CheckButton(self.filterText['seatsshow'])
+ cb.connect('clicked', self.__set_seat_select, 'show')
+ hbox.pack_start(cb, False, False, 0)
+ self.sbSeats['show'] = cb
+ self.seats['show'] = False
+
+ def fillCardsFrame(self, vbox):
+ hbox1 = gtk.HBox(True,0)
+ hbox1.show()
+ vbox.pack_start(hbox1, True, True, 0)
+
+ cards = [ "A", "K","Q","J","T","9","8","7","6","5","4","3","2" ]
+
+ for j in range(0, len(cards)):
+ hbox1 = gtk.HBox(True,0)
+ hbox1.show()
+ vbox.pack_start(hbox1, True, True, 0)
+ for i in range(0, len(cards)):
+ if i < (j + 1):
+ suit = "o"
+ else:
+ suit = "s"
+ button = gtk.ToggleButton("%s%s%s" %(cards[i], cards[j], suit))
+ button.connect("toggled", self.cardCallback, "%s%s%s" %(cards[i], cards[j], suit))
+ hbox1.pack_start(button, True, True, 0)
+ button.show()
+
+ def fillDateFrame(self, vbox):
+ # Hat tip to Mika Bostrom - calendar code comes from PokerStats
+ top_hbox = gtk.HBox(False, 0)
+ vbox.pack_start(top_hbox, False, False, 0)
+ lbl_title = gtk.Label(self.filterText['datestitle'])
+ lbl_title.set_alignment(xalign=0.0, yalign=0.5)
+ top_hbox.pack_start(lbl_title, expand=True, padding=3)
+ showb = gtk.Button(label="hide", stock=None, use_underline=True)
+ showb.set_alignment(xalign=1.0, yalign=0.5)
+ showb.connect('clicked', self.__toggle_box, 'dates')
+ top_hbox.pack_start(showb, expand=False, padding=1)
+
+ vbox1 = gtk.VBox(False, 0)
+ vbox.pack_start(vbox1, False, False, 0)
+ self.boxes['dates'] = vbox1
+
+ hbox = gtk.HBox()
+ vbox1.pack_start(hbox, False, True, 0)
+
+ lbl_start = gtk.Label('From:')
+
+ btn_start = gtk.Button()
+ btn_start.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
+ btn_start.connect('clicked', self.__calendar_dialog, self.start_date)
+
+ hbox.pack_start(lbl_start, expand=False, padding=3)
+ hbox.pack_start(btn_start, expand=False, padding=3)
+ hbox.pack_start(self.start_date, expand=False, padding=2)
+
+ #New row for end date
+ hbox = gtk.HBox()
+ vbox1.pack_start(hbox, False, True, 0)
+
+ lbl_end = gtk.Label(' To:')
+ btn_end = gtk.Button()
+ btn_end.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
+ btn_end.connect('clicked', self.__calendar_dialog, self.end_date)
+
+ btn_clear = gtk.Button(label=' Clear Dates ')
+ btn_clear.connect('clicked', self.__clear_dates)
+
+ hbox.pack_start(lbl_end, expand=False, padding=3)
+ hbox.pack_start(btn_end, expand=False, padding=3)
+ hbox.pack_start(self.end_date, expand=False, padding=2)
+
+ hbox.pack_start(btn_clear, expand=False, padding=15)
+ #end def fillDateFrame
+
+ def __refresh(self, widget, entry):
+ for w in self.mainVBox.get_children():
+ w.destroy()
+ self.make_filter()
+
+ def __toggle_box(self, widget, entry):
+ if self.boxes[entry].props.visible:
+ self.boxes[entry].hide()
+ widget.set_label("show")
+ else:
+ self.boxes[entry].show()
+ widget.set_label("hide")
+ #end def __toggle_box
+
+ def __calendar_dialog(self, widget, entry):
+ d = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ d.set_title('Pick a date')
+
+ vb = gtk.VBox()
+ cal = gtk.Calendar()
+ vb.pack_start(cal, expand=False, padding=0)
+
+ btn = gtk.Button('Done')
+ btn.connect('clicked', self.__get_date, cal, entry, d)
+
+ vb.pack_start(btn, expand=False, padding=4)
+
+ d.add(vb)
+ d.set_position(gtk.WIN_POS_MOUSE)
+ d.show_all()
+ #end def __calendar_dialog
+
+ def __clear_dates(self, w):
+ self.start_date.set_text('')
+ self.end_date.set_text('')
+ #end def __clear_dates
+
+ def __get_dates(self):
+ # self.day_start gives user's start of day in hours
+ offset = int(self.day_start * 3600) # calc day_start in seconds
+
+ t1 = self.start_date.get_text()
+ t2 = self.end_date.get_text()
+
+ if t1 == '':
+ t1 = '1970-01-02'
+ if t2 == '':
+ t2 = '2020-12-12'
+
+ s1 = strptime(t1, "%Y-%m-%d") # make time_struct
+ s2 = strptime(t2, "%Y-%m-%d")
+ e1 = mktime(s1) + offset # s1 is localtime, but returned time since epoch is UTC, then add the
+ e2 = mktime(s2) + offset # s2 is localtime, but returned time since epoch is UTC
+ e2 = e2 + 24 * 3600 - 1 # date test is inclusive, so add 23h 59m 59s to e2
+
+ adj_t1 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e1)) # make adjusted string including time
+ adj_t2 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e2))
+ log.info("t1="+t1+" adj_t1="+adj_t1+'.')
+
+ return (adj_t1, adj_t2)
+ #end def __get_dates
+
+ def __get_date(self, widget, calendar, entry, win):
+ # year and day are correct, month is 0..11
+ (year, month, day) = calendar.get_date()
+ month += 1
+ ds = '%04d-%02d-%02d' % (year, month, day)
+ entry.set_text(ds)
+ win.destroy()
+
+def main(argv=None):
+ """main can also be called in the python interpreter, by supplying the command line as the argument."""
+ if argv is None:
+ argv = sys.argv[1:]
+
+ def destroy(*args): # call back for terminating the main eventloop
+ gtk.main_quit()
+
+ parser = OptionParser()
+ (options, argv) = parser.parse_args(args = argv)
+
+ config = Configuration.Config()
+ db = None
+
+ db = Database.Database()
+ db.do_connect(config)
+
+ qdict = SQL.SQL(db.get_backend_name())
+
+ i = Filters(db, config, qdict)
+ main_window = gtk.Window()
+ main_window.connect('destroy', destroy)
+ main_window.add(i.get_vbox())
+ main_window.show()
+ gtk.main()
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py
index 77a3883c..cc2e9cc1 100644
--- a/pyfpdb/SQL.py
+++ b/pyfpdb/SQL.py
@@ -1941,12 +1941,12 @@ class Sql:
inner join Hands h on (h.id = hp3.handId)
"""
- # used in GuiPlayerStats:
+ # used in Gui*PlayerStats:
self.query['getPlayerId'] = """SELECT id from Players where name = %s"""
self.query['getPlayerIdBySite'] = """SELECT id from Players where name = %s AND siteId = %s"""
- # used in Filters:
+ # used in *Filters:
self.query['getSiteId'] = """SELECT id from Sites where name = %s"""
self.query['getGames'] = """SELECT DISTINCT category from Gametypes"""
self.query['getLimits'] = """SELECT DISTINCT bigBlind from Gametypes ORDER by bigBlind DESC"""
diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw
index d5dc0656..d97a0f75 100755
--- a/pyfpdb/fpdb.pyw
+++ b/pyfpdb/fpdb.pyw
@@ -103,7 +103,7 @@ import GuiLogView
import GuiDatabase
import GuiBulkImport
import ImapSummaries
-import GuiPlayerStats
+import GuiRingPlayerStats
import GuiTourneyPlayerStats
import GuiPositionalStats
import GuiTableViewer
@@ -860,7 +860,7 @@ class fpdb:
self.add_and_display_tab(bulk_tab, "Bulk Import")
def tab_ring_player_stats(self, widget, data=None):
- new_ps_thread = GuiPlayerStats.GuiPlayerStats(self.config, self.sql, self.window)
+ new_ps_thread = GuiRingPlayerStats.GuiRingPlayerStats(self.config, self.sql, self.window)
self.threads.append(new_ps_thread)
ps_tab=new_ps_thread.get_vbox()
self.add_and_display_tab(ps_tab, "Ring Player Stats")