search display tags at top.
authorMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Mon, 30 Jan 2012 16:10:48 +0000 (17:10 +0100)
committerMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Mon, 30 Jan 2012 16:10:48 +0000 (17:10 +0100)
apps/search/index.py
apps/search/views.py
wolnelektury/static/css/base.css
wolnelektury/static/js/base.js
wolnelektury/static/js/search.js
wolnelektury/templates/catalogue/search_multiple_hits.html
wolnelektury/templates/catalogue/tagged_object_list.html

index 6d97047..d63d3f8 100644 (file)
@@ -27,6 +27,7 @@ from librarian import dcparser
 from librarian.parser import WLDocument
 from lxml import etree
 import catalogue.models
+from pdcounter.models import Author as PDCounterAuthor
 from multiprocessing.pool import ThreadPool
 from threading import current_thread
 import atexit
@@ -219,6 +220,15 @@ class Index(BaseIndex):
             doc.add(Field("tag_category", tag.category, Field.Store.NO, Field.Index.NOT_ANALYZED))
             self.index.addDocument(doc)
 
+        for pdtag in PDCounterAuthor.objects.all():
+            doc = Document()
+            doc.add(NumericField("tag_id", Field.Store.YES, True).setIntValue(int(pdtag.id)))
+            doc.add(Field("tag_name", pdtag.name, Field.Store.NO, Field.Index.ANALYZED))
+            doc.add(Field("tag_name_pl", pdtag.name, Field.Store.NO, Field.Index.ANALYZED))
+            doc.add(Field("tag_category", 'pdcounter', Field.Store.NO, Field.Index.NOT_ANALYZED))
+            doc.add(Field("is_pdcounter", 'true', Field.Store.YES, Field.Index.NOT_ANALYZED))
+            self.index.addDocument(doc)
+
     def create_book_doc(self, book):
         """
         Create a lucene document referring book id.
@@ -604,26 +614,25 @@ class SearchResult(object):
         stored = search.searcher.doc(scoreDocs.doc)
         self.book_id = int(stored.get("book_id"))
 
-        header_type = stored.get("header_type")
-        if not header_type:
-            return
-
-        sec = (header_type, int(stored.get("header_index")))
-        header_span = stored.get('header_span')
-        header_span = header_span is not None and int(header_span) or 1
-
-        fragment = stored.get("fragment_anchor")
-
         pd = stored.get("published_date")
         if pd is None:
             pd = 0
         self.published_date = int(pd)
 
-        if snippets:
-            snippets = snippets.replace("/\n", "\n")
-        hit = (sec + (header_span,), fragment, scoreDocs.score, {'how_found': how_found, 'snippets': snippets and [snippets] or []})
+        header_type = stored.get("header_type")
+        # we have a content hit in some header of fragment
+        if header_type is not None:
+            sec = (header_type, int(stored.get("header_index")))
+            header_span = stored.get('header_span')
+            header_span = header_span is not None and int(header_span) or 1
+
+            fragment = stored.get("fragment_anchor")
 
-        self._hits.append(hit)
+            if snippets:
+                snippets = snippets.replace("/\n", "\n")
+            hit = (sec + (header_span,), fragment, scoreDocs.score, {'how_found': how_found, 'snippets': snippets and [snippets] or []})
+
+            self._hits.append(hit)
 
         self.search = search
         self.searched = searched
@@ -749,6 +758,8 @@ class SearchResult(object):
     def __cmp__(self, other):
         c = cmp(self.score, other.score)
         if c == 0:
+            if not hasattr(other,'published_date') or not hasattr(self, 'published_date'):
+                import pdb; pdb.set_trace()
             # this is inverted, because earlier date is better
             return cmp(other.published_date, self.published_date)
         else:
@@ -1208,19 +1219,27 @@ class Search(IndexStore):
         if terms:
             return JArray('object')(terms, Term)
 
-    def search_tags(self, query, filter=None, max_results=40):
+    def search_tags(self, query, filters=None, max_results=40, pdcounter=False):
         """
         Search for Tag objects using query.
         """
-        tops = self.searcher.search(query, filter, max_results)
+        if not pdcounter:
+            filters = self.chain_filters([filter, self.term_filter(Term('is_pdcounter', 'true'), inverse=True)])
+        tops = self.searcher.search(query, filters, max_results)
 
         tags = []
         for found in tops.scoreDocs:
             doc = self.searcher.doc(found.doc)
-            tag = catalogue.models.Tag.objects.get(id=doc.get("tag_id"))
-            tags.append(tag)
-            print "%s (%d) -> %f" % (tag, tag.id, found.score)
-
+            is_pdcounter = doc.get('is_pdcounter')
+            if is_pdcounter:
+                tag = PDCounterAuthor.objects.get(id=doc.get('tag_id'))
+            else:
+                tag = catalogue.models.Tag.objects.get(id=doc.get("tag_id"))
+                # don't add the pdcounter tag if same tag already exists
+            if not (is_pdcounter and filter(lambda t: tag.slug == t.slug, tags)):
+                tags.append(tag)
+                #            print "%s (%d) -> %f" % (tag, tag.id, found.score)
+        print 'returning %s' % tags
         return tags
 
     def search_books(self, query, filter=None, max_results=10):
@@ -1234,7 +1253,7 @@ class Search(IndexStore):
             bks.append(catalogue.models.Book.objects.get(id=doc.get("book_id")))
         return bks
 
-    def create_prefix_phrase(self, toks, field):
+    def make_prefix_phrase(self, toks, field):
         q = MultiPhraseQuery()
         for i in range(len(toks)):
             t = Term(field, toks[i])
@@ -1260,7 +1279,7 @@ class Search(IndexStore):
 
         return only_term
 
-    def hint_tags(self, string, max_results=50):
+    def hint_tags(self, string, max_results=50, pdcounter=True, prefix=True):
         """
         Return auto-complete hints for tags
         using prefix search.
