915b34391c
* chore: Added isort to pre-commit config * chore: Sort imports with isort * chore: Clean up imports with pycln * chore: Sort imports with isort * chore: Fix import issues * chore: Clean up sider issues * chore: Remove import errors from flake8 ignore list * chore: Clean up lint issues
106 lines
2.6 KiB
Python
106 lines
2.6 KiB
Python
from __future__ import unicode_literals
|
|
|
|
import frappe
|
|
import requests
|
|
from frappe import _
|
|
from frappe.utils import sanitize_html
|
|
from frappe.utils.global_search import search
|
|
from html2text import html2text
|
|
from jinja2 import utils
|
|
from six import text_type
|
|
|
|
|
|
def get_context(context):
|
|
context.no_cache = 1
|
|
if frappe.form_dict.q:
|
|
query = str(utils.escape(sanitize_html(frappe.form_dict.q)))
|
|
context.title = _('Help Results for')
|
|
context.query = query
|
|
|
|
context.route = '/search_help'
|
|
d = frappe._dict()
|
|
d.results_sections = get_help_results_sections(query)
|
|
context.update(d)
|
|
else:
|
|
context.title = _('Docs Search')
|
|
|
|
@frappe.whitelist(allow_guest = True)
|
|
def get_help_results_sections(text):
|
|
out = []
|
|
settings = frappe.get_doc("Support Settings", "Support Settings")
|
|
|
|
for api in settings.search_apis:
|
|
results = []
|
|
if api.source_type == "API":
|
|
response_json = get_response(api, text)
|
|
topics_data = get_topics_data(api, response_json)
|
|
results = prepare_api_results(api, topics_data)
|
|
else:
|
|
# Source type is Doctype
|
|
doctype = api.source_doctype
|
|
raw = search(text, 0, 20, doctype)
|
|
results = prepare_doctype_results(api, raw)
|
|
|
|
if results:
|
|
# Add section
|
|
out.append({
|
|
"title": api.source_name,
|
|
"results": results
|
|
})
|
|
|
|
return out
|
|
|
|
def get_response(api, text):
|
|
response = requests.get(api.base_url + '/' + api.query_route, data={
|
|
api.search_term_param_name: text
|
|
})
|
|
|
|
response.raise_for_status()
|
|
return response.json()
|
|
|
|
def get_topics_data(api, response_json):
|
|
if not response_json:
|
|
response_json = {}
|
|
topics_data = {} # it will actually be an array
|
|
key_list = api.response_result_key_path.split(',')
|
|
|
|
for key in key_list:
|
|
topics_data = response_json.get(key) if not topics_data else topics_data.get(key)
|
|
|
|
return topics_data or []
|
|
|
|
def prepare_api_results(api, topics_data):
|
|
if not topics_data:
|
|
topics_data = []
|
|
|
|
results = []
|
|
for topic in topics_data:
|
|
route = api.base_url + '/' + (api.post_route + '/' if api.post_route else "")
|
|
for key in api.post_route_key_list.split(','):
|
|
route += text_type(topic[key])
|
|
|
|
results.append(frappe._dict({
|
|
'title': topic[api.post_title_key],
|
|
'preview': html2text(topic[api.post_description_key]),
|
|
'route': route
|
|
}))
|
|
return results[:5]
|
|
|
|
def prepare_doctype_results(api, raw):
|
|
results = []
|
|
for r in raw:
|
|
prepared_result = {}
|
|
parts = r["content"].split(' ||| ')
|
|
|
|
for part in parts:
|
|
pair = part.split(' : ', 1)
|
|
prepared_result[pair[0]] = pair[1]
|
|
|
|
results.append(frappe._dict({
|
|
'title': prepared_result[api.result_title_field],
|
|
'preview': prepared_result[api.result_preview_field],
|
|
'route': prepared_result[api.result_route_field]
|
|
}))
|
|
|
|
return results
|