from basicauth import logged_in_or_basicauth, factory_decorator
from catalogue.models import Book, Tag
-from search import Search, SearchResult, JVM
+from search.views import get_search, SearchResult, JVM
from lucene import Term, QueryWrapperFilter, TermQuery
+import logging
import re
+log = logging.getLogger('opds')
+
from stats.utils import piwik_track
_root_feeds = (
JVM.attachCurrentThread()
query = request.GET.get('q', '')
-
+
inline_criteria = re.findall(self.INLINE_QUERY_RE, query)
if inline_criteria:
def get_criteria(criteria, name, position):
e = filter(lambda el: el[0][0:len(name)] == name, criteria)
- print e
+ log.info("get_criteria: %s" % e)
if not e:
return None
c = e[0][position]
- print c
+ log.info("get_criteria: %s" % c)
if c[0] == '"' and c[-1] == '"':
c = c[1:-1]
c = c.replace('+', ' ')
return c
- #import pdb; pdb.set_trace()
author = get_criteria(inline_criteria, 'author', 1)
title = get_criteria(inline_criteria, 'title', 2)
translator = None
categories = None
fuzzy = False
-
- srch = Search()
+ srch = get_search()
hint = srch.hint()
# Scenario 1: full search terms provided.
filters = []
if author:
- print "narrow to author %s" % author
+ log.info( "narrow to author %s" % author)
hint.tags(srch.search_tags(author, filt=srch.term_filter(Term('tag_category', 'author'))))
if translator:
- print "filter by translator %s" % translator
+ log.info( "filter by translator %s" % translator)
filters.append(QueryWrapperFilter(
srch.make_phrase(srch.get_tokens(translator, field='translators'),
field='translators')))
flt = srch.chain_filters(filters)
if title:
- print "hint by book title %s" % title
+ log.info( "hint by book title %s" % title)
q = srch.make_phrase(srch.get_tokens(title, field='title'), field='title')
hint.books(*srch.search_books(q, filt=flt))
toks = srch.get_tokens(query)
- print "tokens: %s" % toks
- # import pdb; pdb.set_trace()
+ log.info("tokens for query: %s" % toks)
+
results = SearchResult.aggregate(srch.search_perfect_book(toks, fuzzy=fuzzy, hint=hint),
srch.search_perfect_parts(toks, fuzzy=fuzzy, hint=hint),
srch.search_everywhere(toks, fuzzy=fuzzy, hint=hint))
results.sort(reverse=True)
- return [r.book for r in results]
+ books = []
+ for r in results:
+ try:
+ books.append(r.book)
+ except Book.DoesNotExist:
+ pass
+ log.info("books: %s" % books)
+ return books
else:
# Scenario 2: since we no longer have to figure out what the query term means to the user,
# we can just use filters and not the Hint class.
doc.add(NumericField("parent_id", Field.Store.YES, True).setIntValue(int(book.parent.id)))
return doc
- def remove_book(self, book, remove_snippets=True):
+ def remove_book(self, book_or_id, remove_snippets=True):
"""Removes a book from search index.
book - Book instance."""
- q = NumericRangeQuery.newIntRange("book_id", book.id, book.id, True, True)
+ if isinstance(book_or_id, catalogue.models.Book):
+ book_id = book_or_id.id
+ else:
+ book_id = book_or_id
+
+ q = NumericRangeQuery.newIntRange("book_id", book_id, book_id, True, True)
self.index.deleteDocuments(q)
if remove_snippets:
- snippets = Snippets(book.id)
+ snippets = Snippets(book_id)
snippets.remove()
def index_book(self, book, book_info=None, overwrite=True):
book_doc = self.create_book_doc(book)
meta_fields = self.extract_metadata(book, book_info, dc_only=['source_name', 'authors', 'title'])
# let's not index it - it's only used for extracting publish date
- del meta_fields['source_name']
+ if 'source_name' in meta_fields:
+ del meta_fields['source_name']
for f in meta_fields.values():
if isinstance(f, list) or isinstance(f, tuple):
return toks
- def fuzziness(self, fuzzy):
+ @staticmethod
+ def fuzziness(fuzzy):
"""Helper method to sanitize fuzziness"""
if not fuzzy:
return None
phrase.add(term)
return phrase
- def make_term_query(self, tokens, field='content', modal=BooleanClause.Occur.SHOULD, fuzzy=False):
+ @staticmethod
+ def make_term_query(tokens, field='content', modal=BooleanClause.Occur.SHOULD, fuzzy=False):
"""
Returns term queries joined by boolean query.
modal - applies to boolean query
from django.core.management.base import BaseCommand
-from search import Index
+from search import Index, Search
+from lucene import IndexReader, IndexSearcher, Term
+from catalogue.models import Book
+
class Command(BaseCommand):
help = 'Optimize Lucene search index'
args = ''
+ def delete_old(self, index):
+ existing_ids = set([book.id for book in Book.objects.all()])
+
+ reader = IndexReader.open(index.index, False)
+ searcher = IndexSearcher(reader)
+ try:
+ num = searcher.docFreq(Term('is_book', 'true'))
+ docs = searcher.search(Search.make_term_query(['true'], 'is_book'), num)
+ for result in docs.scoreDocs:
+ stored = searcher.doc(result.doc)
+ book_id = int(stored.get('book_id'))
+ if not book_id in existing_ids:
+ print "book id %d doesn't exist." % book_id
+ index.remove_book(book_id)
+ finally:
+ searcher.close()
+ reader.close()
+
def handle(self, *args, **opts):
index = Index()
index.open()
+
+ self.delete_old(index)
+
try:
index.optimize()
finally:
+
+/*
+ * RESET
+ * src: http://meyerweb.com/eric/tools/css/reset/
+ */
+
+#wl div, #wl span, #wl applet, #wl object, #wl iframe,
+#wl #eh1, #wl h2, #wl h3, #wl h4, #wl h5, #wl h6, #wl p, #wl blockquote, #wl pre,
+#wl a, #wl abbr, #wl acronym, #wl address, #wl big, #wl cite, #wl code,
+#wl del, #wl dfn, #wl em, #wl img, #wl ins, #wl kbd, #wl q, #wl s, #wl samp,
+#wl small, #wl strike, #wl strong, #wl sub, #wl sup, #wl tt, #wl var,
+#wl b, #wl u, #wl i, #wl center,
+#wl dl, #wl dt, #wl dd, #wl ol, #wl ul, #wl li,
+#wl fieldset, #wl form, #wl label, #wl legend,
+#wl table, #wl caption, #wl tbody, #wl tfoot, #wl thead, #wl tr, #wl th, #wl td,
+#wl article, #wl aside, #wl canvas, #wl details, #wl embed,
+#wl figure, #wl figcaption, #wl footer, #wl header, #wl hgroup,
+#wl menu, #wl nav, #wl output, #wl ruby, #wl section, #wl summary,
+#wl time, #wl mark, #wl audio, #wl video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
#wl {
-background-color: white;
+ line-height: 1;
+}
+
+#wl ol, #wl ul {
+ list-style: none;
+}
+#wl blockquote, #wl q {
+ quotes: none;
+}
+
+#wl blockquote:before, #wl blockquote:after,
+#wl q:before, #wl q:after {
+ content: '';
+ content: none;
+}
+#wl table {
+ border-collapse: collapse;
+ border-spacing: 0;
}
+
+/* END RESET */
+
+#wl {
+ background-color: white;
+}
+
#wl a, a:visited, a:hover {
-border: 0;
+ border: 0;
}
+
#wl img {
-border: 0;
+ border: 0;
+ width: 8.625em;
+ margin: 0.375em 0;
}
+
+
.ui-menu {
-width: 160px;
-font-size: small;
-list-style-type: none;
-padding: 0;
-margin:0;
-border-left: 1px solid #696969;
-border-right: 1px solid #696969;
-border-bottom: 1px solid #696969;
+ width: 29em;
+ font-size: small;
+ list-style-type: none;
+ padding: 0;
+ margin:0;
+ border: 1px solid #ddd;
+}
+
+.ui-menu .search-hint-label {
+ display: inline-block;
+ width: 20em;
+ margin-right: 2em;
+ font-size: 1.1em;
+ line-height: 1.636em;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.ui-menu .search-hint-category {
+ width: 9em;
+}
+
+.ui-corner-all {
+ /*width: 160px;*/
+ cursor: pointer;
+ display:block;
+}
+
+.ui-corner-all a {
+ text-decoration: none;
+ color: #0D7E85;
+ font-size: small;
+ padding: 5px;
+
}
.ui-menu li {
-font-size: small;
-padding: 5px;
-width: 150px
}
.ui-menu li:nth-child(odd) {
-background-color: white;
+ background-color: white;
}
.ui-menu li:nth-child(even){
-background-color: #EDF1F5;
+ background-color: #EEE;
+}
+
+.ui-menu li .ui-state-hover {
+ background-color: #fdf5ce;
}
.ui-menu li:hover{
-background-color: #053469;
-color:white;
+ background-color: #053469;
+ color:white;
}
.ui-menu a:hover {
-color:white;
-text-decoration: none;
+ color:white;
+ text-decoration: none;
}
-.ui-corner-all {
-width: 160px;
-cursor: pointer;
-display:block;
+
+#wl #id_qq {
+ font-family: Georgia;
+ font-size: 0.75em;
+
+ background-color: #FFFFFF;
+ border: medium none;
+ border-radius: 0.38em 0.38em 0.38em 0.38em;
+ box-shadow: 0 0 0.5em #444444 inset;
+ color: #000000;
+ height: 2.54em;
+ width: 9.125em;
+
+ line-height: 2.5em;
+ padding: 0 0 0 1em;
+ position: relative;
}
-.ui-corner-all a{
- color: black;
- text-decoration: none;
+#wl input[type=image] {
+ width: 1.5em;
+ height: 1.5625em;
+ top: 0.375em;
+ position: relative;
+ margin-left: 0.625em;
}
+
focus: function() { return false; },
source: this.element.data('source'),
};
- this.element.autocomplete(opts).data("autocomplete")._renderItem = __bind(this, this.render_item);
+
+ this.element.autocomplete($.extend(opts, this.options))
+ .data("autocomplete")._renderItem = __bind(this, this.render_item);
},
enter: function(event, ui) {
.append('<a href="'+item.url+'"><span class="search-hint-label">'+item.label+'</span>'+
'<span class="search-hint-category mono">'+item.category+'</span></a>')
.appendTo(ul);
- },
+ },
destroy: function() {
var inputSubmit = document.createElement('input');
var body = document.getElementsByTagName('body')
var stylesheet = document.createElement('link');
+var stylesheetJQUI = document.createElement('linl');
-var host = 'www.wolnelektury.pl';
+var host = 'localhost:8000'; //'www.wolnelektury.pl';
/* set attributes of created elements */
stylesheet.setAttribute('type', 'text/css');
stylesheet.setAttribute('rel', 'stylesheet');
stylesheet.setAttribute('href', 'http://'+host+'/static/css/widget.css');
+stylesheetJQUI.setAttribute('type', 'text/css');
+stylesheetJQUI.setAttribute('rel', 'stylesheet');
+stylesheetJQUI.setAttribute('href', 'http://'+host+'/static/css/ui-lightness/jquery-ui-1.8.16.custom.css');
linkLogo.setAttribute('href', 'http://'+host);
-logo.setAttribute('src', 'http://'+host+'/static/img/logo.png');
+logo.setAttribute('src', 'http://'+host+'/static/img/logo-bez.png');
form.setAttribute('action', 'http://'+host+'/szukaj/');
form.setAttribute('method', 'get');
form.setAttribute('accept-charset', 'utf-8');
inputText.setAttribute('value', '');
inputText.setAttribute('name', 'q');
inputText.setAttribute('id', 'id_qq');
-inputText.setAttribute('size', '13');
+inputText.setAttribute('data-source', 'http://'+host+'/szukaj/hint');
+/*inputText.setAttribute('size', '13');*/
inputSubmit.setAttribute('type', 'image');
inputSubmit.setAttribute('src', 'http://'+host+'/static/img/search.png');
-inputSubmit.setAttribute('style', 'position:relative; top:5px; margin-left:5px');
+/* inputSubmit.setAttribute('style', 'position:relative; top:5px; margin-left:5px');*/
/* import jquery and autocomplete */
var scriptJ = document.createElement('script');
scriptJ.setAttribute('type', 'text/javascript');
scriptJ.setAttribute('src', 'http://'+host+'/static/js/jquery.js');
-var scriptAutoComplete = document.createElement('script');
-scriptAutoComplete.setAttribute('type', 'text/javascript');
-scriptAutoComplete.setAttribute('src', 'http://'+host+'/static/js/jquery-ui-1.8.2.custom.min.js');
+var scriptUI = document.createElement('script');
+scriptUI.setAttribute('type', 'text/javascript');
+scriptUI.setAttribute('src', 'http://'+host+'/static/js/jquery-ui-1.8.2.custom.min.js');
+scriptUI.setAttribute('id', 'wl-jquery-ui-script')
+
+var scriptSearch = document.createElement('script');
+scriptSearch.setAttribute('type', 'text/javascript');
+scriptSearch.setAttribute('src', 'http://'+host+'/static/js/search.js');
+scriptSearch.setAttribute('id', 'wl-search-script')
-var scriptInit = document.createElement('script');
-scriptInit.setAttribute('type', 'text/javascript');
-scriptInit.setAttribute('src', 'http://'+host+'/static/js/widgetInit.js');
body[0].appendChild(scriptJ);
-body[0].appendChild(scriptAutoComplete);
-body[0].appendChild(scriptInit);
+body[0].appendChild(scriptUI);
+body[0].appendChild(scriptSearch);
/* append elements to widget */
widget.appendChild(stylesheet);
+//widget.appendChild(stylesheetJQUI);
widget.appendChild(linkLogo);
linkLogo.appendChild(logo);
widget.appendChild(form);
form.appendChild(inputSubmit);
/* ...and a little make-up */
+/*
widget.style.borderColor = "#84BF2A";
widget.style.borderWidth = "2px";
widget.style.borderStyle = "solid";
widget.style.padding = "10px";
widget.style.fontSize = "12px";
form.style.paddingTop = "10px";
+*/
/* resize - if needed */
if(widget.getAttribute('width') == '140'){
inputText.setAttribute('size', '10');
widget.style.width = "140px";
}
+
+var wl_loaded_scripts = {};
+
+function wl_initialize_after_load(just_loaded) {
+ wl_loaded_scripts[just_loaded] = true;
+ if (wl_loaded_scripts.jquery
+ && wl_loaded_scripts.ui
+ && wl_loaded_scripts.search) {
+ var s = $('#id_qq');
+ s.search({source: s.attr('data-source')});
+ }
+}
+
+scriptJ.onload = function() { wl_initialize_after_load('jquery'); };
+scriptUI.onload = function() { wl_initialize_after_load('ui'); };
+scriptSearch.onload = function() { wl_initialize_after_load('search'); };
- $(function() {
- $("#id_qq").autocomplete({
+
+var wl_scripts_loaded = {};
+
+function wl_load_search_if_ready(id) {
+ wl_scripts_loaded[id] = true;
+ if (wl_scripts_loaded['wl-search-script'] &&
+ wl_scripts_loaded['wl-jquery-ui-script'])
+ {
+ var s = $('#id_qq');
+ s.search({source: s.attr('data-source')});
+ }
+}
+
+$('#wl-search-script').ready(function(){wl_load_search_if_ready('wl-search-script');});
+$('#wl-jquery-ui-script').ready(function(){wl_load_search_if_ready('wl-jquery-ui-script');});
+
+/*autocomplete({
source: function(request, response) {
$.ajax({
url: "http://www.wolnelektury.pl/katalog/jtags/",
}
});
});
+*/
<!-- KONIEC -->
<!-- START Umiescic ten element zaraz przed zamknieciem taga body: </body> -->
-<script type="text/javascript" src="http://www.wolnelektury.pl/static/js/widget.js"></script>
+<script type="text/javascript" src="http://localhost:8000/static/js/widget.js"></script>
<!-- KONIEC -->
</body>