Reorganize codebase: separate server architecture from business logic

- Created feed_parser.py module with YouTubeFeedParser and FeedEntry classes
- Refactored main.py to focus on Flask routing with two endpoints:
  - GET / for homepage
  - GET /api/feed for REST API with query parameters
- Updated CLAUDE.md with new architecture documentation
- Implemented clean separation between core logic and web server layers

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-26 13:52:20 -05:00
commit f460fb4daf
9 changed files with 387 additions and 0 deletions

86
CLAUDE.md Normal file
View File

@@ -0,0 +1,86 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
`yottob` is a Flask-based web application for processing YouTube RSS feeds. The project provides both a REST API and CLI interface for fetching and parsing YouTube channel feeds, with filtering logic to exclude YouTube Shorts.
## Development Setup
This project uses `uv` for dependency management.
**Install dependencies:**
```bash
uv sync
```
**Activate virtual environment:**
```bash
source .venv/bin/activate # On macOS/Linux
```
## Running the Application
**Run the CLI feed parser:**
```bash
python main.py
```
This executes the `main()` function which fetches and parses a YouTube channel RSS feed for testing.
**Run the Flask web application:**
```bash
flask --app main run
```
The web server exposes:
- `/` - Main page (renders `index.html`)
- `/api/feed` - API endpoint for fetching feeds
**API Usage Example:**
```bash
# Fetch default channel feed
curl http://localhost:5000/api/feed
# Fetch specific channel (without filtering Shorts)
curl "http://localhost:5000/api/feed?channel_id=CHANNEL_ID&filter_shorts=false"
```
## Architecture
The codebase follows a clean separation between business logic and web server:
### Core Logic Layer
**`feed_parser.py`** - Reusable YouTube feed parsing module
- `YouTubeFeedParser`: Main parser class that encapsulates channel-specific logic
- `FeedEntry`: Data model for individual feed entries
- Independent of Flask - can be imported and used in any Python context
### Web Server Layer
**`main.py`** - Flask application and routes
- `app`: Flask application instance (main.py:7)
- `index()`: Homepage route handler (main.py:14)
- `get_feed()`: REST API endpoint (main.py:20) that uses `YouTubeFeedParser`
- `main()`: CLI entry point for testing (main.py:42)
### Templates
**`templates/index.html`** - Frontend HTML (currently static placeholder)
## Feed Parsing Implementation
The `YouTubeFeedParser` class in `feed_parser.py`:
- Constructs YouTube RSS feed URLs from channel IDs
- Uses feedparser to fetch and parse feeds
- Validates HTTP 200 status before processing
- Optionally filters out YouTube Shorts (any entry with "shorts" in URL)
- Returns structured dictionary with feed metadata and entries
**YouTube RSS Feed URL Format:**
```
https://www.youtube.com/feeds/videos.xml?channel_id={CHANNEL_ID}
```
## Dependencies
- **Flask 3.1.2+**: Web framework
- **feedparser 6.0.12+**: RSS/Atom feed parsing
- **Python 3.14+**: Required runtime version