diff --git a/src/api.js b/src/api.js index f778059..dfe10ef 100644 --- a/src/api.js +++ b/src/api.js @@ -1038,7 +1038,6 @@ function api(db, channelService, fillerDB, customShowDB, xmltvInterval, guideSe delete toolRes.programs; let s = JSON.stringify(toolRes); s = s.slice(0, -1); - console.log( JSON.stringify(toolRes)); res.writeHead(200, { 'Content-Type': 'application/json' diff --git a/src/services/get-show-data.js b/src/services/get-show-data.js index 99d44b1..dec2a33 100644 --- a/src/services/get-show-data.js +++ b/src/services/get-show-data.js @@ -12,6 +12,7 @@ module.exports = function () { showId : "custom." + program.customShowId, showDisplayName : program.customShowName, order : program.customOrder, + shuffleOrder : program.shuffleOrder, } } else if (program.isOffline && program.type === 'redirect') { return { @@ -35,6 +36,7 @@ module.exports = function () { showId : "movie.", showDisplayName : "Movies", order : movieTitleOrder[key], + shuffleOrder : program.shuffleOrder, } } else if ( (program.type === 'episode') || (program.type === 'track') ) { let s = 0; @@ -54,6 +56,7 @@ module.exports = function () { showId : prefix + program.showTitle, showDisplayName : program.showTitle, order : s * 1000000 + e, + shuffleOrder : program.shuffleOrder, } } else { return { diff --git a/src/services/random-slots-service.js b/src/services/random-slots-service.js index d7c149b..8be4b72 100644 --- a/src/services/random-slots-service.js +++ b/src/services/random-slots-service.js @@ -2,7 +2,7 @@ const constants = require("../constants"); const getShowData = require("./get-show-data")(); const random = require('../helperFuncs').random; const throttle = require('./throttle'); - +const orderers = require("./show-orderers"); const MINUTE = 60*1000; const DAY = 24*60*MINUTE; @@ -22,29 +22,6 @@ function getShow(program) { } } - -function shuffle(array, lo, hi ) { - if (typeof(lo) === 'undefined') { - lo = 0; - hi = array.length; - } - let currentIndex = hi, temporaryValue, randomIndex - while (lo !== currentIndex) { - randomIndex = random.integer(lo, currentIndex-1); - currentIndex -= 1 - temporaryValue = array[currentIndex] - array[currentIndex] = array[randomIndex] - array[randomIndex] = temporaryValue - } - return array -} - -function _wait(t) { - return new Promise((resolve) => { - setTimeout(resolve, t); - }); -} - function getProgramId(program) { let s = program.serverKey; if (typeof(s) === 'undefined') { @@ -69,78 +46,6 @@ function addProgramToShow(show, program) { } } -function getShowOrderer(show) { - if (typeof(show.orderer) === 'undefined') { - - let sortedPrograms = JSON.parse( JSON.stringify(show.programs) ); - sortedPrograms.sort((a, b) => { - let showA = getShowData(a); - let showB = getShowData(b); - return showA.order - showB.order; - }); - - let position = 0; - while ( - (position + 1 < sortedPrograms.length ) - && - ( - getShowData(show.founder).order - !== - getShowData(sortedPrograms[position]).order - ) - ) { - position++; - } - - - show.orderer = { - - current : () => { - return sortedPrograms[position]; - }, - - next: () => { - position = (position + 1) % sortedPrograms.length; - }, - - } - } - return show.orderer; -} - - -function getShowShuffler(show) { - if (typeof(show.shuffler) === 'undefined') { - if (typeof(show.programs) === 'undefined') { - throw Error(show.id + " has no programs?") - } - - let randomPrograms = JSON.parse( JSON.stringify(show.programs) ); - let n = randomPrograms.length; - shuffle( randomPrograms, 0, n); - let position = 0; - - show.shuffler = { - - current : () => { - return randomPrograms[position]; - }, - - next: () => { - position++; - if (position == n) { - let a = Math.floor(n / 2); - shuffle(randomPrograms, 0, a ); - shuffle(randomPrograms, a, n ); - position = 0; - } - }, - - } - } - return show.shuffler; -} - module.exports = async( programs, schedule ) => { if (! Array.isArray(programs) ) { return { userError: 'Expected a programs array' }; @@ -192,9 +97,6 @@ module.exports = async( programs, schedule ) => { } let flexBetween = ( schedule.flexPreference !== "end" ); - // throttle so that the stream is not affected negatively - let steps = 0; - let showsById = {}; let shows = []; @@ -216,9 +118,9 @@ module.exports = async( programs, schedule ) => { channel: show.channel, } } else if (slot.order === 'shuffle') { - return getShowShuffler(show).current(); + return orderers.getShowShuffler(show).current(); } else if (slot.order === 'next') { - return getShowOrderer(show).current(); + return orderers.getShowOrderer(show).current(); } } @@ -228,9 +130,9 @@ module.exports = async( programs, schedule ) => { } let show = shows[ showsById[slot.showId] ]; if (slot.order === 'shuffle') { - return getShowShuffler(show).next(); + return orderers.getShowShuffler(show).next(); } else if (slot.order === 'next') { - return getShowOrderer(show).next(); + return orderers.getShowOrderer(show).next(); } } diff --git a/src/services/show-orderers.js b/src/services/show-orderers.js new file mode 100644 index 0000000..06af2e8 --- /dev/null +++ b/src/services/show-orderers.js @@ -0,0 +1,156 @@ +const random = require('../helperFuncs').random; +const getShowData = require("./get-show-data")(); +const randomJS = require("random-js"); +const Random = randomJS.Random; + + + +/**** + * + * Code shared by random slots and time slots for keeping track of the order + * of episodes + * + **/ +function shuffle(array, lo, hi, randomOverride ) { + let r = randomOverride; + if (typeof(r) === 'undefined') { + r = random; + } + if (typeof(lo) === 'undefined') { + lo = 0; + hi = array.length; + } + let currentIndex = hi, temporaryValue, randomIndex + while (lo !== currentIndex) { + randomIndex = r.integer(lo, currentIndex-1); + currentIndex -= 1 + temporaryValue = array[currentIndex] + array[currentIndex] = array[randomIndex] + array[randomIndex] = temporaryValue + } + return array +} + + +function getShowOrderer(show) { + if (typeof(show.orderer) === 'undefined') { + + let sortedPrograms = JSON.parse( JSON.stringify(show.programs) ); + sortedPrograms.sort((a, b) => { + let showA = getShowData(a); + let showB = getShowData(b); + return showA.order - showB.order; + }); + + let position = 0; + while ( + (position + 1 < sortedPrograms.length ) + && + ( + getShowData(show.founder).order + !== + getShowData(sortedPrograms[position]).order + ) + ) { + position++; + } + + + show.orderer = { + + current : () => { + return sortedPrograms[position]; + }, + + next: () => { + position = (position + 1) % sortedPrograms.length; + }, + + } + } + return show.orderer; +} + + +function getShowShuffler(show) { + if (typeof(show.shuffler) === 'undefined') { + if (typeof(show.programs) === 'undefined') { + throw Error(show.id + " has no programs?") + } + + let sortedPrograms = JSON.parse( JSON.stringify(show.programs) ); + sortedPrograms.sort((a, b) => { + let showA = getShowData(a); + let showB = getShowData(b); + return showA.order - showB.order; + }); + let n = sortedPrograms.length; + + let splitPrograms = []; + let randomPrograms = []; + + for (let i = 0; i < n; i++) { + splitPrograms.push( sortedPrograms[i] ); + randomPrograms.push( {} ); + } + + + let showId = getShowData(show.programs[0]).showId; + + let position = show.founder.shuffleOrder; + if (typeof(position) === 'undefined') { + position = 0; + } + + let localRandom = null; + + let initGeneration = (generation) => { + let seed = []; + for (let i = 0 ; i < show.showId.length; i++) { + seed.push( showId.charCodeAt(i) ); + } + seed.push(generation); + + localRandom = new Random( randomJS.MersenneTwister19937.seedWithArray(seed) ) + + if (generation == 0) { + shuffle( splitPrograms, 0, n , localRandom ); + } + for (let i = 0; i < n; i++) { + randomPrograms[i] = splitPrograms[i]; + } + let a = Math.floor(n / 2); + shuffle( randomPrograms, 0, a, localRandom ); + shuffle( randomPrograms, a, n, localRandom ); + }; + initGeneration(0); + let generation = Math.floor( position / n ); + initGeneration( generation ); + + show.shuffler = { + + current : () => { + let prog = JSON.parse( + JSON.stringify(randomPrograms[position % n] ) + ); + prog.shuffleOrder = position; + return prog; + }, + + next: () => { + position++; + if (position % n == 0) { + let generation = Math.floor( position / n ); + initGeneration( generation ); + } + }, + + } + } + return show.shuffler; +} + +module.exports = { + getShowOrderer : getShowOrderer, + getShowShuffler: getShowShuffler, +} \ No newline at end of file diff --git a/src/services/time-slots-service.js b/src/services/time-slots-service.js index fe6b6a8..1fb8fe6 100644 --- a/src/services/time-slots-service.js +++ b/src/services/time-slots-service.js @@ -4,6 +4,7 @@ const constants = require("../constants"); const getShowData = require("./get-show-data")(); const random = require('../helperFuncs').random; const throttle = require('./throttle'); +const orderers = require("./show-orderers"); const MINUTE = 60*1000; const DAY = 24*60*MINUTE; @@ -22,28 +23,6 @@ function getShow(program) { } } -function shuffle(array, lo, hi ) { - if (typeof(lo) === 'undefined') { - lo = 0; - hi = array.length; - } - let currentIndex = hi, temporaryValue, randomIndex - while (lo !== currentIndex) { - randomIndex = random.integer(lo, currentIndex-1); - currentIndex -= 1 - temporaryValue = array[currentIndex] - array[currentIndex] = array[randomIndex] - array[randomIndex] = temporaryValue - } - return array -} - -function _wait(t) { - return new Promise((resolve) => { - setTimeout(resolve, t); - }); -} - function getProgramId(program) { let s = program.serverKey; if (typeof(s) === 'undefined') { @@ -68,78 +47,6 @@ function addProgramToShow(show, program) { } } -function getShowOrderer(show) { - if (typeof(show.orderer) === 'undefined') { - - let sortedPrograms = JSON.parse( JSON.stringify(show.programs) ); - sortedPrograms.sort((a, b) => { - let showA = getShowData(a); - let showB = getShowData(b); - return showA.order - showB.order; - }); - - let position = 0; - while ( - (position + 1 < sortedPrograms.length ) - && - ( - getShowData(show.founder).order - !== - getShowData(sortedPrograms[position]).order - ) - ) { - position++; - } - - - show.orderer = { - - current : () => { - return sortedPrograms[position]; - }, - - next: () => { - position = (position + 1) % sortedPrograms.length; - }, - - } - } - return show.orderer; -} - - -function getShowShuffler(show) { - if (typeof(show.shuffler) === 'undefined') { - if (typeof(show.programs) === 'undefined') { - throw Error(show.id + " has no programs?") - } - - let randomPrograms = JSON.parse( JSON.stringify(show.programs) ); - let n = randomPrograms.length; - shuffle( randomPrograms, 0, n); - let position = 0; - - show.shuffler = { - - current : () => { - return randomPrograms[position]; - }, - - next: () => { - position++; - if (position == n) { - let a = Math.floor(n / 2); - shuffle(randomPrograms, 0, a ); - shuffle(randomPrograms, a, n ); - position = 0; - } - }, - - } - } - return show.shuffler; -} - module.exports = async( programs, schedule ) => { if (! Array.isArray(programs) ) { return { userError: 'Expected a programs array' }; @@ -224,9 +131,9 @@ module.exports = async( programs, schedule ) => { channel: show.channel, } } else if (slot.order === 'shuffle') { - return getShowShuffler(show).current(); + return orderers.getShowShuffler(show).current(); } else if (slot.order === 'next') { - return getShowOrderer(show).current(); + return orderers.getShowOrderer(show).current(); } } @@ -236,9 +143,9 @@ module.exports = async( programs, schedule ) => { } let show = shows[ showsById[slot.showId] ]; if (slot.order === 'shuffle') { - return getShowShuffler(show).next(); + return orderers.getShowShuffler(show).next(); } else if (slot.order === 'next') { - return getShowOrderer(show).next(); + return orderers.getShowOrderer(show).next(); } } diff --git a/web/services/common-program-tools.js b/web/services/common-program-tools.js index b851c21..907a6e5 100644 --- a/web/services/common-program-tools.js +++ b/web/services/common-program-tools.js @@ -59,7 +59,9 @@ module.exports = function (getShowData) { let data = getShowData(progs[i]); if (data.hasShow) { let key = data.showId + "|" + data.order; - tmpProgs[key] = progs[i]; + if (typeof(tmpProgs[key]) === 'undefined') { + tmpProgs[key] = progs[i]; + } } } }