@@ -1269,14 +1288,17 @@ class Search(IndexStore):
         top = BooleanQuery()
 
         for field in ['tag_name', 'tag_name_pl']:
-            q = self.create_prefix_phrase(toks, field)
+            if prefix:
+                q = self.make_prefix_phrase(toks, field)
+            else:
+                q = self.make_term_query(toks, field)
             top.add(BooleanClause(q, BooleanClause.Occur.SHOULD))
 
         no_book_cat = self.term_filter(Term("tag_category", "book"), inverse=True)
 
-        return self.search_tags(top, no_book_cat, max_results=max_results)
+        return self.search_tags(top, no_book_cat, max_results=max_results, pdcounter=pdcounter)
 
-    def hint_books(self, string, max_results=50):
+    def hint_books(self, string, max_results=50, prefix=True):
         """
         Returns auto-complete hints for book titles
         Because we do not index 'pseudo' title-tags.
@@ -1284,7 +1306,10 @@ class Search(IndexStore):
         """
         toks = self.get_tokens(string, field='SIMPLE')
 
-        q = self.create_prefix_phrase(toks, 'title')
+        if prefix:
+            q = self.make_prefix_phrase(toks, 'title')
+        else:
+            q = self.make_term_query(toks, 'title')
 
         return self.search_books(q, self.term_filter(Term("is_book", "true")), max_results=max_results)
 
index cf00870..623b311 100644 (file)
@@ -8,7 +8,7 @@ from django.views.decorators import cache
 from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect
 from django.utils.translation import ugettext as _
 
-from catalogue.utils import get_random_hash
+from catalogue.utils import split_tags
 from catalogue.models import Book, Tag, Fragment
 from catalogue.fields import dumps
 from catalogue.views import JSONResponse
@@ -34,7 +34,7 @@ def did_you_mean(query, tokens):
         authors = Tag.objects.filter(category='author', name__iregex=match_word_re(t))
         if len(authors) > 0:
             continue
-        
+
         if not dictionary.check(t):
             try:
                 change[t] = dictionary.suggest(t)[0]
@@ -69,7 +69,7 @@ def hint(request):
     # jezeli tagi dot tylko ksiazki, to wazne zeby te nowe byly w tej samej ksiazce
     # jesli zas dotycza themes, to wazne, zeby byly w tym samym fragmencie.
 
-    tags = s.hint_tags(prefix)
+    tags = s.hint_tags(prefix, pdcounter=True)
     books = s.hint_books(prefix)
 
     # TODO DODAC TU HINTY
@@ -97,26 +97,28 @@ def main(request):
     fuzzy = False
 
     if 'q' in request.GET:
-        tags = request.GET.get('tags', '')
+        tags = request.GET.get('tags', '')
         query = request.GET['q']
-        book_id = request.GET.get('book', None)
-        book = None
-        if book_id is not None:
-            book = get_object_or_404(Book, id=book_id)
+        book_id = request.GET.get('book', None)
+        book = None
+        if book_id is not None:
+            book = get_object_or_404(Book, id=book_id)
 
-        hint = srch.hint()
-        try:
-            tag_list = Tag.get_tag_list(tags)
-        except:
-            tag_list = []
+        hint = srch.hint()
+        try:
+            tag_list = Tag.get_tag_list(tags)
+        except:
+            tag_list = []
 
         if len(query) < 2:
