Spaces:
Paused
Paused
File size: 10,651 Bytes
887eced a36092f 887eced 28b3d23 887eced b0f0c9e 28b3d23 887eced b0f0c9e 887eced 7738737 887eced 7738737 887eced 28b3d23 887eced 28b3d23 887eced a36092f 887eced a36092f 887eced a36092f 887eced 28b3d23 887eced 109d977 b0f0c9e 109d977 b0f0c9e 109d977 7738737 109d977 7738737 b0f0c9e 7738737 b0f0c9e 109d977 7738737 109d977 7738737 109d977 7738737 109d977 887eced 109d977 b0f0c9e 0de483f 109d977 7738737 5ddde19 7738737 b0f0c9e 887eced 7738737 887eced a36092f 887eced 28b3d23 887eced 7738737 887eced 7738737 887eced 28b3d23 887eced 28b3d23 887eced 28b3d23 887eced 28b3d23 887eced 28b3d23 887eced 28b3d23 887eced a36092f 28b3d23 a36092f 28b3d23 a36092f 28b3d23 a36092f 7738737 a36092f 28b3d23 a36092f 28b3d23 a36092f 28b3d23 a36092f 7738737 a36092f 28b3d23 a36092f 7738737 89548aa 7738737 37b4edb 7738737 37b4edb 887eced 806a5a6 28b3d23 887eced 7738737 28b3d23 887eced 7738737 28b3d23 7738737 28b3d23 887eced 7738737 a2753bd 7738737 a2753bd 676b9ca 7738737 28b3d23 7738737 28b3d23 89548aa | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | import requests
import json
from uuid import UUID
from typing import Dict, Any, Optional
import gradio as gr
import os
import threading
import time
import pandas as pd
ZGM_API_TOKEN = os.getenv("ZGM_API_TOKEN")
if not ZGM_API_TOKEN:
raise ValueError("ZGM_API_TOKEN not found in environment variables!")
VPS_IP = os.getenv("VPS_IP")
if not VPS_IP:
raise ValueError("VPS_IP not found in environment variables!")
KEY_API_URL = f"http://{VPS_IP}:3000"
class ZGMApiClient:
def __init__(self, base_url: str, api_token: str):
self.base_url = base_url.rstrip('/')
self.api_token = api_token
self.headers = {
'ZGM-API-TOKEN': api_token,
'Content-Type': 'application/json',
'Accept': 'text/plain'
}
def _make_request(self, method: str, endpoint: str, params: Dict = None, data: Dict = None) -> Dict:
url = f"{self.base_url}{endpoint}"
try:
response = requests.request(
method=method,
url=url,
headers=self.headers,
params=params,
json=data,
timeout=15
)
response.raise_for_status()
return response.json()
except requests.exceptions.ConnectTimeout:
return {"error": f"Cannot connect to {self.base_url}. Please check URL or network.", "status_code": 0}
except requests.exceptions.HTTPError as e:
if response.status_code == 401:
return {"error": "Unauthorized. Please check API Token.", "status_code": 401}
elif response.status_code == 500:
return {"error": "Server error from ZGM API.", "status_code": 500}
return {"error": f"HTTP Error: {str(e)}", "status_code": response.status_code}
except requests.exceptions.RequestException as e:
return {"error": f"Connection error: {str(e)}", "status_code": 0}
def rent_otp(self, service: str) -> Dict:
data = {"service": service}
return self._make_request('POST', '/api/mail/otp-rent', data=data)
def get_otp(self, order_id: str) -> Dict:
try:
UUID(order_id)
return self._make_request('GET', '/api/mail/otp-get', params={"orderId": order_id})
except ValueError:
return {"error": "order_id must be a valid UUID", "status_code": 400}
client = ZGMApiClient("https://gm.haivl.wtf", ZGM_API_TOKEN)
def validate_key_from_api(access_key: str) -> tuple[bool, str]:
try:
response = requests.get(f"{KEY_API_URL}/api/keys/validate", params={"key": access_key}, timeout=5)
response.raise_for_status()
data = response.json()
if data["valid"]:
return True, f"Remaining {data['remaining']} keys."
else:
return False, "Invalid key!"
except requests.exceptions.RequestException as e:
return False, f"Error checking key from API: {str(e)}"
def remove_key_from_api(access_key: str) -> tuple[bool, str]:
try:
response = requests.delete(f"{KEY_API_URL}/api/keys/remove", params={"key": access_key}, timeout=5)
response.raise_for_status()
data = response.json()
if data["success"]:
return True, f"Remaining {data['remaining']} keys."
else:
return False, "Cannot remove key."
except requests.exceptions.RequestException as e:
return False, f"Error removing key from API: {str(e)}"
def validate_and_remove_key(access_key: str, result: Dict) -> tuple[bool, str]:
is_valid, message = validate_key_from_api(access_key)
if not is_valid:
return False, message
if result.get("code") == 200 and result.get("data") and "orderId" in result["data"] and "email" in result["data"]:
success, remove_message = remove_key_from_api(access_key)
if not success:
return True, f"OTP rented successfully but {remove_message}"
remaining_keys = int(remove_message.split("Remaining ")[1].split(" key")[0])
remaining_message = f"Remaining {remaining_keys} keys."
if remaining_keys < 100:
remaining_message += " Low key count! Please create more keys."
return True, remaining_message
else:
return True, f"Error: {result.get('message', 'Unable to rent Gmail.')}\nKey not deleted."
def execute_with_loading(func, *args, **kwargs):
result = [None]
is_loading = [True]
def target():
result[0] = func(*args, **kwargs)
is_loading[0] = False
api_thread = threading.Thread(target=target)
api_thread.start()
while is_loading[0]:
time.sleep(0.1)
api_thread.join()
return result[0]
def format_rent_otp_result(data: Dict) -> pd.DataFrame:
if not data or "data" not in data:
return pd.DataFrame([["No data to display."]], columns=["Message"])
order_info = data["data"]
df = pd.DataFrame([{
"Order ID": order_info.get("orderId", "N/A"),
"Email": order_info.get("email", "N/A")
}])
return df
def format_get_otp_result(data: Dict) -> pd.DataFrame:
if not data or "data" not in data:
return pd.DataFrame([["No data to display."]], columns=["Message"])
otp_data = data["data"]
if isinstance(otp_data, dict):
otp_data = [otp_data]
if not isinstance(otp_data, list):
return pd.DataFrame([["Invalid data."]], columns=["Message"])
df = pd.DataFrame([
{
"Email": item.get("email", "N/A"),
"OTP Code": item.get("otpCode", "N/A"),
"Content": item.get("otpContent", "N/A")
}
for item in otp_data
])
return df
def clear_all_logs():
return pd.DataFrame([["No data yet"]], columns=["Message"]), pd.DataFrame([["No data yet"]], columns=["Message"]), ""
def gradio_interface(access_key, action, service, order_id, rent_otp_log, get_otp_log):
message = ""
new_order_id = order_id
if rent_otp_log is None:
rent_otp_log = pd.DataFrame([["No data yet"]], columns=["Message"])
if get_otp_log is None:
get_otp_log = pd.DataFrame([["No data yet"]], columns=["Message"])
if action == "Rent OTP":
if not access_key:
rent_otp_log = pd.DataFrame([["Please enter a key to rent OTP!"]], columns=["Message"])
return rent_otp_log, get_otp_log, message, order_id
if not service:
rent_otp_log = pd.DataFrame([["Please select a service!"]], columns=["Message"])
return rent_otp_log, get_otp_log, message, order_id
result = execute_with_loading(client.rent_otp, service)
is_valid, message = validate_and_remove_key(access_key, result)
if not is_valid:
rent_otp_log = pd.DataFrame([[message]], columns=["Message"])
return rent_otp_log, get_otp_log, message, order_id
if result.get("code") == 200:
rent_otp_log = format_rent_otp_result(result)
new_order_id = result["data"].get("orderId", order_id)
else:
rent_otp_log = pd.DataFrame([[json.dumps(result, indent=2, ensure_ascii=False)]], columns=["Message"])
return rent_otp_log, get_otp_log, message, new_order_id
elif action == "Get OTP":
if not order_id:
get_otp_log = pd.DataFrame([["Please enter Order ID!"]], columns=["Message"])
return rent_otp_log, get_otp_log, "", order_id
result = execute_with_loading(client.get_otp, order_id)
if result.get("code") == 200 and "data" in result:
get_otp_log = format_get_otp_result(result)
else:
get_otp_log = pd.DataFrame([[json.dumps(result, indent=2, ensure_ascii=False)]], columns=["Message"])
return rent_otp_log, get_otp_log, "", order_id
else:
return rent_otp_log, get_otp_log, "Invalid action!", order_id
SERVICES = [
"ICLOUD", "ZSK", "FACEBOOK", "TELEGRAM",
"GGPLAY", "INSTAGRAM", "FMCPAY", "AMAZON"
]
NOTIFICATION_FILE = "notification.txt"
def read_notification() -> str:
if os.path.exists(NOTIFICATION_FILE):
with open(NOTIFICATION_FILE, "r", encoding="utf-8") as f:
return f.read()
return ""
def update_notification(msg_input, password):
if password == "2312":
with open(NOTIFICATION_FILE, "w", encoding="utf-8") as f:
f.write(msg_input)
return msg_input
return read_notification()
with gr.Blocks() as demo:
gr.Markdown("## Gmail Trust 247 - Enter Key to Rent OTP")
with gr.Row():
access_key = gr.Textbox(label="Access Key (Required for Rent OTP)", placeholder="Enter 32-char key...")
action = gr.Dropdown(label="Select Action", choices=["Rent OTP", "Get OTP"], value="Rent OTP")
with gr.Row():
service = gr.Dropdown(label="Service (For Rent OTP)", choices=SERVICES)
order_id = gr.Textbox(label="Order ID (For Get OTP)", placeholder="Enter Order ID")
rent_otp_log = gr.State(value=pd.DataFrame([["No data yet"]], columns=["Message"]))
get_otp_log = gr.State(value=pd.DataFrame([["No data yet"]], columns=["Message"]))
rent_otp_output = gr.Dataframe(
label="Rent OTP Log",
headers=["Order ID", "Email"],
datatype=["str", "str"],
interactive=False
)
get_otp_output = gr.Dataframe(
label="Get OTP Log",
headers=["Email", "OTP Code", "Content"],
datatype=["str", "str", "str"],
interactive=False
)
message_output = gr.Textbox(label="Message", interactive=False)
with gr.Row():
submit_btn = gr.Button("Submit", variant="primary")
clear_btn = gr.Button("Clear Log", variant="secondary")
submit_btn.click(
fn=gradio_interface,
inputs=[access_key, action, service, order_id, rent_otp_log, get_otp_log],
outputs=[rent_otp_output, get_otp_output, message_output, order_id]
)
clear_btn.click(
fn=clear_all_logs,
inputs=None,
outputs=[rent_otp_output, get_otp_output, message_output]
)
gr.Markdown("## System Notification")
with gr.Row():
notification_input = gr.Textbox(label="View the number of gmail in stock", lines=3)
password_input = gr.Textbox(label="Password", type="password")
with gr.Row():
update_btn = gr.Button("View the number of gmail in stock")
current_notification = gr.Textbox(label="gmail in stock", value=read_notification(), interactive=False)
update_btn.click(update_notification, inputs=[notification_input, password_input], outputs=current_notification)
gr.Markdown("## Get OTP Log")
demo.launch() |