示例#1
0
    def create(self, request):
        """
        Does not work in Swagger!

        Create a new Property from a building file.
        ---
        consumes:
            - multipart/form-data
        parameters:
            - name: organization_id
              type: integer
              required: true
            - name: cycle_id
              type: integer
              required: true
            - name: file_type
              type: string
              enum: ["Unknown", "BuildingSync", "HPXML"]
              required: true
            - name: file
              description: In-memory file object
              required: true
              type: file
        """
        if len(request.FILES) == 0:
            return JsonResponse({
                'success':
                False,
                'message':
                'Must pass file in as a Multipart/Form post'
            })

        the_file = request.data['file']
        file_type = BuildingFile.str_to_file_type(
            request.data.get('file_type', 'Unknown'))

        organization_id = request.data['organization_id']
        cycle = request.data.get('cycle_id', None)

        if not cycle:
            return JsonResponse({
                'success': False,
                'message': 'Cycle ID is not defined'
            })
        else:
            cycle = Cycle.objects.get(pk=cycle)

        # figure out if file is xml or zip
        the_filename = the_file._get_name()
        tmp_filename, file_extension = os.path.splitext(the_filename)
        # initialize
        p_status = True
        property_state = True
        messages = {'errors': [], 'warnings': []}

        if file_extension == '.zip':
            # ZIP FILE, extract and process files one by one
            # print("This file is a ZIP")

            with zipfile.ZipFile(the_file, "r", zipfile.ZIP_STORED) as openzip:
                filelist = openzip.infolist()
                for f in filelist:
                    # print("FILE: {}".format(f.filename))
                    # process xml files
                    if '.xml' in f.filename and '__MACOSX' not in f.filename:
                        # print("PROCESSING file: {}".format(f.filename))
                        data_file = NamedTemporaryFile()
                        data_file.write(openzip.read(f))
                        data_file.seek(0)
                        size = os.path.getsize(data_file.name)
                        content_type = 'text/xml'
                        # print("DATAFILE:")
                        # print(data_file)
                        a_file = InMemoryUploadedFile(data_file,
                                                      'data_file',
                                                      f.filename,
                                                      content_type,
                                                      size,
                                                      charset=None)

                        building_file = BuildingFile.objects.create(
                            file=a_file,
                            filename=f.filename,
                            file_type=file_type,
                        )
                        p_status_tmp, property_state_tmp, property_view, messages_tmp = building_file.process(
                            organization_id, cycle)
                        # print('messages_tmp: ')
                        # print(messages_tmp)

                        # append errors to overall messages
                        for i in messages_tmp['errors']:
                            messages['errors'].append(f.filename + ": " + i)
                        for i in messages_tmp['warnings']:
                            messages['warnings'].append(f.filename + ": " + i)

                        if not p_status_tmp:
                            # capture error
                            p_status = p_status_tmp
                        else:
                            # capture a real property_state (not None)
                            property_state = property_state_tmp

        else:
            # just an XML
            building_file = BuildingFile.objects.create(
                file=the_file,
                filename=the_file.name,
                file_type=file_type,
            )

            p_status, property_state, property_view, messages = building_file.process(
                organization_id, cycle)

        if p_status and property_state:
            if len(messages['warnings']) > 0:
                return JsonResponse({
                    'success': True,
                    'status': 'success',
                    'message': {
                        'warnings': messages['warnings']
                    },
                    'data': {
                        'property_view':
                        PropertyViewAsStateSerializer(property_view).data,
                        # 'property_state': PropertyStateWritableSerializer(property_state).data,
                    },
                })
            else:
                return JsonResponse({
                    'success': True,
                    'status': 'success',
                    'message': {
                        'warnings': []
                    },
                    'data': {
                        'property_view':
                        PropertyViewAsStateSerializer(property_view).data,
                        # 'property_state': PropertyStateWritableSerializer(property_state).data,
                    },
                })
        else:
            return JsonResponse(
                {
                    'success': False,
                    'status': 'error',
                    'message': messages
                },
                status=status.HTTP_400_BAD_REQUEST)
