Merge git://git.assembla.com/fpdboz
This commit is contained in:
		
						commit
						acb4160969
					
				| 
						 | 
					@ -580,6 +580,42 @@ class FpdbSQLQueries:
 | 
				
			||||||
		elif(self.dbname == 'SQLite'):
 | 
							elif(self.dbname == 'SQLite'):
 | 
				
			||||||
			self.query['createHudCacheTable'] = """ """
 | 
								self.query['createHudCacheTable'] = """ """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							################################
 | 
				
			||||||
 | 
							# Queries used in GuiGraphViewer
 | 
				
			||||||
 | 
							################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# Returns all cash game handIds and the money won(winnings is the final pot)
 | 
				
			||||||
 | 
							# by the playerId for a single site.
 | 
				
			||||||
 | 
							if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
 | 
				
			||||||
 | 
								self.query['getRingWinningsAllGamesPlayerIdSite'] = """SELECT handId, winnings FROM HandsPlayers 
 | 
				
			||||||
 | 
										INNER JOIN Players ON HandsPlayers.playerId = Players.id 
 | 
				
			||||||
 | 
										INNER JOIN Hands ON Hands.id = HandsPlayers.handId
 | 
				
			||||||
 | 
										WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
 | 
				
			||||||
 | 
										ORDER BY handStart"""
 | 
				
			||||||
 | 
							elif(self.dbname == 'SQLite'):
 | 
				
			||||||
 | 
								#Probably doesn't work.
 | 
				
			||||||
 | 
								self.query['getRingWinningsAllGamesPlayerIdSite'] = """SELECT handId, winnings FROM HandsPlayers
 | 
				
			||||||
 | 
										INNER JOIN Players ON HandsPlayers.playerId = Players.id 
 | 
				
			||||||
 | 
										INNER JOIN Hands ON Hands.id = HandsPlayers.handId
 | 
				
			||||||
 | 
										WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
 | 
				
			||||||
 | 
										ORDER BY handStart"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# Returns the profit for a given ring game handId, Total pot - money invested by playerId
 | 
				
			||||||
 | 
							if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
 | 
				
			||||||
 | 
								self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
 | 
				
			||||||
 | 
										INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
 | 
				
			||||||
 | 
										INNER JOIN Players ON HandsPlayers.playerId = Players.id 
 | 
				
			||||||
 | 
										WHERE Players.name = %s AND HandsPlayers.handId = %s 
 | 
				
			||||||
 | 
										AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
 | 
				
			||||||
 | 
							elif(self.dbname == 'SQLite'):
 | 
				
			||||||
 | 
								#Probably doesn't work.
 | 
				
			||||||
 | 
								self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
 | 
				
			||||||
 | 
										INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
 | 
				
			||||||
 | 
										INNER JOIN Players ON HandsPlayers.playerId = Players.id 
 | 
				
			||||||
 | 
										WHERE Players.name = %s AND HandsPlayers.handId = %s 
 | 
				
			||||||
 | 
										AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__== "__main__":
 | 
					if __name__== "__main__":
 | 
				
			||||||
        from optparse import OptionParser
 | 
					        from optparse import OptionParser
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ class GuiAutoImport (threading.Thread):
 | 
				
			||||||
				self.inputFile = os.path.join(self.path, file)
 | 
									self.inputFile = os.path.join(self.path, file)
 | 
				
			||||||
				stat_info = os.stat(self.inputFile)
 | 
									stat_info = os.stat(self.inputFile)
 | 
				
			||||||
				if not self.import_files.has_key(self.inputFile) or stat_info.st_mtime > self.import_files[self.inputFile]:
 | 
									if not self.import_files.has_key(self.inputFile) or stat_info.st_mtime > self.import_files[self.inputFile]:
 | 
				
			||||||
				    fpdb_import.import_file_dict(self, self.settings, callHud = True)
 | 
									    self.importer.import_file_dict(self, self.settings)
 | 
				
			||||||
				    self.import_files[self.inputFile] = stat_info.st_mtime
 | 
									    self.import_files[self.inputFile] = stat_info.st_mtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		print "GuiAutoImport.import_dir done"
 | 
							print "GuiAutoImport.import_dir done"
 | 
				
			||||||
| 
						 | 
					@ -121,6 +121,8 @@ class GuiAutoImport (threading.Thread):
 | 
				
			||||||
	def __init__(self, settings, debug=True):
 | 
						def __init__(self, settings, debug=True):
 | 
				
			||||||
		"""Constructor for GuiAutoImport"""
 | 
							"""Constructor for GuiAutoImport"""
 | 
				
			||||||
		self.settings=settings
 | 
							self.settings=settings
 | 
				
			||||||
 | 
							self.importer = fpdb_import.Importer()
 | 
				
			||||||
 | 
							self.importer.setCallHud(True)
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		self.server=settings['db-host']
 | 
							self.server=settings['db-host']
 | 
				
			||||||
		self.user=settings['db-user']
 | 
							self.user=settings['db-user']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ class GuiBulkImport (threading.Thread):
 | 
				
			||||||
				print "BulkImport is not recursive - please select the final directory in which the history files are"
 | 
									print "BulkImport is not recursive - please select the final directory in which the history files are"
 | 
				
			||||||
			else:
 | 
								else:
 | 
				
			||||||
				self.inputFile=self.path+os.sep+file
 | 
									self.inputFile=self.path+os.sep+file
 | 
				
			||||||
				fpdb_import.import_file_dict(self, self.settings, False)
 | 
									self.importer.import_file_dict(self, self.settings)
 | 
				
			||||||
		print "GuiBulkImport.import_dir done"
 | 
							print "GuiBulkImport.import_dir done"
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
	def load_clicked(self, widget, data=None):
 | 
						def load_clicked(self, widget, data=None):
 | 
				
			||||||
| 
						 | 
					@ -69,7 +69,7 @@ class GuiBulkImport (threading.Thread):
 | 
				
			||||||
		if os.path.isdir(self.inputFile):
 | 
							if os.path.isdir(self.inputFile):
 | 
				
			||||||
			self.import_dir()
 | 
								self.import_dir()
 | 
				
			||||||
		else:
 | 
							else:
 | 
				
			||||||
			fpdb_import.import_file_dict(self, self.settings, False)
 | 
								self.importer.import_file_dict(self, self.settings)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	def get_vbox(self):
 | 
						def get_vbox(self):
 | 
				
			||||||
		"""returns the vbox of this thread"""
 | 
							"""returns the vbox of this thread"""
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,7 @@ class GuiBulkImport (threading.Thread):
 | 
				
			||||||
	def __init__(self, db, settings):
 | 
						def __init__(self, db, settings):
 | 
				
			||||||
		self.db=db
 | 
							self.db=db
 | 
				
			||||||
		self.settings=settings
 | 
							self.settings=settings
 | 
				
			||||||
 | 
							self.importer = fpdb_import.Importer()
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		self.vbox=gtk.VBox(False,1)
 | 
							self.vbox=gtk.VBox(False,1)
 | 
				
			||||||
		self.vbox.show()
 | 
							self.vbox.show()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,30 +69,12 @@ class GuiGraphViewer (threading.Thread):
 | 
				
			||||||
		self.ax.set_xlabel("Hands", fontsize = 12)
 | 
							self.ax.set_xlabel("Hands", fontsize = 12)
 | 
				
			||||||
		self.ax.set_ylabel("$", fontsize = 12)
 | 
							self.ax.set_ylabel("$", fontsize = 12)
 | 
				
			||||||
		self.ax.grid(color='g', linestyle=':', linewidth=0.2)
 | 
							self.ax.grid(color='g', linestyle=':', linewidth=0.2)
 | 
				
			||||||
 | 
					 | 
				
			||||||
		self.cursor.execute("""SELECT handId, winnings FROM HandsPlayers
 | 
					 | 
				
			||||||
				INNER JOIN Players ON HandsPlayers.playerId = Players.id 
 | 
					 | 
				
			||||||
				INNER JOIN Hands ON Hands.id = HandsPlayers.handId
 | 
					 | 
				
			||||||
				WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
 | 
					 | 
				
			||||||
				ORDER BY siteHandNo""", (name, site))
 | 
					 | 
				
			||||||
		winnings = self.db.cursor.fetchall()
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
		profit=range(len(winnings))
 | 
					 | 
				
			||||||
		for i in profit:
 | 
					 | 
				
			||||||
			self.cursor.execute("""SELECT SUM(amount) FROM HandsActions
 | 
					 | 
				
			||||||
					INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
 | 
					 | 
				
			||||||
					INNER JOIN Players ON HandsPlayers.playerId = Players.id 
 | 
					 | 
				
			||||||
					WHERE Players.name = %s AND HandsPlayers.handId = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)""", (name, winnings[i][0], site))
 | 
					 | 
				
			||||||
			spent = self.db.cursor.fetchone()
 | 
					 | 
				
			||||||
			profit[i]=(i, winnings[i][1]-spent[0])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		y=map(lambda x:float(x[1]), profit)
 | 
					 | 
				
			||||||
		line = cumsum(y)
 | 
					 | 
				
			||||||
		line = line/100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		self.ax.annotate ("All Hands, Site %s", (61,25), xytext =(0.1, 0.9) , textcoords ="axes fraction" ,)
 | 
							self.ax.annotate ("All Hands, Site %s", (61,25), xytext =(0.1, 0.9) , textcoords ="axes fraction" ,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#Now draw plot
 | 
							#Get graph data from DB
 | 
				
			||||||
 | 
							line = self.getRingProfitGraph(name, site)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#Draw plot
 | 
				
			||||||
		self.ax.plot(line,)
 | 
							self.ax.plot(line,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.canvas = FigureCanvas(self.fig)  # a gtk.DrawingArea
 | 
							self.canvas = FigureCanvas(self.fig)  # a gtk.DrawingArea
 | 
				
			||||||
| 
						 | 
					@ -100,13 +82,29 @@ class GuiGraphViewer (threading.Thread):
 | 
				
			||||||
		self.canvas.show()
 | 
							self.canvas.show()
 | 
				
			||||||
	#end of def showClicked
 | 
						#end of def showClicked
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def __init__(self, db, settings, debug=True):
 | 
						def getRingProfitGraph(self, name, site):
 | 
				
			||||||
 | 
					                self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site))
 | 
				
			||||||
 | 
					                winnings = self.db.cursor.fetchall()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                profit=range(len(winnings))
 | 
				
			||||||
 | 
					                for i in profit:
 | 
				
			||||||
 | 
					                        self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site))
 | 
				
			||||||
 | 
					                        spent = self.db.cursor.fetchone()
 | 
				
			||||||
 | 
					                        profit[i]=(i, winnings[i][1]-spent[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                y=map(lambda x:float(x[1]), profit)
 | 
				
			||||||
 | 
					                line = cumsum(y)
 | 
				
			||||||
 | 
					                return line/100
 | 
				
			||||||
 | 
					        #end of def getRingProfitGraph
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def __init__(self, db, settings, querylist, debug=True):
 | 
				
			||||||
		"""Constructor for GraphViewer"""
 | 
							"""Constructor for GraphViewer"""
 | 
				
			||||||
		self.debug=debug
 | 
							self.debug=debug
 | 
				
			||||||
		#print "start of GraphViewer constructor"
 | 
							#print "start of GraphViewer constructor"
 | 
				
			||||||
		self.db=db
 | 
							self.db=db
 | 
				
			||||||
		self.cursor=db.cursor
 | 
							self.cursor=db.cursor
 | 
				
			||||||
		self.settings=settings
 | 
							self.settings=settings
 | 
				
			||||||
 | 
							self.sql=querylist
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
		self.mainVBox = gtk.VBox(False, 0)
 | 
							self.mainVBox = gtk.VBox(False, 0)
 | 
				
			||||||
		self.mainVBox.show()
 | 
							self.mainVBox.show()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,8 +255,9 @@ class GuiTableViewer (threading.Thread):
 | 
				
			||||||
		self.failOnError=False
 | 
							self.failOnError=False
 | 
				
			||||||
		self.minPrint=0
 | 
							self.minPrint=0
 | 
				
			||||||
		self.handCount=0
 | 
							self.handCount=0
 | 
				
			||||||
 | 
							self.importer = fpdb_import.Importer()
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		self.last_read_hand_id=fpdb_import.import_file_dict(self, self.settings, False)
 | 
							self.last_read_hand_id=importer.import_file_dict(self, self.settings)
 | 
				
			||||||
	#end def table_viewer.import_clicked
 | 
						#end def table_viewer.import_clicked
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def all_clicked(self, widget, data):
 | 
						def all_clicked(self, widget, data):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,19 +57,19 @@ class TestSequenceFunctions(unittest.TestCase):
 | 
				
			||||||
		print self.pgdict.query['list_tables']
 | 
							print self.pgdict.query['list_tables']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
 | 
							self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
 | 
				
			||||||
                self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
 | 
							self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def testMySQLRecreateTables(self):
 | 
						def testMySQLRecreateTables(self):
 | 
				
			||||||
		"""Test droping then recreating fpdb table schema"""
 | 
							"""Test droping then recreating fpdb table schema"""
 | 
				
			||||||
		self.mysql_db.recreate_tables()
 | 
							self.mysql_db.recreate_tables()
 | 
				
			||||||
		self.result = self.mysql_db.cursor.execute("SHOW TABLES")
 | 
							self.result = self.mysql_db.cursor.execute("SHOW TABLES")
 | 
				
			||||||
                self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
 | 
							self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def testPostgresSQLRecreateTables(self):
 | 
						def testPostgresSQLRecreateTables(self):
 | 
				
			||||||
		"""Test droping then recreating fpdb table schema"""
 | 
							"""Test droping then recreating fpdb table schema"""
 | 
				
			||||||
		self.pg_db.recreate_tables()
 | 
							self.pg_db.recreate_tables()
 | 
				
			||||||
		self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
 | 
							self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
 | 
				
			||||||
                self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
 | 
							self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
        unittest.main()
 | 
					        unittest.main()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@ import GuiBulkImport
 | 
				
			||||||
import GuiTableViewer
 | 
					import GuiTableViewer
 | 
				
			||||||
import GuiAutoImport
 | 
					import GuiAutoImport
 | 
				
			||||||
import GuiGraphViewer
 | 
					import GuiGraphViewer
 | 
				
			||||||
 | 
					import FpdbSQLQueries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class fpdb:
 | 
					class fpdb:
 | 
				
			||||||
	def tab_clicked(self, widget, tab_name):
 | 
						def tab_clicked(self, widget, tab_name):
 | 
				
			||||||
| 
						 | 
					@ -344,6 +345,9 @@ class fpdb:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			response = diaDbVersionWarning.run()
 | 
								response = diaDbVersionWarning.run()
 | 
				
			||||||
			diaDbVersionWarning.destroy()
 | 
								diaDbVersionWarning.destroy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# Database connected to successfully, load queries to pass on to other classes
 | 
				
			||||||
 | 
					                self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
 | 
				
			||||||
	#end def load_profile
 | 
						#end def load_profile
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	def not_implemented(self):
 | 
						def not_implemented(self):
 | 
				
			||||||
| 
						 | 
					@ -408,7 +412,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
 | 
				
			||||||
	def tabGraphViewer(self, widget, data):
 | 
						def tabGraphViewer(self, widget, data):
 | 
				
			||||||
		"""opens a graph viewer tab"""
 | 
							"""opens a graph viewer tab"""
 | 
				
			||||||
		#print "start of tabGraphViewer"
 | 
							#print "start of tabGraphViewer"
 | 
				
			||||||
		new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings)
 | 
							new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings,self.querydict)
 | 
				
			||||||
		self.threads.append(new_gv_thread)
 | 
							self.threads.append(new_gv_thread)
 | 
				
			||||||
		gv_tab=new_gv_thread.get_vbox()
 | 
							gv_tab=new_gv_thread.get_vbox()
 | 
				
			||||||
		self.add_and_display_tab(gv_tab, "Graphs")
 | 
							self.add_and_display_tab(gv_tab, "Graphs")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,57 +37,64 @@ import datetime
 | 
				
			||||||
import fpdb_simple
 | 
					import fpdb_simple
 | 
				
			||||||
import fpdb_parse_logic
 | 
					import fpdb_parse_logic
 | 
				
			||||||
from optparse import OptionParser
 | 
					from optparse import OptionParser
 | 
				
			||||||
 | 
					from time import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Importer:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def import_file(server, database, user, password, inputFile):
 | 
						def __init__(self):
 | 
				
			||||||
	self.server=server
 | 
							"""Constructor"""
 | 
				
			||||||
	self.database=database
 | 
							self.settings={'imp-callFpdbHud':False}
 | 
				
			||||||
	self.user=user
 | 
							self.db = None
 | 
				
			||||||
	self.password=password
 | 
							self.cursor = None
 | 
				
			||||||
	self.inputFile=inputFile
 | 
							self.options = None
 | 
				
			||||||
	self.settings={'imp-callFpdbHud':False}
 | 
							self.callHud = False
 | 
				
			||||||
	import_file_dict(self, settings)
 | 
							self.lines = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def import_file_dict(options, settings, callHud=False):
 | 
						def dbConnect(self, options, settings):
 | 
				
			||||||
 | 
							#connect to DB
 | 
				
			||||||
 | 
							if settings['db-backend'] == 2:
 | 
				
			||||||
 | 
								if not mysqlLibFound:
 | 
				
			||||||
 | 
									raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
 | 
				
			||||||
 | 
								self.db = MySQLdb.connect(host = options.server, user = options.user,
 | 
				
			||||||
 | 
												passwd = options.password, db = options.database)
 | 
				
			||||||
 | 
							elif settings['db-backend'] == 3:
 | 
				
			||||||
 | 
								if not pgsqlLibFound:
 | 
				
			||||||
 | 
									raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
 | 
				
			||||||
 | 
								self.db = psycopg2.connect(host = options.server, user = options.user,
 | 
				
			||||||
 | 
													  password = options.password, database = options.database)
 | 
				
			||||||
 | 
							elif settings['db-backend'] == 4:
 | 
				
			||||||
 | 
								pass
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								pass
 | 
				
			||||||
 | 
							self.cursor = self.db.cursor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def setCallHud(self, value):
 | 
				
			||||||
 | 
							self.callHud = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def import_file_dict(self, options, settings):
 | 
				
			||||||
 | 
							starttime = time()
 | 
				
			||||||
		last_read_hand=0
 | 
							last_read_hand=0
 | 
				
			||||||
		if (options.inputFile=="stdin"):
 | 
							if (options.inputFile=="stdin"):
 | 
				
			||||||
			inputFile=sys.stdin
 | 
								inputFile=sys.stdin
 | 
				
			||||||
		else:
 | 
							else:
 | 
				
			||||||
			inputFile=open(options.inputFile, "rU")
 | 
								inputFile=open(options.inputFile, "rU")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#connect to DB
 | 
							self.dbConnect(options,settings)
 | 
				
			||||||
		if settings['db-backend'] == 2:
 | 
					 | 
				
			||||||
			if not mysqlLibFound:
 | 
					 | 
				
			||||||
				raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
 | 
					 | 
				
			||||||
			db = MySQLdb.connect(host = options.server, user = options.user,
 | 
					 | 
				
			||||||
							passwd = options.password, db = options.database)
 | 
					 | 
				
			||||||
		elif settings['db-backend'] == 3:
 | 
					 | 
				
			||||||
			if not pgsqlLibFound:
 | 
					 | 
				
			||||||
				raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
 | 
					 | 
				
			||||||
			db = psycopg2.connect(host = options.server, user = options.user,
 | 
					 | 
				
			||||||
								  password = options.password, database = options.database)
 | 
					 | 
				
			||||||
		elif settings['db-backend'] == 4:
 | 
					 | 
				
			||||||
			pass
 | 
					 | 
				
			||||||
		else:
 | 
					 | 
				
			||||||
			pass
 | 
					 | 
				
			||||||
		cursor = db.cursor()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (not options.quiet):
 | 
							# Read input file into class and close file
 | 
				
			||||||
			print "Opened file", options.inputFile, "and connected to MySQL on", options.server
 | 
							self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
 | 
				
			||||||
 | 
							inputFile.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		line=inputFile.readline()
 | 
							firstline = self.lines[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if line.find("Tournament Summary")!=-1:
 | 
							if firstline.find("Tournament Summary")!=-1:
 | 
				
			||||||
			print "TODO: implement importing tournament summaries"
 | 
								print "TODO: implement importing tournament summaries"
 | 
				
			||||||
			inputFile.close()
 | 
								self.cursor.close()
 | 
				
			||||||
			cursor.close()
 | 
								self.db.close()
 | 
				
			||||||
			db.close()
 | 
					 | 
				
			||||||
			return 0
 | 
								return 0
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		site=fpdb_simple.recogniseSite(line)
 | 
							site=fpdb_simple.recogniseSite(firstline)
 | 
				
			||||||
		category=fpdb_simple.recogniseCategory(line)
 | 
							category=fpdb_simple.recogniseCategory(firstline)
 | 
				
			||||||
		inputFile.seek(0)
 | 
					 | 
				
			||||||
		lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		startpos=0
 | 
							startpos=0
 | 
				
			||||||
		stored=0 #counter
 | 
							stored=0 #counter
 | 
				
			||||||
| 
						 | 
					@ -95,10 +102,10 @@ def import_file_dict(options, settings, callHud=False):
 | 
				
			||||||
		partial=0 #counter
 | 
							partial=0 #counter
 | 
				
			||||||
		errors=0 #counter
 | 
							errors=0 #counter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for i in range (len(lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
 | 
							for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
 | 
				
			||||||
			if (len(lines[i])<2):
 | 
								if (len(self.lines[i])<2):
 | 
				
			||||||
				endpos=i
 | 
									endpos=i
 | 
				
			||||||
				hand=lines[startpos:endpos]
 | 
									hand=self.lines[startpos:endpos]
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
				if (len(hand[0])<2):
 | 
									if (len(hand[0])<2):
 | 
				
			||||||
					hand=hand[1:]
 | 
										hand=hand[1:]
 | 
				
			||||||
| 
						 | 
					@ -131,13 +138,13 @@ def import_file_dict(options, settings, callHud=False):
 | 
				
			||||||
					hand=fpdb_simple.filterCrap(site, hand, isTourney)
 | 
										hand=fpdb_simple.filterCrap(site, hand, isTourney)
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
					try:
 | 
										try:
 | 
				
			||||||
						handsId=fpdb_parse_logic.mainParser(db, cursor, site, category, hand)
 | 
											handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
 | 
				
			||||||
						db.commit()
 | 
											self.db.commit()
 | 
				
			||||||
						
 | 
											
 | 
				
			||||||
						stored+=1
 | 
											stored+=1
 | 
				
			||||||
						db.commit()
 | 
											self.db.commit()
 | 
				
			||||||
#						if settings['imp-callFpdbHud'] and callHud and os.sep=='/':
 | 
					#						if settings['imp-callFpdbHud'] and self.callHud and os.sep=='/':
 | 
				
			||||||
						if settings['imp-callFpdbHud'] and callHud:
 | 
											if settings['imp-callFpdbHud'] and self.callHud:
 | 
				
			||||||
							#print "call to HUD here. handsId:",handsId
 | 
												#print "call to HUD here. handsId:",handsId
 | 
				
			||||||
							#pipe the Hands.id out to the HUD
 | 
												#pipe the Hands.id out to the HUD
 | 
				
			||||||
#							options.pipe_to_hud.write("%s" % (handsId) + os.linesep)
 | 
					#							options.pipe_to_hud.write("%s" % (handsId) + os.linesep)
 | 
				
			||||||
| 
						 | 
					@ -146,31 +153,24 @@ def import_file_dict(options, settings, callHud=False):
 | 
				
			||||||
						duplicates+=1
 | 
											duplicates+=1
 | 
				
			||||||
					except (ValueError), fe:
 | 
										except (ValueError), fe:
 | 
				
			||||||
						errors+=1
 | 
											errors+=1
 | 
				
			||||||
						print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
 | 
											self.printEmailErrorMessage(errors, options.inputFile, hand[0])
 | 
				
			||||||
						print "Filename:",options.inputFile
 | 
					 | 
				
			||||||
						print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
 | 
					 | 
				
			||||||
						print hand[0]
 | 
					 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
						if (options.failOnError):
 | 
											if (options.failOnError):
 | 
				
			||||||
							db.commit() #dont remove this, in case hand processing was cancelled this ties up any open ends.
 | 
												self.db.commit() #dont remove this, in case hand processing was cancelled this ties up any open ends.
 | 
				
			||||||
							inputFile.close()
 | 
												self.cursor.close()
 | 
				
			||||||
							cursor.close()
 | 
												self.db.close()
 | 
				
			||||||
							db.close()
 | 
					 | 
				
			||||||
							raise
 | 
												raise
 | 
				
			||||||
					except (fpdb_simple.FpdbError), fe:
 | 
										except (fpdb_simple.FpdbError), fe:
 | 
				
			||||||
						errors+=1
 | 
											errors+=1
 | 
				
			||||||
						print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
 | 
											self.printEmailErrorMessage(errors, options.inputFile, hand[0])
 | 
				
			||||||
						print "Filename:",options.inputFile
 | 
					
 | 
				
			||||||
						print "Here is the first line so you can identify it."
 | 
					 | 
				
			||||||
						print hand[0]
 | 
					 | 
				
			||||||
						#fe.printStackTrace() #todo: get stacktrace
 | 
											#fe.printStackTrace() #todo: get stacktrace
 | 
				
			||||||
						db.rollback()
 | 
											self.db.rollback()
 | 
				
			||||||
						
 | 
											
 | 
				
			||||||
						if (options.failOnError):
 | 
											if (options.failOnError):
 | 
				
			||||||
							db.commit() #dont remove this, in case hand processing was cancelled this ties up any open ends.
 | 
												self.db.commit() #dont remove this, in case hand processing was cancelled this ties up any open ends.
 | 
				
			||||||
							inputFile.close()
 | 
												self.cursor.close()
 | 
				
			||||||
							cursor.close()
 | 
												self.db.close()
 | 
				
			||||||
							db.close()
 | 
					 | 
				
			||||||
							raise
 | 
												raise
 | 
				
			||||||
					if (options.minPrint!=0):
 | 
										if (options.minPrint!=0):
 | 
				
			||||||
						if ((stored+duplicates+partial+errors)%options.minPrint==0):
 | 
											if ((stored+duplicates+partial+errors)%options.minPrint==0):
 | 
				
			||||||
| 
						 | 
					@ -180,54 +180,33 @@ def import_file_dict(options, settings, callHud=False):
 | 
				
			||||||
						if ((stored+duplicates+partial+errors)>=options.handCount):
 | 
											if ((stored+duplicates+partial+errors)>=options.handCount):
 | 
				
			||||||
							if (not options.quiet):
 | 
												if (not options.quiet):
 | 
				
			||||||
								print "quitting due to reaching the amount of hands to be imported"
 | 
													print "quitting due to reaching the amount of hands to be imported"
 | 
				
			||||||
								print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:", partial, "errors:", errors
 | 
													print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:", partial, "errors:", errors, " time:", (time() - starttime)
 | 
				
			||||||
							sys.exit(0)
 | 
												sys.exit(0)
 | 
				
			||||||
				startpos=endpos
 | 
									startpos=endpos
 | 
				
			||||||
		print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
 | 
							print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time:", (time() - starttime)
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		if stored==0:
 | 
							if stored==0:
 | 
				
			||||||
			if duplicates>0:
 | 
								if duplicates>0:
 | 
				
			||||||
				for line_no in range(len(lines)):
 | 
									for line_no in range(len(self.lines)):
 | 
				
			||||||
					if lines[line_no].find("Game #")!=-1:
 | 
										if self.lines[line_no].find("Game #")!=-1:
 | 
				
			||||||
						final_game_line=lines[line_no]
 | 
											final_game_line=self.lines[line_no]
 | 
				
			||||||
				handsId=fpdb_simple.parseSiteHandNo(final_game_line)
 | 
									handsId=fpdb_simple.parseSiteHandNo(final_game_line)
 | 
				
			||||||
			else:
 | 
								else:
 | 
				
			||||||
				print "failed to read a single hand from file:", inputFile
 | 
									print "failed to read a single hand from file:", inputFile
 | 
				
			||||||
				handsId=0
 | 
									handsId=0
 | 
				
			||||||
			#todo: this will cause return of an unstored hand number if the last hand was error or partial
 | 
								#todo: this will cause return of an unstored hand number if the last hand was error or partial
 | 
				
			||||||
		db.commit()
 | 
							self.db.commit()
 | 
				
			||||||
		inputFile.close()
 | 
							self.cursor.close()
 | 
				
			||||||
		cursor.close()
 | 
							self.db.close()
 | 
				
			||||||
		db.close()
 | 
					 | 
				
			||||||
		return handsId
 | 
							return handsId
 | 
				
			||||||
#end def import_file_dict
 | 
					#end def import_file_dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def printEmailErrorMessage(self, errors, filename, line):
 | 
				
			||||||
 | 
							print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
 | 
				
			||||||
 | 
							print "Filename:",options.inputFile
 | 
				
			||||||
 | 
							print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
 | 
				
			||||||
 | 
							print hand[0]
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
	failOnError=False
 | 
						print "CLI for fpdb_import is currently on vacation please check in later"
 | 
				
			||||||
	quiet=False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	#process CLI parameters
 | 
					 | 
				
			||||||
	parser = OptionParser()
 | 
					 | 
				
			||||||
	parser.add_option("-c", "--handCount", default="0", type="int",
 | 
					 | 
				
			||||||
					help="Number of hands to import (default 0 means unlimited)")
 | 
					 | 
				
			||||||
	parser.add_option("-d", "--database", default="fpdb", help="The MySQL database to use (default fpdb)")
 | 
					 | 
				
			||||||
	parser.add_option("-e", "--errorFile", default="failed.txt", 
 | 
					 | 
				
			||||||
					help="File to store failed hands into. (default: failed.txt) Not implemented.")
 | 
					 | 
				
			||||||
	parser.add_option("-f", "--inputFile", "--file", "--inputfile", default="stdin", 
 | 
					 | 
				
			||||||
					help="The file you want to import (remember to use quotes if necessary)")
 | 
					 | 
				
			||||||
	parser.add_option("-m", "--minPrint", "--status", default="50", type="int",
 | 
					 | 
				
			||||||
					help="How often to print a one-line status report (0 means never, default is 50)")
 | 
					 | 
				
			||||||
	parser.add_option("-p", "--password", help="The password for the MySQL user")
 | 
					 | 
				
			||||||
	parser.add_option("-q", "--quiet", action="store_true",
 | 
					 | 
				
			||||||
					help="If this is passed it doesn't print a total at the end nor the opening line. Note that this purposely does NOT change --minPrint")
 | 
					 | 
				
			||||||
	parser.add_option("-s", "--server", default="localhost",
 | 
					 | 
				
			||||||
					help="Hostname/IP of the MySQL server (default localhost)")
 | 
					 | 
				
			||||||
	parser.add_option("-u", "--user", default="fpdb", help="The MySQL username (default fpdb)")
 | 
					 | 
				
			||||||
	parser.add_option("-x", "--failOnError", action="store_true",
 | 
					 | 
				
			||||||
					help="If this option is passed it quits when it encounters any error")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(options, sys.argv) = parser.parse_args()
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	settings={'imp-callFpdbHud':False, 'db-backend':2}
 | 
					 | 
				
			||||||
	import_file_dict(options, settings, False)
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user