Esempio n. 1
0
    def edit(self, id):
        """ Action for updating a single user, denoted by the ID passed in

            @param id: ID of the user to update
        """

        # Kick unauthorized users out straight away
        if not self.current_user.access_level == 'Admin':
            return render('not_found.html')

        c.user_to_edit = self._user_service.get_user_by_id(id)

        if not c.user_to_edit:
            return render('not_found.html')

        # GET request...
        if not request.method == 'POST':

            return render("edit_user.html")

        else:
            schema = UpdateUserForm()
            c.form_errors = {}
            # POST
            try:
                c.form_result = schema.to_python(request.params)

            except formencode.Invalid, error:

                c.form_result = error.value
                c.form_errors = error.error_dict or {}

            user_email = str(c.form_result.get('email'))
            user_id = int(c.form_result.get('user_id'))

            # Username of the user will be set as the user's email address
            # Generate an error if the email address (and hence username) is already taken
            existing_user = self._user_service.get_user_by_email_address(user_email)

            if existing_user and existing_user.id != user_id:

                c.form_errors = dict(c.form_errors.items() + {
                    'email': 'Email address is already taken - please choose another.'
                }.items())

            if c.form_errors:
                html = render('edit_user.html')
                return htmlfill.render(html,
                                       defaults=c.form_result,
                                       errors=c.form_errors,
                                       auto_error_formatter=custom_formatter)
            else:
                # By default a user will be an external user
                self._user_service.update(c.form_result.get('first_name'),
                                          c.form_result.get('last_name'),
                                          user_email,
                                          "Admin" if c.form_result.get('is_admin') else "CEH",
                                          c.form_result.get('user_id'))

                return redirect(url(controller="user"))
Esempio n. 2
0
    def publish(self):
        """Action for publishing a set of results
        """

        if request.POST:

            analysis_id = request.params.get('analysis_id')

            user_obj = self.current_user
            c.username = user_obj.name

            analysis = self._analysis_service.get_analysis_by_id(analysis_id, user_obj.id)

            if analysis:
                if analysis.result_dataset:
                    # Get the result attributes from the NetCDF file associated with the result dataset
                    analysis.attributes = self._netcdf_service.get_attributes(analysis.result_dataset.netcdf_url)
                c.analysis = analysis

                try:
                    c.form_result = request.params
                except:
                    added_successfully = False
                else:
                    self._analysis_service.publish_analysis(int(analysis_id))
                    added_successfully = True

                return render('analysis_view.html', extra_vars={'added_successfully': added_successfully})
            else:
                return render('not_found.html')
        else:
            return render('not_found.html')
Esempio n. 3
0
    def sort_and_filter(self):
        """Action for sorting the analysis table using a particular column. Also responsible for filtering the table
        based on the model variable.
        """
        user = self.current_user
        query_string = request.query_string
        params = urlparse.parse_qs(query_string)

        column = get_parameter_value(params,'column')
        order = get_parameter_value(params,'order')
        filter_variable = get_parameter_value(params,'filter_variable')
        is_public = get_parameter_value(params,'is_public')

        c.order = order
        c.sorting_column = column
        c.filter_variable = filter_variable

        if is_public == "true":
            c.public_analyses = self._analysis_service.sort_and_filter_public_analyses_by_column(column,order,filter_variable)

            if not c.public_analyses:
                c.empty_public_table = "true"

            return render('public_analyses_table.html')
        else:
            c.private_analyses = self._analysis_service.sort_and_filter_private_analyses_by_column(user.id,column,order,filter_variable)

            if not c.private_analyses:
                c.empty_private_table = "true"

            return render('private_analyses_table.html')
Esempio n. 4
0
    def edit(self, id):
        """Enables a dataset's details to be updated, intended as an admin-only function

            @param id: ID of the dataset to edit
        """
        # Kick unauthorized users out straight away
        if not self.current_user.access_level == 'Admin':
            return render('not_found.html')

        c.dataset_to_edit = self._dataset_service.get_dataset_by_id(id, user_id=self.current_user.id)

        # GET request...
        if not request.method == 'POST':

            return render('edit_dataset.html')

        else:

            # Define our form schema
            schema = UpdateDatasetForm()
            c.form_errors = {}

            try:
                c.form_result = schema.to_python(request.params)

            except formencode.Invalid, error:

                c.form_result = error.value
                c.form_errors = error.error_dict or {}

            if c.form_errors:
                html = render('edit_dataset.html')
                return htmlfill.render(html,
                                       defaults=c.form_result,
                                       errors=c.form_errors,
                                       auto_error_formatter=custom_formatter)
            else:

                # Perform the update
                self._dataset_service.update(c.form_result.get('dataset_id'),
                                             c.form_result.get('data_range_from'),
                                             c.form_result.get('data_range_to'),
                                             c.form_result.get('is_categorical'))
                # By default a user will be an external user
                # self._user_service.update(c.form_result.get('first_name'),
                #                           c.form_result.get('last_name'),
                #                           user_email,
                #                           "Admin" if c.form_result.get('is_admin') else "CEH",
                #                           c.form_result.get('user_id'))

                return redirect(url(controller="dataset"))
