apollo/services/trackers/plex-tracker.js

71 lines
2.0 KiB
JavaScript

const axios = require("axios");
const Song = require("../../models/song");
class PlexTracker {
#config = null;
#cache = [];
provider = "plex";
constructor(config) {
this.#config = config;
}
get name() {
return this.#config.name;
}
get scrobblerNames() {
return this.#config.scrobblers;
}
async poll(useCache = false) {
if (!this.#config.token || !this.#config.url)
return [];
if (useCache)
return this.#cache;
const response = await axios.get(this.#config.url + "/status/sessions", {
headers: {
"Accept": "application/json",
"X-Plex-Token": this.#config.token
}
});
if (!response.data.MediaContainer?.Metadata) {
this.#cache = [];
return this.#cache;
}
const filtered = response.data.MediaContainer?.Metadata.filter(m => this.#filter(m));
this.#cache = filtered.map(m => this.#transform(m, this.#config.name));
return this.#cache;
}
#filter(data) {
if (!this.#config.filters || this.#config.filters.length == 0)
return true;
for (let filter of this.#config.filters) {
if (filter.library && !filter.library.some(l => l == data.librarySectionTitle))
continue;
if (filter.ip && !filter.ip.some(l => l == data.address))
continue;
if (filter.deviceId && !filter.deviceId.some(l => l == data.machineIdentifier))
continue;
if (filter.platform && !filter.platform.some(l => l == data.Player.platform))
continue;
if (filter.product && !filter.product.some(l => l == data.Player.product))
continue;
return true;
}
return false;
}
#transform(data, source) {
const id = data.guid.substring(data.guid.lastIndexOf('/') + 1);
const artists = data.grandparentTitle.split(',').map(a => a.trim());
return new Song(id, data.title, data.parentTitle, artists, data.parentYear, data.duration, data.viewOffset, data.sessionKey, data.Player.state, source, "plex");
}
}
module.exports = PlexTracker;