wow, chrome-extension MUCH improved - websockets

This commit is contained in:
cottongin
2025-10-30 15:17:15 -04:00
parent db2a8abe66
commit 7bb3aabd72
15 changed files with 1323 additions and 14 deletions

View File

@@ -440,5 +440,138 @@ router.delete('/:sessionId/games/:gameId', authenticateToken, (req, res) => {
}
});
// Export session data (plaintext and JSON)
router.get('/:id/export', authenticateToken, (req, res) => {
try {
const { format } = req.query; // 'json' or 'txt'
const sessionId = req.params.id;
// Get session info
const session = db.prepare(`
SELECT
s.*,
COUNT(sg.id) as games_played
FROM sessions s
LEFT JOIN session_games sg ON s.id = sg.session_id
WHERE s.id = ?
GROUP BY s.id
`).get(sessionId);
if (!session) {
return res.status(404).json({ error: 'Session not found' });
}
// Get games for this session
const games = db.prepare(`
SELECT
sg.*,
g.title,
g.pack_name,
g.min_players,
g.max_players,
g.game_type
FROM session_games sg
JOIN games g ON sg.game_id = g.id
WHERE sg.session_id = ?
ORDER BY sg.played_at ASC
`).all(sessionId);
// Get chat logs if any
const chatLogs = db.prepare(`
SELECT * FROM chat_logs
WHERE session_id = ?
ORDER BY timestamp ASC
`).all(sessionId);
if (format === 'json') {
// JSON Export
const exportData = {
session: {
id: session.id,
created_at: session.created_at,
closed_at: session.closed_at,
is_active: session.is_active === 1,
notes: session.notes,
games_played: session.games_played
},
games: games.map(game => ({
title: game.title,
pack: game.pack_name,
players: `${game.min_players}-${game.max_players}`,
type: game.game_type,
played_at: game.played_at,
manually_added: game.manually_added === 1,
status: game.status
})),
chat_logs: chatLogs.map(log => ({
username: log.chatter_name,
message: log.message,
timestamp: log.timestamp,
vote: log.parsed_vote
}))
};
res.setHeader('Content-Type', 'application/json');
res.setHeader('Content-Disposition', `attachment; filename="session-${sessionId}.json"`);
res.send(JSON.stringify(exportData, null, 2));
} else {
// Plain Text Export
let text = `JACKBOX GAME PICKER - SESSION EXPORT\n`;
text += `${'='.repeat(50)}\n\n`;
text += `Session ID: ${session.id}\n`;
text += `Created: ${session.created_at}\n`;
if (session.closed_at) {
text += `Closed: ${session.closed_at}\n`;
}
text += `Status: ${session.is_active ? 'Active' : 'Ended'}\n`;
if (session.notes) {
text += `Notes: ${session.notes}\n`;
}
text += `\nGames Played: ${session.games_played}\n`;
text += `\n${'='.repeat(50)}\n\n`;
if (games.length > 0) {
text += `GAMES:\n`;
text += `${'-'.repeat(50)}\n`;
games.forEach((game, index) => {
text += `\n${index + 1}. ${game.title}\n`;
text += ` Pack: ${game.pack_name}\n`;
text += ` Players: ${game.min_players}-${game.max_players}\n`;
if (game.game_type) {
text += ` Type: ${game.game_type}\n`;
}
text += ` Played: ${game.played_at}\n`;
text += ` Status: ${game.status}\n`;
if (game.manually_added === 1) {
text += ` (Manually Added)\n`;
}
});
text += `\n${'-'.repeat(50)}\n`;
}
if (chatLogs.length > 0) {
text += `\nCHAT LOGS:\n`;
text += `${'-'.repeat(50)}\n`;
chatLogs.forEach(log => {
text += `\n[${log.timestamp}] ${log.chatter_name}:\n`;
text += ` ${log.message}\n`;
if (log.parsed_vote) {
text += ` Vote: ${log.parsed_vote}\n`;
}
});
text += `\n${'-'.repeat(50)}\n`;
}
text += `\nEnd of Session Export\n`;
res.setHeader('Content-Type', 'text/plain');
res.setHeader('Content-Disposition', `attachment; filename="session-${sessionId}.txt"`);
res.send(text);
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = router;