def onAddSourceDocument(self,doctype): ''' Slot raised when the user has selected to add a new source document. ''' #Create a proxy source document manager for inserting documents. srcDocManager = SourceDocumentManager(self.parentWidget()) vBoxProxy = QVBoxLayout(self._parentWidget) self._parentWidget.connect(srcDocManager,SIGNAL("fileUploaded(PyQt_PyObject)"), self._onSourceDocUploaded) if doctype == TITLE_DEED: dialogTitle = QApplication.translate("STRNode", "Specify Title Deed File Location") elif doctype == STATUTORY_REF_PAPER: dialogTitle = QApplication.translate("STRNode", "Specify Statutory Reference Paper File Location") elif doctype == SURVEYOR_REF: dialogTitle = QApplication.translate("STRNode", "Specify Surveyor Reference File Location") elif doctype == NOTARY_REF: dialogTitle = QApplication.translate("STRNode", "Specify Notary Reference File Location") else: return docPath = self._selectSourceDocumentDialog(dialogTitle) if not docPath.isNull(): #Register container then upload document srcDocManager.registerContainer(vBoxProxy, doctype) srcDocManager.insertDocumentFromFile(docPath,doctype)
class Save2DB: """ Class to insert entity data into db """ def __init__(self, entity, attributes, ids=None): """ Initialize class and class variable """ self.attributes = attributes self.form_entity = entity self.doc_model = None self._doc_manager = None self.entity = self.object_from_entity_name(self.form_entity) self.model = self.dbmodel_from_entity() self.key = 0 self.parents_ids = ids self.geom = 4326 self.entity_mapping = {} def object_from_entity_name(self, entity): """ :return: """ if entity == 'social_tenure': return current_profile().social_tenure else: user_entity = current_profile().entity_by_name(entity) return user_entity def entity_has_supporting_docs(self): """ Check if the entity has supporting document before importing :return: Bool """ if self.entity.supports_documents: return self.entity.supports_documents else: return None def entity_supported_document_types(self): """ Get the supported document types before importing so that they are captured during import process :return: List """ return self.entity.document_types_non_hex() def dbmodel_from_entity(self): """ Format model attributes from passed entity attributes :return: """ if self.entity_has_supporting_docs(): entity_object, self.doc_model = entity_model( self.entity, with_supporting_document=True) entity_object_model = entity_object() if hasattr(entity_object_model, 'documents'): if self.entity.TYPE_INFO == 'SOCIAL_TENURE': obj_doc_col = current_profile( ).social_tenure.supporting_doc else: obj_doc_col = self.entity.supporting_doc self._doc_manager = SourceDocumentManager( obj_doc_col, self.doc_model) else: entity_object = entity_model(self.entity) entity_object_model = entity_object() return entity_object_model def objects_from_supporting_doc(self, instance_file=None): """ Create supporting doc path instances based on the collected documents :return:paths :rtype: document object instance """ if instance_file: f_dir, file_name = os.path.split(instance_file) for document, val in self.attributes.iteritems(): if str(document).endswith('supporting_document'): if val != '': doc = self.format_document_name_from_attribute( document) doc_path = os.path.normpath(f_dir + '/' + val) abs_path = doc_path.replace('\\', '/').strip() if QFile.exists(abs_path): self.supporting_document_model(abs_path, doc) def supporting_document_model(self, doc_path, doc): """ :param doc_path: absolute document path :param doc: document name :type: str Construct supporting document model instance to add into the db :return: """ # Create document container doc_container = QVBoxLayout() supporting_doc_entity = self.entity.supporting_doc.document_type_entity document_type_id = entity_attr_to_id(supporting_doc_entity, 'value', doc, lower=False) # Register container self._doc_manager.registerContainer(doc_container, document_type_id) #Copy the document to STDM working directory self._doc_manager.insertDocumentFromFile(doc_path, document_type_id, self.entity) def format_document_name_from_attribute(self, doc): """ Get the type of document from attribute name So that supporting document class instance can save it in the right format :return: """ formatted_doc_list = self.entity_supported_document_types() default = 'General' doc_type = str(doc).split('_', 1) if doc_type[0].startswith( 'supporting') and formatted_doc_list[0] == default: return default elif doc_type[0].startswith( 'supporting') and formatted_doc_list[0] != default: return formatted_doc_list[0] elif not doc_type[0].startswith('supporting'): actual_doc_name = doc_type[0].replace('-', ' ') for doc_name in formatted_doc_list: if actual_doc_name in doc_name or doc_name.startswith( actual_doc_name): return doc_name else: return formatted_doc_list[0] else: return formatted_doc_list[0] def extract_social_tenure_entities(self): ''' We want to extract social tenure enities so that we know if it has multiple or single entities in the list :return: ''' party_ref_column = '' spatial_ref_column = '' if self.parents_ids is not None: print self.parents_ids if self.attributes.has_key('party'): full_party_ref_column = self.attributes.get('party') party_ref_column = full_party_ref_column + '_id' print 'party{}.'.format(party_ref_column) setattr(self.model, party_ref_column, self.parents_ids.get(full_party_ref_column)[0]) if self.attributes.has_key('spatial_unit'): full_spatial_ref_column = self.attributes.get('spatial_unit') spatial_ref_column = full_spatial_ref_column + '_id' print 'sp.{}.'.format(spatial_ref_column) setattr(self.model, spatial_ref_column, self.parents_ids.get(full_spatial_ref_column)[0]) return party_ref_column, spatial_ref_column def save_to_db(self): """ Format object attribute data from entity and save them into database :return: """ self.column_info() attributes = self.attributes try: if self.entity.short_name == 'social_tenure_relationship': #try: prefix = current_profile().prefix + '_' if self.attributes.has_key('party'): full_party_ref_column = self.attributes.get('party') party_ref_column = full_party_ref_column + '_id' self.attributes.pop('party') else: full_party_ref_column = current_profile( ).social_tenure.parties[0].name party_ref_column = full_party_ref_column.replace( prefix, '') + '_id' setattr(self.model, party_ref_column, self.parents_ids.get(full_party_ref_column)[0]) if self.attributes.has_key('spatial_unit'): full_spatial_ref_column = self.attributes.get( 'spatial_unit') spatial_ref_column = full_spatial_ref_column + '_id' self.attributes.pop('spatial_unit') else: full_spatial_ref_column = current_profile( ).social_tenure.spatial_units[0].name spatial_ref_column = full_spatial_ref_column.replace( prefix, '') + '_id' setattr(self.model, spatial_ref_column, self.parents_ids.get(full_spatial_ref_column)[0]) attributes = self.attributes['social_tenure'] except: pass for k, v in attributes.iteritems(): if hasattr(self.model, k): col_type = self.entity_mapping.get(k) col_prop = self.entity.columns[k] var = self.attribute_formatter(col_type, col_prop, v) setattr(self.model, k, var) if self.entity_has_supporting_docs(): self.model.documents = self._doc_manager.model_objects() self.model.save() return self.model.id def save_parent_to_db(self): """ Format object attribute data from entity and save them into database attribute :return: """ self.column_info() for k, v in self.attributes.iteritems(): if hasattr(self.model, k): col_type = self.entity_mapping.get(k) col_prop = self.entity.columns[k] #print "property{0}.... and type.{1}".format(col_prop, col_type) var = self.attribute_formatter(col_type, col_prop, v) setattr(self.model, k, var) if self.entity_has_supporting_docs(): self.model.documents = self._doc_manager.model_objects() self.model.save() self.key = self.model.id return self.key def save_foreign_key_table(self): """ Get the table with foreign keys only :return: """ for col, type_info in self.column_info().iteritems(): col_prop = self.entity.columns[col] var = self.attribute_formatter(type_info, col_prop, None) setattr(self.model, col, var) self.model.save() self.cleanup() def column_info(self): """ :return: """ self.entity_mapping = {} cols = self.entity.columns.values() for c in cols: self.entity_mapping[c.name] = c.TYPE_INFO def get_srid(self, srid): """ Let the user specify the coordinate system during data import :param srid: :return: """ self.geom = srid return self.geom def id_from_model_object(self, obj): """ We need to obtian id from object instance :param obj: :return: """ return obj.id def attribute_formatter(self, col_type, col_prop, var=None): """ Format geoodk attributes collected in the field to conform to STDM database contrains :return: """ if col_type == 'BOOL': if len(var) < 1: return None if len(var) > 1: if var == '' or var is None: return None if var == 'Yes' or var == True: return True if var == 'No' or var == False: return False else: return None if col_type == 'LOOKUP': if len(var) < 1 or var is None: return None if len(var) < 4: if var == 'Yes' or var == 'No': return entity_attr_to_model(col_prop.parent, 'value', var).id if var != 'Yes' and var != 'No': lk_code = entity_attr_to_id(col_prop.parent, "code", var) if not str(lk_code).isdigit(): return None else: return lk_code if len(var) > 3: if not str(entity_attr_to_id(col_prop.parent, 'code', var)).isdigit(): id_value = entity_attr_to_model(col_prop.parent, 'value', var) if id_value is not None: return id_value.id #return entity_attr_to_model(col_prop.parent, 'value', var).id else: lk_code = entity_attr_to_id(col_prop.parent, "code", var) if not str(lk_code).isdigit(): return None else: return lk_code else: return None elif col_type == 'ADMIN_SPATIAL_UNIT': var_code = None try: if len(var) < 1 or var is None: return None elif not len(var) > 3: var_code = entity_attr_to_id(col_prop.parent, "code", var) if var_code and var_code == var: return None else: return var_code elif len(var) > 3 and entity_attr_to_id( col_prop.parent, "name", var) is not None: var_code = entity_attr_to_id(col_prop.parent, "name", var) if var_code and var_code == var: return None else: return var_code else: if entity_attr_to_id(col_prop.parent, "name", var) is None: var_code = entity_attr_to_id(col_prop.parent, "code", var) if not var_code or var_code == var: return None except: pass elif col_type == 'MULTIPLE_SELECT': print 'multiple select {}'.format(var) if var == '' or var is None: return None else: col_parent = col_prop.association.first_parent lk_val_list = col_parent.values.values() choices_list = [] for code in lk_val_list: choices_list.append( entity_attr_to_id(col_parent.association.first_parent, 'value', code.value)) if len(choices_list) > 1: return choices_list else: return None elif col_type == 'GEOMETRY': defualt_srid = 0 if var: geom_provider = STDMGeometry(var) if isinstance(col_prop, GeometryColumn): defualt_srid = col_prop.srid if defualt_srid != 0: geom_provider.set_user_srid(defualt_srid) else: geom_provider.set_user_srid(GEOMPARAM) if col_prop.geometry_type() == 'POINT': return geom_provider.point_to_Wkt() if col_prop.geometry_type() == 'POLYGON': return geom_provider.polygon_to_Wkt() else: return None elif col_type == 'FOREIGN_KEY': ret_val = None for code, val in self.parents_ids.iteritems(): if col_prop.parent.name == code: ret_val = val[0] break return ret_val elif col_type == 'INT' or col_type == 'DOUBLE' or col_type == 'PERCENT': ret_val = None if var <> '': ret_val = var return ret_val elif col_type == 'DATETIME' or col_type == 'DATE': ret_val = None if var <> '': ret_val = var return ret_val else: return var def cleanup(self): """ Reset all the model and entity data before we process the next entity data :return: None z""" self.model = None self.entity = None self.attributes = None self._doc_manager = None
class SupportingDocuments(ComponentUtility): onUploadDocument = pyqtSignal(list) def __init__(self, box, combobox, add_documents_btn, notification_bar, parent=None): """ Handles the supporting documents component loading. :param box: The layout holding the container widget. :type box: QVBoxLayout :param combobox: The combobox loading supporting document types. :type combobox: QComboBox :param add_documents_btn: The add supporting document button :type add_documents_btn: QPushButton :param notification_bar: The NotificationBar object that displays notification. :type notification_bar: Object :param parent: The container of the widget :type parent: QDialog or None """ ComponentUtility.__init__(self) self._parent = parent self.container_box = box self.doc_type_cbo = combobox self.notification_bar = notification_bar self.str_number = 1 self.add_documents_btn = add_documents_btn self.str_numbers = [1] self.current_party_count = None self.init_documents() def init_documents(self): """ Initializes the document type combobox by populating data. """ self.supporting_doc_manager = SourceDocumentManager( self.social_tenure.supporting_doc, self.str_doc_model, self._parent) self.create_doc_tab_populate_combobox() self.doc_type_cbo.currentIndexChanged.connect( self.match_doc_combo_to_tab) self.docs_tab.currentChanged.connect(self.match_doc_tab_to_combo) def party_count(self, count): """ A setter for current_party_count that is used to determined the number of copies for each supporting document. :param count: The number of currently added party records. :type count: Integer """ self.current_party_count = count def create_doc_tab_populate_combobox(self): """ Creates the supporting document component widget. """ self.doc_tab_data() self.docs_tab = QTabWidget() self.docs_tab_index = OrderedDict() for i, (id, doc) in enumerate(self.doc_types.iteritems()): self.docs_tab_index[doc] = i # the tab widget containing the document widget layout # and the child of the tab. tab_widget = QWidget() tab_widget.setObjectName(doc) # The layout of the tab widget cont_layout = QVBoxLayout(tab_widget) cont_layout.setObjectName(u'widget_layout_{}'.format(doc)) # the scroll area widget inside the tab widget. scroll_area = QScrollArea(tab_widget) scroll_area.setFrameShape(QFrame.NoFrame) scroll_area.setObjectName(u'tab_scroll_area_{}'.format(doc)) layout_widget = QWidget() # the widget the is under the scroll area content and # the widget containing the document widget layout # This widget is hidden and shown based on the STR number layout_widget.setObjectName(u'widget_{}'.format(doc)) doc_widget_layout = QVBoxLayout(layout_widget) doc_widget_layout.setObjectName( u'doc_widget_layout_{}'.format(doc)) doc_widget = QWidget() doc_widget.setObjectName(u'doc_widget_{}_{}'.format( doc, self.str_number)) doc_widget_layout.addWidget(doc_widget) # the layout containing document widget. ### This is the layout that is registered to add uploaded # supporting documents widgets into. tab_layout = QVBoxLayout(doc_widget) tab_layout.setObjectName(u'layout_{}_{}'.format( doc, self.str_number)) scroll_area.setWidgetResizable(True) scroll_area.setWidget(layout_widget) cont_layout.addWidget(scroll_area) # Add the tab widget with the document # type name to create a tab. self.docs_tab.addTab(tab_widget, doc) self.container_box.addWidget(self.docs_tab, 1) if len(self.str_numbers) == 1: self.doc_type_cbo.addItem(doc, id) def doc_tab_data(self): """ Sets the document types in the social tenure entity. """ doc_entity = self.social_tenure. \ supporting_doc.document_type_entity doc_type_model = entity_model(doc_entity) docs = doc_type_model() doc_type_list = docs.queryObject().all() self.doc_types = [(doc.id, doc.value) for doc in doc_type_list] self.doc_types = OrderedDict(self.doc_types) def match_doc_combo_to_tab(self): """ Changes the active tab based on the selected value of document type combobox. """ combo_text = self.doc_type_cbo.currentText() if combo_text is not None and len(combo_text) > 0: index = self.docs_tab_index[combo_text] self.docs_tab.setCurrentIndex(index) def match_doc_tab_to_combo(self): """ Changes the document type combobox value based on the selected tab. """ doc_tab_index = self.docs_tab.currentIndex() self.doc_type_cbo.setCurrentIndex(doc_tab_index) @staticmethod def hide_doc_widgets(widget, visibility): """ Hides or shows the visibility of the supporting document container widgets. :param widget: The widget to which the visibility is set. :type widget: QWidget :param visibility: A boolean to show or hide visibility. True hides widget and False shows it. :type visibility: Boolean """ widget.setHidden(visibility) def update_container(self, str_number): """ Update the current supporting document widget container to be used. :param str_number: The STR node number :type str_number: Integer """ doc_text = self.doc_type_cbo.currentText() cbo_index = self.doc_type_cbo.currentIndex() doc_id = self.doc_type_cbo.itemData(cbo_index) scroll_area = self.docs_tab.findChild( QScrollArea, u'tab_scroll_area_{}'.format(doc_text, str_number)) doc_widget = scroll_area.findChild( QWidget, u'doc_widget_{}_{}'.format(doc_text, str_number)) # If the doc widget doesn't exist create it for new STR instance if doc_widget is None: # find the doc_widget layout that contains # all STR doc widget layouts. Single # doc_widget_layout is created for each document type. # But all doc_widgets for each STR instance and # document types will be added here. doc_widget_layout = scroll_area.findChild( QVBoxLayout, u'doc_widget_layout_{}'.format(doc_text)) doc_widget = QWidget() doc_widget.setObjectName(u'doc_widget_{}_{}'.format( doc_text, str_number)) self.hide_all_other_widget(doc_text, str_number) doc_widget_layout.addWidget(doc_widget) # Create the layout so that layouts are registered in # which uploaded document widgets are added. layout = QVBoxLayout(doc_widget) layout.setObjectName(u'layout_{}_{}'.format(doc_text, str_number)) # If the doc widget exists, get the lowest # layout so that it is registered. else: # hide all other widgets self.hide_all_other_widget(doc_text, str_number) # show the current doc widget to display # the document widgets for the current tab. self.hide_doc_widgets(doc_widget, False) layout = doc_widget.findChild( QVBoxLayout, u'layout_{}_{}'.format(doc_text, str_number)) # register layout self.supporting_doc_manager.registerContainer(layout, doc_id) def hide_all_other_widget(self, doc_text, str_number): """ Hides all other supporting document widget except the current STR node widget. :param doc_text: The current document type selected. :type doc_text: String :param str_number: The STR node number :type str_number: Integer """ expression = QRegExp(u'doc_widget*') # hide all existing widgets in all layouts for widget in self.docs_tab.findChildren(QWidget, expression): if widget.objectName() != u'doc_widget_{}_{}'.format( doc_text, str_number): self.hide_doc_widgets(widget, True) def on_upload_document(self): ''' Slot raised when the user clicks to upload a supporting document. ''' document_str = QApplication.translate( "SupportingDocuments", "Specify the Document File Location") documents = self.select_file_dialog(document_str) cbo_index = self.doc_type_cbo.currentIndex() doc_id = self.doc_type_cbo.itemData(cbo_index) for doc in documents: self.supporting_doc_manager.insertDocumentFromFile( doc, doc_id, self.social_tenure, self.current_party_count) # Set last path if len(documents) > 0: doc = documents[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path) model_objs = self.supporting_doc_manager.model_objects() self.onUploadDocument.emit(model_objs) def select_file_dialog(self, title): """ Displays a file dialog for a user to specify a source document :param title: The title of the file dialog :type title: String """ # Get last path for supporting documents last_path = last_document_path() if last_path is None: last_path = '/home' files = QFileDialog.getOpenFileNames( iface.mainWindow(), title, last_path, "Source Documents (*.jpg *.jpeg *.png *.bmp *.tiff *.svg)") return files
class Save2DB: """ Class to insert entity data into db """ def __init__(self, entity, attributes, ids=None): """ Initialize class and class variable """ self.attributes = attributes self.form_entity = entity self.doc_model = None self._doc_manager = None self.entity = self.object_from_entity_name(self.form_entity) self.model = self.dbmodel_from_entity() self.key = 0 self.parents_ids = ids self.geom = 4326 def object_from_entity_name(self, entity): """ :return: """ if entity == 'social_tenure': return current_profile().social_tenure else: user_entity = current_profile().entity_by_name(entity) return user_entity def entity_has_supporting_docs(self): """ Check if the entity has supporting document before importing :return: Bool """ return self.entity.supports_documents def entity_supported_document_types(self): """ Get the supported document types before importing so that they are captured during import process :return: List """ return self.entity.document_types_non_hex() def dbmodel_from_entity(self): """ Format model attributes from passed entity attributes :return: """ if self.entity_has_supporting_docs(): entity_object, self.doc_model = entity_model( self.entity, with_supporting_document=True) entity_object_model = entity_object() if hasattr(entity_object_model, 'documents'): if self.entity.TYPE_INFO == 'SOCIAL_TENURE': obj_doc_col = current_profile( ).social_tenure.supporting_doc else: obj_doc_col = self.entity.supporting_doc self._doc_manager = SourceDocumentManager( obj_doc_col, self.doc_model) else: entity_object = entity_model(self.entity) entity_object_model = entity_object() return entity_object_model def objects_from_supporting_doc(self, instance_file=None): """ Create supporting doc path instances based on the collected documents :return:paths :rtype: document object instance """ if instance_file: f_dir, file_name = os.path.split(instance_file) for document, val in self.attributes.iteritems(): if str(document).endswith('supporting_document'): if val != '': doc = self.format_document_name_from_attribute( document) doc_path = os.path.normpath(f_dir + '/' + val) abs_path = doc_path.replace('\\', '/').strip() if QFile.exists(abs_path): self.supporting_document_model(abs_path, doc) def supporting_document_model(self, doc_path, doc): """ Construct supporting document model instance to add into the db :return: """ # Create document container doc_container = QVBoxLayout() supporting_doc_entity = self.entity.supporting_doc.document_type_entity document_type_id = entity_attr_to_id(supporting_doc_entity, 'value', doc, lower=False) # Register container self._doc_manager.registerContainer(doc_container, document_type_id) #Copy the document to STDM working directory self._doc_manager.insertDocumentFromFile(doc_path, document_type_id, self.entity) def format_document_name_from_attribute(self, key_name): """ Get the type of document from attribute name So that supporting document class instance can save it in the right format :return: """ doc_list = self.entity_supported_document_types() default = 'General' doc_type = str(key_name).split('_') if len(doc_type) > 2: if doc_type[0] in doc_list: return doc_type[0] else: for doc in doc_list: if doc.startswith(doc_type[0]): return doc elif len(doc_type) < 2 and key_name != default: return key_name else: return default def save_to_db(self): """ Format object attribute data from entity and save them into database :return: """ try: if self.parents_ids is not None and self.entity.short_name == 'social_tenure_relationship': str_tables = current_profile().social_tenure setattr(self.model, str_tables.parties[0].short_name.lower() + '_id', self.parents_ids.get(str_tables.parties[0].name)[0]) setattr( self.model, str_tables.spatial_units[0].short_name.lower() + '_id', self.parents_ids.get(str_tables.spatial_units[0].name)[0]) except: pass for k, v in self.attributes.iteritems(): if hasattr(self.model, k): col_type = self.column_info().get(k) col_prop = self.entity.columns[k] var = self.attribute_formatter(col_type, col_prop, v) setattr(self.model, k, var) if self.entity_has_supporting_docs(): self.model.documents = self._doc_manager.model_objects() self.model.save() return self.model.id #self.cleanup() def save_parent_to_db(self): """ Format object attribute data from entity and save them into database attribute :return: """ for k, v in self.attributes.iteritems(): if hasattr(self.model, k): col_type = self.column_info().get(k) col_prop = self.entity.columns[k] var = self.attribute_formatter(col_type, col_prop, v) setattr(self.model, k, var) if self.entity_has_supporting_docs(): self.model.documents = self._doc_manager.model_objects() self.model.save() self.key = self.model.id return self.key #def model_object_formatter(self): def column_info(self): """ :return: """ type_mapping = {} cols = self.entity.columns.values() for c in cols: type_mapping[c.name] = c.TYPE_INFO return type_mapping def get_srid(self, srid): """ Let the user specify the coordinate system during data import :param srid: :return: """ self.geom = srid return self.geom def id_from_model_object(self, obj): """ We need to obtian id from object instance :param obj: :return: """ return obj.id def attribute_formatter(self, col_type, col_prop, var): """ :return: """ if col_type == 'LOOKUP': if var == '' or var is None: return None if var == 'Yes' or var == 'No': return entity_attr_to_model(col_prop.parent, 'value', var).id if not len(var) > 3 and var != 'Yes' and var != 'No': lk_code = entity_attr_to_id(col_prop.parent, "code", var) if not str(lk_code).isdigit(): return None else: return lk_code if len(var) > 3: if not str(entity_attr_to_id(col_prop.parent, 'code', var)).isdigit(): return entity_attr_to_model(col_prop.parent, 'value', var).id else: lk_code = entity_attr_to_id(col_prop.parent, "code", var) if not str(lk_code).isdigit(): return None else: return lk_code else: return None elif col_type == 'ADMIN_SPATIAL_UNIT': if not len(var) > 3: return entity_attr_to_id(col_prop.parent, "code", var) else: return entity_attr_to_id(col_prop.parent, "name", var) elif col_type == 'MULTIPLE_SELECT': if var == '' or var is None: return None if not len(var) > 3: return entity_attr_to_id(col_prop.association.first_parent, "code", var) elif len(var) > 3: if not str( entity_attr_to_id(col_prop.association.first_parent, "code", var)).isdigit(): return entity_attr_to_model( col_prop.association.first_parent, 'value', var).id else: return entity_attr_to_id(col_prop.association.first_parent, "code", var) elif col_type == 'GEOMETRY': defualt_srid = 0 geom_provider = STDMGeometry(var) if isinstance(col_prop, GeometryColumn): defualt_srid = col_prop.srid if defualt_srid != 0: geom_provider.set_user_srid(defualt_srid) else: geom_provider.set_user_srid(GEOMPARAM) if col_prop.geometry_type() == 'POINT': return geom_provider.point_to_Wkt() if col_prop.geometry_type() == 'POLYGON': return geom_provider.polygon_to_Wkt() elif col_type == 'FOREIGN_KEY': if self.parents_ids is None or len(self.parents_ids) < 0: return else: for code, val in self.parents_ids.iteritems(): if code is not None: if val[1] == GROUPCODE and col_prop.parent.name == code: return val[0] else: if col_prop.parent.name == code: return val[0] elif col_type == 'INT' or col_type == 'DOUBLE': if var == '': return 0 else: return var else: return var def cleanup(self): """ Reset all the model and entity data before we process the next entity data :return: None z""" self.model = None self.entity = None self.attributes = None self._doc_manager = None
class SupportingDocumentsWidget(QWidget): """ Widget for managing an entity's supporting documents. It enables listing of documents grouped by tabs depending on type. """ def __init__(self, entity_supporting_document, supporting_doc_model_cls, parent=None): """ Class constructor. :param entity_supporting_document: Object containing information pertaining to document types, parent entity etc. :type entity_supporting_document: EntitySupportingDocument :param supporting_doc_model_cls: Class representing the data model corresponding to the entity supporting document object. :type supporting_doc_model_cls: object :param parent: Parent container widget. :type parent: QWidget """ QWidget.__init__(self, parent) self._init_gui() self._entity_supporting_doc = entity_supporting_document #Container for document type widgets based on lookup id self._doc_type_widgets = {} #Init document manager self.source_document_manager = SourceDocumentManager( self._entity_supporting_doc, supporting_doc_model_cls, self) self._load_document_types() #Connect signals self._btn_add_document.clicked.connect( self._on_add_supporting_document) self._cbo_doc_type.currentIndexChanged.connect( self.on_doc_type_changed) self._doc_tab_container.currentChanged.connect( self.on_tab_doc_type_changed) def _init_gui(self): self._gl = QGridLayout(self) self._label = QLabel(self) self._label.setText(self.tr('Select document type')) self._gl.addWidget(self._label, 0, 0, 1, 1) self._cbo_doc_type = QComboBox(self) self._gl.addWidget(self._cbo_doc_type, 0, 1, 1, 1) self._btn_add_document = QPushButton(self) doc_ico = QIcon(':/plugins/stdm/images/icons/document.png') self._btn_add_document.setIcon(doc_ico) self._btn_add_document.setText(self.tr('Add document...')) self._btn_add_document.setMaximumWidth(200) self._gl.addWidget(self._btn_add_document, 0, 2, 1, 1) self._doc_tab_container = QTabWidget(self) self._gl.addWidget(self._doc_tab_container, 1, 0, 1, 3) self.setMinimumHeight(140) def on_doc_type_changed(self, idx): """ Slot raised when the document types changes. The corresponding widget in the tab container is also selected. :param idx: Item index in the combobox. :type idx: int """ if idx == -1: return self._doc_tab_container.setCurrentIndex(idx) def on_tab_doc_type_changed(self, idx): """ Slot raised when the document types changes. The corresponding widget in the tab container is also selected. :param idx: Item index in the tab widget. :type idx: int """ if idx == -1: return self._cbo_doc_type.setCurrentIndex(idx) def current_document_type(self): """ :return: Returns the currently selected document type in the combobox. :rtype: str """ return self._cbo_doc_type.currentText() def current_document_type_id(self): """ :return: Returns the primary key/id of the currently selected document type in the combobox, else -1 if there is not current item in the combobox :rtype: int """ if not self.current_document_type(): return -1 curr_idx = self._cbo_doc_type.currentIndex() return self._cbo_doc_type.itemData(curr_idx) def count(self): """ :return: Returns the number of document types supported by this widget. :rtype: int """ return self._cbo_doc_type.count() def document_type_containers(self): """ :return: Returns a list of document container widgets for all registered document types. :rtype: list """ return self.source_document_manager.containers.values() def document_type_widget(self, name): """ Searches for the document type widget that corresponds to the given name. :param name: Name of the document type. :type name: str :return: Returns the document widget corresponding to the given type name. :rtype: QWidget """ idx = self._cbo_doc_type.findText(name) if idx == -1: return None rec_id = self._cbo_doc_type.itemData(idx) return self._doc_type_widgets.get(rec_id, None) def _load_document_types(self): #Load document types in the combobox and tab widget vl_cls = entity_model(self._entity_supporting_doc.document_type_entity, entity_only=True) vl_obj = vl_cls() res = vl_obj.queryObject().all() for r in res: #Add to combo self._cbo_doc_type.addItem(r.value, r.id) #Add to tab widget doc_type_widget = _DocumentTypeContainer(self) self._doc_tab_container.addTab(doc_type_widget, r.value) self._doc_type_widgets[r.id] = doc_type_widget #Register container self.source_document_manager.registerContainer( doc_type_widget.container, r.id) def _on_add_supporting_document(self): #Slot raised when the user select to add a supporting document if self.count == 0: return select = self.tr('Select') supporting_docs_str = 'Supporting Documents' title = u'{0} {1} {2}'.format(select, self.current_document_type(), supporting_docs_str) filter_str = u'{0} (*.jpg *.jpeg *.png *.bmp *.tiff *.svg *.pdf)'.format( supporting_docs_str) #Get last path for supporting documents last_path = last_document_path() if last_path is None: last_path = '/home' else: dir = QDir(last_path) if not dir.exists(): last_path = '/home' source_docs = QFileDialog.getOpenFileNames(self, title, last_path, filter_str) doc_type_id = self._cbo_doc_type.itemData( self._cbo_doc_type.currentIndex()) parent_entity = self._entity_supporting_doc.parent_entity for doc in source_docs: self.source_document_manager.insertDocumentFromFile( doc, doc_type_id, parent_entity) #Set last path if len(source_docs) > 0: doc = source_docs[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path)
class SupportingDocumentsWidget(QWidget): """ Widget for managing an entity's supporting documents. It enables listing of documents grouped by tabs depending on type. """ def __init__(self, entity_supporting_document, supporting_doc_model_cls, parent=None): """ Class constructor. :param entity_supporting_document: Object containing information pertaining to document types, parent entity etc. :type entity_supporting_document: EntitySupportingDocument :param supporting_doc_model_cls: Class representing the data model corresponding to the entity supporting document object. :type supporting_doc_model_cls: object :param parent: Parent container widget. :type parent: QWidget """ QWidget.__init__(self, parent) self._init_gui() self._entity_supporting_doc = entity_supporting_document #Container for document type widgets based on lookup id self._doc_type_widgets = {} #Init document manager self.source_document_manager = SourceDocumentManager( self._entity_supporting_doc, supporting_doc_model_cls, self ) self._load_document_types() #Connect signals self._btn_add_document.clicked.connect( self._on_add_supporting_document ) self._cbo_doc_type.currentIndexChanged.connect( self.on_doc_type_changed ) self._doc_tab_container.currentChanged.connect( self.on_tab_doc_type_changed ) def _init_gui(self): self._gl = QGridLayout(self) self._label = QLabel(self) self._label.setText(self.tr('Select document type')) self._gl.addWidget(self._label, 0, 0, 1, 1) self._cbo_doc_type = QComboBox(self) self._gl.addWidget(self._cbo_doc_type, 0, 1, 1, 1) self._btn_add_document = QPushButton(self) doc_ico = QIcon(':/plugins/stdm/images/icons/document.png') self._btn_add_document.setIcon(doc_ico) self._btn_add_document.setText(self.tr('Add document...')) self._btn_add_document.setMaximumWidth(200) self._gl.addWidget(self._btn_add_document, 0, 2, 1, 1) self._doc_tab_container = QTabWidget(self) self._gl.addWidget(self._doc_tab_container, 1, 0, 1, 3) self.setMinimumHeight(140) def on_doc_type_changed(self, idx): """ Slot raised when the document types changes. The corresponding widget in the tab container is also selected. :param idx: Item index in the combobox. :type idx: int """ if idx == -1: return self._doc_tab_container.setCurrentIndex(idx) def on_tab_doc_type_changed(self, idx): """ Slot raised when the document types changes. The corresponding widget in the tab container is also selected. :param idx: Item index in the tab widget. :type idx: int """ if idx == -1: return self._cbo_doc_type.setCurrentIndex(idx) def current_document_type(self): """ :return: Returns the currently selected document type in the combobox. :rtype: str """ return self._cbo_doc_type.currentText() def current_document_type_id(self): """ :return: Returns the primary key/id of the currently selected document type in the combobox, else -1 if there is not current item in the combobox :rtype: int """ if not self.current_document_type(): return -1 curr_idx = self._cbo_doc_type.currentIndex() return self._cbo_doc_type.itemData(curr_idx) def count(self): """ :return: Returns the number of document types supported by this widget. :rtype: int """ return self._cbo_doc_type.count() def document_type_containers(self): """ :return: Returns a list of document container widgets for all registered document types. :rtype: list """ return self.source_document_manager.containers.values() def document_type_widget(self, name): """ Searches for the document type widget that corresponds to the given name. :param name: Name of the document type. :type name: str :return: Returns the document widget corresponding to the given type name. :rtype: QWidget """ idx = self._cbo_doc_type.findText(name) if idx == -1: return None rec_id = self._cbo_doc_type.itemData(idx) return self._doc_type_widgets.get(rec_id, None) def _load_document_types(self): #Load document types in the combobox and tab widget vl_cls = entity_model( self._entity_supporting_doc.document_type_entity, entity_only=True ) vl_obj = vl_cls() res = vl_obj.queryObject().all() for r in res: #Add to combo self._cbo_doc_type.addItem(r.value, r.id) #Add to tab widget doc_type_widget = _DocumentTypeContainer(self) self._doc_tab_container.addTab(doc_type_widget, r.value) self._doc_type_widgets[r.id] = doc_type_widget #Register container self.source_document_manager.registerContainer( doc_type_widget.container, r.id ) def _on_add_supporting_document(self): #Slot raised when the user select to add a supporting document if self.count == 0: return select = self.tr('Select') supporting_docs_str = 'Supporting Documents' title = u'{0} {1} {2}'.format( select, self.current_document_type(), supporting_docs_str ) filter_str = u'{0} (*.jpg *.jpeg *.png *.bmp *.tiff *.svg)'.format( supporting_docs_str ) #Get last path for supporting documents last_path = last_document_path() if last_path is None: last_path = '/home' else: dir = QDir(last_path) if not dir.exists(): last_path = '/home' source_docs = QFileDialog.getOpenFileNames( self, title, last_path, filter_str ) doc_type_id = self._cbo_doc_type.itemData(self._cbo_doc_type.currentIndex()) parent_entity = self._entity_supporting_doc.parent_entity for doc in source_docs: self.source_document_manager.insertDocumentFromFile( doc, doc_type_id, parent_entity ) #Set last path if len(source_docs) > 0: doc = source_docs[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path)
class SupportingDocuments(ComponentUtility): onUploadDocument = pyqtSignal(list) def __init__(self, box, combobox, add_documents_btn, notification_bar, parent=None): """ Handles the supporting documents component loading. :param box: The layout holding the container widget. :type box: QVBoxLayout :param combobox: The combobox loading supporting document types. :type combobox: QComboBox :param add_documents_btn: The add supporting document button :type add_documents_btn: QPushButton :param notification_bar: The NotificationBar object that displays notification. :type notification_bar: Object :param parent: The container of the widget :type parent: QDialog or None """ ComponentUtility.__init__(self) self._parent = parent self.container_box = box self.doc_type_cbo = combobox self.notification_bar = notification_bar self.str_number = 1 self.add_documents_btn = add_documents_btn self.str_numbers = [1] self.current_party_count = None self.init_documents() def init_documents(self): """ Initializes the document type combobox by populating data. """ self.supporting_doc_manager = SourceDocumentManager( self.social_tenure.supporting_doc, self.str_doc_model, self._parent ) self.create_doc_tab_populate_combobox() self.doc_type_cbo.currentIndexChanged.connect( self.match_doc_combo_to_tab ) self.docs_tab.currentChanged.connect( self.match_doc_tab_to_combo ) def party_count(self, count): """ A setter for current_party_count that is used to determined the number of copies for each supporting document. :param count: The number of currently added party records. :type count: Integer """ self.current_party_count = count def create_doc_tab_populate_combobox(self): """ Creates the supporting document component widget. """ self.doc_tab_data() self.docs_tab = QTabWidget() self.docs_tab_index = OrderedDict() for i, (id, doc) in enumerate(self.doc_types.iteritems()): self.docs_tab_index[doc] = i # the tab widget containing the document widget layout # and the child of the tab. tab_widget = QWidget() tab_widget.setObjectName(doc) # The layout of the tab widget cont_layout = QVBoxLayout(tab_widget) cont_layout.setObjectName( u'widget_layout_{}'.format(doc) ) # the scroll area widget inside the tab widget. scroll_area = QScrollArea(tab_widget) scroll_area.setFrameShape(QFrame.NoFrame) scroll_area.setObjectName( u'tab_scroll_area_{}'.format(doc) ) layout_widget = QWidget() # the widget the is under the scroll area content and # the widget containing the document widget layout # This widget is hidden and shown based on the STR number layout_widget.setObjectName( u'widget_{}'.format(doc) ) doc_widget_layout = QVBoxLayout(layout_widget) doc_widget_layout.setObjectName( u'doc_widget_layout_{}'.format( doc ) ) doc_widget = QWidget() doc_widget.setObjectName( u'doc_widget_{}_{}'.format(doc, self.str_number) ) doc_widget_layout.addWidget(doc_widget) # the layout containing document widget. ### This is the layout that is registered to add uploaded # supporting documents widgets into. tab_layout = QVBoxLayout(doc_widget) tab_layout.setObjectName( u'layout_{}_{}'.format(doc, self.str_number) ) scroll_area.setWidgetResizable(True) scroll_area.setWidget(layout_widget) cont_layout.addWidget(scroll_area) # Add the tab widget with the document # type name to create a tab. self.docs_tab.addTab(tab_widget, doc) self.container_box.addWidget(self.docs_tab, 1) if len(self.str_numbers) == 1: self.doc_type_cbo.addItem(doc, id) def doc_tab_data(self): """ Sets the document types in the social tenure entity. """ doc_entity = self.social_tenure. \ supporting_doc.document_type_entity doc_type_model = entity_model(doc_entity) docs = doc_type_model() doc_type_list = docs.queryObject().all() self.doc_types = [(doc.id, doc.value) for doc in doc_type_list ] self.doc_types = OrderedDict(self.doc_types) def match_doc_combo_to_tab(self): """ Changes the active tab based on the selected value of document type combobox. """ combo_text = self.doc_type_cbo.currentText() if combo_text is not None and len(combo_text) > 0: index = self.docs_tab_index[combo_text] self.docs_tab.setCurrentIndex(index) def match_doc_tab_to_combo(self): """ Changes the document type combobox value based on the selected tab. """ doc_tab_index = self.docs_tab.currentIndex() self.doc_type_cbo.setCurrentIndex(doc_tab_index) @staticmethod def hide_doc_widgets(widget, visibility): """ Hides or shows the visibility of the supporting document container widgets. :param widget: The widget to which the visibility is set. :type widget: QWidget :param visibility: A boolean to show or hide visibility. True hides widget and False shows it. :type visibility: Boolean """ widget.setHidden(visibility) def update_container(self, str_number): """ Update the current supporting document widget container to be used. :param str_number: The STR node number :type str_number: Integer """ doc_text = self.doc_type_cbo.currentText() cbo_index = self.doc_type_cbo.currentIndex() doc_id = self.doc_type_cbo.itemData(cbo_index) scroll_area = self.docs_tab.findChild( QScrollArea, u'tab_scroll_area_{}'.format( doc_text, str_number ) ) doc_widget = scroll_area.findChild( QWidget, u'doc_widget_{}_{}'.format( doc_text, str_number ) ) # If the doc widget doesn't exist create it for new STR instance if doc_widget is None: # find the doc_widget layout that contains # all STR doc widget layouts. Single # doc_widget_layout is created for each document type. # But all doc_widgets for each STR instance and # document types will be added here. doc_widget_layout = scroll_area.findChild( QVBoxLayout, u'doc_widget_layout_{}'.format(doc_text) ) doc_widget = QWidget() doc_widget.setObjectName( u'doc_widget_{}_{}'.format(doc_text, str_number) ) self.hide_all_other_widget(doc_text, str_number) doc_widget_layout.addWidget(doc_widget) # Create the layout so that layouts are registered in # which uploaded document widgets are added. layout = QVBoxLayout(doc_widget) layout.setObjectName(u'layout_{}_{}'.format( doc_text, str_number ) ) # If the doc widget exists, get the lowest # layout so that it is registered. else: # hide all other widgets self.hide_all_other_widget(doc_text, str_number) # show the current doc widget to display # the document widgets for the current tab. self.hide_doc_widgets(doc_widget, False) layout = doc_widget.findChild( QVBoxLayout, u'layout_{}_{}'.format( doc_text, str_number ) ) # register layout self.supporting_doc_manager.registerContainer( layout, doc_id ) def hide_all_other_widget(self, doc_text, str_number): """ Hides all other supporting document widget except the current STR node widget. :param doc_text: The current document type selected. :type doc_text: String :param str_number: The STR node number :type str_number: Integer """ expression = QRegExp(u'doc_widget*') # hide all existing widgets in all layouts for widget in self.docs_tab.findChildren(QWidget, expression): if widget.objectName() != u'doc_widget_{}_{}'.format( doc_text, str_number): self.hide_doc_widgets(widget, True) def on_upload_document(self): ''' Slot raised when the user clicks to upload a supporting document. ''' document_str = QApplication.translate( "SupportingDocuments", "Specify the Document File Location" ) documents = self.select_file_dialog(document_str) cbo_index = self.doc_type_cbo.currentIndex() doc_id = self.doc_type_cbo.itemData(cbo_index) for doc in documents: self.supporting_doc_manager.insertDocumentFromFile( doc, doc_id, self.social_tenure, self.current_party_count ) # Set last path if len(documents) > 0: doc = documents[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path) model_objs = self.supporting_doc_manager.model_objects() self.onUploadDocument.emit(model_objs) def select_file_dialog(self, title): """ Displays a file dialog for a user to specify a source document :param title: The title of the file dialog :type title: String """ # Get last path for supporting documents last_path = last_document_path() if last_path is None: last_path = '/home' files = QFileDialog.getOpenFileNames( iface.mainWindow(), title, last_path, "Source Documents (*.jpg *.jpeg *.png *.bmp *.tiff *.svg)" ) return files
class Save2DB: """ Class to insert entity data into db """ def __init__(self, entity, attributes, ids=None): """ Initialize class and class variable """ self.attributes = attributes self.form_entity = entity self.doc_model = None self._doc_manager =None self.entity = self.object_from_entity_name(self.form_entity) self.model = self.dbmodel_from_entity() self.key = 0 self.parents_ids = ids self.geom = 4326 self.entity_mapping = {} def object_from_entity_name(self, entity): """ :return: """ if entity == 'social_tenure': return current_profile().social_tenure else: user_entity = current_profile().entity_by_name(entity) return user_entity def entity_has_supporting_docs(self): """ Check if the entity has supporting document before importing :return: Bool """ if self.entity.supports_documents: return self.entity.supports_documents else: return None def entity_supported_document_types(self): """ Get the supported document types before importing so that they are captured during import process :return: List """ return self.entity.document_types_non_hex() def dbmodel_from_entity(self): """ Format model attributes from passed entity attributes :return: """ if self.entity_has_supporting_docs(): entity_object, self.doc_model = entity_model(self.entity, with_supporting_document=True) entity_object_model = entity_object() if hasattr(entity_object_model, 'documents'): if self.entity.TYPE_INFO == 'SOCIAL_TENURE': obj_doc_col = current_profile().social_tenure.supporting_doc else: obj_doc_col = self.entity.supporting_doc self._doc_manager = SourceDocumentManager( obj_doc_col, self.doc_model ) else: entity_object = entity_model(self.entity) entity_object_model = entity_object() return entity_object_model def objects_from_supporting_doc(self, instance_file = None): """ Create supporting doc path instances based on the collected documents :return:paths :rtype: document object instance """ if instance_file: f_dir, file_name = os.path.split(instance_file) for document, val in self.attributes.iteritems(): if str(document).endswith('supporting_document'): if val != '': doc = self.format_document_name_from_attribute(document) doc_path = os.path.normpath(f_dir+'/'+val) abs_path = doc_path.replace('\\','/').strip() if QFile.exists(abs_path): self.supporting_document_model(abs_path, doc) def supporting_document_model(self,doc_path,doc): """ :param doc_path: absolute document path :param doc: document name :type: str Construct supporting document model instance to add into the db :return: """ # Create document container doc_container = QVBoxLayout() supporting_doc_entity = self.entity.supporting_doc.document_type_entity document_type_id = entity_attr_to_id(supporting_doc_entity, 'value', doc, lower=False) # Register container self._doc_manager.registerContainer( doc_container, document_type_id ) #Copy the document to STDM working directory self._doc_manager.insertDocumentFromFile( doc_path, document_type_id, self.entity ) def format_document_name_from_attribute(self, doc): """ Get the type of document from attribute name So that supporting document class instance can save it in the right format :return: """ formatted_doc_list = self.entity_supported_document_types() default = 'General' doc_type = str(doc).split('_',1) if doc_type[0].startswith('supporting') and formatted_doc_list[0] == default: return default elif doc_type[0].startswith('supporting') and formatted_doc_list[0] != default: return formatted_doc_list[0] elif not doc_type[0].startswith('supporting'): actual_doc_name = doc_type[0].replace('-', ' ') for doc_name in formatted_doc_list: if actual_doc_name in doc_name or doc_name.startswith(actual_doc_name): return doc_name else: return formatted_doc_list[0] else: return formatted_doc_list[0] def extract_social_tenure_entities(self): ''' We want to extract social tenure enities so that we know if it has multiple or single entities in the list :return: ''' party_ref_column = '' spatial_ref_column = '' if self.parents_ids is not None: print self.parents_ids if self.attributes.has_key('party'): full_party_ref_column = self.attributes.get('party') party_ref_column = full_party_ref_column + '_id' print 'party{}.'.format(party_ref_column) setattr(self.model, party_ref_column, self.parents_ids.get(full_party_ref_column)[0]) if self.attributes.has_key('spatial_unit'): full_spatial_ref_column = self.attributes.get('spatial_unit') spatial_ref_column = full_spatial_ref_column + '_id' print 'sp.{}.'.format(spatial_ref_column) setattr(self.model, spatial_ref_column, self.parents_ids.get(full_spatial_ref_column)[0]) return party_ref_column, spatial_ref_column def save_to_db(self): """ Format object attribute data from entity and save them into database :return: """ self.column_info() try: if self.entity.short_name == 'social_tenure_relationship': #try: prefix = current_profile().prefix + '_' if self.attributes.has_key('party'): full_party_ref_column = self.attributes.get('party') party_ref_column = full_party_ref_column + '_id' self.attributes.pop('party') else: full_party_ref_column = current_profile().social_tenure.parties[0].name party_ref_column = full_party_ref_column + '_id' setattr(self.model, party_ref_column, self.parents_ids.get(prefix + full_party_ref_column)[0]) if self.attributes.has_key('spatial_unit'): full_spatial_ref_column = self.attributes.get('spatial_unit') spatial_ref_column = full_spatial_ref_column + '_id' self.attributes.pop('spatial_unit') else: full_spatial_ref_column = current_profile().social_tenure.spatial_units[0].name spatial_ref_column = full_spatial_ref_column + '_id' setattr(self.model, spatial_ref_column, self.parents_ids.get(prefix + full_spatial_ref_column)[0]) except: pass for k, v in self.attributes.iteritems(): if hasattr(self.model, k): col_type = self.entity_mapping.get(k) col_prop = self.entity.columns[k] var = self.attribute_formatter(col_type, col_prop, v) setattr(self.model, k, var) if self.entity_has_supporting_docs(): self.model.documents = self._doc_manager.model_objects() self.model.save() return self.model.id def save_parent_to_db(self): """ Format object attribute data from entity and save them into database attribute :return: """ self.column_info() for k, v in self.attributes.iteritems(): if hasattr(self.model, k): col_type = self.entity_mapping.get(k) col_prop = self.entity.columns[k] #print "property{0}.... and type.{1}".format(col_prop, col_type) var = self.attribute_formatter(col_type, col_prop, v) setattr(self.model, k, var) if self.entity_has_supporting_docs(): self.model.documents = self._doc_manager.model_objects() self.model.save() self.key = self.model.id return self.key def save_foreign_key_table(self): """ Get the table with foreign keys only :return: """ for col, type_info in self.column_info().iteritems(): col_prop = self.entity.columns[col] var = self.attribute_formatter(type_info, col_prop, None) setattr(self.model, col, var) self.model.save() self.cleanup() def column_info(self): """ :return: """ self.entity_mapping = {} cols = self.entity.columns.values() for c in cols: self.entity_mapping[c.name] = c.TYPE_INFO def get_srid(self, srid): """ Let the user specify the coordinate system during data import :param srid: :return: """ self.geom = srid return self.geom def id_from_model_object(self, obj): """ We need to obtian id from object instance :param obj: :return: """ return obj.id def attribute_formatter(self, col_type, col_prop, var=None): """ Format geoodk attributes collected in the field to conform to STDM database contrains :return: """ if col_type == 'BOOL': if len(var) < 1: return None if len(var)>1: if var == '' or var is None: return None if var == 'Yes' or var == True: return True if var == 'No' or var == False: return False else: return None if col_type == 'LOOKUP': if len(var) < 1 or var is None: return None if len(var) <4: if var == 'Yes' or var == 'No': return entity_attr_to_model(col_prop.parent, 'value', var).id if var != 'Yes' and var != 'No': lk_code = entity_attr_to_id(col_prop.parent, "code", var) if not str(lk_code).isdigit(): return None else: return lk_code if len(var) > 3: if not str(entity_attr_to_id(col_prop.parent, 'code', var)).isdigit(): id_value = entity_attr_to_model(col_prop.parent, 'value', var) if id_value is not None: return id_value.id #return entity_attr_to_model(col_prop.parent, 'value', var).id else: lk_code = entity_attr_to_id(col_prop.parent, "code", var) if not str(lk_code).isdigit(): return None else: return lk_code else: return None elif col_type == 'ADMIN_SPATIAL_UNIT': var_code = None try: if len(var) < 1 or var is None: return None elif not len(var) > 3: var_code = entity_attr_to_id(col_prop.parent, "code", var) if var_code and var_code == var: return None else: return var_code elif len(var) > 3 and entity_attr_to_id(col_prop.parent, "name", var) is not None: var_code = entity_attr_to_id(col_prop.parent, "name", var) if var_code and var_code == var: return None else: return var_code else: if entity_attr_to_id(col_prop.parent, "name", var) is None: var_code = entity_attr_to_id(col_prop.parent, "code", var) if not var_code or var_code == var: return None except: pass elif col_type == 'MULTIPLE_SELECT': print 'multiple select {}'.format(var) if var == '' or var is None: return None else: print var col_parent = col_prop.association.first_parent lk_val_list = col_parent.values.values() choices_list = [] for code in lk_val_list: choices_list.append(entity_attr_to_id( col_parent.association.first_parent, 'value', code.value)) print choices_list if len(choices_list) > 1: return choices_list else: return None elif col_type == 'GEOMETRY': defualt_srid = 0 if var: geom_provider = STDMGeometry(var) if isinstance(col_prop, GeometryColumn): defualt_srid = col_prop.srid if defualt_srid != 0: geom_provider.set_user_srid(defualt_srid) else: geom_provider.set_user_srid(GEOMPARAM) if col_prop.geometry_type() == 'POINT': return geom_provider.point_to_Wkt() if col_prop.geometry_type() == 'POLYGON': return geom_provider.polygon_to_Wkt() else: return None elif col_type == 'FOREIGN_KEY': if self.parents_ids is None or len(self.parents_ids) < 0: return None else: for code, val in self.parents_ids.iteritems(): if col_prop.parent.name == code: return val[0] else: return None elif col_type == 'INT' or col_type == 'DOUBLE' or col_type == 'PERCENT': if var == '': return None else: return var elif col_type == 'DATETIME' or col_type == 'DATE': if var is None: return None if var == '': return None else: return var else: return var def cleanup(self): """ Reset all the model and entity data before we process the next entity data :return: None z""" self.model = None self.entity = None self.attributes = None self._doc_manager = None