Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import sqlite3 | |
| import random | |
| import time | |
| import requests | |
| import traceback | |
| from datetime import datetime, timedelta | |
| from werkzeug.utils import secure_filename | |
| from flask import Flask, render_template, jsonify, request, g, send_from_directory | |
| app = Flask(__name__) | |
| app.config['SECRET_KEY'] = 'ocean-guard-secret' | |
| app.config['DATABASE'] = os.path.join(app.instance_path, 'ocean.db') | |
| app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB limit | |
| app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, 'uploads') | |
| # Ensure directories exist | |
| try: | |
| os.makedirs(app.instance_path) | |
| os.makedirs(app.config['UPLOAD_FOLDER']) | |
| except OSError: | |
| pass | |
| # SiliconFlow Config | |
| SILICON_KEY = "sk-vimuseiptfbomzegyuvmebjzooncsqbyjtlddrfodzcdskgi" | |
| SILICON_URL = "https://api.siliconflow.cn/v1/chat/completions" | |
| SILICON_MODEL = "Qwen/Qwen2.5-7B-Instruct" | |
| # --- Database --- | |
| def get_db(): | |
| db = getattr(g, '_database', None) | |
| if db is None: | |
| db = g._database = sqlite3.connect(app.config['DATABASE']) | |
| db.row_factory = sqlite3.Row | |
| return db | |
| def close_connection(exception): | |
| db = getattr(g, '_database', None) | |
| if db is not None: | |
| db.close() | |
| def init_db(): | |
| with app.app_context(): | |
| db = get_db() | |
| db.execute(''' | |
| CREATE TABLE IF NOT EXISTS assets ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| type TEXT NOT NULL, | |
| value REAL NOT NULL, | |
| timestamp DATETIME DEFAULT CURRENT_TIMESTAMP | |
| ) | |
| ''') | |
| db.execute(''' | |
| CREATE TABLE IF NOT EXISTS logs ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| event TEXT NOT NULL, | |
| action TEXT NOT NULL, | |
| result TEXT, | |
| timestamp DATETIME DEFAULT CURRENT_TIMESTAMP | |
| ) | |
| ''') | |
| db.commit() | |
| # --- Error Handlers --- | |
| def not_found_error(error): | |
| return jsonify({"error": "Resource not found", "code": 404}), 404 | |
| def internal_error(error): | |
| traceback.print_exc() | |
| return jsonify({"error": "Internal server error", "code": 500}), 500 | |
| def request_entity_too_large(error): | |
| return jsonify({"error": "File too large (Max 16MB)", "code": 413}), 413 | |
| # --- Mock Data Helpers --- | |
| POSSIBLE_ENTITIES = [ | |
| {"type": "Great Pacific Garbage Patch Fragment", "severity": "Medium", "location": "Sector 7"}, | |
| {"type": "Deepwater Horizon Remnant Oil", "severity": "Critical", "location": "Sector 3"}, | |
| {"type": "Humpback Whale Pod (Migration)", "severity": "None", "location": "Sector 9"}, | |
| {"type": "Illegal IUU Fishing Trawler", "severity": "High", "location": "Sector 2"}, | |
| {"type": "Abandoned Ghost Net (2 tons)", "severity": "High", "location": "Sector 5"}, | |
| {"type": "Coral Reef Bleaching Event", "severity": "Medium", "location": "Sector 1"}, | |
| {"type": "Rare Leatherback Turtle", "severity": "None", "location": "Sector 4"}, | |
| {"type": "Underwater Volcanic Activity", "severity": "Low", "location": "Sector 8"} | |
| ] | |
| # --- Routes --- | |
| def index(): | |
| return render_template('index.html') | |
| def scan_ocean(): | |
| # Simulate scanning logic | |
| entity = random.choice(POSSIBLE_ENTITIES) | |
| # Add random coordinates for map | |
| entity['lat'] = 30.0 + random.uniform(-0.5, 0.5) | |
| entity['lng'] = 122.0 + random.uniform(-0.5, 0.5) | |
| entity['depth'] = random.randint(10, 800) | |
| entity['signal_strength'] = random.randint(40, 100) | |
| return jsonify(entity) | |
| def analyze_entity(): | |
| data = request.json | |
| entity_type = data.get('type') | |
| severity = data.get('severity') | |
| prompt = f""" | |
| You are the AI Core of the 'Ocean Guard' autonomous marine drone. | |
| Detected Entity: {entity_type} | |
| Severity: {severity} | |
| Analyze the situation and decide the best action. | |
| Available Actions: | |
| 1. 'deploy_cleanup': For debris/pollution. | |
| 2. 'deploy_patrol': For illegal activities. | |
| 3. 'log_observation': For wildlife/nature. | |
| 4. 'emergency_alert': For critical threats. | |
| Output strictly in JSON format: | |
| {{ | |
| "analysis": "Markdown formatted analysis. Use bold for key terms.", | |
| "recommended_action": "action_code", | |
| "confidence": 0.95 | |
| }} | |
| """ | |
| try: | |
| headers = { | |
| "Authorization": f"Bearer {SILICON_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| payload = { | |
| "model": SILICON_MODEL, | |
| "messages": [ | |
| {"role": "system", "content": "You are a marine ecology AI assistant. Output JSON only."}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| "temperature": 0.3 | |
| } | |
| # Fast timeout for mock fallback | |
| response = requests.post(SILICON_URL, json=payload, headers=headers, timeout=8) | |
| response.raise_for_status() | |
| result = response.json()['choices'][0]['message']['content'] | |
| # Clean JSON markdown | |
| if "```json" in result: | |
| result = result.split("```json")[1].split("```")[0].strip() | |
| elif "```" in result: | |
| result = result.split("```")[1].strip() | |
| return jsonify(json.loads(result)) | |
| except Exception as e: | |
| print(f"LLM Error: {e}") | |
| # Mock Fallback | |
| mock_response = { | |
| "analysis": f"**Autonomous Protocol Engaged**\n\nConnection to central command unstable. Analyzing locally.\n\nDetected: **{entity_type}**\nSeverity: {severity}\n\nStandard procedure indicates immediate intervention or logging based on entity type.", | |
| "recommended_action": "log_observation", | |
| "confidence": 0.88 | |
| } | |
| if "Plastic" in entity_type or "Net" in entity_type: | |
| mock_response["recommended_action"] = "deploy_cleanup" | |
| elif "Trawler" in entity_type or "Oil" in entity_type: | |
| mock_response["recommended_action"] = "deploy_patrol" | |
| elif "Whale" in entity_type or "Turtle" in entity_type: | |
| mock_response["recommended_action"] = "log_observation" | |
| return jsonify(mock_response) | |
| def execute_action(): | |
| data = request.json | |
| action = data.get('action') | |
| entity = data.get('entity') | |
| time.sleep(1) # Sim delay | |
| # Logic for credits | |
| credits_earned = 0 | |
| if action == 'deploy_cleanup': | |
| credits_earned = random.uniform(8.0, 25.0) | |
| message = "Cleanup Drone dispatched. Debris collected and recycled." | |
| elif action == 'deploy_patrol': | |
| credits_earned = random.uniform(15.0, 30.0) | |
| message = "Coast Guard notified. Evidence package uploaded." | |
| elif action == 'log_observation': | |
| credits_earned = random.uniform(2.0, 5.0) | |
| message = "Species data cataloged. Biodiversity contribution recorded." | |
| elif action == 'emergency_alert': | |
| credits_earned = random.uniform(1.0, 3.0) | |
| message = "Emergency broadcast sent to all nearby vessels." | |
| else: | |
| message = "Action executed." | |
| # Persist | |
| db = get_db() | |
| db.execute('INSERT INTO logs (event, action, result) VALUES (?, ?, ?)', | |
| (f"Detected {entity}", action, message)) | |
| if credits_earned > 0: | |
| db.execute('INSERT INTO assets (type, value) VALUES (?, ?)', | |
| ('Blue Carbon Credit', credits_earned)) | |
| db.commit() | |
| return jsonify({ | |
| "status": "success", | |
| "message": message, | |
| "credits_earned": round(credits_earned, 2) | |
| }) | |
| def get_stats(): | |
| db = get_db() | |
| total_credits = db.execute('SELECT SUM(value) FROM assets').fetchone()[0] or 0 | |
| recent_logs = db.execute('SELECT * FROM logs ORDER BY id DESC LIMIT 10').fetchall() | |
| logs_list = [] | |
| for log in recent_logs: | |
| logs_list.append({ | |
| "time": log['timestamp'], | |
| "event": log['event'], | |
| "action": log['action'], | |
| "result": log['result'] | |
| }) | |
| return jsonify({ | |
| "total_credits": round(total_credits, 2), | |
| "recent_logs": logs_list | |
| }) | |
| def get_market_data(): | |
| # Simulate market trend for carbon credits | |
| now = datetime.now() | |
| labels = [] | |
| data = [] | |
| price = 45.0 # Base price | |
| for i in range(12): | |
| t = now - timedelta(hours=11-i) | |
| labels.append(t.strftime("%H:00")) | |
| change = random.uniform(-2.0, 3.0) | |
| price += change | |
| data.append(round(price, 2)) | |
| return jsonify({ | |
| "labels": labels, | |
| "data": data, | |
| "current_price": round(price, 2) | |
| }) | |
| def upload_file(): | |
| if 'file' not in request.files: | |
| return jsonify({"error": "No file part"}), 400 | |
| file = request.files['file'] | |
| if file.filename == '': | |
| return jsonify({"error": "No selected file"}), 400 | |
| if file: | |
| filename = secure_filename(file.filename) | |
| # In a real app, save it. Here we simulate processing. | |
| # file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) | |
| # Simulate AI processing of the image | |
| time.sleep(1.5) | |
| return jsonify({ | |
| "status": "success", | |
| "message": f"File '{filename}' analyzed successfully. No anomalies detected in satellite imagery." | |
| }) | |
| if __name__ == '__main__': | |
| init_db() | |
| # Ensure robust running on HF | |
| app.run(host='0.0.0.0', port=7860) | |