You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.1 KiB

// venue.js
// Copyright (C) 2022 Digital Telepresence, LLC
// License: Apache-2.0
'use strict';
const https = require('https');
const fetch = require('node-fetch'); // jshint ignore:line
const CACHE_DURATION = 60 * 5;
const { SiteService, SiteError } = require('../../lib/site-lib');
class VenueService extends SiteService {
constructor (dtp) {
super(dtp, module.exports);
this.soapboxDomain = process.env.DTP_SOAPBOX_HOST || 'shing.tv';
}
async start ( ) {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
this.httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
}
channelMiddleware ( ) {
return async (req, res, next) => {
try {
if (!res.locals.site || !res.locals.site.shingChannelSlug) {
return next();
}
res.locals.shingChannelFeed = await this.getChannelFeed(res.locals.site.shingChannelSlug, { allowCache: true });
res.locals.shingChannelStatus = await this.getChannelStatus(res.locals.site.shingChannelSlug, { allowCache: true });
this.log.debug('channel status', { status: res.locals.shingChannelStatus });
return next();
} catch (error) {
this.log.error('failed to populate Soapbox channel feed', { error });
return next();
}
};
}
async getChannelFeed (channelSlug, options) {
const { cache: cacheService } = this.dtp.services;
const cacheKey = `venue:ch:${channelSlug}`;
options = Object.assign({ allowCache: true }, options);
let json;
if (options.allowCache) {
json = await cacheService.getObject(cacheKey);
if (json) { return json; }
}
const requestUrl = `https://${this.soapboxDomain}/channel/${channelSlug}/feed/json`;
this.log.info('fetching Shing channel feed', { channelSlug, requestUrl });
const response = await fetch(requestUrl, {
agent: this.httpsAgent,
});
if (!response.ok) {
throw new SiteError(500, `Failed to fetch Shing channel feed: ${response.statusText}`);
}
json = await response.json();
await cacheService.setObjectEx(cacheKey, CACHE_DURATION, json);
return json;
}
async getChannelStatus (channelSlug, options) {
const { cache: cacheService } = this.dtp.services;
const cacheKey = `venue:ch:${channelSlug}:status`;
options = Object.assign({ allowCache: true }, options);
let json;
if (options.allowCache) {
json = await cacheService.getObject(cacheKey);
if (json) { return json; }
}
const requestUrl = `https://${this.soapboxDomain}/channel/${channelSlug}/status`;
this.log.info('fetching Shing channel status', { channelSlug, requestUrl });
const response = await fetch(requestUrl, {
agent: this.httpsAgent,
});
if (!response.ok) {
throw new SiteError(500, 'Failed to fetch Shing channel status');
}
json = await response.json();
const { channel } = json;
await cacheService.setObjectEx(cacheKey, 30, channel);
return channel;
}
}
module.exports = {
slug: 'venue',
name: 'venue',
create: (dtp) => { return new VenueService(dtp); },
};