Esempio n. 1
0
def index(request, experiment_id):
    url = 'monash_ands/form.html'

    try:
        e = Experiment.objects.get(id=experiment_id)

        import sys
        allowed_protocol = sys.modules['%s.%s.settings' %
                    (settings.TARDIS_APP_ROOT, 'monash_ands')].ALLOWED_PROTOCOL

        if not request.user.is_authenticated():
            # todo: de-duplicate
            from django.template import Context
            c = Context()
            c['disallowed_protocol'] = True

            return HttpResponse(render_response_index(request, url, c))

        ua = UserAuthentication.objects.get(username=request.user.username)
        if not ua.authenticationMethod == allowed_protocol:
            from django.template import Context
            c = Context()
            c['is_owner'] = authz.has_experiment_ownership(request,
                experiment_id)
            c['disallowed_protocol'] = True

            return HttpResponse(render_response_index(request, url, c))

        if not request.POST:
            monashandsService = MonashANDSService(experiment_id)
            c = monashandsService.get_context(request)
            if request.user.is_authenticated():
                c['is_owner'] = authz.has_experiment_ownership(request,
                    experiment_id)

            c['experiment'] = e

            cch = CreativeCommonsHandler(experiment_id=experiment_id, create=False)
            c['has_cc_license'] = cch.has_cc_license()

            return HttpResponse(render_response_index(request, url, c))
        else:
            monashandsService = MonashANDSService(experiment_id)
            c = monashandsService.register(request)
            if request.user.is_authenticated():
                c['is_owner'] = authz.has_experiment_ownership(request,
                    experiment_id)

            c['experiment'] = e

            return HttpResponse(render_response_index(request, url, c))
    except Exception, e:
        # todo: check with web services for adequate responses..
        message = '<b>An error occured:</b> ' + str(e)
        return HttpResponse(content=message)
Esempio n. 2
0
def share(request, experiment_id):
    '''
    Choose access rights and licence.
    '''
    experiment = Experiment.objects.get(id=experiment_id)
    user = request.user

    c = {}

    c['has_write_permissions'] = \
        authz.has_write_permissions(request, experiment_id)
    c['has_download_permissions'] = \
        authz.has_experiment_download_access(request, experiment_id)
    if user.is_authenticated():
        c['is_owner'] = authz.has_experiment_ownership(request, experiment_id)
        c['is_superuser'] = user.is_superuser
        c['is_staff'] = user.is_staff

    domain = Site.objects.get_current().domain
    public_link = experiment.public_access >= Experiment.PUBLIC_ACCESS_METADATA

    c['experiment'] = experiment
    c['public_link'] = public_link
    c['domain'] = domain

    return HttpResponse(render_response_index(request,
                        'tardis_portal/ajax/share.html', c))
Esempio n. 3
0
def share(request, experiment_id):
    '''
    Choose access rights and licence.
    '''
    experiment = Experiment.objects.get(id=experiment_id)
    user = request.user

    c = {}

    c['has_write_permissions'] = \
        authz.has_write_permissions(request, experiment_id)
    c['has_download_permissions'] = \
        authz.has_experiment_download_access(request, experiment_id)
    if user.is_authenticated():
        c['is_owner'] = authz.has_experiment_ownership(request, experiment_id)
        c['is_superuser'] = user.is_superuser
        c['is_staff'] = user.is_staff

    domain = Site.objects.get_current().domain
    public_link = experiment.public_access >= Experiment.PUBLIC_ACCESS_METADATA

    c['experiment'] = experiment
    c['public_link'] = public_link
    c['domain'] = domain

    return HttpResponse(render_response_index(request,
                        'tardis_portal/ajax/share.html', c))
Esempio n. 4
0
def token_delete(request, token_id):
    token = Token.objects.get(id=token_id)
    if authz.has_experiment_ownership(request, token.experiment_id):
        token.delete()
        return HttpResponse('{"success": true}', content_type='application/json')
    else:
        return HttpResponse('{"success": false}', content_type='application/json')
