2019-12-01 17:56:13 +01:00
|
|
|
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) => {
|
2019-12-03 09:55:13 +01:00
|
|
|
// Si c'est KOЯN on remplace par KORN (merci discogs)
|
|
|
|
if (song.artist === 'KOЯN') {
|
|
|
|
song.artist = 'KORN'
|
|
|
|
}
|
|
|
|
|
2019-12-01 17:56:13 +01:00
|
|
|
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 {
|
2019-12-17 11:16:18 +01:00
|
|
|
console.log('[INFO] No cover found for:', song.album, song.artist)
|
2019-12-01 17:56:13 +01:00
|
|
|
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) => {
|
2019-12-03 09:55:13 +01:00
|
|
|
// Si c'est Rx3 on ne met pas de cover
|
2019-12-09 12:01:54 +01:00
|
|
|
if (config.rx3List.indexOf(song.artist) !== -1) {
|
2019-12-03 09:55:13 +01:00
|
|
|
const metadata = new mongo.Metadata(song)
|
|
|
|
metadata.save()
|
|
|
|
callback(null, null)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-12-01 17:56:13 +01:00
|
|
|
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) => {
|
2019-12-08 21:06:26 +01:00
|
|
|
return `#rx3 #nowplaying ${values.artist} - ${values.title}`
|
2019-12-01 17:56:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
}
|