.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.plugins.calculator Namespace Reference

Functions

 _eval_expr (expr)
 
 _eval (node)
 
 timeout_func (timeout, func, *args, **kwargs)
 
 post_search (_request, search)
 

Variables

str name = "Basic Calculator"
 
 description = gettext("Calculate mathematical expressions via the search bar")
 
bool default_on = True
 
str preference_section = 'general'
 
str plugin_id = 'calculator'
 
 logger = logger.getChild(plugin_id)
 
dict operators
 

Detailed Description

Calculate mathematical expressions using ack#eval

Function Documentation

◆ _eval()

searx.plugins.calculator._eval ( node)
protected

Definition at line 53 of file calculator.py.

53def _eval(node):
54 if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
55 return node.value
56
57 if isinstance(node, ast.BinOp):
58 return operators[type(node.op)](_eval(node.left), _eval(node.right))
59
60 if isinstance(node, ast.UnaryOp):
61 return operators[type(node.op)](_eval(node.operand))
62
63 raise TypeError(node)
64
65

References searx.plugins.calculator._eval().

Referenced by searx.plugins.calculator._eval(), and searx.plugins.calculator._eval_expr().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _eval_expr()

searx.plugins.calculator._eval_expr ( expr)
protected
>>> _eval_expr('2^6')
4
>>> _eval_expr('2**6')
64
>>> _eval_expr('1 + 2*3**(4^5) / (6 + -7)')
-5.0

Definition at line 37 of file calculator.py.

37def _eval_expr(expr):
38 """
39 >>> _eval_expr('2^6')
40 4
41 >>> _eval_expr('2**6')
42 64
43 >>> _eval_expr('1 + 2*3**(4^5) / (6 + -7)')
44 -5.0
45 """
46 try:
47 return _eval(ast.parse(expr, mode='eval').body)
48 except ZeroDivisionError:
49 # This is undefined
50 return ""
51
52

References searx.plugins.calculator._eval().

+ Here is the call graph for this function:

◆ post_search()

searx.plugins.calculator.post_search ( _request,
search )

Definition at line 90 of file calculator.py.

90def post_search(_request, search):
91
92 # only show the result of the expression on the first page
93 if search.search_query.pageno > 1:
94 return True
95
96 query = search.search_query.query
97 # in order to avoid DoS attacks with long expressions, ignore long expressions
98 if len(query) > 100:
99 return True
100
101 # replace commonly used math operators with their proper Python operator
102 query = query.replace("x", "*").replace(":", "/")
103
104 # use UI language
105 ui_locale = babel.Locale.parse(flask.request.preferences.get_value('locale'), sep='-')
106
107 # parse the number system in a localized way
108 def _decimal(match: re.Match) -> str:
109 val = match.string[match.start() : match.end()]
110 val = babel.numbers.parse_decimal(val, ui_locale, numbering_system="latn")
111 return str(val)
112
113 decimal = ui_locale.number_symbols["latn"]["decimal"]
114 group = ui_locale.number_symbols["latn"]["group"]
115 query = re.sub(f"[0-9]+[{decimal}|{group}][0-9]+[{decimal}|{group}]?[0-9]?", _decimal, query)
116
117 # only numbers and math operators are accepted
118 if any(str.isalpha(c) for c in query):
119 return True
120
121 # in python, powers are calculated via **
122 query_py_formatted = query.replace("^", "**")
123
124 # Prevent the runtime from being longer than 50 ms
125 result = timeout_func(0.05, _eval_expr, query_py_formatted)
126 if result is None or result == "":
127 return True
128 result = babel.numbers.format_decimal(result, locale=ui_locale)
129 search.result_container.answers['calculate'] = {'answer': f"{search.search_query.query} = {result}"}
130 return True

References searx.plugins.calculator.timeout_func().

+ Here is the call graph for this function:

◆ timeout_func()

searx.plugins.calculator.timeout_func ( timeout,
func,
* args,
** kwargs )

Definition at line 66 of file calculator.py.

66def timeout_func(timeout, func, *args, **kwargs):
67
68 def handler(q: Queue, func, args, **kwargs): # pylint:disable=invalid-name
69 try:
70 q.put(func(*args, **kwargs))
71 except:
72 q.put(None)
73 raise
74
75 que = Queue()
76 p = Process(target=handler, args=(que, func, args), kwargs=kwargs)
77 p.start()
78 p.join(timeout=timeout)
79 ret_val = None
80 if not p.is_alive():
81 ret_val = que.get()
82 else:
83 logger.debug("terminate function after timeout is exceeded")
84 p.terminate()
85 p.join()
86 p.close()
87 return ret_val
88
89

Referenced by searx.plugins.calculator.post_search().

+ Here is the caller graph for this function:

Variable Documentation

◆ default_on

bool searx.plugins.calculator.default_on = True

Definition at line 19 of file calculator.py.

◆ description

searx.plugins.calculator.description = gettext("Calculate mathematical expressions via the search bar")

Definition at line 18 of file calculator.py.

◆ logger

searx.plugins.calculator.logger = logger.getChild(plugin_id)

Definition at line 24 of file calculator.py.

◆ name

str searx.plugins.calculator.name = "Basic Calculator"

Definition at line 17 of file calculator.py.

◆ operators

dict searx.plugins.calculator.operators
Initial value:
1= {
2 ast.Add: operator.add,
3 ast.Sub: operator.sub,
4 ast.Mult: operator.mul,
5 ast.Div: operator.truediv,
6 ast.Pow: operator.pow,
7 ast.BitXor: operator.xor,
8 ast.USub: operator.neg,
9}

Definition at line 26 of file calculator.py.

◆ plugin_id

str searx.plugins.calculator.plugin_id = 'calculator'

Definition at line 22 of file calculator.py.

◆ preference_section

str searx.plugins.calculator.preference_section = 'general'

Definition at line 21 of file calculator.py.