const express = require('express'); const fs = require('fs'); const path = require('path'); const morgan = require('morgan'); const bodyParser = require('body-parser'); const sqlite3 = require('sqlite3').verbose(); const app = express(); const port = 3000; // Create an SQLite database and initialize tables const db = new sqlite3.Database('db/results.db', (err) => { if (err) { console.error('Error opening SQLite database:', err.message); } else { console.log('Connected to SQLite database'); db.run(` CREATE TABLE IF NOT EXISTS button_clicks ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT, animal_name TEXT, button_name TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, time_difference INTEGER -- Add this column for time difference ) `); } }); var accessLogStream = fs.createWriteStream(path.join(__dirname, 'log', 'access.log'), { flags: 'a' }) app.use(bodyParser.json()); app.use(morgan('combined', { stream: accessLogStream })); var animals; // check and load animals into redis try { fs.readFile("./animals.json", function (err, data) { if (err) { throw err; } var jsondata = JSON.parse(data); animals = jsondata.animals; }); } catch (error) { console.error('Error loading animals:', error); animals = ['Dog', 'Cat', 'Elephant', 'Lion', 'Giraffe']; } // Serve the HTML file app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.get('/asset/frontend.js', (req, res) => { res.sendFile(__dirname + '/asset/frontend.js'); }); // Route to get a random animal name app.get('/getNextAnimal', async (req, res) => { try { // TODO this is currently random, and should have a bit of reasoning behind the next choice const randomIndex = Math.floor(Math.random() * animals.length); const randomAnimal = animals[randomIndex]; res.json({ animalName: randomAnimal }); } catch (error) { console.error('Error fetching random animal:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route to record button clicks along with session IDs in SQLite app.post('/recordButtonClick', (req, res) => { try { //const { buttonName, sessionId } = req.body; const result = req.body; console.error(result); db.run('INSERT INTO button_clicks (session_id, animal_name, button_name, timestamp, time_difference) VALUES (?, ?, ?, ?, ?)', [result.session, result.animal, result.button, result.time, result.difference], (err) => { if (err) { console.error('Error recording button click:', err.message); res.status(500).json({ error: 'Internal server error' }); } else { res.sendStatus(200); } }); } catch (error) { console.error('Error recording button click:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Route to show the current results from SQLite app.get('/results', (req, res) => { try { db.all('SELECT animal_name, button_name, COUNT(*) as count FROM button_clicks GROUP BY button_name, animal_name', (err, rows) => { if (err) { console.error('Error fetching results:', err.message); res.status(500).json({ error: 'Internal server error' }); } else { const results = { count: {} }; rows.forEach((row) => { if (typeof results.count[row.animal_name] == 'undefined') { results.count[row.animal_name] = {} } results.count[row.animal_name][row.button_name] = row.count; }); res.json(results); } }); } catch (error) { console.error('Error fetching results:', error); res.status(500).json({ error: 'Internal server error' }); } }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });