Skip to content
This repository was archived by the owner on Dec 22, 2023. It is now read-only.

Commit cc98c30

Browse files
committed
Fix all pylint errors and follow PEP Guidelines for naming
1 parent d49f923 commit cc98c30

File tree

7 files changed

+172
-31
lines changed

7 files changed

+172
-31
lines changed
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1+
'''
2+
Configs for the bot
3+
'''
4+
15
# expressions which are banned
26
banned = ['quit', 'input', 'open', 'import', 'exit']
37

48
# timeout in seconds
5-
timeout = 6
9+
TIMEOUT = 6
610

7-
timeout_message = f'😢 Timeout of {timeout} reached. I have limited resources. \nYou may increase the timeout and run this bot on your own server if required.'
11+
timeout_message = f'''😢 Timeout of {TIMEOUT} reached.
12+
I have limited resources.
13+
You may increase the timeout and run this bot on your own server if required.'''
814

915
restricted_message = f'☹️ SECURITY ISSUE:\nYou have used a restricted word \n{banned}'

Scripts/Bots/runPython_bot/bot/execute_code.py

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import logging
55
from subprocess import TimeoutExpired
66
import subprocess
7-
from .config import banned, timeout, timeout_message, restricted_message
87
import multiprocessing
8+
from .config import banned, TIMEOUT, timeout_message, restricted_message
99

1010

1111
def contains_restricted(input_text):
@@ -18,35 +18,42 @@ def contains_restricted(input_text):
1818

1919
def run(update) -> str:
2020
'''
21-
This function takes an Telegram `update` object, passed by the `reply` function in runPython_bot module, and returns the result after executing update.message.text.
21+
This function takes an Telegram `update` object,
22+
passed by the `reply` function in the runPython_bot module,
23+
and returns the result after executing update.message.text.
2224
'''
2325

2426
def execute_py(code):
2527
'''
26-
This function takes a string of python code and executes it in a subprocess of timeout 30s, and returns the standard out and standard error.
28+
This function takes a string of python code
29+
and executes code in a subprocess of timeout 30s,
30+
Returns the standard out and standard error.
2731
28-
Learn more about subprocesses from the official docs of Python
32+
Learn more about subprocesses from the official docs of Python
2933
https://docs.python.org/3/library/subprocess.html
3034
31-
For a shorter intro read this stack overflow answer
35+
For a shorter intro read this stack overflow answer
3236
https://stackoverflow.com/questions/64606880/how-to-get-the-python-interactive-shell-output-of-a-python-code-in-a-variable
3337
'''
3438

3539
proc = subprocess.Popen(['/usr/bin/python3.8', '-c', code],
36-
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
40+
stdin=subprocess.PIPE,
41+
stdout=subprocess.PIPE,
42+
stderr=subprocess.PIPE)
3743
try:
38-
stdout, stderr = proc.communicate(timeout=timeout)
44+
stdout, stderr = proc.communicate(timeout=TIMEOUT)
3945
return stdout.decode('utf-8'), stderr.decode('utf-8')
4046
except TimeoutExpired:
4147
return '', timeout_message
42-
except Exception as e:
43-
return '', f'Problem occured \n{e}'
48+
except Exception as error:
49+
return '', f'Problem occured \n{error}'
4450
finally:
4551
proc.kill()
4652

4753
def func(input_text: str):
4854
'''
49-
This function is a helper function which does some validation job before passing the code to execute_py.
55+
This function is a helper function which does some validation job before passing
56+
the code to execute_py.
5057
'''
5158

5259
if contains_restricted(input_text):
@@ -62,11 +69,10 @@ def func(input_text: str):
6269

6370
out = func(input_text)
6471
return out
65-
else:
66-
return 'update.message.text was None'
67-
except Exception as e:
72+
return 'update.message.text was None'
73+
except Exception as error:
6874
msg = 'Error in handling update.message.text'
69-
logging.log(level=40, msg=msg)
75+
logging.log(level=40, msg=error)
7076
return msg
7177

7278

@@ -80,24 +86,25 @@ def evaluate(input_text, return_val):
8086
'''wrapper for eval'''
8187
try:
8288
return_val[input_text] = str(eval(input_text))
83-
except Exception as e:
89+
except Exception as error:
8490
return_val[
85-
input_text] = f'''😔 /e feeds your expression to python's eval function, and the following error occured: \n\n{e}'''
91+
input_text] = f'''😔 /e feeds your expression to python's eval function.
92+
The following error occured: \n\n{error}'''
8693

8794
if contains_restricted(input_text):
8895
return restricted_message
8996

