Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
		
						commit
						485180779f
					
				
							
								
								
									
										92
									
								
								gfx/img-PokerStars-Small.xpm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								gfx/img-PokerStars-Small.xpm
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | |||
| /* XPM */ | ||||
| /* C:\Program Files\PokerStars\PokerStarsUpdate.exe */ | ||||
| static char *icon[] = { | ||||
| "48 48 40 2", | ||||
| "01 c #800000", | ||||
| "08 c #C0DCC0", | ||||
| "4C c #7F1F00", | ||||
| "6C c #AA0000", | ||||
| "6D c #AA0055", | ||||
| "70 c #AA1F00", | ||||
| "90 c #D40000", | ||||
| "91 c #D40055", | ||||
| "94 c #D41F00", | ||||
| "95 c #D41F55", | ||||
| "99 c #D43F55", | ||||
| "9D c #D45F55", | ||||
| "9E c #D45FAA", | ||||
| "A1 c #D47F55", | ||||
| "A2 c #D47FAA", | ||||
| "A5 c #D49F55", | ||||
| "A6 c #D49FAA", | ||||
| "AA c #D4BFAA", | ||||
| "AE c #D4DFAA", | ||||
| "AF c #D4DFFF", | ||||
| "B4 c #FF0055", | ||||
| "B6 c #FF1F00", | ||||
| "B7 c #FF1F55", | ||||
| "BA c #FF3F00", | ||||
| "BB c #FF3F55", | ||||
| "BE c #FF5F00", | ||||
| "BF c #FF5F55", | ||||
| "C3 c #FF7F55", | ||||
| "C4 c #FF7FAA", | ||||
| "C7 c #FF9F55", | ||||
| "C8 c #FF9FAA", | ||||
| "CC c #FFBFAA", | ||||
| "CD c #FFBFFF", | ||||
| "D0 c #FFDFAA", | ||||
| "D1 c #FFDFFF", | ||||
| "D5 c #FFCCFF", | ||||
| "F6 c #FFFBF0", | ||||
| "F9 c #FF0000", | ||||
| "FF c #FFFFFF", | ||||
| "   c None", | ||||
| "707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C", | ||||
| "6CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAD1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6949DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6BFBBF999F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "6CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A6A2C7B6F9F99DD1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A2C8CCBFB6B4F99099F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6C8CCC3BEB7F9F9F99099F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2C8D0C7BFBBB6F9B4F9F99099F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "6CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A6AAD0C8C3C3BBF9F9F9F9B4F99099D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFA6C8D0CCC7C3BFBAB6B4F9F9F99090909DF6FFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFA2CCF6CCC8C3BFBEBBF9F9F9B4F9F9B4909099F6FFFFFFFFFFFFFFFFFFFFFFFFFF6C", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFA6CCD1CCC7C3C3BFBAB6B7F9F9F9B490F990906C99FFFFFFD1FFFFFFD1FFFFFFD1FF70", | ||||
| "6CFFFFFFFFFFFFFFFFFFFFFFAAC8F6CCC7C8C3BFBFBFB6C4B7F9F9F9F9F99190906C9DFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFD1FFFFFFD1FFFFFFAAC8F6CCCCC8C3C3C3BEBBB6F6BFF9B4F9B490F99091906CA2FFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFD1A6F6CCCCC7C7C3C3BFBBBABFFFC8F9F9F990F9909090906C90AAFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFF6A6D0D1CCC8C7C3C3BFBEBFB6CCFFF6F9F9F9B4F9B49090906C6C95F6FFFFFFFFFFFFFFFFFF6C", | ||||
| "6CFFFFFFFFFFFFFFFFAACCF6CCCCC7C4C3BFBEBBBABBD1FFFFBFF9F9F990F9F99190956C6C99FFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFD1C8F6CCCCC8C7C7C8C7C8C7C3C8F6FFF6CDBFBBBFBBBFBF9090906C6C6CA6FFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFAAF6D0CCC8C7C3C4D0FFFFFFFFF6F6FFFFF6FFFFFFFFD199F9909090706C99F6FFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFD5CCD1CCCCC7C3C3C3BFC8F6FFFFFFFFFFFFFFFFFFFFC895F990B490916C016CA2FFFFFFFFFFFFFF6C", | ||||
| "6CFFFFFFFFFFF6AAD1D0CCC7C8C3C3C3BFBEBFD1FFFFFFFFFFFFFFFFA1F9F990F9909090906C0170F6FFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFD1CCD0CCC8C8C3C3BFBFBFBABBBACCFFFFFFFFFFD1BBF9F990B490B490906D6C6C6CA6FFFFFFFFFFFF70", | ||||
| "70FFFFFFFFF6AACCD1CCC7C7C3C3BFBEBFBABABBD1FFFFFFFFFFF699F990B4F990F99090906C700199FFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFA6D0CCC8C7C3C3BFBFBFBABBB6BFF6FFFFFFFFFFFFC8F9F990F99091F99190906C0194D1FFFFFFFFFF6C", | ||||
| "6CFFFFFFFFF6C8CCCCC7C4C3BFBFBEBFBABBB6C8FFFFCCBBC4FFFFD091F9F991F9F990F9906C6D016CAAFFFFFFFFFF70", | ||||
| "70FFFFFFF6D5A5CCC8C7C3C3BFBEBBBABBBAB6F6F6C4F9F9F9BBD1FFBBF990F9F991F99091906C016CA2FFFFFFFFFF70", | ||||
| "70FFFFFFFFAEC4C7C7C3BFBFBEBFBABBB6B6BBD1BBF9F9F9F9F9B6CCC8F9B4F990F990909090706C6CA2F6FFFFFFFF70", | ||||
| "70FFFFFFFFCCC3C8C3C3BFBEBBBABBBAB6B7BBB6F9F9F9B4F9F9F9B4BBB690F9B490B49090916C016CA1FFFFFFFFFF6C", | ||||
| "6CFFFFFFFFD19DC3BFBFBFBBBABBB6B7B6F9F9F9F9B4F9F9F9B4F9F9F9B4F9F9F9F990B4906C6C016CC8FFFFFFFFFF70", | ||||
| "70FFFFFFFFF69DBEBFBEBABABBB6B6B6F9F9F9B4F990F9B4F9F9F9F9F9F9F991F990F99090706C016CAAFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFA2B6BBBAB7B6B6B6B4F9B4F991909090F9F9F990B4F9B4F9F9F9F9B49090906D6C0199FFFFFFFFFFFF70", | ||||
| "70FFFFFFFFF6F694F9B6B6B4F9F9F9F990F9909090C8A2F999CC95F9F9F9B4F9909090916C6C0190A6FFFFFFFFFFFF6C", | ||||
| "6CFFFFFFFFFFFFCC91F990F9B4F991F991906C909DFFCCF9BFFFCCF9F9F990F9F991906C70016CA2FFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFC895909090909090906C909EFFFFA2F995FFFFA6B790F99190906C6C6C6CC4F6F6FFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFAEBF9590906C906C99C8FFF6FFBFB69008FFFFF69DB7906C6C6C9499D5F6F6FFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFD0A6A2C3A6CCFFFFFFFF08BBF990A2F6FFFFFFF6CCC8C8CCAFFFF6FFFFFFFFFFFFFFFFFF6C", | ||||
| "6CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6BFF99095F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D1A1BFF9906CA6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2C3BBF9F96C95F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A1C3B6F9B4906C99FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C", | ||||
| "6CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAC3C3BAB4F9F990906C9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD19DBBBBB6F9F9F990F990909099AAFFFFFFFFFFFFFFFFFFF6FFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A2A1BF9D9EBFA2BFA2BFA29DA2BFA2CCFFFFFFFFF6FFFFFFFFFFFFFFFFFFFF70", | ||||
| "70FFFFFFFFFFFFFFFFFFFFFFFFFFFFF6FFFFFFFFFFFFFFFFFFFFFFFFF6FFF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C", | ||||
| "6CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70", | ||||
| "704C706C7001706C7001706C70706C7070707070707070706C7070707070704C707001707001706C704C6C7070017070"}; | ||||
							
								
								
									
										484
									
								
								pyfpdb/DatabaseManager.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										484
									
								
								pyfpdb/DatabaseManager.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,484 @@ | |||
