Skip to content
This repository was archived by the owner on Jan 28, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions search/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def get_sqs():
# Add hard-coded facets.
for facet in ("course", "run", "resource_type"):
sqs = sqs.facet(facet)
# Add dynamic facets (from taxonomy). Values with spaces do not work,
# so use the slug.
for slug in Vocabulary.objects.all().values_list("slug", flat=True):
sqs = sqs.facet(slug)
# Add dynamic facets (from taxonomy). Certain characters cause problems,
# so use the primary key.
for vocabulary_id in Vocabulary.objects.all().values_list("id", flat=True):
sqs = sqs.facet(vocabulary_id)
return sqs
15 changes: 6 additions & 9 deletions search/search_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,13 @@ def prepare(self, obj):
"""
prepared = super(LearningResourceIndex, self).prepare(obj)
for vocab in Vocabulary.objects.all():
# Values with spaces do not work, so replace them with underscores.
# Slugify doesn't work because it adds hypens, which are also
# split by Elasticsearch.
terms = [
term.label.replace(" ", "_")
for term in obj.terms.filter(vocabulary_id=vocab.id)
]
prepared[vocab.slug] = terms
# Use the integer primary keys as index values. This saves space,
# and also avoids all issues dealing with "special" characters.
terms = set(obj.terms.filter(vocabulary_id=vocab.id).values_list(
'id', flat=True))
prepared[vocab.id] = terms
# for faceted "_exact" in URL
prepared[vocab.slug + "_exact"] = terms # for faceted "exact"
prepared["{0}_exact".format(vocab.id)] = terms
return prepared

def prepare_repository(self, obj): # pylint: disable=no-self-use
Expand Down
6 changes: 3 additions & 3 deletions search/tests/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ def test_index_vocabulary(self):
"""
term = self.terms[0]
self.assertTrue(self.count_faceted_results(
self.vocabulary.name, term.label) == 0)
self.vocabulary.id, term.id) == 0)
self.resource.terms.add(term)
self.assertTrue(self.count_faceted_results(
self.vocabulary.name, term.label) == 1)
self.vocabulary.id, term.id) == 1)
self.resource.terms.remove(term)
self.assertTrue(self.count_faceted_results(
self.vocabulary.name, term.label) == 0)
self.vocabulary.id, term.id) == 0)

def test_strip_xml(self):
"""Indexed content_xml should have XML stripped."""
Expand Down
16 changes: 8 additions & 8 deletions ui/templates/includes/facet_panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,28 +108,28 @@ <h4 class="panel-title">
</div>
</div>
</div>
{% for name, vocab in vocabularies.items %}
{% if vocab %}
{% for vocab, terms in vocabularies.items %}
{% if terms %}
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapse-vocab-{{ forloop.counter }}">
{{ name|title }}
{{ vocab.1|title }}
</a>
</h4>
</div>
<div id="collapse-vocab-{{ forloop.counter }}" class="panel-collapse collapse in">
<div class="panel-body">
<ul class="icheck-list">
{% for term in vocab %}
{% for term in terms %}
<li>
<input id="check-{{ name }}-{{ forloop.counter }}"
<input id="check-{{ vocab.0 }}-{{ forloop.counter }}"
tabindex="add" type="checkbox" class="icheck-11"
data-facet-name="{{ name|urlencode }}_exact"
data-facet-name="{{ vocab.0 }}_exact"
data-facet-value="{{ term.0 }}"
>
<label for="check-{{ name }}-{{ forloop.counter }}">{{ term.2 }}</label>
<span class="badge">{{ term.1 }}</span>
<label for="check-{{ vocab.0 }}-{{ forloop.counter }}">{{ term.1 }}</label>
<span class="badge">{{ term.2 }}</span>
</li>
{% endfor %}
</ul>
Expand Down
86 changes: 65 additions & 21 deletions ui/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from roles.permissions import GroupTypes, RepoPermission
from search import get_sqs
from search.sorting import LoreSortingFields
from taxonomy.models import Vocabulary
from taxonomy.models import Vocabulary, Term
from ui.forms import UploadForm, RepositoryForm

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -123,6 +123,58 @@ def create_repo(request):
)


def get_vocabularies(facets):
"""
Parse facet information for the template.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great documentation but can you reformat into a napoleon docstring?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring updated.

It will return a dictionary that looks like this:

{
(u'13', u'difficulty'): [(38, u'medium', 23), (17, u'hard', 19)],
(u'15', u'prerequisite'): [(44, u'yes', 23)]
}

The keys are tuples with Vocabulary ID and name for the key,
and a list of tuples containing id, label, and count for the terms.

This is for ease-of-use in the template, where the integer primary keys
are used for search links and the names/labels are used for display.

Args:
facets (dict): facet ID with terms & term counts
Returns:
vocabularies (dict): dict of vocab info to term info
"""

if "fields" not in facets:
return {}
vocab_ids = []
term_ids = []
for vocab_id, counts in facets["fields"].items():
if not vocab_id.isdigit():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we want to raise an exception if this caused a problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is to filter out course, run, and resource_type.

continue
vocab_ids.append(int(vocab_id))
for term_id, count in counts:
term_ids.append(term_id)

vocabs = {
x: y for x, y in Vocabulary.objects.filter(
id__in=vocab_ids).values_list('id', 'name')
}
terms = {
x: y for x, y in Term.objects.filter(
id__in=term_ids).values_list('id', 'label')
}
vocabularies = {}
for vocabulary_id, term_data in facets["fields"].items():
if not vocabulary_id.isdigit():
continue
vocab = (vocabulary_id, vocabs[int(vocabulary_id)])
vocabularies[vocab] = []
for t_id, count in term_data:
vocabularies[vocab].append((t_id, terms[int(t_id)], count))
return vocabularies


class RepositoryView(FacetedSearchView):
"""Subclass of haystack.views.FacetedSearchView"""

Expand Down Expand Up @@ -154,7 +206,6 @@ def dispatch(self, *args, **kwargs):
def extra_context(self):
"""Add to the context."""
context = super(RepositoryView, self).extra_context()
vocabularies = Vocabulary.objects.all().values_list("slug", flat=True)
params = dict(self.request.GET.copy())
qs_prefix = "?"
# Chop out page number so we don't end up with
Expand All @@ -175,25 +226,18 @@ def extra_context(self):
)
qs_prefix = "?{0}&".format("&".join(qs_prefix))

if "fields" in context["facets"]:
context.update({
"repo": self.repo,
"perms_on_cur_repo": get_perms(self.request.user, self.repo),
# Add a non-slug version to the context for display. This
# turns a "two-tuple" into a "three-tuple."
"vocabularies": {
k: [x + (x[0].replace("_", " "),) for x in v]
for k, v in context["facets"]["fields"].items()
if k in vocabularies
},
"qs_prefix": qs_prefix,
"sorting_options": {
"current": LoreSortingFields.get_sorting_option(
self.sortby),
"all": LoreSortingFields.all_sorting_options_but(
self.sortby)
}
})
context.update({
"repo": self.repo,
"perms_on_cur_repo": get_perms(self.request.user, self.repo),
"vocabularies": get_vocabularies(context["facets"]),
"qs_prefix": qs_prefix,
"sorting_options": {
"current": LoreSortingFields.get_sorting_option(
self.sortby),
"all": LoreSortingFields.all_sorting_options_but(
self.sortby)
}
})
return context

def build_form(self, form_kwargs=None):
Expand Down