Spaces:
Sleeping
Sleeping
Upload main.py
Browse files
main.py
CHANGED
|
@@ -1,19 +1,15 @@
|
|
| 1 |
from fastapi import FastAPI
|
| 2 |
from fastapi.staticfiles import StaticFiles
|
| 3 |
-
from pydantic import BaseModel
|
| 4 |
import uvicorn
|
| 5 |
import threading
|
| 6 |
import time
|
| 7 |
-
import requests
|
|
|
|
|
|
|
| 8 |
from datetime import datetime
|
| 9 |
-
import os
|
| 10 |
|
| 11 |
app = FastAPI()
|
| 12 |
|
| 13 |
-
# Your API Key from earlier
|
| 14 |
-
API_KEY = "c14e1300-c6d6-4165-8424-8a00c80c1b94"
|
| 15 |
-
URL = f"https://api.cricapi.com/v1/currentMatches?apikey={API_KEY}&offset=0"
|
| 16 |
-
|
| 17 |
# Central Python Brain State Memory
|
| 18 |
system_state = {
|
| 19 |
"live": False, "status": "UPCOMING", "teams": ["Initializing", "Data"],
|
|
@@ -22,69 +18,90 @@ system_state = {
|
|
| 22 |
prediction_history = []
|
| 23 |
last_over = ""
|
| 24 |
|
|
|
|
|
|
|
| 25 |
def autonomous_backend_scraper():
|
| 26 |
global system_state, prediction_history, last_over
|
| 27 |
-
print("
|
| 28 |
|
| 29 |
while True:
|
| 30 |
try:
|
| 31 |
-
#
|
| 32 |
-
|
| 33 |
-
|
|
|
|
|
|
|
| 34 |
|
| 35 |
-
if
|
| 36 |
-
|
|
|
|
| 37 |
|
| 38 |
-
|
|
|
|
| 39 |
|
| 40 |
-
if
|
|
|
|
|
|
|
| 41 |
system_state["live"] = True
|
| 42 |
system_state["status"] = "LIVE"
|
| 43 |
-
system_state["teams"] = live_match.get('teams', ["Team A", "Team B"])
|
| 44 |
-
system_state["venue"] = live_match.get('venue', "Live Stadium")
|
| 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 |
else:
|
| 70 |
-
# No live
|
| 71 |
-
|
| 72 |
-
if
|
|
|
|
| 73 |
system_state["live"] = False
|
| 74 |
system_state["status"] = "UPCOMING"
|
| 75 |
-
|
| 76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
except Exception as e:
|
| 79 |
print("Python Server Network Error:", e)
|
| 80 |
|
| 81 |
-
# Cooldown timer
|
| 82 |
time.sleep(5)
|
| 83 |
|
| 84 |
# Start the Ghost Thread
|
| 85 |
threading.Thread(target=autonomous_backend_scraper, daemon=True).start()
|
| 86 |
|
| 87 |
-
# API Endpoints
|
| 88 |
@app.get("/api/state")
|
| 89 |
def get_state():
|
| 90 |
return system_state
|
|
@@ -93,7 +110,7 @@ def get_state():
|
|
| 93 |
def get_history():
|
| 94 |
return prediction_history
|
| 95 |
|
| 96 |
-
# Serve the beautiful frontend
|
| 97 |
app.mount("/", StaticFiles(directory=".", html=True), name="frontend")
|
| 98 |
|
| 99 |
if __name__ == "__main__":
|
|
|
|
| 1 |
from fastapi import FastAPI
|
| 2 |
from fastapi.staticfiles import StaticFiles
|
|
|
|
| 3 |
import uvicorn
|
| 4 |
import threading
|
| 5 |
import time
|
| 6 |
+
from curl_cffi import requests
|
| 7 |
+
from bs4 import BeautifulSoup
|
| 8 |
+
import json
|
| 9 |
from datetime import datetime
|
|
|
|
| 10 |
|
| 11 |
app = FastAPI()
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
# Central Python Brain State Memory
|
| 14 |
system_state = {
|
| 15 |
"live": False, "status": "UPCOMING", "teams": ["Initializing", "Data"],
|
|
|
|
| 18 |
prediction_history = []
|
| 19 |
last_over = ""
|
| 20 |
|
| 21 |
+
LIVE_MATCH_URL = "https://www.espncricinfo.com/live-cricket-score"
|
| 22 |
+
|
| 23 |
def autonomous_backend_scraper():
|
| 24 |
global system_state, prediction_history, last_over
|
| 25 |
+
print("ESPN Network Hack Engaged. Stealth fetching active...")
|
| 26 |
|
| 27 |
while True:
|
| 28 |
try:
|
| 29 |
+
# Reverting back to our core hacker mechanic instead of the blocked free API
|
| 30 |
+
# We natively rip the Next.js database bypassing Cloudflare
|
| 31 |
+
r = requests.get(LIVE_MATCH_URL, impersonate='chrome120', timeout=15)
|
| 32 |
+
soup = BeautifulSoup(r.text, 'html.parser')
|
| 33 |
+
next_data = soup.find('script', id='__NEXT_DATA__')
|
| 34 |
|
| 35 |
+
if next_data:
|
| 36 |
+
data = json.loads(next_data.string)
|
| 37 |
+
matches_data = data.get('props', {}).get('appPageProps', {}).get('data', {}).get('content', {}).get('matches', [])
|
| 38 |
|
| 39 |
+
# Filter for LIVE matches dynamically
|
| 40 |
+
live_matches = [m for m in matches_data if m.get('state') == 'LIVE']
|
| 41 |
|
| 42 |
+
if len(live_matches) > 0:
|
| 43 |
+
live_match = live_matches[0]
|
| 44 |
+
|
| 45 |
system_state["live"] = True
|
| 46 |
system_state["status"] = "LIVE"
|
|
|
|
|
|
|
| 47 |
|
| 48 |
+
# Extract Teams
|
| 49 |
+
teams = live_match.get('teams', [])
|
| 50 |
+
team1_name = teams[0].get('team', {}).get('shortName', teams[0].get('team', {}).get('name', 'Team A')) if len(teams) > 0 else "Team A"
|
| 51 |
+
team2_name = teams[1].get('team', {}).get('shortName', teams[1].get('team', {}).get('name', 'Team B')) if len(teams) > 1 else "Team B"
|
| 52 |
+
|
| 53 |
+
system_state["teams"] = [team1_name, team2_name]
|
| 54 |
+
system_state["venue"] = live_match.get('ground', {}).get('name', 'Live Stadium')
|
| 55 |
+
|
| 56 |
+
# Extract Score & Overs natively from ESPN database
|
| 57 |
+
new_over = str(live_match.get('liveOvers', '0.0'))
|
| 58 |
+
|
| 59 |
+
# Find which team is currently batting
|
| 60 |
+
btm_team = next((t for t in teams if t.get('isLive')), teams[0] if len(teams)>0 else {})
|
| 61 |
+
new_score = btm_team.get('score', "0/0")
|
| 62 |
+
|
| 63 |
+
system_state["score"] = new_score
|
| 64 |
+
system_state["overs"] = new_over
|
| 65 |
+
|
| 66 |
+
# History Logic: Save records when ball increments!
|
| 67 |
+
if new_over != last_over and last_over != "":
|
| 68 |
+
prediction_history.append({
|
| 69 |
+
"time": datetime.now().strftime("%H:%M:%S"),
|
| 70 |
+
"match": f"{team1_name} vs {team2_name}",
|
| 71 |
+
"over": new_over,
|
| 72 |
+
"score": new_score,
|
| 73 |
+
"prediction": "Vanguard Assessment Complete"
|
| 74 |
+
})
|
| 75 |
+
if len(prediction_history) > 50:
|
| 76 |
+
prediction_history.pop(0)
|
| 77 |
|
| 78 |
+
last_over = new_over
|
| 79 |
|
| 80 |
else:
|
| 81 |
+
# No live match found, default to upcoming
|
| 82 |
+
upc_matches = [m for m in matches_data if m.get('state') != 'LIVE']
|
| 83 |
+
if len(upc_matches) > 0:
|
| 84 |
+
upc = upc_matches[0]
|
| 85 |
system_state["live"] = False
|
| 86 |
system_state["status"] = "UPCOMING"
|
| 87 |
+
|
| 88 |
+
teams = upc.get('teams', [])
|
| 89 |
+
team1_name = teams[0].get('team', {}).get('name', 'Team A') if len(teams) > 0 else "Team A"
|
| 90 |
+
team2_name = teams[1].get('team', {}).get('name', 'Team B') if len(teams) > 1 else "Team B"
|
| 91 |
+
system_state["teams"] = [team1_name, team2_name]
|
| 92 |
+
|
| 93 |
+
system_state["venue"] = upc.get('ground', {}).get('name', 'Upcoming Stadium')
|
| 94 |
|
| 95 |
except Exception as e:
|
| 96 |
print("Python Server Network Error:", e)
|
| 97 |
|
| 98 |
+
# Cooldown timer
|
| 99 |
time.sleep(5)
|
| 100 |
|
| 101 |
# Start the Ghost Thread
|
| 102 |
threading.Thread(target=autonomous_backend_scraper, daemon=True).start()
|
| 103 |
|
| 104 |
+
# API Endpoints
|
| 105 |
@app.get("/api/state")
|
| 106 |
def get_state():
|
| 107 |
return system_state
|
|
|
|
| 110 |
def get_history():
|
| 111 |
return prediction_history
|
| 112 |
|
| 113 |
+
# Serve the beautiful frontend GUI
|
| 114 |
app.mount("/", StaticFiles(directory=".", html=True), name="frontend")
|
| 115 |
|
| 116 |
if __name__ == "__main__":
|