@rmdes/indiekit-endpoint-funkwhale 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,50 +1,54 @@
1
1
  # @rmdes/indiekit-endpoint-funkwhale
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@rmdes/indiekit-endpoint-funkwhale.svg)](https://www.npmjs.com/package/@rmdes/indiekit-endpoint-funkwhale)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
3
6
  Funkwhale listening activity endpoint for [Indiekit](https://getindiekit.com/).
4
7
 
5
8
  Display your Funkwhale listening history, favorite tracks, and listening statistics on your IndieWeb site.
6
9
 
10
+ ## Installation
11
+
12
+ Install from npm:
13
+
14
+ ```bash
15
+ npm install @rmdes/indiekit-endpoint-funkwhale
16
+ ```
17
+
7
18
  ## Features
8
19
 
20
+ - **Admin Dashboard** - Overview of your listening activity in Indiekit's admin UI
9
21
  - **Now Playing Widget** - Shows currently playing or recently played tracks
10
22
  - **Listening History** - Browse your listening history with album art
11
23
  - **Favorites** - Display your favorite tracks
12
- - **Statistics** - View listening stats with tabbed interface:
13
- - All Time / This Month / This Week views
14
- - Top Artists and Albums
15
- - Listening trend charts
24
+ - **Statistics** - View listening stats (plays, unique tracks, unique artists)
25
+ - **Background Sync** - Automatically syncs listening data to MongoDB
16
26
  - **Public JSON API** - For integration with static site generators like Eleventy
17
27
 
18
- ## Installation
19
-
20
- ```bash
21
- npm install @rmdes/indiekit-endpoint-funkwhale
22
- ```
23
-
24
28
  ## Configuration
25
29
 
26
30
  Add to your `indiekit.config.js`:
27
31
 
28
32
  ```javascript
33
+ import FunkwhaleEndpoint from "@rmdes/indiekit-endpoint-funkwhale";
34
+
29
35
  export default {
30
36
  plugins: [
31
- "@rmdes/indiekit-endpoint-funkwhale",
37
+ new FunkwhaleEndpoint({
38
+ mountPath: "/funkwhale",
39
+ instanceUrl: process.env.FUNKWHALE_INSTANCE,
40
+ username: process.env.FUNKWHALE_USERNAME,
41
+ token: process.env.FUNKWHALE_TOKEN,
42
+ cacheTtl: 900_000, // 15 minutes
43
+ syncInterval: 300_000, // 5 minutes
44
+ limits: {
45
+ listenings: 20,
46
+ favorites: 20,
47
+ topArtists: 10,
48
+ topAlbums: 10
49
+ }
50
+ }),
32
51
  ],
33
-
34
- "@rmdes/indiekit-endpoint-funkwhale": {
35
- mountPath: "/funkwhale",
36
- instanceUrl: process.env.FUNKWHALE_INSTANCE,
37
- username: process.env.FUNKWHALE_USERNAME,
38
- token: process.env.FUNKWHALE_TOKEN,
39
- cacheTtl: 900_000, // 15 minutes
40
- syncInterval: 300_000, // 5 minutes
41
- limits: {
42
- listenings: 20,
43
- favorites: 20,
44
- topArtists: 10,
45
- topAlbums: 10
46
- }
47
- },
48
52
  };
49
53
  ```
50
54
 
@@ -65,24 +69,45 @@ export default {
65
69
 
66
70
  ## Routes
67
71
 
68
- ### Protected Routes (require authentication)
72
+ ### Admin Routes (require authentication)
69
73
 
70
74
  | Route | Description |
71
75
  |-------|-------------|
72
- | `GET /funkwhale/` | Dashboard with overview |
73
- | `GET /funkwhale/listenings` | Full listening history |
74
- | `GET /funkwhale/favorites` | Favorite tracks |
75
- | `GET /funkwhale/stats` | Statistics with tabs |
76
+ | `GET /funkwhale/` | Dashboard overview with stats, recent plays, favorites |
77
+ | `POST /funkwhale/sync` | Trigger manual sync |
76
78
 
77
79
  ### Public API Routes (JSON)
78
80
 
81
+ These endpoints are publicly accessible and can be used by static site generators like Eleventy to display listening activity on your site.
82
+
79
83
  | Route | Description |
80
84
  |-------|-------------|
81
85
  | `GET /funkwhale/api/now-playing` | Current/recent track |
82
86
  | `GET /funkwhale/api/listenings` | Recent listenings |
83
87
  | `GET /funkwhale/api/favorites` | Favorites list |
84
- | `GET /funkwhale/api/stats` | All statistics |
85
- | `GET /funkwhale/api/stats/trends` | Trend data for charts |
88
+ | `GET /funkwhale/api/stats` | All statistics (summary, top artists, top albums) |
89
+ | `GET /funkwhale/api/stats/trends` | Trend data for charts (30 days) |
90
+
91
+ ### Example: Eleventy Integration
92
+
93
+ Fetch data from the public API in your Eleventy `_data` file:
94
+
95
+ ```javascript
96
+ // _data/funkwhale.js
97
+ import EleventyFetch from "@11ty/eleventy-fetch";
98
+
99
+ export default async function() {
100
+ const baseUrl = process.env.SITE_URL || "https://example.com";
101
+
102
+ const [nowPlaying, listenings, stats] = await Promise.all([
103
+ EleventyFetch(`${baseUrl}/funkwhale/api/now-playing`, { duration: "15m", type: "json" }),
104
+ EleventyFetch(`${baseUrl}/funkwhale/api/listenings`, { duration: "15m", type: "json" }),
105
+ EleventyFetch(`${baseUrl}/funkwhale/api/stats`, { duration: "15m", type: "json" }),
106
+ ]);
107
+
108
+ return { nowPlaying, listenings, stats };
109
+ }
110
+ ```
86
111
 
87
112
  ## Options
88
113
 
@@ -108,7 +133,7 @@ export default {
108
133
  ## Requirements
109
134
 
110
135
  - Indiekit >= 1.0.0-beta.25
111
- - MongoDB (for statistics aggregation)
136
+ - MongoDB (for statistics aggregation and sync)
112
137
  - Funkwhale instance with API v2
113
138
 
114
139
  ## License
@@ -66,21 +66,16 @@ export const dashboardController = {
66
66
  // Get stats from cache (same source as public API)
67
67
  // If cache is empty, try to refresh it from database
68
68
  let cachedStats = getCachedStats();
69
- console.log("[Funkwhale Dashboard] cachedStats:", cachedStats ? "exists" : "null");
70
69
  if (!cachedStats) {
71
70
  const getDb = request.app.locals.application.getFunkwhaleDb;
72
- console.log("[Funkwhale Dashboard] getFunkwhaleDb:", getDb ? "exists" : "null");
73
71
  if (getDb) {
74
72
  const db = getDb();
75
- console.log("[Funkwhale Dashboard] db:", db ? "exists" : "null");
76
73
  if (db) {
77
74
  cachedStats = await refreshStatsCache(db, limits);
78
- console.log("[Funkwhale Dashboard] after refresh:", cachedStats ? "exists" : "null");
79
75
  }
80
76
  }
81
77
  }
82
78
  const summary = cachedStats?.summary?.all || null;
83
- console.log("[Funkwhale Dashboard] summary:", JSON.stringify(summary));
84
79
 
85
80
  // Determine public frontend URL (strip 'api' from mount path)
86
81
  // e.g., /funkwhaleapi -> /funkwhale
@@ -91,7 +86,10 @@ export const dashboardController = {
91
86
  nowPlaying,
92
87
  listenings: listenings.slice(0, 5),
93
88
  favorites: favorites.slice(0, 5),
94
- summary,
89
+ totalPlays: summary?.totalPlays || 0,
90
+ uniqueTracks: summary?.uniqueTracks || 0,
91
+ uniqueArtists: summary?.uniqueArtists || 0,
92
+ hasStats: !!summary,
95
93
  publicUrl,
96
94
  mountPath: request.baseUrl,
97
95
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-funkwhale",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Funkwhale listening activity endpoint for Indiekit. Display listening history, favorites, and statistics.",
5
5
  "keywords": [
6
6
  "indiekit",
@@ -193,20 +193,20 @@
193
193
  {% endif %}
194
194
 
195
195
  {# Quick Stats Summary #}
196
- {% if summary %}
196
+ {% if hasStats %}
197
197
  <section class="fw-section">
198
198
  <h2>{{ __("funkwhale.stats") }}</h2>
199
199
  <div class="fw-stats-grid">
200
200
  <div class="fw-stat">
201
- <span class="fw-stat-value">{{ summary.totalPlays | default(0) }}</span>
201
+ <span class="fw-stat-value">{{ totalPlays }}</span>
202
202
  <span class="fw-stat-label">{{ __("funkwhale.plays") }}</span>
203
203
  </div>
204
204
  <div class="fw-stat">
205
- <span class="fw-stat-value">{{ summary.uniqueTracks | default(0) }}</span>
205
+ <span class="fw-stat-value">{{ uniqueTracks }}</span>
206
206
  <span class="fw-stat-label">{{ __("funkwhale.tracks") }}</span>
207
207
  </div>
208
208
  <div class="fw-stat">
209
- <span class="fw-stat-value">{{ summary.uniqueArtists | default(0) }}</span>
209
+ <span class="fw-stat-value">{{ uniqueArtists }}</span>
210
210
  <span class="fw-stat-label">{{ __("funkwhale.artists") }}</span>
211
211
  </div>
212
212
  </div>