from flask import Flask, render_template, send_file, jsonify import os import random import json app = Flask(__name__) # Configuration for NASA data paths - using environment variables with defaults METADATA_PATH = os.environ.get( "NASA_METADATA_PATH", "/Volumes/MediaServer/Images/NASA/metadata" ) IMAGES_PATH = os.environ.get( "NASA_IMAGES_PATH", "/Volumes/MediaServer/Images/NASA/images" ) SNAPSHOT_FILE = os.environ.get("SNAPSHOT_FILE", "./files_snapshot.txt") # History tracking image_history = [] MAX_HISTORY = 50 def load_snapshot(): """Load the snapshot file to get all available image metadata files""" try: if not os.path.exists(SNAPSHOT_FILE): return [] with open(SNAPSHOT_FILE, "r") as f: lines = [line.strip() for line in f.readlines() if line.strip()] return lines except Exception as e: print(f"Error loading snapshot: {e}") return [] def get_random_image_metadata(): """Get a random image from the snapshot""" snapshot_files = load_snapshot() if not snapshot_files: return None selected_file = random.choice(snapshot_files) return selected_file def get_image_data(metadata_filename): """Extract image data from metadata file""" try: # Construct full path to metadata file metadata_path = os.path.join(METADATA_PATH, metadata_filename) if not os.path.exists(metadata_path): return None with open(metadata_path, "r") as f: metadata = json.load(f) # Extract the image name from metadata filename (remove index- prefix and .json suffix) base_name = metadata_filename[6:-5] # Remove "index-" prefix and ".json" suffix # Construct full path to image file image_filename = f"{base_name}~orig.jpg" image_path = os.path.join(IMAGES_PATH, image_filename) # Parse data structure - it's an array, so get first element description = "" title = base_name if ( "data" in metadata and isinstance(metadata["data"], list) and len(metadata["data"]) > 0 ): data_item = metadata["data"][0] # Get the first item from the array if isinstance(data_item, dict): # Look for description in the first data element if "description" in data_item: description = data_item["description"] elif "abstract" in data_item: description = data_item["abstract"] elif "title" in data_item: title = data_item["title"] # Additional fallbacks if not description and isinstance(data_item, dict): for key, value in data_item.items(): if ( isinstance(value, str) and len(value) > 20 and not key.startswith("_") ): if len(value) > 100 or ( len(value) > 50 and "space" in value.lower() ): description = value break # If no description from data array, try root level if not description and "description" in metadata: description = metadata["description"] # If still no description, try looking for long strings at root level if not description and isinstance(metadata, dict): for key, value in metadata.items(): if isinstance(value, str) and len(value) > 100: description = value break # Final fallback if not description: description = "No description available" return { "id": base_name, "title": title, "description": description, "image_path": image_path, } except Exception as e: print(f"Error processing metadata {metadata_filename}: {e}") return None def add_to_history(image_data): """Add image to history with limit""" global image_history # Only add if not already in history if not any(item["id"] == image_data["id"] for item in image_history): image_history.append(image_data) # Limit history size if len(image_history) > MAX_HISTORY: image_history.pop(0) def get_next_image(): """Get the next image in history or a random one if at end""" if not image_history: return None # Return random image instead of going to next in history # This ensures we always generate new images when at the end metadata_filename = get_random_image_metadata() if metadata_filename: image_data = get_image_data(metadata_filename) return image_data return None def get_previous_image(): """Get previous image from history""" global image_history if len(image_history) >= 2: # Return the second-to-last item (previous in history) return image_history[-2] elif len(image_history) == 1: return image_history[0] # Return current if only one in history else: return None @app.route("/") def index(): """Main page - get initial random image""" metadata_filename = get_random_image_metadata() if metadata_filename: image_data = get_image_data(metadata_filename) if image_data: add_to_history(image_data) return render_template("index.html", facts=[image_data]) # Fallback to empty page return render_template("index.html", facts=[]) @app.route("/api/facts") def get_facts(): """Return current fact - for backwards compatibility""" if image_history: return jsonify([image_history[-1]]) return jsonify([]) @app.route("/api/fact/") def get_fact(fact_id): """Get a specific fact by ID - this is primarily for demo purposes""" # In our implementation, we don't actually support this since we're generating random images return jsonify({"error": "Not implemented in this version"}), 404 @app.route("/api/image/") def get_image(fact_id): """Get image by ID""" try: # This is a bit tricky because our structure is different now # We'll find the metadata file with that id and return its image image_filename = f"{fact_id}~orig.jpg" full_image_path = os.path.join(IMAGES_PATH, image_filename) if os.path.exists(full_image_path): return send_file(full_image_path) else: return "Image not found", 404 except Exception as e: return f"Error: {e}", 500 @app.route("/api/random-image") def get_random_image(): """Get a random image with metadata""" metadata_filename = get_random_image_metadata() if metadata_filename: image_data = get_image_data(metadata_filename) if image_data: add_to_history(image_data) return jsonify(image_data) return jsonify({"error": "No images available"}), 404 @app.route("/api/next-image") def get_next_image_route(): """Get next image (random)""" next_image = get_next_image() if next_image: add_to_history(next_image) return jsonify(next_image) return jsonify({"error": "No more images"}), 404 @app.route("/api/previous-image") def get_previous_image_route(): """Get previous image from history""" prev_image = get_previous_image() if prev_image: return jsonify(prev_image) return jsonify({"error": "No previous image"}), 404 if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=6008)