Tweaks to caches
This commit is contained in:
parent
c97ff8f24e
commit
0fc689bc3e
18
index.js
18
index.js
@ -10,14 +10,15 @@ const api = require('./src/api')
|
||||
const dbMigration = require('./src/database-migration');
|
||||
const video = require('./src/video')
|
||||
const HDHR = require('./src/hdhr')
|
||||
const CacheImageService = require('./src/cache-image-service');
|
||||
const SettingsService = require('./src/services/settings-service');
|
||||
const FileCacheService = require('./src/services/file-cache-service');
|
||||
const CacheImageService = require('./src/services/cache-image-service');
|
||||
|
||||
const xmltv = require('./src/xmltv')
|
||||
const Plex = require('./src/plex');
|
||||
const channelCache = require('./src/channel-cache');
|
||||
const constants = require('./src/constants')
|
||||
const ChannelDB = require("./src/dao/channel-db");
|
||||
const M3uService = require("./src/services/m3u-service");
|
||||
const FillerDB = require("./src/dao/filler-db");
|
||||
const TVGuideService = require("./src/tv-guide-service");
|
||||
const onShutdown = require("node-graceful-shutdown").onShutdown;
|
||||
@ -72,10 +73,14 @@ fillerDB = new FillerDB( path.join(process.env.DATABASE, 'filler') , channelDB,
|
||||
|
||||
db.connect(process.env.DATABASE, ['channels', 'plex-servers', 'ffmpeg-settings', 'plex-settings', 'xmltv-settings', 'hdhr-settings', 'db-version', 'client-id', 'cache-images', 'settings'])
|
||||
|
||||
fileCache = new FileCacheService( path.join(process.env.DATABASE, 'cache') );
|
||||
cacheImageService = new CacheImageService(db, fileCache);
|
||||
m3uService = new M3uService(channelDB, fileCache, channelCache)
|
||||
|
||||
initDB(db, channelDB)
|
||||
|
||||
|
||||
const guideService = new TVGuideService(xmltv, db);
|
||||
const guideService = new TVGuideService(xmltv, db, cacheImageService);
|
||||
|
||||
|
||||
|
||||
@ -185,16 +190,15 @@ app.get('/version.js', (req, res) => {
|
||||
app.use('/images', express.static(path.join(process.env.DATABASE, 'images')))
|
||||
app.use(express.static(path.join(__dirname, 'web/public')))
|
||||
app.use('/images', express.static(path.join(process.env.DATABASE, 'images')))
|
||||
app.use('/cache/images', CacheImageService.routerInterceptor())
|
||||
app.use('/cache/images', cacheImageService.routerInterceptor())
|
||||
app.use('/cache/images', express.static(path.join(process.env.DATABASE, 'cache/images')))
|
||||
app.use('/favicon.svg', express.static(
|
||||
path.join(__dirname, 'resources/favicon.svg')
|
||||
) );
|
||||
|
||||
// API Routers
|
||||
app.use(api.router(db, channelDB, fillerDB, xmltvInterval, guideService ))
|
||||
app.use('/api/cache/images', CacheImageService.apiRouters())
|
||||
app.use('/api/settings/cache', SettingsService.apiRouters())
|
||||
app.use(api.router(db, channelDB, fillerDB, xmltvInterval, guideService, m3uService ))
|
||||
app.use('/api/cache/images', cacheImageService.apiRouters())
|
||||
|
||||
app.use(video.router( channelDB, fillerDB, db))
|
||||
app.use(hdhr.router)
|
||||
|
||||
24
src/api.js
24
src/api.js
@ -10,11 +10,10 @@ const PlexServerDB = require('./dao/plex-server-db');
|
||||
const Plex = require("./plex.js");
|
||||
const FillerDB = require('./dao/filler-db');
|
||||
const timeSlotsService = require('./services/time-slots-service');
|
||||
const M3uService = require('./services/m3u-service');
|
||||
|
||||
module.exports = { router: api }
|
||||
function api(db, channelDB, fillerDB, xmltvInterval, guideService ) {
|
||||
const m3uService = new M3uService(channelDB);
|
||||
function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService ) {
|
||||
const m3uService = _m3uService;
|
||||
const router = express.Router()
|
||||
const plexServerDB = new PlexServerDB(channelDB, channelCache, db);
|
||||
|
||||
@ -452,6 +451,7 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService ) {
|
||||
_id: req.body._id,
|
||||
cache: req.body.cache,
|
||||
refresh: req.body.refresh,
|
||||
enableImageCache: (req.body.enableImageCache === true),
|
||||
file: xmltv.file,
|
||||
}
|
||||
);
|
||||
@ -612,24 +612,6 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService ) {
|
||||
|
||||
})
|
||||
|
||||
// hls.m3u Download is not really working correctly right now
|
||||
router.get('/api/hls.m3u', async (req, res) => {
|
||||
try {
|
||||
res.type('text');
|
||||
|
||||
const host = `${req.protocol}://${req.get('host')}`;
|
||||
const data = await m3uService.getChannelList(host, 'hls');
|
||||
|
||||
res.send(data);
|
||||
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
function updateXmltv() {
|
||||
xmltvInterval.updateXML()
|
||||
|
||||
@ -4,6 +4,7 @@ let cache = {};
|
||||
let programPlayTimeCache = {};
|
||||
let fillerPlayTimeCache = {};
|
||||
let configCache = {};
|
||||
let numbers = null;
|
||||
|
||||
async function getChannelConfig(channelDB, channelId) {
|
||||
//with lazy-loading
|
||||
@ -21,6 +22,22 @@ async function getChannelConfig(channelDB, channelId) {
|
||||
return configCache[channelId];
|
||||
}
|
||||
|
||||
async function getAllNumbers(channelDB) {
|
||||
if (numbers === null) {
|
||||
let n = channelDB.getAllChannelNumbers();
|
||||
numbers = n;
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
async function getAllChannels(channelDB) {
|
||||
let channelNumbers = await getAllNumbers(channelDB);
|
||||
return await Promise.all( channelNumbers.map( async (x) => {
|
||||
return (await getChannelConfig(channelDB, x))[0];
|
||||
}) );
|
||||
}
|
||||
|
||||
|
||||
function saveChannelConfig(number, channel ) {
|
||||
configCache[number] = [channel];
|
||||
}
|
||||
@ -127,6 +144,7 @@ function clear() {
|
||||
//it's not necessary to clear the playback cache and it may be undesirable
|
||||
configCache = {};
|
||||
cache = {};
|
||||
numbers = null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@ -134,6 +152,7 @@ module.exports = {
|
||||
recordPlayback: recordPlayback,
|
||||
clear: clear,
|
||||
getProgramLastPlayTime: getProgramLastPlayTime,
|
||||
getAllChannels: getAllChannels,
|
||||
getChannelConfig: getChannelConfig,
|
||||
saveChannelConfig: saveChannelConfig,
|
||||
getFillerLastPlayTime: getFillerLastPlayTime,
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
module.exports = {
|
||||
DATABASE: process.env.DATABASE || './.dizquetv',
|
||||
PORT: process.env.PORT || 8000,
|
||||
};
|
||||
@ -20,7 +20,7 @@
|
||||
const path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
const TARGET_VERSION = 800;
|
||||
const TARGET_VERSION = 801;
|
||||
|
||||
const STEPS = [
|
||||
// [v, v2, x] : if the current version is v, call x(db), and version becomes v2
|
||||
@ -40,6 +40,7 @@ const STEPS = [
|
||||
// the addDeinterlaceFilter step. This 702 step no longer exists as a target
|
||||
// but we have to migrate it to 800 using the reAddIcon.
|
||||
[ 702, 800, (db,channels,dir) => reAddIcon(dir) ],
|
||||
[ 800, 801, (db) => addImageCache(db) ],
|
||||
]
|
||||
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
@ -803,6 +804,14 @@ function addDeinterlaceFilter(db) {
|
||||
fs.writeFileSync( f, JSON.stringify( [ffmpegSettings] ) );
|
||||
}
|
||||
|
||||
function addImageCache(db) {
|
||||
let xmltvSettings = db['xmltv-settings'].find()[0];
|
||||
let f = path.join(process.env.DATABASE, 'xmltv-settings.json');
|
||||
xmltvSettings.enableImageCache = false;
|
||||
fs.writeFileSync( f, JSON.stringify( [xmltvSettings] ) );
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
initDB: initDB,
|
||||
defaultFFMPEG: ffmpeg,
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
const fs = require('fs');
|
||||
const express = require('express');
|
||||
const request = require('request');
|
||||
const diskDb = require('diskdb');
|
||||
|
||||
const config = require('./config');
|
||||
const CacheService = require('./cache-service');
|
||||
const SettingsService = require('./services/settings-service');
|
||||
|
||||
/**
|
||||
* Manager a cache in disk for external images.
|
||||
@ -13,13 +8,10 @@ const SettingsService = require('./services/settings-service');
|
||||
* @class CacheImageService
|
||||
*/
|
||||
class CacheImageService {
|
||||
constructor() {
|
||||
this.cacheService = CacheService;
|
||||
constructor( db, fileCacheService ) {
|
||||
this.cacheService = fileCacheService;
|
||||
this.imageCacheFolder = 'images';
|
||||
const connection = diskDb.connect(config.DATABASE, ['cache-images']);
|
||||
this.db = connection['cache-images'];
|
||||
|
||||
SettingsService.saveSetting('enabled-cache-image', 'Enable Cache Image', false);
|
||||
this.db = db['cache-images'];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -161,4 +153,4 @@ class CacheImageService {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new CacheImageService();
|
||||
module.exports = CacheImageService;
|
||||
@ -1,15 +1,14 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const config = require('./config');
|
||||
|
||||
/**
|
||||
* A File Cache controller for store and retrieve files from disk
|
||||
* Store files in cache
|
||||
*
|
||||
* @class CacheService
|
||||
* @class FileCacheService
|
||||
*/
|
||||
class CacheService {
|
||||
constructor() {
|
||||
this.cachePath = path.join(config.DATABASE, 'cache');
|
||||
class FileCacheService {
|
||||
constructor(cachePath) {
|
||||
this.cachePath = cachePath;
|
||||
this.cache = {};
|
||||
}
|
||||
|
||||
@ -76,7 +75,11 @@ class CacheService {
|
||||
deleteCache(fullFilePath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
fs.unlinkSync(path.join(this.cachePath, fullFilePath), (err) => {
|
||||
let thePath = path.join(this.cachePath, fullFilePath);
|
||||
if (! fs.existsSync(thePath)) {
|
||||
return resolve(true);
|
||||
}
|
||||
fs.unlinkSync(thePath, (err) => {
|
||||
if(err) {
|
||||
throw Error("Can't save file: ", err);
|
||||
} else {
|
||||
@ -91,4 +94,4 @@ class CacheService {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new CacheService();
|
||||
module.exports = FileCacheService;
|
||||
@ -1,16 +1,14 @@
|
||||
const CacheService = require('../cache-service');
|
||||
const SettingsService = require('./settings-service');
|
||||
|
||||
/**
|
||||
* Manager and Generate M3U content
|
||||
*
|
||||
* @class M3uService
|
||||
*/
|
||||
class M3uService {
|
||||
constructor(dataBase) {
|
||||
constructor(dataBase, fileCacheService, channelCache) {
|
||||
this.dataBase = dataBase;
|
||||
this.cacheService = CacheService;
|
||||
SettingsService.saveSetting('enabled-cache-m3u', 'Enable Cache M3U', false);
|
||||
this.cacheService = fileCacheService;
|
||||
this.channelCache = channelCache;
|
||||
this.cacheReady = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -20,12 +18,8 @@ class M3uService {
|
||||
* @returns {promise} Return a Promise with HLS or M3U file content
|
||||
* @memberof M3uService
|
||||
*/
|
||||
getChannelList(host, type = 'm3u') {
|
||||
if(type === 'hls') {
|
||||
return this.buildHLSList(host);
|
||||
} else {
|
||||
return this.buildM3uList(host);
|
||||
}
|
||||
getChannelList(host) {
|
||||
return this.buildM3uList(host);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,105 +30,46 @@ class M3uService {
|
||||
* @memberof M3uService
|
||||
*/
|
||||
|
||||
buildM3uList(host) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
try {
|
||||
|
||||
const cache = SettingsService.getSetting('enabled-cache-m3u').value;
|
||||
|
||||
if(cache) {
|
||||
const cacheChannels = await this.cacheService.getCache('channels.m3u');
|
||||
if(cacheChannels) {
|
||||
resolve(this.replaceHostOnM3u(host, cacheChannels));
|
||||
}
|
||||
}
|
||||
|
||||
let channels = await this.dataBase.getAllChannels();
|
||||
|
||||
channels.sort((a, b) => {
|
||||
return a.number < b.number ? -1 : 1
|
||||
});
|
||||
|
||||
const tvg = `{{host}}/api/xmltv.xml`;
|
||||
|
||||
let data = `#EXTM3U url-tvg="${tvg}" x-tvg-url="${tvg}"\n`;
|
||||
|
||||
for (var i = 0; i < channels.length; i++) {
|
||||
if (channels[i].stealth!==true) {
|
||||
data += `#EXTINF:0 tvg-id="${channels[i].number}" CUID="${channels[i].number}" tvg-chno="${channels[i].number}" tvg-name="${channels[i].name}" tvg-logo="${channels[i].icon}" group-title="dizqueTV",${channels[i].name}\n`
|
||||
data += `{{host}}/video?channel=${channels[i].number}\n`
|
||||
}
|
||||
}
|
||||
if (channels.length === 0) {
|
||||
data += `#EXTINF:0 tvg-id="1" tvg-chno="1" tvg-name="dizqueTV" tvg-logo="{{host}}/resources/dizquetv.png" group-title="dizqueTV",dizqueTV\n`
|
||||
data += `{{host}}/setup\n`
|
||||
}
|
||||
|
||||
if(cache) {
|
||||
await this.cacheService.setCache('channels.m3u', data);
|
||||
}
|
||||
|
||||
resolve(this.replaceHostOnM3u(host, data));
|
||||
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
async buildM3uList(host) {
|
||||
if (this.cacheReady) {
|
||||
const cachedM3U = await this.cacheService.getCache('channels.m3u');
|
||||
if (cachedM3U) {
|
||||
return this.replaceHostOnM3u(host, cachedM3U);
|
||||
}
|
||||
}
|
||||
let channels = await this.channelCache.getAllChannels(this.dataBase);
|
||||
|
||||
|
||||
channels.sort((a, b) => {
|
||||
return a.number < b.number ? -1 : 1
|
||||
});
|
||||
|
||||
const tvg = `{{host}}/api/xmltv.xml`;
|
||||
|
||||
let data = `#EXTM3U url-tvg="${tvg}" x-tvg-url="${tvg}"\n`;
|
||||
|
||||
for (var i = 0; i < channels.length; i++) {
|
||||
if (channels[i].stealth !== true) {
|
||||
data += `#EXTINF:0 tvg-id="${channels[i].number}" CUID="${channels[i].number}" tvg-chno="${channels[i].number}" tvg-name="${channels[i].name}" tvg-logo="${channels[i].icon}" group-title="dizqueTV",${channels[i].name}\n`
|
||||
data += `{{host}}/video?channel=${channels[i].number}\n`
|
||||
}
|
||||
}
|
||||
if (channels.length === 0) {
|
||||
data += `#EXTINF:0 tvg-id="1" tvg-chno="1" tvg-name="dizqueTV" tvg-logo="{{host}}/resources/dizquetv.png" group-title="dizqueTV",dizqueTV\n`
|
||||
data += `{{host}}/setup\n`
|
||||
}
|
||||
let saveCacheThread = async() => {
|
||||
try {
|
||||
await this.cacheService.setCache('channels.m3u', data);
|
||||
this.cacheReady = true;
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
};
|
||||
saveCacheThread();
|
||||
return this.replaceHostOnM3u(host, data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* "hls.m3u Download is not really working correctly right now"
|
||||
*
|
||||
* @param {boolean} [cache=true]
|
||||
* @param {*} host
|
||||
* @returns {promise} M3U file content
|
||||
* @memberof M3uService
|
||||
*/
|
||||
buildHLSList(host, cache = true) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
try {
|
||||
|
||||
const cacheChannels = await this.cacheService.getCache('channels-hls.m3u');
|
||||
|
||||
if(cache && cacheChannels) {
|
||||
resolve(this.replaceHostOnM3u(host, cacheChannels));
|
||||
}
|
||||
|
||||
let channels = await this.dataBase.getAllChannels();
|
||||
|
||||
channels.sort((a, b) => {
|
||||
return a.number < b.number ? -1 : 1
|
||||
});
|
||||
|
||||
const tvg = `{{host}}/api/xmltv.xml`;
|
||||
|
||||
let data = "#EXTM3U\n"
|
||||
for (var i = 0; i < channels.length; i++) {
|
||||
data += `#EXTINF:0 tvg-id="${channels[i].number}" tvg-chno="${channels[i].number}" tvg-name="${channels[i].name}" tvg-logo="${channels[i].icon}" group-title="dizqueTV",${channels[i].name}\n`
|
||||
data += `{{host}}/m3u8?channel=${channels[i].number}\n`
|
||||
}
|
||||
if (channels.length === 0) {
|
||||
data += `#EXTINF:0 tvg-id="1" tvg-chno="1" tvg-name="dizqueTV" tvg-logo="{{host}}/resources/dizquetv.png" group-title="dizqueTV",dizqueTV\n`
|
||||
data += `{{host}}/setup\n`
|
||||
}
|
||||
|
||||
if(cache) {
|
||||
await this.cacheService.setCache('channels-hls.m3u', data);
|
||||
}
|
||||
|
||||
resolve(this.replaceHostOnM3u(host, data));
|
||||
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace {{host}} string with a URL on file contents.
|
||||
*
|
||||
@ -153,8 +88,7 @@ class M3uService {
|
||||
* @memberof M3uService
|
||||
*/
|
||||
async clearCache() {
|
||||
await this.cacheService.deleteCache('channels.m3u');
|
||||
await this.cacheService.deleteCache('channels-hls.m3u');
|
||||
this.cacheReady = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
const diskDb = require('diskdb');
|
||||
const express = require('express');
|
||||
const config = require('../config');
|
||||
|
||||
class SettingsService {
|
||||
constructor() {
|
||||
const connection = diskDb.connect(config.DATABASE, ['settings']);
|
||||
this.db = connection['settings'];
|
||||
}
|
||||
|
||||
apiRouters() {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const settings = await this.getAllSettings();
|
||||
res.send(settings);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send("error");
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', async (req, res) => {
|
||||
try {
|
||||
const {key, title, value} = req.body;
|
||||
if(!key || !title || value === undefined) {
|
||||
throw Error("Key, title and value are Required");
|
||||
}
|
||||
|
||||
const settings = await this.saveSetting(key, title, value);
|
||||
res.send(settings);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send("error");
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:key', async (req, res) => {
|
||||
try {
|
||||
const key = req.params.key;
|
||||
const {value} = req.body;
|
||||
console.log(key, value);
|
||||
if(!key || value === undefined) {
|
||||
throw Error("Key and value are Required");
|
||||
}
|
||||
const settings = await this.updateSetting(key, value);
|
||||
console.log(settings);
|
||||
res.send(settings);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send("error");
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
getSetting(key) {
|
||||
return new Promise((resolve, reject) =>{
|
||||
try {
|
||||
const setting = this.db.find({key})[0];
|
||||
resolve(setting);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getAllSettings() {
|
||||
return new Promise((resolve, reject) =>{
|
||||
try {
|
||||
const settings = this.db.find();
|
||||
resolve(settings);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
saveSetting(key, title, value) {
|
||||
return new Promise((resolve, reject) =>{
|
||||
try {
|
||||
const setting = this.db.find({key})[0];
|
||||
if(!setting) {
|
||||
this.db.save({key, title, value});
|
||||
}
|
||||
resolve(true);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
updateSetting(key, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const setting = this.db.find({key})[0];
|
||||
if(setting) {
|
||||
const query = this.db.update({_id: setting._id}, {key, value});
|
||||
if(query.updated > 0) {
|
||||
const settings = this.db.find();
|
||||
resolve(settings);
|
||||
}
|
||||
reject();
|
||||
} else {
|
||||
reject({error: true, msg: "Setting not found!"});
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new SettingsService();
|
||||
@ -7,7 +7,7 @@ class TVGuideService
|
||||
/****
|
||||
*
|
||||
**/
|
||||
constructor(xmltv, db) {
|
||||
constructor(xmltv, db, cacheImageService) {
|
||||
this.cached = null;
|
||||
this.lastUpdate = 0;
|
||||
this.updateTime = 0;
|
||||
@ -18,6 +18,7 @@ class TVGuideService
|
||||
this.doThrottle = false;
|
||||
this.xmltv = xmltv;
|
||||
this.db = db;
|
||||
this.cacheImageService = cacheImageService;
|
||||
}
|
||||
|
||||
async get() {
|
||||
@ -351,7 +352,7 @@ class TVGuideService
|
||||
|
||||
async refreshXML() {
|
||||
let xmltvSettings = this.db['xmltv-settings'].find()[0];
|
||||
await this.xmltv.WriteXMLTV(this.cached, xmltvSettings, async() => await this._throttle(), this.db);
|
||||
await this.xmltv.WriteXMLTV(this.cached, xmltvSettings, async() => await this._throttle(), this.cacheImageService);
|
||||
}
|
||||
|
||||
async getStatus() {
|
||||
|
||||
32
src/xmltv.js
32
src/xmltv.js
@ -1,14 +1,12 @@
|
||||
const XMLWriter = require('xml-writer')
|
||||
const fs = require('fs')
|
||||
const CacheImageService = require('./cache-image-service');
|
||||
const SettingsService = require('./services/settings-service');
|
||||
|
||||
module.exports = { WriteXMLTV: WriteXMLTV, shutdown: shutdown }
|
||||
|
||||
let isShutdown = false;
|
||||
let isWorking = false;
|
||||
|
||||
async function WriteXMLTV(json, xmlSettings, throttle) {
|
||||
async function WriteXMLTV(json, xmlSettings, throttle, cacheImageService) {
|
||||
if (isShutdown) {
|
||||
return;
|
||||
}
|
||||
@ -18,14 +16,14 @@ async function WriteXMLTV(json, xmlSettings, throttle) {
|
||||
}
|
||||
isWorking = true;
|
||||
try {
|
||||
await writePromise(json, xmlSettings, throttle);
|
||||
await writePromise(json, xmlSettings, throttle, cacheImageService);
|
||||
} catch (err) {
|
||||
console.error("Error writing xmltv", err);
|
||||
}
|
||||
isWorking = false;
|
||||
}
|
||||
|
||||
function writePromise(json, xmlSettings, throttle) {
|
||||
function writePromise(json, xmlSettings, throttle, cacheImageService) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let ws = fs.createWriteStream(xmlSettings.file)
|
||||
let xw = new XMLWriter(true, (str, enc) => ws.write(str, enc))
|
||||
@ -39,7 +37,7 @@ function writePromise(json, xmlSettings, throttle) {
|
||||
_writeChannels( xw, channels );
|
||||
for (let i = 0; i < channelNumbers.length; i++) {
|
||||
let number = channelNumbers[i];
|
||||
await _writePrograms(xw, json[number].channel, json[number].programs, throttle);
|
||||
await _writePrograms(xw, json[number].channel, json[number].programs, throttle, xmlSettings, cacheImageService);
|
||||
}
|
||||
}
|
||||
middle().then( () => {
|
||||
@ -77,16 +75,16 @@ function _writeChannels(xw, channels) {
|
||||
}
|
||||
}
|
||||
|
||||
async function _writePrograms(xw, channel, programs, throttle) {
|
||||
async function _writePrograms(xw, channel, programs, throttle, xmlSettings, cacheImageService) {
|
||||
for (let i = 0; i < programs.length; i++) {
|
||||
if (! isShutdown) {
|
||||
await throttle();
|
||||
}
|
||||
await _writeProgramme(channel, programs[i], xw);
|
||||
await _writeProgramme(channel, programs[i], xw, xmlSettings, cacheImageService);
|
||||
}
|
||||
}
|
||||
|
||||
async function _writeProgramme(channel, program, xw) {
|
||||
async function _writeProgramme(channel, program, xw, xmlSettings, cacheImageService) {
|
||||
// Programme
|
||||
xw.startElement('programme')
|
||||
xw.writeAttribute('start', _createXMLTVDate(program.start))
|
||||
@ -113,16 +111,14 @@ async function _writeProgramme(channel, program, xw) {
|
||||
}
|
||||
// Icon
|
||||
if (typeof program.icon !== 'undefined') {
|
||||
xw.startElement('icon')
|
||||
|
||||
if(await SettingsService.getSetting('enabled-cache-image')){
|
||||
const imgUrl = CacheImageService.registerImageOnDatabase(program.icon);
|
||||
xw.writeAttribute('src', `{{host}}/cache/images/${imgUrl}`)
|
||||
} else {
|
||||
xw.writeAttribute('src', program.icon)
|
||||
xw.startElement('icon');
|
||||
let icon = program.icon;
|
||||
if (xmlSettings.enableImageCache === true) {
|
||||
const imgUrl = cacheImageService.registerImageOnDatabase(icon);
|
||||
icon = `{{host}}/cache/images/${imgUrl}`;
|
||||
}
|
||||
|
||||
xw.endElement()
|
||||
xw.writeAttribute('src', icon);
|
||||
xw.endElement();
|
||||
}
|
||||
// Desc
|
||||
xw.startElement('desc')
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<label>EPG Cache (hours)</label>
|
||||
<label>EPG Hours</label>
|
||||
<input type="number" class="form-control form-control-sm" ng-model="settings.cache" aria-describedby="cachehelp"/>
|
||||
<small id="cachehelp" class="form-text text-muted">How many hours of programming to include in the xmltv file.</small>
|
||||
</div>
|
||||
@ -24,5 +24,13 @@
|
||||
<small id="timerhelp" class="form-text text-muted">How often should the xmltv file be updated.</small>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="imageCache" aria-describedby="imageCacheHelp" ng-model='settings.enableImageCache'>
|
||||
<label class="form-check-label" for="stealth">Image Cache</label>
|
||||
|
||||
<div class='text-muted' id="imageCacheHelp">If enabled the pictures used for Movie and TV Show posters will be cached in dizqueTV's .dizqueTV folder and will be delivered by dizqueTV's server instead of requiring calls to Plex. Note that using fixed xmltv location in Plex (as opposed to url) will not work correctly in this case.</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user