Skip to content

Commit

Permalink
Add retry for all APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
houshmand-2005 committed Jul 24, 2024
1 parent 8be64f7 commit 2bd39b6
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 138 deletions.
15 changes: 9 additions & 6 deletions telegram_bot/send_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
async def send_logs(msg):
"""Send logs to all admins."""
admins = await check_admin()
retries = 2
if admins:
for admin in admins:
try:
await application.bot.sendMessage(
chat_id=admin, text=msg, parse_mode="HTML"
)
except Exception as e: # pylint: disable=broad-except
print(f"Failed to send message to admin {admin}: {e}")
for _ in range(retries):
try:
await application.bot.sendMessage(
chat_id=admin, text=msg, parse_mode="HTML"
)
break
except Exception as e: # pylint: disable=broad-except
print(f"Failed to send message to admin {admin}: {e}")
else:
print("No admins found.")
292 changes: 161 additions & 131 deletions utils/panel_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

import asyncio
import random
import sys
from ssl import SSLError

Expand All @@ -12,6 +13,7 @@
print("Module 'httpx' is not installed use: 'pip install httpx' to install it")
sys.exit()
from telegram_bot.send_message import send_logs

from utils.handel_dis_users import DISABLED_USERS, DisabledUsers
from utils.logs import logger
from utils.read_config import read_config
Expand All @@ -36,7 +38,7 @@ async def get_token(panel_data: PanelType) -> PanelType | ValueError:
"username": f"{panel_data.panel_username}",
"password": f"{panel_data.panel_password}",
}
for attempt in range(10):
for attempt in range(20):
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/admin/token"
try:
Expand All @@ -58,9 +60,9 @@ async def get_token(panel_data: PanelType) -> PanelType | ValueError:
await send_logs(message)
logger.error(message)
continue
await asyncio.sleep(5 * attempt)
await asyncio.sleep(random.randint(2, 5) * attempt)
message = (
"Failed to get token after 10 attempts. Make sure the panel is running "
"Failed to get token after 20 attempts. Make sure the panel is running "
+ "and the username and password are correct."
)
await send_logs(message)
Expand All @@ -83,35 +85,39 @@ async def all_user(panel_data: PanelType) -> list[UserType] | ValueError:
ValueError: If the function fails to get the users from both the HTTP
and HTTPS endpoints.
"""
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/users"
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.get(url, headers=headers, timeout=10)
response.raise_for_status()
user_inform = response.json()
return [UserType(name=user["username"]) for user in user_inform["users"]]
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
for attempt in range(20):
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/users"
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.get(url, headers=headers, timeout=10)
response.raise_for_status()
user_inform = response.json()
return [
UserType(name=user["username"]) for user in user_inform["users"]
]
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
await asyncio.sleep(random.randint(2, 5) * attempt)
message = (
"Failed to get users. make sure the panel is running "
"Failed to get users after 20 attempts. make sure the panel is running "
+ "and the username and password are correct."
)
await send_logs(message)
Expand Down Expand Up @@ -150,7 +156,9 @@ async def enable_all_user(panel_data: PanelType) -> None | ValueError:
status = {"status": "active"}
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.put(url, json=status, headers=headers)
response = await client.put(
url, json=status, headers=headers, timeout=5
)
response.raise_for_status()
message = f"Enabled user: {username.name}"
await send_logs(message)
Expand Down Expand Up @@ -188,37 +196,53 @@ async def enable_selected_users(
ValueError: If the function fails to enable the users on both the HTTP
and HTTPS endpoints.
"""
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
for username in inactive_users:
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/user/{username}"
success = False
for attempt in range(5):
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
status = {"status": "active"}
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.put(url, json=status, headers=headers)
response.raise_for_status()
message = f"Enabled user: {username}"
await send_logs(message)
logger.info(message)
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/user/{username}"
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.put(
url, json=status, headers=headers, timeout=5
)
response.raise_for_status()
message = f"Enabled user: {username}"
await send_logs(message)
logger.info(message)
success = True
break
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
if success:
break
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
await asyncio.sleep(random.randint(2, 5) * attempt)
if not success:
message = (
f"Failed enable user: {username} after 20 attempts. Make sure the panel is running "
+ "and the username and password are correct."
)
await send_logs(message)
logger.error(message)
raise ValueError(message)
logger.info("Enabled selected users")


