wow, chrome-extension MUCH improved - websockets
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user