#!/usr/bin/env python3
"""
Basic script to generate static HTML pages for ICE detention facilities
"""
import json
import os
def load_facilities_data():
"""Load facilities data from JSON file"""
with open('src/data/facilities.json', 'r') as f:
return json.load(f)
def create_facilities_directory():
"""Create facilities directory if it doesn't exist"""
os.makedirs('public/facilities', exist_ok=True)
def generate_facility_page(facility, index):
"""Generate HTML page for a single facility"""
name = facility['name']
address = facility['address']
population = facility['population_count']
lat = facility['latitude']
lng = facility['longitude']
# Create URL-friendly name
url_name = name.lower().replace(' ', '-').replace('/', '-').replace(',', '').replace('(', '').replace(')', '')
# Generate state from address
state = address.split(', ')[-2] if ', ' in address else 'Unknown'
html = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>""" + name + """ - ICE Detention Facility | Population & Location</title>
<meta name="description" content="""" + name + """ is an ICE detention facility located in """ + address + """ with a population of """ + str(population) + """ detainees. Get detailed information about this immigration detention center.">
<meta name="keywords" content="""" + name + """, ICE detention, immigration detention center, """ + state + """, detention facility, population """ + str(population) + """">
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:title" content="""" + name + """ - ICE Detention Facility">
<meta property="og:description" content="""" + name + """ immigration detention facility information including location, population, and statistics.">
<meta property="og:url" content="https://ice-locator-mcp.vercel.app/facilities/""" + url_name + """.html">
<meta property="og:site_name" content="ICE Facility Locator">
<!-- Twitter -->
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="""" + name + """ - ICE Detention Facility">
<meta name="twitter:description" content="""" + name + """ immigration detention facility information.">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.header {
background: linear-gradient(135deg, #1e40af, #3b82f6);
color: white;
padding: 2rem;
border-radius: 8px;
margin-bottom: 2rem;
text-align: center;
}
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin: 2rem 0;
}
.stat-card {
background: #f8fafc;
padding: 1.5rem;
border-radius: 8px;
border-left: 4px solid #3b82f6;
}
.stat-number {
font-size: 2rem;
font-weight: bold;
color: #1e40af;
}
.stat-label {
color: #64748b;
font-size: 0.9rem;
}
.map-container {
height: 400px;
margin: 2rem 0;
border-radius: 8px;
overflow: hidden;
border: 1px solid #e2e8f0;
}
.back-link {
display: inline-block;
margin-bottom: 2rem;
color: #3b82f6;
text-decoration: none;
padding: 0.5rem 1rem;
border: 1px solid #3b82f6;
border-radius: 4px;
}
.back-link:hover {
background: #3b82f6;
color: white;
}
</style>
</head>
<body>
<a href="../index.html" class="back-link">← Back to Home</a>
<a href="index.html" class="back-link">← All Facilities</a>
<div class="header">
<h1>""" + name + """</h1>
<p>ICE Immigration Detention Facility</p>
</div>
<div class="stats">
<div class="stat-card">
<div class="stat-number">""" + str(population) + """</div>
<div class="stat-label">Current Population</div>
</div>
<div class="stat-card">
<div class="stat-number">""" + state + """</div>
<div class="stat-label">State</div>
</div>
<div class="stat-card">
<div class="stat-number">#""" + str(index + 1) + """</div>
<div class="stat-label">Facility Rank</div>
</div>
</div>
<h2>Facility Information</h2>
<div class="stat-card">
<h3>Location Details</h3>
<p><strong>Address:</strong> """ + address + """</p>
<p><strong>Coordinates:</strong> """ + str(lat) + """, """ + str(lng) + """</p>
<p><strong>State:</strong> """ + state + """</p>
</div>
<h2>Interactive Map</h2>
<div class="map-container">
<iframe
width="100%"
height="100%"
frameborder="0"
style="border:0"
src="https://www.google.com/maps/embed/v1/place?key=AIzaSyBFw0Qbyq9zTFTd-tUY6dOMLD0k9XKTtf8&q=""" + str(lat) + """,""" + str(lng) + """&zoom=15"
allowfullscreen>
</iframe>
</div>
<h2>About This Facility</h2>
<p>""" + name + """ is an Immigration and Customs Enforcement (ICE) detention facility located in """ + address + """. This facility is part of the U.S. immigration detention system and currently holds """ + str(population) + """ detainees.</p>
<p>The facility provides detention services for individuals awaiting immigration proceedings or deportation. ICE detention facilities are operated by private contractors or local governments under contract with the federal government.</p>
<h2>Related Facilities</h2>
<p>Compare with other major ICE detention facilities:</p>
<ul>
<li><a href="adelanto-ice-processing-center.html">Adelanto ICE Processing Center</a></li>
<li><a href="stewart-detention-center.html">Stewart Detention Center</a></li>
<li><a href="otay-mesa-detention-center.html">Otay Mesa Detention Center</a></li>
<li><a href="eloy-detention-center.html">Eloy Detention Center</a></li>
</ul>
<h2>Data Sources</h2>
<p>Information provided by <a href="https://tracreports.org/" target="_blank">TRAC Reports</a> from Syracuse University. Data is updated monthly and represents average daily population counts.</p>
<footer style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid #e2e8f0; color: #64748b; text-align: center;">
<p>© 2025 ICE Facility Locator. Data transparency for immigration detention.</p>
</footer>
</body>
</html>"""
return html
def generate_facilities_index_page(facilities):
"""Generate the main facilities index page"""
# Sort facilities by population (descending)
sorted_facilities = sorted(facilities, key=lambda x: x['population_count'], reverse=True)
# Get statistics
total_facilities = len(facilities)
total_population = sum(f['population_count'] for f in facilities)
avg_population = total_population / total_facilities
# Group by state
states = {}
for facility in facilities:
state = facility['address'].split(', ')[-2] if ', ' in facility['address'] else 'Unknown'
if state not in states:
states[state] = []
states[state].append(facility)
html = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ICE Detention Facilities Directory | Complete List & Statistics</title>
<meta name="description" content="Complete directory of """ + str(total_facilities) + """ ICE detention facilities across the United States. Find locations, population data, and statistics for immigration detention centers.">
<meta name="keywords" content="ICE facilities, detention centers, immigration detention, facility directory, population statistics">
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:title" content="ICE Detention Facilities Directory">
<meta property="og:description" content="Complete directory of ICE detention facilities with locations and population data.">
<meta property="og:url" content="https://ice-locator-mcp.vercel.app/facilities/index.html">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header {
background: linear-gradient(135deg, #1e40af, #3b82f6);
color: white;
padding: 2rem;
border-radius: 8px;
margin-bottom: 2rem;
text-align: center;
}
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
margin: 2rem 0;
}
.stat-card {
background: #f8fafc;
padding: 1.5rem;
border-radius: 8px;
border-left: 4px solid #3b82f6;
text-align: center;
}
.stat-number {
font-size: 2.5rem;
font-weight: bold;
color: #1e40af;
}
.stat-label {
color: #64748b;
font-size: 0.9rem;
margin-top: 0.5rem;
}
.facilities-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1rem;
margin: 2rem 0;
}
.facility-card {
background: white;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 1.5rem;
transition: box-shadow 0.2s;
}
.facility-card:hover {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.facility-name {
font-size: 1.2rem;
font-weight: 600;
color: #1e40af;
margin-bottom: 0.5rem;
}
.facility-location {
color: #64748b;
margin-bottom: 1rem;
}
.facility-population {
font-size: 1.5rem;
font-weight: bold;
color: #dc2626;
}
.state-section {
margin-bottom: 2rem;
}
.state-header {
background: #f1f5f9;
padding: 1rem;
border-radius: 8px;
margin-bottom: 1rem;
font-weight: 600;
color: #334155;
}
.back-link {
display: inline-block;
margin-bottom: 2rem;
color: #3b82f6;
text-decoration: none;
padding: 0.5rem 1rem;
border: 1px solid #3b82f6;
border-radius: 4px;
}
.back-link:hover {
background: #3b82f6;
color: white;
}
</style>
</head>
<body>
<a href="../index.html" class="back-link">← Back to Home</a>
<div class="header">
<h1>ICE Detention Facilities Directory</h1>
<p>Complete list of """ + str(total_facilities) + """ immigration detention facilities across the United States</p>
</div>
<div class="stats">
<div class="stat-card">
<div class="stat-number">""" + str(total_facilities) + """</div>
<div class="stat-label">Total Facilities</div>
</div>
<div class="stat-card">
<div class="stat-number">""" + str(total_population) + """</div>
<div class="stat-label">Total Population</div>
</div>
<div class="stat-card">
<div class="stat-number">""" + f"{avg_population".1f"}" + """</div>
<div class="stat-label">Average per Facility</div>
</div>
</div>
<h2>Facilities by State</h2>"""
# Add state sections
for state in sorted(states.keys()):
facilities_in_state = states[state]
html += """
<div class="state-section">
<div class="state-header">
""" + state + """ (""" + str(len(facilities_in_state)) + """ facilities)
</div>
<div class="facilities-grid">"""
for facility in sorted(facilities_in_state, key=lambda x: x['population_count'], reverse=True):
name = facility['name']
address = facility['address']
population = facility['population_count']
url_name = name.lower().replace(' ', '-').replace('/', '-').replace(',', '').replace('(', '').replace(')', '')
html += """
<div class="facility-card">
<div class="facility-name">""" + name + """</div>
<div class="facility-location">""" + address + """</div>
<div class="facility-population">""" + str(population) + """ detainees</div>
<a href="""" + url_name + """.html" style="color: #3b82f6; text-decoration: none; font-size: 0.9rem;">View Details →</a>
</div>"""
html += """
</div>
</div>"""
html += """
<h2>About This Directory</h2>
<p>This directory contains information about all ICE detention facilities currently in operation across the United States. Data includes facility locations, population counts, and operational details.</p>
<p>Information is sourced from <a href="https://tracreports.org/" target="_blank">TRAC Reports</a> and updated regularly to provide the most current information available.</p>
<footer style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid #e2e8f0; color: #64748b; text-align: center;">
<p>© 2025 ICE Facility Locator. Data transparency for immigration detention.</p>
</footer>
</body>
</html>"""
return html
def main():
"""Main function to generate all static pages"""
print("Loading facilities data...")
data = load_facilities_data()
facilities = data['facilities']
print(f"Found {len(facilities)} facilities")
# Create facilities directory
create_facilities_directory()
# Generate facilities index page
print("Generating facilities index page...")
index_html = generate_facilities_index_page(facilities)
with open('public/facilities/index.html', 'w') as f:
f.write(index_html)
# Generate individual facility pages (top 30 by population)
print("Generating individual facility pages...")
sorted_facilities = sorted(facilities, key=lambda x: x['population_count'], reverse=True)[:30]
for i, facility in enumerate(sorted_facilities):
print(f" Generating page for {facility['name']}...")
facility_html = generate_facility_page(facility, i)
url_name = facility['name'].lower().replace(' ', '-').replace('/', '-').replace(',', '').replace('(', '').replace(')', '')
with open(f'public/facilities/{url_name}.html', 'w') as f:
f.write(facility_html)
print("✅ Static pages generated successfully!")
print(" - Facilities index: public/facilities/index.html")
print(f" - Individual pages: {len(sorted_facilities)} facility pages")
if __name__ == "__main__":
main()