-            return render_to_response('catalogue/search_too_short.html', {'tags': tag_list, 'prefix': query},
+            return render_to_response('catalogue/search_too_short.html', {'prefix': query},
                                       context_instance=RequestContext(request))
 
-        hint.tags(tag_list)
-        if book:
-            hint.books(book)
+        # hint.tags(tag_list)
+        # if book:
+        #     hint.books(book)
+        tags = srch.hint_tags(query, pdcounter=True, prefix=False)
+        tags = split_tags(tags)
 
         toks = StringReader(query)
         tokens_cache = {}
@@ -160,7 +162,7 @@ def main(request):
 
         author_results = SearchResult.aggregate(author_results)
         title_results = SearchResult.aggregate(title_results)
-        
+
         everywhere = SearchResult.aggregate(everywhere, author_title_rest)
 
         for res in [author_results, title_results, text_phrase, everywhere]:
@@ -168,15 +170,15 @@ def main(request):
             for r in res:
                 for h in r.hits:
                     h['snippets'] = map(lambda s:
-                                        re.subn(r"(^[ \t\n]+|[ \t\n]+$)", u"", 
+                                        re.subn(r"(^[ \t\n]+|[ \t\n]+$)", u"",
                                                 re.subn(r"[ \t\n]*\n[ \t\n]*", u"\n", s)[0])[0], h['snippets'])
-                    
+
         suggestion = did_you_mean(query, srch.get_tokens(toks, field="SIMPLE"))
         print "dym? %s" % repr(suggestion).encode('utf-8')
-        
+
         results = author_results + title_results + text_phrase + everywhere
         results.sort(reverse=True)
-        
+
         if len(results) == 1:
             fragment_hits = filter(lambda h: 'fragment' in h, results[0].hits)
             if len(fragment_hits) == 1:
@@ -187,14 +189,15 @@ def main(request):
         elif len(results) == 0:
             form = PublishingSuggestForm(initial={"books": query + ", "})
             return render_to_response('catalogue/search_no_hits.html',
-                                      {'tags': tag_list,
+                                      {'tags': tags,
                                        'prefix': query,
                                        "form": form,
                                        'did_you_mean': suggestion},
                 context_instance=RequestContext(request))
 
+        print "TAGS: %s" % tags
         return render_to_response('catalogue/search_multiple_hits.html',
-                                  {'tags': tag_list,
+                                  {'tags': tags,
                                    'prefix': query,
                                    'results': { 'author': author_results,
                                                 'title': title_results,
index ecb461a..64e390e 100755 (executable)
@@ -173,3 +173,9 @@ h2 {
     padding-top:3em;
     background: #fff;
 }
+
+/* just on search page */
+.top-tag-list {
+    margin-top: 2.2em;
+    margin-bottom: 1.6em;
+}
\ No newline at end of file
index 8225a1f..34f8500 100755 (executable)
@@ -100,6 +100,8 @@ $('.open-player').click(function(event) {
             return false;
         });
 
+       $(function(){
+           $("#search").search();});
 
     });
 })(jQuery)
index dc85dde..ee4cc51 100644 (file)
@@ -38,12 +38,6 @@ var __bind = function (self, fn) {
        },
        
 
-
-       });
-
-       $(".search-result .see-more-snippets").click(function() {
-           $(this).closest('.search-result').find('.snippets').removeClass('ui-helper-hidden');
-           });
     });
 
 
index efe6d79..70988f3 100644 (file)
       <span class="did_you_mean">{% trans "Did you mean" %} <a href="{% url search %}?q={{did_you_mean|urlencode}}">{{did_you_mean|lower}}</a>?</span>
     {% endif %}
     <!-- tu pójdą trafienia w tagi: Autorzy - z description oraz motywy i rodzaje (z book_count) -->
+      <div class="inline-tag-lists top-tag-list">
+       {% if tags.author %}
+       <div>
+         <div class="mono inline-header">{% trans "Authors" %}:</div>
+         <div class="inline-body">
+           {% inline_tag_list tags.author %}
+         </div>
+       </div>
+       {% endif %}
+       {% if tags.kind %}
+       <div>
+         <div class="mono inline-header">{% trans "Kinds" %}:</div>
+         <div class="inline-body">
+           {% inline_tag_list tags.kind %}
+         </div>
+       </div>
+       {% endif %}
+       {% if tags.genre %}
+       <div>
+         <div class="mono inline-header">{% trans "Genres" %}:</div>
+         <div class="inline-body">
+           {% inline_tag_list tags.genre  %}
+         </div>
+       </div>
+       {% endif %}
+       {% if tags.epoch %}
+       <div class="inline-tag-list">
+         <div class="mono inline-header">{% trans "Epochs" %}:</div>
+         <div class="inline-body">
+           {% inline_tag_list tags.epoch  %}
+         </div>
+       </div>
+       {% endif %}
+      </div>
+
 
