xtremio-plus / index.js
mikmc's picture
Update index.js
e72e934 verified
const express = require("express");
const path = require("path"); // Import path module for path handling
const app = express();
const config = require('./config');
const MANIFEST = require('./manifest');
const { getManifest, getCatalog, getMeta, getUserData } = require("./addon");
const { createXtreamModule } = require("./xtream-module");
const NodeCache = require("node-cache");
const myCache = new NodeCache({ stdTTL: 200 });
// Middleware to allow CORS and set response headers
var respond = function (res, data) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
res.setHeader('Content-Type', 'application/json');
res.send(data);
};
// Serve static files from the 'assets' directory
app.use('/assets', express.static(path.join(__dirname, 'assets')));
app.engine('html', require('ejs').renderFile);
app.set('views', path.join(__dirname, 'views'));
app.get("/", function (req, res) {
res.redirect("/configure");
});
app.get("/:userConf?/configure", function (req, res) {
const newManifest = { ...{ MANIFEST } };
res.render('configure.html', newManifest);
});
app.get('/manifest.json', function (req, res) {
const newManifest = { ...MANIFEST };
newManifest.behaviorHints.configurationRequired = true;
respond(res, newManifest);
});
app.get('/:userConf/manifest.json', async function (req, res) {
let newManifest = { ...MANIFEST };
if (!((req || {}).params || {}).userConf) {
newManifest.behaviorHints.configurationRequired = true;
respond(res, newManifest);
} else {
try {
if (myCache.has(`manifest-${req.params.userConf}`)) {
respond(res, myCache.get(`manifest-${req.params.userConf}`));
} else {
newManifest = await getManifest(req.params.userConf);
if (newManifest && newManifest.id) {
myCache.set(`manifest-${req.params.userConf}`, newManifest);
}
respond(res, newManifest);
}
} catch (error) {
console.log(error);
respond(res, { error: error });
}
}
});
app.get('/:userConf/catalog/:type/:id/:extra?.json', async function (req, res) {
let { userConf, type, id, extra } = req.params;
let extraObj;
if (extra) {
try {
extraObj = JSON.parse('{"' + decodeURI(extra.replace(/&/g, '","').replace(/=/g, '":"')) + '"}');
} catch (error) {
console.log(error);
return respond(res, { metas: [] });
}
}
if (extraObj && extraObj.genre && extraObj.genre.includes("+")) {
extraObj.genre = extraObj.genre.replace(/\+/g, ' ');
}
let metas = [];
try {
if (myCache.has(`catalog-${userConf}-${type}-${id}-${extra}`)) {
respond(res, myCache.get(`catalog-${userConf}-${type}-${id}-${extra}`));
} else {
metas = await getCatalog(userConf, type, extraObj.genre);
if (metas.length > 0) {
myCache.set(`catalog-${userConf}-${type}-${id}-${extra}`, { metas: metas });
}
respond(res, { metas: metas });
}
} catch (error) {
console.log(error);
respond(res, { metas: [] });
}
});
app.get('/:userConf/meta/:type/:id.json', async function (req, res) {
let { userConf, type, id } = req.params;
try {
if (myCache.has(`meta-${userConf}-${type}-${id}`)) {
respond(res, myCache.get(`meta-${userConf}-${type}-${id}`));
} else {
const meta = await getMeta(userConf, type, id);
if (meta && meta.id) {
myCache.set(`meta-${userConf}-${type}-${id}`, { meta: meta });
}
respond(res, { meta: meta });
}
} catch (error) {
console.log(error);
respond(res, { error });
}
});
app.get('/:userConf/stream/:type/:id.json', async function (req, res) {
let { userConf, type, id } = req.params;
const obj = getUserData(userConf);
if (id.startsWith('tt')) {
// Handle IMDb IDs using the Xtream module
const xtreamModule = createXtreamModule(obj.baseURL, obj.username, obj.password);
try {
const xtreamResponse = await xtreamModule(id);
if (xtreamResponse && xtreamResponse.contentUrl) {
console.log('Stream URL for IMDb ID:', xtreamResponse.contentUrl);
respond(res, { streams: [{ url: xtreamResponse.contentUrl, name: xtreamResponse.title }] });
} else {
console.log('No stream found for IMDb ID:', id);
respond(res, { streams: [] });
}
} catch (error) {
console.error('Xtream module error:', error);
respond(res, { streams: [] });
}
} else {
// Existing logic for non-IMDb IDs
let extension = "mp4";
const streamID = id.split(":")[1];
let stream = [];
if (type === "tv") {
type = "live";
extension = "ts";
const url = `${obj.baseURL}/${type}/${obj.username}/${obj.password}/${streamID}.${extension}`;
console.log('Stream URL for TV:', url);
stream = [{
url: url,
name: "Watch Now",
behaviorHints: {
notWebReady: true
}
}];
} else {
const url = `${obj.baseURL}/${type}/${obj.username}/${obj.password}/${streamID}.${extension}`;
console.log('Stream URL for VOD:', url);
stream = [{
url: url,
name: "Watch Now"
}];
}
respond(res, { streams: stream });
}
});
// Listen for incoming requests
// Listen for incoming requests
if (module.parent) {
module.exports = app;
} else {
// Bind to 0.0.0.0 and use the configured port
app.listen(config.port, '0.0.0.0', function () {
console.log(`Server started: ${config.addon}`);
console.log(`Listening on: ${config.local} (${config.port})`);
});
}