def search_items_test(): """ Tests if parsed items can be searched by a bunch of parameters """ items = bib_parser.BibParser().parse_string(TEST_ITEMS) item_index = index.Index(items) for item in items: item.process_crossrefs(item_index) item_index.update(items) author_search = search.search_for_iterable("author", "Петров") filtered_items = filter(author_search, items) eq_(len(list(filtered_items)), 1) #testing exact match year_search = search.and_([ search.search_for("year_from", 1825), search.search_for("year_to", 1825) ]) filtered_items = filter(year_search, items) eq_(len(list(filtered_items)), 1) #testing partial intersection year_search = search.and_([ search.search_for("year_from", 1500), search.search_for("year_to", 1600) ]) filtered_items = filter(year_search, items) eq_(len(list(filtered_items)), 1) #testing inner containment year_search = search.and_([ search.search_for("year_from", 1499), search.search_for("year_to", 1501) ]) filtered_items = filter(year_search, items) eq_(len(list(filtered_items)), 1) #testing outer containment year_search = search.and_([ search.search_for("year_from", 1400), search.search_for("year_to", 1600) ]) filtered_items = filter(year_search, items) eq_(len(list(filtered_items)), 1) filtered_items = item_index["keywords"]["grumbling"] eq_(len(list(filtered_items)), 1) filtered_items = \ item_index["keywords"]["cinquecento"] & \ item_index["keywords"]["historical dance"] eq_(len(list(filtered_items)), 1)
def test_search_items(self): """ Tests if parsed items can be searched by a bunch of parameters """ items = bib_parser.BibParser().parse_string(TEST_ITEMS) item_index = index.Index(items) for item in items: item.process_crossrefs(item_index) item_index.update(items) author_search = search.search_for_iterable("author", "Петров") filtered_items = filter(author_search, items) self.assertEqual(len(list(filtered_items)), 1) #testing exact match year_search = search.and_([ search.search_for("year_from", 1825), search.search_for("year_to", 1825) ]) filtered_items = filter(year_search, items) self.assertEqual(len(list(filtered_items)), 1) #testing partial intersection year_search = search.and_([ search.search_for("year_from", 1500), search.search_for("year_to", 1600) ]) filtered_items = filter(year_search, items) self.assertEqual(len(list(filtered_items)), 1) #testing inner containment year_search = search.and_([ search.search_for("year_from", 1499), search.search_for("year_to", 1501) ]) filtered_items = filter(year_search, items) self.assertEqual(len(list(filtered_items)), 1) #testing outer containment year_search = search.and_([ search.search_for("year_from", 1400), search.search_for("year_to", 1600) ]) filtered_items = filter(year_search, items) self.assertEqual(len(list(filtered_items)), 1) filtered_items = item_index["keywords"]["grumbling"] self.assertEqual(len(list(filtered_items)), 1) filtered_items = \ item_index["keywords"]["cinquecento"] & \ item_index["keywords"]["historical dance"] self.assertEqual(len(list(filtered_items)), 1)
def search_items(show_secrets): request_args = { key: value.strip() for key, value in flask.request.values.items() if value and (key in config.www.search_params) } request_keys = set(request_args.keys()) order_by = flask.request.values.get("orderBy", const.DEFAULT_ORDER_BY) if order_by not in config.www.order_by_keys: flask.abort( http.client.BAD_REQUEST, "Key {order_by} is not supported for ordering".format( order_by=order_by)) #if request_args is empty, we should render empty search form if len(request_args) == 0: flask.abort(http.client.BAD_REQUEST, "No search parameters specified") found_items = set(items) for index_to_use in (config.www.indexed_search_params & request_keys): value_to_use = request_args[index_to_use] if ((index_to_use in config.parser.list_params) or (index_to_use in config.parser.keyword_list_params)): values_to_use = utils.strip_split_list(value_to_use, ",") else: values_to_use = [value_to_use] for value in values_to_use: if index_to_use == "availability": value = bib_parser.Availability(value) indexed_items = set(item_index[index_to_use].get(value, set())) found_items &= indexed_items searches = [] try: for search_key in (config.www.nonindexed_search_params & request_keys): # argument can be missing or be empty # both cases should be ignored during search search_param = request_args[search_key] if len(search_param) > 0: param_filter = search.search_for(search_key, search_param) if param_filter is not None: searches.append(param_filter) except Exception as ex: flask.abort(http.client.BAD_REQUEST, "Some of the search parameters are wrong: {0}".format(ex)) found_items = list( sorted(filter(search.and_(searches), found_items), key=bib_parser.BibItem.key_to_key_func(order_by))) return flask.render_template("search.html", found_items=found_items, show_secrets=show_secrets)
def root(show_secrets): args_filter = lambda pair: len(pair[1]) > 0 request_args = dict(filter(args_filter, flask.request.args.items())) request_keys = set(request_args.keys()) #if request_args is empty, we should render empty search form if len(request_args) == 0: return flask.render_template( "index.html", items=items, show_secrets=show_secrets ) found_items = None for index_to_use in (config.www.indexed_search_params & request_keys): value_to_use = request_args[index_to_use] if index_to_use in config.parser.list_params: values_to_use = utils.strip_split_list(value_to_use, ",") else: values_to_use = [value_to_use] for value in values_to_use: indexed_items = set(item_index[index_to_use].get(value, set())) if found_items is None: found_items = indexed_items else: found_items &= indexed_items searches = [] if found_items is None: #no index was applied found_items = items try: for search_key in (config.www.nonindexed_search_params & request_keys): # argument can be missing or be empty # both cases should be ignored during search search_param = request_args[search_key] if len(search_param) > 0: param_filter = search.search_for(search_key, search_param) if param_filter is not None: searches.append(param_filter) except Exception as ex: flask.abort(400, "Some of the search parameters are wrong: {0}".format(ex)) if len(searches) > 0: found_items = list(filter(search.and_(searches), found_items)) return flask.render_template( "index.html", found_items=found_items, search_params=request_args, show_secrets=show_secrets )
def search_items(show_secrets): request_args = { key: value.strip() for key, value in flask.request.values.items() if value and (key in config.www.search_params) } request_keys = set(request_args.keys()) order_by = flask.request.values.get("orderBy", const.DEFAULT_ORDER_BY) if order_by not in config.www.order_by_keys: flask.abort(http.client.BAD_REQUEST, "Key {order_by} is not supported for ordering".format( order_by=order_by )) #if request_args is empty, we should render empty search form if len(request_args) == 0: flask.abort(http.client.BAD_REQUEST, "No search parameters specified") found_items = set(items) for index_to_use in (config.www.indexed_search_params & request_keys): value_to_use = request_args[index_to_use] if ( (index_to_use in config.parser.list_params) or (index_to_use in config.parser.keyword_list_params) ): values_to_use = utils.strip_split_list(value_to_use, ",") else: values_to_use = [value_to_use] for value in values_to_use: if index_to_use == "availability": value = bib_parser.Availability(value) indexed_items = set(item_index[index_to_use].get(value, set())) found_items &= indexed_items searches = [] try: for search_key in (config.www.nonindexed_search_params & request_keys): # argument can be missing or be empty # both cases should be ignored during search search_param = request_args[search_key] if len(search_param) > 0: param_filter = search.search_for(search_key, search_param) if param_filter is not None: searches.append(param_filter) except Exception as ex: flask.abort(http.client.BAD_REQUEST, "Some of the search parameters are wrong: {0}".format(ex)) found_items = list(sorted( filter(search.and_(searches), found_items), key=bib_parser.BibItem.key_to_key_func(order_by) )) return flask.render_template( "search.html", found_items=found_items, show_secrets=show_secrets )
def create_search_from_metadata(metadata: {"str": str}) -> callable: """ Creates callable applicable to an item, checing if this item match given metadata """ langid = metadata["langid"] year = metadata["year"] title = metadata["title"] author = metadata.get("author", None) tome = metadata.get("tome", None) edition = metadata.get("edition", None) part = metadata.get("part", None) #keywords = metadata.get("keywords", None) title_regexp = re.compile("^" + re.escape(title)) search_for_langid = search.search_for_eq("langid", langid) search_for_year = search.and_([ search.search_for("year_from", year[0]), search.search_for("year_to", year[1]) ]) search_for_itemtitle = search.search_for_string_regexp("title", title_regexp) search_for_booktitle = search.search_for_string_regexp("booktitle", title_regexp) search_for_title = search.or_([search_for_itemtitle, search_for_booktitle]) searches = [ search_for_langid, search_for_year, search_for_title, ] if author is not None: search_for_author = search.search_for_eq( "author", author ) searches.append(search_for_author) if tome is not None: search_for_volume = search.search_for_optional_eq( "volume", tome ) search_for_volumes = search.search_for_integer_ge( "volumes", tome ) searches.append(search.or_([search_for_volume, search_for_volumes])) if edition is not None: search_for_edition = search.search_for_eq( "edition", edition ) searches.append(search_for_edition) if part is not None: search_for_part = search.search_for_eq( "part", part ) searches.append(search_for_part) #keywords aren't counted return search.and_(searches)