def get_data_view( request, data_view_id ): """ Returns a rendered template for the given view. """ # Load the template dv = get_object_or_404(DataView, pk=data_view_id) code_type = dv.data_view_type.code_type template = loader.get_template( "catmaid/" + code_type + ".html" ) # Get project information and pass all to the template context config = json.loads( dv.config ) # Get all the projects that are visible for the current user projects = get_project_qs_for_user(request.user) # If requested, filter projects by tags. Otherwise, get all. if "filter_tags" in config: filter_tags = config["filter_tags"] # Only get projects that have all the filter tags set projects = projects.filter( tags__name__in=filter_tags ).annotate( repeat_count=Count("id") ).filter( repeat_count=len(filter_tags) ) # Build a stack index stacks = list(Stack.objects.all()) stack_index = dict([(s.id, s) for s in stacks]) stacks_of = defaultdict(list) for pid, sid in ProjectStack.objects.filter(project__in=projects) \ .order_by('stack__id').values_list('project_id', 'stack_id'): stacks_of[pid].append(stack_index[sid]) # Extend the project list with additional information like editabilty projects = extend_projects( request.user, projects ) # Sort by default if "sort" not in config or config["sort"] == True: projects = natural_sort( projects, "title" ) # Build project index project_index = dict([(p.id, p) for p in projects]) project_ids = set(project_index.keys()) # Build tag index ct = ContentType.objects.get_for_model(Project) tag_links = TaggedItem.objects.filter(content_type=ct) \ .values_list('object_id', 'tag__name') tag_index = defaultdict(set) for pid, t in tag_links: if pid in project_ids: tag_index[t].add(pid) context = Context({ 'data_view': dv, 'projects': projects, 'config': config, 'settings': settings, 'tag_index': tag_index, 'project_index': project_index, 'stack_index': stack_index, 'stacks_of': stacks_of, }) return HttpResponse( template.render( context ) );
def get_data_view( request, data_view_id ): """ Returns a rendered template for the given view. """ # Load the template dv = get_object_or_404(DataView, pk=data_view_id) code_type = dv.data_view_type.code_type template = loader.get_template( "catmaid/" + code_type + ".html" ) # Get project information and pass all to the template context config = json.loads( dv.config ) # Get all the projects that are visible for the current user projects = get_project_qs_for_user(request.user) # If requested, filter projects by tags. Otherwise, get all. if "filter_tags" in config: filter_tags = config["filter_tags"] # Only get projects that have all the filter tags set projects = projects.filter( tags__name__in=filter_tags ).annotate( repeat_count=Count("id") ).filter( repeat_count=len(filter_tags) ) # Extend the project list with additional information like editabilty projects = extend_projects( request.user, projects ) # Sort by default if "sort" not in config or config["sort"] == True: projects = natural_sort( projects, "title" ) context = Context({ 'data_view': dv, 'projects': projects, 'config': config, 'settings': settings }) return HttpResponse( template.render( context ) );
def get_data_view(request, data_view_id): """ Returns a rendered template for the given view. """ # Load the template dv = get_object_or_404(DataView, pk=data_view_id) code_type = dv.data_view_type.code_type template = loader.get_template("catmaid/" + code_type + ".html") # Get project information and pass all to the template context config = json.loads(dv.config) # Get all the projects that are visible for the current user projects = get_project_qs_for_user(request.user) # If requested, filter projects by tags. Otherwise, get all. if "filter_tags" in config: filter_tags = config["filter_tags"] # Only get projects that have all the filter tags set projects = projects.filter(tags__name__in=filter_tags).annotate( repeat_count=Count("id")).filter(repeat_count=len(filter_tags)) # Extend the project list with additional information like editabilty projects = extend_projects(request.user, projects) # Sort by default if "sort" not in config or config["sort"] == True: projects = natural_sort(projects, "title") context = Context({ 'data_view': dv, 'projects': projects, 'config': config, 'settings': settings }) return HttpResponse(template.render(context))
def test_project_export(self): """Test projects/export endpoint, which returns a YAML format which can also be understood by the importer. """ # Check that, pre-authentication, we can see none of the # projects: response = self.client.get('/projects/export') self.assertEqual(response.status_code, 200) result = json.loads(response.content) self.assertEqual(len(result), 0) # Now log in and check that we see a different set of projects: self.fake_authentication() # Add permission to the test user to browse three projects test_user = User.objects.get(pk=self.test_user_id) valid_project_ids = (1,2,3,5) for pid in valid_project_ids: p = Project.objects.get(pk=pid) assign_perm('can_browse', test_user, p) visible_projects = project.get_project_qs_for_user(test_user) response = self.client.get('/projects/export') self.assertEqual(response.status_code, 200) result = yaml.load(response.content) # Expect a returned list with four projects self.assertEqual(len(result), 4) seen_projects = [] for exported_project in result: data = exported_project['project'] pid = data['id'] self.assertTrue(pid in valid_project_ids) self.assertFalse(pid in seen_projects) seen_projects.append(pid) p = Project.objects.get(id=pid) self.assertEqual(p.title, data['title']) stacks = p.stacks.all() valid_stack_ids = [s.id for s in stacks] stackgroup_links = StackStackGroup.objects.filter(stack__in=stacks) valid_stackgroup_ids = [sgl.stack_group_id for sgl in stackgroup_links] seen_stacks = [] seen_stackgroups = [] for s in data.get('stacks', []): stack_id = s['id'] self.assertIn(stack_id, valid_stack_ids) self.assertNotIn(stack_id, seen_stacks) seen_stacks.append(stack_id) # Compare stacks stack = Stack.objects.get(id=stack_id) self.assertEqual(stack.title, s['title']) self.assertEqual(literal_eval(unicode(stack.dimension)), literal_eval(s['dimension'])) self.assertEqual(literal_eval(unicode(stack.resolution)), literal_eval(s['resolution'])) self.assertEqual(stack.num_zoom_levels, s['zoomlevels']) self.assertEqual(stack.metadata, s['metadata']) self.assertEqual(stack.comment, s['comment']) self.assertEqual(stack.attribution, s['attribution']) self.assertEqual(stack.description, s['description']) self.assertEqual(literal_eval(unicode(stack.canary_location)), literal_eval(s['canary_location'])) self.assertEqual(literal_eval(unicode(stack.placeholder_color)), literal_eval(s['placeholder_color'])) # Get all stack mirrors for this stack stack_mirrors = StackMirror.objects.filter(stack_id=stack_id).order_by('position') self.assertEqual(len(stack_mirrors), len(s['mirrors'])) # Expect exported stack mirros to be ordered by position for sm, sm_export in zip(stack_mirrors, s['mirrors']): # Compare stack mirrors self.assertEqual(sm.image_base, sm_export['url']) self.assertEqual(sm.tile_width, sm_export['tile_width']) self.assertEqual(sm.tile_height, sm_export['tile_height']) self.assertEqual(sm.tile_source_type, sm_export['tile_source_type']) self.assertEqual(sm.file_extension, sm_export['fileextension']) for sge in s.get('stackgroups', []): sg_id = sge['id'] self.assertIn(sg_id, valid_stackgroup_ids) self.assertNotIn(sg_id, seen_stackgroups) seen_stackgroups.append(sg_id) sg = StackGroup.objects.get(id=sg_id) sg_link = StackStackGroup.objects.get( stack=stack, stack_group=sg) self.assertEqual(sg.title, sge['title']) self.assertEqual(sg_link.group_relation.name, sge['relation']) # Make sure we have seen all relevant stack groups self.assertItemsEqual(valid_stackgroup_ids, seen_stackgroups) # Make sure we have seen all relevant stacks self.assertItemsEqual(valid_stack_ids, seen_stacks) self.assertItemsEqual(valid_project_ids, seen_projects)
def get_data_view(request, data_view_id): """ Returns a rendered template for the given view. """ # Load the template dv = get_object_or_404(DataView, pk=data_view_id) code_type = dv.data_view_type.code_type template = loader.get_template("catmaid/" + code_type + ".html") # Get project information and pass all to the template context config = json.loads(dv.config) # Get all the projects that are visible for the current user projects = get_project_qs_for_user(request.user) # If requested, filter projects by tags. Otherwise, get all. if "filter_tags" in config: filter_tags = config["filter_tags"] # Only get projects that have all the filter tags set # TODO: Improve performande by not using an IN query (but a temp table # join) over all filter_tags. projects = projects.filter(tags__name__in=filter_tags).annotate( repeat_count=Count("id")).filter(repeat_count=len(filter_tags)) show_stacks = config.get('show_stacks', True) show_stackgroups = config.get('show_stackgroups', True) show_mirrors = config.get('show_mirrors', True) # Make sure we get all needed stacks in the first query if show_stacks: projects = projects.prefetch_related('stacks') # Build a stack index stack_index = defaultdict(list) stacks_of = defaultdict(list) stack_set_of = defaultdict(set) projects_of_stack = defaultdict(set) if show_stacks: for p in projects: stacks = p.stacks.all() if show_mirrors: stacks = stacks.prefetch_related('stackmirror_set') for s in stacks: stack_index[s.id] = s stacks_of[p.id].append(s) if show_stackgroups: stack_set_of[p.id].add(s.id) projects_of_stack[s.id].add(p.id) # Build a stack group index, if stack groups should be made available stackgroup_index = {} stackgroups_of = defaultdict(list) if show_stackgroups: stackgroup_links = StackStackGroup.objects.all().prefetch_related( 'stack', 'stack_group') stackgroup_members = defaultdict(set) for sgl in stackgroup_links: stackgroup_index[sgl.stack_group_id] = sgl.stack_group stackgroup_members[sgl.stack_group_id].add(sgl.stack.id) for sg, members in six.iteritems(stackgroup_members): # Only accept stack groups of which all member stacks are linked to # the same project. member_project_ids = set() project_member_ids = defaultdict(set) for m in members: project_ids = projects_of_stack.get(m, []) member_project_ids.update(project_ids) for pid in project_ids: project_member_ids[pid].add(m) # Find projects where all stacks are linked to for p in member_project_ids: project_members = project_member_ids[p] # If the stack group members in this project are all stack group # members, this stack group is available to the project if not members.difference(project_members): stackgroups_of[p].append(stackgroup_index[sg]) # Extend the project list with catalogue information if 'catalogue_link' in config: projects = add_catalogue_info(request.user, projects) # Sort by default if "sort" not in config or config["sort"] is True: projects = natural_sort(projects, "title") # Build project index project_index = dict([(p.id, p) for p in projects]) project_ids = set(project_index.keys()) # Build tag index ct = ContentType.objects.get_for_model(Project) tag_links = TaggedItem.objects.filter(content_type=ct) \ .values_list('object_id', 'tag__name') tag_index = defaultdict(set) for pid, t in tag_links: if pid in project_ids: tag_index[t].add(pid) context = { 'data_view': dv, 'projects': projects, 'config': config, 'settings': settings, 'tag_index': tag_index, 'project_index': project_index, 'stack_index': stack_index, 'stacks_of': stacks_of, 'stackgroup_index': stackgroup_index, 'stackgroups_of': stackgroups_of, 'STATIC_URL': settings.STATIC_URL, } return HttpResponse(template.render(context))
def get_data_view( request, data_view_id ): """ Returns a rendered template for the given view. """ # Load the template dv = get_object_or_404(DataView, pk=data_view_id) code_type = dv.data_view_type.code_type template = loader.get_template( "catmaid/" + code_type + ".html" ) # Get project information and pass all to the template context config = json.loads( dv.config ) # Get all the projects that are visible for the current user projects = get_project_qs_for_user(request.user) # If requested, filter projects by tags. Otherwise, get all. if "filter_tags" in config: filter_tags = config["filter_tags"] # Only get projects that have all the filter tags set # TODO: Improve performande by not using an IN query (but a temp table # join) over all filter_tags. projects = projects.filter( tags__name__in=filter_tags ).annotate( repeat_count=Count("id") ).filter( repeat_count=len(filter_tags) ) show_stacks = config.get('show_stacks', True) show_stackgroups = config.get('show_stackgroups', True) show_mirrors = config.get('show_mirrors', True) # Make sure we get all needed stacks in the first query if show_stacks or show_stackgroups: projects = projects.prefetch_related('stacks') # Build a stack index stack_index = defaultdict(list) stacks_of = defaultdict(list) stack_set_of = defaultdict(set) projects_of_stack = defaultdict(set) if show_stacks or show_stackgroups: for p in projects: stacks = p.stacks.all() if show_mirrors: stacks = stacks.prefetch_related('stackmirror_set') for s in stacks: stack_index[s.id] = s stacks_of[p.id].append(s) if show_stackgroups: stack_set_of[p.id].add(s.id) projects_of_stack[s.id].add(p.id) # Build a stack group index, if stack groups should be made available stackgroup_index = {} stackgroups_of = defaultdict(list) if show_stackgroups: stackgroup_links = StackStackGroup.objects.all().prefetch_related('stack', 'stack_group') stackgroup_members = defaultdict(set) for sgl in stackgroup_links: stackgroup_index[sgl.stack_group_id] = sgl.stack_group stackgroup_members[sgl.stack_group_id].add(sgl.stack.id) for sg, members in six.iteritems(stackgroup_members): # Only accept stack groups of which all member stacks are linked to # the same project. member_project_ids = set() project_member_ids = defaultdict(set) for m in members: project_ids = projects_of_stack.get(m, []) member_project_ids.update(project_ids) for pid in project_ids: project_member_ids[pid].add(m) # Find projects where all stacks are linked to for p in member_project_ids: project_members = project_member_ids[p] # If the stack group members in this project are all stack group # members, this stack group is available to the project if not members.difference(project_members): stackgroups_of[p].append(stackgroup_index[sg]) # Extend the project list with catalogue information if 'catalogue_link' in config: projects = add_catalogue_info( request.user, projects ) # Sort by default if "sort" not in config or config["sort"] is True: projects = natural_sort( projects, "title" ) # Build project index project_index = dict([(p.id, p) for p in projects]) project_ids = set(project_index.keys()) # Build tag index ct = ContentType.objects.get_for_model(Project) tag_links = TaggedItem.objects.filter(content_type=ct) \ .values_list('object_id', 'tag__name') tag_index = defaultdict(set) for pid, t in tag_links: if pid in project_ids: tag_index[t].add(pid) context = { 'data_view': dv, 'projects': projects, 'config': config, 'settings': settings, 'tag_index': tag_index, 'project_index': project_index, 'stack_index': stack_index, 'stacks_of': stacks_of, 'stackgroup_index': stackgroup_index, 'stackgroups_of': stackgroups_of, 'STATIC_URL': settings.STATIC_URL, } return HttpResponse( template.render( context ) )
def test_project_export(self): """Test projects/export endpoint, which returns a YAML format which can also be understood by the importer. """ # Check that, pre-authentication, we can see none of the # projects: response = self.client.get('/projects/export') self.assertEqual(response.status_code, 200) result = json.loads(response.content.decode('utf-8')) self.assertEqual(len(result), 0) # Now log in and check that we see a different set of projects: self.fake_authentication() # Add permission to the test user to browse three projects test_user = User.objects.get(pk=self.test_user_id) valid_project_ids = (1,2,3,5) for pid in valid_project_ids: p = Project.objects.get(pk=pid) assign_perm('can_browse', test_user, p) visible_projects = project.get_project_qs_for_user(test_user) response = self.client.get('/projects/export') self.assertEqual(response.status_code, 200) result = yaml.load(response.content.decode('utf-8')) # Expect a returned list with four projects self.assertEqual(len(result), 4) seen_projects = [] for exported_project in result: data = exported_project['project'] pid = data['id'] self.assertTrue(pid in valid_project_ids) self.assertFalse(pid in seen_projects) seen_projects.append(pid) p = Project.objects.get(id=pid) self.assertEqual(p.title, data['title']) stacks = p.stacks.all() valid_stack_ids = [s.id for s in stacks] stackgroup_links = StackStackGroup.objects.filter(stack__in=stacks) valid_stackgroup_ids = [sgl.stack_group_id for sgl in stackgroup_links] seen_stacks = [] seen_stackgroups = [] for s in data.get('stacks', []): stack_id = s['id'] self.assertIn(stack_id, valid_stack_ids) self.assertNotIn(stack_id, seen_stacks) seen_stacks.append(stack_id) # Compare stacks stack = Stack.objects.get(id=stack_id) self.assertEqual(stack.title, s['title']) self.assertEqual(literal_eval(str(stack.dimension)), literal_eval(s['dimension'])) self.assertEqual(literal_eval(str(stack.resolution)), literal_eval(s['resolution'])) self.assertEqual(stack.downsample_factors, s['downsample_factors']) self.assertEqual(stack.metadata, s['metadata']) self.assertEqual(stack.comment, s['comment']) self.assertEqual(stack.attribution, s['attribution']) self.assertEqual(stack.description, s['description']) self.assertEqual(literal_eval(str(stack.canary_location)), literal_eval(s['canary_location'])) self.assertEqual(literal_eval(str(stack.placeholder_color)), literal_eval(s['placeholder_color'])) # Get all stack mirrors for this stack stack_mirrors = StackMirror.objects.filter(stack_id=stack_id).order_by('position') self.assertEqual(len(stack_mirrors), len(s['mirrors'])) # Expect exported stack mirros to be ordered by position for sm, sm_export in zip(stack_mirrors, s['mirrors']): # Compare stack mirrors self.assertEqual(sm.image_base, sm_export['url']) self.assertEqual(sm.tile_width, sm_export['tile_width']) self.assertEqual(sm.tile_height, sm_export['tile_height']) self.assertEqual(sm.tile_source_type, sm_export['tile_source_type']) self.assertEqual(sm.file_extension, sm_export['fileextension']) for sge in s.get('stackgroups', []): sg_id = sge['id'] self.assertIn(sg_id, valid_stackgroup_ids) self.assertNotIn(sg_id, seen_stackgroups) seen_stackgroups.append(sg_id) sg = StackGroup.objects.get(id=sg_id) sg_link = StackStackGroup.objects.get( stack=stack, stack_group=sg) self.assertEqual(sg.title, sge['title']) self.assertEqual(sg_link.group_relation.name, sge['relation']) # Make sure we have seen all relevant stack groups self.assertCountEqual(valid_stackgroup_ids, seen_stackgroups) # Make sure we have seen all relevant stacks self.assertCountEqual(valid_stack_ids, seen_stacks) self.assertCountEqual(valid_project_ids, seen_projects)
def get_data_view( request, data_view_id ): """ Returns a rendered template for the given view. """ # Load the template dv = get_object_or_404(DataView, pk=data_view_id) code_type = dv.data_view_type.code_type template = loader.get_template( "catmaid/" + code_type + ".html" ) # Get project information and pass all to the template context config = json.loads( dv.config ) # Get all the projects that are visible for the current user projects = get_project_qs_for_user(request.user) # If requested, filter projects by tags. Otherwise, get all. if "filter_tags" in config: filter_tags = config["filter_tags"] # Only get projects that have all the filter tags set # TODO: Improve performande by not using an IN query (but a temp table # join) over all filter_tags. projects = projects.filter( tags__name__in=filter_tags ).annotate( repeat_count=Count("id") ).filter( repeat_count=len(filter_tags) ) show_stacks = config.get('show_stacks', True) show_stackgroups = config.get('show_stackgroups', True) # Make sure we get all needed stacks in the first query if show_stacks: projects = projects.prefetch_related('stacks') # Build a stack index stack_index = defaultdict(list) stacks_of = defaultdict(list) if show_stacks: for p in projects: for s in p.stacks.all(): stack_index[s.id] = s stacks_of[p.id].append(s) # Build a stack group index, if stack groups should be made available stackgroup_index = defaultdict(list) stackgroups_of = defaultdict(list) if show_stackgroups: # Get all stackgroups = StackGroup.objects.filter(project__in=projects) for sg in stackgroups: stackgroup_index[sg.id] = sg stackgroups_of[sg.project_id].append(sg) # Extend the project list with additional information like editabilty projects = extend_projects( request.user, projects ) # Sort by default if "sort" not in config or config["sort"] == True: projects = natural_sort( projects, "title" ) # Build project index project_index = dict([(p.id, p) for p in projects]) project_ids = set(project_index.keys()) # Build tag index ct = ContentType.objects.get_for_model(Project) tag_links = TaggedItem.objects.filter(content_type=ct) \ .values_list('object_id', 'tag__name') tag_index = defaultdict(set) for pid, t in tag_links: if pid in project_ids: tag_index[t].add(pid) context = { 'data_view': dv, 'projects': projects, 'config': config, 'settings': settings, 'tag_index': tag_index, 'project_index': project_index, 'stack_index': stack_index, 'stacks_of': stacks_of, 'stackgroup_index': stackgroup_index, 'stackgroups_of': stackgroups_of, 'STATIC_URL': settings.STATIC_URL, } return HttpResponse( template.render( context ) )
def get_data_view(request, data_view_id): """ Returns a rendered template for the given view. """ # Load the template dv = get_object_or_404(DataView, pk=data_view_id) code_type = dv.data_view_type.code_type template = loader.get_template("catmaid/" + code_type + ".html") # Get project information and pass all to the template context config = json.loads(dv.config) # Get all the projects that are visible for the current user projects = get_project_qs_for_user(request.user).prefetch_related('stacks') # If requested, filter projects by tags. Otherwise, get all. if "filter_tags" in config: filter_tags = config["filter_tags"] # Only get projects that have all the filter tags set projects = projects.filter(tags__name__in=filter_tags).annotate( repeat_count=Count("id")).filter(repeat_count=len(filter_tags)) # Build a stack index stack_index = defaultdict(list) stacks_of = defaultdict(list) for p in projects: for s in p.stacks.all(): stack_index[s.id] = s stacks_of[p.id].append(s) # Extend the project list with additional information like editabilty projects = extend_projects(request.user, projects) # Sort by default if "sort" not in config or config["sort"] == True: projects = natural_sort(projects, "title") # Build project index project_index = dict([(p.id, p) for p in projects]) project_ids = set(project_index.keys()) # Build tag index ct = ContentType.objects.get_for_model(Project) tag_links = TaggedItem.objects.filter(content_type=ct) \ .values_list('object_id', 'tag__name') tag_index = defaultdict(set) for pid, t in tag_links: if pid in project_ids: tag_index[t].add(pid) context = Context({ 'data_view': dv, 'projects': projects, 'config': config, 'settings': settings, 'tag_index': tag_index, 'project_index': project_index, 'stack_index': stack_index, 'stacks_of': stacks_of, 'STATIC_URL': settings.STATIC_URL, }) return HttpResponse(template.render(context))