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
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
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
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
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)