apollo/services/poll.js

75 lines
2.2 KiB
JavaScript

const plex = require("./plex");
const logger = require("./logging")
const config = require("../config/configuration");
const lastPlaying = {};
const lastScrobbleTimes = {};
async function poll() {
const now = Date.now();
const playing = [];
try {
const data = await plex.getCurrentlyPlaying();
playing.push.apply(playing, data);
} catch (ex) {
logger.error(ex, "Could not fetch currently playing data from Plex.");
return;
}
for (let media of playing) {
if (!lastScrobbleTimes[media.mediaKey]) {
lastScrobbleTimes[media.mediaKey] = 1;
}
const lastTrack = lastPlaying[media.sessionKey];
if (!lastTrack) {
logger.info(media, "A new session has started.");
} else {
if (checkIfCanScrobble(media, lastTrack, now)) {
logger.info(lastTrack, "Scrobble");
lastScrobbleTimes[lastTrack.mediaKey] = now;
}
}
lastPlaying[media.sessionKey] = media;
}
// Scrobble then remove lingering sessions
for (let key in lastPlaying) {
if (!playing.some(p => p.sessionKey == key)) {
const track = lastPlaying[key];
if (checkIfCanScrobble(null, track, now)) {
logger.info(track, "Scrobble");
lastScrobbleTimes[track.mediaKey] = now;
}
delete lastPlaying[key];
logger.debug("Deleted old session.", key);
}
}
}
function checkIfCanScrobble(current, last, now) {
const scrobbleDuration = isInt(config.scrobble.duration) ? Number(config.scrobble.duration) : 30;
const scrobblePercent = isInt(config.scrobble.percent) ? Number(config.scrobble.percent) : 30;
if (last) {
const newPlayback = current == null || current.playtime < last.playtime;
const canBeScrobbled = last.playtime > scrobbleDuration * 1000 || last.playtime / last.duration > scrobblePercent;
if (newPlayback && canBeScrobbled) {
const sameSong = current != null && current.mediaKey == last.mediaKey;
const lastTime = lastScrobbleTimes[last.mediaKey];
return !sameSong || !lastTime || now - lastTime > scrobbleDuration;
}
}
return false;
}
function isInt(value) {
return !isNaN(value) &&
parseInt(Number(value)) == value &&
!isNaN(parseInt(value, 10));
}
module.exports = poll;