Building rebuild_typescript_course.py
๐ Building rebuild_typescript_course.py
rebuild_typescript_course.py is the complete automation script that uses all the tools from chapters 1-4: navigating the filesystem (paths), loading configuration (.env), connecting to databases, and using db_utils to populate the database with generated course chapters. This is a real-world, production-ready script.
๐ Overview: What This Script Does
The script automates the complete workflow:
Use Path and glob() to find all ts1-*.html files
Read HTML files and extract title from <h2> tags with regex
Load .env and use DatabaseConnection to connect
Use get_or_create_subtopic() to create TypeScript Fundamentals course
For each chapter, call insert_chapter_with_content()
Display summary of what was created
๐ Directory Structure
The script expects this layout:
myapp/
โโโ .env โ Configuration (loaded by script)
โโโ rebuild_typescript_course.py โ This script
โโโ courses/
โโโ Programming/
โโโ TypeScript/
โโโ html/
โโโ ts1-1.html โ Chapter files
โโโ ts1-2.html
โโโ ts1-3.html
...
โโโ ts1-12.html
Using Path(__file__).parent, the script can navigate relative to itself. No matter where you run it from, it finds the chapters in the correct location.
๐ง Main Components
Imports & Constants
from pathlib import Path import sys import re from db_utils import DatabaseConnection, get_or_create_subtopic, insert_chapter_with_content # Constants SUBJECT_ID = 3 # Programming subject SUBJECT_NAME = "Programming" SUBTOPIC_NAME = "TypeScript Fundamentals" # Calculate path to chapters directory SCRIPT_DIR = Path(__file__).resolve().parent CHAPTERS_DIR = SCRIPT_DIR / "courses" / "Programming" / "TypeScript" / "html"
Finding Chapter Files
def find_chapters() -> list: """Find all chapter HTML files.""" if not CHAPTERS_DIR.exists(): print(f"โ Chapters directory not found: {CHAPTERS_DIR}") return [] # Find all ts1-*.html files and sort them html_files = sorted(CHAPTERS_DIR.glob("ts1-*.html")) if not html_files: print(f"โ ๏ธ No chapter files found in {CHAPTERS_DIR}") return [] print(f"โ Found {len(html_files)} chapter files") return html_files
Parsing Chapter Data
def parse_chapter(html_file: Path) -> dict: """Extract chapter data from HTML file.""" try: # Read HTML content html_content = html_file.read_text(encoding='utf-8') # Extract chapter number from filename (ts1-1.html โ 1) match = re.match(r"ts1-(\d+)", html_file.stem) if not match: return None chapter_num = int(match.group(1)) # Extract title from <h2> tag title_match = re.search(r'<h2>(.*?)</h2>', html_content) chapter_title = title_match.group(1) if title_match else f"Chapter {chapter_num}" return { 'number': chapter_num, 'title': chapter_title, 'html': html_content, 'sort_order': chapter_num * 10 } except Exception as e: print(f"โ Error parsing {html_file.name}: {e}") return None
Main Workflow
def main(): """Main rebuild workflow.""" print("=" * 60) print("๐ TypeScript Course Rebuild") print("=" * 60 + "\n") # Step 1: Find chapters html_files = find_chapters() if not html_files: exit(1) # Step 2: Connect to database print("\n๐ Connecting to database...") db = DatabaseConnection() if not db.connect(): exit(1) try: # Step 3: Create or get subtopic print("\n๐ Creating course...") subtopic_id = get_or_create_subtopic( db, subject_id=SUBJECT_ID, subtopic_name=SUBTOPIC_NAME, description="Master TypeScript from fundamentals to advanced patterns" ) if subtopic_id is None: print("โ Failed to create subtopic") exit(1) # Step 4: Insert chapters print(f"\n๐ Inserting {len(html_files)} chapters...") inserted_count = 0 for html_file in html_files: chapter = parse_chapter(html_file) if not chapter: continue page_id = insert_chapter_with_content( db, subtopic_id=subtopic_id, chapter_title=chapter['title'], html_content=chapter['html'], sort_order=chapter['sort_order'] ) if page_id: inserted_count += 1 # Step 5: Report results print("\n" + "=" * 60) print(f"โ REBUILD COMPLETE!") print("=" * 60) print(f"Course: {SUBTOPIC_NAME}") print(f"Chapters inserted: {inserted_count}") finally: db.disconnect() if __name__ == "__main__": main()
๐ Key Patterns Used
| Pattern | From Chapter | Purpose |
|---|---|---|
| Path(__file__).parent | Chapter 1 | Find script's directory |
| glob("ts1-*.html") | Chapter 1 | Find all chapter files |
| load_dotenv() | Chapter 2 | Load database credentials |
| DatabaseConnection | Chapter 3 | Connect to database |
| get_or_create_subtopic() | Chapter 4 | Create course |
| insert_chapter_with_content() | Chapter 4 | Insert chapters |
๐ Running the Script
# From the myapp directory: python rebuild_typescript_course.py # Output: ============================================================ ๐ TypeScript Course Rebuild ============================================================ โ Found 12 chapter files ๐ Connecting to database... โ Database connection established ๐ Creating course... โ Created subtopic 'TypeScript Fundamentals' with ID 8 ๐ Inserting 12 chapters... โ Created chapter with ID: 101 โ Created chapter with ID: 102 โ Created chapter with ID: 103 ... ============================================================ โ REBUILD COMPLETE! ============================================================ Course: TypeScript Fundamentals Chapters inserted: 12
๐ป Coding Challenges
Challenge 1: Test File Discovery
Create a script that:
- Uses Path(__file__) to find its directory
- Navigates to courses/Programming/TypeScript/html/
- Uses glob() to find all ts1-*.html files
- Reports how many found and lists them
Goal: Practice path navigation and file discovery.
Challenge 2: Parse Chapter Metadata
Create a script that:
- Finds all chapter HTML files
- For each file, extract: chapter number, title from <h2>
- Display a table with all chapters
- Show chapter count
Goal: Practice HTML parsing with regex.
Challenge 3: Complete Rebuild Script
Create a script that:
- Finds all chapter files
- Parses metadata from HTML
- Connects to database using db_utils
- Creates subtopic and inserts all chapters
- Reports final count
Goal: Build the complete automation workflow.
๐ฏ What's Next
Chapter 6, the final chapter, covers Building Your Own Utilities โ how to take the patterns you've learned and create your own reusable scripts for any project. You'll also learn best practices for organizing, documenting, and testing your utilities.