103 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from __future__ import unicode_literals
 | |
| import frappe, requests
 | |
| from frappe import _
 | |
| from jinja2 import utils
 | |
| from html2text import html2text
 | |
| from six import text_type
 | |
| from frappe.utils import sanitize_html
 | |
| from frappe.utils.global_search import search
 | |
| 
 | |
| 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
 |