Esempio n. 5
0
    def create(self):
        """Create a new user
        """

        if not self.current_user.access_level == 'Admin':
            return render('not_found.html')

        if not request.POST:

            return render('new_user.html')

        schema = CreateUserForm()
        c.form_errors = {}

        if request.POST:

            try:
                c.form_result = schema.to_python(request.params)

            except formencode.Invalid, error:

                c.form_result = error.value
                c.form_errors = error.error_dict or {}

            user_email = str(c.form_result.get('email'))

            # Username of the user will be set as the user's email address
            # Generate an error if the email address (and hence username) is already taken
            if self._user_service.get_user_by_email_address(user_email):
                c.form_errors = dict(c.form_errors.items() + {
                    'email': 'Email address is already taken - please choose another.'
                }.items())

            if c.form_errors:
                html = render('new_user.html')
                return htmlfill.render(html,
                                       defaults=c.form_result,
                                       errors=c.form_errors,
                                       auto_error_formatter=custom_formatter)
            else:



                # By default a user will be an external user
                self._user_service.create(c.form_result.get('user_name'),
                                          c.form_result.get('first_name'),
                                          c.form_result.get('last_name'),
                                          user_email,
                                          "Admin" if c.form_result.get('is_admin') else "CEH")
                return redirect(url(controller="user"))
Esempio n. 6
0
    def index(self):
        """Allow admin-user to see all available datasets. If user is non-admin, redirect to page not found.
        """
        identity = request.environ.get('REMOTE_USER')

        user = self._user_service.get_user_by_username(identity)

        if user.access_level == "Admin":

            c.datasets = self._dataset_service.get_all_datasets()
            return render('all_datasets.html')

        else:

            return render('not_found.html')
Esempio n. 7
0
    def index(self):
        """Allow admin-user to see all users of the system. If user is non-admin, redirect to page not found.
        """
        identity = request.environ.get('REMOTE_USER')

        user = self._user_service.get_user_by_username(identity)

        if user.access_level == "Admin":

            c.all_users = self._user_service.get_all_users()

            return render('list_of_users.html')

        else:

            return render('not_found.html')
Esempio n. 8
0
    def add(self):
        "Add a new dataset"
        if not request.POST:

            return render('add_dataset.html')

        schema = AddDatasetForm()
        c.form_errors = {}

        if request.POST:

            try:
                c.form_result = schema.to_python(request.params)

            except formencode.Invalid, error:

                c.form_result = error.value
                c.form_errors = error.error_dict or {}

            if c.form_errors:
                html = render('add_dataset.html')
                return htmlfill.render(html,
                                       defaults=c.form_result,
                                       errors=c.form_errors,
                                       auto_error_formatter=custom_formatter)
            else:
                dataset_type = c.form_result.get('type')

                if dataset_type == "Coverage":
                    self._dataset_service.create_coverage_dataset(c.form_result.get('name'),
                                                            c.form_result.get('wms_url'),
                                                            c.form_result.get('netcdf_url'),
                                                            c.form_result.get('low_res_url'),
                                                            c.form_result.get('data_range_from'),
                                                            c.form_result.get('data_range_to'),
                                                            c.form_result.get('is_categorical'))
                else:
                    # Point data, so we only need the netcdf OpenDAP url,
                    # we need to generate a gridded copy for the WMS
                    opendap_url = c.form_result.get('netcdf_url')
                    wms_url = self._netcdf_service.overlay_point_data(opendap_url)

                    self._dataset_service.create_point_dataset(c.form_result.get('name'),
                                                            wms_url,
                                                            opendap_url)

                return redirect(url(controller="dataset"))
Esempio n. 9
0
 def error_window(self):
     """Renders a page containing an error window with a specified message.
     """
     log.debug("running viewdata.error_window")
     if "message" in request.params:
         c.message = request.params["message"]
     else:
         c.message = "Unknown error"
     return render("viewdata_error.html")
