예제 #1
0
def update_resource(user_id, project_id, params):
    hs = hss.get_client(user_id)
    hsresource = HydroShareResource.objects.get(project_id=project_id)

    if not hs.check_resource_exists(hsresource.resource):
        raise RuntimeError('HydroShare could not find requested resource')

    # Update files
    files = params.get('files', [])
    for md in params.get('mapshed_data', []):
        muuid = md.get('uuid')
        if muuid:
            try:
                job = Job.objects.get(uuid=muuid)
                mdata = json.loads(job.result)
                files.append({
                    'name': md.get('name'),
                    'contents': to_gms_file(mdata).read(),
                })
            except (Job.DoesNotExist, ValueError):
                # Either the job wasn't found, or its content isn't JSON
                pass

    hs.add_files(hsresource.resource, files)

    hsresource.exported_at = now()
    hsresource.save()

    serializer = HydroShareResourceSerializer(hsresource)
    return serializer.data
예제 #2
0
def export_gms(request, format=None):
    mapshed_data = json.loads(request.POST.get('mapshed_data', '{}'))
    filename = request.POST.get('filename', None)

    if not mapshed_data or not filename:
        return Response('Must specify mapshed_data and filename',
                        status.HTTP_400_BAD_REQUEST)

    gms_file = tasks.to_gms_file(mapshed_data)

    response = HttpResponse(FileWrapper(gms_file), content_type='text/plain')
    response['Content-Disposition'] = f'attachment; filename={filename}.gms'
    return response
예제 #3
0
def _hs_gather_client_files(params):
    # Files sent from the client
    files = params.get('files', [])

    # MapShed Data
    for md in params.get('mapshed_data', []):
        mdata = md.get('data')
        files.append({
            'name': md.get('name'),
            'contents': to_gms_file(mdata).read() if mdata else None,
        })

    # Weather Data
    for wd in params.get('weather_data', []):
        s = Scenario.objects.get(id=wd.get('id'))
        files.append({
            'name': wd.get('name'),
            'contents': s.weather_custom.read(),
        })

    return files
예제 #4
0
def create_resource(user_id, project_id, params):
    hs = hss.get_client(user_id)
    project = Project.objects.get(pk=project_id)

    # Convert keywords from array to set of values
    keywords = params.get('keywords')
    keywords = set(keywords) if keywords else set()

    # POST new resource creates it in HydroShare
    resource = hs.createResource(
        'CompositeResource',
        params.get('title', project.name),
        abstract=params.get('abstract', ''),
        keywords=tuple(DEFAULT_KEYWORDS | keywords),
        extra_metadata=MMW_APP_KEY_FLAG,
    )

    # Files sent from the client
    files = params.get('files', [])

    # AoI GeoJSON
    aoi_geojson = GEOSGeometry(project.area_of_interest).geojson
    files.append({
        'name': 'area-of-interest.geojson',
        'contents': aoi_geojson,
    })

    # MapShed Data
    for md in params.get('mapshed_data', []):
        muuid = md.get('uuid')
        if muuid:
            try:
                job = Job.objects.get(uuid=muuid)
                mdata = json.loads(job.result)
                files.append({
                    'name': md.get('name'),
                    'contents': to_gms_file(mdata).read(),
                })
            except (Job.DoesNotExist, ValueError):
                # Either the job wasn't found, or its content isn't JSON
                pass

    # Add all files
    hs.add_files(resource, files)

    # AoI Shapefile
    aoi_json = json.loads(aoi_geojson)
    crs = {'no_defs': True, 'proj': 'longlat',
           'ellps': 'WGS84', 'datum': 'WGS84'}
    schema = {'geometry': aoi_json['type'], 'properties': {}}
    with fiona.open('/tmp/{}.shp'.format(resource), 'w',
                    driver='ESRI Shapefile',
                    crs=crs, schema=schema) as shapefile:
        shapefile.write({'geometry': aoi_json, 'properties': {}})

    for ext in SHAPEFILE_EXTENSIONS:
        filename = '/tmp/{}.{}'.format(resource, ext)
        with open(filename) as shapefile:
            hs.addResourceFile(resource, shapefile,
                               'area-of-interest.{}'.format(ext))
        os.remove(filename)

    # MapShed BMP Spreadsheet Tool
    if params.get('mapshed_data'):
        response = requests.get(BMP_SPREADSHEET_TOOL_URL,
                                allow_redirects=True, stream=True)
        hs.addResourceFile(resource, io.BytesIO(response.content),
                           'MMW_BMP_Spreadsheet_Tool.xlsx')

    # Make resource public and shareable
    endpoint = hs.resource(resource)
    endpoint.public(True)
    endpoint.shareable(True)

    # Add geographic coverage
    endpoint.functions.set_file_type({
        'file_path': 'area-of-interest.shp',
        'hs_file_type': 'GeoFeature',
    })

    # Link HydroShareResrouce to Project and save
    hsresource = HydroShareResource.objects.create(
        project=project,
        resource=resource,
        title=params.get('title', project.name),
        autosync=params.get('autosync', False),
        exported_at=now()
    )
    hsresource.save()

    # Make Project public and save
    project.is_private = False
    project.save()

    # Return newly created HydroShareResource
    serializer = HydroShareResourceSerializer(hsresource)
    return serializer.data
