Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions bot/db.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
'use strict';
"use strict";
const admin = require("firebase-admin");

/**
*
* @param {string} serviceAccount
* @param {string} BASEURL
* @param {string} [optionalAppName]
* @returns
*
* @param {string | import('firebase-admin').ServiceAccount} serviceAccount
* @param {string} BASEURL
* @param {string} [optionalAppName]
* @returns
*/
module.exports = function database(serviceAccount, BASEURL, optionalAppName) {
if (!serviceAccount || !BASEURL) {
throw new Error("Missing databse credentials for Database");
}

// returns an instances of admin.app
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: BASEURL
}, optionalAppName);
admin.initializeApp(
{
credential: admin.credential.cert(serviceAccount),
databaseURL: BASEURL,
},
optionalAppName
);

return admin.database();
};
};
143 changes: 73 additions & 70 deletions bot/events/room_playlist-update.js
Original file line number Diff line number Diff line change
@@ -1,127 +1,128 @@
/***************************************************************
* Event: room_playlist-update
*
*
* This event is fired when a new song begins to play
*/
'use strict';
const mediaStore = require(process.cwd()+ '/bot/store/mediaInfo.js');
const userStore = require(process.cwd()+ '/bot/store/users.js');
const youtube = require(process.cwd()+'/bot/utilities/youtube.js');
const soundcloud = require(process.cwd()+'/bot/utilities/soundcloud');
const historyStore = require(process.cwd()+ '/bot/store/history.js');
const _ = require('lodash');
const moment = require('moment');
const repo = require(process.cwd()+'/repo');
"use strict";
const mediaStore = require(process.cwd() + "/bot/store/mediaInfo.js");
const userStore = require(process.cwd() + "/bot/store/users.js");
const youtube = require(process.cwd() + "/bot/utilities/youtube.js");
const soundcloud = require(process.cwd() + "/bot/utilities/soundcloud");
const historyStore = require(process.cwd() + "/bot/store/history.js");
const _ = require("lodash");
const moment = require("moment");
const repo = require(process.cwd() + "/repo");

/**
*
* @param {object} bot instance of dubapi
*
* @param {DubAPI} bot instance of dubapi
* @param {object} currentSong song data of current track playing
*/
function reviewPoints(bot, currentSong) {
var propped = userStore.getProps();
var flowed = userStore.getFlows();

var messageToSend = [];
var plural = '';
var finalChat = '';
var plural = "";
var finalChat = "";


if (propped.length > 0) {
plural = propped.length > 1 ? 's' : '';
plural = propped.length > 1 ? "s" : "";
messageToSend.push(`${propped.length} prop${plural} :fist: :heart: :musical_note:`);
}

if (flowed.length > 0) {
plural = flowed.length > 1 ? 's' : '';
plural = flowed.length > 1 ? "s" : "";
messageToSend.push(`${flowed.length} flowpoint${plural} :surfer:`);
}

if (messageToSend.length > 0) {
finalChat = `'${currentSong.name}', queued by ${currentSong.dj} received `;
finalChat += messageToSend.join( ' and ' );
finalChat += messageToSend.join(" and ");
bot.sendChat(finalChat);
}
}

