| 
				
			 | 
			
			
				@@ -0,0 +1,101 @@ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				1
			 | 
			
			
				+#!/usr/bin/env python 
			 | 
		
	
		
			
			| 
				
			 | 
			
				2
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				3
			 | 
			
			
				+''' 
			 | 
		
	
		
			
			| 
				
			 | 
			
				4
			 | 
			
			
				+searx is free software: you can redistribute it and/or modify 
			 | 
		
	
		
			
			| 
				
			 | 
			
				5
			 | 
			
			
				+it under the terms of the GNU Affero General Public License as published by 
			 | 
		
	
		
			
			| 
				
			 | 
			
				6
			 | 
			
			
				+the Free Software Foundation, either version 3 of the License, or 
			 | 
		
	
		
			
			| 
				
			 | 
			
				7
			 | 
			
			
				+(at your option) any later version. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				8
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				9
			 | 
			
			
				+searx is distributed in the hope that it will be useful, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				10
			 | 
			
			
				+but WITHOUT ANY WARRANTY; without even the implied warranty of 
			 | 
		
	
		
			
			| 
				
			 | 
			
				11
			 | 
			
			
				+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
			 | 
		
	
		
			
			| 
				
			 | 
			
				12
			 | 
			
			
				+GNU Affero General Public License for more details. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				13
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				14
			 | 
			
			
				+You should have received a copy of the GNU Affero General Public License 
			 | 
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				+along with searx. If not, see < http://www.gnu.org/licenses/ >. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				16
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				+(C) 2016- by Alexandre Flament, <alex@al-f.net> 
			 | 
		
	
		
			
			| 
				
			 | 
			
				18
			 | 
			
			
				+''' 
			 | 
		
	
		
			
			| 
				
			 | 
			
				19
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				20
			 | 
			
			
				+# set path 
			 | 
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				+from sys import path 
			 | 
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				+from os.path import realpath, dirname 
			 | 
		
	
		
			
			| 
				
			 | 
			
				23
			 | 
			
			
				+path.append(realpath(dirname(realpath(__file__)) + '/../')) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				+# initialization 
			 | 
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				+from json import dumps 
			 | 
		
	
		
			
			| 
				
			 | 
			
				27
			 | 
			
			
				+from searx import settings 
			 | 
		
	
		
			
			| 
				
			 | 
			
				28
			 | 
			
			
				+import searx.query 
			 | 
		
	
		
			
			| 
				
			 | 
			
				29
			 | 
			
			
				+import searx.search 
			 | 
		
	
		
			
			| 
				
			 | 
			
				30
			 | 
			
			
				+import searx.engines 
			 | 
		
	
		
			
			| 
				
			 | 
			
				31
			 | 
			
			
				+import searx.preferences 
			 | 
		
	
		
			
			| 
				
			 | 
			
				32
			 | 
			
			
				+import argparse 
			 | 
		
	
		
			
			| 
				
			 | 
			
				33
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				+searx.engines.initialize_engines(settings['engines']) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				+# command line parsing 
			 | 
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				+parser = argparse.ArgumentParser(description='Standalone searx.') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				+parser.add_argument('query', type=str, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				39
			 | 
			
			
				+                    help='Text query') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				40
			 | 
			
			
				+parser.add_argument('--category', type=str, nargs='?', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				41
			 | 
			
			
				+                    choices=searx.engines.categories.keys(), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				42
			 | 
			
			
				+                    default='general', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				43
			 | 
			
			
				+                    help='Search category') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				+parser.add_argument('--lang', type=str, nargs='?',default='all', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				+                    help='Search language') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				+parser.add_argument('--pageno', type=int, nargs='?', default=1, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				+                    help='Page number starting from 1') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				+parser.add_argument('--safesearch', type=str, nargs='?', choices=['0', '1', '2'], default='0', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				+                    help='Safe content filter from none to strict') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				+parser.add_argument('--timerange', type=str, nargs='?', choices=['day', 'week', 'month', 'year'], 
			 | 
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				+                    help='Filter by time range') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				+args = parser.parse_args() 
			 | 
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				+# search results for the query 
			 | 
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				+form = { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				+    "q":args.query, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				+    "categories":args.category.decode('utf-8'), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				+    "pageno":str(args.pageno), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				+    "language":args.lang, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				+    "time_range":args.timerange 
			 | 
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				+} 
			 | 
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				+preferences = searx.preferences.Preferences(['oscar'], searx.engines.categories.keys(), searx.engines.engines, []) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				+preferences.key_value_settings['safesearch'].parse(args.safesearch) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				+search_query = searx.search.get_search_query_from_webapp(preferences, form) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				+search = searx.search.Search(search_query) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				+result_container = search.search() 
			 | 
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				+# output 
			 | 
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				+from datetime import datetime 
			 | 
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				+def no_parsed_url(results): 
			 | 
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				+    for result in results: 
			 | 
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				+        del result['parsed_url'] 
			 | 
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				+    return results 
			 | 
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				+def json_serial(obj): 
			 | 
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				+    """JSON serializer for objects not serializable by default json code""" 
			 | 
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				+    if isinstance(obj, datetime): 
			 | 
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				+        serial = obj.isoformat() 
			 | 
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				+        return serial 
			 | 
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				+    raise TypeError ("Type not serializable") 
			 | 
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				+result_container_json = { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				+    "search": { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				+        "q": search_query.query, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				87
			 | 
			
			
				+        "pageno": search_query.pageno, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				+        "lang": search_query.lang, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				89
			 | 
			
			
				+        "safesearch": search_query.safesearch, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				+        "timerange": search_query.time_range, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				+        "engines": search_query.engines   
			 | 
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				+    }, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				+    "results": no_parsed_url(result_container.get_ordered_results()), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				+    "infoboxes": result_container.infoboxes, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				+    "suggestions": list(result_container.suggestions), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				96
			 | 
			
			
				+    "answers": list(result_container.answers), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				+    "paging": result_container.paging, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				+    "results_number": result_container.results_number() 
			 | 
		
	
		
			
			| 
				
			 | 
			
				99
			 | 
			
			
				+} 
			 | 
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				+print(dumps(result_container_json, sort_keys=True, indent=4, ensure_ascii=False, encoding="utf-8", default=json_serial)) 
			 |