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')
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
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