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