diff --git a/packaging/debian/changelog b/packaging/debian/changelog index e95fd1c5..0616ad0e 100644 --- a/packaging/debian/changelog +++ b/packaging/debian/changelog @@ -1,3 +1,34 @@ +free-poker-tools (0.20.902-1) unstable; urgency=low + + * New snapshot release; .901 was broken for FTP + + -- Mika Bostrom Sat, 24 Jul 2010 09:05:57 +0300 + +free-poker-tools (0.20.901-1) unstable; urgency=low + + * Snapshot release before oncoming 0.21 + + -- Mika Bostrom Thu, 22 Jul 2010 23:32:47 +0300 + +free-poker-tools (0.20.1-1) unstable; urgency=low + + * 0.20.1 release + + -- Mika Bostrom Thu, 22 Jul 2010 08:47:39 +0300 + +free-poker-tools (0.20-2) unstable; urgency=low + + * Fix executable script shebangs: there is no /usr/bin/python2 (nor + /usr/bin/python3) symlink on Debian or Ubuntu + + -- Mika Bostrom Thu, 08 Jul 2010 21:29:40 +0300 + +free-poker-tools (0.20-1) unstable; urgency=low + + * 0.20 release + + -- Mika Bostrom Thu, 08 Jul 2010 11:25:36 +0300 + free-poker-tools (0.20~git20100630) unstable; urgency=low * Snapshot release diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index b5e3e76f..03858760 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -357,6 +357,7 @@ class Game: class Database: def __init__(self, node): self.db_name = node.getAttribute("db_name") + self.db_desc = node.getAttribute("db_desc") self.db_server = node.getAttribute("db_server").lower() self.db_ip = node.getAttribute("db_ip") self.db_user = node.getAttribute("db_user") @@ -817,6 +818,9 @@ class Config: try: db['db-databaseName'] = name except: pass + try: db['db-desc'] = self.supported_databases[name].db_desc + except: pass + try: db['db-host'] = self.supported_databases[name].db_ip except: pass @@ -834,20 +838,29 @@ class Config: return db def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None, - db_pass = None, db_server = None): + db_pass = None, db_desc = None, db_server = None, + default = "False"): db_node = self.get_db_node(db_name) + default = default.lower() + defaultb = string_to_bool(default, False) if db_node != None: + if db_desc is not None: db_node.setAttribute("db_desc", db_desc) if db_ip is not None: db_node.setAttribute("db_ip", db_ip) if db_user is not None: db_node.setAttribute("db_user", db_user) if db_pass is not None: db_node.setAttribute("db_pass", db_pass) if db_server is not None: db_node.setAttribute("db_server", db_server) - if db_type is not None: db_node.setAttribute("db_type", db_type) + if defaultb: db_node.setAttribute("default", default) + elif db_node.hasAttribute("default"): + db_node.removeAttribute("default") if self.supported_databases.has_key(db_name): + if db_desc is not None: self.supported_databases[db_name].dp_desc = db_desc if db_ip is not None: self.supported_databases[db_name].dp_ip = db_ip if db_user is not None: self.supported_databases[db_name].dp_user = db_user if db_pass is not None: self.supported_databases[db_name].dp_pass = db_pass if db_server is not None: self.supported_databases[db_name].dp_server = db_server - if db_type is not None: self.supported_databases[db_name].dp_type = db_type + self.supported_databases[db_name].db_selected = defaultb + if defaultb: + self.db_selected = db_name return def get_backend(self, name): diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index c7e00190..028097dd 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -74,7 +74,7 @@ except ImportError: use_numpy = False -DB_VERSION = 136 +DB_VERSION = 138 # Variance created as sqlite has a bunch of undefined aggregate functions. @@ -147,7 +147,6 @@ class Database: {'tab':'Hands', 'col':'gametypeId', 'drop':0} , {'tab':'HandsPlayers', 'col':'handId', 'drop':0} , {'tab':'HandsPlayers', 'col':'playerId', 'drop':0} - , {'tab':'HandsPlayers', 'col':'tourneyTypeId', 'drop':0} , {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0} , {'tab':'HudCache', 'col':'gametypeId', 'drop':1} , {'tab':'HudCache', 'col':'playerId', 'drop':0} @@ -168,7 +167,6 @@ class Database: {'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} - , {'fktab':'HandsPlayers', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1} , {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} @@ -1641,7 +1639,6 @@ class Database: pdata[p]['street3Bets'], pdata[p]['street4Bets'], pdata[p]['position'], - pdata[p]['tourneyTypeId'], pdata[p]['tourneysPlayersIds'], pdata[p]['startCards'], pdata[p]['street0_3BChance'], @@ -1983,17 +1980,21 @@ class Database: (hand.tourNo, hand.siteId) ) result=cursor.fetchone() + #print "result of fetching TT by number and site:",result if result: tourneyTypeId = result[0] else: # Check for an existing TTypeId that matches tourney info, if not found create it + #print "info that we use to get TT by detail:", hand.siteId, hand.buyinCurrency, hand.buyin, hand.fee, hand.gametype['category'], hand.gametype['limitType'], hand.isKO, hand.isRebuy, hand.isAddOn, hand.speed, hand.isShootout, hand.isMatrix + #print "the query:",self.sql.query['getTourneyTypeId'].replace('%s', self.sql.query['placeholder']) cursor.execute (self.sql.query['getTourneyTypeId'].replace('%s', self.sql.query['placeholder']), (hand.siteId, hand.buyinCurrency, hand.buyin, hand.fee, hand.gametype['category'], hand.gametype['limitType'], hand.isKO, - hand.isRebuy, hand.isRebuy, hand.speed, hand.isShootout, hand.isMatrix, hand.added, hand.addedCurrency) + hand.isRebuy, hand.isAddOn, hand.speed, hand.isShootout, hand.isMatrix) ) result=cursor.fetchone() - + #print "result of fetching TT by details:",result + try: tourneyTypeId = result[0] except TypeError: #this means we need to create a new entry diff --git a/pyfpdb/EverleafToFpdb.py b/pyfpdb/EverleafToFpdb.py index b16980ed..a069d89c 100755 --- a/pyfpdb/EverleafToFpdb.py +++ b/pyfpdb/EverleafToFpdb.py @@ -146,13 +146,14 @@ or None if we fail to get the info """ tourno = t.group('TOURNO') hand.tourNo = tourno hand.tablename = t.group('TABLE') + #TODO we should fetch info including buyincurrency, buyin and fee from URL: + # https://www.poker4ever.com/tourney/%TOURNEY_NUMBER% # Believe Everleaf time is GMT/UTC, no transation necessary # Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET] # or : 2008/11/07 12:38:49 ET # Not getting it in my HH files yet, so using # 2008/11/10 3:58:52 ET - #TODO: Do conversion from GMT to ET #TODO: Need some date functions to convert to different timezones (Date::Manip for perl rocked for this) hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), "%Y/%m/%d - %H:%M:%S") return diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py index 06f43610..94bee25f 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -229,12 +229,21 @@ class Filters(threading.Thread): return self.numHands #end def getNumHands + def getNumTourneys(self): + return self.numTourneys + #end def getNumTourneys + def getSites(self): return self.sites #end def getSites + def getTourneyTypes(self): + return self.tourneyTypes + #end def getTourneyTypes + def getGames(self): return self.games + #end def getGames def getSiteIds(self): return self.siteid @@ -316,6 +325,7 @@ class Filters(threading.Thread): liststore.append(_nt) self.__set_hero_name(pname, site) + #end def createPlayerLine def __set_hero_name(self, w, site): _name = w.get_text() @@ -338,6 +348,20 @@ class Filters(threading.Thread): cb.connect('clicked', self.__set_site_select, site) cb.set_active(True) hbox.pack_start(cb, False, False, 0) + #end def createSiteLine + + def __set_tourney_type_select(self, w, tourneyType): + #print w.get_active() + self.tourneyTypes[tourneyType] = w.get_active() + log.debug("self.tourney_types[%s] set to %s" %(tourneyType, self.tourneyTypes[tourneyType])) + #end def __set_tourney_type_select + + def createTourneyTypeLine(self, hbox, tourneyType): + cb = gtk.CheckButton(str(tourneyType)) + cb.connect('clicked', self.__set_tourney_type_select, tourneyType) + hbox.pack_start(cb, False, False, 0) + cb.set_active(True) + #end def createTourneyTypeLine def createGameLine(self, hbox, game): cb = gtk.CheckButton(game) @@ -357,6 +381,7 @@ class Filters(threading.Thread): #print w.get_active() self.sites[site] = w.get_active() log.debug("self.sites[%s] set to %s" %(site, self.sites[site])) + #end def __set_site_select def __set_game_select(self, w, game): #print w.get_active() @@ -505,6 +530,7 @@ class Filters(threading.Thread): #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]) ) + #end def __set_seat_select def __set_group_select(self, w, group): #print "__set_seat_select: seat =", seat, "active =", w.get_active() @@ -552,6 +578,7 @@ class Filters(threading.Thread): hbox.pack_start(phands, False, False, 0) phands.connect("changed", self.__set_num_hands, site) top_hbox.pack_start(showb, expand=False, padding=1) + #end def fillPlayerFrame def fillSitesFrame(self, vbox): top_hbox = gtk.HBox(False, 0) @@ -583,6 +610,33 @@ class Filters(threading.Thread): # self.siteid[site] = result[0][0] #else: # print "Either 0 or more than one site matched - EEK" + #end def fillSitesFrame + + def fillTourneyTypesFrame(self, vbox): + top_hbox = gtk.HBox(False, 0) + vbox.pack_start(top_hbox, False, False, 0) + lbl_title = gtk.Label(self.filterText['tourneyTypesTitle']) + 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, 'tourneyTypes') + top_hbox.pack_start(showb, expand=False, padding=1) + + vbox1 = gtk.VBox(False, 0) + vbox.pack_start(vbox1, False, False, 0) + self.boxes['tourneyTypes'] = vbox1 + + result = self.db.getTourneyTypesIds() + if len(result) >= 1: + for line in result: + hbox = gtk.HBox(False, 0) + vbox1.pack_start(hbox, False, True, 0) + self.createTourneyTypeLine(hbox, line[0]) + else: + print "INFO: No tourney types returned from database" + log.info("No tourney types returned from database") + #end def fillTourneyTypesFrame def fillGamesFrame(self, vbox): top_hbox = gtk.HBox(False, 0) @@ -859,6 +913,7 @@ class Filters(threading.Thread): for w in self.mainVBox.get_children(): w.destroy() self.make_filter() + #end def __refresh def __toggle_box(self, widget, entry): if self.boxes[entry].props.visible: diff --git a/pyfpdb/GuiDatabase.py b/pyfpdb/GuiDatabase.py index 418910cf..a808c7df 100755 --- a/pyfpdb/GuiDatabase.py +++ b/pyfpdb/GuiDatabase.py @@ -33,17 +33,32 @@ log = logging.getLogger("maintdbs") import Exceptions import Database +import SQL class GuiDatabase: + # columns in liststore: + MODEL_DBMS = 0 + MODEL_NAME = 1 + MODEL_DESC = 2 + MODEL_USER = 3 + MODEL_PASS = 4 + MODEL_HOST = 5 + MODEL_DFLT = 6 + MODEL_DFLTIC = 7 + MODEL_STATUS = 8 + MODEL_STATIC = 9 + + # columns in listview: COL_DBMS = 0 COL_NAME = 1 COL_DESC = 2 COL_USER = 3 COL_PASS = 4 COL_HOST = 5 - COL_ICON = 6 + COL_DFLT = 6 + COL_ICON = 7 def __init__(self, config, mainwin, dia): self.config = config @@ -56,9 +71,9 @@ class GuiDatabase: #gtk.Widget.set_size_request(self.vbox, 700, 400); # list of databases in self.config.supported_databases: - self.liststore = gtk.ListStore(str, str, str, str - ,str, str, str, str) #object, gtk.gdk.Pixbuf) - # dbms, name, comment, user, pass, ip, status(, icon?) + self.liststore = gtk.ListStore(str, str, str, str, str + ,str, str, str, str, str) + # dbms, name, comment, user, passwd, host, "", default_icon, status, icon # this is how to add a filter: # # # Creation of the filter, from the model @@ -70,11 +85,12 @@ class GuiDatabase: self.listview = gtk.TreeView(model=self.liststore) self.listview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_NONE) self.listcols = [] + self.changes = False - scrolledwindow = gtk.ScrolledWindow() - scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - scrolledwindow.add(self.listview) - self.vbox.pack_start(scrolledwindow, expand=True, fill=True, padding=0) + self.scrolledwindow = gtk.ScrolledWindow() + self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.scrolledwindow.add(self.listview) + self.vbox.pack_start(self.scrolledwindow, expand=True, fill=True, padding=0) refreshbutton = gtk.Button("Refresh") refreshbutton.connect("clicked", self.refresh, None) @@ -87,18 +103,28 @@ class GuiDatabase: col = self.addTextColumn("Username", 3, True) col = self.addTextColumn("Password", 4, True) col = self.addTextColumn("Host", 5, True) - col = self.addTextObjColumn("", 6) + col = self.addTextObjColumn("Default", 6, 6) + col = self.addTextObjColumn("Status", 7, 8) + + #self.listview.get_selection().set_mode(gtk.SELECTION_SINGLE) + #self.listview.get_selection().connect("changed", self.on_selection_changed) + self.listview.add_events(gtk.gdk.BUTTON_PRESS_MASK) + self.listview.connect('button_press_event', self.selectTest) self.loadDbs() - self.dia.connect('response', self.dialog_response_cb) + #self.dia.connect('response', self.dialog_response_cb) except: err = traceback.extract_tb(sys.exc_info()[2])[-1] print 'guidbmaint: '+ err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]) def dialog_response_cb(self, dialog, response_id): # this is called whether close button is pressed or window is closed + log.info('dialog_response_cb: response_id='+str(response_id)) + #if self.changes: + # self.config.save() dialog.destroy() + return(response_id) def get_dialog(self): @@ -125,6 +151,7 @@ class GuiDatabase: def edited_cb(self, cell, path, new_text, user_data): liststore, col = user_data + log.info('edited_cb: col = '+str(col)) valid = True name = self.liststore[path][self.COL_NAME] @@ -138,10 +165,11 @@ class GuiDatabase: self.config.set_db_parameters( db_server = self.liststore[path][self.COL_DBMS] , db_name = name + , db_desc = self.liststore[path][self.COL_DESC] , db_ip = self.liststore[path][self.COL_HOST] , db_user = self.liststore[path][self.COL_USER] , db_pass = self.liststore[path][self.COL_PASS] ) - + self.changes = True return def check_new_name(self, path, new_text): @@ -152,38 +180,73 @@ class GuiDatabase: #TODO: popup an error message telling user names must be unique return name_ok - def addTextObjColumn(self, title, n): + def addTextObjColumn(self, title, viewcol, storecol, editable=False): col = gtk.TreeViewColumn(title) self.listview.append_column(col) cRenderT = gtk.CellRendererText() cRenderT.set_property("wrap-mode", pango.WRAP_WORD_CHAR) col.pack_start(cRenderT, False) - col.add_attribute(cRenderT, 'text', n) + col.add_attribute(cRenderT, 'text', storecol) cRenderP = gtk.CellRendererPixbuf() - col.pack_start(cRenderP, False) - col.add_attribute(cRenderP, 'stock-id', n+1) + col.pack_start(cRenderP, True) + col.add_attribute(cRenderP, 'stock-id', storecol+1) col.set_max_width(1000) col.set_spacing(0) # no effect self.listcols.append(col) - #col.set_clickable(True) - #col.connect("clicked", self.sortCols, p) + + col.set_clickable(True) + col.connect("clicked", self.sortCols, viewcol) return(col) + def selectTest(self, widget, event): + if event.button == 1: # and event.type == gtk.gdk._2BUTTON_PRESS: + pthinfo = self.listview.get_path_at_pos( int(event.x), int(event.y) ) + if pthinfo is not None: + path, col, cellx, celly = pthinfo + row = path[0] + if col == self.listcols[self.COL_DFLT]: + if self.liststore[row][self.MODEL_STATUS] == 'ok' and self.liststore[row][self.MODEL_DFLTIC] is None: + self.setDefaultDB(row) + + def setDefaultDB(self, row): + print "set new defaultdb:", row, self.liststore[row][self.MODEL_NAME] + for r in xrange(len(self.liststore)): + if r == row: + self.liststore[r][self.MODEL_DFLTIC] = gtk.STOCK_APPLY + default = "True" + else: + self.liststore[r][self.MODEL_DFLTIC] = None + default = "False" + + self.config.set_db_parameters( db_server = self.liststore[r][self.COL_DBMS] + , db_name = self.liststore[r][self.COL_NAME] + , db_desc = self.liststore[r][self.COL_DESC] + , db_ip = self.liststore[r][self.COL_HOST] + , db_user = self.liststore[r][self.COL_USER] + , db_pass = self.liststore[r][self.COL_PASS] + , default = default + ) + self.changes = True + return + + def loadDbs(self): self.liststore.clear() - self.listcols = [] - self.dbs = [] # list of tuples: (dbms, name, comment, user, passwd, host, status, icon) + #self.listcols = [] + dia = self.info_box2(None, 'Testing database connections ... ', "", False, False) + while gtk.events_pending(): + gtk.mainiteration() try: - # want to fill: dbms, name, comment, user, passwd, host, status(, icon?) + # want to fill: dbms, name, comment, user, passwd, host, default, status, icon for name in self.config.supported_databases: #db_ip/db_user/db_pass/db_server dbms = self.config.supported_databases[name].db_server # mysql/postgresql/sqlite dbms_num = self.config.get_backend(dbms) # 2 / 3 / 4 - comment = "" + comment = self.config.supported_databases[name].db_desc if dbms == 'sqlite': user = "" passwd = "" @@ -191,22 +254,30 @@ class GuiDatabase: user = self.config.supported_databases[name].db_user passwd = self.config.supported_databases[name].db_pass host = self.config.supported_databases[name].db_ip + default = (name == self.config.db_selected) + default_icon = None + if default: default_icon = gtk.STOCK_APPLY status = "" icon = None err_msg = "" - db = Database.Database(self.config, sql = None, autoconnect = False) + sql = SQL.Sql(db_server=dbms) + db = Database.Database(self.config, sql = sql, autoconnect = False) # try to connect to db, set status and err_msg if it fails try: # is creating empty db for sqlite ... mod db.py further? # add noDbTables flag to db.py? + log.debug("loaddbs: trying to connect to: %s/%s, %s, %s/%s" % (str(dbms_num),dbms,name,user,passwd)) db.connect(backend=dbms_num, host=host, database=name, user=user, password=passwd, create=False) if db.connected: + log.debug(" connected ok") status = 'ok' icon = gtk.STOCK_APPLY if db.wrongDbVersion: status = 'old' icon = gtk.STOCK_INFO + else: + log.debug(" not connected but no exception") except Exceptions.FpdbMySQLAccessDenied: err_msg = "MySQL Server reports: Access denied. Are your permissions set correctly?" status = "failed" @@ -230,13 +301,17 @@ class GuiDatabase: + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]) ) status = "failed" icon = gtk.STOCK_CANCEL + if err_msg: + log.info( 'db connection to '+str(dbms_num)+','+host+','+name+','+user+','+passwd+' failed: ' + + err_msg ) b = gtk.Button(name) b.show() - iter = self.liststore.append( (dbms, name, comment, user, passwd, host, status, icon) ) + iter = self.liststore.append( (dbms, name, comment, user, passwd, host, "", default_icon, status, icon) ) + self.info_box2(dia[0], "finished.", "", False, True) self.listview.show() - scrolledwindow.show() + self.scrolledwindow.show() self.vbox.show() self.dia.set_focus(self.listview) @@ -249,13 +324,16 @@ class GuiDatabase: def sortCols(self, col, n): try: + log.info('sortcols n='+str(n)) 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.set_sort_column_id(n, col.get_sort_order()) #self.liststore.set_sort_func(n, self.sortnums, (n,grid)) + log.info('sortcols len(listcols)='+str(len(self.listcols))) for i in xrange(len(self.listcols)): + log.info('sortcols i='+str(i)) self.listcols[i].set_sort_indicator(False) self.listcols[n].set_sort_indicator(True) # use this listcols[col].set_sort_indicator(True) @@ -264,10 +342,69 @@ class GuiDatabase: 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] ) + log.info('sortCols error: ' + str(sys.exc_info()) ) def refresh(self, widget, data): self.loadDbs() + def info_box(self, dia, str1, str2, run, destroy): + if dia is None: + #if run: + btns = gtk.BUTTONS_NONE + btns = gtk.BUTTONS_OK + dia = gtk.MessageDialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT + , type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 ) + # try to remove buttons! + # (main message is in inverse video if no buttons, so try removing them after + # creating dialog) + # NO! message just goes back to inverse video :-( use info_box2 instead + for c in dia.vbox.get_children(): + if isinstance(c, gtk.HButtonBox): + for d in c.get_children(): + log.info('child: '+str(d)+' is a '+str(d.__class__)) + if isinstance(d, gtk.Button): + log.info('removing button '+str(d)) + c.remove(d) + if str2: + dia.format_secondary_text(str2) + else: + dia.set_markup(str1) + if str2: + dia.format_secondary_text(str2) + dia.show() + response = None + if run: response = dia.run() + if destroy: dia.destroy() + return (dia, response) + + def info_box2(self, dia, str1, str2, run, destroy): + if dia is None: + # create dialog and add icon and label + btns = (gtk.BUTTONS_OK) + btns = None + # messagedialog puts text in inverse colors if no buttons are displayed?? + #dia = gtk.MessageDialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT + # , type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 ) + dia = gtk.Dialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT + , title="" ) # , buttons=btns + vbox = dia.vbox + + h = gtk.HBox(False, 2) + i = gtk.Image() + i.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG) + l = gtk.Label(str1) + h.pack_start(i, padding=5) + h.pack_start(l, padding=5) + vbox.pack_start(h) + else: + # add extra label + vbox = dia.vbox + vbox.pack_start( gtk.Label(str1) ) + dia.show_all() + response = None + if run: response = dia.run() + if destroy: dia.destroy() + return (dia, response) if __name__=="__main__": diff --git a/pyfpdb/GuiTableViewer.py b/pyfpdb/GuiTableViewer.py deleted file mode 100644 index 8086c0a0..00000000 --- a/pyfpdb/GuiTableViewer.py +++ /dev/null @@ -1,290 +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 fpdb_import -from Exceptions import * - - -class GuiTableViewer (threading.Thread): - def hudDivide (self, a, b): - if b==0: - return "n/a" - else: - return str(int((a/float(b))*100))+"%" - #end def hudDivide - - def browse_clicked(self, widget, data): - """runs when user clicks browse on tv tab""" - #print "start of table_viewer.browser_clicked" - current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) - - dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer", - action=gtk.FILE_CHOOSER_ACTION_OPEN, - buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) - #dia_chooser.set_current_folder(pathname) - dia_chooser.set_filename(current_path) - #dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import - - response = dia_chooser.run() - if response == gtk.RESPONSE_OK: - #print dia_chooser.get_filename(), 'selected' - self.filename_tbuffer.set_text(dia_chooser.get_filename()) - elif response == gtk.RESPONSE_CANCEL: - print 'Closed, no files selected' - dia_chooser.destroy() - #end def table_viewer.browse_clicked - - def prepare_data(self): - """prepares the data for display by refresh_clicked, returns a 2D array""" - #print "start of prepare_data" - arr=[] - #first prepare the header row - if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"): - tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST") - - tmp+=("FS", "FB") - - tmp+=("CB", ) - - tmp+=("2B", "3B") - - tmp+=("AF", "FF", "AT", "FT", "AR", "FR") - - tmp+=("WtSD", "W$wsF", "W$SD") - else: - raise FpdbError("reimplement stud") - arr.append(tmp) - - #then the data rows - for player in range(len(self.player_names)): - tmp=[] - p_name = Charset.to_gui(self.player_names[player][0]) - tmp.append(p_name) - - seatCount=len(self.player_names) - if seatCount>=8: - minSeats,maxSeats=7,10 - elif seatCount==7: - minSeats,maxSeats=6,10 - elif seatCount==6 or seatCount==5: - minSeats,maxSeats=seatCount-1,seatCount+1 - elif seatCount==4: - minSeats,maxSeats=4,5 - elif seatCount==2 or seatCount==3: - minSeats,maxSeats=seatCount,seatCount - else: - FpdbError("invalid seatCount") - - self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats)) - rows=self.cursor.fetchall() - - row=[] - for field_no in range(len(rows[0])): - row.append(rows[0][field_no]) - - for row_no in range(len(rows)): - if row_no==0: - pass - else: - for field_no in range(len(rows[row_no])): - if field_no<=3: - pass - else: - #print "in prep data, row_no:",row_no,"field_no:",field_no - row[field_no]+=rows[row_no][field_no] - - tmp.append(str(row[6]))#Hands - tmp.append(self.hudDivide(row[7],row[6])) #VPIP - tmp.append(self.hudDivide(row[8],row[6])) #PFR - tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B - - tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST - - tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS - tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB - - tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB - - tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B - tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B - - tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF - tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF - tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT - tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT - tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR - tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR - - tmp.append(self.hudDivide(row[15],row[11])) #WtSD - tmp.append(self.hudDivide(row[28],row[11])) #W$wSF - tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD - - arr.append(tmp) - return arr - #end def table_viewer.prepare_data - - def refresh_clicked(self, widget, data): - """runs when user clicks refresh""" - #print "start of table_viewer.refresh_clicked" - arr=self.prepare_data() - - try: self.data_table.destroy() - except AttributeError: pass - self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False) - self.main_vbox.pack_start(self.data_table) - self.data_table.show() - - for row in range(len(arr)): - for column in range (len(arr[row])): - eventBox=gtk.EventBox() - new_label=gtk.Label(arr[row][column]) - if row%2==0: # - bg_col="white" - if column==0 or (column>=5 and column<=10): - bg_col="lightgrey" - else: - bg_col="lightgrey" - if column==0 or (column>=5 and column<=10): - bg_col="grey" - #style = eventBox.get_style() - #style.font.height=8 - #eventBox.set_style(style) - - eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col)) - eventBox.add(new_label) - self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1) - eventBox.show() - new_label.show() - #end def table_viewer.refresh_clicked - - def read_names_clicked(self, widget, data): - """runs when user clicks read names""" - #print "start of table_viewer.read_names_clicked" - self.db.reconnect() - self.cursor=self.db.get_cursor() - #self.hands_id=self.last_read_hand_id - - self.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, )) - self.gametype_id=self.cursor.fetchone()[0] - self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, )) - self.category=self.cursor.fetchone()[0] - #print "self.gametype_id", self.gametype_id," category:", self.category, " self.hands_id:", self.hands_id - - self.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers - INNER JOIN Players ON HandsPlayers.playerId=Players.id - WHERE handId=%s""", (self.hands_id, )) - self.player_ids=self.cursor.fetchall() - #print "self.player_ids:",self.player_ids - - self.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers - INNER JOIN Players ON HandsPlayers.playerId=Players.id - WHERE handId=%s""", (self.hands_id, )) - self.player_names=self.cursor.fetchall() - #print "self.player_names:",self.player_names - #end def table_viewer.read_names_clicked - - def import_clicked(self, widget, data): - """runs when user clicks import""" - #print "start of table_viewer.import_clicked" - self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter()) - - self.importer = fpdb_import.Importer(self, self.settings, self.config) - self.importer.setMinPrint(0) - self.importer.setQuiet(False) - self.importer.setFailOnError(False) - self.importer.setHandCount(0) - - self.importer.addImportFile(self.inputFile) - self.importer.runImport() - self.hands_id=self.importer.handsId - #end def table_viewer.import_clicked - - def all_clicked(self, widget, data): - """runs when user clicks all""" - #print "start of table_viewer.all_clicked" - self.import_clicked(widget, data) - self.read_names_clicked(widget, data) - self.refresh_clicked(widget, data) - #end def table_viewer.all_clicked - - def get_vbox(self): - """returns the vbox of this thread""" - return self.main_vbox - #end def get_vbox - - def __init__(self, db, settings, config=None, debug=True): - """Constructor for table_viewer""" - self.debug=debug - #print "start of table_viewer constructor" - self.db = db - self.cursor = db.get_cursor() - self.settings = settings - self.config = config - - self.main_vbox = gtk.VBox(False, 0) - self.main_vbox.show() - - self.settings_hbox = gtk.HBox(False, 0) - self.main_vbox.pack_end(self.settings_hbox, False, True, 0) - self.settings_hbox.show() - - self.filename_label = gtk.Label("Path of history file") - self.settings_hbox.pack_start(self.filename_label, False, False) - self.filename_label.show() - - self.filename_tbuffer=gtk.TextBuffer() - self.filename_tbuffer.set_text(self.settings['hud-defaultPath']) - self.filename_tview=gtk.TextView(self.filename_tbuffer) - self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5) - self.filename_tview.show() - - self.browse_button=gtk.Button("Browse...") - self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked") - self.settings_hbox.pack_start(self.browse_button, False, False) - self.browse_button.show() - - - self.button_hbox = gtk.HBox(False, 0) - self.main_vbox.pack_end(self.button_hbox, False, True, 0) - self.button_hbox.show() - - #self.import_button = gtk.Button("Import") - #self.import_button.connect("clicked", self.import_clicked, "Import clicked") - #self.button_hbox.add(self.import_button) - #self.import_button.show() - - #self.read_names_button = gtk.Button("Read Names") - #self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked") - #self.button_hbox.add(self.read_names_button) - #self.read_names_button.show() - - #self.refresh_button = gtk.Button("Show/Refresh data") - #self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked") - #self.button_hbox.add(self.refresh_button) - #self.refresh_button.show() - - self.all_button = gtk.Button("Import&Read&Refresh") - self.all_button.connect("clicked", self.all_clicked, "All clicked") - self.button_hbox.add(self.all_button) - self.all_button.show() - #end of table_viewer.__init__ diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index a3dfd5e5..59fa4378 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -392,9 +392,9 @@ class Sql: self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id), siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id), - currency varchar(4) NOT NULL, - buyIn INT NOT NULL, - fee INT NOT NULL, + currency varchar(4), + buyIn INT, + fee INT, category varchar(9) NOT NULL, limitType char(2) NOT NULL, buyInChips INT, @@ -423,9 +423,9 @@ class Sql: self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( id SERIAL, PRIMARY KEY (id), siteId INT NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id), - currency varchar(4) NOT NULL, - buyin INT NOT NULL, - fee INT NOT NULL, + currency varchar(4), + buyin INT, + fee INT, category varchar(9), limitType char(2), buyInChips INT, @@ -453,9 +453,9 @@ class Sql: self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( id INTEGER PRIMARY KEY, siteId INT NOT NULL, - currency VARCHAR(4) NOT NULL, - buyin INT NOT NULL, - fee INT NOT NULL, + currency VARCHAR(4), + buyin INT, + fee INT, category TEXT, limitType TEXT, buyInChips INT, @@ -560,7 +560,6 @@ class Sql: comment text, commentTs DATETIME, tourneysPlayersId BIGINT UNSIGNED, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id), - tourneyTypeId SMALLINT UNSIGNED, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id), wonWhenSeenStreet1 FLOAT, wonWhenSeenStreet2 FLOAT, @@ -677,7 +676,6 @@ class Sql: comment text, commentTs timestamp without time zone, tourneysPlayersId BIGINT, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id), - tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id), wonWhenSeenStreet1 FLOAT, wonWhenSeenStreet2 FLOAT, @@ -793,7 +791,6 @@ class Sql: comment TEXT, commentTs REAL, tourneysPlayersId INT, - tourneyTypeId INT, wonWhenSeenStreet1 REAL, wonWhenSeenStreet2 REAL, @@ -2447,6 +2444,8 @@ class Sql: ) hprof2 on hprof2.gtId = stats.gtId order by stats.category, stats.limittype, stats.bigBlindDesc desc """ + #elif db_server == 'sqlite': #TODO + # self.query['playerStats'] = """ """ else: # assume postgres self.query['playerStats'] = """ SELECT upper(stats.limitType) || ' ' @@ -2550,8 +2549,6 @@ class Sql: ) hprof2 on hprof2.gtId = stats.gtId order by stats.base, stats.limittype, stats.bigBlindDesc desc """ - #elif db_server == 'sqlite': - # self.query['playerStats'] = """ """ if db_server == 'mysql': self.query['playerStatsByPosition'] = """ @@ -2989,7 +2986,7 @@ class Sql: when hp.position = '9' then 'E' else 'E' end AS hc_position - ,hp.tourneyTypeId + ,t.tourneyTypeId ,date_format(h.startTime, 'd%y%m%d') ,count(1) ,sum(wonWhenSeenStreet1) @@ -3063,12 +3060,14 @@ class Sql: ,sum(hp.street4Raises) FROM HandsPlayers hp INNER JOIN Hands h ON (h.id = hp.handId) + INNER JOIN TourneysPlayers tp ON (tp.id = hp.tourneysPlayersId) + INNER JOIN Tourneys t ON (t.id = tp.tourneyId) GROUP BY h.gametypeId ,hp.playerId ,h.seats ,hc_position - ,hp.tourneyTypeId + ,t.tourneyTypeId ,date_format(h.startTime, 'd%y%m%d') """ elif db_server == 'postgresql': @@ -3168,7 +3167,7 @@ class Sql: when hp.position = '9' then 'E' else 'E' end AS hc_position - ,hp.tourneyTypeId + ,t.tourneyTypeId ,'d' || to_char(h.startTime, 'YYMMDD') ,count(1) ,sum(wonWhenSeenStreet1) @@ -3242,12 +3241,14 @@ class Sql: ,sum(CAST(hp.street4Raises as integer)) FROM HandsPlayers hp INNER JOIN Hands h ON (h.id = hp.handId) + INNER JOIN TourneysPlayers tp ON (tp.id = hp.tourneysPlayersId) + INNER JOIN Tourneys t ON (t.id = tp.tourneyId) GROUP BY h.gametypeId ,hp.playerId ,h.seats ,hc_position - ,hp.tourneyTypeId + ,t.tourneyTypeId ,to_char(h.startTime, 'YYMMDD') """ else: # assume sqlite @@ -3347,7 +3348,7 @@ class Sql: when hp.position = '9' then 'E' else 'E' end AS hc_position - ,hp.tourneyTypeId + ,t.tourneyTypeId ,'d' || substr(strftime('%Y%m%d', h.startTime),3,7) ,count(1) ,sum(wonWhenSeenStreet1) @@ -3421,12 +3422,14 @@ class Sql: ,sum(CAST(hp.street4Raises as integer)) FROM HandsPlayers hp INNER JOIN Hands h ON (h.id = hp.handId) + INNER JOIN TourneysPlayers tp ON (tp.id = hp.tourneysPlayersId) + INNER JOIN Tourneys t ON (t.id = tp.tourneyId) GROUP BY h.gametypeId ,hp.playerId ,h.seats ,hc_position - ,hp.tourneyTypeId + ,t.tourneyTypeId ,'d' || substr(strftime('%Y%m%d', h.startTime),3,7) """ @@ -3698,8 +3701,6 @@ class Sql: AND speed=%s AND shootout=%s AND matrix=%s - AND added=%s - AND addedCurrency=%s """ self.query['insertTourneyType'] = """INSERT INTO TourneyTypes @@ -3860,7 +3861,6 @@ class Sql: street3Bets, street4Bets, position, - tourneyTypeId, tourneysPlayersId, startCards, street0_3BChance, @@ -3919,7 +3919,7 @@ class Sql: %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s + %s )""" ################################ diff --git a/pyfpdb/TourneyFilters.py b/pyfpdb/TourneyFilters.py index 977c94ec..774c64c7 100644 --- a/pyfpdb/TourneyFilters.py +++ b/pyfpdb/TourneyFilters.py @@ -63,68 +63,12 @@ class TourneyFilters(Filters.Filters): self.make_filter() #end def __init__ - 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 __refresh(self, widget, entry): + def __refresh(self, widget, entry): #identical with Filters for w in self.mainVBox.get_children(): w.destroy() self.make_filter() #end def __refresh - 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_tourneys(self, w, val): try: self.numTourneys = int(w.get_text()) @@ -133,25 +77,7 @@ class TourneyFilters(Filters.Filters): print "setting numTourneys:", self.numTourneys #end def __set_num_tourneys - 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]) ) - #end def __set_seat_select - - 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])) - #end def __set_site_select - - def __set_tourney_type_select(self, w, tourneyType): - #print w.get_active() - self.tourneyTypes[tourneyType] = w.get_active() - log.debug("self.tourney_types[%s] set to %s" %(tourneyType, self.tourneyTypes[tourneyType])) - #end def __set_tourney_type_select - - def __toggle_box(self, widget, entry): + def __toggle_box(self, widget, entry): #identical with Filters if self.boxes[entry].props.visible: self.boxes[entry].hide() widget.set_label("show") @@ -160,259 +86,6 @@ class TourneyFilters(Filters.Filters): widget.set_label("hide") #end def __toggle_box - 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) - #end def createPlayerLine - - 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) - #end def createSiteLine - - def createTourneyTypeLine(self, hbox, tourneyType): - cb = gtk.CheckButton(str(tourneyType)) - cb.connect('clicked', self.__set_tourney_type_select, tourneyType) - hbox.pack_start(cb, False, False, 0) - cb.set_active(True) - #end def createTourneyTypeLine - - 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 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) - - 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) - #end def fillPlayerFrame - - 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 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) - #end def fillSitesFrame - - def fillTourneyTypesFrame(self, vbox): - top_hbox = gtk.HBox(False, 0) - vbox.pack_start(top_hbox, False, False, 0) - lbl_title = gtk.Label(self.filterText['tourneyTypesTitle']) - 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, 'tourneyTypes') - top_hbox.pack_start(showb, expand=False, padding=1) - - vbox1 = gtk.VBox(False, 0) - vbox.pack_start(vbox1, False, False, 0) - self.boxes['tourneyTypes'] = vbox1 - - result = self.db.getTourneyTypesIds() - if len(result) >= 1: - for line in result: - hbox = gtk.HBox(False, 0) - vbox1.pack_start(hbox, False, True, 0) - self.createTourneyTypeLine(hbox, line[0]) - else: - print "INFO: No tourney types returned from database" - log.info("No tourney types returned from database") - #end def fillTourneyTypesFrame - - def getDates(self): - return self.__get_dates() - #end def getDates - - def getHeroes(self): - return self.heroes - #end def getHeroes - - def getNumTourneys(self): - return self.numTourneys - #end def getNumTourneys - - 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 getSiteIds(self): - return self.siteid - #end def getSiteIds - - def getSites(self): - return self.sites - #end def getSites - - def getTourneyTypes(self): - return self.tourneyTypes - #end def getTourneyTypes - - def get_vbox(self): - """returns the vbox of this thread""" - return self.mainVBox - #end def get_vbox - def make_filter(self): self.tourneyTypes = {} #self.tourneys = {} @@ -526,15 +199,4 @@ class TourneyFilters(Filters.Filters): # make sure any locks on db are released: self.db.rollback() #end def make_filter - - 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 #end class TourneyFilters diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index c90bca06..85519afc 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -107,7 +107,6 @@ import ImapFetcher import GuiRingPlayerStats import GuiTourneyPlayerStats import GuiPositionalStats -import GuiTableViewer import GuiAutoImport import GuiGraphViewer import GuiSessionViewer @@ -117,7 +116,7 @@ import Configuration import Exceptions import Stats -VERSION = "0.20.1 plus git" +VERSION = "0.20.901 plus git" class fpdb: @@ -306,8 +305,8 @@ class fpdb: dia.destroy() def dia_maintain_dbs(self, widget, data=None): - self.warning_box("Unimplemented: Maintain Databases") - return + #self.warning_box("Unimplemented: Maintain Databases") + #return if len(self.tab_names) == 1: if self.obtain_global_lock("dia_maintain_dbs"): # returns true if successful # only main tab has been opened, open dialog @@ -321,8 +320,14 @@ class fpdb: prefs = GuiDatabase.GuiDatabase(self.config, self.window, dia) response = dia.run() if response == gtk.RESPONSE_ACCEPT: + log.info('saving updated db data') # save updated config self.config.save() + self.load_profile() + for name in self.config.supported_databases: #db_ip/db_user/db_pass/db_server + log.info('fpdb: name,desc='+name+','+self.config.supported_databases[name].db_desc) + else: + log.info('guidb response was '+str(response)) self.release_global_lock() @@ -547,23 +552,14 @@ class fpdb: # self.release_global_lock() # lock_released = True self.db.recreate_tables() - # find any guibulkimport windows and clear player cache: + # find any guibulkimport/guiautoimport windows and clear player cache: for t in self.threads: - if isinstance(t, GuiBulkImport.GuiBulkImport): + if isinstance(t, GuiBulkImport.GuiBulkImport) or isinstance(t, GuiAutoImport.GuiAutoImport): t.importer.database.resetPlayerIDs() self.release_global_lock() #else: # for other dbs use same connection as holds global lock # self.fdb_lock.fdb.recreate_tables() - # TODO: figure out why this seems to be necessary - dia_restart = gtk.MessageDialog(parent=self.window, flags=0, type=gtk.MESSAGE_WARNING, - buttons=(gtk.BUTTONS_OK), message_format="Restart fpdb") - diastring = "Fpdb now needs to close. Please restart it." - dia_restart.format_secondary_text(diastring) - - dia_restart.run() - dia_restart.destroy() - self.quit(None, None) elif response == gtk.RESPONSE_NO: self.release_global_lock() print 'User cancelled recreating tables' @@ -801,7 +797,6 @@ class fpdb: - @@ -839,12 +834,11 @@ class fpdb: ('hudConfigurator', None, '_HUD Configurator', 'H', 'HUD Configurator', self.diaHudConfigurator), ('graphs', None, '_Graphs', 'G', 'Graphs', self.tabGraphViewer), ('ringplayerstats', None, 'Ring _Player Stats (tabulated view)', 'P', 'Ring Player Stats (tabulated view)', self.tab_ring_player_stats), - ('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view)', 'T', 'Tourney Player Stats (tabulated view)', self.tab_tourney_player_stats), + ('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view, mysql only)', 'T', 'Tourney Player Stats (tabulated view, mysql only)', self.tab_tourney_player_stats), ('posnstats', None, 'P_ositional Stats (tabulated view)', 'O', 'Positional Stats (tabulated view)', self.tab_positional_stats), ('sessionstats', None, 'Session Stats', None, 'Session Stats', self.tab_session_stats), - ('tableviewer', None, 'Poker_table Viewer (mostly obselete)', None, 'Poker_table Viewer (mostly obselete)', self.tab_table_viewer), ('database', None, '_Database'), - ('maintaindbs', None, '_Maintain Databases (todo)', None, 'Maintain Databases', self.dia_maintain_dbs), + ('maintaindbs', None, '_Maintain Databases', None, 'Maintain Databases', self.dia_maintain_dbs), ('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables), ('rebuildhudcache', None, 'Rebuild HUD Cache', None, 'Rebuild HUD Cache', self.dia_recreate_hudcache), ('rebuildindexes', None, 'Rebuild DB Indexes', None, 'Rebuild DB Indexes', self.dia_rebuild_indexes), @@ -1071,13 +1065,6 @@ This program is free/libre open source software licensed partially under the AGP You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt and gpl-3.0.txt in the fpdb installation directory.""") self.add_and_display_tab(mh_tab, "Help") - def tab_table_viewer(self, widget, data=None): - """opens a table viewer tab""" - new_tv_thread = GuiTableViewer.GuiTableViewer(self.db, self.settings, self.config) - self.threads.append(new_tv_thread) - tv_tab = new_tv_thread.get_vbox() - self.add_and_display_tab(tv_tab, "Table Viewer") - def tabGraphViewer(self, widget, data=None): """opens a graph viewer tab""" new_gv_thread = GuiGraphViewer.GuiGraphViewer(self.sql, self.config, self.window) diff --git a/pyfpdb/logging.conf b/pyfpdb/logging.conf index ecd74fcc..57a74008 100644 --- a/pyfpdb/logging.conf +++ b/pyfpdb/logging.conf @@ -1,5 +1,5 @@ [loggers] -keys=root,fpdb,logview,parser,importer,config,db,hud,filter +keys=root,fpdb,logview,parser,importer,config,db,hud,filter,maintdbs [handlers] keys=consoleHandler,rotatingFileHandler @@ -17,6 +17,12 @@ handlers=consoleHandler,rotatingFileHandler qualname=fpdb propagate=0 +[logger_maintdbs] +level=INFO +handlers=consoleHandler,rotatingFileHandler +qualname=maintdbs +propagate=0 + [logger_logview] level=INFO handlers=consoleHandler,rotatingFileHandler diff --git a/setup.py b/setup.py index bdf5560d..83e46a0c 100644 --- a/setup.py +++ b/setup.py @@ -13,14 +13,12 @@ from distutils.core import setup setup(name = 'fpdb', description = 'Free Poker Database', - version = '0.12', + version = '0.20', author = 'FPDB team', author_email = 'fpdb-main@lists.sourceforge.net', packages = ['fpdb'], package_dir = { 'fpdb' : 'pyfpdb' }, data_files = [ - ('/usr/share/doc/python-fpdb', - ['THANKS.txt']), ('/usr/share/pixmaps', ['gfx/fpdb-icon.png', 'gfx/fpdb-icon2.png', 'gfx/fpdb-cards.png'