class FinalPage(ProgressPage): """FinalPage is the final page in the import process""" title = ugettext_lazy('Import Progress') sub_title = ugettext_lazy('Please wait while data is being imported.') def __init__(self, parent=None, model=None, admin=None): """ :model: the source model from which to import data :admin: the admin class of the target data """ super(FinalPage, self).__init__(parent) self.model = model self.admin = admin icon = 'tango/32x32/mimetypes/x-office-spreadsheet.png' self.setPixmap(QtGui.QWizard.LogoPixmap, Pixmap(icon).getQPixmap()) self.setButtonText(QtGui.QWizard.FinishButton, _('Close')) self.progressbar = QtGui.QProgressBar() def run(self): collection = self.model.get_collection() self.update_maximum_signal.emit(len(collection)) for i, row in enumerate(collection): new_entity_instance = self.admin.entity() for field_name, attributes in self.model.get_admin().get_columns(): try: from_string = attributes['from_string'] except KeyError: logger.warn( 'field %s has no from_string field attribute, dont know how to import it properly' % attributes['original_field']) from_string = lambda _a: None setattr(new_entity_instance, attributes['original_field'], from_string(getattr(row, field_name))) self.admin.add(new_entity_instance) self.admin.flush(new_entity_instance) self.update_progress_signal.emit( i, _('Row %i of %i imported') % (i + 1, len(collection)))
def get_field_attributes(self, field_name): """ Get the attributes needed to visualize the field field_name. This function is called by get_static_field_attributes and get_dynamic_field_attributes. This function first tries to fill the dictionary with field attributes for a field with those gathered through introspection, and then updates them with those found in the field_attributes class attribute. :param field_name: the name of the field :return: a dictionary of attributes needed to visualize the field The values of the returned dictionary either contain the value of the field attribute, or in the case of dynamic field attributes, a function that returns the value of the field attribute. """ # # @todo : this function should return a frozen dictionary, so no # other parts of the application can modify the cached field # attributes # try: return self._field_attributes[field_name] except KeyError: def create_default_getter(field_name): return lambda o:getattr(o, field_name) from camelot.view.controls import delegates # # Default attributes for all fields # attributes = dict( getter=create_default_getter(field_name), to_string = to_string, field_name=field_name, python_type=str, length=None, tooltip=None, background_color=None, #minimal_column_width=12, editable=False, nullable=True, widget='str', blank=True, delegate=delegates.PlainTextDelegate, validator_list=[], name=ugettext_lazy(field_name.replace( '_', ' ' ).capitalize()) ) # # Field attributes forced by the field_attributes property # forced_attributes = {} try: forced_attributes = self.field_attributes[field_name] except KeyError: pass # # TODO : move part of logic from entity admin class over here # # # Overrule introspected field_attributes with those defined # attributes.update(forced_attributes) # # In case of a 'target' field attribute, instantiate an appropriate # 'admin' attribute # def get_entity_admin(target): """Helper function that instantiated an Admin object for a target entity class :param target: an entity class for which an Admin object is needed """ try: fa = self.field_attributes[field_name] target = fa.get('target', target) admin_class = fa['admin'] return admin_class(self.app_admin, target) except KeyError: return self.get_related_admin(target) if 'target' in attributes: attributes['admin'] = get_entity_admin(attributes['target']) self._field_attributes[field_name] = attributes return attributes
def get_field_attributes(self, field_name): """Get the attributes needed to visualize the field field_name :param field_name: the name of the field :return: a dictionary of attributes needed to visualize the field, those attributes can be: * python_type : the corresponding python type of the object * editable : bool specifying wether the user can edit this field * widget : which widget to be used to render the field * ... """ from sqlalchemy.orm.mapper import _mapper_registry try: return self._field_attributes[field_name] except KeyError: def create_default_getter(field_name): return lambda o:getattr(o, field_name) from camelot.view.controls import delegates # # Default attributes for all fields # attributes = dict( python_type = str, to_string = to_string, field_name = field_name, getter = create_default_getter(field_name), length = None, tooltip = None, background_color = None, #minimal_column_width = 12, editable = False, nullable = True, widget = 'str', blank = True, delegate = delegates.PlainTextDelegate, validator_list = [], name = ugettext_lazy(field_name.replace('_', ' ').capitalize()) ) # # Field attributes forced by the field_attributes property # forced_attributes = {} try: forced_attributes = self.field_attributes[field_name] except KeyError: pass def resolve_target(target): """A class or name of the class representing the other side of a relation. Use the name of the class to avoid circular dependencies""" if isinstance(target, basestring): for mapped_class in _mapper_registry.keys(): if mapped_class.class_.__name__ == target: return mapped_class.class_ raise Exception('No mapped class found for target %s'%target) return target def get_entity_admin(target): """Helper function that instantiated an Admin object for a target entity class. :param target: an entity class for which an Admin object is needed """ try: admin_class = forced_attributes['admin'] return admin_class(self.app_admin, target) except KeyError: return self.get_related_admin(target) # # Get the default field_attributes trough introspection if the # field is a mapped field # from sqlalchemy import orm from sqlalchemy.exc import InvalidRequestError try: property = self.mapper.get_property( field_name ) if isinstance(property, orm.properties.ColumnProperty): columns = property.columns sql_attributes = self.get_sql_field_attributes( columns ) attributes.update( sql_attributes ) elif isinstance(property, orm.properties.PropertyLoader): target = forced_attributes.get( 'target', property.mapper.class_ ) # # _foreign_keys is for sqla pre 0.6.4 # if hasattr(property, '_foreign_keys'): foreign_keys = list(property._foreign_keys) else: foreign_keys = list( property._user_defined_foreign_keys ) foreign_keys.extend( list(property._calculated_foreign_keys) ) if property.direction == orm.interfaces.ONETOMANY: attributes.update( python_type = list, editable = True, nullable = True, delegate = delegates.One2ManyDelegate, target = target, create_inline = False, direction = 'onetomany', admin = get_entity_admin(target) ) elif property.direction == orm.interfaces.MANYTOONE: attributes.update( python_type = str, editable = True, delegate = delegates.Many2OneDelegate, target = target, # # @todo: take into account all foreign keys instead # of only the first one # nullable = foreign_keys[0].nullable, direction = 'manytoone', admin = get_entity_admin(target) ) elif property.direction == orm.interfaces.MANYTOMANY: attributes.update( python_type = list, editable = True, target = target, nullable = True, create_inline = False, direction = 'manytomany', delegate = delegates.One2ManyDelegate, admin = get_entity_admin(target) ) else: raise Exception('PropertyLoader has unknown direction') except InvalidRequestError: # # If the field name is not a property of the mapper, then use # the default stuff # pass if 'choices' in forced_attributes: attributes['delegate'] = delegates.ComboBoxDelegate attributes['editable'] = True if isinstance(forced_attributes['choices'], list): choices_dict = dict(forced_attributes['choices']) attributes['to_string'] = lambda x : choices_dict[x] # # Overrule introspected field_attributes with those defined # attributes.update(forced_attributes) # # In case of a 'target' field attribute, instantiate an appropriate # 'admin' attribute # if 'target' in attributes: attributes['target'] = resolve_target(attributes['target']) attributes['admin'] = get_entity_admin(attributes['target']) self._field_attributes[field_name] = attributes return attributes
def get_field_attributes(self, field_name): """Get the attributes needed to visualize the field field_name :param field_name: the name of the field :return: a dictionary of attributes needed to visualize the field, those attributes can be: * python_type : the corresponding python type of the object * editable : bool specifying wether the user can edit this field * widget : which widget to be used to render the field * ... """ from sqlalchemy.orm.mapper import _mapper_registry try: return self._field_attributes[field_name] except KeyError: def create_default_getter(field_name): return lambda o: getattr(o, field_name) from camelot.view.controls import delegates # # Default attributes for all fields # attributes = dict( python_type=str, to_string=to_string, field_name=field_name, getter=create_default_getter(field_name), length=None, tooltip=None, background_color=None, #minimal_column_width = 12, editable=False, nullable=True, widget='str', blank=True, delegate=delegates.PlainTextDelegate, validator_list=[], name=ugettext_lazy(field_name.replace('_', ' ').capitalize())) # # Field attributes forced by the field_attributes property # forced_attributes = {} try: forced_attributes = self.field_attributes[field_name] except KeyError: pass def resolve_target(target): """A class or name of the class representing the other side of a relation. Use the name of the class to avoid circular dependencies""" if isinstance(target, basestring): for mapped_class in _mapper_registry.keys(): if mapped_class.class_.__name__ == target: return mapped_class.class_ raise Exception('No mapped class found for target %s' % target) return target def get_entity_admin(target): """Helper function that instantiated an Admin object for a target entity class. :param target: an entity class for which an Admin object is needed """ try: admin_class = forced_attributes['admin'] return admin_class(self.app_admin, target) except KeyError: return self.get_related_admin(target) # # Get the default field_attributes trough introspection if the # field is a mapped field # from sqlalchemy import orm from sqlalchemy.exc import InvalidRequestError try: property = self.mapper.get_property(field_name) if isinstance(property, orm.properties.ColumnProperty): columns = property.columns sql_attributes = self.get_sql_field_attributes(columns) attributes.update(sql_attributes) elif isinstance(property, orm.properties.PropertyLoader): target = forced_attributes.get('target', property.mapper.class_) # # _foreign_keys is for sqla pre 0.6.4 # if hasattr(property, '_foreign_keys'): foreign_keys = list(property._foreign_keys) else: foreign_keys = list( property._user_defined_foreign_keys) foreign_keys.extend( list(property._calculated_foreign_keys)) if property.direction == orm.interfaces.ONETOMANY: attributes.update(python_type=list, editable=True, nullable=True, delegate=delegates.One2ManyDelegate, target=target, create_inline=False, direction='onetomany', admin=get_entity_admin(target)) elif property.direction == orm.interfaces.MANYTOONE: attributes.update( python_type=str, editable=True, delegate=delegates.Many2OneDelegate, target=target, # # @todo: take into account all foreign keys instead # of only the first one # nullable=foreign_keys[0].nullable, direction='manytoone', admin=get_entity_admin(target)) elif property.direction == orm.interfaces.MANYTOMANY: attributes.update(python_type=list, editable=True, target=target, nullable=True, create_inline=False, direction='manytomany', delegate=delegates.One2ManyDelegate, admin=get_entity_admin(target)) else: raise Exception('PropertyLoader has unknown direction') except InvalidRequestError: # # If the field name is not a property of the mapper, then use # the default stuff # pass if 'choices' in forced_attributes: attributes['delegate'] = delegates.ComboBoxDelegate attributes['editable'] = True if isinstance(forced_attributes['choices'], list): choices_dict = dict(forced_attributes['choices']) attributes['to_string'] = lambda x: choices_dict[x] # # Overrule introspected field_attributes with those defined # attributes.update(forced_attributes) # # In case of a 'target' field attribute, instantiate an appropriate # 'admin' attribute # if 'target' in attributes: attributes['target'] = resolve_target(attributes['target']) attributes['admin'] = get_entity_admin(attributes['target']) self._field_attributes[field_name] = attributes return attributes
def get_field_attributes(self, field_name): """ Get the attributes needed to visualize the field field_name. This function is called by get_static_field_attributes and get_dynamic_field_attributes. This function first tries to fill the dictionary with field attributes for a field with those gathered through introspection, and then updates them with those found in the field_attributes class attribute. :param field_name: the name of the field :return: a dictionary of attributes needed to visualize the field The values of the returned dictionary either contain the value of the field attribute, or in the case of dynamic field attributes, a function that returns the value of the field attribute. """ # # @todo : this function should return a frozen dictionary, so no # other parts of the application can modify the cached field # attributes # try: return self._field_attributes[field_name] except KeyError: from camelot.view.controls import delegates # # Default attributes for all fields # attributes = dict(to_string=to_string, field_name=field_name, python_type=str, length=None, tooltip=None, background_color=None, editable=False, nullable=True, widget='str', blank=True, delegate=delegates.PlainTextDelegate, validator_list=[], name=ugettext_lazy( field_name.replace('_', ' ').capitalize())) descriptor_attributes = self.get_descriptor_field_attributes( field_name) attributes.update(descriptor_attributes) # # first put the attributes in the cache, and only then start to expand # them, to be able to prevent recursion when expanding the attributes # self._field_attributes[field_name] = attributes forced_attributes = self.field_attributes.get(field_name, {}) attributes.update(forced_attributes) if 'choices' in forced_attributes: from camelot.view.controls import delegates attributes['delegate'] = delegates.ComboBoxDelegate if isinstance(forced_attributes['choices'], list): choices_dict = dict(forced_attributes['choices']) attributes['to_string'] = lambda x: choices_dict.get(x, '') self._expand_field_attributes(attributes, field_name) return attributes
def get_field_attributes(self, field_name): """Get the attributes needed to visualize the field field_name :param field_name: the name of the field :return: a dictionary of attributes needed to visualize the field, those attributes can be: * python_type : the corresponding python type of the object * editable : bool specifying wether the user can edit this field * widget : which widget to be used to render the field * ... """ try: return self._field_attributes[field_name] except KeyError: def create_default_getter(field_name): return lambda o: getattr(o, field_name) from camelot.view.controls import delegates # # Default attributes for all fields # attributes = dict(python_type=str, field_name=field_name, getter=create_default_getter(field_name), length=None, tooltip=None, background_color=None, minimal_column_width=12, editable=False, nullable=True, widget='str', blank=True, delegate=delegates.PlainTextDelegate, validator_list=[], name=ugettext_lazy( field_name.replace('_', ' ').capitalize())) # # Field attributes forced by the field_attributes property # forced_attributes = {} try: forced_attributes = self.field_attributes[field_name] except KeyError: pass def get_entity_admin(target): """Helper function that instantiated an Admin object for a target entity class. :param target: an entity class for which an Admin object is needed. """ try: fa = self.field_attributes[field_name] target = fa.get('target', target) admin_class = fa['admin'] return admin_class(self.app_admin, target) except KeyError: return self.get_related_entity_admin(target) # # Get the default field_attributes trough introspection if the # field is a mapped field # from sqlalchemy import orm from sqlalchemy.exceptions import InvalidRequestError from camelot.view.field_attributes import _sqlalchemy_to_python_type_ try: property = self.mapper.get_property(field_name, resolve_synonyms=True) if isinstance(property, orm.properties.ColumnProperty): column_type = property.columns[0].type python_type = _sqlalchemy_to_python_type_.get( column_type.__class__, None) if python_type: attributes.update(python_type(column_type)) if not isinstance( property.columns[0], (sqlalchemy.sql.expression._Label, sqlalchemy.sql.expression.ColumnClause)): attributes['nullable'] = property.columns[0].nullable attributes['default'] = property.columns[0].default elif isinstance(property, orm.properties.PropertyLoader): target = property._get_target().class_ # # _foreign_keys is for sqla pre 0.6.4 # if hasattr(property, '_foreign_keys'): foreign_keys = list(property._foreign_keys) else: foreign_keys = list( property._user_defined_foreign_keys) foreign_keys.extend( list(property._calculated_foreign_keys)) if property.direction == orm.interfaces.ONETOMANY: attributes.update(python_type=list, editable=True, nullable=True, delegate=delegates.One2ManyDelegate, target=target, create_inline=False, direction=property.direction, admin=get_entity_admin(target)) elif property.direction == orm.interfaces.MANYTOONE: attributes.update( python_type=str, editable=True, delegate=delegates.Many2OneDelegate, target=target, # # @todo: take into account all foreign keys instead # of only the first one # nullable=foreign_keys[0].nullable, direction=property.direction, admin=get_entity_admin(target)) elif property.direction == orm.interfaces.MANYTOMANY: attributes.update( python_type=list, editable=True, target=target, nullable=True, create_inline=False, direction=property.direction, delegate=delegates.ManyToManyDelegate, admin=get_entity_admin(target)) else: raise Exception('PropertyLoader has unknown direction') except InvalidRequestError: # # If the field name is not a property of the mapper, then use # the default stuff # pass if 'choices' in forced_attributes: attributes['delegate'] = delegates.ComboBoxDelegate attributes['editable'] = True # # Overrule introspected field_attributes with those defined # attributes.update(forced_attributes) # # In case of a 'target' field attribute, instantiate an appropriate # 'admin' attribute # if 'target' in attributes: attributes['admin'] = get_entity_admin(attributes['target']) self._field_attributes[field_name] = attributes return attributes
def get_field_attributes(self, field_name): """Get the attributes needed to visualize the field field_name :param field_name: the name of the field :return: a dictionary of attributes needed to visualize the field, those attributes can be: * python_type : the corresponding python type of the object * editable : bool specifying wether the user can edit this field * widget : which widget to be used to render the field * ... """ try: return self._field_attributes[field_name] except KeyError: def create_default_getter(field_name): return lambda o: getattr(o, field_name) from camelot.view.controls import delegates # # Default attributes for all fields # attributes = dict( python_type=str, field_name=field_name, getter=create_default_getter(field_name), length=None, tooltip=None, background_color=None, minimal_column_width=12, editable=False, nullable=True, widget="str", blank=True, delegate=delegates.PlainTextDelegate, validator_list=[], name=ugettext_lazy(field_name.replace("_", " ").capitalize()), ) # # Field attributes forced by the field_attributes property # forced_attributes = {} try: forced_attributes = self.field_attributes[field_name] except KeyError: pass def get_entity_admin(target): """Helper function that instantiated an Admin object for a target entity class. :param target: an entity class for which an Admin object is needed. """ try: fa = self.field_attributes[field_name] target = fa.get("target", target) admin_class = fa["admin"] return admin_class(self.app_admin, target) except KeyError: return self.get_related_entity_admin(target) # # Get the default field_attributes trough introspection if the # field is a mapped field # from sqlalchemy import orm from sqlalchemy.exceptions import InvalidRequestError from camelot.view.field_attributes import _sqlalchemy_to_python_type_ try: property = self.mapper.get_property(field_name, resolve_synonyms=True) if isinstance(property, orm.properties.ColumnProperty): column_type = property.columns[0].type python_type = _sqlalchemy_to_python_type_.get(column_type.__class__, None) if python_type: attributes.update(python_type(column_type)) if not isinstance( property.columns[0], (sqlalchemy.sql.expression._Label, sqlalchemy.sql.expression.ColumnClause) ): attributes["nullable"] = property.columns[0].nullable attributes["default"] = property.columns[0].default elif isinstance(property, orm.properties.PropertyLoader): target = property._get_target().class_ # # _foreign_keys is for sqla pre 0.6.4 # if hasattr(property, "_foreign_keys"): foreign_keys = list(property._foreign_keys) else: foreign_keys = list(property._user_defined_foreign_keys) foreign_keys.extend(list(property._calculated_foreign_keys)) if property.direction == orm.interfaces.ONETOMANY: attributes.update( python_type=list, editable=True, nullable=True, delegate=delegates.One2ManyDelegate, target=target, create_inline=False, direction=property.direction, admin=get_entity_admin(target), ) elif property.direction == orm.interfaces.MANYTOONE: attributes.update( python_type=str, editable=True, delegate=delegates.Many2OneDelegate, target=target, # # @todo: take into account all foreign keys instead # of only the first one # nullable=foreign_keys[0].nullable, direction=property.direction, admin=get_entity_admin(target), ) elif property.direction == orm.interfaces.MANYTOMANY: attributes.update( python_type=list, editable=True, target=target, nullable=True, create_inline=False, direction=property.direction, delegate=delegates.ManyToManyDelegate, admin=get_entity_admin(target), ) else: raise Exception("PropertyLoader has unknown direction") except InvalidRequestError: # # If the field name is not a property of the mapper, then use # the default stuff # pass if "choices" in forced_attributes: attributes["delegate"] = delegates.ComboBoxDelegate attributes["editable"] = True # # Overrule introspected field_attributes with those defined # attributes.update(forced_attributes) # # In case of a 'target' field attribute, instantiate an appropriate # 'admin' attribute # if "target" in attributes: attributes["admin"] = get_entity_admin(attributes["target"]) self._field_attributes[field_name] = attributes return attributes