| 
 | ||||
| import os | ||||
| import pygtk | ||||
| pygtk.require('2.0') | ||||
| import gtk | ||||
| 
 | ||||
| #******************************************************************************************************* | ||||
| class DatabaseManager(object): | ||||
|     DatabaseTypes = {} | ||||
|      | ||||
|     def __init__(self, defaultDatabaseType=None): | ||||
|         self._defaultDatabaseType = defaultDatabaseType | ||||
|     def set_default_database_type(self, databaseType): | ||||
|         self._defaultDatabaseType = defaultDatabaseType | ||||
|     def get_default_database_type(self): | ||||
|         return self._defaultDatabaseType | ||||
|          | ||||
| class DatabaseTypeMeta(type): | ||||
|     def __new__(klass, name, bases, kws): | ||||
|         newKlass = type.__new__(klass, name, bases, kws) | ||||
|         if newKlass.Type is not None: | ||||
|             if newKlass.Type in DatabaseManager.DatabaseTypes: | ||||
|                 raise ValueError('data base type already registered for: %s' % newKlass.Type) | ||||
|             DatabaseManager.DatabaseTypes[newKlass.Type] = newKlass | ||||
|         return newKlass | ||||
| 
 | ||||
| class DatabaseTypeBase(object): | ||||
|     __metaclass__ = DatabaseTypeMeta | ||||
|     Type = None | ||||
| 
 | ||||