Esempio n. 5
0
def experiment_description(request, experiment_id):
    """View an existing experiment's description. To be loaded via ajax.

    :param request: a HTTP Request instance
    :type request: :class:`django.http.HttpRequest`
    :param experiment_id: the ID of the experiment to be edited
    :type experiment_id: string
    :rtype: :class:`django.http.HttpResponse`

    """
    c = {}

    try:
        experiment = Experiment.safe.get(request.user, experiment_id)
    except PermissionDenied:
        return return_response_error(request)
    except Experiment.DoesNotExist:
        return return_response_not_found(request)

    c['experiment'] = experiment
    c['subtitle'] = experiment.title
    c['nav'] = [{
        'name': 'Data',
        'link': '/experiment/view/'
    }, {
        'name': experiment.title,
        'link': experiment.get_absolute_url()
    }]

    c['authors'] = experiment.experimentauthor_set.all()

    c['datafiles'] = \
        DataFile.objects.filter(dataset__experiments=experiment_id)

    c['owners'] = experiment.get_owners()

    # calculate the sum of the datafile sizes
    c['size'] = DataFile.sum_sizes(c['datafiles'])

    c['has_download_permissions'] = \
        authz.has_experiment_download_access(request, experiment_id)

    c['has_write_permissions'] = \
        authz.has_write_permissions(request, experiment_id)

    if request.user.is_authenticated():
        c['is_owner'] = authz.has_experiment_ownership(request, experiment_id)

    _add_protocols_and_organizations(request, experiment, c)

    if 'status' in request.GET:
        c['status'] = request.GET['status']
    if 'error' in request.GET:
        c['error'] = request.GET['error']

    return HttpResponse(
        render_response_index(
            request, 'tardis_portal/ajax/experiment_description.html', c))
Esempio n. 6
0
 def add_experiments(updated_experiments):
     current_experiments = \
         frozenset(dataset.experiments.values_list('id', flat=True))
     # Get all the experiments that currently aren't associated
     for experiment_id in updated_experiments - current_experiments:
         # You must own the experiment to assign datasets to it
         if authz.has_experiment_ownership(request, experiment_id):
             experiment = Experiment.safe.get(request.user, experiment_id)
             logger.info("Adding dataset #%d to experiment #%d" %
                         (dataset.id, experiment.id))
             dataset.experiments.add(experiment)
Esempio n. 7
0
 def add_experiments(updated_experiments):
     current_experiments = \
         frozenset(dataset.experiments.values_list('id', flat=True))
     # Get all the experiments that currently aren't associated
     for experiment_id in updated_experiments - current_experiments:
         # You must own the experiment to assign datasets to it
         if authz.has_experiment_ownership(request, experiment_id):
             experiment = Experiment.safe.get(request.user, experiment_id)
             logger.info("Adding dataset #%d to experiment #%d" %
                         (dataset.id, experiment.id))
             dataset.experiments.add(experiment)
Esempio n. 8
0
def experiment_description(request, experiment_id):
    """View an existing experiment's description. To be loaded via ajax.

    :param request: a HTTP Request instance
    :type request: :class:`django.http.HttpRequest`
    :param experiment_id: the ID of the experiment to be edited
    :type experiment_id: string
    :rtype: :class:`django.http.HttpResponse`

    """
    c = {}

    try:
        experiment = Experiment.safe.get(request.user, experiment_id)
    except PermissionDenied:
        return return_response_error(request)
    except Experiment.DoesNotExist:
        return return_response_not_found(request)

    c['experiment'] = experiment
    c['subtitle'] = experiment.title
    c['nav'] = [{'name': 'Data', 'link': '/experiment/view/'},
                {'name': experiment.title,
                 'link': experiment.get_absolute_url()}]

    c['authors'] = experiment.experimentauthor_set.all()

    c['datafiles'] = \
        DataFile.objects.filter(dataset__experiments=experiment_id)

    c['owners'] = experiment.get_owners()

    # calculate the sum of the datafile sizes
    c['size'] = DataFile.sum_sizes(c['datafiles'])

    c['has_download_permissions'] = \
        authz.has_experiment_download_access(request, experiment_id)

    c['has_write_permissions'] = \
        authz.has_write_permissions(request, experiment_id)

    if request.user.is_authenticated():
        c['is_owner'] = authz.has_experiment_ownership(request, experiment_id)

    _add_protocols_and_organizations(request, experiment, c)

    if 'status' in request.GET:
        c['status'] = request.GET['status']
    if 'error' in request.GET:
        c['error'] = request.GET['error']

    return HttpResponse(render_response_index(request,
                        'tardis_portal/ajax/experiment_description.html', c))