示例#2
0
    def update_with_building_sync(self, request, pk):
        """
        Does not work in Swagger!

        Update an existing PropertyView with a building file. Currently only supports BuildingSync.
        ---
        consumes:
            - multipart/form-data
        parameters:
            - name: pk
              description: The PropertyView to update with this buildingsync file
              type: path
              required: true
            - name: organization_id
              type: integer
              required: true
            - name: cycle_id
              type: integer
              required: true
            - name: file_type
              type: string
              enum: ["Unknown", "BuildingSync"]
              required: true
            - name: file
              description: In-memory file object
              required: true
              type: file
        """
        if len(request.FILES) == 0:
            return JsonResponse({
                'success':
                False,
                'message':
                "Must pass file in as a Multipart/Form post"
            })

        the_file = request.data['file']
        file_type = BuildingFile.str_to_file_type(
            request.data.get('file_type', 'Unknown'))
        organization_id = request.query_params.get('organization_id', None)
        cycle_pk = request.query_params.get('cycle_id', None)

        if not cycle_pk:
            return JsonResponse({
                'success': False,
                'message': "Cycle ID is not defined"
            })
        else:
            cycle = Cycle.objects.get(pk=cycle_pk)

        result = self._get_property_view(pk, cycle_pk)
        p_status = False
        new_pv_state = None
        if result.get('status', None) != 'error':
            building_file = BuildingFile.objects.create(
                file=the_file,
                filename=the_file.name,
                file_type=file_type,
            )

            property_view = result.pop('property_view')
            previous_state = property_view.state
            # passing in the existing propertyview allows it to process the buildingsync file and attach it to the
            # existing propertyview.
            p_status, new_pv_state, new_pv_view, messages = building_file.process(
                organization_id, cycle, property_view=property_view)

            # merge the relationships from the old property state
            self._merge_relationships(previous_state, new_pv_state)

        else:
            messages = [
                'Cannot match a PropertyView with property_id=%s; cycle_id=%s'
                % (pk, cycle_pk)
            ]

        if p_status and new_pv_state:
            return JsonResponse({
                'success': True,
                'status': 'success',
                'message': 'successfully imported file',
                'data': {
                    'property_view':
                    PropertyViewAsStateSerializer(new_pv_view).data,
                },
            })
        else:
            return JsonResponse(
                {
                    'status':
                    'error',
                    'message':
                    "Could not process building file with messages {}".format(
                        messages)
                },
                status=status.HTTP_400_BAD_REQUEST)
示例#3
0
    def create(self, request):
        """
        Does not work in Swagger!

        Create a new Property from a building file.
        ---
        consumes:
            - multipart/form-data
        parameters:
            - name: organization_id
              type: integer
              required: true
            - name: cycle_id
              type: integer
              required: true
            - name: file_type
              type: string
              enum: ["Unknown", "BuildingSync", "GeoJSON", "HPXML"]
              required: true
            - name: file
              description: In-memory file object
              required: true
              type: file
        """
        if len(request.FILES) == 0:
            return JsonResponse({
                'success': False,
                'message': "Must pass file in as a Multipart/Form post"
            })

        the_file = request.data['file']
        file_type = BuildingFile.str_to_file_type(request.data.get('file_type', 'Unknown'))
        organization_id = request.data['organization_id']
        cycle = request.data.get('cycle_id', None)

        if not cycle:
            return JsonResponse({
                'success': False,
                'message': "Cycle ID is not defined"
            })
        else:
            cycle = Cycle.objects.get(pk=cycle)

        building_file = BuildingFile.objects.create(
            file=the_file,
            filename=the_file.name,
            file_type=file_type,
        )

        p_status, property_state, property_view, messages = building_file.process(organization_id, cycle)
        if p_status and property_state:
            return JsonResponse({
                "status": "success",
                "message": "successfully imported file",
                "data": {
                    "property_view": PropertyViewAsStateSerializer(property_view).data,
                    # "property_state": PropertyStateWritableSerializer(property_state).data,
                },
            })
        else:
            return JsonResponse({
                "status": "error",
                "message": "Could not process building file with messages {}".format(messages)
            }, status=status.HTTP_400_BAD_REQUEST)