Exemple #1
0
def run_queue(request):
    """
    Render status of queue
    """
    # Get all runs that should be shown
    queued_status = STATUS.get_queued()
    processing_status = STATUS.get_processing()
    pending_jobs = ReductionRun.objects.filter(
        Q(status=queued_status)
        | Q(status=processing_status)).order_by('created')
    # Filter those which the user shouldn't be able to see
    if USER_ACCESS_CHECKS and not request.user.is_superuser:
        with ICATCache(AUTH='uows',
                       SESSION={'sessionid':
                                request.session['sessionid']}) as icat:
            pending_jobs = filter(
                lambda job: job.experiment.reference_number in icat.
                get_associated_experiments(int(request.user.username)),
                pending_jobs)  # check RB numbers
            pending_jobs = filter(
                lambda job: job.instrument.name in icat.get_owned_instruments(
                    int(request.user.username)),
                pending_jobs)  # check instrument
    # Initialise list to contain the names of user/team that started runs
    started_by = []
    # cycle through all filtered runs and retrieve the name of the user/team that started the run
    for run in pending_jobs:
        started_by.append(started_by_id_to_name(run.started_by))
    # zip the run information with the user/team name to enable simultaneous iteration with django
    context_dictionary = {'queue': zip(pending_jobs, started_by)}
    return context_dictionary
Exemple #2
0
    def authenticate(token=None):
        """
        Checks that the given session ID (token) is still valid and returns an appropriate user object.
        If this is the first time a user has logged in a new user object is created.
        A users permissions (staff/superuser) is also set based on calls to ICAT.
        """
        with UOWSClient() as client:
            if client.check_session(token):
                person = client.get_person(token)
                try:
                    user = User.objects.get(username=person['usernumber'])
                except User.DoesNotExist:
                    user = User(username=person['usernumber'],
                                password='******',
                                first_name=person['first_name'],
                                last_name=person['last_name'],
                                email=person['email'])

                with ICATCache() as icat:
                    # Make sure user has correct permissions set. This will be checked upon each login
                    user.is_superuser = icat.is_admin(int(
                        person['usernumber']))
                    user.is_staff = (icat.is_instrument_scientist(
                        int(person['usernumber'])) or user.is_superuser)
                user.save()
                return user

        return None
Exemple #3
0
    def request_processor(request, *args, **kwargs):
        if USER_ACCESS_CHECKS and not request.user.is_superuser:
            # Get the things to check by from the arguments supplied.
            experiment_reference, owned_instrument_name, viewed_instrument_name, optional_instrument_names = None, None, None, []
            if "run_number" in kwargs:
                # Get the experiment and instrument from the given run number.
                run = ReductionRun.objects.filter(
                    run_number=int(kwargs["run_number"])).first()
                experiment_reference, viewed_instrument_name = run.experiment.reference_number, run.instrument.name
            else:
                # Get the experiment reference if it's supplied.
                if "reference_number" in kwargs:
                    experiment_reference = int(kwargs["reference_number"])
                    # Find the associated instrument.
                    experiment_obj = Experiment.objects.filter(
                        reference_number=experiment_reference).first()
                    if experiment_obj:
                        optional_instrument_names = list(
                            set([
                                run.instrument.name
                                for run in experiment_obj.reduction_runs.all()
                            ]))
                else:
                    # Look for an instrument name under 'instrument_name', or, failing that, 'instrument'.
                    owned_instrument_name = kwargs.get(
                        "instrument_name", kwargs.get("instrument"))

            with ICATCache(AUTH='uows',
                           SESSION={'sessionid':
                                    request.session['sessionid']}) as icat:
                owned_instrument_list, valid_instrument_list = icat.get_owned_instruments(
                    int(request.user.username)), icat.get_valid_instruments(
                        int(request.user.username))

                # Check for access to the instrument
                if owned_instrument_name or viewed_instrument_name:
                    optional_instrument_names.append(
                        owned_instrument_name if owned_instrument_name
                        is not None else viewed_instrument_name)

                    # Check access to an owned instrument.
                    if owned_instrument_name is not None and owned_instrument_name not in owned_instrument_list:
                        raise PermissionDenied()  # No access allowed

                    # Check access to a valid instrument (able to view some runs, etc.).
                    if viewed_instrument_name is not None and viewed_instrument_name not in owned_instrument_list + valid_instrument_list:
                        raise PermissionDenied()  # No access allowed

                # Check for access to the experiment; if the user owns one of the associated instruments, we don't need to check this.
                if optional_instrument_names and list(
                        set(optional_instrument_names).intersection(
                            owned_instrument_list)):
                    pass
                elif experiment_reference is not None and experiment_reference not in icat.get_associated_experiments(
                        int(request.user.username)):
                    raise PermissionDenied()

        # If we're here, the access checks have passed.
        return fn(request, *args, **kwargs)
