Metadata-Version: 2.5
Name: gencon-audiobook
Version: 0.2.0
Summary: Download General Conference talks as a complete audiobook (m4b) and epub with full transcripts
Project-URL: Homepage, https://github.com/XeroIP/gencon-audiobook
Project-URL: Repository, https://github.com/XeroIP/gencon-audiobook
Project-URL: Bug Tracker, https://github.com/XeroIP/gencon-audiobook/issues
Author: XeroIP
License: MIT
License-File: LICENSE
License-File: LICENSE-CONTENT.md
Keywords: audiobook,epub,general-conference,latter-day-saints,lds,m4b
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: click>=8.0
Requires-Dist: mutagen>=1.47
Requires-Dist: pillow>=10.0
Requires-Dist: requests>=2.28
Requires-Dist: rich>=13.0
Requires-Dist: static-ffmpeg>=2.7
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy>=1.9; extra == 'dev'
Requires-Dist: pip-audit>=2.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: responses>=0.23; extra == 'dev'
Requires-Dist: ruff>=0.3; extra == 'dev'
Requires-Dist: types-beautifulsoup4>=4.12; extra == 'dev'
Requires-Dist: types-requests>=2.31; extra == 'dev'
Description-Content-Type: text/markdown

# gencon-audiobook

[![CI](https://github.com/XeroIP/gencon-audiobook/actions/workflows/ci.yml/badge.svg)](https://github.com/XeroIP/gencon-audiobook/actions/workflows/ci.yml)
[![PyPI version](https://img.shields.io/pypi/v/gencon-audiobook)](https://pypi.org/project/gencon-audiobook/)
[![Python versions](https://img.shields.io/pypi/pyversions/gencon-audiobook)](https://pypi.org/project/gencon-audiobook/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Download General Conference talks from [churchofjesuschrist.org](https://www.churchofjesuschrist.org) and produce:

- A **chaptered `.m4b` audiobook** — one chapter per talk, with speaker name in the chapter title, cover art, and full metadata
- An **`.epub` companion** — full transcripts, speaker photos, nested session/talk table of contents, and theme-safe CSS (dark mode, sepia, and accessibility modes all work)

Single `pip install`, no prerequisites beyond Python 3.10+. ffmpeg is located automatically — on your PATH if present, otherwise downloaded once via `static-ffmpeg`.

Inspired by [General-Conference-to-Audiobook](https://github.com/ChurchofJesusChristDev/General-Conference-to-Audiobook).

> **Disclaimer:** This is an unofficial tool not affiliated with The Church of Jesus Christ of Latter-day Saints. General Conference content is copyright Intellectual Reserve, Inc. All rights reserved. This tool downloads content for personal, noncommercial use as permitted by the Church's Terms of Use.

---

## Installation

```bash
pip install gencon-audiobook
```

Python 3.10 or newer is required. All other dependencies, including ffmpeg, are handled automatically. ffmpeg 1.0+ is required for per-file progress display during conversion; any ffmpeg from a package manager or the `static-ffmpeg` fallback exceeds this.

New to the terminal or Python? See the [User Guide](https://github.com/XeroIP/gencon-audiobook/wiki/User-Guide) for step-by-step instructions.

---

## Usage

```bash
# Download the most recent conference (both audiobook and epub)
gencon-audiobook

# Select a specific conference
gencon-audiobook --conference 2024-04

# Audiobook only (skip epub)
gencon-audiobook --audiobook-only

# EPUB only (skip audiobook and audio download)
gencon-audiobook --epub-only

# Custom output directory
gencon-audiobook --output ~/Books

# Rebuild existing output files
gencon-audiobook --overwrite

# Re-scrape fresh data from the Church website (bypass local cache)
gencon-audiobook --force-scrape

# Reduce file size (lower bitrate and sample rate)
gencon-audiobook --bitrate 32k --sample-rate 22050

# Use higher-quality video audio when older MP3 audio is worse
gencon-audiobook --conference 2024-04 --prefer-video-audio

# Show detailed progress in the terminal
gencon-audiobook --verbose

# Add paragraph numbers to EPUB transcripts (useful for study groups and citations)
gencon-audiobook --epub-paragraph-numbers

# Build from the talks posted so far while a conference is still being published
gencon-audiobook --conference 2026-10 --allow-partial
```

For the full options reference, file size guide, and platform compatibility notes, see the [User Guide](https://github.com/XeroIP/gencon-audiobook/wiki/User-Guide).

---

## Output structure

```
~/gencon-audiobook/
  April 2024 General Conference/
    April 2024 General Conference.m4b    # Chaptered audiobook
    April 2024 General Conference.epub   # Transcript companion
    cover.jpg                            # Conference cover image
    conference.json                      # Cached conference metadata (skip re-scraping)
    audio/                               # Downloaded MP3 files
    speakers/                            # Speaker photos
    inline/                              # Inline body images embedded in the EPUB
    gencon-audiobook.log                 # Full DEBUG log for troubleshooting
```

Running the tool a second time skips files that already exist and loads conference metadata from `conference.json` instead of re-scraping the Church website. Use `--overwrite` to rebuild output files. Use `--force-scrape` to bypass the metadata cache and fetch fresh data from the Church website.

### Newly held conferences

The Church website lists each conference before it is held and posts talks and audio over the days after it ends.

- Before any talks are posted, running with no `--conference` uses the previous conference instead; asking for the new one by name (`--conference 2026-10`) reports that it has not been published yet.
- While some talks are still missing, the tool lists them and stops without downloading or writing anything. Run the same command again once they are posted. To build from the talks available now, add `--allow-partial`; that build is never cached, and `--overwrite` rebuilds the complete conference later.

For older conferences, the tool checks whether the 360p video has better audio than the MP3 source. If it does, the default run warns you before downloading. Re-run with `--prefer-video-audio` to extract the higher-quality AAC track from video files. This takes significantly longer and requires much more disk space, so the tool shows estimated download and audio-cache sizes before starting.

---

## Documentation

- [User Guide](https://github.com/XeroIP/gencon-audiobook/wiki/User-Guide) — full options reference, file size guide, platform support, troubleshooting
- [Listening/Reading Guide](https://github.com/XeroIP/gencon-audiobook/wiki/Listening-Reading-Guide) — how to open the output files on every platform
- [Architecture](https://github.com/XeroIP/gencon-audiobook/wiki/Architecture) — codebase structure for contributors
- [Technical Decisions](https://github.com/XeroIP/gencon-audiobook/wiki/Technical-Decisions) — design choices with rationale

---

## Development

```bash
git clone https://github.com/XeroIP/gencon-audiobook.git
cd gencon-audiobook
pip install -e ".[dev]"

# Run unit tests (no network required)
pytest tests/ --ignore=tests/test_scraper_live.py --ignore=tests/test_integration.py

# Build source and wheel distributions
python -m build

# Run live smoke tests (hits the real website)
pytest tests/test_scraper_live.py -v -m live

# Run full end-to-end integration test (requires ffmpeg)
pytest tests/test_integration.py -v -m integration
```

### Project layout

```
src/gencon_audiobook/
  cli.py            Click entry point
  scraper.py        Fetch and parse conference listings and talk pages
  downloader.py     Download MP3s, cover, speaker photos, and inline images (parallel)
  audio.py          Convert MP3 to AAC, assemble chaptered m4b
  epub_builder.py   Build EPUB 3 ZIP from transcripts and images
  ffmpeg_manager.py Locate ffmpeg/ffprobe (PATH first, static-ffmpeg fallback)
  cache.py          Save/load Conference metadata to conference.json (skip re-scraping)
  models.py         Conference / Session / Talk / InlineImage dataclasses
  progress.py       Custom Rich progress column (TimeRemainingWithLabel)
  utils.py          sanitize_filename(), validate_url()

tests/
  conftest.py             Shared helpers (ffmpeg discovery, silent MP3, JPEG)
  test_scraper.py         Unit tests against saved HTML fixtures
  test_downloader.py      Mocked HTTP tests
  test_audio.py           Audio pipeline with generated silent fixtures
  test_epub.py            EPUB structure and content validation
  test_cache.py           Cache serialization and version compatibility
  test_cli.py             CLI behavior (all external calls mocked)
  test_utils.py           Filename sanitization and URL validation
  test_ffmpeg_manager.py  ffmpeg/ffprobe discovery and caching
  test_scraper_live.py    Live smoke tests (@pytest.mark.live)
  test_integration.py     End-to-end test (@pytest.mark.integration)
  fixtures/               Saved HTML snapshots for scraper unit tests
```

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

---

## Legal

- **Tool license:** MIT — see [LICENSE](LICENSE)
- **Downloaded content:** Copyright Intellectual Reserve, Inc. — see [LICENSE-CONTENT.md](LICENSE-CONTENT.md)

This tool accesses publicly available content using a transparent User-Agent string, respects `robots.txt`, and applies a rate-limiting delay between requests. It is intended for personal, noncommercial use only.