| class DatabaseTypePostgres(DatabaseTypeBase): | ||||
|     Type = 'postgres' | ||||
|     def __init__(self, host='localhost', port=5432, user='postgres', password='', database='fpdb', name=''): | ||||
|         self.host = host | ||||
|         self.port = port | ||||
|         self.user = user | ||||
|         self.password = password | ||||
|         self.database = database | ||||
|         self.name = name | ||||
| 
 | ||||
| class DatabaseTypeMysql(DatabaseTypeBase): | ||||
|     Type = 'mysql' | ||||
|     def __init__(self, host='localhost', port=3306, user='root', password='', database='fpdb', name=''): | ||||
|         self.host = host | ||||
|         self.port = port | ||||
|         self.user = user | ||||
|         self.password = password | ||||
|         self.database = database | ||||
|         self.name = name | ||||
|          | ||||
| class DatabaseTypeSqLite(DatabaseTypeBase): | ||||
|     Type = 'sqlite' | ||||
|     def __init__(self, host='', file='', name=''): | ||||
|         self.file = file | ||||
|         self.name = name | ||||
| 
 | ||||
| #*************************************************************************************************************************** | ||||
| class MyFileChooserButton(gtk.HBox): | ||||
|     #NOTE: for some weird reason it is impossible to let the user choose a non exiting filename with gtk.FileChooserButton, so impl our own on the fly | ||||
|     def __init__(self): | ||||
|         gtk.HBox.__init__(self) | ||||
|         self.set_homogeneous(False) | ||||
|          | ||||
|         self.entry = gtk.Entry() | ||||
|         self.button = gtk.Button('...') | ||||
|         self.button.connect('clicked', self.on_button_clicked) | ||||
|          | ||||
|         # layout widgets | ||||
|         self.pack_start(self.entry, True, True) | ||||
|         self.pack_start(self.button, False, False) | ||||
|          | ||||
|     def get_filename(self): | ||||
|         return self.entry.get_text() | ||||
|          | ||||
|     def set_filename(self, name): | ||||
|         self.entry.set_text(name) | ||||
|          | ||||
|     def on_button_clicked(self, button): | ||||
|         dlg = gtk.FileChooserDialog( | ||||
|                 title='Choose an exiting database file or type in name of a new one',  | ||||
|                 parent=None,  | ||||
|                 action=gtk.FILE_CHOOSER_ACTION_SAVE,  | ||||
|                 buttons=( | ||||
|                         gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, | ||||
|                         gtk.STOCK_OK, gtk.RESPONSE_OK, | ||||
|                         ),  | ||||
|                 backend=None | ||||
|                 ) | ||||
|         dlg.connect('confirm-overwrite', self.on_dialog_confirm_overwrite) | ||||
|         dlg.set_default_response(gtk.RESPONSE_OK) | ||||
|         dlg.set_do_overwrite_confirmation(True) | ||||
|         if dlg.run() == gtk.RESPONSE_OK: | ||||
|             self.set_filename(dlg.get_filename()) | ||||
|         dlg.destroy() | ||||
|          | ||||
|     #TODO: when the user selects a sqLite database file we got three possible actions | ||||
|     #    1. user types in a new filename. easy one, create the file | ||||
|     #    2. user selectes a file with the intention to overwrite it | ||||
|     #    3. user selects a file with the intention to plug an existing database file in | ||||
|     #IDEA: impl open_existing as plug in, never overwrite, cos we can not guess | ||||
|     #PROBLEMS: how to validate an existing file is a database? | ||||
|     def on_dialog_confirm_overwrite(self, dlg): | ||||
|         print dlg.get_filename() | ||||
|          | ||||
|         gtk.FILE_CHOOSER_CONFIRMATION_CONFIRM | ||||
|         #The file chooser will present its stock dialog to confirm overwriting an existing file. | ||||
| 
 | ||||
|         gtk.FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME | ||||
|         #The file chooser will terminate and accept the user's choice of a file name. | ||||
| 
 | ||||
