Beispiel #1
0
    def test_ead_lastmodified(self):
        modified = ead_lastmodified('rqst', 'abbey244')
        self.assert_(isinstance(modified, datetime),
                     "ead_lastmodified should return a datetime object")
        date_format = '%Y-%m-%d'
        expected = datetime.now().strftime(date_format)
        value = modified.strftime(date_format)
        self.assertEqual(expected, value,
                     'ead lastmodified should be today, expected %s, got %s' % (expected, value))

        # invalid eadid
        self.assertRaises(Http404, ead_lastmodified, 'rqst', 'bogusid')

        db = ExistDB()
        # preview document - load fixture to preview collection
        fullpath = path.join(exist_fixture_path, 'raoul548.xml')
        db.load(open(fullpath, 'r'), settings.EXISTDB_PREVIEW_COLLECTION + '/raoul548.xml')
        preview_modified = ead_lastmodified('rqst', 'raoul548', preview=True)
        self.assert_(isinstance(preview_modified, datetime),
                     "ead_lastmodified should return a datetime object")
        # clean up
        db.removeDocument(settings.EXISTDB_PREVIEW_COLLECTION + '/raoul548.xml')
Beispiel #2
0
def findingaid(request, id, preview=False):
    """View a single finding aid.   In preview mode, pulls the document from the
    configured eXist-db preview collection instead of the default public one.

    :param id: eadid for the document to view
    :param preview: boolean indicating preview mode, defaults to False
    """
    if 'keywords' in request.GET:
        search_terms = request.GET['keywords']
        url_params = '?' + urlencode({'keywords': search_terms.encode('utf-8')})
        filter = {'highlight': search_terms}
    else:
        url_params = ''
        filter = {}
    fa = get_findingaid(id, preview=preview, filter=filter)
    last_modified = ead_lastmodified(request, id, preview)
    series = _subseries_links(fa.dsc, url_ids=[fa.eadid], preview=preview,
                              url_params=url_params)

    extra_ns = RDFA_NAMESPACES.copy()
    # add any non-default namespaces from the EAD document
    extra_ns.update(dict((prefix, ns) for prefix, ns in fa.node.nsmap.iteritems()
                    if prefix is not None))
    context = {
        'ead': fa,
        'series': series,
        'all_indexes': fa.archdesc.index,
        'preview': preview,
        'url_params': url_params,
        'docsearch_form': KeywordSearchForm(),
        'last_search': request.session.get('last_search', None),
        'feedback_opts': _get_feedback_options(request, id),
        'extra_ns': extra_ns,
        'last_modified': last_modified,
    }

    # provide series list without keyword params to use in RDFa uris
    if url_params and not preview:
        context['series_noparam'] = _subseries_links(fa.dsc, url_ids=[fa.eadid])

    response = render(request, 'fa/findingaid.html', context,
                      current_app='preview')
    # Set Cache-Control to private when there is a last_search
    if "last_search" in request.session:
        response['Cache-Control'] = 'private'

    return response