Esempio n. 9
0
def index(request, experiment_id):
    url = 'ands_register/index.html'

    e = Experiment.objects.get(pk=experiment_id)
    cch = CreativeCommonsHandler(experiment_id=experiment_id, create=False)
    has_licence = cch.has_cc_license()
    is_owner = authz.has_experiment_ownership(request, experiment_id)

    if request.POST:
        if not is_owner:
            return return_response_error(request)

        publish_handler = publishing.PublishHandler(experiment_id, True)
        form = forms.PublishingForm(has_licence, request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            publish_handler.update(cleaned_data)
            return HttpResponse('{"success": true}', mimetype='application/json')
    else:
        publish_handler = publishing.PublishHandler(experiment_id)
        form = forms.PublishingForm(has_licence, initial=publish_handler.form_data())

    c = Context()
    c['is_owner'] = is_owner
    c['has_licence'] = has_licence
    c['experiment'] = e
    c['form'] = form

    c['custom_description'] = publish_handler.custom_description()

    authors = [a.author for a in e.author_experiment_set.all()]
    c['authors_csv'] = ', '.join(authors)

    custom_authors = publish_handler.custom_authors()
    if custom_authors:
        c['custom_authors_csv'] = ', '.join(custom_authors)

    c['access_type'] = publish_handler.access_type()

    return HttpResponse(render_response_index(request, url, c))
Esempio n. 10
0
def retrieve_datafile_list(request, dataset_id, template_name='tardis_portal/ajax/datafile_list.html'):

    params = {}

    query = None
    highlighted_dsf_pks = []

    if 'query' in request.GET:
        search_query = FacetFixedSearchQuery(backend=HighlightSearchBackend())
        sqs = SearchQuerySet(query=search_query)
        query =  SearchQueryString(request.GET['query'])
        results = sqs.raw_search(query.query_string() + ' AND dataset_id_stored:%i' % (int(dataset_id))).load_all()
        highlighted_dsf_pks = [int(r.pk) for r in results if r.model_name == 'dataset_file' and r.dataset_id_stored == int(dataset_id)]

        params['query'] = query.query_string()

    elif 'datafileResults' in request.session and 'search' in request.GET:
        highlighted_dsf_pks = [r.pk for r in request.session['datafileResults']]

    dataset_results = \
        Dataset_File.objects.filter(
            dataset__pk=dataset_id,
        ).order_by('filename')
        
# microtardis change start
    if 'session_show_hidden' not in request.session:
        request.session['session_show_hidden'] = False
    if 'session_hidden_text' not in request.session:
        request.session['session_hidden_text'] = "Show Hidden Datasets and Files"
        
    if not request.session['session_show_hidden']:
        # hide hidden objects
        hidden_datafiles = Datafile_Hidden.objects.filter(hidden=True).values_list('datafile', flat=True)
        dataset_results = dataset_results.exclude(pk__in=hidden_datafiles)
# microtardis change end

    if request.GET.get('limit', False) and len(highlighted_dsf_pks):
        dataset_results = \
        dataset_results.filter(pk__in=highlighted_dsf_pks)
        params['limit'] = request.GET['limit']

    filename_search = None

    if 'filename' in request.GET and len(request.GET['filename']):
        filename_search = request.GET['filename']
        dataset_results = \
            dataset_results.filter(url__icontains=filename_search)

        params['filename'] = filename_search

    # pagination was removed by someone in the interface but not here.
    # need to fix.
    pgresults = 100

    paginator = Paginator(dataset_results, pgresults)

    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.

    try:
        dataset = paginator.page(page)
    except (EmptyPage, InvalidPage):
        dataset = paginator.page(paginator.num_pages)

    is_owner = False
    has_write_permissions = False

    if request.user.is_authenticated():
        experiment_id = Experiment.objects.get(dataset__id=dataset_id).id
        is_owner = authz.has_experiment_ownership(request, experiment_id)

        has_write_permissions = \
            authz.has_write_permissions(request, experiment_id)

    immutable = Dataset.objects.get(id=dataset_id).immutable

    params = urlencode(params)

    c = Context({
        'dataset': dataset,
        'paginator': paginator,
        'immutable': immutable,
        'dataset_id': dataset_id,
        'filename_search': filename_search,
        'is_owner': is_owner,
        'highlighted_dataset_files': highlighted_dsf_pks,
        'has_write_permissions': has_write_permissions,
        'search_query' : query,
        'params' : params

        })

# microtardis change start
    if request.session['session_show_hidden']:
        # show all objects
        # highlight hidden objects
        hidden_datafiles = Datafile_Hidden.objects.filter(hidden=True).values_list('datafile', flat=True)
        objects = Dataset_File.objects.filter(dataset__pk=dataset_id, pk__in=hidden_datafiles)
        c['linethrough_dataset_files'] = [ obj.pk for obj in objects ]
# microtardis change end

    return HttpResponse(render_response_index(request, template_name, c))
Esempio n. 11
0
def experiment_description(request, experiment_id):
    """View an existing experiment's description. To be loaded via ajax.

    :param request: a HTTP Request instance
    :type request: :class:`django.http.HttpRequest`
    :param experiment_id: the ID of the experiment to be edited
    :type experiment_id: string
    :rtype: :class:`django.http.HttpResponse`

    """
    c = Context({})

    try:
        experiment = Experiment.safe.get(request, experiment_id)
    except PermissionDenied:
        return return_response_error(request)
    except Experiment.DoesNotExist:
        return return_response_not_found(request)

    c['experiment'] = experiment
    c['subtitle'] = experiment.title
    c['nav'] = [{'name': 'Data', 'link': '/experiment/view/'},
                {'name': experiment.title,
                 'link': experiment.get_absolute_url()}]

    c['authors'] = experiment.author_experiment_set.all()

# microtardis change start
    if 'session_show_hidden' not in request.session:
        request.session['session_show_hidden'] = False
    if 'session_hidden_text' not in request.session:
        request.session['session_hidden_text'] = "Show Hidden Datasets and Files"
        
    if not request.session['session_show_hidden']:
        # hide hidden objects
        hidden_datasets = Dataset_Hidden.objects.filter(hidden=True).values_list('dataset', flat=True)
        c['datasets'] = Dataset.objects.filter(experiment=experiment_id).exclude(pk__in=hidden_datasets)
        hidden_datafiles = Datafile_Hidden.objects.filter(hidden=True).values_list('datafile', flat=True)
        c['datafiles'] = Dataset_File.objects.filter(dataset__experiment=experiment_id).exclude(pk__in=hidden_datafiles)
    else:
        # show all objects
        c['datasets'] = Dataset.objects.filter(experiment=experiment_id)
        c['datafiles'] = Dataset_File.objects.filter(dataset__experiment=experiment_id)
# microtardis change end

    acl = ExperimentACL.objects.filter(pluginId=django_user,
                                       experiment=experiment,
                                       isOwner=True)

    # TODO: resolve usernames through UserProvider!
    # Right now there are exceptions every time for ldap users..
    c['owners'] = []
    for a in acl:
        try:
            c['owners'].append(User.objects.get(pk=str(a.entityId)))
        except User.DoesNotExist:
            #logger.exception('user for acl %i does not exist' % a.id)
            pass

    # calculate the sum of the datafile sizes
    size = 0
    for df in c['datafiles']:
        try:
            size = size + long(df.size)
        except:
            pass
    c['size'] = size

    c['has_read_or_owner_ACL'] = \
        authz.has_read_or_owner_ACL(request, experiment_id)

    c['has_write_permissions'] = \
        authz.has_write_permissions(request, experiment_id)

    if request.user.is_authenticated():
        c['is_owner'] = authz.has_experiment_ownership(request, experiment_id)

    c['protocol'] = []
    download_urls = experiment.get_download_urls()
    for key, value in download_urls.iteritems():
        c['protocol'] += [[key, value]]

    if 'status' in request.GET:
        c['status'] = request.GET['status']
    if 'error' in request.GET:
        c['error'] = request.GET['error']

    return HttpResponse(render_response_index(request,
                        'tardis_portal/ajax/experiment_description.html', c))
Esempio n. 12
0
def view_experiment(request, experiment_id):

    """View an existing experiment.

    :param request: a HTTP Request instance
    :type request: :class:`django.http.HttpRequest`
    :param experiment_id: the ID of the experiment to be edited
    :type experiment_id: string
    :rtype: :class:`django.http.HttpResponse`

    """
    c = Context({})

    try:
        experiment = Experiment.safe.get(request, experiment_id)
    except PermissionDenied:
        return return_response_error(request)
    except Experiment.DoesNotExist:
        return return_response_not_found(request)

# microtardis change start
    if 'session_show_hidden' not in request.session:
        request.session['session_show_hidden'] = False
    if 'session_hidden_text' not in request.session:
        request.session['session_hidden_text'] = "Show Hidden Datasets and Files"
    
    if not request.session['session_show_hidden']:
        # hide hidden objects
        hidden_datasets = Dataset_Hidden.objects.filter(hidden=True).values_list('dataset', flat=True)
        c['datasets'] = Dataset.objects.filter(experiment=experiment_id).exclude(pk__in=hidden_datasets)
    else:
        # show all datasets
        c['datasets'] = Dataset.objects.filter(experiment=experiment_id)
# microtardis change end

    c['experiment'] = experiment
    c['has_write_permissions'] = \
        authz.has_write_permissions(request, experiment_id)
    if request.user.is_authenticated():
        c['is_owner'] = authz.has_experiment_ownership(request, experiment_id)
    c['subtitle'] = experiment.title
    c['nav'] = [{'name': 'Data', 'link': '/experiment/view/'},
                {'name': experiment.title,
                 'link': experiment.get_absolute_url()}]

    if 'status' in request.POST:
        c['status'] = request.POST['status']
    if 'error' in request.POST:
        c['error'] = request.POST['error']
    if 'query' in request.GET:
        c['search_query'] = SearchQueryString(request.GET['query'])
    if  'search' in request.GET:
        c['search'] = request.GET['search']
    if  'load' in request.GET:
        c['load'] = request.GET['load']

    import sys
    appnames = []
    appurls = []
    for app in getTardisApps():
        try:
            appnames.append(sys.modules['%s.%s.settings'
                                        % (settings.TARDIS_APP_ROOT, app)].NAME)
            appurls.append('%s.%s.views.index' % (settings.TARDIS_APP_ROOT, app))
        except:
            pass

    c['apps'] = zip(appurls, appnames)

    return HttpResponse(render_response_index(request,
                        'tardis_portal/view_experiment.html', c))
Esempio n. 13
0
    def get_context_data(self, request, experiment, **kwargs):
        """
        Prepares the values to be passed to the default experiment view,
        respecting authorization rules. Returns a dict of values (the context).

        :param request: a HTTP request object
        :type request: :class:`django.http.HttpRequest`
        :param experiment: the experiment model instance
        :type experiment: tardis.tardis_portal.models.experiment.Experiment
        :return: A dictionary of values for the view/template.
        :rtype: dict
        """

        c = super(ExperimentView, self).get_context_data(**kwargs)

        c['experiment'] = experiment
        c['has_write_permissions'] = \
            authz.has_write_permissions(request, experiment.id)
        c['has_download_permissions'] = \
            authz.has_experiment_download_access(request, experiment.id)
        if request.user.is_authenticated():
            c['is_owner'] = authz.has_experiment_ownership(request, experiment.id)
            c['has_read_or_owner_ACL'] = authz.has_read_or_owner_ACL(request,
                                                                     experiment.id)

        # Enables UI elements for the publication form
        c['pub_form_enabled'] = 'tardis.apps.publication_forms' in \
                                settings.INSTALLED_APPS

        # Enables UI elements for the push_to app
        c['push_to_enabled'] = PushToConfig.name in settings.INSTALLED_APPS
        if c['push_to_enabled']:
            push_to_args = {
                'experiment_id': experiment.pk
            }
            c['push_to_url'] = reverse(initiate_push_experiment,
                                       kwargs=push_to_args)

        c['subtitle'] = experiment.title
        c['nav'] = [{'name': 'Data', 'link': '/experiment/view/'},
                    {'name': experiment.title,
                     'link': experiment.get_absolute_url()}]

        if 'status' in request.POST:
            c['status'] = request.POST['status']
        if 'error' in request.POST:
            c['error'] = request.POST['error']
        if 'query' in request.GET:
            c['search_query'] = SearchQueryString(request.GET['query'])
        if 'search' in request.GET:
            c['search'] = request.GET['search']
        if 'load' in request.GET:
            c['load'] = request.GET['load']

        _add_protocols_and_organizations(request, experiment, c)

        default_apps = [
            {'name': 'Description',
             'viewfn': 'tardis.tardis_portal.views.experiment_description'},
            {'name': 'Metadata',
             'viewfn': 'tardis.tardis_portal.views.retrieve_experiment_metadata'},
            {'name': 'Sharing', 'viewfn': 'tardis.tardis_portal.views.share'},
            {'name': 'Transfer Datasets',
             'viewfn': 'tardis.tardis_portal.views.experiment_dataset_transfer'},
        ]
        appnames = []
        appurls = []

        for app in getattr(settings, 'EXPERIMENT_APPS', default_apps):
            try:
                appnames.append(app['name'])
                if 'viewfn' in app:
                    appurls.append(reverse(app['viewfn'], args=[experiment.id]))
                elif 'url' in app:
                    appurls.append(app['url'])
            except:
                logger.debug('error when loading default exp apps')

        from tardis.app_config import get_tardis_apps

        for app_name, app in get_tardis_apps():
            try:
                appnames.append(
                    sys.modules['%s.settings' % app].NAME)
                appurls.append(
                    reverse('%s.views.index' % app, args=[experiment.id]))
            except:
                logger.debug("No tab for %s" % app)

        c['apps'] = zip(appurls, appnames)

        return c
Esempio n. 14
0
    def get_context_data(self, request, experiment, **kwargs):
        """
        Prepares the values to be passed to the default experiment view,
        respecting authorization rules. Returns a dict of values (the context).

        :param request: a HTTP request object
        :type request: :class:`django.http.HttpRequest`
        :param experiment: the experiment model instance
        :type experiment: tardis.tardis_portal.models.experiment.Experiment
        :return: A dictionary of values for the view/template.
        :rtype: dict
        """

        c = super(ExperimentView, self).get_context_data(**kwargs)

        c['experiment'] = experiment
        c['has_write_permissions'] = \
            authz.has_write_permissions(request, experiment.id)
        c['has_download_permissions'] = \
            authz.has_experiment_download_access(request, experiment.id)
        if request.user.is_authenticated():
            c['is_owner'] = authz.has_experiment_ownership(
                request, experiment.id)
            c['has_read_or_owner_ACL'] = authz.has_read_or_owner_ACL(
                request, experiment.id)

        # Enables UI elements for the publication form
        c['pub_form_enabled'] = 'tardis.apps.publication_forms' in \
                                settings.INSTALLED_APPS

        # Enables UI elements for the push_to app
        c['push_to_enabled'] = PushToConfig.name in settings.INSTALLED_APPS
        if c['push_to_enabled']:
            push_to_args = {'experiment_id': experiment.pk}
            c['push_to_url'] = reverse(initiate_push_experiment,
                                       kwargs=push_to_args)

        c['subtitle'] = experiment.title
        c['nav'] = [{
            'name': 'Data',
            'link': '/experiment/view/'
        }, {
            'name': experiment.title,
            'link': experiment.get_absolute_url()
        }]

        if 'status' in request.POST:
            c['status'] = request.POST['status']
        if 'error' in request.POST:
            c['error'] = request.POST['error']
        if 'query' in request.GET:
            c['search_query'] = SearchQueryString(request.GET['query'])
        if 'search' in request.GET:
            c['search'] = request.GET['search']
        if 'load' in request.GET:
            c['load'] = request.GET['load']

        _add_protocols_and_organizations(request, experiment, c)

        default_apps = [
            {
                'name': 'Description',
                'viewfn': 'tardis.tardis_portal.views.experiment_description'
            },
            {
                'name': 'Metadata',
                'viewfn':
                'tardis.tardis_portal.views.retrieve_experiment_metadata'
            },
            {
                'name': 'Sharing',
                'viewfn': 'tardis.tardis_portal.views.share'
            },
            {
                'name': 'Transfer Datasets',
                'viewfn':
                'tardis.tardis_portal.views.experiment_dataset_transfer'
            },
        ]
        appnames = []
        appurls = []

        for app in getattr(settings, 'EXPERIMENT_APPS', default_apps):
            try:
                appnames.append(app['name'])
                if 'viewfn' in app:
                    appurls.append(reverse(app['viewfn'],
                                           args=[experiment.id]))
                elif 'url' in app:
                    appurls.append(app['url'])
            except:
                logger.debug('error when loading default exp apps')

        from tardis.app_config import get_tardis_apps

        for app_name, app in get_tardis_apps():
            try:
                appnames.append(sys.modules['%s.settings' % app].NAME)
                appurls.append(
                    reverse('%s.views.index' % app, args=[experiment.id]))
            except:
                logger.debug("No tab for %s" % app)

        c['apps'] = zip(appurls, appnames)

        return c