/**
* handles various song warning and skipping of broken tracks
* for now this only handles youtube because it's more complex
*
*
* @param {DubAPI} bot instanceOf dubapi
* @param {import('firebase-admin').database} db database object
* @param {object} data dubapi song data
* @param {Song} data dubapi song data
*/
function songModerate(bot, db, data){
var songLength = _.get(data, 'media.songLength');
if (songLength &&
bot.myconfig.longSongs.warn &&
songLength >= bot.myconfig.longSongs.max)
{
function songModerate(bot, db, data) {
var songLength = data?.media?.songLength;
if (songLength && bot.myconfig.longSongs.warn && songLength >= bot.myconfig.longSongs.max) {
bot.sendChat(bot.myconfig.longSongs.message);
}

var songID = _.get(data, 'media.fkid');
var type = _.get(data, 'media.type');
if (!type || !songID) { return; }
var songID = data?.media?.fkid;
var type = data?.media?.type;
if (!type || !songID) {
return;
}

if (type.toUpperCase() === 'YOUTUBE'){
if (type.toUpperCase() === "YOUTUBE") {
return youtube(bot, db, data.media);
}
}

/**
* Save song to bot's own playlist.
* Helpful to build a large playlist so bot can play during off hours
*
* @param {import('firebase-admin').database} db
* @param {DubAPI} bot
* @param {object} song
*
* @param {import('firebase-admin').database} db
* @param {DubAPI} bot
* @param {Song} song
*/
function saveSong(db, bot, song) {
// then save songs to bot's playlist for later use
// skip saving songs on Funky Friday
if (moment().format('dddd') === 'Friday') { return; }
if (moment().format("dddd") === "Friday") {
return;
}

bot.getRoomHistory(1, function(history){

bot.getRoomHistory(1, function (history) {
if (history && history.length > 0) {

// we don't want to save a skipped song
if (history[0].skipped) {return;}
if (history[0].skipped) {
return;
}

let song = history[0]._song;

bot.addToPlaylist(
bot.myconfig.playlistID, song.fkid, song.type,
function(code, _data){
if (code === 200) {
bot.log('info','BOT', `${song.name} saved to playlist`);
}
if (code === 400) {
bot.log('info','BOT', `${song.name} - ${_data.data.details.message}`);
}
bot.addToPlaylist(bot.myconfig.playlistID, song.fkid, song.type, function (code, _data) {
if (code === 200) {
bot.log("info", "BOT", `${song.name} saved to playlist`);
}
);
if (code === 400) {
bot.log("info", "BOT", `${song.name} - ${_data.data.details.message}`);
}
});
}

});
}

module.exports = function(bot, db) {
bot.on(bot.events.roomPlaylistUpdate, function(data) {
/**
*
* @param {DubAPI} bot
* @param {import('firebase-admin').database} db
*/
module.exports = function (bot, db) {
bot.on(bot.events.roomPlaylistUpdate, function (data) {
bot.updub();

let dj = _.get(data, 'user.username', '404usernamenotfound');
let dj = data?.user?.username || "404usernamenotfound";

/************************************************************
* song info and trackinng
*/

var currentSong = mediaStore.getCurrent(); // gets last played song
var propped = userStore.getProps(); // get props given for last song
var flowed = userStore.getFlows(); // get flow points for last song

/************************************************************
* review points
* send chat message if there were any props or flow points given
Expand All @@ -132,7 +133,7 @@ module.exports = function(bot, db) {
* save current song as last song data in the store
* !lastplayed uses it
*/

currentSong.usersThatFlowed = flowed.length;
currentSong.usersThatPropped = propped.length;
mediaStore.setLast(db, currentSong);
Expand All @@ -144,7 +145,9 @@ module.exports = function(bot, db) {
var newSong = {};

// if no data.media from the api then stop now because everything below needs it
if(!data.media) { return; }
if (!data.media) {
return;
}

newSong.name = data.media.name;
newSong.id = data.media.fkid;
Expand All @@ -155,28 +158,29 @@ module.exports = function(bot, db) {

// store new song data reseting current in the store
mediaStore.setCurrent(newSong);

if (data.media.type.toUpperCase() === 'SOUNDCLOUD') {

soundcloud.getLink(bot, data.media ,function(result){
mediaStore.setCurrentKey('link', result.link);
if (data.media.type.toUpperCase() === "SOUNDCLOUD") {
soundcloud.getLink(bot, data.media, function (result) {
mediaStore.setCurrentKey("link", result.link);
// by doing this we also check if we need to skip because track is broken
// youtube has much more various reasons for being skipped, sc is more basic
// so we can do it here
// so we can do it here
if (result.skippable) {
soundcloud.skip(bot, data.media, `Sorry @${dj} that ${result.reason}`, result.error_message);
soundcloud.skip(
bot,
data.media,
`Sorry @${dj} that ${result.reason}`,
result.error_message
);
}

});

} else {
mediaStore.setCurrentKey('link', `http://www.youtube.com/watch?v=${data.media.fkid}`);
mediaStore.setCurrentKey("link", `http://www.youtube.com/watch?v=${data.media.fkid}`);
}

/************************************************************
* check youtube links for various issues
*/

songModerate(bot, db, data);

/************************************************************
Expand All @@ -185,6 +189,5 @@ module.exports = function(bot, db) {
if (bot.myconfig.saveSongs) {
saveSong(db, bot, newSong);
}

});
};
22 changes: 15 additions & 7 deletions bot/extend/addToPlaylist.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,23 @@
let loc = process.cwd() + '/node_modules/dubapi';
const endpoints = require(loc + '/lib/data/endpoints.js');

module.exports = function(playlistID, fkid, type, callback){
/* jshint validthis:true */
if (!this._.connected){ return false; }

var url = endpoints.userPlaylist.replace('%PID%',playlistID) + '/songs';
/**
*
* @this {DubAPI}
* @param {string} playlistID
* @param {string} fkid
* @param {string} type
* @param {(code: number, data) => void} callback
* @returns {boolean}
*/
module.exports = function (playlistID, fkid, type, callback) {
if (!this._.connected) { return false; }

var form = {fkid: fkid, type: type};
var url = endpoints.userPlaylist.replace('%PID%', playlistID) + '/songs';

this._.reqHandler.queue({method: 'POST', url: url, form: form}, callback);
var form = { fkid, type };

this._.reqHandler.queue({ method: 'POST', url, form }, callback);

return true;
};
21 changes: 12 additions & 9 deletions bot/extend/getRoomHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ function makeRequestArray(roomID, pages) {

// store our module-scoped generator
/**
* @type {IterableIterator<string>}
* @type {IterableIterator<void>}
*/
var hist;

/**
* Make requests to url and return results to yield
* @param {object} context "this" of DubAPI
* @param {DubAPI} context "this" of DubAPI
* @param {string} url The url to make GET request to
*/
function requestWrapper(context, url) {
Expand All @@ -69,14 +69,15 @@ function requestWrapper(context, url) {

/**
* Main Generator function to iterate over array at our own pace
* @param {object} context the "this" of the DubAPI
* @param {string[]} reqArray the array of history urls that we will be calling
* @param {(history: string[]) => void} doneCB on complete, this will be exec passing history[] to it
* @param {DubAPI} context the "this" of the DubAPI
* @param {string[]} reqArray the array of history urls that we will be calling
* @param {(history: SongHistory[]) => void} doneCB on complete, this will be exec passing history[] to it
* TODO: the param is actually an array of objects
* @returns {IterableIterator<void>}
*/
function* history(context, reqArray, doneCB) {
/**
* @type {string[]}
* @type {SongHistory[]}
*/
let history = [];

Expand All @@ -93,17 +94,19 @@ function* history(context, reqArray, doneCB) {

/**
* API for module. This is what you will be calling externally
* @this {DubAPI}
* @param {number} pages number of pages of history to retrieve
* @param {()=>void} callback when all history pages are retrieved, this funciton will be run
* @param {(history: SongHistory[])=>void} callback when all history pages are retrieved, this funciton will be run
* @returns {false | void}
*/
function getRoomHistory(pages, callback) {
/* jshint validthis:true */
if (!this._.connected) {
if (!this._?.connected) {
return false;
}

// make sure we can get roomid
var roomid = _.get(this, "_.room.id");
var roomid = this._?.room?.id;
if (!roomid) {
return false;
}
Expand Down
Loading