예제 #1
0
 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.'))
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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)
예제 #6
0
    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
예제 #10
0
 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)))
예제 #11
0
    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)
예제 #12
0
    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)
예제 #13
0
    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
예제 #14
0
 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
예제 #15
0
 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)))
예제 #16
0
 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)))
예제 #17
0
    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
예제 #18
0
 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
예제 #19
0
    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
예제 #20
0
    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