Files
Lottery-Tracker/app.py

173 lines
6.3 KiB
Python

"""
Flask Backend for Lottery Investment Calculator
Provides API endpoints for jackpots and investment calculations
"""
from flask import Flask, jsonify, request
from flask_cors import CORS
import requests
from bs4 import BeautifulSoup
import urllib3
from playwright.sync_api import sync_playwright
import re
from lottery_calculator import calculate_us_lottery, calculate_canadian_lottery
# Suppress SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
app = Flask(__name__)
CORS(app) # Enable CORS for Next.js frontend
# Common headers to mimic a browser request
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Cache-Control": "max-age=0",
}
def get_us_lotteries():
"""Fetch Powerball and Mega Millions jackpots"""
results = {"Powerball": None, "Mega Millions": None}
# Powerball
try:
resp = requests.get("https://www.lotto.net/powerball", timeout=10, verify=False, headers=HEADERS)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
all_text = soup.get_text()
lines = all_text.split('\n')
for i, line in enumerate(lines):
if 'Next Jackpot' in line and i + 1 < len(lines):
next_line = lines[i + 1].strip()
if '$' in next_line and 'Million' in next_line:
# Extract numeric value
match = re.search(r'\$(\d+(?:,\d+)?(?:\.\d+)?)', next_line)
if match:
value = float(match.group(1).replace(',', ''))
results["Powerball"] = value * 1_000_000
break
except Exception as e:
print(f"Error fetching Powerball: {e}")
# Mega Millions
try:
resp = requests.get("https://www.lotto.net/mega-millions", timeout=10, verify=False, headers=HEADERS)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
all_text = soup.get_text()
lines = all_text.split('\n')
for i, line in enumerate(lines):
if 'Next Jackpot' in line and i + 1 < len(lines):
next_line = lines[i + 1].strip()
if '$' in next_line and 'Million' in next_line:
# Extract numeric value
match = re.search(r'\$(\d+(?:,\d+)?(?:\.\d+)?)', next_line)
if match:
value = float(match.group(1).replace(',', ''))
results["Mega Millions"] = value * 1_000_000
break
except Exception as e:
print(f"Error fetching Mega Millions: {e}")
return results
def get_canadian_lotteries():
"""Fetch Lotto Max and Lotto 6/49 jackpots using Playwright"""
results = {"Lotto Max": None, "Lotto 6/49": None}
try:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://www.olg.ca/", wait_until="networkidle", timeout=30000)
page.wait_for_timeout(3000)
content = page.content()
browser.close()
# Lotto Max
lotto_max_match = re.search(r'LOTTO\s*MAX(?:(?!LOTTO\s*6/49).)*?\$\s*([\d.,]+)\s*Million', content, re.IGNORECASE | re.DOTALL)
if lotto_max_match:
value = float(lotto_max_match.group(1).replace(',', ''))
results["Lotto Max"] = value * 1_000_000
# Lotto 6/49
lotto_649_match = re.search(r'LOTTO\s*6/49(?:(?!LOTTO\s*MAX).)*?\$\s*([\d.,]+)\s*Million', content, re.IGNORECASE | re.DOTALL)
if lotto_649_match:
value = float(lotto_649_match.group(1).replace(',', ''))
results["Lotto 6/49"] = value * 1_000_000
except Exception as e:
print(f"Error fetching Canadian lotteries: {e}")
return results
@app.route('/api/jackpots', methods=['GET'])
def get_jackpots():
"""API endpoint to get all lottery jackpots"""
us_lotteries = get_us_lotteries()
canadian_lotteries = get_canadian_lotteries()
return jsonify({
"us": {
"powerball": us_lotteries["Powerball"],
"megaMillions": us_lotteries["Mega Millions"]
},
"canadian": {
"lottoMax": canadian_lotteries["Lotto Max"],
"lotto649": canadian_lotteries["Lotto 6/49"]
}
})
@app.route('/api/calculate', methods=['POST'])
def calculate():
"""API endpoint to calculate investment returns"""
data = request.json
jackpot = data.get('jackpot')
lottery_type = data.get('type', 'us') # 'us' or 'canadian'
invest_percentage = data.get('investPercentage', 0.90)
annual_return = data.get('annualReturn', 0.045)
cycles = data.get('cycles', 8)
if not jackpot:
return jsonify({"error": "Jackpot amount is required"}), 400
try:
if lottery_type == 'us':
result = calculate_us_lottery(jackpot, invest_percentage, annual_return, cycles)
else:
result = calculate_canadian_lottery(jackpot, invest_percentage, annual_return, cycles)
return jsonify(result)
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route('/api/health', methods=['GET'])
def health():
"""Health check endpoint"""
return jsonify({"status": "ok"})
if __name__ == '__main__':
print("🎰 Lottery Investment Calculator API")
print("=" * 50)
print("Starting Flask server on http://localhost:5000")
print("API Endpoints:")
print(" - GET /api/jackpots - Get current jackpots")
print(" - POST /api/calculate - Calculate investments")
print(" - GET /api/health - Health check")
print("=" * 50)
# Bind to 0.0.0.0 so the Flask app is reachable from outside the container
app.run(debug=True, host='0.0.0.0', port=5000)