Use Global elements container

pull/178/head
J-Rios 2022-12-29 14:01:21 +01:00
rodzic 78df061f59
commit d021e1b064
Nie znaleziono w bazie danych klucza dla tego podpisu
1 zmienionych plików z 191 dodań i 174 usunięć

Wyświetl plik

@ -129,14 +129,22 @@ logger = logging.getLogger(__name__)
############################################################################### ###############################################################################
### Globals ### Globals
updater = None class Globals():
files_config_list = [] '''Global Elements Container.'''
to_delete_in_time_messages_list = [] updater = None
new_users = {} files_config_list = []
connections = {} to_delete_in_time_messages_list = []
th_0 = None new_users = {}
th_1 = None connections = {}
force_exit = False th_0 = None
th_1 = None
force_exit = False
###############################################################################
### Objects Instantiation
# Global Data Elements
Global = Globals()
# Create Captcha Generator object of specified size (2 -> 640x360) # Create Captcha Generator object of specified size (2 -> 640x360)
CaptchaGen = CaptchaGenerator(2) CaptchaGen = CaptchaGenerator(2)
@ -226,8 +234,8 @@ def get_chat_config_file(chat_id):
''' '''
file = OrderedDict([("ID", chat_id), ("File", None)]) file = OrderedDict([("ID", chat_id), ("File", None)])
found = False found = False
if files_config_list: if Global.files_config_list:
for chat_file in files_config_list: for chat_file in Global.files_config_list:
if chat_file["ID"] == chat_id: if chat_file["ID"] == chat_id:
file = chat_file file = chat_file
found = True found = True
@ -237,13 +245,13 @@ def get_chat_config_file(chat_id):
f'{CONST["CHATS_DIR"]}/{chat_id}/{CONST["F_CONF"]}' f'{CONST["CHATS_DIR"]}/{chat_id}/{CONST["F_CONF"]}'
file["ID"] = chat_id file["ID"] = chat_id
file["File"] = TSjson(chat_config_file_name) file["File"] = TSjson(chat_config_file_name)
files_config_list.append(file) Global.files_config_list.append(file)
else: else:
chat_config_file_name = \ chat_config_file_name = \
f'{CONST["CHATS_DIR"]}/{chat_id}/{CONST["F_CONF"]}' f'{CONST["CHATS_DIR"]}/{chat_id}/{CONST["F_CONF"]}'
file["ID"] = chat_id file["ID"] = chat_id
file["File"] = TSjson(chat_config_file_name) file["File"] = TSjson(chat_config_file_name)
files_config_list.append(file) Global.files_config_list.append(file)
return file["File"] return file["File"]
############################################################################### ###############################################################################
@ -320,7 +328,7 @@ def tlg_msg_to_selfdestruct_in(message, time_delete_sec):
sent_msg_data["Msg_id"] = msg_id sent_msg_data["Msg_id"] = msg_id
sent_msg_data["time"] = _t0 sent_msg_data["time"] = _t0
sent_msg_data["delete_time"] = time_delete_sec sent_msg_data["delete_time"] = time_delete_sec
to_delete_in_time_messages_list.append(sent_msg_data) Global.to_delete_in_time_messages_list.append(sent_msg_data)
return True return True
############################################################################### ###############################################################################
@ -332,9 +340,10 @@ def save_session():
''' '''
# Let's backup to file # Let's backup to file
data = { data = {
"to_delete_in_time_messages_list": to_delete_in_time_messages_list, "to_delete_in_time_messages_list": \
"new_users": new_users, Global.to_delete_in_time_messages_list,
"connections": connections "new_users": Global.new_users,
"connections": Global.connections
} }
if not pickle_save(CONST["F_SESSION"], data): if not pickle_save(CONST["F_SESSION"], data):
logger.error("Fail to save current session data") logger.error("Fail to save current session data")
@ -347,9 +356,6 @@ def restore_session():
''' '''
Load last execution data. Load last execution data.
''' '''
global to_delete_in_time_messages_list
global new_users
global connections
# Check if session file exists # Check if session file exists
if not file_exists(CONST["F_SESSION"]): if not file_exists(CONST["F_SESSION"]):
return False return False
@ -359,22 +365,22 @@ def restore_session():
logger.error("Fail to restore last session data") logger.error("Fail to restore last session data")
return False return False
# Load last session data to current RAM # Load last session data to current RAM
connections = last_session_data["connections"] Global.connections = last_session_data["connections"]
new_users = last_session_data["new_users"] Global.new_users = last_session_data["new_users"]
to_delete_in_time_messages_list = \ Global.to_delete_in_time_messages_list = \
last_session_data["to_delete_in_time_messages_list"] last_session_data["to_delete_in_time_messages_list"]
# Renew time to kick users # Renew time to kick users
for chat_id in new_users: for chat_id in Global.new_users:
for user_id in new_users[chat_id]: for user_id in Global.new_users[chat_id]:
# Some rand to avoid all requests sent at same time # Some rand to avoid all requests sent at same time
_t0 = time() + randint(0, 10) _t0 = time() + randint(0, 10)
new_users[chat_id][user_id]["join_data"]["join_time"] = _t0 Global.new_users[chat_id][user_id]["join_data"]["join_time"] = _t0
# Renew time to remove messages # Renew time to remove messages
i = 0 i = 0
while i < len(to_delete_in_time_messages_list): while i < len(Global.to_delete_in_time_messages_list):
# Some rand to avoid all requests sent at same time # Some rand to avoid all requests sent at same time
_t0 = time() + randint(0, 10) _t0 = time() + randint(0, 10)
to_delete_in_time_messages_list[i]["time"] = _t0 Global.to_delete_in_time_messages_list[i]["time"] = _t0
i = i + 1 i = i + 1
logger.info("Last session data restored") logger.info("Last session data restored")
return True return True
@ -408,8 +414,9 @@ def initialize_resources():
for f_chat_id in files: for f_chat_id in files:
# Populate config files list # Populate config files list
file_path = f'{CONST["CHATS_DIR"]}/{f_chat_id}/{CONST["F_CONF"]}' file_path = f'{CONST["CHATS_DIR"]}/{f_chat_id}/{CONST["F_CONF"]}'
files_config_list.append(OrderedDict([("ID", f_chat_id), Global.files_config_list.append(
("File", TSjson(file_path))])) OrderedDict(
[("ID", f_chat_id), ("File", TSjson(file_path))]))
# Create default configuration file if it does not exists # Create default configuration file if it does not exists
if not path.exists(file_path): if not path.exists(file_path):
default_conf = get_default_config_data() default_conf = get_default_config_data()
@ -696,8 +703,9 @@ def captcha_fail_kick_ban_member(bot, chat_id, user_id, max_join_retries):
# Get parameters # Get parameters
lang = get_chat_config(chat_id, "Language") lang = get_chat_config(chat_id, "Language")
rm_result_msg = get_chat_config(chat_id, "Rm_Result_Msg") rm_result_msg = get_chat_config(chat_id, "Rm_Result_Msg")
user_name = new_users[chat_id][user_id]["join_data"]["user_name"] user_name = Global.new_users[chat_id][user_id]["join_data"]["user_name"]
join_retries = new_users[chat_id][user_id]["join_data"]["join_retries"] join_retries = \
Global.new_users[chat_id][user_id]["join_data"]["join_retries"]
logger.info("[%s] %s join_retries: %d", chat_id, user_id, join_retries) logger.info("[%s] %s join_retries: %d", chat_id, user_id, join_retries)
# Kick if user has fail to solve the captcha less than # Kick if user has fail to solve the captcha less than
# "max_join_retries" # "max_join_retries"
@ -779,22 +787,23 @@ def captcha_fail_kick_ban_member(bot, chat_id, user_id, max_join_retries):
else: else:
tlg_send_msg(bot, chat_id, msg_text) tlg_send_msg(bot, chat_id, msg_text)
# Update user info (join_retries & kick_ban) # Update user info (join_retries & kick_ban)
new_users[chat_id][user_id]["join_data"]["kicked_ban"] = True Global.new_users[chat_id][user_id]["join_data"]["kicked_ban"] = True
new_users[chat_id][user_id]["join_data"]["join_retries"] = join_retries Global.new_users[chat_id][user_id]["join_data"]["join_retries"] = \
join_retries
# Remove join messages # Remove join messages
logger.info("[%s] Removing messages from user %s...", chat_id, user_name) logger.info("[%s] Removing messages from user %s...", chat_id, user_name)
join_msg = new_users[chat_id][user_id]["join_msg"] join_msg = Global.new_users[chat_id][user_id]["join_msg"]
if join_msg is not None: if join_msg is not None:
tlg_delete_msg(bot, chat_id, join_msg) tlg_delete_msg(bot, chat_id, join_msg)
for msg in new_users[chat_id][user_id]["msg_to_rm"]: for msg in Global.new_users[chat_id][user_id]["msg_to_rm"]:
tlg_delete_msg(bot, chat_id, msg) tlg_delete_msg(bot, chat_id, msg)
new_users[chat_id][user_id]["msg_to_rm"].clear() Global.new_users[chat_id][user_id]["msg_to_rm"].clear()
for msg in new_users[chat_id][user_id]["msg_to_rm_on_kick"]: for msg in Global.new_users[chat_id][user_id]["msg_to_rm_on_kick"]:
tlg_delete_msg(bot, chat_id, msg) tlg_delete_msg(bot, chat_id, msg)
new_users[chat_id][user_id]["msg_to_rm_on_kick"].clear() Global.new_users[chat_id][user_id]["msg_to_rm_on_kick"].clear()
# Delete user join info if ban was success # Delete user join info if ban was success
if banned: if banned:
del new_users[chat_id][user_id] del Global.new_users[chat_id][user_id]
logger.info("[%s] Kick/Ban process completed", chat_id) logger.info("[%s] Kick/Ban process completed", chat_id)
logger.info("") logger.info("")
@ -911,12 +920,12 @@ def chat_member_status_change(update: Update, context: CallbackContext):
if not should_manage_captcha(update, bot): if not should_manage_captcha(update, bot):
return return
# Check and remove previous join messages of that user (if any) # Check and remove previous join messages of that user (if any)
if chat_id in new_users: if chat_id in Global.new_users:
if join_user_id in new_users[chat_id]: if join_user_id in Global.new_users[chat_id]:
if "msg_to_rm" in new_users[chat_id][join_user_id]: if "msg_to_rm" in Global.new_users[chat_id][join_user_id]:
for msg in new_users[chat_id][join_user_id]["msg_to_rm"]: for msg in Global.new_users[chat_id][join_user_id]["msg_to_rm"]:
tlg_delete_msg(bot, chat_id, msg) tlg_delete_msg(bot, chat_id, msg)
new_users[chat_id][join_user_id]["msg_to_rm"].clear() Global.new_users[chat_id][join_user_id]["msg_to_rm"].clear()
# Ignore if the captcha protection is not enable in this chat # Ignore if the captcha protection is not enable in this chat
captcha_enable = get_chat_config(chat_id, "Enabled") captcha_enable = get_chat_config(chat_id, "Enabled")
if not captcha_enable: if not captcha_enable:
@ -1061,34 +1070,35 @@ def chat_member_status_change(update: Update, context: CallbackContext):
"kicked_ban": False "kicked_ban": False
} }
# Create dict keys for new user # Create dict keys for new user
if chat_id not in new_users: if chat_id not in Global.new_users:
new_users[chat_id] = {} Global.new_users[chat_id] = {}
if join_user_id not in new_users[chat_id]: if join_user_id not in Global.new_users[chat_id]:
new_users[chat_id][join_user_id] = {} Global.new_users[chat_id][join_user_id] = {}
if "join_data" not in new_users[chat_id][join_user_id]: if "join_data" not in Global.new_users[chat_id][join_user_id]:
new_users[chat_id][join_user_id]["join_data"] = {} Global.new_users[chat_id][join_user_id]["join_data"] = {}
if "join_msg" not in new_users[chat_id][join_user_id]: if "join_msg" not in Global.new_users[chat_id][join_user_id]:
new_users[chat_id][join_user_id]["join_msg"] = None Global.new_users[chat_id][join_user_id]["join_msg"] = None
if "msg_to_rm" not in new_users[chat_id][join_user_id]: if "msg_to_rm" not in Global.new_users[chat_id][join_user_id]:
new_users[chat_id][join_user_id]["msg_to_rm"] = [] Global.new_users[chat_id][join_user_id]["msg_to_rm"] = []
if "msg_to_rm_on_kick" not in new_users[chat_id][join_user_id]: if "msg_to_rm_on_kick" not in Global.new_users[chat_id][join_user_id]:
new_users[chat_id][join_user_id]["msg_to_rm_on_kick"] = [] Global.new_users[chat_id][join_user_id]["msg_to_rm_on_kick"] = []
# Check if this user was before in the chat without solve the # Check if this user was before in the chat without solve the
# captcha and restore previous join_retries # captcha and restore previous join_retries
if len(new_users[chat_id][join_user_id]["join_data"]) != 0: if len(Global.new_users[chat_id][join_user_id]["join_data"]) != 0:
user_join_data = new_users[chat_id][join_user_id]["join_data"] user_join_data = \
Global.new_users[chat_id][join_user_id]["join_data"]
join_data["join_retries"] = user_join_data["join_retries"] join_data["join_retries"] = user_join_data["join_retries"]
# Add new user join data and messages to be removed # Add new user join data and messages to be removed
new_users[chat_id][join_user_id]["join_data"] = join_data Global.new_users[chat_id][join_user_id]["join_data"] = join_data
if update.message: if update.message:
new_users[chat_id][join_user_id]["join_msg"] = \ Global.new_users[chat_id][join_user_id]["join_msg"] = \
update.message.message_id update.message.message_id
if sent_result["msg"]: if sent_result["msg"]:
new_users[chat_id][join_user_id]["msg_to_rm"].append( Global.new_users[chat_id][join_user_id]["msg_to_rm"].append(
sent_result["msg"].message_id) sent_result["msg"].message_id)
if (captcha_mode == "poll") \ if (captcha_mode == "poll") \
and (solve_poll_request_msg_id is not None): and (solve_poll_request_msg_id is not None):
new_users[chat_id][join_user_id]["msg_to_rm"].append( Global.new_users[chat_id][join_user_id]["msg_to_rm"].append(
solve_poll_request_msg_id) solve_poll_request_msg_id)
# Restrict user to deny send any kind of message until captcha # Restrict user to deny send any kind of message until captcha
# is solve. Allow send text messages for image based captchas # is solve. Allow send text messages for image based captchas
@ -1134,14 +1144,14 @@ def msg_user_joined_group(update: Update, context: CallbackContext):
# For each new user that join or has been added # For each new user that join or has been added
for join_user in new_chat_members: for join_user in new_chat_members:
# Ignore if the chat is not expected # Ignore if the chat is not expected
if chat_id not in new_users: if chat_id not in Global.new_users:
continue continue
# Ignore if user is not expected # Ignore if user is not expected
if join_user.id not in new_users[chat_id]: if join_user.id not in Global.new_users[chat_id]:
continue continue
# If user has join the group, add the "USER joined the group" # If user has join the group, add the "USER joined the group"
# message ID to new user data to be removed # message ID to new user data to be removed
new_users[chat_id][join_user.id]["join_msg"] = msg_id Global.new_users[chat_id][join_user.id]["join_msg"] = msg_id
def msg_notext(update: Update, context: CallbackContext): def msg_notext(update: Update, context: CallbackContext):
@ -1177,9 +1187,9 @@ def msg_notext(update: Update, context: CallbackContext):
return return
# Ignore if msg not from a new user that needs to solve the captcha # Ignore if msg not from a new user that needs to solve the captcha
user_id = update_msg.from_user.id user_id = update_msg.from_user.id
if chat_id not in new_users: if chat_id not in Global.new_users:
return return
if user_id not in new_users[chat_id]: if user_id not in Global.new_users[chat_id]:
return return
# Get username, if has an alias, just use the alias # Get username, if has an alias, just use the alias
user_name = update_msg.from_user.full_name user_name = update_msg.from_user.full_name
@ -1289,14 +1299,15 @@ def msg_nocmd(update: Update, context: CallbackContext):
topic_id=topic_id) topic_id=topic_id)
# Ignore if message is not from a new user that has not completed # Ignore if message is not from a new user that has not completed
# the captcha yet # the captcha yet
if chat_id not in new_users: if chat_id not in Global.new_users:
return return
if user_id not in new_users[chat_id]: if user_id not in Global.new_users[chat_id]:
return return
# Get Chat settings # Get Chat settings
lang = get_chat_config(chat_id, "Language") lang = get_chat_config(chat_id, "Language")
rm_result_msg = get_chat_config(chat_id, "Rm_Result_Msg") rm_result_msg = get_chat_config(chat_id, "Rm_Result_Msg")
captcha_mode = new_users[chat_id][user_id]["join_data"]["captcha_mode"] captcha_mode = \
Global.new_users[chat_id][user_id]["join_data"]["captcha_mode"]
# Check for forwarded messages and delete it # Check for forwarded messages and delete it
forward_from = getattr(update_msg, "forward_from", None) forward_from = getattr(update_msg, "forward_from", None)
forward_from_chat = getattr(update_msg, "forward_from_chat", None) forward_from_chat = getattr(update_msg, "forward_from_chat", None)
@ -1336,7 +1347,7 @@ def msg_nocmd(update: Update, context: CallbackContext):
# removed when kick # removed when kick
rm_all_msg = get_chat_config(chat_id, "RM_All_Msg") rm_all_msg = get_chat_config(chat_id, "RM_All_Msg")
if rm_all_msg: if rm_all_msg:
new_users[chat_id][user_id]["msg_to_rm_on_kick"].append(msg_id) Global.new_users[chat_id][user_id]["msg_to_rm_on_kick"].append(msg_id)
# End here if no image captcha mode # End here if no image captcha mode
if captcha_mode not in { "nums", "hex", "ascii", "math" }: if captcha_mode not in { "nums", "hex", "ascii", "math" }:
return return
@ -1344,17 +1355,17 @@ def msg_nocmd(update: Update, context: CallbackContext):
"[%s] Received captcha reply from %s: %s", "[%s] Received captcha reply from %s: %s",
chat_id, user_name, msg_text) chat_id, user_name, msg_text)
# Check if the expected captcha solve number is in the message # Check if the expected captcha solve number is in the message
solve_num = new_users[chat_id][user_id]["join_data"]["captcha_num"] solve_num = Global.new_users[chat_id][user_id]["join_data"]["captcha_num"]
if is_captcha_num_solve(captcha_mode, msg_text, solve_num): if is_captcha_num_solve(captcha_mode, msg_text, solve_num):
logger.info("[%s] Captcha solved by %s", chat_id, user_name) logger.info("[%s] Captcha solved by %s", chat_id, user_name)
# Remove all restrictions on the user # Remove all restrictions on the user
tlg_unrestrict_user(bot, chat_id, user_id) tlg_unrestrict_user(bot, chat_id, user_id)
# Remove join messages # Remove join messages
for msg in new_users[chat_id][user_id]["msg_to_rm"]: for msg in Global.new_users[chat_id][user_id]["msg_to_rm"]:
tlg_delete_msg(bot, chat_id, msg) tlg_delete_msg(bot, chat_id, msg)
new_users[chat_id][user_id]["msg_to_rm"].clear() Global.new_users[chat_id][user_id]["msg_to_rm"].clear()
new_users[chat_id][user_id]["msg_to_rm_on_kick"].clear() Global.new_users[chat_id][user_id]["msg_to_rm_on_kick"].clear()
del new_users[chat_id][user_id] del Global.new_users[chat_id][user_id]
# Remove user captcha numbers message # Remove user captcha numbers message
tlg_delete_msg(bot, chat_id, msg_id) tlg_delete_msg(bot, chat_id, msg_id)
# Send message solve message # Send message solve message
@ -1416,8 +1427,9 @@ def msg_nocmd(update: Update, context: CallbackContext):
sent_msg_id = tlg_send_selfdestruct_msg_in( sent_msg_id = tlg_send_selfdestruct_msg_in(
bot, chat_id, TEXT[lang]["CAPTCHA_INCORRECT_MATH"], bot, chat_id, TEXT[lang]["CAPTCHA_INCORRECT_MATH"],
CONST["T_FAST_DEL_MSG"], topic_id=topic_id) CONST["T_FAST_DEL_MSG"], topic_id=topic_id)
new_users[chat_id][user_id]["msg_to_rm"].append(sent_msg_id) Global.new_users[chat_id][user_id]["msg_to_rm"].append(
new_users[chat_id][user_id]["msg_to_rm"].append(msg_id) sent_msg_id)
Global.new_users[chat_id][user_id]["msg_to_rm"].append(msg_id)
# If "nums", "hex" or "ascii" captcha # If "nums", "hex" or "ascii" captcha
else: else:
# Check if the message has 4 chars # Check if the message has 4 chars
@ -1425,15 +1437,17 @@ def msg_nocmd(update: Update, context: CallbackContext):
sent_msg_id = tlg_send_selfdestruct_msg_in( sent_msg_id = tlg_send_selfdestruct_msg_in(
bot, chat_id, TEXT[lang]["CAPTCHA_INCORRECT_0"], bot, chat_id, TEXT[lang]["CAPTCHA_INCORRECT_0"],
CONST["T_FAST_DEL_MSG"], topic_id=topic_id) CONST["T_FAST_DEL_MSG"], topic_id=topic_id)
new_users[chat_id][user_id]["msg_to_rm"].append(sent_msg_id) Global.new_users[chat_id][user_id]["msg_to_rm"].append(
new_users[chat_id][user_id]["msg_to_rm"].append(msg_id) sent_msg_id)
Global.new_users[chat_id][user_id]["msg_to_rm"].append(msg_id)
# Check if the message was just a 4 numbers msg # Check if the message was just a 4 numbers msg
elif is_int(msg_text): elif is_int(msg_text):
sent_msg_id = tlg_send_selfdestruct_msg_in( sent_msg_id = tlg_send_selfdestruct_msg_in(
bot, chat_id, TEXT[lang]["CAPTCHA_INCORRECT_1"], bot, chat_id, TEXT[lang]["CAPTCHA_INCORRECT_1"],
CONST["T_FAST_DEL_MSG"], topic_id=topic_id) CONST["T_FAST_DEL_MSG"], topic_id=topic_id)
new_users[chat_id][user_id]["msg_to_rm"].append(sent_msg_id) Global.new_users[chat_id][user_id]["msg_to_rm"].append(
new_users[chat_id][user_id]["msg_to_rm"].append(msg_id) sent_msg_id)
Global.new_users[chat_id][user_id]["msg_to_rm"].append(msg_id)
logger.info("[%s] Captcha reply process completed.", chat_id) logger.info("[%s] Captcha reply process completed.", chat_id)
logger.info("") logger.info("")
@ -1478,9 +1492,9 @@ def receive_poll_answer(update: Update, context: CallbackContext):
# Wait 3s to let poll animation be shown # Wait 3s to let poll animation be shown
sleep(3) sleep(3)
# Remove previous join messages # Remove previous join messages
for msg in new_users[chat_id][user_id]["msg_to_rm"]: for msg in Global.new_users[chat_id][user_id]["msg_to_rm"]:
tlg_delete_msg(bot, chat_id, msg) tlg_delete_msg(bot, chat_id, msg)
new_users[chat_id][user_id]["msg_to_rm"].clear() Global.new_users[chat_id][user_id]["msg_to_rm"].clear()
# Check if user vote the correct option # Check if user vote the correct option
if option_answer == poll_correct_option: if option_answer == poll_correct_option:
logger.info("[%s] User %s solve a poll challenge.", chat_id, user_name) logger.info("[%s] User %s solve a poll challenge.", chat_id, user_name)
@ -1493,7 +1507,7 @@ def receive_poll_answer(update: Update, context: CallbackContext):
bot, chat_id, bot_msg, CONST["T_FAST_DEL_MSG"]) bot, chat_id, bot_msg, CONST["T_FAST_DEL_MSG"])
else: else:
tlg_send_msg(bot, chat_id, bot_msg) tlg_send_msg(bot, chat_id, bot_msg)
del new_users[chat_id][user_id] del Global.new_users[chat_id][user_id]
# Check for custom welcome message and send it # Check for custom welcome message and send it
if welcome_msg != "-": if welcome_msg != "-":
if rm_welcome_msg: if rm_welcome_msg:
@ -1587,9 +1601,9 @@ def button_request_captcha(bot, query):
chat_title = add_lrm(chat_title) chat_title = add_lrm(chat_title)
# Ignore if message is not from a new user that has not # Ignore if message is not from a new user that has not
# completed the captcha yet # completed the captcha yet
if chat_id not in new_users: if chat_id not in Global.new_users:
return return
if user_id not in new_users[chat_id]: if user_id not in Global.new_users[chat_id]:
return return
# Get chat language # Get chat language
lang = get_chat_config(chat_id, "Language") lang = get_chat_config(chat_id, "Language")
@ -1607,7 +1621,8 @@ def button_request_captcha(bot, query):
timeout_str = f"{timeout_min} min" timeout_str = f"{timeout_min} min"
# Get current chat configurations # Get current chat configurations
captcha_level = get_chat_config(chat_id, "Captcha_Difficulty_Level") captcha_level = get_chat_config(chat_id, "Captcha_Difficulty_Level")
captcha_mode = new_users[chat_id][user_id]["join_data"]["captcha_mode"] captcha_mode = \
Global.new_users[chat_id][user_id]["join_data"]["captcha_mode"]
# Use nums mode if captcha_mode was changed while captcha was # Use nums mode if captcha_mode was changed while captcha was
# in progress # in progress
if captcha_mode not in { "nums", "hex", "ascii", "math" }: if captcha_mode not in { "nums", "hex", "ascii", "math" }:
@ -1639,7 +1654,7 @@ def button_request_captcha(bot, query):
reply_markup=reply_markup, timeout=20) reply_markup=reply_markup, timeout=20)
if edit_result["error"] == "": if edit_result["error"] == "":
# Set and modified to new expected captcha number # Set and modified to new expected captcha number
new_users[chat_id][user_id]["join_data"]["captcha_num"] = \ Global.new_users[chat_id][user_id]["join_data"]["captcha_num"] = \
captcha_num captcha_num
# Remove sent captcha image file from file system # Remove sent captcha image file from file system
if path.exists(captcha["image"]): if path.exists(captcha["image"]):
@ -1667,18 +1682,18 @@ def button_request_pass(bot, query):
# arabic, hebrew, etc.) # arabic, hebrew, etc.)
chat_title = add_lrm(chat_title) chat_title = add_lrm(chat_title)
# Ignore if request doesn't come from a new user in captcha process # Ignore if request doesn't come from a new user in captcha process
if chat_id not in new_users: if chat_id not in Global.new_users:
return return
if user_id not in new_users[chat_id]: if user_id not in Global.new_users[chat_id]:
return return
# Get chat settings # Get chat settings
lang = get_chat_config(chat_id, "Language") lang = get_chat_config(chat_id, "Language")
rm_result_msg = get_chat_config(chat_id, "Rm_Result_Msg") rm_result_msg = get_chat_config(chat_id, "Rm_Result_Msg")
# Remove previous join messages # Remove previous join messages
for msg in new_users[chat_id][user_id]["msg_to_rm"]: for msg in Global.new_users[chat_id][user_id]["msg_to_rm"]:
tlg_delete_msg(bot, chat_id, msg) tlg_delete_msg(bot, chat_id, msg)
# Remove user from captcha process # Remove user from captcha process
del new_users[chat_id][user_id] del Global.new_users[chat_id][user_id]
# Send message solve message # Send message solve message
logger.info( logger.info(
"[%s] User %s solved a button-only challenge.", "[%s] User %s solved a button-only challenge.",
@ -1876,7 +1891,7 @@ def cmd_connect(update: Update, context: CallbackContext):
return return
# Connection # Connection
group_lang = get_chat_config(group_id, "Language") group_lang = get_chat_config(group_id, "Language")
connections[user_id] = { "group_id": group_id, "lang": group_lang } Global.connections[user_id] = { "group_id": group_id, "lang": group_lang }
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, TEXT[lang]["CONNECT_OK"].format(group_id), bot, chat_type, chat_id, TEXT[lang]["CONNECT_OK"].format(group_id),
topic_id=tlg_get_msg_topic(update_msg)) topic_id=tlg_get_msg_topic(update_msg))
@ -1910,16 +1925,16 @@ def cmd_disconnect(update: Update, context: CallbackContext):
topic_id=tlg_get_msg_topic(update_msg)) topic_id=tlg_get_msg_topic(update_msg))
return return
# Check if User is connected to some group # Check if User is connected to some group
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["DISCONNECT_NOT_CONNECTED"], TEXT[lang]["DISCONNECT_NOT_CONNECTED"],
topic_id=tlg_get_msg_topic(update_msg)) topic_id=tlg_get_msg_topic(update_msg))
return return
# Disconnection # Disconnection
lang = connections[user_id]["lang"] lang = Global.connections[user_id]["lang"]
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
del connections[user_id] del Global.connections[user_id]
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["DISCONNECT_OK"].format(group_id), TEXT[lang]["DISCONNECT_OK"].format(group_id),
@ -1940,12 +1955,12 @@ def cmd_checkcfg(update: Update, context: CallbackContext):
chat_type = update_msg.chat.type chat_type = update_msg.chat.type
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -1981,12 +1996,12 @@ def cmd_language(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check usage in private chat # Check usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2011,8 +2026,8 @@ def cmd_language(update: Update, context: CallbackContext):
if lang_provided != lang: if lang_provided != lang:
lang = lang_provided lang = lang_provided
save_config_property(group_id, "Language", lang) save_config_property(group_id, "Language", lang)
if (chat_type == "private") and (user_id in connections): if (chat_type == "private") and (user_id in Global.connections):
connections[user_id]["lang"] = lang Global.connections[user_id]["lang"] = lang
msg_text = TEXT[lang]["LANG_CHANGE"] msg_text = TEXT[lang]["LANG_CHANGE"]
else: else:
msg_text = TEXT[lang]["LANG_SAME"].format( msg_text = TEXT[lang]["LANG_SAME"].format(
@ -2041,12 +2056,12 @@ def cmd_time(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2127,12 +2142,12 @@ def cmd_difficulty(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2180,12 +2195,12 @@ def cmd_captcha_mode(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2231,11 +2246,11 @@ def cmd_welcome_msg(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat(bot, chat_type, chat_id, tlg_send_msg_type_chat(bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2286,13 +2301,13 @@ def cmd_welcome_msg_time(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"], TEXT[lang]["CMD_NEEDS_CONNECTION"],
topic_id=tlg_get_msg_topic(update_msg)) topic_id=tlg_get_msg_topic(update_msg))
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2373,12 +2388,12 @@ def cmd_captcha_poll(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2515,12 +2530,12 @@ def cmd_restrict_non_text(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2581,12 +2596,12 @@ def cmd_add_ignore(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2640,12 +2655,12 @@ def cmd_remove_ignore(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2691,12 +2706,12 @@ def cmd_ignore_list(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2734,13 +2749,13 @@ def cmd_remove_solve_kick_msg(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"], TEXT[lang]["CMD_NEEDS_CONNECTION"],
topic_id=tlg_get_msg_topic(update_msg)) topic_id=tlg_get_msg_topic(update_msg))
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2788,12 +2803,12 @@ def cmd_remove_welcome_msg(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2840,12 +2855,12 @@ def cmd_remove_all_msg_kick_on(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2884,12 +2899,12 @@ def cmd_remove_all_msg_kick_off(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2928,12 +2943,12 @@ def cmd_url_enable(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -2972,12 +2987,12 @@ def cmd_url_disable(update: Update, context: CallbackContext):
lang = get_update_user_lang(update_msg.from_user) lang = get_update_user_lang(update_msg.from_user)
# Check and deny usage in private chat # Check and deny usage in private chat
if chat_type == "private": if chat_type == "private":
if user_id not in connections: if user_id not in Global.connections:
tlg_send_msg_type_chat( tlg_send_msg_type_chat(
bot, chat_type, chat_id, bot, chat_type, chat_id,
TEXT[lang]["CMD_NEEDS_CONNECTION"]) TEXT[lang]["CMD_NEEDS_CONNECTION"])
return return
group_id = connections[user_id]["group_id"] group_id = Global.connections[user_id]["group_id"]
else: else:
# Remove command message automatically after a while # Remove command message automatically after a while
tlg_msg_to_selfdestruct(update_msg) tlg_msg_to_selfdestruct(update_msg)
@ -3387,16 +3402,16 @@ def th_selfdestruct_messages(bot):
Handle remove messages sent by the Bot with the timed self-delete Handle remove messages sent by the Bot with the timed self-delete
function. function.
''' '''
while not force_exit: while not Global.force_exit:
# Thread sleep for each iteration # Thread sleep for each iteration
sleep(0.01) sleep(0.01)
# Check each Bot sent message # Check each Bot sent message
i = 0 i = 0
while i < len(to_delete_in_time_messages_list): while i < len(Global.to_delete_in_time_messages_list):
# Check for break iterating if script must exit # Check for break iterating if script must exit
if force_exit: if Global.force_exit:
return return
sent_msg = to_delete_in_time_messages_list[i] sent_msg = Global.to_delete_in_time_messages_list[i]
# Sleep each 100 iterations # Sleep each 100 iterations
i = i + 1 i = i + 1
if (i > 1) and ((i % 1000) == 0): if (i > 1) and ((i % 1000) == 0):
@ -3418,7 +3433,8 @@ def th_selfdestruct_messages(bot):
reply_to_message_id=sent_msg["Msg_id"]) reply_to_message_id=sent_msg["Msg_id"])
if sent_result["msg"] is not None: if sent_result["msg"] is not None:
tlg_msg_to_selfdestruct(sent_result["msg"]) tlg_msg_to_selfdestruct(sent_result["msg"])
list_remove_element(to_delete_in_time_messages_list, sent_msg) list_remove_element(
Global.to_delete_in_time_messages_list, sent_msg)
sleep(0.01) sleep(0.01)
############################################################################### ###############################################################################
@ -3429,14 +3445,14 @@ def th_time_to_kick_not_verify_users(bot):
Check if the time for ban new users that has not completed the Check if the time for ban new users that has not completed the
captcha has arrived. captcha has arrived.
''' '''
while not force_exit: while not Global.force_exit:
# Thread sleep for each iteration # Thread sleep for each iteration
sleep(0.01) sleep(0.01)
# Get all id from users in captcha process (list shallow copy) # Get all id from users in captcha process (list shallow copy)
users_id = [] users_id = []
chats_id_list = list(new_users.keys()).copy() chats_id_list = list(Global.new_users.keys()).copy()
for chat_id in chats_id_list: for chat_id in chats_id_list:
users_id_list = list(new_users[chat_id].keys()).copy() users_id_list = list(Global.new_users[chat_id].keys()).copy()
for user_id in users_id_list: for user_id in users_id_list:
if user_id not in users_id: if user_id not in users_id:
users_id.append(user_id) users_id.append(user_id)
@ -3450,13 +3466,14 @@ def th_time_to_kick_not_verify_users(bot):
i = 0 i = 0
sleep(0.01) sleep(0.01)
# Check if script must exit for end thread # Check if script must exit for end thread
if force_exit: if Global.force_exit:
return return
# Ignore if user is not in this chat # Ignore if user is not in this chat
if user_id not in new_users[chat_id]: if user_id not in Global.new_users[chat_id]:
continue continue
try: try:
user_join_data = new_users[chat_id][user_id]["join_data"] user_join_data = \
Global.new_users[chat_id][user_id]["join_data"]
user_join_time = user_join_data["join_time"] user_join_time = user_join_data["join_time"]
captcha_timeout = user_join_data["captcha_timeout"] captcha_timeout = user_join_data["captcha_timeout"]
if user_join_data["kicked_ban"]: if user_join_data["kicked_ban"]:
@ -3470,7 +3487,7 @@ def th_time_to_kick_not_verify_users(bot):
logger.info( logger.info(
"Removing kicked user %s after 30 mins", "Removing kicked user %s after 30 mins",
user_id) user_id)
del new_users[chat_id][user_id] del Global.new_users[chat_id][user_id]
else: else:
# If time for kick/ban has not arrived yet # If time for kick/ban has not arrived yet
if time() - user_join_time < captcha_timeout: if time() - user_join_time < captcha_timeout:
@ -3516,9 +3533,6 @@ def main(argc, argv):
''' '''
Main Function. Main Function.
''' '''
global updater
global th_0
global th_1
# Disable unused arguments # Disable unused arguments
del argc del argc
del argv del argv
@ -3542,8 +3556,8 @@ def main(argc, argv):
msgs_defaults = Defaults(disable_notification=True) msgs_defaults = Defaults(disable_notification=True)
# Create an event handler (updater) for a Bot with the given Token # Create an event handler (updater) for a Bot with the given Token
# and get the dispatcher # and get the dispatcher
updater = Updater(CONST["TOKEN"], workers=12, defaults=msgs_defaults) Global.updater = Updater(CONST["TOKEN"], workers=12, defaults=msgs_defaults)
bot_dp = updater.dispatcher bot_dp = Global.updater.dispatcher
# Set Telegram errors handler # Set Telegram errors handler
bot_dp.add_error_handler(tlg_error_callback) bot_dp.add_error_handler(tlg_error_callback)
# Set to dispatcher all expected commands messages handler # Set to dispatcher all expected commands messages handler
@ -3630,13 +3644,13 @@ def main(argc, argv):
# updates (allowed_uptades=[]) # updates (allowed_uptades=[])
if CONST["WEBHOOK_HOST"] == "None": if CONST["WEBHOOK_HOST"] == "None":
logger.info("Setup Bot for Polling.") logger.info("Setup Bot for Polling.")
updater.start_polling( Global.updater.start_polling(
drop_pending_updates=True, drop_pending_updates=True,
allowed_updates=Update.ALL_TYPES allowed_updates=Update.ALL_TYPES
) )
else: else:
logger.info("Setup Bot for Webhook.") logger.info("Setup Bot for Webhook.")
updater.start_webhook( Global.updater.start_webhook(
drop_pending_updates=True, listen="0.0.0.0", drop_pending_updates=True, listen="0.0.0.0",
port=CONST["WEBHOOK_PORT"], url_path=CONST["TOKEN"], port=CONST["WEBHOOK_PORT"], url_path=CONST["TOKEN"],
key=CONST["WEBHOOK_CERT_PRIV_KEY"], cert=CONST["WEBHOOK_CERT"], key=CONST["WEBHOOK_CERT_PRIV_KEY"], cert=CONST["WEBHOOK_CERT"],
@ -3646,18 +3660,22 @@ def main(argc, argv):
) )
logger.info("Bot setup completed. Bot is now running.") logger.info("Bot setup completed. Bot is now running.")
# Launch delete messages and kick users threads # Launch delete messages and kick users threads
th_0 = Thread(target=th_selfdestruct_messages, args=(updater.bot,)) Global.th_0 = Thread(
th_1 = Thread(target=th_time_to_kick_not_verify_users, args=(updater.bot,)) target=th_selfdestruct_messages,
th_0.name = "th_selfdestruct_messages" args=(Global.updater.bot,))
th_1.name = "th_time_to_kick_not_verify_users" Global.th_1 = Thread(
th_0.start() target=th_time_to_kick_not_verify_users,
args=(Global.updater.bot,))
Global.th_0.name = "th_selfdestruct_messages"
Global.th_1.name = "th_time_to_kick_not_verify_users"
Global.th_0.start()
sleep(0.05) sleep(0.05)
th_1.start() Global.th_1.start()
# Set main thread to idle # Set main thread to idle
# The updater.idle() catch external signals, preventing to get catch # The updater.idle() catch external signals, preventing to get catch
# by our signal handler, so we need to call the signal handler # by our signal handler, so we need to call the signal handler
# directly for a safe close # directly for a safe close
updater.idle() Global.updater.idle()
logger.info("Bot Thread end") logger.info("Bot Thread end")
if hasattr(signal, "SIGUSR1"): if hasattr(signal, "SIGUSR1"):
system_termination_signal_handler(signal.SIGUSR1, None) system_termination_signal_handler(signal.SIGUSR1, None)
@ -3670,25 +3688,24 @@ def main(argc, argv):
def system_termination_signal_handler(signal_id, frame): def system_termination_signal_handler(signal_id, frame):
'''Termination signals detection handler to stop APP execution.''' '''Termination signals detection handler to stop APP execution.'''
global force_exit
# Disable unused arguments # Disable unused arguments
del signal_id del signal_id
del frame del frame
# Exit Request # Exit Request
force_exit = True Global.force_exit = True
logger.info("Termination signal received. Releasing resources...") logger.info("Termination signal received. Releasing resources...")
# Close the Bot instance (it wait for updater, dispatcher and other # Close the Bot instance (it wait for updater, dispatcher and other
# internals threads to end) # internals threads to end)
if updater is not None: if Global.updater is not None:
logger.info("Closing Bot...") logger.info("Closing Bot...")
updater.stop() Global.updater.stop()
# Launch threads to acquire all messages and users files mutex to # Launch threads to acquire all messages and users files mutex to
# ensure that them are closed (make sure to close the script when no # ensure that them are closed (make sure to close the script when no
# read/write operation on files) # read/write operation on files)
if files_config_list: if Global.files_config_list:
logger.info("Closing resource files...") logger.info("Closing resource files...")
th_list = [] th_list = []
for chat_config_file in files_config_list: for chat_config_file in Global.files_config_list:
thread = Thread( thread = Thread(
target=th_close_resource_file, target=th_close_resource_file,
args=(chat_config_file["File"],)) args=(chat_config_file["File"],))
@ -3700,13 +3717,13 @@ def system_termination_signal_handler(signal_id, frame):
_th.join() _th.join()
# Wait to end threads # Wait to end threads
logger.info("Waiting th_0 end...") logger.info("Waiting th_0 end...")
if th_0 is not None: if Global.th_0 is not None:
if th_0.is_alive(): if Global.th_0.is_alive():
th_0.join() Global.th_0.join()
logger.info("Waiting th_1 end...") logger.info("Waiting th_1 end...")
if th_1 is not None: if Global.th_1 is not None:
if th_1.is_alive(): if Global.th_1.is_alive():
th_1.join() Global.th_1.join()
# Save current session data # Save current session data
save_session() save_session()
# Close the program # Close the program