|         gtk.FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN | ||||
|         # | ||||
|          | ||||
|          | ||||
| class WidgetDatabaseProperties(gtk.VBox): | ||||
|     ModeEdit = 0x1 | ||||
|     ModeAdd = 0x2 | ||||
|     ModeNew = 0x4 | ||||
|          | ||||
|     class FieldWidget(object): | ||||
|         def __init__(self, text='', attrDatabase='', widget=None, attrGet=None, attrSet=None, defaultValue=None, canEdit=False, tooltip=''): | ||||
|             """ | ||||
|             @param canEdit: True if the user can edit the attr in edit mode, False otherwise | ||||
|             """ | ||||
|             self._label = gtk.Label(text) | ||||
|             self._attrDatabase = attrDatabase | ||||
|             self._widget = widget | ||||
|             self._defaultValue = defaultValue | ||||
|             self._attrGetter=None,  | ||||
|             self._attrGet = attrGet  | ||||
|             self._attrSet = attrSet  | ||||
|             self._canEdit = canEdit | ||||
|              | ||||
|             self._label.set_tooltip_text(tooltip) | ||||
|             self._widget.set_tooltip_text(tooltip) | ||||
|                      | ||||
|         def widget(self):  | ||||
|             return self._widget | ||||
|         def label(self): | ||||
|             return self._label | ||||
|         def is_sensitive(self, database): | ||||
|             return hasattr(database, self._attrDatabase) | ||||
|         def can_edit(self): | ||||
|             return self._canEdit | ||||
|         def set_sensitive(self, flag): | ||||
|             self._label.set_sensitive(flag) | ||||
|             self._widget.set_sensitive(flag) | ||||
|         def value_from_database(self, database): | ||||
|             getattr(self._widget, self._attrSet)( getattr(database, self._attrDatabase) ) | ||||
|         def value_to_database(self, database): | ||||
|             setattr(database, self._attrDatabase, getattr(self._widget, self._attrGet)() ) | ||||
|         def reset_value(self): | ||||
|             getattr(self._widget, self._attrSet)(self._defaultValue) | ||||
|          | ||||
|     def __init__(self, databaseManager, database=None, flags=ModeEdit): | ||||
|             gtk.VBox.__init__(self) | ||||
|                          | ||||
|             self.flags = flags | ||||
|             self.fieldWidgets = (        #fieldName--> fieldHandler | ||||
|                         self.FieldWidget( | ||||
|                                 text='Name:', | ||||
|                                 attrDatabase='name',  | ||||
|                                 widget=gtk.Entry(), | ||||
|                                 defaultValue='', | ||||
|                                 attrGet='get_text',  | ||||
|                                 attrSet='set_text',  | ||||
|                                 canEdit=True, | ||||
|                                 tooltip='' | ||||
|                         ), | ||||
|                         self.FieldWidget( | ||||
|                             text='File:',  | ||||
|                             attrDatabase='file',  | ||||
|                             widget=MyFileChooserButton(),  | ||||
|                             defaultValue='', | ||||
|                             attrGet='get_filename',  | ||||
|                             attrSet='set_filename',  | ||||
|                             canEdit=False,  | ||||
|                             tooltip='' | ||||
|                         ), | ||||
|                         self.FieldWidget( | ||||
|                             text='Host:',  | ||||
|                             attrDatabase='host',  | ||||
|                             widget=gtk.Entry(),  | ||||
|                             defaultValue='', | ||||
|                             attrGet='get_text',  | ||||
|                             attrSet='set_text',  | ||||
|                             canEdit=False,  | ||||
|                             tooltip='' | ||||
|                         ), | ||||
|                         self.FieldWidget( | ||||
|                             text='Port:',  | ||||
|                             attrDatabase='port',  | ||||
|                             widget=gtk.SpinButton(adjustment=gtk.Adjustment(value=0, lower=0, upper=999999, step_incr=1, page_incr=10) ),  | ||||
|                             defaultValue=0, | ||||
|                             attrGet='get_value',  | ||||
|                             attrSet='set_value',  | ||||
|                             canEdit=False,  | ||||
|                             tooltip='' | ||||
|                         ), | ||||
|                         self.FieldWidget( | ||||
|                             text='User:',  | ||||
|                             attrDatabase='user',  | ||||
|                             widget=gtk.Entry(),  | ||||
|                             defaultValue='', | ||||
|                             attrGet='get_text',  | ||||
|                             attrSet='set_text',  | ||||
|                             canEdit=False,  | ||||
|                             tooltip='' | ||||
|                         ), | ||||
|                         self.FieldWidget( | ||||
|                             text='Pwd:',  | ||||
|                             attrDatabase='password',  | ||||
|                             widget=gtk.Entry(),  | ||||
|                             defaultValue='', | ||||
|                             attrGet='get_text',  | ||||
|                             attrSet='set_text',  | ||||
|                             canEdit=False,  | ||||
|                             tooltip='' | ||||
|                         ), | ||||
|                         self.FieldWidget( | ||||
|                             text='Db:',  | ||||
|                             attrDatabase='database',  | ||||
|                             widget=gtk.Entry(),  | ||||
|                             defaultValue='', | ||||
|                             attrGet='get_text',  | ||||
|                             attrSet='set_text',  | ||||
|                             canEdit=False, | ||||
|                             tooltip='' | ||||
|                         ), | ||||
|                     ) | ||||
|              | ||||
|             # setup database type combo | ||||
|             self.comboType = gtk.ComboBox() | ||||
|             listStore= gtk.ListStore(str, str) | ||||
|             self.comboType.set_model(listStore) | ||||
|             cell = gtk.CellRendererText() | ||||
|             self.comboType.pack_start(cell, True) | ||||
|             self.comboType.add_attribute(cell, 'text', 0) | ||||
|             # fill out combo with database type. we store (displayName, databaseType) in our model for later lookup | ||||
|             for dbType, dbDisplayName in sorted([(klass.Type, klass.Type) for klass in databaseManager.DatabaseTypes.values()]): | ||||
|                 listStore.append( (dbDisplayName, dbType) ) | ||||
|             self.comboType.connect('changed', self.on_combo_type_changed) | ||||
|                  | ||||
|             # init and layout field widgets | ||||
|             self.pack_start(self.comboType, False, False, 2) | ||||
|             table = gtk.Table(rows=len(self.fieldWidgets) +1, columns=2, homogeneous=False) | ||||
|             self.pack_start(table, False, False, 2) | ||||
|             for i,fieldWidget in enumerate(self.fieldWidgets): | ||||
|                 table.attach(fieldWidget.label(), 0, 1, i, i+1, xoptions=gtk.FILL) | ||||
|                 table.attach(fieldWidget.widget(), 1, 2, i, i+1) | ||||
|                  | ||||
|             # init widget | ||||
|              | ||||
|             # if a database has been passed user is not allowed to change database type | ||||
|             if database is None: | ||||
|                 self.comboType.set_button_sensitivity(gtk.SENSITIVITY_ON) | ||||
|             else: | ||||
|                 self.comboType.set_button_sensitivity(gtk.SENSITIVITY_OFF) | ||||
|                  | ||||
|             # set current database | ||||
|             self.databaseManager = databaseManager | ||||
|             self.database= None | ||||
|             if database is None: | ||||
|                 databaseType = self.databaseManager.get_default_database_type() | ||||
|                 if databaseType is not None: | ||||
|                     database = databaseType() | ||||
|             if database is not None: | ||||
|                 self.set_database(database) | ||||
|      | ||||
|     def on_combo_type_changed(self, combo): | ||||
|         i = self.comboType.get_active() | ||||
|         if i > -1: | ||||
|             # change database if necessary | ||||
|             currentDatabaseType = self.comboType.get_model()[i][1] | ||||
|             if currentDatabaseType != self.database.Type: | ||||
|                 newDatabase = self.databaseManager.DatabaseTypes[currentDatabaseType]() | ||||
|                 self.set_database(newDatabase) | ||||
|          | ||||
|     def set_database(self, database): | ||||
|         self.database = database | ||||
|          | ||||
|         # adjust database type combo if necessary | ||||
|         i = self.comboType.get_active() | ||||
|         if i == -1: | ||||
|             currentDatabaseType = None | ||||
|         else: | ||||
|             currentDatabaseType = self.comboType.get_model()[i][1] | ||||
|         if currentDatabaseType != self.database.Type: | ||||
|             for i, row in enumerate(self.comboType.get_model()):  | ||||
|                 if row[1] == self.database.Type: | ||||
|                     self.comboType.set_active(i) | ||||
|                     break | ||||
|             else: | ||||
|                 raise ValueError('unknown database type') | ||||
|                  | ||||
|         # adjust field widgets to database | ||||
|         for fieldWidget in self.fieldWidgets: | ||||
|             isSensitive = fieldWidget.is_sensitive(self.database) | ||||
|             if isSensitive: | ||||
|                 fieldWidget.value_from_database(self.database) | ||||
|             else: | ||||
|                 fieldWidget.reset_value() | ||||
|             if self.flags & self.ModeEdit: | ||||
|                 isSensitive = isSensitive and fieldWidget.can_edit() | ||||
|             fieldWidget.set_sensitive(isSensitive) | ||||
|                      | ||||
|     def get_database(self): | ||||
|         for fieldWidget in self.fieldWidgets: | ||||
|             if fieldWidget.is_sensitive(self.database): | ||||
|                 fieldWidget.value_to_database(self.database) | ||||
|         return self.database | ||||
| 
 | ||||
