directory changes and restructuring

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-22 02:01:41 +09:00
parent eea49f9f8c
commit 236be6c580
598 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,398 @@
#!/usr/bin/env python3
"""
Gateway Page Content Generator
Automates the creation of SEO-optimized gateway pages for local services
"""
import json
import os
from datetime import datetime
from typing import Dict, List, Optional
import re
from dataclasses import dataclass
from pathlib import Path
@dataclass
class Location:
"""Location data structure"""
id: str
name_en: str
name_kr: str
full_address: str
landmarks: List[str]
subway_stations: List[str]
demographics: str
latitude: float
longitude: float
@dataclass
class Service:
"""Service data structure"""
id: str
name_en: str
name_kr: str
category: str
description: str
keywords: List[str]
procedure_time: str
recovery_time: str
price_range: str
@dataclass
class Brand:
"""Brand/Clinic information"""
name_en: str
name_kr: str
website: str
phone: str
email: str
established_year: int
certifications: List[str]
unique_selling_points: List[str]
class GatewayPageGenerator:
"""Main class for generating gateway page content"""
def __init__(self, brand: Brand, template_path: str = None):
self.brand = brand
# Use script directory as base for template path
if template_path is None:
script_dir = Path(__file__).parent.parent
self.template_path = script_dir / "templates"
else:
self.template_path = Path(template_path)
self.generated_pages = []
def load_template(self, template_name: str) -> str:
"""Load a template file"""
template_file = self.template_path / template_name
if template_file.exists():
with open(template_file, 'r', encoding='utf-8') as f:
return f.read()
else:
raise FileNotFoundError(f"Template {template_name} not found")
def generate_meta_tags(self, service: Service, location: Location) -> Dict:
"""Generate SEO meta tags"""
return {
"title": f"{service.name_en} in {location.name_en} | Expert {service.category} | {self.brand.name_en}",
"description": f"Looking for {service.name_en.lower()} in {location.name_en}? "
f"{self.brand.name_en} offers professional {service.category.lower()} services. "
f"✓ Experienced team ✓ Latest technology ✓ {self.brand.unique_selling_points[0]}",
"keywords": ", ".join([
f"{service.name_en} {location.name_en}",
f"{location.name_en} {service.name_en}",
*service.keywords,
f"{service.category} {location.name_en}"
]),
"canonical": f"https://{self.brand.website}/{location.id}/{service.id}/",
"og:title": f"{service.name_en} in {location.name_en} - {self.brand.name_en}",
"og:description": f"Professional {service.name_en} services in {location.name_en}. "
f"Book your consultation today.",
"og:image": f"https://{self.brand.website}/images/{service.id}-{location.id}-og.jpg"
}
def generate_schema_markup(self, service: Service, location: Location) -> str:
"""Generate JSON-LD schema markup"""
schema = {
"@context": "https://schema.org",
"@type": "MedicalBusiness",
"name": f"{self.brand.name_en} - {location.name_en}",
"url": f"https://{self.brand.website}",
"telephone": self.brand.phone,
"email": self.brand.email,
"address": {
"@type": "PostalAddress",
"streetAddress": location.full_address,
"addressLocality": location.name_en,
"addressCountry": "KR"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": location.latitude,
"longitude": location.longitude
},
"areaServed": {
"@type": "City",
"name": location.name_en
},
"availableService": {
"@type": "MedicalProcedure",
"name": service.name_en,
"description": service.description
},
"priceRange": service.price_range
}
return json.dumps(schema, indent=2, ensure_ascii=False)
def generate_content_variations(self, service: Service, location: Location) -> Dict[str, List[str]]:
"""Generate content variations for uniqueness"""
return {
"hero_headlines": [
f"Professional {service.name_en} in {location.name_en}",
f"{location.name_en}'s Premier {service.name_en} {service.category}",
f"Expert {service.name_en} Services for {location.name_en} Residents",
f"Transform Your Look with {service.name_en} in {location.name_en}"
],
"intro_paragraphs": [
f"Welcome to {self.brand.name_en}, where we specialize in providing exceptional "
f"{service.name_en} services to the {location.name_en} community. "
f"Our state-of-the-art facility, conveniently located near {location.landmarks[0]}, "
f"combines advanced technology with personalized care.",
f"Looking for trusted {service.name_en} in {location.name_en}? "
f"At {self.brand.name_en}, we've been serving the {location.demographics} "
f"for over {datetime.now().year - self.brand.established_year} years. "
f"Our expert team understands the unique needs of {location.name_en} residents.",
f"Discover why {location.name_en} residents choose {self.brand.name_en} "
f"for their {service.name_en} needs. Located just minutes from "
f"{', '.join(location.subway_stations[:2])}, we offer {service.category} "
f"services that deliver remarkable results."
],
"cta_buttons": [
f"Book Your {location.name_en} Consultation",
f"Schedule {service.name_en} Today",
f"Get Started in {location.name_en}",
f"Reserve Your Appointment"
],
"trust_signals": [
f"Trusted by {location.name_en} residents since {self.brand.established_year}",
f"Over 10,000 successful {service.category} treatments",
f"5-star rated {service.name_en} clinic in {location.name_en}",
f"Certified specialists serving {location.demographics}"
]
}
def localize_content(self, content: str, service: Service, location: Location) -> str:
"""Add local elements to content"""
local_elements = {
"transportation": f"Easily accessible via {', '.join(location.subway_stations)} stations",
"landmarks": f"Located near {' and '.join(location.landmarks[:2])}",
"community": f"Proud to serve the {location.name_en} community",
"convenience": f"Convenient for {location.demographics} in {location.name_en}",
"local_stats": f"Join thousands of satisfied patients from {location.name_en}"
}
# Add local elements naturally throughout content
for key, value in local_elements.items():
placeholder = f"[LOCAL_{key.upper()}]"
if placeholder in content:
content = content.replace(placeholder, value)
return content
def generate_page(self, service: Service, location: Location,
template_name: str = "gateway-page-medical.md") -> str:
"""Generate a complete gateway page"""
# Load template
template = self.load_template(template_name)
# Generate components
meta_tags = self.generate_meta_tags(service, location)
schema = self.generate_schema_markup(service, location)
variations = self.generate_content_variations(service, location)
# Replace placeholders in template
replacements = {
"[Medical Service]": service.name_en,
"[Location]": location.name_en,
"[location]": location.name_en.lower(),
"[Clinic Name]": self.brand.name_en,
"[service-slug]": service.id,
"[X years]": str(datetime.now().year - self.brand.established_year),
"[specific address near landmark]": f"{location.full_address}, near {location.landmarks[0]}",
"[nearby subway/bus stations]": ", ".join(location.subway_stations),
"[certification details]": ", ".join(self.brand.certifications[:2]),
"[equipment type]": f"{service.category} equipment",
"[duration]": service.procedure_time,
"[Medical Specialty]": service.category,
"[phone-number]": self.brand.phone,
"[website-url]": f"https://{self.brand.website}",
"[page-url]": f"https://{self.brand.website}/{location.id}/{service.id}/",
"[latitude]": str(location.latitude),
"[longitude]": str(location.longitude),
}
# Apply replacements
content = template
for placeholder, value in replacements.items():
content = content.replace(placeholder, value)
# Add localized content
content = self.localize_content(content, service, location)
# Add schema markup at the end if not already present
if '"@context": "https://schema.org"' not in content:
content += f"\n\n<!-- Schema Markup -->\n<script type='application/ld+json'>\n{schema}\n</script>"
return content
def generate_batch(self, services: List[Service], locations: List[Location],
output_dir: str = "output/") -> List[str]:
"""Generate multiple gateway pages"""
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
generated_files = []
for location in locations:
location_dir = output_path / location.id
location_dir.mkdir(exist_ok=True)
for service in services:
# Generate content
content = self.generate_page(service, location)
# Save to file
filename = f"{service.id}-{location.id}.md"
filepath = location_dir / filename
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
generated_files.append(str(filepath))
print(f"✓ Generated: {filepath}")
# Generate index file
self.generate_index(services, locations, output_path)
return generated_files
def generate_index(self, services: List[Service], locations: List[Location],
output_path: Path):
"""Generate an index of all created pages"""
index_content = f"# Gateway Pages Index - {self.brand.name_en}\n\n"
index_content += f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}\n\n"
index_content += "## Pages by Location\n\n"
for location in locations:
index_content += f"### {location.name_en}\n"
for service in services:
url = f"/{location.id}/{service.id}/"
index_content += f"- [{service.name_en} in {location.name_en}]({url})\n"
index_content += "\n"
index_content += "## Pages by Service\n\n"
for service in services:
index_content += f"### {service.name_en}\n"
for location in locations:
url = f"/{location.id}/{service.id}/"
index_content += f"- [{location.name_en}]({url})\n"
index_content += "\n"
index_content += f"\n---\nTotal Pages Generated: {len(services) * len(locations)}\n"
with open(output_path / "index.md", 'w', encoding='utf-8') as f:
f.write(index_content)
def create_sample_data():
"""Create sample data for testing"""
# Sample brand
brand = Brand(
name_en="Jamie Clinic",
name_kr="제이미 클리닉",
website="www.jamieclinic.com",
phone="+82-2-1234-5678",
email="info@jamieclinic.com",
established_year=2010,
certifications=["ISO 9001", "KAHF Certified", "JCI Accredited"],
unique_selling_points=[
"Same-day appointments available",
"15+ years of experience",
"Latest medical technology"
]
)
# Sample locations
locations = [
Location(
id="gangnam",
name_en="Gangnam",
name_kr="강남",
full_address="123 Teheran-ro, Gangnam-gu, Seoul",
landmarks=["COEX", "Gangnam Station", "Samsung Station"],
subway_stations=["Gangnam Station (Line 2)", "Sinnonhyeon Station (Line 9)"],
demographics="Young professionals and affluent residents",
latitude=37.4979,
longitude=127.0276
),
Location(
id="myeongdong",
name_en="Myeongdong",
name_kr="명동",
full_address="456 Myeongdong-gil, Jung-gu, Seoul",
landmarks=["Myeongdong Cathedral", "Lotte Department Store"],
subway_stations=["Myeongdong Station (Line 4)", "Euljiro 1-ga Station (Line 2)"],
demographics="Tourists and young shoppers",
latitude=37.5636,
longitude=126.9869
)
]
# Sample services
services = [
Service(
id="laser-hair-removal",
name_en="Laser Hair Removal",
name_kr="레이저 제모",
category="Dermatology",
description="Advanced laser technology for permanent hair reduction",
keywords=["permanent hair removal", "IPL", "diode laser"],
procedure_time="30-60 minutes",
recovery_time="No downtime",
price_range="₩₩₩"
),
Service(
id="botox",
name_en="Botox Treatment",
name_kr="보톡스",
category="Cosmetic Dermatology",
description="FDA-approved botulinum toxin for wrinkle reduction",
keywords=["wrinkle treatment", "anti-aging", "facial rejuvenation"],
procedure_time="15-30 minutes",
recovery_time="No downtime",
price_range="₩₩₩₩"
)
]
return brand, locations, services
def main():
"""Main execution function"""
print("=" * 60)
print("Gateway Page Content Generator")
print("=" * 60)
# Get sample data
brand, locations, services = create_sample_data()
# Initialize generator
generator = GatewayPageGenerator(brand)
# Generate pages
print(f"\nGenerating {len(services) * len(locations)} gateway pages...")
print("-" * 40)
generated_files = generator.generate_batch(services, locations)
print("-" * 40)
print(f"\n✅ Successfully generated {len(generated_files)} pages!")
print(f"📁 Output directory: output/")
print(f"📋 Index file created: output/index.md")
# Generate report
print("\n" + "=" * 60)
print("GENERATION REPORT")
print("=" * 60)
print(f"Brand: {brand.name_en}")
print(f"Locations: {', '.join([loc.name_en for loc in locations])}")
print(f"Services: {', '.join([svc.name_en for svc in services])}")
print(f"Total Pages: {len(generated_files)}")
print(f"Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("=" * 60)
if __name__ == "__main__":
main()