/* * main page */ var sqlite3 = require('sqlite3'); var path = require('path'); var db = null; // make it global /********************************************************************** * Helper functions *********************************************************************/ /** db name */ function dbName() { return path.join(__dirname, '../../db/lyrics.sq3'); } /** turn a phrase into a list of acronyms */ function acronymize(phrase) { var letters = []; phrase.split(' ').forEach(function (elem, idx, array) { letters.push(elem[0].toUpperCase()); }); return letters.join(''); } /** return a json response */ function asJson(res, obj) { console.log(JSON.stringify(obj)); res.writeHead(200, {'Content-Type': 'application/json'}); res.write(JSON.stringify(obj)); res.end(); } /** mark a song as played */ function markAsDone(song_id, after) { var now = new Date(); db.run('UPDATE songs SET done_in = ? WHERE id = ?', [ now.toJSON(), song_id ], function (error) { if (error) { throw error; } if (after) { after(); } } ); } /********************************************************************** * Open the database *********************************************************************/ console.log('Opening the database ' + dbName() + '...'); db = new sqlite3.Database(dbName(), sqlite3.OPEN_READWRITE, function (error) { if (error) { db = null; // keep it null, to point that it is broken } }); /** small note: the db structure: * artists: * id int primary key * name text unique * * songs: * id int primary key * title text * artist int * done_in text * * lyrics: * id int primary key * song int * lyrics text */ /********************************************************************** * Select a song and display it *********************************************************************/ function index(req, res) { if (!db) { res.render('db-error'); return; } console.log('Picking song...'); var query = [ 'SELECT', ' songs.id as song_id,', ' songs.title as song_title,', ' artists.name as artist_name,', ' lyrics.lyrics as lyrics', 'FROM songs,', ' artists,', ' lyrics', 'WHERE songs.done_in is NULL', ' AND songs.artist = artists.id', ' AND songs.id = lyrics.song', 'ORDER BY random()', 'LIMIT 1' ]; console.log(query.join(' ')); db.get(query.join(' '), function (err, selectSong) { if (err) { throw err; } console.log(selectSong); var params = { title: 'Round', lyrics: selectSong.lyrics, song_title: selectSong.song_title, song_artist: selectSong.artist_name, acronym_title: acronymize(selectSong.song_title), acronym_artist: acronymize(selectSong.artist_name), id: selectSong.song_id }; res.render('index', params); }); } exports.index = index; /*********************************************************************** * Support for the small box with the "others" picks **********************************************************************/ exports.others = function (req, res) { var posted_artist = req.body.artist.toLowerCase(); var posted_song = req.body.song.toLowerCase(); console.log('Artist: ' + posted_artist); console.log('Song: ' + posted_song); var result = {status: '', message: ''}; function duplicateOrNotDone(err, song) { if (err) { throw err; } // the record will always exist, it's just a matter of "does it have a done_in"? console.log('Song done in ' + song.done_in); if (song.done_in) { // yup, already picked that song result.status = 'ERROR'; result.message = 'Song already picked'; asJson(res, result); } else { // it was one of your songs that someone else picked. // just tell the user that and update it in the background result.status = 'OK'; result.message = 'Someone picked one of your songs'; asJson(res, result); markAsDone(song.id); } } function insertSong(artist) { var now = new Date(); console.log('Adding song as played in ' + now.toJSON() + '...'); db.run('INSERT INTO songs (id, title, artist, done_in) VALUES (NULL, ?, ?, ?)', [ posted_song, artist, now.toJSON() ], function (error) { if (error) { // expected: artist AND song already picked console.log('Insert failed, possible duplicate'); db.get('SELECT * FROM songs WHERE artist = ? AND title = ?', [ artist, posted_song ], duplicateOrNotDone ); } else { console.log('Insert succeded'); // things went alright result.status = 'OK'; result.message = 'Added'; asJson(res, result); } } ); } db.run('INSERT INTO artists (id, name) VALUES (NULL, ?)', [ posted_artist ], function (error) { if (error) { // expected error: artist already exists console.log('Artist exists, trying to find id...'); db.get('SELECT id FROM artists WHERE name = ?', [posted_artist], function (err, artist) { if (err) { throw err; } console.log('Artist id = ' + artist.id); insertSong(artist.id); }); } else { console.log('New artist id = ' + this.lastID); insertSong(this.lastID); } } ); }; /********************************************************************** * Mark a song as played *********************************************************************/ exports.played = function (req, res) { markAsDone(req.body.id); index(req, res); };