| 
 | ||||
| class DialogDatabaseProperties(gtk.Dialog): | ||||
|     def __init__(self, databaseManager, database=None,parent=None, flags=WidgetDatabaseProperties.ModeEdit): | ||||
|         if flags & WidgetDatabaseProperties.ModeEdit: | ||||
|             title = '[Edit database] - database properties' | ||||
|         elif flags & WidgetDatabaseProperties.ModeAdd: | ||||
|             title = '[Add database] - database properties' | ||||
|         elif flags & WidgetDatabaseProperties.ModeNew: | ||||
|             title = '[New database] - database properties' | ||||
|         else: | ||||
|                 title = 'database properties'     | ||||
|          | ||||
|         gtk.Dialog.__init__(self, | ||||
|                 title=title,  | ||||
|                 parent=parent, | ||||
|                 flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, | ||||
|                 buttons=( | ||||
|                         gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, | ||||
|                         gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, | ||||
|                         ) | ||||
|                 ) | ||||
|         self.connect('response', self.on_dialog_response) | ||||
|          | ||||
|         # setup widget | ||||
|         self.flags = flags | ||||
|         self.widgetDatabaseProperties = WidgetDatabaseProperties(databaseManager,database=database, flags=self.flags) | ||||
|         self.vbox.pack_start(self.widgetDatabaseProperties, True, True) | ||||
|         self.widgetDatabaseProperties.show_all() | ||||
| 
 | ||||
