radiobot/modules/producing.js
2022-03-22 20:25:39 -04:00

213 lines
4.8 KiB
JavaScript

var colors = require("colors");
var moment = require("moment");
const ffmpeg = require('fluent-ffmpeg');
class ProducingModule
{
constructor(config, client, bot)
{
this.config = config;
this.client = client;
this.bot = bot;
this.client.on("messageReactionAdd", (r, user) => { this.onMessageReactionAdd(r, user); });
this.client.on("messageReactionRemove", (r, user) => { this.onMessageReactionRemove(r, user); });
if (!this.bot.mongodb) {
console.error("The producing module requires MongoDB to be connected to a database!");
return;
}
this.collUsers = this.bot.mongodb.collection("users");
this.collFiles = this.bot.mongodb.collection("files");
this.collFilesFeedback = this.bot.mongodb.collection("files_feedback");
}
async getOrCreateUser(id)
{
var user = await this.collUsers.findOne({ id: id });
if (!user) {
user = {
id: id,
files_uploaded: 0,
feedback_given: 0
};
await this.collUsers.insertOne(user);
}
return user;
}
async getNumberOfFeedbackGiven(userId)
{
var result = await this.collFilesFeedback.aggregate([
{ $match: { user: userId } },
{ $group: { _id: "$msg", count: { $sum: 1 } } },
{ $count: "count" }
]).next();
if (!result) {
return 0;
}
return result.count;
}
onMessageReactionAdd(r, user)
{
if (user == this.client.user) {
return;
}
var msg = r.message;
if (msg.channel.id != this.config.channel) {
return;
}
if (user == msg.author) {
return;
}
if (this.config.reactions.indexOf(r.emoji.name) == -1) {
return;
}
this.collFilesFeedback.insertOne({
time: new Date(),
msg: msg.id,
msg_user: msg.author.id,
user: user.id,
emoji: r.emoji.name
});
}
onMessageReactionRemove(r, user)
{
if (user == this.client.user) {
return;
}
var msg = r.message;
if (msg.channel.id != this.config.channel) {
return;
}
if (user == msg.author) {
return;
}
if (this.config.reactions.indexOf(r.emoji.name) == -1) {
return;
}
this.collFilesFeedback.deleteOne({
msg: msg.id,
user: user.id,
emoji: r.emoji.name
});
}
onMessage(msg, edited)
{
if (msg.channel.id != this.config.channel) {
return false;
}
if (edited) {
return false;
}
(async () => {
var user = await this.getOrCreateUser(msg.author.id);
var filenames = "";
var numFiles = 0;
msg.attachments.each(async a => {
if (!a.name.match(/.*\.(wav|mp3|ogg|flac)/)) {
return;
}
filenames += a.name + " ";
numFiles++;
var logUsername = msg.author.username + '#' + msg.author.discriminator;
console.log(logUsername + " uploaded " + a.name.red.underline);
this.collUsers.updateOne({ id: user.id }, {
$inc: { files_uploaded: 1 }
});
/*
statsmessage = false
feedbackmessage = false
spectrumpic = false
*/
if (this.config.spectrumpic) {
new Promise((resolve, reject) => {
let path = '/tmp/waveform-' + msg.id + '.png';
let cmd = ffmpeg(a.url);
cmd.complexFilter([
'[0:a] showspectrumpic=s=400x70:color=nebulae:legend=false [tmp1]',
//'[0:a] showwavespic=s=400x70:colors=0xFFFFFFFF:filter=peak [tmp2]',
//'[tmp1][tmp2] overlay=y=0:format=rgb:alpha=premultiplied [tmp3]',
'[tmp1] drawbox=0:0:400:70:black',
]);
cmd.frames(1);
cmd.on('error', err => {
reject(err);
});
cmd.on('end', () => {
msg.channel.send({
files: [{
attachment: path,
name: 'waveform.png',
}],
}).then(resolve).catch(reject);
});
cmd.save(path);
}).catch(err => {
console.error('ffmpeg waveform failed!', err);
});
}
for (var i = 0; i < this.config.reactions.length; i++) {
await msg.react(this.config.reactions[i]);
}
});
if (numFiles > 0) {
var numFeedbackGiven = await this.getNumberOfFeedbackGiven(user.id);
if (this.config.statsmessage) {
msg.channel.send("**Give " + msg.member.displayName + " your feedback!** :outbox_tray: " + (user.files_uploaded + 1) + " / :bulb: " + numFeedbackGiven);
}
if (this.config.feedbackmessage) {
if (numFeedbackGiven < user.files_uploaded) {
msg.channel.send(msg.member.toString() + " Remember to give others feedback, too! :ok_hand:");
}
}
}
})();
return false;
}
async onCmdStats(msg)
{
if (msg.channel.id != this.config.channel) {
return;
}
var user = await this.getOrCreateUser(msg.author.id);
var numFeedbackReceived = await this.collFilesFeedback.countDocuments({ msg_user: user.id });
var numFeedbackGiven = await this.getNumberOfFeedbackGiven(user.id);
msg.channel.send(":bar_chart: " + msg.member.toString() + ", you have uploaded **" + (user.files_uploaded || 0) + "** files, given **" + numFeedbackGiven + "** feedback reactions, and received **" + numFeedbackReceived + "**.");
}
}
module.exports = ProducingModule;