예제 #5
0
def hydroshare(request):
    # Get HydroShare client with user's credentials
    try:
        hs = hss.get_client(request.user)
    except ObjectDoesNotExist:
        return Response(
            data={'errors': ['User not connected to HydroShare']},
            status=status.HTTP_401_UNAUTHORIZED
        )

    project_id = request.GET.get('project')
    if not project_id:
        # No support for exporting without a project right now
        return Response(
            data={'errors': ['Cannot export to HydroShare without project']},
            status=status.HTTP_400_BAD_REQUEST
        )

    params = request.data
    project = get_object_or_404(Project, id=project_id,
                                user__id=request.user.id)

    try:
        hsresource = HydroShareResource.objects.get(project=project)
    except HydroShareResource.DoesNotExist:
        hsresource = None

    # GET existing resource simply returns it
    if hsresource and request.method == 'GET':
        if not hs.check_resource_exists(hsresource.resource):
            return Response(
                data={
                    'errors': ['HydroShare could not find requested resource']
                },
                status=status.HTTP_404_NOT_FOUND
            )
        serializer = HydroShareResourceSerializer(hsresource)
        return Response(serializer.data)

    # PATCH existing resource updates its autosync status
    if hsresource and request.method == 'PATCH':
        autosync = params.get('autosync', None)
        if autosync is None:
            return Response(
                data={'errors': ['Must specify autosync as true or false']},
                status=status.HTTP_400_BAD_REQUEST
            )
        hsresource.autosync = autosync
        hsresource.save()
        serializer = HydroShareResourceSerializer(hsresource)
        return Response(serializer.data)

    # DELETE existing resource removes it from MMW and HydroShare
    if hsresource and request.method == 'DELETE':
        if hs.check_resource_exists(hsresource.resource):
            hs.deleteResource(hsresource.resource)
        hsresource.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    # Cannot GET, PATCH or DELETE non-existing resource
    if not hsresource and request.method in ['GET', 'PATCH', 'DELETE']:
        return Response(status=status.HTTP_404_NOT_FOUND)

    # POST existing resource updates it
    if hsresource and request.method == 'POST':
        # Get list of existing files to see if some can be skipped
        existing_files = hs.get_file_list(hsresource.resource)
        if not existing_files:
            return Response(
                data={
                    'errors': ['HydroShare could not find requested resource']
                },
                status=status.HTTP_404_NOT_FOUND
            )

        current_analyze_files = [
            f['url'][(1 + f['url'].index('/analyze_')):]
            for f in existing_files
            if '/analyze_' in f['url']
        ]

        # Update files
        files = params.get('files', [])
        for md in params.get('mapshed_data', []):
            mdata = md.get('data')
            files.append({
                'name': md.get('name'),
                'contents': to_gms_file(json.loads(mdata)) if mdata else None,
                'object': True
            })

        # Except the existing analyze files
        files = [f for f in files if f['name'] not in current_analyze_files]

        hs.add_files(hsresource.resource, files, overwrite=True)

        hsresource.exported_at = now()
        hsresource.save()

        serializer = HydroShareResourceSerializer(hsresource)
        return Response(serializer.data)

    # Convert keywords from array to set of values
    keywords = params.get('keywords')
    keywords = set(keywords) if keywords else set()

    # POST new resource creates it in HydroShare
    resource = hs.createResource(
        'CompositeResource',
        params.get('title', project.name),
        abstract=params.get('abstract', ''),
        keywords=tuple(DEFAULT_KEYWORDS | keywords),
        extra_metadata=MMW_APP_KEY_FLAG,
    )

    # Files sent from the client
    files = params.get('files', [])

    # AoI GeoJSON
    aoi_geojson = GEOSGeometry(project.area_of_interest).geojson
    files.append({
        'name': 'area-of-interest.geojson',
        'contents': aoi_geojson,
    })

    # MapShed Data
    for md in params.get('mapshed_data', []):
        mdata = md.get('data')
        files.append({
            'name': md.get('name'),
            'contents': to_gms_file(json.loads(mdata)) if mdata else None,
            'object': True
        })

    # Add all files
    hs.add_files(resource, files)

    # AoI Shapefile
    aoi_json = json.loads(aoi_geojson)
    crs = {'no_defs': True, 'proj': 'longlat',
           'ellps': 'WGS84', 'datum': 'WGS84'}
    schema = {'geometry': aoi_json['type'], 'properties': {}}
    with fiona.open('/tmp/{}.shp'.format(resource), 'w',
                    driver='ESRI Shapefile',
                    crs=crs, schema=schema) as shapefile:
        shapefile.write({'geometry': aoi_json, 'properties': {}})

    for ext in SHAPEFILE_EXTENSIONS:
        filename = '/tmp/{}.{}'.format(resource, ext)
        with open(filename) as shapefile:
            hs.addResourceFile(resource, shapefile,
                               'area-of-interest.{}'.format(ext))
        os.remove(filename)

    # Make resource public and shareable
    endpoint = hs.resource(resource)
    endpoint.public(True)
    endpoint.shareable(True)

    # Add geographic coverage
    endpoint.functions.set_file_type({
        'file_path': 'area-of-interest.shp',
        'hs_file_type': 'GeoFeature',
    })

    # Link HydroShareResrouce to Project and save
    hsresource = HydroShareResource.objects.create(
        project=project,
        resource=resource,
        title=params.get('title', project.name),
        autosync=params.get('autosync', True),
        exported_at=now()
    )
    hsresource.save()

    # Make Project public and save
    project.is_private = False
    project.save()

    # Return newly created HydroShareResource
    serializer = HydroShareResourceSerializer(hsresource)
    return Response(serializer.data, status=status.HTTP_201_CREATED)