A small Python script to pick lyrics, which I can use for our company lunch-game "LyricsPop".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

224 lines
5.7 KiB

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