|     def get_database(self): | ||||
|         return self.widgetDatabaseProperties.get_database() | ||||
|      | ||||
|     def on_dialog_response(self, dlg, responseId): | ||||
|         if responseId == gtk.RESPONSE_REJECT: | ||||
|             pass | ||||
|         elif responseId == gtk.RESPONSE_ACCEPT: | ||||
|             pass | ||||
|              | ||||
|      | ||||
| #TODO: just boilerplate code | ||||
| class DialogDatabase(gtk.Dialog): | ||||
|     def __init__(self, databaseManager, parent=None): | ||||
|         gtk.Dialog.__init__(self, | ||||
|         title="My dialog",  | ||||
|                 parent=parent, | ||||
|                 flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, | ||||
|                 buttons=( | ||||
|                         gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, | ||||
|                         gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, | ||||
|                         )) | ||||
|         #self.set_size_request(260, 250) | ||||
|          | ||||
|         self.databaseManager = databaseManager | ||||
|              | ||||
|         #TODO: dono how to make word wrap work as expected | ||||
|         self.labelInfo = gtk.Label('database management') | ||||
|         self.labelInfo.set_line_wrap(True) | ||||
|         self.labelInfo.set_selectable(True) | ||||
|         self.labelInfo.set_single_line_mode(False) | ||||
|         self.labelInfo.set_alignment(0, 0) | ||||
|          | ||||
|         # database management buttons | ||||
|          | ||||
|         #TODO: bit messy the distinction New/Add/Edit. we'd have to pass three flags to DialogDatabaseProperties | ||||
|         # to handle this. maybe drop Edit (is just a Remove + Add), to keep things simple | ||||
|         self.buttonDatabaseNew = gtk.Button("New..") | ||||
|         self.buttonDatabaseNew.set_tooltip_text('creates a new database') | ||||
|         self.buttonDatabaseNew.connect('clicked', self.on_button_database_new_clicked) | ||||
|         self.buttonDatabaseAdd = gtk.Button("Add..") | ||||
|         self.buttonDatabaseAdd.set_tooltip_text('adds an existing database') | ||||
|         self.buttonDatabaseAdd.connect('clicked', self.on_button_database_add_clicked) | ||||
|         self.buttonDatabaseEdit = gtk.Button("Edit..") | ||||
|         self.buttonDatabaseEdit.set_tooltip_text('edit database settings') | ||||
|         self.buttonDatabaseEdit.connect('clicked', self.on_button_database_edit_clicked) | ||||
|         self.buttonDatabaseEdit.set_sensitive(False) | ||||
|         self.buttonDatabaseRemove = gtk.Button("Remove") | ||||
|         self.buttonDatabaseRemove.set_tooltip_text('removes the database from the list') | ||||
|         self.buttonDatabaseRemove.set_sensitive(False) | ||||
|          | ||||
|         #TODO: i dont think we should do any real database management here. maybe drop it | ||||
|         self.buttonDatabaseDelete = gtk.Button("Delete") | ||||
|         self.buttonDatabaseDelete.set_tooltip_text('removes the database from the list and deletes it') | ||||
|         self.buttonDatabaseDelete.set_sensitive(False) | ||||
|              | ||||
|         # database tree         | ||||
|         self.treeDatabases = gtk.TreeView() | ||||
|         store = gtk.ListStore(str, str, str) | ||||
|         self.treeDatabases.set_model(store) | ||||
|         columns = ('Name', 'Status', 'Type') | ||||
|         for i, column in enumerate(columns): | ||||
|             col = gtk.TreeViewColumn(column, gtk.CellRendererText(), text=i) | ||||
|             self.treeDatabases.append_column(col) | ||||
|         self.treeDatabases.get_selection().connect('changed', self.on_tree_databases_selection_changed) | ||||
|                  | ||||
|         # layout widgets | ||||
|         self.vbox.pack_start(self.labelInfo, False, False, 2) | ||||
|         self.vbox.pack_start(gtk.HSeparator(), False, False, 2) | ||||
|          | ||||
|         hbox = gtk.HBox() | ||||
|         self.vbox.add(hbox) | ||||
|         hbox.set_homogeneous(False) | ||||
|         vbox = gtk.VBox() | ||||
|         hbox.pack_start(vbox, False, False, 2) | ||||
|         vbox.pack_start(self.buttonDatabaseNew, False, False, 2) | ||||
|         vbox.pack_start(self.buttonDatabaseAdd, False, False, 2) | ||||
|         vbox.pack_start(self.buttonDatabaseEdit, False, False, 2) | ||||
|         vbox.pack_start(self.buttonDatabaseRemove, False, False, 2) | ||||
|         vbox.pack_start(self.buttonDatabaseDelete, False, False, 2) | ||||
|         box = gtk.VBox() | ||||
|         vbox.pack_start(box, True, True, 0) | ||||
|          | ||||
|         hbox.pack_start(gtk.VSeparator(), False, False, 2) | ||||
|         hbox.pack_end(self.treeDatabases, True, True, 2) | ||||
|          | ||||
|         self.show_all() | ||||
|              | ||||
|              | ||||
|     #TODO: for some reason i have to click OK/Cancel twice to close the dialog         | ||||
|     def on_button_database_new_clicked(self, button): | ||||
|         dlg = DialogDatabaseProperties(self.databaseManager, parent=self, flags=WidgetDatabaseProperties.ModeNew) | ||||
|         if dlg.run() == gtk.RESPONSE_REJECT: | ||||
|             pass | ||||
|         if dlg.run() == gtk.RESPONSE_ACCEPT: | ||||
|             database = dlg.get_database() | ||||
|             self.treeDatabases.get_model().append( (database.name, 'foo', database.Type) ) | ||||
|         dlg.destroy() | ||||
| 
 | ||||
