blob: 1ef3942cbc918eb1b453ed977a9a81de5606df20 [file] [log] [blame]
Chillar Anand915b3432021-09-02 16:44:59 +05301import frappe
2import requests
Prateeksha Singhb44ea4c2018-05-22 11:57:21 +05303from frappe import _
Prateeksha Singhb44ea4c2018-05-22 11:57:21 +05304from frappe.utils import sanitize_html
5from frappe.utils.global_search import search
Chillar Anand915b3432021-09-02 16:44:59 +05306from html2text import html2text
7from jinja2 import utils
Chillar Anand915b3432021-09-02 16:44:59 +05308
Prateeksha Singhb44ea4c2018-05-22 11:57:21 +05309
10def get_context(context):
11 context.no_cache = 1
12 if frappe.form_dict.q:
13 query = str(utils.escape(sanitize_html(frappe.form_dict.q)))
Prateeksha Singh0c796222018-08-06 12:33:34 +053014 context.title = _('Help Results for')
15 context.query = query
Aditya Hase691c1662019-02-07 20:35:52 +053016
Prateeksha Singhb44ea4c2018-05-22 11:57:21 +053017 context.route = '/search_help'
18 d = frappe._dict()
19 d.results_sections = get_help_results_sections(query)
20 context.update(d)
21 else:
22 context.title = _('Docs Search')
23
24@frappe.whitelist(allow_guest = True)
25def get_help_results_sections(text):
26 out = []
27 settings = frappe.get_doc("Support Settings", "Support Settings")
28
29 for api in settings.search_apis:
30 results = []
31 if api.source_type == "API":
32 response_json = get_response(api, text)
33 topics_data = get_topics_data(api, response_json)
34 results = prepare_api_results(api, topics_data)
35 else:
36 # Source type is Doctype
37 doctype = api.source_doctype
38 raw = search(text, 0, 20, doctype)
39 results = prepare_doctype_results(api, raw)
40
41 if results:
42 # Add section
43 out.append({
44 "title": api.source_name,
45 "results": results
46 })
47
48 return out
49
50def get_response(api, text):
51 response = requests.get(api.base_url + '/' + api.query_route, data={
52 api.search_term_param_name: text
53 })
54
55 response.raise_for_status()
56 return response.json()
57
58def get_topics_data(api, response_json):
59 if not response_json:
60 response_json = {}
61 topics_data = {} # it will actually be an array
62 key_list = api.response_result_key_path.split(',')
63
64 for key in key_list:
65 topics_data = response_json.get(key) if not topics_data else topics_data.get(key)
66
67 return topics_data or []
68
69def prepare_api_results(api, topics_data):
70 if not topics_data:
71 topics_data = []
72
73 results = []
74 for topic in topics_data:
75 route = api.base_url + '/' + (api.post_route + '/' if api.post_route else "")
76 for key in api.post_route_key_list.split(','):
Ankush Menat8fe5feb2021-11-04 19:48:32 +053077 route += str(topic[key])
Prateeksha Singhb44ea4c2018-05-22 11:57:21 +053078
79 results.append(frappe._dict({
80 'title': topic[api.post_title_key],
81 'preview': html2text(topic[api.post_description_key]),
82 'route': route
83 }))
84 return results[:5]
85
86def prepare_doctype_results(api, raw):
87 results = []
88 for r in raw:
89 prepared_result = {}
90 parts = r["content"].split(' ||| ')
91
92 for part in parts:
93 pair = part.split(' : ', 1)
94 prepared_result[pair[0]] = pair[1]
95
96 results.append(frappe._dict({
97 'title': prepared_result[api.result_title_field],
98 'preview': prepared_result[api.result_preview_field],
99 'route': prepared_result[api.result_route_field]
100 }))
101
102 return results