From 3da41e44cb99ef95dbb98a2b1251676800dc11b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christer=20War=C3=A9n?= Date: Tue, 31 Mar 2020 09:53:58 +0300 Subject: [PATCH] Added statistics command and datastore for statistics --- commands/play.js | 26 ++++++++++++- commands/statistics.js | 59 +++++++++++++++++++++++++++++ commands/stop.js | 15 ++++++++ package.json | 3 +- struct/client.js | 2 + struct/datastore.js | 85 ++++++++++++++++++++++++++++++++++++++++++ struct/messages.js | 3 +- 7 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 commands/statistics.js create mode 100644 struct/datastore.js diff --git a/commands/play.js b/commands/play.js index 313edba..1dd4941 100644 --- a/commands/play.js +++ b/commands/play.js @@ -38,14 +38,27 @@ module.exports = { const sstation = await searchStation(args.slice(1).join(' '), client); if (!sstation) return msg.channel.send(client.messageEmojis["x"] + client.messages.noSearchResults); url = sstation.stream[sstation.stream.default]; - station = sstation + station = sstation; } if (radio) { + + if(!radio.currentGuild.statistics[radio.station.name]){ + radio.currentGuild.statistics[radio.station.name] = {}; + radio.currentGuild.statistics[radio.station.name].time = 0; + radio.currentGuild.statistics[radio.station.name].used = 0; + client.datastore.updateEntry(msg.guild, radio.currentGuild); + } + + radio.currentGuild.statistics[radio.station.name].time = parseInt(radio.currentGuild.statistics[radio.station.name].time)+parseInt(radio.connection.dispatcher.streamTime.toFixed(0)); + radio.currentGuild.statistics[radio.station.name].used = parseInt(radio.currentGuild.statistics[radio.station.name].used)+1; + client.datastore.updateEntry(msg.guild, radio.currentGuild); + radio.connection.dispatcher.destroy(); radio.station = station; radio.textChannel = msg.channel; play(msg.guild, client, url); + return; } @@ -62,6 +75,17 @@ module.exports = { const connection = await voiceChannel.join(); construct.connection = connection; play(msg.guild, client, url); + + client.datastore.checkEntry(msg.guild.id); + construct.currentGuild = client.datastore.getEntry(msg.guild.id); + + if(!construct.currentGuild.statistics[construct.station.name]){ + construct.currentGuild.statistics[construct.station.name] = {}; + construct.currentGuild.statistics[construct.station.name].time = 0; + construct.currentGuild.statistics[construct.station.name].used = 0; + client.datastore.updateEntry(msg.guild, construct.currentGuild); + } + } catch (error) { client.radio.delete(msg.guild.id); return msg.channel.send(client.messageEmojis["x"] + `An error occured: ${error}`); diff --git a/commands/statistics.js b/commands/statistics.js new file mode 100644 index 0000000..0bad094 --- /dev/null +++ b/commands/statistics.js @@ -0,0 +1,59 @@ +module.exports = { + name: 'statistics', + alias: 'stats', + usage: '', + description: 'Show usage statistics.', + permission: 'none', + category: 'info', + execute(msg, args, client, Discord, command) { + let stations = client.stations; + let currentGuildStatistics = client.datastore.getEntry(msg.guild.id).statistics; + let statistics; + let i = 0; + + Object.keys(client.stations).forEach(function(station) { + if(currentGuildStatistics[stations[station].name]){ + if(i > 0){ + statistics += "**" + station + " " + stations[station].name + "** \n"; + statistics += "Time: " + msToTime(currentGuildStatistics[stations[station].name].time, "hh:mm:ss") + "\n"; + statistics += "Used: " + currentGuildStatistics[stations[station].name].used + "\n"; + } else { + statistics = "**" + station + " " + stations[station].name + "** \n"; + statistics += "Time: " + msToTime(currentGuildStatistics[stations[station].name].time, "hh:mm:ss") + "\n"; + statistics += "Used: " + currentGuildStatistics[stations[station].name].used + "\n"; + } + i++; + } + }); + + if(!statistics){ + statistics = "You have not listened any radio station"; + } + + const embed = new Discord.MessageEmbed() + .setTitle(client.messages.statisticsTitle) + .setThumbnail("https://cdn.discordapp.com/emojis/" + client.messageEmojis["list"].replace(/[^0-9]+/g, '')) + .setColor(client.config.embedColor) + .setDescription(statistics) + .setFooter('EximiaBots by Warén Media', "https://cdn.discordapp.com/emojis/" + client.messageEmojis["eximiabots"].replace(/[^0-9]+/g, '')); + return msg.channel.send(embed); + } +}; + +function msToTime(duration, format) { + var seconds = Math.floor((duration / 1000) % 60), + minutes = Math.floor((duration / (1000 * 60)) % 60), + hours = Math.floor((duration / (1000 * 60 * 60)) % 24); + days = Math.floor((duration / (1000 * 60 * 60 * 24)) % 24); + + days = (days < 10) ? "0" + days : days; + hours = (hours < 10) ? "0" + hours : hours; + minutes = (minutes < 10) ? "0" + minutes : minutes; + seconds = (seconds < 10) ? "0" + seconds : seconds; + + if (format === "hh:mm:ss") { + return `${hours}:${minutes}:${seconds}`; + } else if (format === "dd:hh:mm:ss") { + return `${days}:${hours}:${minutes}:${seconds}`; + } +} \ No newline at end of file diff --git a/commands/stop.js b/commands/stop.js index f7979f6..122a574 100644 --- a/commands/stop.js +++ b/commands/stop.js @@ -8,6 +8,21 @@ module.exports = { execute(msg, args, client, Discord, command) { const radio = client.radio.get(msg.guild.id); if (client.funcs.check(client, msg, command)) { + + client.datastore.checkEntry(msg.guild.id); + radio.currentGuild = client.datastore.getEntry(msg.guild.id); + if(!radio.currentGuild.statistics[radio.station.name]){ + radio.currentGuild.statistics[radio.station.name] = {}; + radio.currentGuild.statistics[radio.station.name].time = 0; + radio.currentGuild.statistics[radio.station.name].used = 0; + client.datastore.updateEntry(msg.guild, radio.currentGuild); + } + + radio.currentGuild.statistics[radio.station.name].time = parseInt(radio.currentGuild.statistics[radio.station.name].time)+parseInt(radio.connection.dispatcher.streamTime.toFixed(0)); + radio.currentGuild.statistics[radio.station.name].used = parseInt(radio.currentGuild.statistics[radio.station.name].used)+1; + client.datastore.updateEntry(msg.guild, radio.currentGuild); + + radio.connection.dispatcher.destroy(); radio.voiceChannel.leave(); client.radio.delete(msg.guild.id); diff --git a/package.json b/package.json index f19f570..0ed5fec 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "We will bring you finnish radio to your discord server", "main": "index.js", "scripts": { - "start": "node ." + "start": "node .", + "install": "mkdir datastore" }, "repository": { "type": "git", diff --git a/struct/client.js b/struct/client.js index cbf4288..21ca272 100644 --- a/struct/client.js +++ b/struct/client.js @@ -3,6 +3,7 @@ const Discord = require('discord.js'); const fs = require('fs'); const path = require('path'); const events = '../events/'; +const Datastore = require('./datastore.js'); module.exports = class extends Client { constructor() { @@ -28,6 +29,7 @@ module.exports = class extends Client { this.on('ready', () => { require(`${events}ready`).execute(this, Discord); + this.datastore = new Datastore(); }); this.on('message', (msg) => { require(`${events}msg`).execute(this, msg, Discord); diff --git a/struct/datastore.js b/struct/datastore.js new file mode 100644 index 0000000..a37d691 --- /dev/null +++ b/struct/datastore.js @@ -0,0 +1,85 @@ +const fs = require('fs'); +const path = require('path'); + +module.exports = class { + constructor() { + this.map = new Map(); + this.loadData(); + } + + loadData() { + console.log(""); + const dataFiles = fs.readdirSync(path.join(path.dirname(__dirname), 'datastore')).filter(f => f.endsWith('.json')); + for (const file of dataFiles) { + try { + const json = require(`../datastore/${file}`); + this.map.set(json.guild.id, json); + //console.log('[LOADED] ' + file + " (" + json.guild.id + ")"); + //console.log(JSON.stringify(json, null, 4)); + } catch (error) { + //console.log('[ERROR] Loading ' + file + ' failed'); + } + } + console.log(""); + } + + checkEntry(id){ + if(!this.map.has(id)){ + this.createEntry(id); + //this.showEntry(this.getEntry(id)); + } else { + //this.showEntry(this.getEntry(id)); + } + } + + createEntry(id){ + let newData = {}; + newData.guild = {}; + newData.guild.id = id; + newData.statistics = {}; + this.map.set(id, newData); + this.saveEntry(id, newData); + } + + getEntry(id){ + return this.map.get(id); + } + + updateEntry(guild, newData) { + newData.guild.name = guild.name; + this.map.set(guild.id, newData); + this.saveEntry(guild.id, newData); + //this.showEntry(this.getEntry(guild.id)); + } + + showEntry(data){ + console.log(data); + } + + createTestFile () { + let newData = { + "guild": { + "id": "test", + "name": "Test" + }, + "statistics": { + "test": { + "time": 0, + "used": 0 + } + } + } + + this.updateEntry(newData.guild, newData); + } + + saveEntry(file, data) { + data = JSON.stringify(data, null, 4); + + fs.writeFile(path.join(path.dirname(__dirname), 'datastore') + "/" + file + ".json", data, function(err) { + if (err) { + //console.log(err); + } + }); + } +}; diff --git a/struct/messages.js b/struct/messages.js index d36c502..3eeed40 100644 --- a/struct/messages.js +++ b/struct/messages.js @@ -28,5 +28,6 @@ module.exports = { maxVolume: "The max volume is `100`!", invalidVolume: "You need to enter a valid __number__.", negativeVolume: "The volume needs to be a positive number!", - newVolume: "Volume is now: **%volume%**" + newVolume: "Volume is now: **%volume%**", + statisticsTitle: "Statistics" }; \ No newline at end of file