+    
     {% if results.author %}
     <div class="book-list-header">
       <div class="book-box-inner">
     </div>
     <div>
       <ol class="work-list">
-       {% for author in results.author %}
-       <li class="Book-item">
-         {% book_short author.book %}
-       </li>
-       {% endfor %}
+       {% for author in results.author %}<li class="Book-item">{% book_short author.book %}</li>{% endfor %}
       </ol>
     </div>
     {% endif %}
     </div>
     <div>
       <ol class="work-list">
-       {% for result in results.title %}
-       <li class="Book-item">
+       {% for result in results.title %}<li class="Book-item">
          {% book_short result.book %}
-       </li>
-       {% endfor %}
+       </li>{% endfor %}
       </ol>
     </div>
     {% endif %}
index 8d53005..b729ca9 100644 (file)
@@ -7,63 +7,65 @@
 {% block bodyid %}tagged-object-list{% endblock %}
 
 {% block body %}
-    <div class="left-column">
-    <div class="page-desc">
+<div class="left-column">
+  <div class="page-desc">
     <h1>{% html_title_from_tags tags %}</h1>
 
     {% with tags|last as last_tag %}
     {% if last_tag.has_description %}
-        <div id="description" class="normal-text">
-            <div id='description-long' style="display:none">{{ last_tag.description|safe }}</div>
-            <div id='description-short'>{{ last_tag.description|safe|truncatewords_html:40 }}</div>
-        </div>
+    <div id="description" class="normal-text">
+      <div id='description-long' style="display:none">{{ last_tag.description|safe }}</div>
+      <div id='description-short'>{{ last_tag.description|safe|truncatewords_html:40 }}</div>
+    </div>
     {% endif %}
 
-
+    <div class="clearboth"></div>
     <div class="inline-tag-lists">
-    {% if categories.author %}
-       <div>
-               <div class="mono inline-header">{% trans "Authors" %}:</div>
-           <div class="inline-body">
-                           {% inline_tag_list categories.author tags %}
-               </div>
+      {% if categories.author %}
+      <div>
+       <div class="mono inline-header">{% trans "Authors" %}:</div>
+       <div class="inline-body">
+         {% inline_tag_list categories.author tags %}
         </div>
-    {% endif %}
-    {% if categories.kind %}
-       <div>
-               <div class="mono inline-header">{% trans "Kinds" %}:</div>
-           <div class="inline-body">
-                           {% inline_tag_list categories.kind tags %}
-               </div>
+      </div>
+      {% endif %}
+      {% if categories.kind %}
+      <div>
+       <div class="mono inline-header">{% trans "Kinds" %}:</div>
+       <div class="inline-body">
+         {% inline_tag_list categories.kind tags %}
         </div>
-    {% endif %}
-    {% if categories.genre %}
-       <div>
-               <div class="mono inline-header">{% trans "Genres" %}:</div>
-           <div class="inline-body">
-                           {% inline_tag_list categories.genre tags %}
-               </div>
+      </div>
+      {% endif %}
+      {% if categories.genre %}
+      <div>
+       <div class="mono inline-header">{% trans "Genres" %}:</div>
+       <div class="inline-body">
+         {% inline_tag_list categories.genre tags %}
         </div>
-    {% endif %}
-    {% if categories.epoch %}
-       <div class="inline-tag-list">
-               <div class="mono inline-header">{% trans "Epochs" %}:</div>
-           <div class="inline-body">
-                           {% inline_tag_list categories.epoch tags %}
-               </div>
+      </div>
+      {% endif %}
+      {% if categories.epoch %}
+      <div class="inline-tag-list">
+       <div class="mono inline-header">{% trans "Epochs" %}:</div>
+       <div class="inline-body">
+         {% inline_tag_list categories.epoch tags %}
         </div>
-    {% endif %}
+      </div>
+      {% endif %}
+
+      {% if categories.theme %}
+      <div class="hidden-box-wrapper">
+       <p><a href="#" class="hidden-box-trigger theme-list-link mono">
+            {% trans "Motifs and themes" %}</a></p>
+       <div class="hidden-box">
+          {% tag_list categories.theme tags %}
+       </div>
+      </div>
+      {% endif %}
     </div>
 
-    {% if categories.theme %}
-        <div class="hidden-box-wrapper">
-            <p><a href="#" class="hidden-box-trigger theme-list-link mono">
-               {% trans "Motifs and themes" %}</a></p>
-            <div class="hidden-box">
-                {% tag_list categories.theme tags %}
-            </div>
-        </div>
-    {% endif %}
+    <div class="clearboth"></div>
 
 
        {% if theme_is_set %}