rx3-to-mastodon/libs.js
2019-12-09 12:01:54 +01:00

243 lines
5.9 KiB
JavaScript

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) => {
// Si c'est KOЯN on remplace par KORN (merci discogs)
if (song.artist === 'KOЯN') {
song.artist = 'KORN'
}
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) => {
// Si c'est Rx3 on ne met pas de cover
if (config.rx3List.indexOf(song.artist) !== -1) {
const metadata = new mongo.Metadata(song)
metadata.save()
callback(null, null)
return true
}
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
}