Beispiel #3
0
def _view_series(request, eadid, *series_ids, **kwargs):
    """Retrieve and display a series, subseries, or index.

    :param eadid: eadid for the document the series or index belongs to
    :param series_ids: list of series ids - number of ids determines series level

    Also takes an optional named argument for preview mode.
    """
    # explicitly set the collection to be queried so we can always use it, whether in preview mode or not
    collection = settings.EXISTDB_ROOT_COLLECTION
    if 'preview' in kwargs and kwargs['preview']:
        collection = settings.EXISTDB_PREVIEW_COLLECTION
        preview_mode = True
    else:
        preview_mode = False

    # unspecified sub- and sub-sub-series come in as None; filter them out
    _series_ids = list(series_ids)
    while None in _series_ids:
        _series_ids.remove(None)

    # user-facing urls should use short-form ids (eadid not repeated)
    # to query eXist, we need full ids with eadid
    # check and convert them here
    series_ids = []
    redirect_ids = []
    redirect = False
    for id in _series_ids:
        if id.startswith('%s_' % eadid):
            # an unshortened id was passed in - shorten and redirect to canonical url
            redirect = True
            redirect_ids.append(shortform_id(id, eadid))
        else:
            # a shortened id was passed in - generate long-form for query to exist
            series_ids.append('%s_%s' % (eadid, id))
            # append to redirect ids in case redirect is required for a later id
            redirect_ids.append(id)

    # if any id was passed in unshortened, return a permanent redirect to the canonical url
    if redirect:
        # log redirects - if any of them are coming from this application, they should be fixed
        if 'HTTP_REFERER' in request.META:
            referrer = 'Referrer %s' % request.META['HTTP_REFERER']
        else:
            referrer = ' (referrer not available)'

        logger.info('''Redirecting from long-form series/index %s url to short-form url. %s'''
                    % (request.path, referrer))
        return HttpResponsePermanentRedirect(_series_url(eadid, *redirect_ids))

    # build initial series and index filters and field lists
    filter_list = {'ead__eadid': eadid}
    series_fields = ['id', 'level', 'did__unitid', 'did__unittitle']
    index_fields = ['id', 'head']

    # info needed to construct navigation links within this ead
    # - summary info for all top-level series in this finding aid
    all_series = Series.objects.filter(**filter_list).using(collection)
    # - summary info for any indexes
    all_indexes = Index.objects.filter(**filter_list).using(collection)

    if 'keywords' in request.GET:
        search_terms = request.GET['keywords']
        url_params = '?' + urlencode({'keywords': search_terms.encode('utf-8')})
        #filter further based on highlighting
        filter = {'highlight': search_terms}
        # add highlighting & match counts to series & index lists for navigation links
        all_series = all_series.filter(**filter)
        all_indexes = all_indexes.filter(**filter)
        series_fields.append('match_count')
        index_fields.append('match_count')

    else:
        url_params = ''
        filter = {}
    # get the item to be displayed (series, subseries, index)
    result = _get_series_or_index(eadid, *series_ids, filter=filter, use_collection=collection)

    if 'keywords' in request.GET:
        # when full-text highlighting is enabled, ead must be retrieved separately
        # in order to retrieve match counts for main page ToC items

        # fields needed for top-level display (some redundancy with list in _get_series_or_index)
        return_fields = ['eadid', 'title', 'archdesc__controlaccess__head',
                         'archdesc__origination',
                         'dsc__head', 'archdesc__did',
                         # required to determine off-site access
                         'archdesc__access_restriction',
                         ]
        fa = FindingAid.objects.filter(eadid=eadid).filter(**filter).using(collection)
        # using raw xpaths for exist-specific logic to expand and count matches
        ead = fa.only(*return_fields) \
                .only_raw(coll_desc_matches=FindingAid.coll_desc_matches_xpath,
                          admin_info_matches=FindingAid.admin_info_matches_xpath,
                          archdesc__controlaccess__match_count=FindingAid.controlaccess_matches_xpath) \
                .using(collection).get()
    else:
        # when no highlighting, get ead retrieved with main item
        fa = FindingAid.objects.filter(eadid=eadid).using(collection)
        # when no highlighting, use partial ead retrieved with main item
        ead = result.ead

    # info needed to construct navigation links within this ead
    # - summary info for all top-level series in this finding aid
    all_series = all_series.only(*series_fields).all()
    # - summary info for any indexes
    all_indexes = all_indexes.only(*index_fields).all()

    #find index of requested object so next and prev can be determined
    index = 0
    for i, s in enumerate(all_series):
        if(s.id == result.id):
            index = i
    prev = index - 1
    next = index + 1

    # query_times = [result.queryTime(), all_series.queryTime(), all_indexes.queryTime()]
    # if hasattr(ead, 'queryTime'):
        # query_times.append(ead.queryTime())

    extra_ns = RDFA_NAMESPACES.copy()
    # add any non-default namespaces from the EAD document
    extra_ns.update(dict((prefix, ns) for prefix, ns in ead.node.nsmap.iteritems()
                    if prefix is not None))

    render_opts = {
        'ead': ead,
        'all_series': all_series,
        'all_indexes': all_indexes,
        # 'querytime': query_times,
        'prev': prev,
        'next': next,
        'url_params': url_params,
        'canonical_url': _series_url(eadid, *[shortform_id(id) for id in series_ids]),
        'docsearch_form': KeywordSearchForm(),
        'last_search': request.session.get('last_search', None),
        'feedback_opts': _get_feedback_options(request, eadid),
        'extra_ns': extra_ns,
        'last_modified': ead_lastmodified(request, eadid, preview_mode)
    }
    # include any keyword args in template parameters (preview mode)
    render_opts.update(kwargs)

    if isinstance(result, Index):
        render_opts['index'] = result
    else:
        render_opts['series'] = result
        render_opts['subseries'] = _subseries_links(result, preview=preview_mode, url_params=url_params)

        # provide series list without keyword params to use in RDFa uris
        if url_params and not preview_mode:
            render_opts['subseries_noparam'] = _subseries_links(result)

    response = render(request, 'fa/series_or_index.html', render_opts)

    #Cache-Control to private when there is a last_search
    if "last_search" in request.session:
        response['Cache-Control'] = 'private'

    return response