def _get_questionnaire(self, id_string, version): try: return Questionnaire.objects.get( id_string=id_string, version=int(version) ) except Questionnaire.DoesNotExist: raise InvalidXMLSubmission(_('Questionnaire not found.'))
def create_tenure_relationship(self, data, party, location, project): tenure_resources = [] try: if data.get('tenure_type'): tenure_group = [data] else: tenure_group = self._format_repeat(data, ['party', 'location']) for p in range(len(party)): for l in range(len(location)): t = 0 if len(tenure_group) > 1: if p > l: t = p else: t = l tenure = TenureRelationship.objects.create( project=project, party=party[p], spatial_unit=location[l], tenure_type=TenureRelationshipType.objects.get( id=tenure_group[t]['tenure_type']), attributes=self._get_attributes( tenure_group[t], 'tenure_relationship')) tenure_resources.append( self._get_resource_names(tenure_group[t], tenure, 'tenure')) except Exception as e: raise InvalidXMLSubmission( _("Tenure relationship error: {}".format(e))) return tenure_resources
def create_spatial_unit(self, data, project, party=None, duplicate=None): location_resources = [] location_objects = [] if duplicate: get_or_create_spatial_units = duplicate.spatial_units.get else: get_or_create_spatial_units = SpatialUnit.objects.create try: location_group = self._format_repeat(data, ['location']) for group in location_group: geom = self._format_geometry(group) location = get_or_create_spatial_units( project=project, type=group['location_type'], geometry=geom, attributes=self._get_attributes(group, 'location')) location_resources.append( self._get_resource_names(group, location, 'location')) location_objects.append(location) except Exception as e: raise InvalidXMLSubmission(_('Location error: {}'.format(e))) return location_objects, location_resources
def upload_submission_data(self, request): if 'xml_submission_file' not in request.data.keys(): raise InvalidXMLSubmission(_('XML submission not found')) xml_submission_file = request.data['xml_submission_file'].read() full_submission = XFormToDict( xml_submission_file.decode('utf-8')).get_dict() submission = full_submission[list(full_submission.keys())[0]] with transaction.atomic(): questionnaire, party, location = self.create_models(submission) location_photo = submission.get('location_photo', None) party_photo = submission.get('party_photo', None) resource_data = { 'project': questionnaire.project, 'location_photo': location_photo, 'location': location, 'party_photo': party_photo, 'party_id': party } self.upload_files(request, resource_data) return XFormSubmission(json_submission=full_submission, user=request.user, questionnaire=questionnaire)
def sanitize_submission(self, submission, sanitizable_questions): for key, value in submission.items(): if isinstance(value, dict): self.sanitize_submission(value, sanitizable_questions) elif key in sanitizable_questions and not sanitize_string(value): raise InvalidXMLSubmission(SANITIZE_ERROR)
def create_spatial_unit(self, data, project, questionnaire, party=None): location_resources = [] location_objects = [] try: location_group = self._format_repeat(data, ['location']) for group in location_group: if 'location_geotrace' in group.keys(): location_geometry = group['location_geotrace'] elif 'location_geoshape' in group.keys(): location_geometry = group['location_geoshape'] else: location_geometry = group['location_geometry'] geom = odk_geom_to_wkt(location_geometry) location = SpatialUnit.objects.create( project=project, type=group['location_type'], geometry=geom, attributes=self._get_attributes(group, 'location')) location_resources.append( self._get_resource_names(group, location, 'location')) location_objects.append(location) except Exception as e: raise InvalidXMLSubmission(_('Location error: {}'.format(e))) return location_objects, location_resources
def create_models(self, data, user): questionnaire = self._get_questionnaire(id_string=data['id'], version=data['version']) self._check_perm(user, questionnaire.project) # If xform has already been submitted, check for additional resources additional_resources = self.check_for_duplicate_submission( data, questionnaire) if additional_resources: return additional_resources project = questionnaire.project if project.current_questionnaire != questionnaire.id: raise InvalidXMLSubmission(_('Form out of date')) parties, party_resources = self.create_party(data=data, project=project) locations, location_resources = self.create_spatial_unit( data=data, project=project, party=parties) (tenure_relationships, tenure_resources) = self.create_tenure_relationship( data=data, project=project, parties=parties, locations=locations) return (questionnaire, parties, party_resources, locations, location_resources, tenure_relationships, tenure_resources)
def create_party(self, data, project, duplicate=None): party_objects = [] party_resources = [] if duplicate: get_or_create_party = duplicate.parties.get else: get_or_create_party = Party.objects.create try: party_groups = self._format_repeat(data, ['party']) for group in party_groups: party = get_or_create_party(project=project, name=group['party_name'], type=group['party_type'], attributes=self._get_attributes( group, 'party')) party_resources.append( self._get_resource_names(group, party, 'party')) party_objects.append(party) except Exception as e: raise InvalidXMLSubmission(_("Party error: {}".format(e))) return party_objects, party_resources
def create_spatial_unit(self, data, project, party=None, duplicate=None): location_resources = [] location_objects = [] try: location_group = self._format_repeat(data, ['location']) for group in location_group: geom = self._format_geometry(group) attrs = dict(project=project, type=group['location_type'], attributes=self._get_attributes( group, 'location')) if duplicate: geom_type = GEOSGeometry(geom).geom_type GeometryField = getattr(geo_models, geom_type + 'Field') location = duplicate.spatial_units.annotate( geom=Cast('geometry', GeometryField())).get(geom=geom, **attrs) else: location = SpatialUnit.objects.create(geometry=geom, **attrs) location_resources.append( self._get_resource_names(group, location, 'location')) location_objects.append(location) except Exception as e: raise InvalidXMLSubmission(_('Location error: {}'.format(e))) return location_objects, location_resources
def create_resource(self, data, user, project, content_object=None): Storage = get_storage_class() file = data.file.read() try: if file == b'': Resource.objects.get( name=data.name, contributor=user, mime_type=data.content_type, project=project, original_file=data.name ).content_objects.create( content_object=content_object ) else: url = Storage().save('resources/' + data.name, file) Resource.objects.create( name=data.name, file=url, content_object=content_object, mime_type=data.content_type, contributor=user, project=project, original_file=data.name ).full_clean() except Exception as e: raise InvalidXMLSubmission(_("{}".format(e)))
def sanitize_submission(self, submission): for value in list(submission.values()): if isinstance(value, dict): self.sanitize_submission(value) elif not sanitize_string(value): raise InvalidXMLSubmission(SANITIZE_ERROR)
def upload_submission_data(self, request): if 'xml_submission_file' not in request.data.keys(): raise InvalidXMLSubmission(_('XML submission not found')) xml_submission_file = request.data['xml_submission_file'].read() full_submission = XFormToDict( xml_submission_file.decode('utf-8')).get_dict() submission = full_submission[list(full_submission.keys())[0]] with transaction.atomic(): (questionnaire, party, location, tenure) = self.create_models(submission) party_submission = [submission] location_submission = [submission] tenure_submission = [submission] if 'party_repeat' in submission: party_submission = self._format_repeat(submission, ['party']) if 'tenure_type' in party_submission[0]: tenure_submission = party_submission elif 'location_repeat' in submission: location_submission = self._format_repeat( submission, ['location']) if 'tenure_type' in location_submission[0]: tenure_submission = location_submission party_resources = [] location_resources = [] tenure_resources = [] for group in party_submission: party_resources.extend(self._get_resource_files( group, 'party')) for group in location_submission: location_resources.extend( self._get_resource_files(group, 'location')) for group in tenure_submission: tenure_resources.extend( self._get_resource_files(group, 'tenure')) resource_data = { 'project': questionnaire.project, 'location_resources': location_resources, 'locations': location, 'party_resources': party_resources, 'parties': party, 'tenure_resources': tenure_resources, 'tenures': tenure, } self.upload_resource_files(request, resource_data) return XFormSubmission(json_submission=full_submission, user=request.user, questionnaire=questionnaire)
def upload_submission_data(self, request): if 'xml_submission_file' not in request.data.keys(): raise InvalidXMLSubmission(_('XML submission not found')) xml_submission_file = request.data['xml_submission_file'].read() full_submission = XFormToDict( xml_submission_file.decode('utf-8')).get_dict() submission = full_submission[list(full_submission.keys())[0]] sanitizable_questions = self.get_sanitizable_questions( submission['id'], submission['version']) self.sanitize_submission(submission, sanitizable_questions) with transaction.atomic(): (questionnaire, parties, party_resources, locations, location_resources, tenure_relationships, tenure_resources ) = self.create_models(submission, request.user) party_resource_files = [] for party in party_resources: party_resource_files.extend(party['resources']) location_resource_files = [] for location in location_resources: location_resource_files.extend(location['resources']) tenure_resource_files = [] for tenure in tenure_resources: tenure_resource_files.extend(tenure['resources']) resource_data = { 'project': questionnaire.project, 'location_resources': location_resource_files, 'locations': location_resources, 'party_resources': party_resource_files, 'parties': party_resources, 'tenure_resources': tenure_resource_files, 'tenures': tenure_resources, } self.upload_resource_files(request, resource_data) if XFormSubmission.objects.filter( instanceID=submission['meta']['instanceID']).exists(): return XFormSubmission.objects.get( instanceID=submission['meta']['instanceID']) xform_submission = XFormSubmission( json_submission=full_submission, user=request.user, questionnaire=questionnaire, instanceID=submission['meta']['instanceID'] ) return xform_submission, parties, locations, tenure_relationships
def create_party(self, data, project): try: party = Party.objects.create(project=project, name=data['party_name'], type=data['party_type'], attributes=self.get_attributes( data, 'party')) except Exception as e: raise InvalidXMLSubmission(_("Party error: {}".format(e))) return party
def create_tenure_relationship(self, data, party, location, project): try: TenureRelationship.objects.create( project=project, party=party, spatial_unit=location, tenure_type=TenureRelationshipType.objects.get( id=data['tenure_type']), attributes=self.get_attributes(data, 'tenure_relationship')) except Exception as e: raise InvalidXMLSubmission( _("Tenure relationship error: {}".format(e)))
def add_file_to_resource(self, data, user, project, content_object=None): Storage = get_storage_class() storage = Storage() url = storage.save('resources/' + data.name, data.file.read()) try: resource = Resource.objects.create(name=data.name, file=url, content_object=content_object, mime_type=data.content_type, contributor=user, project=project, original_file=data.name) resource.full_clean() except Exception as e: raise InvalidXMLSubmission(_("{}".format(e)))
def create_tenure_relationship(self, data, parties, locations, project, duplicate=None): tenure_resources = [] tenure_objects = [] if duplicate: get_or_create_tenure_rels = duplicate.tenure_relationships.get else: get_or_create_tenure_rels = TenureRelationship.objects.create try: if data.get('tenure_type'): tenure_group = [data] else: tenure_group = self._format_repeat(data, ['party', 'location']) for p, party in enumerate(parties): for l, location in enumerate(locations): t = 0 if len(tenure_group) > 1: if p > l: t = p else: t = l tenure = get_or_create_tenure_rels( project=project, party=party, spatial_unit=location, tenure_type=TenureRelationshipType.objects.get( id=tenure_group[t]['tenure_type']), attributes=self._get_attributes( tenure_group[t], 'tenure_relationship')) tenure_objects.append(tenure) tenure_resources.append( self._get_resource_names(tenure_group[t], tenure, 'tenure')) except Exception as e: raise InvalidXMLSubmission( _("Tenure relationship error: {}".format(e))) return tenure_objects, tenure_resources
def create_spatial_unit(self, data, project, questionnaire, party=None): if 'location_geotrace' in data.keys(): location_geometry = data['location_geotrace'] geoshape = False elif 'location_geoshape' in data.keys(): location_geometry = data['location_geoshape'] geoshape = True else: location_geometry = data['location_geometry'] geoshape = False try: location = SpatialUnit.objects.create( project=project, type=data['location_type'], geometry=self._format_geometry(location_geometry, geoshape), attributes=self.get_attributes(data, 'location')) except Exception as e: raise InvalidXMLSubmission(_('Location error: {}'.format(e))) return location
def create_models(self, data): questionnaire = self.get_questionnaire(id_string=data['id'], version=data['version']) project = questionnaire.project if project.current_questionnaire != questionnaire.id: raise InvalidXMLSubmission(_('Form out of date')) party = self.create_party(data=data, project=project) location = self.create_spatial_unit(data=data, project=project, questionnaire=questionnaire, party=party) self.create_tenure_relationship(data=data, project=project, party=party, location=location) return questionnaire, party.id, location.id
def upload_submission_data(self, request): if 'xml_submission_file' not in request.data.keys(): raise InvalidXMLSubmission(_('XML submission not found')) xml_submission_file = request.data['xml_submission_file'].read() full_submission = XFormToDict( xml_submission_file.decode('utf-8')).get_dict() submission = full_submission[list(full_submission.keys())[0]] self.sanitize_submission(submission) with transaction.atomic(): (questionnaire, parties, party_resources, locations, location_resources, tenure_relationships, tenure_resources) = self.create_models(submission, request.user) party_submissions = [submission] location_submissions = [submission] tenure_submissions = [submission] if 'party_repeat' in submission: party_submissions = self._format_repeat(submission, ['party']) if 'tenure_type' in party_submissions[0]: tenure_submissions = party_submissions elif 'location_repeat' in submission: location_submissions = self._format_repeat( submission, ['location']) if 'tenure_type' in location_submissions[0]: tenure_submissions = location_submissions party_resource_files = [] location_resource_files = [] tenure_resource_files = [] for group in party_submissions: party_resource_files.extend( self._get_resource_files(group, 'party')) for group in location_submissions: location_resource_files.extend( self._get_resource_files(group, 'location')) for group in tenure_submissions: tenure_resource_files.extend( self._get_resource_files(group, 'tenure')) resource_data = { 'project': questionnaire.project, 'location_resources': location_resource_files, 'locations': location_resources, 'party_resources': party_resource_files, 'parties': party_resources, 'tenure_resources': tenure_resource_files, 'tenures': tenure_resources, } self.upload_resource_files(request, resource_data) if XFormSubmission.objects.filter( instanceID=submission['meta']['instanceID']).exists(): return XFormSubmission.objects.get( instanceID=submission['meta']['instanceID']) xform_submission = XFormSubmission( json_submission=full_submission, user=request.user, questionnaire=questionnaire, instanceID=submission['meta']['instanceID']) return xform_submission, parties, locations, tenure_relationships