Exemple #4
0
def run_queue(request):
    # Get all runs that should be shown
    queued_status = StatusUtils().get_queued()
    processing_status = StatusUtils().get_processing()
    pending_jobs = ReductionRun.objects.filter(Q(status=queued_status) | Q(status=processing_status)).order_by('created')
    
    # Filter those which the user shouldn't be able to see
    if USER_ACCESS_CHECKS and not request.user.is_superuser:
        with ICATCache(AUTH='uows', SESSION={'sessionid':request.session['sessionid']}) as icat:
            pending_jobs = filter(lambda job: job.experiment.reference_number in icat.get_associated_experiments(int(request.user.username)), pending_jobs) # check RB numbers
            pending_jobs = filter(lambda job: job.instrument.name in icat.get_owned_instruments(int(request.user.username)), pending_jobs) # check instrument
    
    context_dictionary = { 'queue' : pending_jobs }
    return context_dictionary
Exemple #5
0
def experiment_summary(request, reference_number=None):
    try:
        experiment = Experiment.objects.get(reference_number=reference_number)
        runs = ReductionRun.objects.filter(experiment=experiment).order_by('-run_version')
        data = []
        reduced_data = []
        for run in runs:
            for location in run.data_location.all():
                if location not in data:
                    data.append(location)
            for location in run.reduction_location.all():
                if location not in reduced_data:
                    reduced_data.append(location)
        try:
            with ICATCache(AUTH='uows', SESSION={'sessionid':request.session['sessionid']}) as icat:
                experiment_details = icat.get_experiment_details(int(reference_number))
        except Exception as icat_e:
            logger.error(icat_e.message)
            experiment_details = {
                'reference_number' : '',
                'start_date' : '',
                'end_date' : '',
                'title' : '',
                'summary' : '',
                'instrument' : '',
                'pi' : '',
            }
        context_dictionary = {
            'experiment' : experiment,
            'runs' :  sorted(runs, key=operator.attrgetter('last_updated'), reverse=True),
            'experiment_details' : experiment_details,
            'data' : data,
            'reduced_data' : reduced_data,
        }
    except Exception as e:
        logger.error(e.message)
        context_dictionary = {}

    return context_dictionary
