Add explicit filtering, fuzzy matching, reply modes, bulk actions, and refresh README
- Explicit/clean track filtering with configurable explicitMode per channel - Last.fm spell correction and smart dual-strategy iTunes search - Configurable queuedReplyMode and announceReplyMode (channel/private/notice) - Per-channel announceApproved/announceRejected/announceNowPlaying toggles - Bulk select mode for mass approve/reject/mark-played in web dashboard - Comprehensive README rewrite covering all current features and config Made-with: Cursor
This commit is contained in:
106
README.md
106
README.md
@@ -7,19 +7,30 @@ A Limnoria (Supybot) plugin that watches IRC channels for song requests, validat
|
||||
- **Passive detection** — recognizes `Artist - Title` patterns in chat and validates against Apple Music
|
||||
- **Explicit command** — `!request Artist - Title` for direct requests
|
||||
- **Disambiguation** — presents top matches when multiple results found; user picks by number
|
||||
- **Feeling Lucky mode** — auto-select the first match, store the rest as alternates (per-channel)
|
||||
- **Explicit/clean filtering** — prefer explicit tracks, filter out clean duplicates, or vice versa (configurable per-channel)
|
||||
- **Last.fm spell correction** — optionally correct misspelled artist/track names before searching iTunes
|
||||
- **Smart search** — dual-strategy iTunes queries with attribute-targeted searches and increased result limits
|
||||
- **Web dashboard** — HTMX-powered UI with album art, Apple Music links, and moderation controls
|
||||
- **Real-time updates** — WebSocket pushes new requests and status changes to all connected dashboards
|
||||
- **Moderation** — approve, reject, or mark requests as played from the web UI
|
||||
- **Bulk actions** — select multiple requests and approve, reject, or mark played in one action
|
||||
- **Alternate matches** — when disambiguating, unchosen tracks appear as collapsible sub-cards with approve and mark-played buttons
|
||||
- **Clickable cards** — the entire request card links to Apple Music
|
||||
- **Session management** — start/stop named sessions, archive them, rename/clear/delete archived sessions
|
||||
- **Channel grouping** — requests grouped by channel with tab filtering; URL-based channel routing
|
||||
- **Auth system** — per-admin login via IRC-managed accounts (`addSongAdmin`), admin presence indicator
|
||||
- **Theme support** — dark/light/system theme toggle
|
||||
- **Rate limiting** — configurable per-user request limits
|
||||
- **Ignore list** — block specific users from making requests
|
||||
- **Auto-approve** — skip the pending queue and auto-approve requests (per-channel)
|
||||
- **Persistence** — SQLite-backed; survives bot restarts
|
||||
- **IRC announcements** — optionally announces status changes back to the originating channel
|
||||
- **IRC announcements** — configurable delivery: channel, private message, or NOTICE
|
||||
- **Quiet mode** — suppress the "Queued" IRC confirmation per-channel
|
||||
- **Alternate matches** — when disambiguating, unchosen tracks appear as collapsible sub-cards
|
||||
- **Clickable cards** — the entire request card links to Apple Music
|
||||
- **Export history** — download request history as a Markdown file
|
||||
- **Open/close requests** — global toggle (with per-channel override) from IRC or the web panel
|
||||
- **Clear history** — wipe played/rejected entries from IRC or the web panel
|
||||
- **Mobile responsive** — optimized layout for phones and tablets
|
||||
|
||||
## Dependencies
|
||||
|
||||
@@ -43,31 +54,61 @@ pip install aiohttp
|
||||
@config plugins.SongRequest.enabledChannels #music #requests
|
||||
```
|
||||
|
||||
4. Set a web dashboard auth token:
|
||||
4. Add a web dashboard admin (from IRC, requires bot admin):
|
||||
```
|
||||
@config plugins.SongRequest.webAuthToken your-secret-token-here
|
||||
@addsongadmin alice s3cretK3y
|
||||
```
|
||||
|
||||
5. Access the dashboard at `http://<bot-host>:8888/` (default port, configurable via `webPort`).
|
||||
5. (Optional) Set a Last.fm API key for spell correction:
|
||||
```
|
||||
@config plugins.SongRequest.lastfmApiKey YOUR_LASTFM_KEY
|
||||
```
|
||||
|
||||
6. Access the dashboard at `http://<bot-host>:8888/` (default port, configurable via `webPort`).
|
||||
|
||||
## Configuration
|
||||
|
||||
### Global Settings
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
|---------|------|---------|-------------|
|
||||
| `enabledChannels` | Space-separated list | (empty) | Channels for passive detection |
|
||||
| `ignoredUsers` | Space-separated list | (empty) | Nicks/hostmasks to ignore |
|
||||
| `maxRequestsPerUser` | Integer | 10 | Max requests per rate limit window (0 = unlimited) |
|
||||
| `rateLimitWindow` | Integer | 3600 | Rate limit window in seconds |
|
||||
| `webAuthToken` | String (private) | (empty) | Auth token for web dashboard actions |
|
||||
| `announceStatus` | Boolean | True | Announce status changes back to IRC |
|
||||
| `webAuthToken` | String (private) | (empty) | (Deprecated) Legacy shared auth token; prefer per-admin accounts |
|
||||
| `lastfmApiKey` | String (private) | (empty) | Last.fm API key for spell correction; empty to disable |
|
||||
| `announceStatus` | Boolean | True | Master switch for all IRC status announcements |
|
||||
| `maxChoices` | Integer | 3 | Disambiguation choices shown |
|
||||
| `webPort` | Integer | 8888 | Port for the web dashboard server |
|
||||
| `webHost` | String | 0.0.0.0 | Bind address for the web dashboard server |
|
||||
| `requestsOpen` | Boolean | True | Global toggle — accept or reject new requests |
|
||||
| `requestsOpenOverride` | String (per-channel) | (empty) | Per-channel override: `open`, `closed`, or empty for global |
|
||||
| `quietQueued` | Boolean (per-channel) | False | Suppress the "Queued: ..." IRC confirmation |
|
||||
| `passiveDetection` | Boolean (per-channel) | True | Enable passive pattern matching |
|
||||
| `requestCommand` | Boolean (per-channel) | True | Enable the `!request` command |
|
||||
|
||||
### Per-Channel Settings
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
|---------|------|---------|-------------|
|
||||
| `requestsOpenOverride` | String | (empty) | `open`, `closed`, or empty for global default |
|
||||
| `quietQueued` | Boolean | False | Suppress the "Queued: ..." IRC confirmation |
|
||||
| `queuedReplyMode` | String | `channel` | Queued confirmation delivery: `channel`, `private`, or `notice` |
|
||||
| `autoApprove` | Boolean | False | Auto-approve requests (skip pending queue) |
|
||||
| `feelingLucky` | Boolean | False | Auto-select first match; store rest as alternates |
|
||||
| `explicitMode` | String | `filter` | `off`, `prefer`, `filter`, or `clean` (see below) |
|
||||
| `announceApproved` | Boolean | True | Announce approved requests in IRC |
|
||||
| `announceRejected` | Boolean | True | Announce rejected requests in IRC |
|
||||
| `announceNowPlaying` | Boolean | True | Announce now-playing requests in IRC |
|
||||
| `announceReplyMode` | String | `channel` | Status announcement delivery: `channel`, `private`, or `notice` |
|
||||
| `passiveDetection` | Boolean | True | Enable passive pattern matching |
|
||||
| `requestCommand` | Boolean | True | Enable the `!request` command |
|
||||
|
||||
### Explicit Mode
|
||||
|
||||
Controls how explicit/clean track versions are handled in search results:
|
||||
|
||||
- **`off`** — return results as-is from iTunes
|
||||
- **`prefer`** — sort explicit tracks first, keep all results
|
||||
- **`filter`** (default) — drop cleaned versions when an explicit version of the same track exists, sort explicit first
|
||||
- **`clean`** — drop explicit versions when a clean version exists, sort clean first
|
||||
|
||||
## Commands
|
||||
|
||||
@@ -81,31 +122,52 @@ pip install aiohttp
|
||||
| `openrequests [channel]` | Open requests globally or per-channel | Admin |
|
||||
| `closerequests [channel]` | Close requests globally or per-channel | Admin |
|
||||
| `clearhistory` | Clear all played/rejected requests | Admin |
|
||||
| `startsession [name]` | Start a new request session | Admin |
|
||||
| `stopsession` | Stop and archive the active session | Admin |
|
||||
| `addsongadmin <user> <key>` | Add a web dashboard admin account | Admin |
|
||||
| `removesongadmin <user>` | Remove a web dashboard admin account | Admin |
|
||||
| `listsongadmins` | List all web dashboard admin accounts | Admin |
|
||||
|
||||
## Web Dashboard
|
||||
|
||||
The dashboard runs on a standalone aiohttp server (separate from Limnoria's built-in HTTP server) at the configured `webPort` (default `8888`). It shows:
|
||||
The dashboard runs on a standalone aiohttp server at the configured `webPort` (default `8888`).
|
||||
|
||||
### Authentication
|
||||
|
||||
Admins are managed via IRC commands (`addsongadmin`/`removesongadmin`). The dashboard has a login page at `/login`. Non-admins can view the queue and history read-only; admin controls (moderation buttons, session management, export, etc.) are only visible to logged-in admins.
|
||||
|
||||
A floating presence indicator shows which admins are currently online.
|
||||
|
||||
### Queue View
|
||||
|
||||
- **Pending** requests awaiting moderation
|
||||
- **Approved** requests ready to play
|
||||
- **History** of played/rejected requests
|
||||
- **Bulk select** mode for mass approve/reject/mark-played
|
||||
- Action buttons (approve/reject/mark played) positioned in the top-right corner of each card
|
||||
|
||||
Each request card is a clickable link to Apple Music and displays album art, song title, artist, album name, requester info, and action buttons (Approve / Reject / Mark Played). When a request had disambiguation, the alternate matches appear in a collapsible section below the main card.
|
||||
### History View
|
||||
|
||||
The history tab includes **Export .md** (download as Markdown) and **Clear History** buttons. A toggle switch in the header opens/closes requests globally (synced in real time across all connected dashboards).
|
||||
- History of played/rejected requests with **Export .md** and **Clear History** buttons
|
||||
- **Session archives** — previous sessions listed with expand-to-view, plus rename/clear/delete actions
|
||||
|
||||
Real-time updates are delivered via WebSocket — the status indicator dot in the header shows green when connected and red when disconnected (with automatic reconnection).
|
||||
### Other Features
|
||||
|
||||
Admin actions require the auth token, which is automatically injected into the dashboard page at serve time.
|
||||
- Channel filter tabs with URL-based routing (`/#channelName` or `/channelName`)
|
||||
- Dark/light/system theme toggle
|
||||
- Toast notifications for new requests when viewing history
|
||||
- Custom themed modals (no native browser prompts)
|
||||
- Real-time WebSocket connection with auto-reconnect
|
||||
|
||||
## How Passive Detection Works
|
||||
|
||||
1. The bot watches messages in `enabledChannels` for lines matching `Something - Something`
|
||||
2. Lines starting with bot command prefixes (`!`, `.`, `@`, etc.) or URLs are skipped
|
||||
3. The extracted text is searched against the iTunes Search API
|
||||
4. If no song matches, the message is silently ignored (primary false-positive filter)
|
||||
5. If one match, it's queued automatically
|
||||
6. If multiple matches, the user is presented with choices
|
||||
3. If a Last.fm API key is configured, artist/track names are spell-corrected
|
||||
4. The extracted text is searched against the iTunes Search API (dual-strategy: combined + attribute-targeted)
|
||||
5. Results are filtered/sorted based on `explicitMode`
|
||||
6. If no song matches, the message is silently ignored
|
||||
7. If one match (or `feelingLucky` is on), it's queued automatically
|
||||
8. If multiple matches, the user is presented with choices
|
||||
|
||||
## Running Tests
|
||||
|
||||
|
||||
Reference in New Issue
Block a user