|     def on_button_database_add_clicked(self, button): | ||||
|         dlg = DialogDatabaseProperties(self.databaseManager, parent=self, flags=WidgetDatabaseProperties.ModeAdd) | ||||
|         if dlg.run() == gtk.RESPONSE_REJECT: | ||||
|             pass | ||||
|         if dlg.run() == gtk.RESPONSE_ACCEPT: | ||||
|             database = dlg.get_database() | ||||
|             self.treeDatabases.get_model().append( (database.name, 'foo', database.Type) ) | ||||
|         dlg.destroy() | ||||
|          | ||||
|     def on_button_database_edit_clicked(self, button): | ||||
|         dlg = DialogDatabaseProperties(self.databaseManager, parent=self, flags=WidgetDatabaseProperties.ModeEdit) | ||||
|         if dlg.run() == gtk.RESPONSE_REJECT: | ||||
|             pass | ||||
|         if dlg.run() == gtk.RESPONSE_ACCEPT: | ||||
|             database = dlg.get_database() | ||||
|             selection = self.treeDatabases.get_selection() | ||||
|             if selection is not None: | ||||
|                 model, iter = selection.get_selected() | ||||
|                 model.set_value(iter, 0, database.name) | ||||
|         dlg.destroy() | ||||
| 
 | ||||
|     def on_tree_databases_selection_changed(self, treeSelection): | ||||
|         hasSelection = bool(treeSelection.count_selected_rows()) | ||||
|          | ||||
|             # enable/disable selection dependend widgets | ||||
|         self.buttonDatabaseEdit.set_sensitive(hasSelection) | ||||
|         self.buttonDatabaseRemove.set_sensitive(hasSelection) | ||||
|         self.buttonDatabaseDelete.set_sensitive(hasSelection) | ||||
|          | ||||
|          | ||||
|          | ||||
| 
 | ||||
| #************************************************************************************************** | ||||
| if __name__ == '__main__': | ||||
|     #d = DialogDatabaseProperties( | ||||
|     #        DatabaseManager(defaultDatabaseType=DatabaseTypeSqLite), | ||||
|             #database=DatabaseTypePostgres(), | ||||
|     #        database=None, | ||||
|     #        ) | ||||
|     d = DialogDatabase(DatabaseManager(defaultDatabaseType=DatabaseTypeSqLite)) | ||||
|     d.connect("destroy", gtk.main_quit) | ||||
|     d.run() | ||||
|     #gtk.main() | ||||
| 
 | ||||
| 
 | ||||
|  | @ -56,7 +56,10 @@ class DerivedStats(): | |||
| 
 | ||||
|         # This (i think...) is correct for both stud and flop games, as hand.board['street'] disappears, and | ||||
|         # those values remain default in stud. | ||||
|         boardcards = hand.board['FLOP'] + hand.board['TURN'] + hand.board['RIVER'] + [u'0x', u'0x', u'0x', u'0x', u'0x'] | ||||
|         boardcards = [] | ||||
|         for street in hand.communityStreets: | ||||
|             boardcards += hand.board[street] | ||||
|         boardcards += [u'0x', u'0x', u'0x', u'0x', u'0x'] | ||||
|         cards = [Card.encodeCard(c) for c in boardcards[0:5]] | ||||
|         self.hands['boardcard1'] = cards[0] | ||||
|         self.hands['boardcard2'] = cards[1] | ||||
|  | @ -809,24 +812,11 @@ class DerivedStats(): | |||
|         self.hands['playersAtStreet4']  = 0 | ||||
|         self.hands['playersAtShowdown'] = 0 | ||||
| 
 | ||||