Exemple #6
0
def run_list(request):
    context_dictionary = {}
    instruments = []
    owned_instruments = []
    experiments = {}

    # Superuser sees everything
    if request.user.is_superuser or not USER_ACCESS_CHECKS:
        instrument_names = Instrument.objects.values_list('name', flat=True)
        is_instrument_scientist = True
        if instrument_names:
            for instrument_name in instrument_names:
                experiments[instrument_name] = []
                instrument = Instrument.objects.get(name=instrument_name)
                instrument_experiments = Experiment.objects.filter(reduction_runs__instrument=instrument).values_list('reference_number', flat=True)
                for experiment in instrument_experiments:
                    experiments[instrument_name].append(str(experiment))
    else:
        with ICATCache(AUTH='uows',SESSION={'sessionid':request.session.get('sessionid')}) as icat:
            instrument_names = icat.get_valid_instruments(int(request.user.username))
            if instrument_names:
                experiments = icat.get_valid_experiments_for_instruments(int(request.user.username), instrument_names)
            owned_instruments = icat.get_owned_instruments(int(request.user.username))
            is_instrument_scientist = (len(owned_instruments) > 0)
                

    # get database status labels up front to reduce queries to database
    status_error = StatusUtils().get_error()
    status_queued = StatusUtils().get_queued()
    status_processing = StatusUtils().get_processing()
    
    # Keep count of the total number of runs, to preload if there aren't too many.
    total_runs = 0

    for instrument_name in instrument_names:
        try:
            instrument = Instrument.objects.get(name=instrument_name)
        except:
            continue
        instrument_queued_runs = 0
        instrument_processing_runs = 0
        instrument_error_runs = 0

        instrument_obj = {
            'name' : instrument_name,
            'experiments' : [],
            'is_instrument_scientist' : is_instrument_scientist,
            'is_active' : instrument.is_active,
            'is_paused' : instrument.is_paused
        }
        
        if instrument_name in owned_instruments:
            matching_experiments = list(set(Experiment.objects.filter(reduction_runs__instrument=instrument)))
        else:
            experiment_references = experiments[instrument_name] if instrument_name in experiments else []
            matching_experiments = Experiment.objects.filter(reference_number__in=experiment_references)
        
        for experiment in matching_experiments:
            runs = ReductionRun.objects.filter(experiment=experiment, instrument=instrument).order_by('-created')
            total_runs += runs.count()

            # count how many runs are in status error, queued and processing
            experiment_error_runs = runs.filter(status__exact=status_error).count()
            experiment_queued_runs = runs.filter(status__exact=status_queued).count()
            experiment_processing_runs = runs.filter(status__exact=status_processing).count()

            # Add experiment stats to instrument
            instrument_queued_runs += experiment_queued_runs
            instrument_processing_runs += experiment_processing_runs
            instrument_error_runs += experiment_error_runs

            experiment_obj = {
                'reference_number' : experiment.reference_number,
                'progress_summary' : {
                    'processing' : experiment_processing_runs,
                    'queued' : experiment_queued_runs,
                    'error' : experiment_error_runs,
                }
            }
            instrument_obj['experiments'].append(experiment_obj)

        instrument_obj['progress_summary']= {
            'processing' : instrument_processing_runs,
            'queued' : instrument_queued_runs,
            'error' : instrument_error_runs,
        }

        # Sort lists before appending
        instrument_obj['experiments'] = sorted(instrument_obj['experiments'], key=lambda k: k['reference_number'], reverse=True)
        instruments.append(instrument_obj)

    context_dictionary['instrument_list'] = instruments
    context_dictionary['preload_runs'] = (total_runs < PRELOAD_RUNS_UNDER)
    if is_instrument_scientist:
        context_dictionary['default_tab'] = 'run_number'
    else:
        context_dictionary['default_tab'] = 'experiment'

    return context_dictionary
Exemple #7
0
def experiment_summary(request, reference_number=None):
    """
    Render experiment summary
    """
    try:
        experiment = Experiment.objects.get(reference_number=reference_number)
        runs = ReductionRun.objects.filter(
            experiment=experiment).order_by('-run_version')
        data = []
        reduced_data = []
        started_by = []
        for run in runs:
            for location in run.data_location.all():
                if location not in data:
                    data.append(location)
            for location in run.reduction_location.all():
                if location not in reduced_data:
                    reduced_data.append(location)
            started_by.append(started_by_id_to_name(run.started_by))
        sorted_runs = sorted(runs,
                             key=operator.attrgetter('last_updated'),
                             reverse=True)
        runs_with_started_by = zip(sorted_runs, started_by)

        try:
            if DEVELOPMENT_MODE:
                # If we are in development mode use user/password for ICAT from django settings
                # e.g. do not attempt to use same authentication as the user office
                with ICATCache() as icat:
                    experiment_details = icat.get_experiment_details(
                        int(reference_number))
            else:
                with ICATCache(
                        AUTH='uows',
                        SESSION={'sessionid':
                                 request.session['sessionid']}) as icat:
                    experiment_details = icat.get_experiment_details(
                        int(reference_number))
        # pylint:disable=broad-except
        except Exception as icat_e:
            LOGGER.error(icat_e)
            experiment_details = {
                'reference_number': '',
                'start_date': '',
                'end_date': '',
                'title': '',
                'summary': '',
                'instrument': '',
                'pi': '',
            }
        context_dictionary = {
            'experiment': experiment,
            'runs_with_started_by': runs_with_started_by,
            'run_count': len(runs),
            'experiment_details': experiment_details,
            'data': data,
            'reduced_data': reduced_data,
        }
    # pylint:disable=broad-except
    except Exception as exception:
        LOGGER.error(exception)
        context_dictionary = {}

    return context_dictionary