README.md

# PodcastRSS

An Elixir library for generating podcast RSS feeds in RSS 2.0 format with iTunes and Podcast Index namespace support.

PodcastRSS provides a pipeline-friendly API for creating podcast feeds with sensible defaults and support for modern podcast features. It focuses on simplicity and readability while supporting all the core requirements for podcast distribution.

## Features

- **RSS 2.0 Compliant** - Generates valid RSS feeds for podcast distribution
- **iTunes Support** - Built-in support for iTunes podcast tags
- **Podcast Index** - Support for modern Podcast Index namespace features
- **Pipeline API** - Clean, chainable functions for easy feed construction
- **Fast XML Generation** - Uses Saxy for efficient XML serialization

## Installation

Add `podcast_rss` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:podcast_rss, "~> 0.1.0"}
  ]
end
```

## Quick Start

```elixir
alias PodcastRSS.Episode

# Create an episode
episode = Episode.new()
  |> Episode.title("The Birth of the NES")
  |> Episode.description("How Nintendo revolutionized home gaming in 1985")
  |> Episode.enclosure("https://example.com/episodes/nes-birth.mp3", 45678901, "audio/mpeg")
  |> Episode.guid("retro-001-nes-birth")

# Create a podcast feed
feed_xml = PodcastRSS.new()
  |> PodcastRSS.title("Retro Gaming Chronicles")
  |> PodcastRSS.link("https://example.com")
  |> PodcastRSS.description("Exploring the golden age of video games")
  |> PodcastRSS.self_link("https://feeds.example.com/rss")
  |> PodcastRSS.image("https://example.com/cover.png")
  |> PodcastRSS.language("en-us")
  |> PodcastRSS.category("Technology")
  |> PodcastRSS.add_episode(episode)
  |> PodcastRSS.to_xml()

IO.puts(feed_xml)
```

## Usage

### Creating a Channel

The `PodcastRSS.new/0` function creates a channel with useful defaults:

- Pre-registers common namespaces (iTunes, Podcast Index, Atom)
- Sets language to "en-us"
- Adds iTunes block and complete tags with sensible defaults

```elixir
channel = PodcastRSS.new()
  |> PodcastRSS.title("My Podcast")
  |> PodcastRSS.description("A fascinating podcast about interesting topics")
  |> PodcastRSS.link("https://example.com")
  |> PodcastRSS.self_link("https://feeds.example.com/rss")
  |> PodcastRSS.image("https://example.com/cover.jpg")
```

### Adding Episodes

Episodes are created using the `PodcastRSS.Episode` module:

```elixir
alias PodcastRSS.Episode

episode = Episode.new()
  |> Episode.title("Episode 1: Getting Started")
  |> Episode.description("Our first episode covers the basics")
  |> Episode.enclosure("https://cdn.example.com/episode1.mp3", 98765432, "audio/mpeg")
  |> Episode.guid("episode-001")

channel = PodcastRSS.add_episode(channel, episode)
```

### Categories

Set iTunes categories and subcategories:

```elixir
channel = PodcastRSS.category(channel, "Arts")
# or with subcategory
channel = PodcastRSS.category(channel, "Arts", "Design")
```

### Custom Fields and Namespaces

Add custom fields for extended functionality:

```elixir
channel = PodcastRSS.new()
  |> PodcastRSS.register_namespace("dc", "http://purl.org/dc/elements/1.1/")
  |> PodcastRSS.custom_field("dc:creator", "John Doe")
```

### Low-Level API

For more control, use the `PodcastRSS.Channel` module directly:

```elixir
alias PodcastRSS.Channel

channel = Channel.new()  # No defaults
  |> Channel.title("My Podcast")
  |> Channel.description("Custom channel")
```

## Architecture

PodcastRSS follows a clear separation between high-level convenience and low-level control:

- **`PodcastRSS`** - High-level "batteries included" API with sensible defaults
- **`PodcastRSS.Channel`** - Low-level channel API for direct control
- **`PodcastRSS.Episode`** - Episode/item management
- **`PodcastRSS.XML`** - XML generation using Saxy

## Testing

Run the test suite:

```bash
mix test
```

## Documentation

Generate documentation:

```bash
mix docs
```

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Write tests for your changes
4. Ensure all tests pass (`mix test`)
5. Format your code (`mix format`)
6. Commit your changes (`git commit -am 'Add some feature'`)
7. Push to the branch (`git push origin my-new-feature`)
8. Create a new Pull Request

## License

This project is licensed under the MIT License.

## Acknowledgments

- Built with [Saxy](https://github.com/qcam/saxy) for fast XML generation
- Inspired by podcast RSS standards and iTunes podcast requirements
- Supports modern Podcast Index namespace features