|         for street in hand.actionStreets: | ||||
|         for (i, street) in enumerate(hand.actionStreets[2:]): | ||||
|             actors = {} | ||||
|             for act in hand.actions[street]: | ||||
|                 actors[act[0]] = 1 | ||||
|             #print "len(actors.keys(%s)): %s" % ( street, len(actors.keys())) | ||||
|             if hand.gametype['base'] in ("hold"): | ||||
|                 if street in "FLOP": self.hands['playersAtStreet1'] = len(actors.keys()) | ||||
|                 elif street in "TURN": self.hands['playersAtStreet2'] = len(actors.keys()) | ||||
|                 elif street in "RIVER": self.hands['playersAtStreet3'] = len(actors.keys()) | ||||
|             elif hand.gametype['base'] in ("stud"): | ||||
|                 if street in "FOURTH": self.hands['playersAtStreet1'] = len(actors.keys()) | ||||
|                 elif street in "FIFTH": self.hands['playersAtStreet2'] = len(actors.keys()) | ||||
|                 elif street in "SIXTH": self.hands['playersAtStreet3'] = len(actors.keys()) | ||||
|                 elif street in "SEVENTH": self.hands['playersAtStreet4'] = len(actors.keys()) | ||||
|             elif hand.gametype['base'] in ("draw"): | ||||
|                 if street in "DRAWONE": self.hands['playersAtStreet1'] = len(actors.keys()) | ||||
|                 elif street in "DRAWTWO": self.hands['playersAtStreet2'] = len(actors.keys()) | ||||
|                 elif street in "DRAWTHREE": self.hands['playersAtStreet3'] = len(actors.keys()) | ||||
|             self.hands['playersAtStreet%s' % str(i+1)] = len(actors.keys()) | ||||
| 
 | ||||
|         #Need playersAtShowdown | ||||
| 
 | ||||
|  |  | |||
|  | @ -304,5 +304,5 @@ if __name__ == "__main__": | |||
|     LOG_FILENAME = './logging.out' | ||||
|     logging.basicConfig(filename=LOG_FILENAME,level=options.verbosity) | ||||
| 
 | ||||
|     e = Everleaf(in_path = options.ipath, out_path = options.opath, follow = options.follow, autostart=True, debugging=True) | ||||
|     e = Everleaf(in_path = options.ipath, out_path = options.opath, follow = options.follow, autostart=True) | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,11 +32,12 @@ try: | |||
|     from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar | ||||
|     from numpy import arange, cumsum | ||||
|     from pylab import * | ||||
| except ImportError: | ||||
| except ImportError as inst: | ||||
|     print """Failed to load libs for graphing, graphing will not function. Please in | ||||
|                  stall numpy and matplotlib if you want to use graphs.""" | ||||
|     print """This is of no consequence for other parts of the program, e.g. import  | ||||
|          and HUD are NOT affected by this problem.""" | ||||
|     print "ImportError: %s" % inst.args | ||||
| 
 | ||||
| import fpdb_import | ||||
| import Database | ||||
|  |  | |||
|  | @ -37,11 +37,10 @@ try: | |||
| #    from matplotlib.dates import  DateFormatter, WeekdayLocator, HourLocator, \ | ||||
| #     DayLocator, MONDAY, timezone | ||||
| 
 | ||||
| except: | ||||
|     err = traceback.extract_tb(sys.exc_info()[2])[-1] | ||||
|     print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) | ||||
| except ImportError as inst: | ||||
|     print """Failed to load numpy in Session Viewer""" | ||||
|     print """This is of no consequence as the module currently doesn't do anything.""" | ||||
|     print """This is of no consequence as the page is broken and only of interest to developers.""" | ||||
|     print "ImportError: %s" % inst.args | ||||
| 
 | ||||
| import Card | ||||
| import fpdb_import | ||||
|  |  | |||
|  | @ -77,10 +77,11 @@ class fpdb_db: | |||
|             import MySQLdb | ||||
|             if use_pool: | ||||
|                 MySQLdb = pool.manage(MySQLdb, pool_size=5) | ||||
|             try: | ||||
|                 self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True) | ||||
|             except: | ||||
|                 raise FpdbMySQLFailedError("MySQL connection failed") | ||||
| #            try: | ||||
|             self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True) | ||||
|             #TODO: Add port option | ||||
| #            except: | ||||
| #                raise FpdbMySQLFailedError("MySQL connection failed") | ||||
|         elif backend==fpdb_db.PGSQL: | ||||
|             import psycopg2 | ||||
|             import psycopg2.extensions | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user