From 94870b81926a07b26bc74c70b6c75e9b643ca497 Mon Sep 17 00:00:00 2001 From: Igor Chubin Date: Sun, 17 Feb 2019 14:10:00 +0100 Subject: [PATCH] searching separated into search.py --- lib/routing.py | 51 ++++--------------------------------------- lib/search.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 47 deletions(-) create mode 100644 lib/search.py diff --git a/lib/routing.py b/lib/routing.py index d2028f4..67f1ee9 100644 --- a/lib/routing.py +++ b/lib/routing.py @@ -296,50 +296,7 @@ def get_answer(topic, keyword, options="", request_options=None): # pylint: disa if not keyword: return answer - # shorten the answer, because keyword is specified - # - insensitive = 'i' in options - word_boundaries = 'b' in options - - paragraphs = _split_paragraphs(answer) - paragraphs = [p for p in paragraphs - if _paragraph_contains(p, keyword, - insensitive=insensitive, - word_boundaries=word_boundaries)] - if paragraphs == []: - return "" - - answer = _join_paragraphs(paragraphs) - - return answer - -def find_answer_by_keyword(directory, keyword, options="", request_options=None): - """ - Search in the whole tree of all cheatsheets or in its subtree `directory` - by `keyword` - """ - - recursive = 'r' in options - - answer_paragraphs = [] - for topic in get_topics_list(skip_internal=True, skip_dirs=True): - - if not topic.startswith(directory): - continue - - subtopic = topic[len(directory):] - if not recursive and '/' in subtopic: - continue - - answer = get_answer(topic, keyword, options=options, request_options=request_options) - if answer: - answer_paragraphs.append(answer) - - if len(answer_paragraphs) > MAX_SEARCH_LEN: - answer_paragraphs.append({ - 'topic_type': 'LIMITED', - 'answer': "LIMITED TO %s ANSWERS" % MAX_SEARCH_LEN, - }) - break - - return answer_paragraphs +# pylint: disable=invalid-name +_ROUTER = Router() +get_topics_list = _ROUTER.get_topics_list +get_answer_dict = _ROUTER.get_answer_dict diff --git a/lib/search.py b/lib/search.py new file mode 100644 index 0000000..981596f --- /dev/null +++ b/lib/search.py @@ -0,0 +1,59 @@ +""" +Very naive search implementation. Just a placeholder. + +Exports: + + find_answer_by_keyword() + +It should be implemented on the adapter basis: + + 1. adapter.search(keyword) returns list of matching answers + * maybe with some initial weight + 2. ranking is done + 3. sorted results are returned + 4. eage page are cut by keyword + 5. results are paginated + +""" + +from globals import MAX_SEARCH_LEN +from routing import get_answer_dict, get_topics_list + +def _limited_entry(): + return { + 'topic_type': 'LIMITED', + "topic": "LIMITED", + 'answer': "LIMITED TO %s ANSWERS" % MAX_SEARCH_LEN, + 'format': "code", + } + +def find_answers_by_keyword(directory, keyword, options="", request_options=None): + """ + Search in the whole tree of all cheatsheets or in its subtree `directory` + by `keyword` + """ + + recursive = 'r' in options + + answers_found = [] + for topic in get_topics_list(skip_internal=True, skip_dirs=True): + + if not topic.startswith(directory): + continue + + subtopic = topic[len(directory):] + if not recursive and '/' in subtopic: + continue + + answer = get_answer_dict(topic, request_options=request_options) + + if answer and answer.get('answer') and keyword.lower() in answer.get('answer', '').lower(): + answers_found.append(answer) + + if len(answers_found) > MAX_SEARCH_LEN: + answers_found.append( + _limited_entry() + ) + break + + return answers_found