diff --git a/src/calibre/srv/ajax.py b/src/calibre/srv/ajax.py index ee6e46f940..e1a6e25f93 100644 --- a/src/calibre/srv/ajax.py +++ b/src/calibre/srv/ajax.py @@ -519,3 +519,36 @@ def books_in(ctx, rd, encoded_category, encoded_item, library_id): result['additional_fields'] = additional_fields return result # }}} + + +@endpoint('/ajax/search/{library_id=None}', postprocess=json) +def search(ctx, rd, library_id): + ''' + Return the books (as list of ids) matching the specified search query. + + Optional: ?num=100&offset=0&sort=title&sort_order=asc&get_additional_fields= + ''' + db = get_db(ctx, library_id) + with db.safe_read_lock: + query = rd.query.get('query') + num, offset = get_pagination(rd.query) + sort, sort_order = rd.query.get('sort', 'title'), rd.query.get('sort_order') + sort_order = ensure_val(sort_order, 'asc', 'desc') + sfield = sanitize_sort_field_name(db.field_metadata, sort) + if sfield not in db.field_metadata.sortable_field_keys(): + raise HTTPNotFound('%s is not a valid sort field'%sort) + + if not query: + ids = ctx.allowed_book_ids(rd, db) + else: + ids = ctx.search(rd, db, query) + ids = db.multisort(fields=[(sfield, sort_order == 'asc')], ids_to_sort=ids) + total_num = len(ids) + ids = ids[offset:offset+num] + return { + 'total_num': total_num, 'sort_order':sort_order, + 'offset':offset, 'num':len(ids), 'sort':sort, + 'base_url':ctx.url_for(search, library_id=db.server_library_id), + 'query': query, + 'book_ids':ids + } diff --git a/src/calibre/srv/handler.py b/src/calibre/srv/handler.py index 54502fcf85..68a254065f 100644 --- a/src/calibre/srv/handler.py +++ b/src/calibre/srv/handler.py @@ -108,7 +108,7 @@ class Context(object): if old is None or old[0] < db.clear_search_cache_count: matches = db.search(query, book_ids=restrict_to_ids) cache[key] = old = (db.clear_search_cache_count, matches) - if len(self._search_cache) > self.SEARCH_CACHE_SIZE: + if len(cache) > self.SEARCH_CACHE_SIZE: cache.popitem(last=False) else: cache[key] = old diff --git a/src/calibre/srv/tests/ajax.py b/src/calibre/srv/tests/ajax.py index c76d0eb9d0..fc860a253f 100644 --- a/src/calibre/srv/tests/ajax.py +++ b/src/calibre/srv/tests/ajax.py @@ -8,6 +8,7 @@ __copyright__ = '2015, Kovid Goyal ' import httplib, zlib, json from functools import partial +from urllib import urlencode from calibre.srv.tests.base import LibraryBaseTest @@ -47,7 +48,7 @@ class ContentTest(LibraryBaseTest): # }}} def test_ajax_categories(self): # {{{ - 'Test /ajax/categories' + 'Test /ajax/categories and /ajax/search' with self.create_server() as server: db = server.handler.router.ctx.get_library() conn = server.connect() @@ -68,4 +69,7 @@ class ContentTest(LibraryBaseTest): r, data = request(names['Tag One'], prefix='') self.ae(r.status, httplib.OK) self.ae(set(data['book_ids']), {1, 2}) + r, data = request('/search?' + urlencode({'query': 'tags:"=Tag One"'})) + self.ae(r.status, httplib.OK) + self.ae(set(data['book_ids']), {1, 2}) # }}}