Simplify the webhook endpoint path to match the URL documented in the Lidarr integration guide. Also add a Lidarr integration section to README covering Coda environment variables, Lidarr webhook configuration, and the full end-to-end flow.
174 lines
7.7 KiB
Markdown
174 lines
7.7 KiB
Markdown
# Coda
|
|
|
|
Transcoder para Lidarr, escrito em Go e distribuído via Docker. Converte álbuns de **FLAC** para **MP3 320 kbps CBR**, acionado automaticamente por webhooks do Lidarr ou manualmente pela interface web.
|
|
|
|
Em ambos os fluxos, o Coda converte os arquivos, valida o resultado, remove os FLACs originais e solicita ao Lidarr um rescan da biblioteca.
|
|
|
|
## Funcionalidades
|
|
|
|
- Conversão FLAC → MP3 320 kbps CBR (libmp3lame), preservando metadados e capa.
|
|
- Acionamento por **webhook** do Lidarr ou **manual** pela interface web.
|
|
- Fila interna com worker pool e conversão paralela configurável.
|
|
- Validação pós-conversão (ffprobe, tamanho, existência) antes de apagar qualquer FLAC.
|
|
- **Janela de trabalho** opcional (desabilitada por padrão) para restringir o processamento a um intervalo de horário.
|
|
- Interface web: dashboard, tarefas, logs, navegação/scan de FLACs e configurações.
|
|
- Persistência em **SQLite** (jobs, logs e configurações).
|
|
- Modo **dry run** para simular sem converter nem apagar.
|
|
- Notificações via **ntfy** (self-hosted ou público) ao final de cada job.
|
|
|
|
## Stack
|
|
|
|
| Camada | Escolha |
|
|
|--------------|------------------------------------|
|
|
| Linguagem | Go 1.25.x |
|
|
| HTTP Router | chi (go-chi/chi/v5) |
|
|
| Banco | SQLite (modernc.org/sqlite, sem CGO) |
|
|
| UI | html/template + htmx + Tailwind CSS v4 + DaisyUI |
|
|
| Logging | log/slog (stdlib) + handler SQLite |
|
|
| Áudio | ffmpeg + ffprobe (libmp3lame) |
|
|
| Distribuição | Docker (Alpine Linux) |
|
|
|
|
## Início Rápido (local, sem Docker)
|
|
|
|
Pré-requisitos: **Go 1.25+** e **ffmpeg** com `libmp3lame`.
|
|
|
|
No Fedora, o ffmpeg completo vem do RPM Fusion:
|
|
|
|
```bash
|
|
sudo dnf install -y https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
|
|
sudo dnf install -y ffmpeg
|
|
```
|
|
|
|
Setup e execução:
|
|
|
|
```bash
|
|
make setup # baixa Tailwind + DaisyUI + htmx, deps Go, cria .env
|
|
mkdir -p data testdata/music # pastas locais (ajuste MUSIC_PATH no .env)
|
|
make run # dev com hot-reload (http://localhost:8080)
|
|
```
|
|
|
|
O SQLite **não** precisa ser instalado (`modernc.org/sqlite` é Go puro).
|
|
|
|
## Comandos (Makefile)
|
|
|
|
```bash
|
|
make setup # baixa ferramentas + deps + cria .env
|
|
make css # gera web/static/app.css
|
|
make css-watch # regenera o CSS ao salvar (dev)
|
|
make run # dev (build tag dev, assets do disco, hot-reload)
|
|
make run-prod # produção (assets embutidos via //go:embed)
|
|
make build # binário de produção em bin/server
|
|
make test # go test ./...
|
|
make lint # go vet ./...
|
|
make clean # remove bin/ e app.css
|
|
```
|
|
|
|
## Docker
|
|
|
|
```bash
|
|
docker build -t coda .
|
|
docker run -d \
|
|
-p 8080:8080 \
|
|
-v /caminho/para/musica:/music \
|
|
-v coda-data:/data \
|
|
-e LIDARR_URL=http://lidarr:8686 \
|
|
-e LIDARR_API_KEY=... \
|
|
coda
|
|
```
|
|
|
|
Volumes:
|
|
- **`/music`** — arquivos de música (mesmo path usado pelo Lidarr).
|
|
- **`/data`** — volume persistente do SQLite (`coda.db`).
|
|
|
|
## Configuração
|
|
|
|
Definida por variáveis de ambiente (defaults) e sobrescrita pela interface web (persistida no SQLite; a web vence). Em dev, o `.env` é carregado no startup.
|
|
|
|
| Variável | Default | Descrição |
|
|
|-----------------------|--------------------|----------------------------------------|
|
|
| `PORT` | `8080` | Porta do servidor HTTP |
|
|
| `WORKERS` | `4` | Workers simultâneos |
|
|
| `FFMPEG_BIN` | `/usr/bin/ffmpeg` | Caminho do ffmpeg |
|
|
| `FFPROBE_BIN` | `/usr/bin/ffprobe` | Caminho do ffprobe |
|
|
| `LOG_LEVEL` | `INFO` | Nível de log |
|
|
| `DRY_RUN` | `false` | Não converte nem apaga (só registra) |
|
|
| `LIDARR_URL` | — | URL base do Lidarr |
|
|
| `LIDARR_API_KEY` | — | API key do Lidarr |
|
|
| `WEBHOOK_SECRET` | — | Segredo para validar webhooks |
|
|
| `MUSIC_PATH` | `/music` | Diretório com os arquivos de música |
|
|
| `DB_PATH` | `/data/coda.db` | Caminho do arquivo SQLite |
|
|
| `TIMEZONE` | `UTC` | Timezone da janela de trabalho |
|
|
| `WORK_WINDOW_ENABLED` | `false` | Habilita a janela de trabalho |
|
|
| `WORK_WINDOW_START` | `08:00` | Início da janela (HH:MM) |
|
|
| `WORK_WINDOW_END` | `18:00` | Fim da janela (HH:MM) |
|
|
| `NTFY_ENABLED` | `false` | Habilita notificações ntfy |
|
|
| `NTFY_URL` | — | URL base do servidor ntfy |
|
|
| `NTFY_TOPIC` | — | Tópico para publicar notificações |
|
|
| `NTFY_TOKEN` | — | Token de autenticação (opcional) |
|
|
|
|
## Integração com o Lidarr
|
|
|
|
O Coda funciona como um pós-processador do Lidarr. Após o Lidarr importar um álbum, ele dispara um webhook para o Coda, que converte os FLACs para MP3 e solicita um rescan da biblioteca.
|
|
|
|
### Pré-requisito: paths compartilhados
|
|
|
|
O Lidarr e o Coda precisam enxergar a biblioteca no **mesmo caminho absoluto**. Se o Lidarr acessa os arquivos em `/music`, o Coda também deve ter `/music` montado apontando para o mesmo diretório físico.
|
|
|
|
### 1. Configurar o Coda
|
|
|
|
Defina as variáveis de ambiente (ou configure via `/settings` na interface web):
|
|
|
|
| Variável | Descrição |
|
|
|------------------|--------------------------------------------------------|
|
|
| `LIDARR_URL` | URL base do Lidarr, ex: `http://lidarr:8686` |
|
|
| `LIDARR_API_KEY` | API key do Lidarr (**Settings → General → API Key**) |
|
|
| `WEBHOOK_SECRET` | Segredo para validar webhooks (opcional, mas recomendado) |
|
|
| `MUSIC_PATH` | Caminho raiz da biblioteca, deve coincidir com o Lidarr |
|
|
|
|
### 2. Configurar o Webhook no Lidarr
|
|
|
|
No Lidarr, acesse **Settings → Connect → + → Webhook** e configure:
|
|
|
|
| Campo | Valor |
|
|
|------------------------|----------------------------------------------|
|
|
| **Name** | Coda (ou qualquer nome) |
|
|
| **Notification Triggers** | `On Release Import` |
|
|
| **URL** | `http://<host-do-coda>:8080/webhook` |
|
|
| **Method** | POST |
|
|
|
|
Se `WEBHOOK_SECRET` estiver definido, adicione um header:
|
|
|
|
| Header | Valor |
|
|
|---------------------|------------------|
|
|
| `X-Webhook-Secret` | `<seu-secret>` |
|
|
|
|
Salve e clique em **Test** para validar. O Coda responderá com `{"status":"ok"}`.
|
|
|
|
### Fluxo completo
|
|
|
|
```
|
|
Lidarr importa álbum FLAC
|
|
→ POST /webhook (Lidarr → Coda)
|
|
→ Coda enfileira job
|
|
→ Worker converte FLAC → MP3, valida, remove FLACs
|
|
→ Coda chama API do Lidarr para rescan da pasta
|
|
→ Lidarr detecta os MP3s e atualiza a biblioteca
|
|
```
|
|
|
|
## Estrutura do Projeto
|
|
|
|
```
|
|
cmd/server/ # entrypoint
|
|
internal/ # config, scheduler, webhook, queue, worker,
|
|
# transcoder, validator, lidarr, logger, web,
|
|
# models, store, scanner, ntfy
|
|
web/ # styles/ (fonte CSS), static/ (gerado), templates/
|
|
data/ # volume local do SQLite
|
|
```
|
|
|
|
## Documentação
|
|
|
|
- [Requisitos](docs/requirements.md)
|
|
- [Arquitetura](docs/architecture.md)
|
|
- [AGENTS.md](AGENTS.md) — guia para agentes e convenções do projeto
|