OrbitMC commited on
Commit
0e4ddd2
·
verified ·
1 Parent(s): c2f9a6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -131
app.py CHANGED
@@ -1,142 +1,45 @@
1
  import gradio as gr
2
- import requests
3
- import time
4
- import threading
5
- import json
6
  import os
7
- import itertools
8
- import string
9
-
10
- # --- CONFIGURATION ---
11
- CHARS = string.ascii_lowercase + string.digits + "_"
12
- DELAY_SECONDS = 2.0 # Safe delay to prevent IP bans from APIs
13
- STATE_FILE = "hunter_state.json"
14
-
15
- # Generate all 50,653 combinations deterministically
16
- ALL_COMBOS = ["".join(c) for c in itertools.product(CHARS, repeat=4)]
17
- TOTAL_COMBOS = len(ALL_COMBOS)
18
-
19
- # --- STATE MANAGEMENT ---
20
- def load_state():
21
- if os.path.exists(STATE_FILE):
22
- try:
23
- with open(STATE_FILE, "r") as f:
24
- return json.load(f)
25
- except:
26
- pass
27
- return {"index": 0, "available_names": [], "is_running": True}
28
-
29
- def save_state(state):
30
- with open(STATE_FILE, "w") as f:
31
- json.dump(state, f)
32
-
33
- # Global state loaded into memory
34
- app_state = load_state()
35
-
36
- # --- BACKGROUND WORKER ---
37
- def background_scanner():
38
- while app_state["index"] < TOTAL_COMBOS:
39
- if not app_state.get("is_running", True):
40
- time.sleep(5)
41
- continue
42
 
43
- current_name = ALL_COMBOS[app_state["index"]]
 
 
 
 
 
 
44
 
45
- try:
46
- # Using PlayerDB to avoid direct Mojang IP rate-limits
47
- response = requests.get(
48
- f"https://playerdb.co/api/player/minecraft/{current_name}",
49
- timeout=10
50
- )
51
-
52
- # 404 or success=false means the player does not exist (Name is available)
53
- if response.status_code == 404 or (response.status_code == 200 and not response.json().get("success")):
54
- if current_name not in app_state["available_names"]:
55
- app_state["available_names"].append(current_name)
56
- print(f"[FOUND] {current_name} is available!")
57
-
58
- # If we hit a rate limit, back off for a minute
59
- elif response.status_code == 429:
60
- print("[RATE LIMIT] Sleeping for 60 seconds...")
61
- time.sleep(60)
62
- continue # Retry same index
63
-
64
- except Exception as e:
65
- print(f"[NETWORK ERROR] {e}. Retrying in 10s...")
66
- time.sleep(10)
67
- continue # Retry same index
68
-
69
- # Move forward and save
70
- app_state["index"] += 1
71
 
72
- # Save to disk every 10 checks to minimize disk I/O but ensure persistence
73
- if app_state["index"] % 10 == 0:
74
- save_state(app_state)
75
-
76
- time.sleep(DELAY_SECONDS)
77
-
78
- # Final save when complete
79
- app_state["is_running"] = False
80
- save_state(app_state)
81
-
82
- # Start the background thread (daemon=True means it dies when the app dies)
83
- scanner_thread = threading.Thread(target=background_scanner, daemon=True)
84
- scanner_thread.start()
85
-
86
- # --- UI FUNCTIONS ---
87
- def get_dashboard_stats():
88
- idx = app_state["index"]
89
- percent = (idx / TOTAL_COMBOS) * 100
90
- names = app_state["available_names"]
91
-
92
- status_msg = "🟢 Running in Background" if idx < TOTAL_COMBOS else "✅ Scan Complete"
93
-
94
- stats_markdown = f"""
95
- ### 📊 Scanner Status: {status_msg}
96
- * **Progress:** {idx:,} / {TOTAL_COMBOS:,} ({percent:.2f}%)
97
- * **Available Names Found:** {len(names)}
98
- * **Currently Checking:** `{ALL_COMBOS[min(idx, TOTAL_COMBOS-1)]}`
99
- """
100
-
101
- names_list = "\n".join(names) if names else "No names found yet. Check back later!"
102
- return stats_markdown, names_list
103
 
104
- # --- GRADIO UI ---
105
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo"), title="3-Letter MC Hunter") as demo:
106
- gr.Markdown(
107
- """
108
- # 🕵️‍♂️ Autonomous 3-Letter Name Hunter
109
- This tool runs continuously in the background checking all 50,653 combinations of A-Z, 0-9, and _.
110
- You can safely close this tab; the server will keep scanning.
111
- """
112
- )
113
 
114
  with gr.Row():
115
- with gr.Column(scale=1):
116
- stats_display = gr.Markdown(value="Loading stats...")
117
- refresh_btn = gr.Button("🔄 Refresh Dashboard", variant="primary")
118
-
119
- with gr.Column(scale=2):
120
- gr.Markdown("### 💎 Available Names Vault")
121
- names_display = gr.TextArea(
122
- label="Available Names (Copy & Paste)",
123
- interactive=False,
124
- lines=15
125
- )
126
-
127
- # Wire up the refresh button
128
- refresh_btn.click(
129
- fn=get_dashboard_stats,
130
- inputs=[],
131
- outputs=[stats_display, names_display]
132
- )
133
 
134
- # Run once on load
135
- demo.load(
136
- fn=get_dashboard_stats,
137
- inputs=[],
138
- outputs=[stats_display, names_display]
139
- )
140
 
141
  if __name__ == "__main__":
142
- demo.launch()
 
 
 
1
  import gradio as gr
2
+ import psutil
 
 
 
3
  import os
4
+ import time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ def get_space_metrics():
7
+ """
8
+ Calculates the memory and CPU usage of the current process
9
+ and all its children to stay within Space limits.
10
+ """
11
+ try:
12
+ current_process = psutil.Process(os.getpid())
13
 
14
+ # Calculate total RAM (RSS) for this process and children
15
+ total_rss = current_process.memory_info().rss
16
+ for child in current_process.children(recursive=True):
17
+ total_rss += child.memory_info().rss
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ ram_usage_mb = total_rss / (1024**2)
20
+
21
+ # CPU usage over a short interval
22
+ cpu_usage_pct = current_process.cpu_percent(interval=0.1)
23
+
24
+ return f"RAM: {ram_usage_mb:.1f} MB", f"CPU: {cpu_usage_pct:.1f}%"
25
+ except Exception as e:
26
+ return "Error", str(e)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ # Build the Gradio UI
29
+ with gr.Blocks() as demo:
30
+ gr.Markdown("# 🚀 Space Resource Monitor")
 
 
 
 
 
 
31
 
32
  with gr.Row():
33
+ ram_output = gr.Textbox(label="Allocated RAM Usage")
34
+ cpu_output = gr.Textbox(label="Allocated CPU Usage")
35
+
36
+ refresh_btn = gr.Button("Refresh Metrics")
37
+ refresh_btn.click(get_space_metrics, outputs=[ram_output, cpu_output])
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ # Auto-refresh on load
40
+ demo.load(get_space_metrics, outputs=[ram_output, cpu_output])
 
 
 
 
41
 
42
  if __name__ == "__main__":
43
+ # CRITICAL: server_name="0.0.0.0" allows external access to the container
44
+ # server_port=7860 is the default port expected by HF Spaces
45
+ demo.launch(server_name="0.0.0.0", server_port=7860)