docs: refine README presentation and streamline setup guide
This commit is contained in:
@@ -1,29 +1,61 @@
|
||||
# RadioSync Hub
|
||||
|
||||
RadioSync Hub is a self-hosted podcast synchronization service for selected Polish radio stations. It collects podcast metadata, retrieves protected audio URLs where supported, stores the local catalogue, and exposes podcast feeds for compatible clients.
|
||||

|
||||
|
||||
The project is designed to run on a home server or Raspberry Pi using Docker.
|
||||
**Your radio catalogue, ready for your podcast player.** A self-hosted service that collects podcast metadata from selected Polish radio stations, retrieves protected audio URLs where supported, and exposes feeds for compatible clients.
|
||||
|
||||
[Features](#features) · [Requirements](#requirements) · [Getting started](#getting-started) · [Configuration](#configuration) · [Usage](#usage) · [Architecture](#architecture) · [Limitations](#limitations) · [Development](#development) · [Documentation](#documentation) · [Credits](#credits) · [License](#license)
|
||||
| Project | Deployment | Storage | Output |
|
||||
| --- | --- | --- | --- |
|
||||
| Self-hosted service | Docker Compose | SQLite | RSS + OPML |
|
||||
|
||||
<p align="center">
|
||||
<a href="#getting-started"><strong>Get started</strong></a> ·
|
||||
<a href="#supported-stations">Supported stations</a> ·
|
||||
<a href="#configuration">Configure</a> ·
|
||||
<a href="#usage">Use your feeds</a>
|
||||
</p>
|
||||
|
||||
Designed for a home server or Raspberry Pi. Station credentials and synchronization are managed from the web dashboard.
|
||||
|
||||
<details>
|
||||
<summary>Browse all sections</summary>
|
||||
|
||||
- [Features](#features)
|
||||
- [Requirements](#requirements)
|
||||
- [Getting started](#getting-started)
|
||||
- [Configuration](#configuration)
|
||||
- [Usage](#usage)
|
||||
- [Architecture](#architecture)
|
||||
- [Limitations](#limitations)
|
||||
- [Development](#development)
|
||||
- [Documentation](#documentation)
|
||||
- [Credits](#credits)
|
||||
- [License](#license)
|
||||
|
||||
</details>
|
||||
|
||||
## Features
|
||||
|
||||
- FastAPI web dashboard.
|
||||
- Automatic synchronization using APScheduler.
|
||||
- Manual full-station and single-programme synchronization.
|
||||
- SQLite storage through SQLAlchemy.
|
||||
- RSS feeds generated for locally synchronized episodes.
|
||||
- Master and station-specific OPML files.
|
||||
- Error and warning tracking with acknowledgement from the dashboard.
|
||||
- Grouping of repeated errors and warnings.
|
||||
- Diagnostic snapshots for unexpected API or HTML responses.
|
||||
- ntfy notifications for synchronization errors.
|
||||
- CSRF protection for dashboard actions.
|
||||
- Encrypted configuration values in SQLite, including passwords, tokens, and cookies.
|
||||
- Docker Compose deployment.
|
||||
| Capability | Included behavior |
|
||||
| --- | --- |
|
||||
| **Collect** | Scheduled synchronization with APScheduler; manual station or programme sync. |
|
||||
| **Subscribe** | RSS for synchronized episodes; master and station-specific OPML files. |
|
||||
| **Manage** | FastAPI dashboard, error acknowledgement, and grouped errors and warnings. |
|
||||
| **Diagnose** | Response snapshots for unexpected API or HTML responses; ntfy error notifications. |
|
||||
| **Store** | SQLite through SQLAlchemy; encrypted passwords, tokens, and cookies. |
|
||||
| **Deploy** | Docker Compose with persistent local data; CSRF protection for dashboard actions. |
|
||||
|
||||
### Supported stations
|
||||
|
||||
| Station | Catalogue and feeds | Access |
|
||||
| --- | --- | --- |
|
||||
| **Radio 357** | API metadata with an initial catalogue index and incremental sync. | Authentication for protected audio URLs. |
|
||||
| **Radio Nowy Świat** | Programme and episode pages; recent sync followed by older catalogue backfill. | Logged-in session for patron-only content. |
|
||||
| **Radio Jazz FM** | Discovery of public programme RSS feeds; links to the station's original feeds. | Public feeds. |
|
||||
|
||||
<details>
|
||||
<summary>Station-specific synchronization details</summary>
|
||||
|
||||
#### Radio 357
|
||||
|
||||
- Fetches podcast metadata from the Radio 357 content API.
|
||||
@@ -46,6 +78,8 @@ The project is designed to run on a home server or Raspberry Pi using Docker.
|
||||
|
||||
Radio Jazz FM is treated as a catalogue of public RSS feeds. The service discovers available programmes and links directly to the original feeds hosted by the station.
|
||||
|
||||
</details>
|
||||
|
||||
## Requirements
|
||||
|
||||
- Docker Engine
|
||||
@@ -54,41 +88,43 @@ Radio Jazz FM is treated as a catalogue of public RSS feeds. The service discove
|
||||
|
||||
## Getting started
|
||||
|
||||
First complete [Configuration](#configuration), then start the service:
|
||||
### Prepare the local files
|
||||
|
||||
The repository contains `docker-compose.example.yml` as a portable default configuration. Copy it to `docker-compose.yml` before starting the service:
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
cp docker-compose.example.yml docker-compose.yml
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
The copied `docker-compose.yml` is ignored by Git, so it can be customized locally without affecting the public repository. The example exposes port `8000` directly, which is convenient for a local installation.
|
||||
Both local configuration files are ignored by Git. The Compose example exposes port `8000` directly.
|
||||
|
||||
Build and start the service:
|
||||
### Set your keys
|
||||
|
||||
Follow [Configuration](#configuration) to generate and set both keys in `.env` before starting the service.
|
||||
|
||||
### Start the service
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Open the dashboard at:
|
||||
**Open the dashboard:** [http://localhost:8000](http://localhost:8000), or your server's address on port `8000`. Configure station credentials in the dashboard.
|
||||
|
||||
```text
|
||||
http://localhost:8000
|
||||
```
|
||||
The `data/` directory is mounted into the container, so the database survives container rebuilds.
|
||||
|
||||
View container logs:
|
||||
<details>
|
||||
<summary>View logs or stop the service</summary>
|
||||
|
||||
```bash
|
||||
# Follow application logs
|
||||
docker compose logs -f radiosync
|
||||
```
|
||||
|
||||
Stop the service:
|
||||
|
||||
```bash
|
||||
# Stop the service
|
||||
docker compose down
|
||||
```
|
||||
|
||||
The `data/` directory is mounted as a Docker volume, so the database survives container rebuilds.
|
||||
</details>
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -108,7 +144,7 @@ python3 -c "import base64, secrets; print(base64.urlsafe_b64encode(secrets.token
|
||||
|
||||
`RADIOSYNC_SECRET_KEY` signs browser sessions. `RADIOSYNC_CONFIG_KEY` encrypts sensitive values stored in SQLite.
|
||||
|
||||
Keep both keys safe and do not change them after the application has stored credentials. Losing or changing the encryption key makes existing encrypted configuration unreadable.
|
||||
> **Keep your keys** — Back up both keys and keep them stable after storing credentials. Losing or changing `RADIOSYNC_CONFIG_KEY` makes existing encrypted configuration unreadable.
|
||||
|
||||
The repository includes `.env.example` as a template. Never commit `.env`, the SQLite database, or the contents of `data/`.
|
||||
|
||||
@@ -136,6 +172,9 @@ Station names are `radio357`, `rns`, and `jazz`.
|
||||
|
||||
### Diagnostics
|
||||
|
||||
<details>
|
||||
<summary>Diagnostic codes and response snapshots</summary>
|
||||
|
||||
Unexpected responses are recorded with a diagnostic code such as:
|
||||
|
||||
- `HTTP_ERROR`
|
||||
@@ -148,8 +187,19 @@ Unexpected responses are recorded with a diagnostic code such as:
|
||||
|
||||
When possible, the response is saved under `data/diagnostics/` for investigation. Diagnostic snapshots can contain website HTML and should be treated as local operational data.
|
||||
|
||||
</details>
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
Station APIs / websites → Scrapers → Local SQLite catalogue → RSS / OPML
|
||||
↑
|
||||
Scheduler + web dashboard
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Repository layout</summary>
|
||||
|
||||
```text
|
||||
.
|
||||
├── core/
|
||||
@@ -171,6 +221,8 @@ When possible, the response is saved under `data/diagnostics/` for investigation
|
||||
└── .env.example
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Limitations
|
||||
|
||||
This project relies on unofficial endpoints and the current HTML structure of the station websites. The stations may change those interfaces without notice. The scrapers therefore validate responses, retry transient failures, preserve existing data, and report unexpected changes through the dashboard and ntfy.
|
||||
@@ -198,7 +250,11 @@ python -m py_compile main.py core/*.py core/scrapers/*.py
|
||||
|
||||
## Documentation
|
||||
|
||||
[README style guide](docs/README-STYLE.md).
|
||||
| Reference | What you will find |
|
||||
| --- | --- |
|
||||
| [Environment example](.env.example) | Required application keys. |
|
||||
| [Compose example](docker-compose.example.yml) | Portable container deployment. |
|
||||
| [README style guide](docs/README-STYLE.md) | Shared documentation structure and presentation rules. |
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
+18
-2
@@ -1,12 +1,12 @@
|
||||
# Repository README standard
|
||||
|
||||
Version: 1.0. Documentation language: English.
|
||||
Version: 1.1. Documentation language: English.
|
||||
|
||||
A README should explain the project, help a new reader start it, and point to detailed references. Keep project-specific instructions and existing attribution when applying this standard.
|
||||
|
||||
## Original projects
|
||||
|
||||
Start with one `# Project name` heading and a short description of what the project does and who it serves. An optional local screenshot or banner may follow. Then add a navigation line linking to the level-two sections present in the document.
|
||||
Start with one `# Project name` heading and a short description of what the project does and who it serves. An optional local screenshot or banner may follow. Follow with a compact project facts table and three or four primary navigation links. Put the complete section navigation inside a `Browse all sections` disclosure.
|
||||
|
||||
Use these level-two headings in this order. Omit sections that do not apply; do not add empty sections or filler just to match the template.
|
||||
|
||||
@@ -69,6 +69,22 @@ Borrowing a component or taking inspiration from another project does not by its
|
||||
- Preserve existing technical instructions, screenshots, credits, and license notices when reorganizing. Move long references into `docs/` when useful and update links relative to their new location.
|
||||
- Never infer a license from a badge, framework, dependency, or a different repository. License choices require an explicit project decision.
|
||||
|
||||
## Presentation
|
||||
|
||||
Use the same visual hierarchy for original projects and forks:
|
||||
|
||||
1. A plain H1 with the project name.
|
||||
2. An optional repository-local SVG banner or real product screenshot, with meaningful alt text. Use a short, factual tagline and a simple product-specific illustration. Keep text readable at narrow widths, and preserve an existing project logo or identity.
|
||||
3. A one-paragraph description with a bold opening sentence.
|
||||
4. A compact facts table with one row and three or four columns, such as project type, platform, deployment, storage, or license. Include only verified facts.
|
||||
5. Three or four primary action links, optionally centered with `<p align="center">`. Use real destinations such as Getting started, Releases, Configuration, and Usage. Do not imply a download exists unless one is available.
|
||||
6. A short fork-identity callout for forks, linking to both this repository and upstream and distinguishing their downloads.
|
||||
7. A `<details>` block labeled `Browse all sections` with links to every level-two section.
|
||||
|
||||
Use short two- or three-column tables for grouped capabilities, station/platform support, fork changes, and documentation links. Keep ordinary prose for explanations. Put long file trees, diagnostic references, and platform-specific details in `<details>` blocks with descriptive summaries. Leave installation prerequisites, required configuration, important limitations, and primary commands expanded. Include blank lines around Markdown inside HTML disclosure blocks so Gitea renders it correctly.
|
||||
|
||||
Keep the header compact. Banners should use repository-local assets and render without scripts, external fonts, or network dependencies. Do not add decorative status badges or unverified build/test claims. A banner is optional for small repositories; the facts table, clear primary links, and content hierarchy should still work without one.
|
||||
|
||||
## Maintenance
|
||||
|
||||
Update the README alongside changes to installation, configuration, commands, supported hardware, or release behavior. Check local links, navigation, and Markdown structure before committing. Run a command only when its effects are appropriate; a documentation check must not flash hardware, publish a release, send messages, or start an import.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="260" viewBox="0 0 1200 260" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Radio podcasts, in one place</title>
|
||||
<desc id="desc">Sync your stations. Keep a local catalogue. Subscribe via RSS.</desc>
|
||||
<rect width="1200" height="260" rx="22" fill="#0d1b2a"/>
|
||||
<path d="M0 238h1200" stroke="#f2bd6b" stroke-width="4"/>
|
||||
<circle cx="1170" cy="15" r="190" fill="#f2bd6b" opacity=".04"/>
|
||||
<g font-family="DejaVu Sans,Arial,sans-serif">
|
||||
<rect x="42" y="40" width="6" height="18" rx="3" fill="#f2bd6b"/>
|
||||
<text x="60" y="54" fill="#f2bd6b" font-size="13" font-weight="600" letter-spacing="2">RADIOSYNC HUB / SELF-HOSTED</text>
|
||||
<text x="42" y="118" fill="#f0f6fc" font-size="33" font-weight="700">Radio podcasts, in one place</text>
|
||||
<text x="42" y="156" fill="#b6c8d9" font-size="16">Sync your stations. Keep a local catalogue. Subscribe via RSS.</text>
|
||||
<text x="42" y="208" fill="#91a9bf" font-size="12" letter-spacing="1">SELF-HOSTED PROJECTS / KAROL LABUS</text>
|
||||
<rect x="690" y="89" width="134" height="104" rx="16" fill="#172b42" stroke="#33506a"/><circle cx="714" cy="116" r="5" fill="#f2bd6b"/><text x="708" y="148" fill="#f0f6fc" font-size="18" font-weight="600">Stations</text><text x="708" y="171" fill="#b6c8d9" font-size="12">357 / RNS / Jazz</text><path d="M830 141h8m-4-4 4 4-4 4" fill="none" stroke="#f2bd6b" stroke-width="2"/><rect x="844" y="89" width="134" height="104" rx="16" fill="#172b42" stroke="#33506a"/><circle cx="868" cy="116" r="5" fill="#f2bd6b"/><text x="862" y="148" fill="#f0f6fc" font-size="18" font-weight="600">Catalogue</text><text x="862" y="171" fill="#b6c8d9" font-size="12">Local SQLite</text><path d="M984 141h8m-4-4 4 4-4 4" fill="none" stroke="#f2bd6b" stroke-width="2"/><rect x="998" y="89" width="134" height="104" rx="16" fill="#172b42" stroke="#33506a"/><circle cx="1022" cy="116" r="5" fill="#f2bd6b"/><text x="1016" y="148" fill="#f0f6fc" font-size="18" font-weight="600">Your player</text><text x="1016" y="171" fill="#b6c8d9" font-size="12">RSS / OPML</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
Reference in New Issue
Block a user