Skip to content

Commit 343781f

Browse files
Merge pull request #69 from Dans-Plugins/copilot/add-average-daily-activity
Add average daily activity calculation with command and REST API
2 parents 6f00f1a + 67e8201 commit 343781f

File tree

12 files changed

+708
-0
lines changed

12 files changed

+708
-0
lines changed

REST_API.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,41 @@ Get detailed activity information for a specific player.
111111
}
112112
```
113113

114+
### Average Daily Activity
115+
```
116+
GET /api/average-daily-activity/{uuid}?days=7
117+
```
118+
Get average daily activity for a specific player over a specified period.
119+
120+
**Parameters:**
121+
- `uuid` (path): Player's UUID
122+
- `days` (query, optional): Number of days to calculate average over (default: 7)
123+
124+
**Response:**
125+
```json
126+
{
127+
"playerUuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
128+
"playerName": "Steve",
129+
"days": 7,
130+
"averageHoursPerDay": 3.25,
131+
"totalHours": 22.75
132+
}
133+
```
134+
135+
**Error Response (404):**
136+
```json
137+
{
138+
"error": "Player not found"
139+
}
140+
```
141+
142+
**Error Response (400):**
143+
```json
144+
{
145+
"error": "Days must be a positive number"
146+
}
147+
```
148+
114149
## OpenAPI Specification
115150

116151
A complete OpenAPI 3.0 specification is available in the `openapi.yaml` file in the plugin repository. You can use this specification with tools like:
@@ -143,6 +178,12 @@ curl http://localhost:8080/api/leaderboard
143178

144179
# Get specific player info
145180
curl http://localhost:8080/api/players/a1b2c3d4-e5f6-7890-abcd-ef1234567890
181+
182+
# Get average daily activity for a player (default 7 days)
183+
curl http://localhost:8080/api/average-daily-activity/a1b2c3d4-e5f6-7890-abcd-ef1234567890
184+
185+
# Get average daily activity for a player over 30 days
186+
curl "http://localhost:8080/api/average-daily-activity/a1b2c3d4-e5f6-7890-abcd-ef1234567890?days=30"
146187
```
147188

148189
### Using JavaScript (fetch)
@@ -156,6 +197,11 @@ fetch('http://localhost:8080/api/stats')
156197
fetch('http://localhost:8080/api/leaderboard')
157198
.then(response => response.json())
158199
.then(data => console.log(data));
200+
201+
// Get average daily activity
202+
fetch('http://localhost:8080/api/average-daily-activity/a1b2c3d4-e5f6-7890-abcd-ef1234567890?days=7')
203+
.then(response => response.json())
204+
.then(data => console.log(data));
159205
```
160206

161207
### Using Python
@@ -173,6 +219,13 @@ response = requests.get('http://localhost:8080/api/leaderboard')
173219
leaderboard = response.json()
174220
for i, player in enumerate(leaderboard, 1):
175221
print(f"{i}. {player['playerName']} - {player['hoursPlayed']:.2f} hours")
222+
223+
# Get average daily activity
224+
response = requests.get('http://localhost:8080/api/average-daily-activity/a1b2c3d4-e5f6-7890-abcd-ef1234567890',
225+
params={'days': 7})
226+
avg_activity = response.json()
227+
print(f"Player: {avg_activity['playerName']}")
228+
print(f"Average hours per day ({avg_activity['days']} days): {avg_activity['averageHoursPerDay']:.2f}")
176229
```
177230

178231
## Troubleshooting

openapi.yaml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,51 @@ paths:
129129
schema:
130130
$ref: '#/components/schemas/ErrorResponse'
131131

132+
/api/average-daily-activity/{uuid}:
133+
get:
134+
summary: Get average daily activity for a player
135+
description: Calculate and retrieve the average daily activity for a specific player over a specified period
136+
operationId: getAverageDailyActivity
137+
tags:
138+
- Players
139+
parameters:
140+
- name: uuid
141+
in: path
142+
required: true
143+
description: The UUID of the player
144+
schema:
145+
type: string
146+
format: uuid
147+
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
148+
- name: days
149+
in: query
150+
required: false
151+
description: Number of days to calculate average over (default 7)
152+
schema:
153+
type: integer
154+
minimum: 1
155+
default: 7
156+
example: 7
157+
responses:
158+
'200':
159+
description: Average daily activity retrieved successfully
160+
content:
161+
application/json:
162+
schema:
163+
$ref: '#/components/schemas/AverageDailyActivityResponse'
164+
'400':
165+
description: Invalid UUID format or days parameter
166+
content:
167+
application/json:
168+
schema:
169+
$ref: '#/components/schemas/ErrorResponse'
170+
'404':
171+
description: Player not found
172+
content:
173+
application/json:
174+
schema:
175+
$ref: '#/components/schemas/ErrorResponse'
176+
132177
components:
133178
schemas:
134179
HealthResponse:
@@ -250,6 +295,39 @@ components:
250295
- totalHoursPlayed
251296
- currentlyOnline
252297