Esempio n. 10
0
    def index(self):
        """Default action for the map controller"""

        user = self._user_service.get_user_by_username(request.environ['REMOTE_USER'])

        c.dataset_types = self._dataset_service.get_datasets_for_user(user.id)


        return render('map.html')
Esempio n. 11
0
    def login(self):
        """Action for the 'log in' view"""

        identity = request.environ.get('REMOTE_USER')
        came_from = request.params.get('came_from', None)
        message = request.params.get('message', None)

        if identity is not None:
            if came_from:
                redirect(url(str(came_from)))

        return render('login.html', extra_vars={'came_from': came_from, 'message': message})
Esempio n. 12
0
    def index(self):
        """Default action for the analysis controller"""

        # Who am I?
        user = self.current_user

        # Grab the analyses...
        c.private_analyses = self._analysis_service.get_analyses_for_user(user.id)
        c.public_analyses = self._analysis_service.get_public_analyses()

        #Get the model variables - used to populate the filter dropdown
        c.all_model_variables = self._analysis_service.get_all_model_variables()

        return render('analysis_list.html')
Esempio n. 13
0
    def timeselection(self, id):
        """ Gets the possible time points for a temporal dataset
            @param id: ID of the dataset to get time points for
        """

        ds = self._dataset_service.get_dataset_by_id(id, user_id = self.current_user.id)
        c.time_points = self._netcdf_service.get_time_points(ds.netcdf_url)

        c.dataset_name = ds.name
        c.column_name = request.params.get('col', '')
        c.identifier = "%s_%s" % (ds.id, c.column_name)

        if c.time_points:
            # Render the points back
            return render("dataset_time_values.html")
Esempio n. 14
0
    def view(self, id):
        """Action for looking in detail at a single analysis
            id - ID of the analysis to look at
        """

        user_obj = self.current_user

        analysis = self._analysis_service.get_analysis_by_id(id, user_obj.id)
        c.run_by_user = analysis.run_by_user.name

        if analysis:
            if analysis.result_dataset:
                # Get the result attributes from the NetCDF file associated with the result dataset
                analysis.attributes = self._netcdf_service.get_attributes(analysis.result_dataset.netcdf_url)

            c.analysis = analysis

            if 'compact' in request.params:
                return render('analysis_compact.html')
            else:
                return render('analysis_view.html', extra_vars={'added_successfully': None})
        else:
            c.object_type = 'analysis'
            return render('not_found.html')
Esempio n. 15
0
    def rerun(self, id):
        """Action for re-running a particular analysis with same parameters as before
            id - ID of the analysis to look at
        """

        user_id = self.current_user.id
        c.point_datasets = self._dataset_service.get_datasets_for_user(user_id,'Point')
        coverage_datasets = self._dataset_service.get_datasets_for_user(user_id, 'Coverage')

        # Be sure to populate the column names for each coverage dataset, this
        # will populate the list correctly
        for ds in coverage_datasets:
            ds.column_names = self._netcdf_service.get_variable_column_names(ds.netcdf_url)

        c.coverage_datasets = coverage_datasets
        c.all_models = self._model_service.get_all_models()

        current_analysis = self._analysis_service.get_analysis_by_id(id, user_id)
        point_dataset_id = current_analysis.point_data_dataset_id
        model_id = current_analysis.model_id

        # For each coverage dataset that was linked to the original analysis, there
        # will be a number of column names chosen...
        cds = current_analysis.coverage_datasets
        coverage_dataset_ids = []

        # So create the right type of "ID" based on the convention we're using
        # which is <id>_<column-name>
        for dataset in cds:
            coverage_dataset_ids.extend(["%s_%s" % (dataset.dataset_id, col.column) for col in dataset.columns])

        unit_of_time = current_analysis.unit_of_time
        random_group = current_analysis.random_group
        model_variable = current_analysis.model_variable
        data_type = current_analysis.data_type

        return render('configure_analysis.html',
                              extra_vars={'current_model_id': model_id,
                                          'current_point_dataset_id': point_dataset_id,
                                          'current_coverage_dataset_ids': coverage_dataset_ids,
                                          'unit_of_time': unit_of_time,
                                          'random_group': random_group,
                                          'model_variable': model_variable,
                                          'data_type': data_type})
