|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
};
|