Random episode order in random/time slots is preserved in consecutive runs.

This commit is contained in:
vexorian 2021-09-20 13:42:17 -04:00
parent 1e2336d627
commit ee53210f2f
6 changed files with 172 additions and 203 deletions

View File

@ -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'

View File

@ -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 {

View File

@ -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();
}
}

View File

@ -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,
}

View File

@ -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();
}
}

View File

@ -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];
}
}
}
}