const fs = require('fs') const request = require('request') const Discogs = require('disconnect').Client const Masto = require('mastodon') const mongo = require('./mongo') const config = require('./config') // Instanciation de Mastodon const M = new Masto({ access_token: config.mastodonToken, api_url: config.mastondonApi }) // Instanciation de Disgocs const dis = new Discogs({ userToken: config.discogsToken }).database() /** * Fonction permettant de sauvegarder en historique le morceau en cours de diffusion * @param {Object} values * @param {Function} callback */ const saveSong = (values, callback) => { mongo.Histories .find({}) .sort({ createdAt: 'desc' }) .limit(1) .exec(function (err, last) { if (err || last.length === 0 || (last[0] !== undefined && last[0].id !== values.id) ) { const history = new mongo.Histories(values) history.save(callback) } }) } /** * Fonction permettant de retrouver le dernier morceau sauvegardé en base * @param {Function} callback */ const getLastSong = (callback) => { mongo.Histories .find({}) .sort({ createdAt: 'desc' }) .limit(1) .exec(function (err, last) { if (err) { callback(err) return false } callback(null, last) }) } /** * Fonction permettant de chercher sur Discogs la pochette d'un album * @param {Object} song * @param {Function} callback */ const getRemoteCover = (song, callback) => { dis.search({ q: song.album, artist: song.artist, page: 1, per_page: 1 }, (err, res) => { if (err) { console.log('ERR:', err) callback(err) return false } // Une pochette est trouvée if (res.results && res.results.length === 1) { callback(null, res.results[0].cover_image) } else { callback(null, null) } }) } /** * Fonction permettant de retourner l'url de la pochette d'un album * @param {Object} song * @param {Function} callback */ const findCover = (song, callback) => { mongo.Metadata.findOne({ id: song.id }) .exec((err, metadata) => { if (err) { callback(err) return false } // Ce morceau est déjà en base if (metadata) { // On a déjà une pochette pour ce morceau if (metadata.cover) { callback(null, metadata.cover) return true } // Aucune pochette trouvée, on interroge Discogs getRemoteCover(song, (err, coverUrl) => { if (err) { callback(err) return false } metadata.updateOne({ cover: coverUrl }) callback(null, coverUrl) }) } else { // Première fois que ce morceau est jouée, on rempli sa fiche getRemoteCover(song, (err, coverUrl) => { if (err) { callback(err) return false } song.cover = coverUrl const metadata = new mongo.Metadata(song) metadata.save() callback(null, coverUrl) }) } }) } /** * Fonction permettant de récupérer le titre diffusé * @param {Funtion} callback */ const getStream = (callback) => { request.get(config.streamUrl, (error, response, body) => { if (!error && response.statusCode === 200) { let res = null const _body = JSON.parse(body) res = { artist: _body.data[0].track.artist, title: _body.data[0].track.title, album: _body.data[0].track.album, royaltytrackid: _body.data[0].track.royaltytrackid, id: _body.data[0].track.id, playlistId: _body.data[0].track.playlist ? _body.data[0].track.playlist.id : null, thumbCover: _body.data[0].track.imageurl } if (res !== null && res.artist !== undefined && res.title !== undefined) { callback(null, res) } else { error = true } } if (error) { callback(error) } }) } /** * Fonction permettant de télécharger la pochette d'un album selon une URL donnée * @param {String} coverUrl * @param {Function} callback */ const getMedia = (coverUrl, callback) => { const dest = '/tmp/attachment.jpg' const file = fs.createWriteStream(dest) request({ uri: coverUrl, headers: { 'Cache-Control': 'max-age=0', Connection: 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36' } }) .pipe(file) .on('finish', () => { callback(null, dest) }) .on('error', (error) => { console.log('ERR:', error) callback(error) }) } /** * Fonction formattant le texte à publier * @param {Object} values */ const formatMessage = (values) => { return `#rx3 #nowplaying ${values.artist} - ${values.title}` } /** * Fonction publiant un message (et média si attaché) sur Mastdon * @param {Object} song * @param {String} cover */ const publishMessage = (song, cover) => { if (cover) { getMedia(cover, (err, dest) => { if (err) { M.post('statuses', { status: formatMessage(song) }) } else { M.post('media', { file: fs.createReadStream(dest) }).then(resp => { const id = resp.data.id M.post('statuses', { status: formatMessage(song), media_ids: [id] }) }) } }) } else { M.post('statuses', { status: formatMessage(song) }) } } module.exports = { saveSong: saveSong, getLastSong: getLastSong, findCover: findCover, getStream: getStream, getMedia: getMedia, formatMessage: formatMessage, publishMessage: publishMessage }