def file_list_json(request): app_access = __check_app_access() if app_access is not None: return app_access authed_user = auth.get_current_user() user_key = ps.get_user_key_by_id(authed_user.user_id()) #TODO: This shouldn't be here - a generic method in APIPermissions would be nice. # 'your files' file_list = [] lst = ps.get_user_permissions_list(user_key) temp_group = [] if lst is not None: for perm in lst: list_entry = {} file_entry = ps.get_file_by_key(perm.file_key) if file_entry is not None: temp_file = ds.get_file_info(file_entry.file_name) if temp_file is None: continue list_entry.update({ 'permissions' : 'yes', 'friendlyName' : file_entry.friendly_name, 'colour' : perm.colour, 'starred' : perm.starred } ) temp_file.filename = temp_file.filename.rpartition('/')[2] list_entry.update( { 'filename' : temp_file.filename, 'size' : temp_file.st_size, 'hash' : temp_file.etag, 'timestamp' : temp_file.st_ctime }) temp_group.append(list_entry) if len(temp_group) > 0: file_list.append({ 'catagory' : 'owned', 'heading' : 'Your Files', 'type' : 'files', 'data' : temp_group }) if len(file_list) == 0: file_list.append({ 'catagory' : 'notice', 'type' : 'html', # TODO: move this line out 'data' : '<a data-toggle="modal" data-target="#uploadModal" class="list-group-item">No files - Click here to upload one</a>' }) return HttpResponse(json.dumps(file_list), content_type="application/json")
def __check_app_access(redir = False): authed_user = auth.get_current_user() if authed_user is None: return __unauthed_response(redir) else: elem = ps.get_element_key_by_ref('canLogIn') if elem is not None: user_key = ps.get_user_key_by_id(authed_user.user_id()) if user_key is not None: perm = ps.get_user_element_permissions(user_key, elem) if perm is not None: if perm.access: return None return __not_signed_up_response(redir)
def analysis_status_json(request): authed_user = auth.get_current_user() if authed_user is None: return __unauthed_response() user_key = ps.get_user_key_by_id(authed_user.user_id()) response_part = { 'backoff' : 0, #tells the client to back off for a given amount of time (milliseconds) (This is added to the client's constant poll interval) 'giveup' : True, #True instructs the client to stop polling - useful for situations such as unauthed requests where polling will never result in the user being shown a graph 'done' : False #True indicates that the analysis has finished and that the user can be redirected to the new image } try: file_req = json.loads(request.raw_post_data) except ValueError: response_part.update({'error' : 'Invalid request payload.'}) return HttpResponse(json.dumps(response_part), content_type="application/json") if 'filename' not in file_req: response_part.update({'error' : 'Incomplete request.'}) return HttpResponse(json.dumps(response_part), content_type="application/json") chk_file_name = DATA_BUCKET + '/' + file_req['filename'] file_entry = ps.get_file_by_name(chk_file_name) logging.info(file_entry) if file_entry is None: response_part.update( { 'error' : 'File or gate not recognised.', 'giveup' : False } ) return HttpResponse(json.dumps(response_part), content_type="application/json") else: fp_entry = ps.get_user_file_permissions(file_entry.key, user_key) if fp_entry is None: response_part.update( { 'error' : 'Permission denied.' } ) return HttpResponse(json.dumps(response_part), content_type="application/json") name = file_req['filename'] is_done = ds.check_exists(GRAPH_BUCKET + '/' + name + '.png', None) #Prevent redirecting before the view is ready is_done &= ds.check_exists(DATA_BUCKET + '/' + name, None) #Prevent redirecting before gating info is ready is_done &= ds.check_exists(INFO_BUCKET + '/' + name + '.txt', None) response_part.update( { 'done' : is_done, 'giveup' : False } ) return HttpResponse(json.dumps(response_part), content_type="application/json")
def generate_gating_feedback(status, message, new_graph_name = None, existing_name = None, new_axis_a = "FSC-A", new_axis_b = "SSC-A"): if new_graph_name is not None: ## Authenticate and get user authed_user = auth.get_current_user() user_key = ps.get_user_key_by_id(authed_user.user_id()) ## Get previous file permissions. previous_file = ps.get_file_by_name(DATA_BUCKET + existing_name) previous_permissions = ps.get_user_file_permissions(previous_file.key, user_key) if isinstance(new_graph_name, list): new_graph_names = new_graph_name else: new_graph_names = [new_graph_name] # Overwrite new_graph_name for return dictionary new_graph_name = new_graph_names[0] logging.info(new_graph_name) logging.info(new_graph_names) for new_name in new_graph_names: new_file = FileInfo(file_name = DATA_BUCKET + new_name, owner_key = user_key, friendly_name = previous_file.friendly_name + '-gate', prev_file_key = previous_file.key, axis_a = new_axis_a, axis_b = new_axis_b ) file_key = ps.add_file(new_file) ps.add_file_permissions(file_key, user_key, Permissions ( previous_permissions.read, previous_permissions.write, previous_permissions.full_control ), previous_permissions.colour, False) return { 'status': status, 'message': message, 'url': reverse('get_graph', args=[new_graph_name]), 'graphName' : new_graph_name }
def tool(request): authed_user = auth.get_current_user() if authed_user is None: return __unauthed_response() try: gate_info = json.loads(request.raw_post_data) print gate_info except ValueError: return HttpResponse(simplejson.dumps(gt.generate_gating_feedback('fail', 'Invalid request payload')), content_type="application/json") ## \todo This should probably iterate over list if (('points' not in gate_info) or ('tool' not in gate_info) or ('filename' not in gate_info)): return HttpResponse(simplejson.dumps(gt.generate_gating_feedback('fail', 'Incomplete gate parameters')), content_type="application/json") if (gate_info['points']): if not isinstance(gate_info['points'], list): return HttpResponse(simplejson.dumps(gt.generate_gating_feedback('fail', 'Invalid points list')), content_type="application/json") else: # Normalise false value to None gate_info.update( { 'points' : None } ) file_entry = ps.get_file_by_name(DATA_BUCKET + '/' + gate_info['filename']) if file_entry is None: return HttpResponse(simplejson.dumps(gt.generate_gating_feedback('fail', 'File not found')), content_type="application/json") gate_info.update( { 'axes' : { 'x' : file_entry.axis_a, 'y' : file_entry.axis_b } } ) tool = gt.AVAILABLE_TOOLS.get(gate_info['tool'], gt.no_such_tool) ## first two arguments passed for compatibility tool_response = tool(gate_info) ## Load balance instances in the background. background.run(instances.balance, 0) json_response = simplejson.dumps(tool_response); return HttpResponse(json_response, content_type="application/json")
def app(request): lst = ds.list(DATA_BUCKET) file_info = None app_access = __check_app_access(True) if app_access is not None: return app_access authed_user = auth.get_current_user() authed_user_nick = authed_user.nickname() request.upload_handlers = [upload_handling.fcsUploadHandler()] if request.method == 'POST': form = forms.UploadFile(request.POST, request.FILES) if form.is_valid(): cd = form.cleaned_data return redirect('#!/preview/' + request.FILES['file'].name) else: return render(request, 'app.html', {'form': form, 'files' : lst , 'current_file' : file_info, 'authed_user_nick' : authed_user_nick}) else: form = forms.UploadFile() return render(request, 'app.html', {'form': form, 'files' : lst , 'current_file' : file_info, 'authed_user_nick' : authed_user_nick})
def signup_handler(request): authed_user = auth.get_current_user() if authed_user is None: return __unauthed_response() user_key = ps.get_user_key_by_id(authed_user.user_id()) if user_key is None: user_key = ps.add_user(authed_user) response_part = { 'success' : False } try: file_req = json.loads(request.raw_post_data) except ValueError: response_part.update({'error' : 'Invalid request payload.'}) return HttpResponse(json.dumps(response_part), content_type="application/json") if 'action' not in file_req: response_part.update({'error' : 'Incomplete request.'}) return HttpResponse(json.dumps(response_part), content_type="application/json") elem_key = ps.get_element_key_by_ref('canLogIn') if elem_key is None: elem_key = ps.add_element('canLogIn') user_elem = ps.get_user_element_permissions(user_key, elem_key) if user_elem is not None: response_part.update({'error' : 'Already signed up.'}) return HttpResponse(json.dumps(response_part), content_type="application/json") else: ps.add_element_permissions(user_key, elem_key, True) response_part.update({'success' : True}) return HttpResponse(json.dumps(response_part), content_type="application/json")
def file_preview(request, file = None): app_access = __check_app_access() if app_access is not None: return app_access ## Authentication. authed_user = auth.get_current_user() if authed_user is None: authed_user_nick = 'Guest' else: authed_user_nick = authed_user.nickname() ## Graph visualisation. # Replaced by a spinning canvas on the clientside # if not ds.check_exists(GRAPH_BUCKET + '/' + file_name_without_extension + '.png', None): # file_name_without_extension = None #TODO: Might need to be simplified or moved to a function in fileinfo # TODO the folowing should be replaced by a method in the APIDatastore file_info = ps.get_file_by_name(DATA_BUCKET + '/' + file) undo_uri = None if file_info is not None: prev_file = ps.get_file_by_key(file_info.prev_file_key) if prev_file is not None: undo_uri = prev_file.file_name.rpartition(DATA_BUCKET + '/')[2] lst = ds.list(DATA_BUCKET) current_file = None for temp_file in lst: temp_file.filename = temp_file.filename.rpartition('/')[2] if temp_file.filename == file: current_file = temp_file; # Check whether graph exists yet. graph_exists = ds.check_exists(GRAPH_BUCKET + '/' + file.partition('.')[0] + '.png', None) # Get permissions for file. permissions = None if file_info is not None: user_key = ps.get_user_key_by_id(authed_user.user_id()) permissions = ps.get_user_file_permissions(file_info.key, user_key) template_dict = {'current_file' : current_file, 'name' : file, 'authed_user_nick': authed_user_nick, 'file_info' : file_info, 'graph_ready' : graph_exists, 'undo_link' : undo_uri, 'permissions' : permissions } ## Get gating information. info_path = INFO_BUCKET + '/' + file.partition('.')[0] + '.txt' if ds.check_exists(info_path, None): buffer = ds.open(info_path) if buffer: file_text = buffer.read() stats = file_text.split(' ') if len(stats)>=3: template_dict.update( { 'gating_stats' : { 'selection' : stats[0], 'total' : stats[1], 'percent' : float(stats[2])*100 } } ) ## Get different axis axis_path = INFO_BUCKET + '/' + file.partition('.')[0] + 'info.txt' if ds.check_exists(axis_path, None): buffer = ds.open(axis_path) if buffer: file_text = buffer.read() axis = file_text.split('\n') if len(axis)>0: while '' in axis: axis.remove('') template_dict.update( { 'available_axes' : axis } ) return render(request, 'file_preview.html', template_dict)
def signup(request): link = auth.create_login_url('/#!/signup') return redirect(link)
def file_permissions_edit(request): authed_user = auth.get_current_user() if authed_user is None: return __unauthed_response() user_key = ps.get_user_key_by_id(authed_user.user_id()) json_response = { 'success' : False } action_responses = [] try: permissions_request = json.loads(request.raw_post_data) except ValueError: json_response.update( {'error' : 'Invalid request payload.'} ) return HttpResponse(json.dumps(json_response), content_type="application/json") if ( ('actions' not in permissions_request) or ('filename' not in permissions_request)): json_response.update( {'error' : 'Incomplete request.'} ) return HttpResponse(json.dumps(json_response), content_type="application/json") filename = permissions_request['filename'] actions = permissions_request['actions'] if not isinstance(actions, list): json_response.update( {'error' : 'Actions list is not a list.'} ) return HttpResponse(json.dumps(json_response), content_type="application/json") file_entry = ps.get_file_by_name(DATA_BUCKET + '/' + filename) if file_entry is None: json_response.update( { 'error' : 'File does not exist.' } ) return HttpResponse(json.dumps(json_response), content_type="application/json") fp_entry = ps.get_user_file_permissions(file_entry.key, user_key) if fp_entry is None: json_response.update( { 'error' : 'Permission denied.' } ) return HttpResponse(json.dumps(json_response), content_type="application/json") res = [] for action in actions: if ( ('action' in action) # Can't do anything without an action name and ('userEmail' in action)): # Or a user for that matter user_email = action['userEmail'] action_name = action['action'] response_part = { 'success' : False, 'action' : action, 'userEmail' : user_email } share_user_key = ps.get_user_key_by_email(user_email) if share_user_key is None: response_part.update( { 'error' : 'User not found.' } ) action_responses.append(response_part) continue else: response_part = { 'success' : False, 'error' : 'Incomplete request.' } continue edit_permissions = ps.get_user_file_permissions(file_entry.key, share_user_key) if action_name == 'dropUser': if edit_permissions is None: response_part.update( { 'error' : 'User does not have permissions for this file.' } ) else: remove_action = ps.revoke_permissions_by_key(edit_permissions.key) if remove_action: response_part.update( { 'success' : True } ) else: response_part.update( { 'error' : 'Could not revoke permissions.' } ) elif action_name == 'addUser': if edit_permissions is None: if ( ('read' not in action) or ('write' not in action) or ('fullControl' not in action)): response_part.update( { 'error' : 'Incomplete action - permissions not specified.'} ) else: add_action = ps.add_file_permissions(file_entry.key, share_user_key, Permissions( action['read'], action['write'], action['fullControl'] ) ) if add_action: response_part.update( { 'success' : True } ) else: response_part.update( { 'error' : 'Could not add user to file.' } ) else: response_part.update( { 'error' : 'User already has permissions for this file.' } ) elif action_name == 'editUser': if edit_permissions is not None: if ( ('read' not in action) or ('write' not in action) or ('fullControl' not in action)): response_part.update( { 'error' : 'Incomplete action - permissions not specified.'} ) else: edit_action = ps.modify_file_permissions_by_key(edit_permissions.key, Permissions( action['read'], action['write'], action['fullControl'] ) ) if edit_action: response_part.update( { 'success' : True } ) else: response_part.update( { 'error' : 'Could not update user permissions.' } ) else: response_part.update( { 'error' : 'User does not have a permissions entry for this file.' } ) else: response_part.update( { 'error' : "Action '%s' not recognised."%action_name } ) action_responses.append(response_part) json_response.update( { 'success' : True, 'actions' : action_responses } ) return HttpResponse(json.dumps(json_response), content_type="application/json")
def logout(request): link = auth.create_logout_url('/') return redirect(link)
def file_permissions_json(request): authed_user = auth.get_current_user() if authed_user is None: return __unauthed_response() user_key = ps.get_user_key_by_id(authed_user.user_id()) json_response = { 'success' : False, 'users' : [] } try: list_req = json.loads(request.raw_post_data) except ValueError: json_response.update({'error' : 'Invalid request payload.'}) return HttpResponse(json.dumps(json_response), content_type="application/json") if 'filename' not in list_req: json_response.update({'error' : 'Incomplete request.'}) return HttpResponse(json.dumps(json_response), content_type="application/json") filename = list_req['filename'] file_entry = ps.get_file_by_name(DATA_BUCKET + '/' + filename) if file_entry is None: json_response.update( { 'error' : 'File does not exist.' } ) return HttpResponse(json.dumps(json_response), content_type="application/json") fp_entry = ps.get_user_file_permissions(file_entry.key, user_key) if fp_entry is None: json_response.update( { 'error' : 'Permission denied.' } ) return HttpResponse(json.dumps(json_response), content_type="application/json") permissions_list = ps.get_file_permissions_list(file_entry.key) if permissions_list is None: json_response.update( { 'error' : 'Permission could not be retrieved.' } ) return HttpResponse(json.dumps(json_response), content_type="application/json") for perm in permissions_list: new_perm = {} user = ps.get_user_by_key(perm.user_key) if user is not None: nickname = user.nickname() email = user.email() user_found = True else: nickname = 'Unknown' email = 'unknown' user_found = False new_perm.update( { 'nickname' : nickname, 'userFound' : user_found, 'email' : email, 'isMe' : (perm.user_key == user_key), 'permissions' : { 'read' : perm.read, 'write' : perm.write, 'fullControl' : perm.full_control } } ) json_response['users'].append(new_perm) json_response.update({ 'success' : True }) return HttpResponse(json.dumps(json_response), content_type="application/json")
def login(request): link = auth.create_login_url('app/') return redirect(link)
def file_list_edit(request): authed_user = auth.get_current_user() if authed_user is None: return __unauthed_response() user_key = ps.get_user_key_by_id(authed_user.user_id()) try: actions = json.loads(request.raw_post_data) except ValueError: return HttpResponse(json.dumps({'error' : 'invalid request payload'}), content_type="application/json") if not isinstance(actions, list): return HttpResponse(json.dumps({'error' : 'Payload is not a list'}), content_type="application/json") res = [] for a in actions: #We can't do anything without a filename if 'filename' not in a: continue else: filename = a['filename'] if 'action' not in a: continue else: action = a['action'] res_fragment = { 'filename' : a['filename'], 'action' : a['action'] } if action == 'delete': file_entry = ps.get_file_by_name(DATA_BUCKET + '/' + filename) if file_entry is not None: ps.remove_file_by_key(file_entry.key) ds.delete(DATA_BUCKET + '/' + filename) ds.delete(INFO_BUCKET + '/' + filename + 'info.txt') ds.delete(INFO_BUCKET + '/' + filename + '.txt') ds.delete(GRAPH_BUCKET + '/' + filename + '.png') res_fragment.update( { 'success' : True } ) #Reinstate this when CE PAL is available #else: #res_fragment.update( { 'success' : False, 'error' : 'File does not exist.' } ) elif action == 'rename': if 'newname' not in a: res_fragment.update( { 'success' : False, 'error' : 'New name not specified' } ) else: file_entry = ps.get_file_by_name(DATA_BUCKET + '/' + filename) if file_entry is None: res_fragment.update( { 'success' : False, 'error' : 'File does not exist.' } ) else: file_entry.friendly_name = a['newname'] if ps.update_file(file_entry): res_fragment.update( { 'success' : True } ) else: res_fragment.update( { 'success' : False, 'error' : 'Could not rename file' } ) elif action == 'star' or action == 'unstar': file_entry = ps.get_file_by_name(DATA_BUCKET + '/' + filename) if file_entry is None: res_fragment.update( { 'success' : False, 'error' : 'File does not exist.' } ) else: fp_entry = ps.get_user_file_permissions(file_entry.key, user_key) if fp_entry is None: res_fragment.update( { 'success' : False, 'error' : 'Permissions entry not found' } ) else: if ps.modify_file_permissions_by_key(fp_entry.key, new_starred = (action == 'star')): res_fragment.update( { 'success' : True } ) else: res_fragment.update( { 'success' : False, 'error' : 'Could not update file' } ) elif action == 'recolour': if 'newcolour' not in a: res_fragment.update( { 'success' : False, 'error' : 'New colour not specified' } ) else: colour = a['newcolour'] chk_string = re.compile("^[A-Fa-f0-9]{6}$") if (chk_string.match(colour)): file_entry = ps.get_file_by_name(DATA_BUCKET + '/' + filename) if file_entry is None: res_fragment.update( { 'success' : False, 'error' : 'File does not exist.' } ) else: fp_entry = ps.get_user_file_permissions(file_entry.key, user_key) if fp_entry is None: res_fragment.update( { 'success' : False, 'error' : 'Permissions entry not found' } ) else: if ps.modify_file_permissions_by_key(fp_entry.key, new_colour = colour): res_fragment.update( { 'success' : True } ) else: res_fragment.update( { 'success' : False, 'error' : 'Could not update file' } ) else: res_fragment.update( { 'success' : False, 'error' : 'New colour invalid' } ) else: res_fragment.update( { 'success' : False, 'error' : 'Action not recognised' } ) res.append(res_fragment) return HttpResponse(json.dumps(res), content_type="application/json")