Esempio n. 16
0
    def preview(self, id):
        """ Renders a preview view of the first 10 rows of a dataset (currently point data only!)
        """

        # Need to make sure the user has access to the dataset in question
        user = self._user_service.get_user_by_username(request.environ['REMOTE_USER'])
        ds = self._dataset_service.get_dataset_by_id(id, user_id = user.id)

        c.dataset_name = ds.name

        # This should contain the first 10 rows
        preview_data = self._netcdf_service.get_point_data_preview(ds.netcdf_url, 10)

        c.columns = preview_data.keys()

        # Number of rows - 1 for the row range--------------------------------------v
        c.row_set = [[preview_data[col][row] for col in c.columns] for row in range(9)]

        return render('dataset_preview.html')
Esempio n. 17
0
    def layers(self, id):
        """ Returns a view on a dataset's map layers
            @param dataset_id: The ID of the dataset to get the layer data for
        """
        dataset = self._dataset_service.get_dataset_by_id(id, user_id=self.current_user.id)

        c.dataset = dataset

        if dataset.dataset_type.type == "Result":
            c.analysis_id = self._analysis_service.get_analysis_for_result_dataset(dataset.id)

        c.layers = self.get_layers_for_dataset(dataset)

        c.dimensions = []

        # Check for dimensionality
        if c.layers and c.layers[0]["dimensions"]:
            c.dimensions = c.layers[0]["dimensions"]

        return render("layers.html")
Esempio n. 18
0
    def index(self):
        """
        Default controller method to handle the initial requests to the page
        """
        st = time.time()
        params = self._getParams()

        #get the list of default WCS endpoints
        ep = EndpointConfigFileParser()
        endpointList = ep.buildEndpointList('wcsdown')
        wcsEPList = utils.filterEnpointList(endpointList, 'WCS')
        #log.debug("wcsEPList = %s" % (pprint.pformat(wcsEPList),))
        
        c.defaultWCSEndpoints = utils.toJSON(wcsEPList)
        
        log.debug("params = %s" % (params,))
        
        endpoint = params.get('ENDPOINT', None)
        bbox = params.get('BBOX', None)
        c.time = params.get('TIME', None)
        c.time_end = params.get('TIME_END', None)
        layer = params.get('LAYER', None)
        format = params.get('FORMAT', None)
        crs = params.get('CRS', None)
        c.message = params.get('MESSAGE', "")
        c.singleTimePoint = params.get('SINGLE_TIME', "")
        
        layers = []
        supportedFormats = []
        supportedCRS = []
        bboxLimits = None
        timepositions = None
        
        if endpoint != None:
            
            st1 = time.time()
            wcs, layers = self._getWCSObj(endpoint)
            log.debug("retrieved wcs metadata in  = %s" % (time.time() - st1,))
            
            if layer != None:
                st1 = time.time()
                layerMetadata, bboxLimits, timepositions, supportedFormats, supportedCRS =\
                       self._getWCSMetadata(wcs, layer)
                log.debug("retrieved layer metadata in  = %s" % (time.time() - st1,))
                
        
        if bbox != None:
            c.selected_bbox = bbox
        elif bboxLimits != None:
            c.selected_bbox = bboxLimits
        else:
            c.selected_bbox = '-180.0,-90.0,180.0,90.0'
        
        log.debug("timepositions = %s" % (timepositions,))
        if timepositions != None and timepositions != [None]:
            builder = DateTimeOptionsBuilder(timepositions)
            options = builder.buildOptions()
            #log.debug("options = %s" % (options,))
            c.timedata = utils.toJSON(options) 
            
        c.endpoint = endpoint
        
        c.selected_layer = layer
        c.layer_options = [(x,x) for x in layers]
        c.layer_options.insert(0, ("","")) #add an empty value at the start
        
        c.selected_format = format
        c.format_options = [(x,x) for x in supportedFormats]
        c.format_options.insert(0, ("","")) #add an empty value at the start
        
        c.selected_crs = crs
        c.crs_options = [(x,x) for x in supportedCRS]
        c.crs_options.insert(0, ("","")) #add an empty value at the start
        
        # get server information from config file
        g.server=config['app_conf']['serverurl']
        
        lp = OutlineLayersConfigParser()

                
        layersList = lp.getOutlineLayerList('wcsdown')
        log.debug("layerList = %s" % (layersList,))
        
        c.baseLayerJSON = utils.toJSON(layersList) 
        
        log.debug("rendering template after %ss" % (time.time() - st,))
        return render('wcsdown.html')
