From dd6284e01f00296294a527ded7e840ac14c5fbb8 Mon Sep 17 00:00:00 2001 From: Marcin Koziej Date: Tue, 27 Dec 2011 12:47:29 +0100 Subject: [PATCH] Search hints/javascript --- apps/catalogue/models.py | 12 ++++---- apps/catalogue/tasks.py | 7 ++++- apps/search/index.py | 18 ++---------- apps/search/views.py | 9 ++++-- wolnelektury/settings.py | 6 ++++ wolnelektury/static/js/search.js | 49 ++++++++++++++++++++++++++++++++ wolnelektury/templates/base.html | 2 +- wolnelektury/urls.py | 2 +- 8 files changed, 77 insertions(+), 28 deletions(-) create mode 100644 wolnelektury/static/js/search.js diff --git a/apps/catalogue/models.py b/apps/catalogue/models.py index 4da82ef72..e69d23168 100644 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@ -24,7 +24,7 @@ from newtagging.models import TagBase, tags_updated from newtagging import managers from catalogue.fields import JSONField, OverwritingFileField from catalogue.utils import create_zip, split_tags -from catalogue.tasks import touch_tag +from catalogue.tasks import touch_tag, index_book from shutil import copy from glob import glob import re @@ -732,17 +732,15 @@ class Book(models.Model): return result.wait() def search_index(self, book_info=None): - if settings.SEARCH_INDEX_PARALLEL: - if instance(settings.SEARCH_INDEX_PARALLEL, int): - idx = search.ReusableIndex(threads=4) - else: - idx = search.ReusableIndex() + if settings.CELERY_ALWAYS_EAGER: + idx = search.ReusableIndex() else: idx = search.Index() idx.open() try: idx.index_book(self, book_info) + idx.index_tags() finally: idx.close() @@ -834,7 +832,7 @@ class Book(models.Model): book.build_mobi() if not settings.NO_SEARCH_INDEX and search_index: - book.search_index(book_info) + index_book.delay(book.id, book_info) book_descendants = list(book.children.all()) descendants_tags = set() diff --git a/apps/catalogue/tasks.py b/apps/catalogue/tasks.py index 5566fe177..86e84a511 100755 --- a/apps/catalogue/tasks.py +++ b/apps/catalogue/tasks.py @@ -4,7 +4,7 @@ # from datetime import datetime from celery.task import task - +import catalogue.models @task def touch_tag(tag): @@ -14,3 +14,8 @@ def touch_tag(tag): } type(tag).objects.filter(pk=tag.pk).update(**update_dict) + + +@task +def index_book(book_id, book_info=None): + return catalogue.models.Book.objects.get(id=book_id).search_index(book_info) diff --git a/apps/search/index.py b/apps/search/index.py index f4da66f10..10069e4e4 100644 --- a/apps/search/index.py +++ b/apps/search/index.py @@ -412,35 +412,23 @@ class ReusableIndex(Index): if you cannot rely on atexit, use ReusableIndex.close_reusable() yourself. """ index = None - pool = None - pool_jobs = None def open(self, analyzer=None, threads=4): if ReusableIndex.index is not None: self.index = ReusableIndex.index else: print("opening index") - ReusableIndex.pool = ThreadPool(threads, initializer=lambda: JVM.attachCurrentThread() ) - ReusableIndex.pool_jobs = [] Index.open(self, analyzer) ReusableIndex.index = self.index atexit.register(ReusableIndex.close_reusable) - def index_book(self, *args, **kw): - job = ReusableIndex.pool.apply_async(log_exception_wrapper(Index.index_book), (self,) + args, kw) - ReusableIndex.pool_jobs.append(job) + # def index_book(self, *args, **kw): + # job = ReusableIndex.pool.apply_async(log_exception_wrapper(Index.index_book), (self,) + args, kw) + # ReusableIndex.pool_jobs.append(job) @staticmethod def close_reusable(): if ReusableIndex.index is not None: - print("wait for indexing to finish") - for job in ReusableIndex.pool_jobs: - job.get() - sys.stdout.write('.') - sys.stdout.flush() - print("done.") - ReusableIndex.pool.close() - ReusableIndex.index.optimize() ReusableIndex.index.close() ReusableIndex.index = None diff --git a/apps/search/views.py b/apps/search/views.py index fad5e6f61..75cc16a0d 100644 --- a/apps/search/views.py +++ b/apps/search/views.py @@ -5,6 +5,7 @@ from django.template import RequestContext from django.contrib.auth.decorators import login_required 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.models import Book, Tag, Fragment, TAG_CATEGORIES @@ -50,7 +51,7 @@ def category_name(category): def hint(request): prefix = request.GET.get('term', '') if len(prefix) < 2: - return JSONResponse(dumps(None)) + return JSONResponse([]) JVM.attachCurrentThread() s = MultiSearch() @@ -66,6 +67,8 @@ 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. + # import pdb; pdb.set_trace() + tags = s.hint_tags(prefix) books = s.hint_books(prefix) @@ -73,12 +76,12 @@ def hint(request): return JSONResponse( [{'label': t.name, - 'category': category_name(t.category), + 'category': _(category_name(t.category)), 'id': t.id, 'url': t.get_absolute_url()} for t in tags] + \ [{'label': b.title, - 'category': category_name('book'), + 'category': _(category_name('book')), 'id': b.id, 'url': b.get_absolute_url()} for b in books]) diff --git a/wolnelektury/settings.py b/wolnelektury/settings.py index 4184c4e66..fe2572904 100644 --- a/wolnelektury/settings.py +++ b/wolnelektury/settings.py @@ -175,6 +175,8 @@ COMPRESS_CSS = { 'css/book_box.css', 'css/catalogue.css', 'css/sponsors.css', + + 'css/ui-lightness/jquery-ui-1.8.16.custom.css', ], 'output_filename': 'css/all.min?.css', }, @@ -199,11 +201,15 @@ COMPRESS_JS = { 'js/jquery.countdown-es.js', 'js/jquery.countdown-lt.js', 'js/jquery.countdown-ru.js', 'js/jquery.countdown-fr.js', + 'js/jquery-ui-1.8.16.custom.min.js', + 'js/locale.js', 'js/dialogs.js', 'js/sponsors.js', 'js/pdcounter.js', + 'js/search.js', + #~ 'js/jquery.autocomplete.js', #~ 'js/jquery.labelify.js', 'js/catalogue.js', ), diff --git a/wolnelektury/static/js/search.js b/wolnelektury/static/js/search.js new file mode 100644 index 000000000..e58d37256 --- /dev/null +++ b/wolnelektury/static/js/search.js @@ -0,0 +1,49 @@ + +var __bind = function (self, fn) { + return function() { fn.apply(self, arguments); }; +}; + +(function($){ + $.widget("wl.search", { + options: { + minLength: 0, + }, + + _create: function() { + var opts = { + minLength: this.options.minLength, + select: __bind(this, this.enter), + focus: function() { return false; }, + source: this.element.data('source'), + }; + this.element.autocomplete(opts).data("autocomplete")._renderItem = __bind(this, this.render_item); + }, + + enter: function(event, ui) { + if (ui.item.url != undefined) { + location.href = ui.item.url; + } else { + this.element.closest('form').submit(); + } + }, + + render_item: function (ul, item) { + return $("
  • ").data('item.autocomplete', item) + .append(''+item.label+ ' ('+item.category+')') + .appendTo(ul); + }, + + destroy: function() { + + }, + + + + }); + + $(function() { + $("#search input[name=q]").search(); + + }); + +})(jQuery); diff --git a/wolnelektury/templates/base.html b/wolnelektury/templates/base.html index 534f5cfc1..844095903 100644 --- a/wolnelektury/templates/base.html +++ b/wolnelektury/templates/base.html @@ -65,7 +65,7 @@