Expand All @@ -238,40 +262,44 @@ async def disable_user(panel_data: PanelType, username: UserType) -> None | Valu
ValueError: If the function fails to disable the user on both the HTTP
and HTTPS endpoints.
"""
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
status = {"status": "disabled"}
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/user/{username.name}"
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.put(url, json=status, headers=headers)
response.raise_for_status()
message = f"Disabled user: {username.name}"
await send_logs(message)
logger.info(message)
dis_obj = DisabledUsers()
await dis_obj.add_user(username.name)
return None
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
for attempt in range(20):
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
status = {"status": "disabled"}
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/user/{username.name}"
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.put(
url, json=status, headers=headers, timeout=5
)
response.raise_for_status()
message = f"Disabled user: {username.name}"
await send_logs(message)
logger.info(message)
dis_obj = DisabledUsers()
await dis_obj.add_user(username.name)
return None
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
await asyncio.sleep(random.randint(2, 5) * attempt)
message = (
f"Failed to disable user: {username.name}. Make sure the panel is running "
f"Failed disable user: {username.name} after 20 attempts. Make sure the panel is running "
+ "and the username and password are correct."
)
await send_logs(message)
Expand All @@ -294,46 +322,48 @@ async def get_nodes(panel_data: PanelType) -> list[NodeType] | ValueError:
ValueError: If the function fails to get the nodes from both the HTTP
and HTTPS endpoints.
"""
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
all_nodes = []
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/nodes"
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.get(url, headers=headers, timeout=10)
response.raise_for_status()
user_inform = response.json()
for node in user_inform:
all_nodes.append(
NodeType(
node_id=node["id"],
node_name=node["name"],
node_ip=node["address"],
status=node["status"],
message=node["message"],
for attempt in range(20):
get_panel_token = await get_token(panel_data)
if isinstance(get_panel_token, ValueError):
raise get_panel_token
token = get_panel_token.panel_token
headers = {
"Authorization": f"Bearer {token}",
}
all_nodes = []
for scheme in ["https", "http"]:
url = f"{scheme}://{panel_data.panel_domain}/api/nodes"
try:
async with httpx.AsyncClient(verify=False) as client:
response = await client.get(url, headers=headers, timeout=10)
response.raise_for_status()
user_inform = response.json()
for node in user_inform:
all_nodes.append(
NodeType(
node_id=node["id"],
node_name=node["name"],
node_ip=node["address"],
status=node["status"],
message=node["message"],
)
)
)
return all_nodes
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
return all_nodes
except SSLError:
continue
except httpx.HTTPStatusError:
message = f"[{response.status_code}] {response.text}"
await send_logs(message)
logger.error(message)
continue
except Exception as error: # pylint: disable=broad-except
message = f"An unexpected error occurred: {error}"
await send_logs(message)
logger.error(message)
continue
await asyncio.sleep(random.randint(2, 5) * attempt)
message = (
"Failed to get nodes. make sure the panel is running "
"Failed to get nodes after 20 attempts. make sure the panel is running "
+ "and the username and password are correct."
)
await send_logs(message)
Expand Down
2 changes: 1 addition & 1 deletion v2iplimit.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from utils.read_config import read_config
from utils.types import PanelType

VERSION = "1.0.6"
VERSION = "1.0.6.1"

parser = argparse.ArgumentParser(description="Help message")
parser.add_argument("--version", action="version", version=VERSION)
Expand Down

0 comments on commit 2bd39b6

Please sign in to comment.