Esempio n. 19
0
                            message = 'The EcoMaps database is unavailable, please contact technical support'
                            log.error("EcoMaps database unavailable: %s" % sx)

                else:
                    # Authentication not successful
                    message = 'Login failed: check your username and/or password.'
        else:
             # Forcefully forget any existing credentials.
            _, headers = who_api.login({})

            request.response_headerlist = headers
        if 'REMOTE_USER' in request.environ:
            del request.environ['REMOTE_USER']

        return htmlfill.render(
            render('login.html', extra_vars={'came_from': came_from, 'message': message}),
            defaults=c.form_result,
            errors=c.form_errors,
            auto_error_formatter=custom_formatter
        )

    def logout(self):
        """Action to log the user out of ecomaps - removing their session"""

        who_api = get_api(request.environ)
        headers = who_api.logout()

        return HTTPFound(location='/account/login', headers=headers)

def custom_formatter(error):
    """Custom error formatter"""
Esempio n. 20
0
    def about(self):
        """Action for when the user selects the about tab"""

        return render("about.html")
Esempio n. 21
0
    def index(self):
        """Default action, shows the home page"""

        c.name = self.current_user.first_name

        return render("home.html")
Esempio n. 22
0
    def test(self, id):

        c.analysis_id = id
        return render('analysis_progress.html')
Esempio n. 23
0
    def create(self):
        """ Creates the configure analysis page"""

        user_id = self.current_user.id

        c.all_models = self._model_service.get_all_models()

        c.point_datasets = self._dataset_service.get_datasets_for_user(user_id,'Point')

        coverage_datasets = self._dataset_service.get_datasets_for_user(user_id, 'Coverage')

        for ds in coverage_datasets:

            ds.column_names = self._netcdf_service.get_variable_column_names(ds.netcdf_url)

        c.coverage_datasets = coverage_datasets

        if not request.POST:

            unit_of_time = None
            random_group = None
            model_variable = None
            data_type = None

            return render('configure_analysis.html',
                          extra_vars={'unit_of_time': unit_of_time,
                                      'random_group': random_group,
                                      'model_variable': model_variable,
                                      'data_type': data_type})

        else:
            schema = ConfigureAnalysisForm()
            c.form_errors = {}

            try:
                c.form_result = schema.to_python(request.params)

            except formencode.Invalid, error:
                c.form_result = error.value
                c.form_errors = error.error_dict or {}

            #    If coverage_dataset_ids is not populated on the form
            #    the validation doesn't throw an error, but instead returns an empty
            #    array. Hence we have to do the error-handling ourselves
            if not c.form_result.get('coverage_dataset_ids'):
                c.form_errors = dict(c.form_errors.items() + {
                    'coverage_dataset_ids': 'Please select at least one coverage dataset'
                }.items())

            if c.form_errors:
                html = render('configure_analysis.html')

                return htmlfill.render(html,
                                       defaults=c.form_result,
                                       errors=c.form_errors,
                                       auto_error_formatter=custom_formatter)
            else:

                # OK, the form has been processed successfully, now
                # to see if this combination of inputs has been used
                # before
                hash = get_hash_for_inputs(c.form_result, ['point_dataset_id',
                                                           'coverage_dataset_ids',
                                                           'unit_of_time',
                                                           'random_group',
                                                           'model_variable',
                                                           'data_type',
                                                           'model_id',
                                                           'analysis_description'])


                # Almost ready to create, although first we need to create a collection of
                # time point indicies based on any temporal datasets we may have chosen

                time_indicies = {}

                for column in c.form_result.get('coverage_dataset_ids'):

                    # Is there a time selection field for this coverage ds column ?
                    # If so, it'll have been given a name starting with 'time' - see dataset_time_values.html
                    if c.form_result.get('time_%s' % column):
                        time_indicies[column] = int(c.form_result.get('time_%s' % column))

                test_analysis = self._analysis_service.get_public_analyses_with_identical_input(hash)

                if test_analysis and not any(time_indicies):
                    return redirect(url(controller='analysis', action='view', id=test_analysis.id))


                analysis_id = self._analysis_service.create(c.form_result.get('analysis_name'),
                            c.form_result.get('point_dataset_id'),
                            c.form_result.get('coverage_dataset_ids'),
                            user_id,
                            c.form_result.get('unit_of_time'),
                            c.form_result.get('random_group'),
                            c.form_result.get('model_variable'),
                            c.form_result.get('data_type'),
                            c.form_result.get('model_id'),
                            c.form_result.get('analysis_description'),
                            hash,
                            time_indicies)

                c.analysis_id = analysis_id

                analysis_to_run = self._analysis_service.get_analysis_by_id(analysis_id, user_id)

                model = self._model_service.get_model_by_id(analysis_to_run.model_id)

                # The path to the code may need to be made dynamic
                # if we start running multiple analyses
                runner = AnalysisRunner(model.code_path)
                runner.run_async(analysis_to_run)

                return render('analysis_progress.html')