9097
# using multiprocessing and getting value returned by target function
91-
m = multiprocessing.Manager()
92-
return_val = m.dict() # enable target function to return a value
93-
94-
p = multiprocessing.Process(target=evaluate, args=(input_text, return_val))
95-
p.start()
96-
p.join(6) # allow the process to run for 6 seconds
97-
if p.is_alive():
98+
manger = multiprocessing.Manager()
99+
return_val = manger.dict() # enable target function to return a value
100+
101+
process = multiprocessing.Process(
102+
target=evaluate, args=(input_text, return_val))
103+
process.start()
104+
process.join(6) # allow the process to run for 6 seconds
105+
if process.is_alive():
98106
# kill the process if it is still alive
99-
p.kill()
107+
process.kill()
100108
return timeout_message
101-
else:
102-
output = return_val[input_text]
103-
return output
109+
output = return_val[input_text]
110+
return output
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
'''
2+
This module makes the bot actually run
3+
'''
4+
5+
from telegram.ext import CommandHandler, MessageHandler, Filters, Updater
6+
# python-telegram-bot is a Pythonic Wrapper to the core Telegram API
7+
# it helps us to be DRY by giving us convinient wrapper functions to deal with Telegram API
8+
# you can install it by pip install python-telegram-bot --upgrade
9+
# learn more about it here https://github.com/python-telegram-bot/python-telegram-bot
10+
11+
12+
from .execute_code import eval_py, run
13+
14+
# read the token for authenticating our bot
15+
with open('token.txt') as f:
16+
tok = f.readline().strip()
17+
18+
with open('docs/start.txt') as f:
19+
start_text = f.read()
20+
21+
with open('docs/help.txt') as f:
22+
help_text = f.read()
23+
24+
with open('docs/code.txt') as f:
25+
code_text = f.read()
26+
27+
28+
def handle_long_message(msg):
29+
'''Telegram does not support messages over 4096 characters.
30+
This handler handles all messages above 2000 characters
31+
'''
32+
33+
if msg:
34+
if len(msg) > 2000:
35+
return msg[:2000]+'\n\n 😟 Output was too long, truncated to 2000 characters'
36+
return msg
37+
return 'handle_long_message recieved an empty message'
38+
39+
40+
def bot():
41+
'''
42+
Running this function runs the bot
43+
You may learn more from this tutorial
44+
https://github.com/python-telegram-bot/python-telegram-bot/wiki/Extensions-%E2%80%93-Your-first-Bot
45+
'''
46+
47+
updater = Updater(token=tok)
48+
49+
dispatcher = updater.dispatcher
50+
51+
def start(update, context):
52+
'''This fuction replies to the start command'''
53+
54+
context.bot.send_message(
55+
chat_id=update.effective_chat.id, text=start_text, parse_mode='Markdown')
56+
# for more info on parse modes
57+
# see https://python-telegram-bot.readthedocs.io/en/stable/telegram.parsemode.html
58+
59+
def bot_help(update, context):
60+
'''This function replies to the help command'''
61+
context.bot.send_message(
62+
chat_id=update.effective_chat.id, text=help_text, parse_mode='Markdown')
63+
64+
def code_info(update, context):
65+
'''This function replies to the code command.'''
66+
context.bot.send_message(
67+
chat_id=update.effective_chat.id, text=code_text, parse_mode='Markdown')
68+
69+
def reply_execute(update, context):
70+
'''
71+
This function replies to any non-command messages.
72+
'''
73+
input_text = str(update.message.text)
74+
# allowing usage of /e at the end of expressions
75+
76+
if input_text == 'hi':
77+
user = update.message.from_user
78+
context.bot.send_message(chat_id=update.effective_chat.id,
79+
text=f'Hi! {user["username"]} 🥰')
80+
81+
if input_text.endswith('/e'):
82+
message = handle_long_message(eval_py(input_text.strip('/e')))
83+
update.message.reply_text(message, quote=True)
84+
else:
85+
returned_val = run(update)
86+
if not returned_val:
87+
update.message.reply_text(
88+
'''*No output. No error.*
89+
\n> Try using a `print` statement.
90+
\n > To evaluate an expression use the /e command.''',
91+
quote=True, parse_mode='Markdown')
92+
else:
93+
message = handle_long_message(returned_val)
94+
update.message.reply_text(message, quote=True)
95+
96+
def reply_eval(update, context):
97+
''' This function handles the /e command'''
98+
if context.args:
99+
input_text = ''
100+
for string in context.args:
101+
input_text += string + ' '
102+
out = eval_py(input_text)
103+
message = handle_long_message(out)
104+
update.message.reply_text(message, quote=True)
105+
else:
106+
update.message.reply_text(
107+
'''*No expression provided to eval*.
108+
\nUse command /e before or after your expression like
109+
\n/e `4 >= 5` \n \t or \n`4 >= 5` /e ''', quote=True, parse_mode='Markdown')
110+
111+
_handlers = {}
112+
113+
_handlers['start_handler'] = CommandHandler('start', start)
114+
_handlers['help_handler'] = CommandHandler('help', bot_help)
115+
_handlers['code_info_handler'] = CommandHandler('code', code_info)
116+
_handlers['message_handler'] = MessageHandler(
117+
Filters.text & (~Filters.command), reply_execute)
118+
_handlers['eval_handler'] = CommandHandler('e', reply_eval)
119+
120+
for name, _handler in _handlers.items():
121+
print(f'Adding {name}')
122+
dispatcher.add_handler(_handler)
123+
124+
updater.start_polling()
125+
updater.idle()
126+
# Search google to know what is polling...
127+
# i came to know while building this project
128+
# this can be stopped by interrupting the terminal by `Ctrl+C`
-7.31 KB
Loading
-15.8 KB
Loading
-86.6 KB
Loading

Scripts/Bots/runPython_bot/start.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from bot import runPython_bot
1+
from bot import run_python_bot
22
import logging
33
from pytz import timezone
44
from datetime import datetime
@@ -14,4 +14,4 @@
1414
logger = logging.getLogger()
1515
logger.setLevel(20)
1616

17-
runPython_bot.bot()
17+
run_python_bot.bot()

0 commit comments

Comments
 (0)