298+
AverageDailyActivityResponse:
299+
type: object
300+
properties:
301+
playerUuid:
302+
type: string
303+
format: uuid
304+
description: UUID of the player
305+
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
306+
playerName:
307+
type: string
308+
description: Name of the player
309+
example: "Steve"
310+
days:
311+
type: integer
312+
description: Number of days the average was calculated over
313+
example: 7
314+
averageHoursPerDay:
315+
type: number
316+
format: double
317+
description: Average hours played per day
318+
example: 3.25
319+
totalHours:
320+
type: number
321+
format: double
322+
description: Total hours played in the specified period
323+
example: 22.75
324+
required:
325+
- playerUuid
326+
- playerName
327+
- days
328+
- averageHoursPerDay
329+
- totalHours
330+
253331
ErrorResponse:
254332
type: object
255333
properties:

src/main/java/dansplugins/activitytracker/ActivityTracker.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.bukkit.event.Listener;
1919

2020
import dansplugins.activitytracker.bstats.Metrics;
21+
import dansplugins.activitytracker.commands.AverageCommand;
2122
import dansplugins.activitytracker.commands.ConfigCommand;
2223
import dansplugins.activitytracker.commands.DefaultCommand;
2324
import dansplugins.activitytracker.commands.HelpCommand;
@@ -156,6 +157,7 @@ private void registerEventHandlers() {
156157
*/
157158
private void initializeCommandService() {
158159
ArrayList<AbstractPluginCommand> commands = new ArrayList<>(Arrays.asList(
160+
new AverageCommand(persistentData, activityRecordService),
159161
new ConfigCommand(configService),
160162
new HelpCommand(),
161163
new InfoCommand(persistentData),
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package dansplugins.activitytracker.api;
2+
3+
/**
4+
* Response object for average daily activity data
5+
* @author Daniel McCoy Stephenson
6+
*/
7+
public class AverageDailyActivityResponse {
8+
private final String playerUuid;
9+
private final String playerName;
10+
private final int days;
11+
private final double averageHoursPerDay;
12+
private final double totalHours;
13+
14+
public AverageDailyActivityResponse(String playerUuid, String playerName, int days, double averageHoursPerDay, double totalHours) {
15+
this.playerUuid = playerUuid;
16+
this.playerName = playerName;
17+
this.days = days;
18+
this.averageHoursPerDay = averageHoursPerDay;
19+
this.totalHours = totalHours;
20+
}
21+
22+
public String getPlayerUuid() {
23+
return playerUuid;
24+
}
25+
26+
public String getPlayerName() {
27+
return playerName;
28+
}
29+
30+
public int getDays() {
31+
return days;
32+
}
33+
34+
public double getAverageHoursPerDay() {
35+
return averageHoursPerDay;
36+
}
37+
38+
public double getTotalHours() {
39+
return totalHours;
40+
}
41+
}

src/main/java/dansplugins/activitytracker/api/RestApiService.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,60 @@ private void setupRoutes() {
209209
return gson.toJson(playerResponse);
210210
});
211211

212+
// GET /api/average-daily-activity/:uuid - Get average daily activity for a player
213+
Spark.get("/api/average-daily-activity/:uuid", (request, response) -> {
214+
String uuidParam = request.params(":uuid");
215+
UUID playerUuid;
216+
217+
try {
218+
playerUuid = UUID.fromString(uuidParam);
219+
} catch (IllegalArgumentException e) {
220+
response.status(400);
221+
return gson.toJson(new ErrorResponse("Invalid UUID format"));
222+
}
223+
224+
ActivityRecord record = persistentData.getActivityRecord(playerUuid);
225+
if (record == null) {
226+
response.status(404);
227+
return gson.toJson(new ErrorResponse("Player not found"));
228+
}
229+
230+
// Get days parameter from query string (default: 7)
231+
String daysParam = request.queryParams("days");
232+
int days = 7;
233+
if (daysParam != null) {
234+
try {
235+
days = Integer.parseInt(daysParam);
236+
if (days <= 0) {
237+
response.status(400);
238+
return gson.toJson(new ErrorResponse("Days must be a positive number"));
239+
}
240+
} catch (NumberFormatException e) {
241+
response.status(400);
242+
return gson.toJson(new ErrorResponse("Invalid days parameter"));
243+
}
244+
}
245+
246+
UUIDChecker uuidChecker = new UUIDChecker();
247+
String playerName = uuidChecker.findPlayerNameBasedOnUUID(playerUuid);
248+
if (playerName == null) {
249+
playerName = "Unknown";
250+
}
251+
252+
double averageHoursPerDay = activityRecordService.calculateAverageDailyActivity(record, days);
253+
double totalHours = activityRecordService.calculateTotalHoursInPeriod(record, days);
254+
255+
AverageDailyActivityResponse avgResponse = new AverageDailyActivityResponse(
256+
playerUuid.toString(),
257+
playerName,
258+
days,
259+
averageHoursPerDay,
260+
totalHours
261+
);
262+
263+
return gson.toJson(avgResponse);
264+
});
265+
212266
// GET /api/health - Health check endpoint
213267
Spark.get("/api/health", (request, response) -> {
214268
return gson.toJson(new HealthResponse("OK", "Activity Tracker REST API"));

0 commit comments

Comments
 (0)