def add(): sample_set = db.sample_set[request.vars["id"]] if not auth.can_upload_sample_set(sample_set.id): return error_message("you don't have right to upload files") else: sample_type = sample_set.sample_type enough_space = vidjil_utils.check_enough_space(defs.DIR_SEQUENCES) if not enough_space: mail.send( to=defs.ADMIN_EMAILS, subject="[Vidjil] Server space", message="The space in directory %s has passed below %d%%." % (defs.DIR_SEQUENCES, defs.FS_LOCK_THRESHHOLD)) return error_message( "Uploads are temporarily disabled. System admins have been made aware of the situation." ) patient_id = None run_id = None generic_id = None if sample_set.sample_type == defs.SET_TYPE_GENERIC: generic_id = db( db.generic.sample_set_id == request.vars["id"]).select()[0].id if sample_set.sample_type == defs.SET_TYPE_PATIENT: patient_id = db( db.patient.sample_set_id == request.vars["id"]).select()[0].id if sample_set.sample_type == defs.SET_TYPE_RUN: run_id = db( db.run.sample_set_id == request.vars["id"]).select()[0].id query_pre_process = db(db.pre_process > 0).select( db.pre_process.ALL, orderby=~db.pre_process.id) pre_process_list = [] for row in query_pre_process: file = 1 if "&file2" in row.command: file = 2 pre_process_list.append( dict(id=row.id, name=row.name, file=file, info=row.info)) generic_list, generic = get_sample_set_list(defs.SET_TYPE_GENERIC, generic_id) patient_list, patient = get_sample_set_list(defs.SET_TYPE_PATIENT, patient_id) run_list, run = get_sample_set_list(defs.SET_TYPE_RUN, run_id) source_module_active = hasattr(defs, 'FILE_SOURCE') and hasattr( defs, 'FILE_TYPES') return dict(message=T('add file'), generic_list=generic_list, patient_list=patient_list, run_list=run_list, pre_process_list=pre_process_list, generic=generic, patient=patient, sample_type=sample_set.sample_type, run=run, source_module_active=source_module_active)
def search_clonedb(sequences, sample_set_id): sys.path.insert(1, os.path.abspath(defs.DIR_CLONEDB)) import grep_clones clonedb = imp.load_source('clonedb', defs.DIR_CLONEDB + os.path.sep + 'clonedb.py') results = [] parent_group = get_default_creation_group(auth)[1] auth.load_permissions(PermissionEnum.read.value, 'sample_set') auth.load_permissions(PermissionEnum.anon.value, 'sample_set') options = clonedb.build_grep_clones_options({ 'sequence': sequences[0] + ' -sample_set:%d' % sample_set_id, 'index': 'clonedb_{}'.format(parent_group) }) options += sequences[1:] args = grep_clones.parser.parse_args(options) log.debug("Seaching {} sequences in CloneDB for group {}".format( len(sequences), parent_group)) try: occurrences = grep_clones.launch_search(args) # Get occurrences for each sample with informations on its corresponding sample sets except ValueError: return error_message( 'Are you sure your account has an enabled CloneDB?') except Exception as e: return error_message(e.message) sample_set_ids = [ sid for occurrences_one_seq in occurrences for occ in occurrences_one_seq if 'tags' in occ and 'sample_set' in occ['tags'] for sid in occ['tags']['sample_set'] ] sample_sets = SampleSets(sample_set_ids) sample_names = sample_sets.get_names() sample_tags = sample_sets.get_tag_names() for occurrences_one_seq in occurrences: for occ in occurrences_one_seq: if 'tags' in occ and 'sample_set' in occ['tags']: info = get_info_of_viewable_sample_set([ int(sample_id) for sample_id in occ['tags']['sample_set'] ], int(occ['tags']['config_id'][0]), sample_names, sample_tags) occ['tags']['sample_set_viewable'] = info['viewable'] occ['tags']['sample_set_name'] = info['name'] occ['tags']['sample_tags'] = info['sample_tags'] config_db = db.config[occ['tags']['config_id'][0]] occ['tags']['config_name'] = [ config_db.name if config_db else None ] results.append(occurrences_one_seq) return response.json(results)
def restart_pre_process(): if "sequence_file_id" not in request.vars: return error_message("missing parameter") sequence_file = db.sequence_file[request.vars["sequence_file_id"]] if sequence_file is None or not auth.can_modify_file(sequence_file.id): return error_message("Permission denied") pre_process = db.pre_process[sequence_file.pre_process_id] db.sequence_file[sequence_file.id] = dict(pre_process_flag='WAIT') db.commit() res = schedule_pre_process(sequence_file.id, pre_process.id) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def download(): sample_set_id = get_sample_set_id(request.vars["results_file_id"]) if auth.can_view_sample_set(sample_set_id): results_id = int(request.vars["results_file_id"]) directory = defs.DIR_OUT_VIDJIL_ID % results_id filepath = directory + os.path.basename(request.vars['filename']) try: return response.stream(open(filepath), attachment=True, filename=request.vars['filename'], chunk_size=10**6) except IOError: return error_message("File could not be read") return error_message("access denied")
def restart_pre_process(): if "sequence_file_id" not in request.vars or request.vars['sequence_file_id'] is None: return error_message("missing parameter") sequence_file = db.sequence_file[request.vars["sequence_file_id"]] if sequence_file is None or not auth.can_modify_file(sequence_file.id): return error_message("Permission denied") pre_process = db.pre_process[sequence_file.pre_process_id] db.sequence_file[sequence_file.id] = dict(pre_process_flag = 'WAIT') db.commit() res = schedule_pre_process(sequence_file.id, pre_process.id) log.debug("restart pre process", extra={'user_id': auth.user.id, 'record_id': sequence_file.id, 'table_name': "sequence_file"}) return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
def output(): sample_set_id = get_sample_set_id_from_results_file( request.vars["results_file_id"]) if (auth.can_view_sample_set(sample_set_id)): results_id = int(request.vars["results_file_id"]) output_directory = defs.DIR_OUT_VIDJIL_ID % results_id files = os.listdir(output_directory) file_dicts = [] for f in files: file_size = vidjil_utils.format_size( os.stat(output_directory + f).st_size) file_dicts.append({'filename': f, 'size': file_size}) log.info("view output files", extra={ 'user_id': auth.user.id, 'record_id': request.vars["results_file_id"], 'table_name': "results_file" }) return dict(message="output files", results_file_id=results_id, files=file_dicts) return error_message("access denied")
def change_permission(): if not auth.can_modify_group(request.vars["group_id"]): return error_message("ACCESS_DENIED") auth.add_permission(auth.user_group(request.vars["user_id"]), PermissionEnum.admin_group.value, db.auth_group, request.vars["group_id"]) res = { "redirect": "group/permission", "args": { "id": request.vars["group_id"] }, "message": "user '%s' is now owner of the group '%s'" % (request.vars["user_id"], request.vars["group_id"]) } log.admin(res) log.info(res, extra={ 'user_id': auth.user.id, 'record_id': request.vars["id"], 'table_name': "group" }) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def remove_permission(): if not auth.can_modify_group(request.vars["group_id"]): return error_message(ACCESS_DENIED) error = "" if request.vars["group_id"] == "": error += "missing group_id, " if request.vars["user_id"] == "": error += "missing user_id, " if error == "": auth.del_permission(auth.user_group(request.vars["user_id"]), PermissionEnum.admin_group.value, db.auth_group, request.vars["group_id"]) res = { "redirect": "group/permission", "args": { "id": request.vars["group_id"] }, "message": "user '%s' is not anymore owner of the group '%s'" % (request.vars["user_id"], request.vars["group_id"]) } log.info(res, extra={ 'user_id': auth.user.id, 'record_id': request.vars["id"], 'table_name': "group" }) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def delete(): ''' Called (via request) with: \param: id (the sequence ID) \param: delete_results: (optional) boolean stating if we also want to delete the results. ''' delete_results = ('delete_results' in request.vars and request.vars['delete_results'] == "True") sample_set = db.sample_set[request.vars["redirect_sample_set_id"]] associated_id = None if sample_set.sample_type != 'sequence_file': associated_elements = db(db[sample_set.sample_type].sample_set_id == sample_set.id).select() if len(associated_elements) > 0: associated_id = associated_elements[0].id if auth.can_modify_file(request.vars["id"]): if not(delete_results): delete_sequence_file(request.vars['id']) else: db(db.results_file.sequence_file_id == request.vars["id"]).delete() db(db.sequence_file.id == request.vars["id"]).delete() for row in db( db.sample_set_membership.sequence_file_id == request.vars["id"]).select() : db(db.sample_set_membership.id == row.id).delete() res = {"redirect": "sample_set/index", "args" : { "id" : request.vars["redirect_sample_set_id"]}, "message": "sequence file deleted"} if associated_id is not None: log.info(res, extra={'user_id': auth.user.id, 'record_id': associated_id, 'table_name': sample_set.sample_type}) else: log.info(res) return gluon.contrib.simplejson.dumps(res, separators=(',',':')) else: return error_message("you need admin permission to delete this file")
def edit(): if auth.is_admin(): user = db.auth_user[request.vars["id"]] log.info("load edit form for user", extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'auth_user'}) return dict(message=T("Edit user"), user=user) return error_message(ACCESS_DENIED)
def edit_form(): if not auth.can_modify_group(request.vars['id']): return error_message(ACCESS_DENIED) error = "" if request.vars["group_name"] == "": error += "group name needed, " if error == "": db.auth_group[request.vars["id"]] = dict( role=request.vars["group_name"], description=request.vars["info"]) res = { "redirect": "group/index", "message": "group '%s' modified" % request.vars["id"] } log.info(res, extra={ 'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': "group" }) log.admin(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':')) else: res = {"success": "false", "message": error} log.error(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def get_custom_data(): from subprocess import Popen, PIPE, STDOUT if not auth.user : res = {"redirect" : URL('default', 'user', args='login', scheme=True, host=True)} #TODO _next return gluon.contrib.simplejson.dumps(res, separators=(',',':')) error = "" samples = [] if not "custom" in request.vars : error += "no file selected, " else: samples = request.vars['custom'] if type(request.vars['custom']) is not str else [request.vars['custom']] if not samples: error += "incorrect query, need at least one sample" else: for id in samples: log.debug("id = '%s'" % str(id)) sequence_file_id = db.results_file[id].sequence_file_id sample_set_id = db((db.sample_set_membership.sequence_file_id == sequence_file_id) ).select(db.sample_set_membership.sample_set_id).first().sample_set_id if not auth.can_view_sample_set(sample_set_id): error += "you do not have permission to consult this element ("+str(sample_set_id)+")" if error == "" : try: data = custom_fuse(samples) except IOError, error: return error_message(str(error)) generic_info = "Compare samples" if len(samples) > 1 else "Sample %s" % samples[0] data["sample_name"] = generic_info data["dataFileName"] = generic_info data["info"] = generic_info data["samples"]["original_names"] = [] data["samples"]["timestamp"] = [] data["samples"]["info"] = [] data["samples"]["commandline"] = [] for id in samples: sequence_file_id = db.results_file[id].sequence_file_id sample_set = db((db.sequence_file.id == sequence_file_id) & (db.sample_set_membership.sequence_file_id == db.sequence_file.id) & (db.sample_set.id == db.sample_set_membership.sample_set_id) & (db.sample_set.sample_type.belongs([defs.SET_TYPE_PATIENT, defs.SET_TYPE_RUN, defs.SET_TYPE_GENERIC])) ).select(db.sample_set.id, db.sample_set.sample_type).first() patient_run = db(db[sample_set.sample_type].sample_set_id == sample_set.id).select().first() config_id = db.results_file[id].config_id name = vidjil_utils.anon_ids([patient_run.id])[0] if sample_set.sample_type == defs.SET_TYPE_PATIENT else patient_run.name filename = db.sequence_file[sequence_file_id].filename data["samples"]["original_names"].append(name + "_" + filename) data["samples"]["timestamp"].append(str(db.sequence_file[sequence_file_id].sampling_date)) data["samples"]["info"].append(db.sequence_file[sequence_file_id].info) data["samples"]["commandline"].append(db.config[config_id].command) log.info("load custom data #TODO log db") return gluon.contrib.simplejson.dumps(data, separators=(',',':'))
def edit(): if (auth.can_modify_config(request.vars['id'])): mes = u"Load config edit form" classification = db( (db.classification) ).select() log.info(mes, extra={'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'config'}) return dict(message=T('edit config'), classification=classification) return error_message(ACCESS_DENIED)
def auto_complete(): if "keys" not in request.vars: return error_message("missing group ids") prefix = get_tag_prefix() group_ids = json.loads(request.vars["keys"]) tags = get_tags(db, group_ids) return tags_to_json(tags, group_ids)
def info(): if auth.can_view_group(request.vars["id"]): log.info("access user list", extra={ 'user_id': auth.user.id, 'record_id': request.vars["id"], 'table_name': "group" }) return dict(message=T('group info')) return error_message(ACCESS_DENIED)
def permission(): if auth.can_modify_group(request.vars["id"]): log.info("view permission page", extra={ 'user_id': auth.user.id, 'record_id': request.vars["id"], 'table_name': "group" }) return dict(message=T('permission')) return error_message(ACCESS_DENIED)
def confirm(): ''' Request parameters: \param delete_results: (optional) boolean \param id: sequence file ID ''' delete_only_sequence = ('delete_only_sequence' in request.vars and request.vars['delete_only_sequence'] == 'True') delete_results = ('delete_results' in request.vars and request.vars['delete_results'] == 'True') sequence_file = db.sequence_file[request.vars['id']] if sequence_file == None: return error_message("The requested file doesn't exist") if sequence_file.data_file == None: delete_results = True if auth.can_modify_sample_set(request.vars['redirect_sample_set_id']): return dict(message=T('choose what you would like to delete'), delete_only_sequence = delete_only_sequence, delete_results = delete_results) else: return error_message("you need admin permission to delete this file")
def delete_sequence_file(seq_id): sequence = db.sequence_file[seq_id] seq_filename = sequence.data_file if auth.can_modify_file(seq_id): if seq_filename is not None: log.debug('Deleting '+defs.DIR_SEQUENCES+seq_filename+' with ID'+str(seq_id)) db.sequence_file[seq_id] = dict(data_file = None) else: return error_message('you need admin permission to delete this file')
def edit(): if auth.is_admin(): user = db.auth_user[request.vars["id"]] log.info("load edit form for user", extra={ 'user_id': auth.user.id, 'record_id': request.vars['id'], 'table_name': 'auth_user' }) return dict(message=T("Edit user"), user=user) return error_message(ACCESS_DENIED)
def get_custom_data(): from subprocess import Popen, PIPE, STDOUT if not auth.user : res = {"redirect" : URL('default', 'user', args='login', scheme=True, host=True)} #TODO _next return gluon.contrib.simplejson.dumps(res, separators=(',',':')) error = "" if not "custom" in request.vars : error += "no file selected, " else: if type(request.vars['custom']) is not list or len(request.vars['custom']) < 2: error += "you must select several files." else: for id in request.vars["custom"] : log.debug("id = '%s'" % str(id)) sequence_file_id = db.results_file[id].sequence_file_id patient_id = db((db.sample_set_membership.sequence_file_id == sequence_file_id) & (db.patient.sample_set_id == db.sample_set_membership.sample_set_id) ).select(db.patient.id).first() if not auth.can_view_patient(patient_id): error += "you do not have permission to consult this patient ("+str(patient_id)+")" if error == "" : try: data = custom_fuse(request.vars["custom"]) except IOError, error: return error_message(str(error)) data["dataFileName"] = "Compare patients" data["info"] = "Compare patients" data["samples"]["original_names"] = [] data["samples"]["timestamp"] = [] data["samples"]["info"] = [] data["samples"]["commandline"] = [] for id in request.vars["custom"] : sequence_file_id = db.results_file[id].sequence_file_id sample_set = db((db.sequence_file.id == sequence_file_id) & (db.sample_set_membership.sequence_file_id == db.sequence_file.id) & (db.sample_set.id == db.sample_set_membership.sample_set_id) & (db.sample_set.sample_type.belongs(['patient', 'run'])) ).select(db.sample_set.id, db.sample_set.sample_type).first() patient_run = db(db[sample_set.sample_type].sample_set_id == sample_set.id).select().first() config_id = db.results_file[id].config_id name = vidjil_utils.anon_ids(patient_run.id) if sample_set.sample_type == 'patient' else patient_run.name filename = db.sequence_file[sequence_file_id].filename data["samples"]["original_names"].append(name + "_" + filename) data["samples"]["timestamp"].append(str(db.sequence_file[sequence_file_id].sampling_date)) data["samples"]["info"].append(db.sequence_file[sequence_file_id].info) data["samples"]["commandline"].append(db.config[config_id].command) return gluon.contrib.simplejson.dumps(data, separators=(',',':'))
def delete(): if not auth.can_modify_group(request.vars["id"]): return error_message(ACCESS_DENIED) #delete group db(db.auth_group.id == request.vars["id"]).delete() res = { "redirect": "group/index", "message": "group '%s' deleted" % request.vars["id"] } log.info(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def add_form(): error ="" if (not auth.can_create_config()): return error_message(ACCESS_DENIED) required_fields = ['config_name', 'config_command', 'config_fuse_command', 'config_program'] for field in required_fields: if request.vars[field] == "" : error += field+" needed, " ## test if classification id exist if request.vars["config_classification"] != "-1": classification = db(db.classification.id == request.vars["config_classification"]).count() if classification == 0: error += "classification id don't exist, " else : request.vars["config_classification"] = None if error=="" : config_id = db.config.insert(name=request.vars['config_name'], info=request.vars['config_info'], command=request.vars['config_command'], fuse_command=request.vars['config_fuse_command'], program=request.vars['config_program'], classification=request.vars['config_classification'] ) user_group = None group_ids = list(auth.user_groups.keys()) for gid in group_ids: if (auth.user_groups[gid] != 'public'): user_group = gid break db.auth_permission.insert(group_id=user_group, name=PermissionEnum.create_config.value, table_name='config', record_id=config_id) mes = u"Added config" log.info(mes, extra={'user_id': auth.user.id, 'record_id': config_id, 'table_name': 'config'}) res = {"redirect": "config/index", "message": "config '%s' added" % request.vars['config_name']} log.info(res) return gluon.contrib.simplejson.dumps(res, separators=(',',':')) else : res = {"success" : "false", "message" : error} log.error(res) return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
def delete(): if (auth.can_modify_config(request.vars['id'])): #delete results_file using this config db(db.results_file.config_id==request.vars["id"]).delete() #delete config db(db.config.id==request.vars["id"]).delete() res = {"redirect": "config/index", "message": "config '%s' deleted" % request.vars["id"]} log.admin(res) return gluon.contrib.simplejson.dumps(res, separators=(',',':')) return error_message(ACCESS_DENIED)
def edit(): if auth.is_admin() or auth.has_permission( PermissionsEnum.admin.value, db.auth_group, request.vars["id"]): group = db.auth_group[request.vars["id"]] return dict(message=T('Edit group'), group=group) log.info('access group edit form', extra={ 'user_id': auth.user.id, 'record_id': request.vars["id"], 'table_name': "group" }) return error_message(ACCESS_DENIED)
def download(): sample_set_id = get_sample_set_id_from_results_file( request.vars["results_file_id"]) if auth.can_view_sample_set( sample_set_id) and not '..' in request.vars['filename']: results_id = int(request.vars["results_file_id"]) directory = defs.DIR_OUT_VIDJIL_ID % results_id filepath = directory + request.vars['filename'] try: log.info("Downloaded results file", extra={ 'user_id': auth.user.id, 'record_id': request.vars["results_file_id"], 'table_name': "results_file" }) return response.stream(open(filepath), attachment=True, filename=request.vars['filename'], chunk_size=10**6) except IOError: return error_message("File could not be read") return error_message("access denied")
def search_clonedb(sequences, sample_set_id): sys.path.insert(1, os.path.abspath(defs.DIR_CLONEDB)) import grep_clones clonedb = imp.load_source('clonedb', defs.DIR_CLONEDB+os.path.sep+'clonedb.py') results = [] parent_group = get_default_creation_group(auth)[1] auth.load_permissions(PermissionEnum.read.value, 'sample_set') auth.load_permissions(PermissionEnum.anon.value, 'sample_set') options = clonedb.build_grep_clones_options({'sequence': sequences[0]+' -sample_set:%d' % sample_set_id, 'index': 'clonedb_{}'.format(parent_group)}) options += sequences[1:] args = grep_clones.parser.parse_args(options) try: occurrences = grep_clones.launch_search(args) except ValueError: return error_message('Are you sure your account has an enabled CloneDB?') except Exception as e: return error_message(e.message) sample_set_ids = [ sid for occurrences_one_seq in occurrences for occ in occurrences_one_seq if 'tags' in occ and 'sample_set' in occ['tags'] for sid in occ['tags']['sample_set'] ] sample_sets = SampleSets(sample_set_ids) sample_names = sample_sets.get_names() sample_tags = sample_sets.get_tag_names() for occurrences_one_seq in occurrences: for occ in occurrences_one_seq: if 'tags' in occ and 'sample_set' in occ['tags']: info = get_info_of_viewable_sample_set([int(sample_id) for sample_id in occ['tags']['sample_set']], int(occ['tags']['config_id'][0]), sample_names, sample_tags) occ['tags']['sample_set_viewable'] = info['viewable'] occ['tags']['sample_set_name'] = info['name'] occ['tags']['sample_tags'] = info['sample_tags'] config_db = db.config[occ['tags']['config_id'][0]] occ['tags']['config_name'] = [config_db.name if config_db else None] results.append(occurrences_one_seq) return response.json(results)
def add_form(): if not auth.is_admin(): return error_message(ACCESS_DENIED) error = "" if request.vars["group_name"] == "": error += "group name needed, " if error == "": id = db.auth_group.insert(role=request.vars["group_name"], description=request.vars["info"]) user_group = auth.user_group(auth.user.id) #group creator is a group member auth.add_membership(id, auth.user.id) # Associate group with parent group network group_parent = request.vars["group_parent"] if group_parent != None and group_parent != 'None': parent_list = db( db.group_assoc.second_group_id == group_parent).select( db.group_assoc.ALL) parent = None if len(parent_list) > 0: for parent in parent_list: db.group_assoc.insert(first_group_id=parent.first_group_id, second_group_id=id) auth.add_permission(parent.first_group_id, PermissionEnum.admin_group.value, db.auth_group, id) else: db.group_assoc.insert(first_group_id=group_parent, second_group_id=id) auth.add_permission(group_parent, PermissionEnum.admin_group.value, db.auth_group, id) else: auth.add_permission(id, PermissionEnum.admin_group.value, id) add_default_group_permissions(auth, id) res = {"redirect": "group/index", "message": "group '%s' created" % id} log.info(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':')) else: res = {"success": "false", "message": error} log.error(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def index(): ''' The request should receive two parameters: - sequences: a list of comma-separated DNA sequences to be searched in the CloneDB - sample_set_id: the sample set we're coming from ''' if not auth.user: return response.json({'error': 'Access denied'}) if request.vars['sequences'] == None or request.vars['sequences'] == ''\ or request.vars['sample_set_id'] == None: return error_message('Malformed request') return search_clonedb(request.vars['sequences'].split(','), int(request.vars['sample_set_id']))
def edit(): if auth.can_modify_file(request.vars['id']): relevant_ids = {'patient': None, 'run': None, 'generic': None} sample_set_list = db( (db.sample_set_membership.sequence_file_id == request.vars['id']) & (db.sample_set_membership.sample_set_id != None) & (db.sample_set.id == db.sample_set_membership.sample_set_id) & (db.sample_set.sample_type != 'sequence_file')).select( db.sample_set_membership.sample_set_id) for row in sample_set_list: sample_type = db.sample_set[row.sample_set_id].sample_type relevant_ids[sample_type] = db(db[sample_type].sample_set_id == row.sample_set_id).select()[0].id query_pre_process = db(db.pre_process > 0).select( db.pre_process.ALL, orderby=~db.pre_process.id) pre_process_list = [] for row in query_pre_process: file = 1 if "&file2" in row.command: file = 2 pre_process_list.append( dict(id=row.id, name=row.name, file=file, info=row.info)) generic_list, generic = get_sample_set_list(defs.SET_TYPE_GENERIC, relevant_ids['generic']) patient_list, patient = get_sample_set_list(defs.SET_TYPE_PATIENT, relevant_ids['patient']) run_list, run = get_sample_set_list(defs.SET_TYPE_RUN, relevant_ids['run']) source_module_active = hasattr(defs, 'FILE_SOURCE') and hasattr( defs, 'FILE_TYPES') return dict(message=T('edit file'), generic_list=generic_list, patient_list=patient_list, run_list=run_list, patient=patient, pre_process_list=pre_process_list, run=run, generic=generic, file=db.sequence_file[request.vars["id"]], sample_type=request.vars['sample_type'], source_module_active=source_module_active) else: return error_message("you need admin permission to edit files")
def delete(): ''' Called (via request) with: \param: id (the sequence ID) \param: delete_results: (optional) boolean stating if we also want to delete the results. ''' delete_results = ('delete_results' in request.vars and request.vars['delete_results'] == "True") sample_set = db.sample_set[request.vars["redirect_sample_set_id"]] associated_id = None if sample_set.sample_type not in ['sequence_file', 'sample_set']: associated_elements = db(db[sample_set.sample_type].sample_set_id == sample_set.id).select() if len(associated_elements) > 0: associated_id = associated_elements[0].id if auth.can_modify_file(request.vars["id"]): if not (delete_results): delete_sequence_file(request.vars['id']) else: sample_set_ids = get_sequence_file_sample_sets(request.vars["id"]) config_ids = get_sequence_file_config_ids(request.vars["id"]) db(db.results_file.sequence_file_id == request.vars["id"]).delete() db(db.sequence_file.id == request.vars["id"]).delete() set_memberships = db( db.sample_set_membership.sample_set_id.belongs( sample_set_ids)).select() non_empty_set_ids = [r.sample_set_id for r in set_memberships] schedule_fuse(non_empty_set_ids, config_ids) res = { "redirect": "sample_set/index", "args": { "id": request.vars["redirect_sample_set_id"] }, "message": "sequence file ({}) deleted".format(request.vars['id']) } if associated_id is not None: log.info(res, extra={ 'user_id': auth.user.id, 'record_id': associated_id, 'table_name': sample_set.sample_type }) else: log.info(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':')) else: return error_message("you need admin permission to delete this file")
def delete(): if (auth.can_modify_config(request.vars['id'])): #delete results_file using this config db(db.results_file.config_id == request.vars["id"]).delete() #delete config db(db.config.id == request.vars["id"]).delete() res = { "redirect": "config/index", "message": "config '%s' deleted" % request.vars["id"] } log.admin(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':')) return error_message(ACCESS_DENIED)
def change_permission(): if not auth.can_modify_group(request.vars["group_id"]): return error_message("ACCESS_DENIED") auth.add_permission(auth.user_group(request.vars["user_id"]), PermissionEnum.admin_group.value, db.auth_group, request.vars["group_id"]) res = { "redirect": "group/permission", "args": { "id": request.vars["group_id"] } } log.info(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def run_request(): error = "" enough_space = vidjil_utils.check_enough_space(defs.DIR_RESULTS) if not enough_space: mail.send(to=defs.ADMIN_EMAILS, subject="[Vidjil] Server space", message="The space in directory %s has passed below %d%%." % (defs.DIR_RESULTS, defs.FS_LOCK_THRESHHOLD)) return error_message( "Runs are temporarily disabled. System admins have been made aware of the situation." ) ##TODO check if not "sequence_file_id" in request.vars: error += "id sequence file needed, " if not "config_id" in request.vars: error += "id config needed, " id_config = None else: id_config = request.vars["config_id"] if not auth.can_process_sample_set(request.vars['sample_set_id']): error += "permission needed" id_sample_set = request.vars["sample_set_id"] if "grep_reads" in request.vars: grep_reads = request.vars["grep_reads"] else: grep_reads = None if not auth.can_modify_sample_set(id_sample_set): error += "you do not have permission to launch process for this sample_set (" + str( id_sample_set) + "), " if id_config: if not auth.can_use_config(id_config): error += "you do not have permission to launch process for this config (" + str( id_config) + "), " if error == "": res = schedule_run(request.vars["sequence_file_id"], id_config, grep_reads) return gluon.contrib.simplejson.dumps(res, separators=(',', ':')) else: res = {"success": "false", "message": "default/run_request : " + error} log.error(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def add_form(): error = "" if (not auth.can_create_config()): return error_message(ACCESS_DENIED) required_fields = [ 'config_name', 'config_command', 'config_fuse_command', 'config_program' ] for field in required_fields: if request.vars[field] == "": error += field + " needed, " if error == "": config_id = db.config.insert( name=request.vars['config_name'], info=request.vars['config_info'], command=request.vars['config_command'], fuse_command=request.vars['config_fuse_command'], program=request.vars['config_program']) user_group = None group_ids = list(auth.user_groups.keys()) for gid in group_ids: if (auth.user_groups[gid] != 'public'): user_group = gid break db.auth_permission.insert(group_id=user_group, name=PermissionEnum.create_config.value, table_name='config', record_id=config_id) res = { "redirect": "config/index", "message": "config '%s' added" % request.vars['config_name'] } log.admin(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':')) else: res = {"success": "false", "message": error} log.error(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def delete(): if not auth.can_modify_group(request.vars["id"]): return error_message(ACCESS_DENIED) #delete group db(db.auth_group.id == request.vars["id"]).delete() res = { "redirect": "group/index", "message": "group '%s' deleted" % request.vars["id"] } log.info(res, extra={ 'user_id': auth.user.id, 'record_id': request.vars["id"], 'table_name': "group" }) log.admin(res) return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))
def run_request(): error = "" enough_space = vidjil_utils.check_enough_space(defs.DIR_RESULTS) if not enough_space: mail.send(to=defs.ADMIN_EMAILS, subject="[Vidjil] Server space", message="The space in directory %s has passed below %d%%." % (defs.DIR_RESULTS, defs.FS_LOCK_THRESHHOLD)) return error_message("Runs are temporarily disabled. System admins have been made aware of the situation.") ##TODO check if not "sequence_file_id" in request.vars : error += "id sequence file needed, " if not "config_id" in request.vars: error += "id config needed, " id_config = None else: id_config = request.vars["config_id"] if not auth.can_process_sample_set(request.vars['sample_set_id']): error += "permission needed" id_sample_set = request.vars["sample_set_id"] if "grep_reads" in request.vars: grep_reads = request.vars["grep_reads"] else: grep_reads = None if not auth.can_modify_sample_set(id_sample_set) : error += "you do not have permission to launch process for this sample_set ("+str(id_sample_set)+"), " if id_config: if not auth.can_use_config(id_config) : error += "you do not have permission to launch process for this config ("+str(id_config)+"), " if error == "" : res = schedule_run(request.vars["sequence_file_id"], id_config, grep_reads) log.info("run requested", extra={'user_id': auth.user.id, 'record_id': request.vars['sequence_file_id'], 'table_name': 'sequence_file'}) return gluon.contrib.simplejson.dumps(res, separators=(',',':')) else : res = {"success" : "false", "message" : "default/run_request : " + error} log.error(res) return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
def edit_form(): error = "" patient_id = None run_id = None if request.vars['patient_id'] != '' : patient_id = int(request.vars['patient_id'].split('(')[-1][:-1]) if request.vars['run_id'] != '' : run_id = int(request.vars['run_id'].split('(')[-1][:-1]) if request.vars['id'] == None : error += "missing id" if request.vars['filename'] == None : error += " missing filename" if request.vars['sampling_date'] != '' : try: datetime.datetime.strptime(""+request.vars['sampling_date'], '%Y-%m-%d') except ValueError: error += "date (wrong format), " if error=="" : mes = "file {%s}: " % request.vars['id'] filename = db.sequence_file[request.vars['id']].filename if request.vars['filename'] != "": filename = request.vars['filename'] pre_process = None if request.vars['pre_process'] != "0": pre_process = int(request.vars['pre_process']) if request.vars['sampling_date'] != None and request.vars['file_info'] != None : db.sequence_file[request.vars["id"]] = dict(sampling_date=request.vars['sampling_date'], info=request.vars['file_info'], filename=filename, pre_process_id=pre_process, provider=auth.user_id) #remove previous membership for row in db( db.sample_set_membership.sequence_file_id == request.vars["id"]).select() : if db.sample_set[row.sample_set_id].sample_type != "sequence_file" : db(db.sample_set_membership.id == row.id).delete() #add sequence_file to a run sample_set if run_id is not None : run_sample_set_id = db.run[run_id].sample_set_id id_sample_set_membership_run = db.sample_set_membership.insert(sample_set_id=run_sample_set_id, sequence_file_id=request.vars["id"]) #add sequence_file to a patient sample_set if patient_id is not None : patient_sample_set_id = db.patient[patient_id].sample_set_id id_sample_set_membership_patient = db.sample_set_membership.insert(sample_set_id=patient_sample_set_id, sequence_file_id=request.vars["id"]) if request.vars['sample_type'] == 'run': originating_id = run_sample_set_id else: originating_id = patient_sample_set_id redirect_args = {"id" : originating_id} res = {"file_id" : request.vars["id"], "message": "file {%s}: metadata saved" % request.vars["id"], "redirect": "sample_set/index", "args" : redirect_args } log.info(res, extra={'user_id': auth.user.id, 'record_id': redirect_args['id'], 'table_name': 'run' if run_id is not None else 'patient'}) return gluon.contrib.simplejson.dumps(res, separators=(',',':')) else : return error_message(error)
def add(): sample_set = db.sample_set[request.vars["id"]] if not auth.can_upload_sample_set(sample_set.id): return error_message("you don't have right to upload files") else: patient_id = None run_id = None if sample_set.sample_type == "patient" : patient_id = db( db.patient.sample_set_id == request.vars["id"]).select()[0].id if sample_set.sample_type == "run" : run_id = db( db.run.sample_set_id == request.vars["id"]).select()[0].id query_pre_process = db( db.pre_process>0 ).select( db.pre_process.ALL, orderby = ~db.pre_process.id ) pre_process_list = [] for row in query_pre_process : file = 1 if "&file2" in row.command: file = 2 pre_process_list.append(dict( id = row.id, name = row.name, file = file, info = row.info )) query_patient = db( auth.vidjil_accessible_query(PermissionEnum.read.value, db.patient) ).select( db.patient.ALL, orderby = ~db.patient.id ) patient_list = [] patient = "" for row in query_patient : name = row.first_name + " " + row.last_name birth = "[" + str(row.birth) + "] " id = " ("+str(row.id)+")" patient_list.append(birth+name+id) if patient_id == row.id : patient = birth+name+id query_run = db( auth.vidjil_accessible_query(PermissionEnum.read.value, db.run) ).select( db.run.ALL, orderby = ~db.run.id ) run_list = [] run = "" for row in query_run : name = row.name run_date = "[" + str(row.run_date) + "] " id = " ("+str(row.id)+")" run_list.append(run_date+name+id) if run_id == row.id : run = run_date+name+id return dict(message = T('add file'), patient_list = patient_list, run_list = run_list, pre_process_list = pre_process_list, patient = patient, sample_type = sample_set.sample_type, run = run)
def add_form(): error = "" patient_id = None run_id = None if request.vars['sampling_date'] != '' : try: datetime.datetime.strptime(""+request.vars['sampling_date'], '%Y-%m-%d') except ValueError: error += "date (wrong format), " if request.vars['filename'] == None : error += " missing file" if request.vars['patient_id'] == '' and request.vars['run_id'] == "" : error += " missing patient or run" if request.vars['patient_id'] != '' : patient_id = int(request.vars['patient_id'].split('(')[-1][:-1]) if not auth.can_modify_patient(patient_id) : error += " missing permission for patient "+str(patient_id) query = db((db.patient.id == patient_id) &(db.sample_set_membership.sample_set_id == db.patient.sample_set_id) &(db.sequence_file.id == db.sample_set_membership.sequence_file_id) ).select(db.sequence_file.ALL) for row in query : if row.filename == request.vars['filename'] : error += " this sequence file already exists for this patient" if request.vars['run_id'] != '' : run_id = int(request.vars['run_id'].split('(')[-1][:-1]) if not auth.can_modify_run(run_id) : error += " missing permission for run "+str(run_id) pre_process = None pre_process_flag = "DONE" if request.vars['pre_process'] != "0": pre_process = request.vars['pre_process'] pre_process_flag = "WAIT" if error=="" : #add sequence_file to the db id = db.sequence_file.insert(sampling_date=request.vars['sampling_date'], info=request.vars['file_info'], filename=request.vars['filename'], pre_process_id=pre_process, pre_process_flag=pre_process_flag, provider=auth.user_id) #add a default sample_set for this sequence file id_sample_set = db.sample_set.insert(sample_type="sequence_file") ids_sample_set = [] id_sample_set_membership = db.sample_set_membership.insert(sample_set_id=id_sample_set, sequence_file_id=id) #add sequence_file to a run sample_set if run_id is not None : run_sample_set_id = db.run[run_id].sample_set_id ids_sample_set += [run_sample_set_id] # for logging id_sample_set_membership_run = db.sample_set_membership.insert(sample_set_id=run_sample_set_id, sequence_file_id=id) #add sequence_file to a patient sample_set if patient_id is not None : patient_sample_set_id = db.patient[patient_id].sample_set_id ids_sample_set += [patient_sample_set_id] # for logging id_sample_set_membership_patient = db.sample_set_membership.insert(sample_set_id=patient_sample_set_id, sequence_file_id=id) if request.vars['sample_type'] == 'run': originating_id = run_sample_set_id else: originating_id = patient_sample_set_id redirect_args = {"id" : originating_id} res = {"file_id" : id, "message": "(%s) file {%s} : upload started: %s" % (','.join(map(str,ids_sample_set)), id, request.vars['filename']), "redirect": "sample_set/index", "args" : redirect_args } log.info(res, extra={'user_id': auth.user.id,\ 'record_id': run_id if run_id is not None else patient_id,\ 'table_name': 'run' if run_id is not None else 'patient'}) return gluon.contrib.simplejson.dumps(res, separators=(',',':')) else : return error_message(error)
def form(): group_ids = [] relevant_ids = {} helpers = get_set_helpers() # new file if 'sample_set_id' in request.vars: sample_set = db.sample_set[request.vars["sample_set_id"]] if not auth.can_upload_sample_set(sample_set.id): return error_message("you don't have right to upload files") sample_type = sample_set.sample_type enough_space = vidjil_utils.check_enough_space(defs.DIR_SEQUENCES) if not enough_space: mail.send(to=defs.ADMIN_EMAILS, subject="[Vidjil] Server space", message="The space in directory %s has passed below %d%%." % (defs.DIR_SEQUENCES, defs.FS_LOCK_THRESHHOLD)) return error_message("Uploads are temporarily disabled. System admins have been made aware of the situation.") row = db(db[sample_set.sample_type].sample_set_id == request.vars["sample_set_id"]).select().first() stype = sample_set.sample_type if stype not in relevant_ids: relevant_ids[stype] = [] relevant_ids[stype].append(row.id) action = 'add' log.debug("load add form", extra={'user_id': auth.user.id, 'record_id': request.vars['sample_set_id'], 'table_name': "sample_set"}) # edit file elif 'file_id' in request.vars and request.vars['file_id'] is not None: if not auth.can_modify_file(request.vars['file_id']): return error_message("you need admin permission to edit files") sample_set_list = db( (db.sample_set_membership.sequence_file_id == request.vars['file_id']) & (db.sample_set_membership.sample_set_id != None) & (db.sample_set.id == db.sample_set_membership.sample_set_id) & (db.sample_set.sample_type != 'sequence_file') ).select(db.sample_set_membership.sample_set_id.with_alias('sample_set_id'), db.sample_set.sample_type.with_alias('sample_type')) for row in sample_set_list : smp_type= row.sample_type if smp_type not in relevant_ids: relevant_ids[smp_type] = [] relevant_ids[smp_type].append(db(db[smp_type].sample_set_id == row.sample_set_id).select()[0].id) action = 'edit' sample_type = request.vars["sample_type"] log.debug("load edit form", extra={'user_id': auth.user.id, 'record_id': request.vars['file_id'], 'table_name': "sequence_file"}) else: return error_message("missing sample_set or file id") myfile = db.sequence_file[request.vars["file_id"]] if myfile is None: myfile = {} myfile['sets'] = [] sets = get_set_list(relevant_ids, helpers) data = {} data['file'] = [myfile] data['sets'] = sets data['sample_type'] = sample_type data['errors'] = [] data['action'] = action return form_response(data)
def confirm(): if (auth.can_modify_config(request.vars['id'])): return dict(message=T('confirm config deletion')) return error_message(ACCESS_DENIED)
def edit(): if (auth.can_modify_config(request.vars['config_id'])): return dict(message=T('edit config')) return error_message(ACCESS_DENIED)
def edit(): if auth.can_modify_file(request.vars['id']): patient_id = None run_id = None sample_set_list = db(db.sample_set_membership.sequence_file_id == request.vars['id']).select(db.sample_set_membership.sample_set_id) for row in sample_set_list : if db.sample_set[row.sample_set_id].sample_type == "patient" : patient_id = db( db.patient.sample_set_id == row.sample_set_id).select()[0].id if db.sample_set[row.sample_set_id].sample_type == "run" : run_id = db( db.run.sample_set_id == row.sample_set_id).select()[0].id query_pre_process = db( db.pre_process>0 ).select( db.pre_process.ALL, orderby = ~db.pre_process.id ) pre_process_list = [] for row in query_pre_process : file = 1 if "&file2" in row.command: file = 2 pre_process_list.append(dict( id = row.id, name = row.name, file = file, info = row.info )) query_patient = db( auth.vidjil_accessible_query(PermissionEnum.admin.value, db.patient) ).select( db.patient.ALL, orderby = ~db.patient.id ) patient_list = [] patient = "" for row in query_patient : name = row.first_name + " " + row.last_name birth = "[" + str(row.birth) + "] " id = " ("+str(row.id)+")" patient_list.append(birth+name+id) if patient_id == row.id : patient = birth+name+id query_run = db( auth.vidjil_accessible_query(PermissionEnum.admin.value, db.run) ).select( db.run.ALL, orderby = ~db.run.id ) run_list = [] run = "" for row in query_run : name = row.name run_date = "[" + str(row.run_date) + "] " id = " ("+str(row.id)+")" run_list.append(run_date+name+id) if run_id == row.id : run = run_date+name+id return dict(message = T('edit file'), patient_list = patient_list, run_list = run_list, patient = patient, pre_process_list = pre_process_list, run = run, file = db.sequence_file[request.vars["id"]], sample_type = request.vars['sample_type']) else: return error_message("you need admin permission to edit files")