Files
trunk-server/frontend/server/index.js
2026-01-22 21:25:16 -05:00

235 lines
8.8 KiB
JavaScript

var ObjectID = require('mongodb').ObjectID;
var db = require('./db');
const express = require("express");
const path = require("path");
const secrets = require("./config/secrets");
const configureExpress = require("./config/express");
const { Podcast, Item, FeedOptions } = require('podcast');
// -------------------------------------------
const app = express()
// -------------------------------------------
// -------------------------------------------
// Connect to Mongo on start
db.connect(function (err) {
if (err) {
console.log('Unable to connect to Mongo.')
process.exit(1)
}
})
// -------------------------------------------
const isDev = process.env.NODE_ENV === "development"
// -------------------------------------------
configureExpress(app)
function getCard(req, res, next) {
var objectId = req.params.id;
try {
var o_id = ObjectID.createFromHexString(objectId);
} catch (err) {
console.warn("Error - /card/:id generating ObjectID " + err);
res.status(500);
res.send(JSON.stringify({
error: err,
"_id": objectId
}));
return;
}
db.get().collection('calls', function (err, transCollection) {
transCollection.findOne({
'_id': o_id
},
function (err, item) {
if (item) {
var time = new Date(item.time);
var timeString = time.toLocaleTimeString('en-US', { timeZone: "America/New_York" });
var dateString = time.toLocaleDateString('en-US', { timeZone: "America/New_York" });
//console.log(item)
res.render('card.ejs', {
item: item,
url: item.url,
time: timeString,
date: dateString
});
} else {
console.warn("Error - /card/:id Could not find Item " + err);
res.send(404, 'Sorry, we cannot find that!');
}
});
});
}
const dateRange = (start, end) => {
if (start.getYear() != end.getYear()) {
return { "part1": start.toLocaleDateString('en-us', { weekday: "short", year: "numeric", month: "short", day: "numeric" }) + " " + start.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }), "part2": end.toLocaleDateString('en-us', { weekday: "short", year: "numeric", month: "short", day: "numeric" }) + " " + end.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }) };
} else if (start.getMonth() != end.getMonth()) {
return { "part1": start.toLocaleDateString('en-us', { weekday: "short", month: "short", day: "numeric" }) + " " + start.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }), "part2": end.toLocaleDateString('en-us', { weekday: "short", month: "short", day: "numeric" }) + " " + end.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }) };
} else if (start.getDay() != end.getDay()) {
return { "part1": start.toLocaleDateString('en-us', { weekday: "short", month: "short", day: "numeric" }) + " " + start.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }), "part2": end.toLocaleDateString('en-us', { weekday: "short", day: "numeric" }) + " " + end.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }) };
} else {
return { "part1": start.toLocaleDateString('en-us', { weekday: "short", month: "short", day: "numeric" }) + " " + start.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }), "part2": end.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }) };
}
}
async function getPodcast(req, res, next) {
const now = new Date();
try {
const podcastsCollection = db.get().collection('podcasts');
podcastsCollection.find().toArray(function (err, podcasts) {
const feed = new Podcast({
title: 'OpenMHz',
description: 'Real public safety radio recordings, from across the country. OpenMHz is a website that makes it easy to share recordings of public safety radio system. This podcast is a collection of interesting events that has been curated by the OpenMHz community.',
feedUrl: 'https://openmhz.com/rss.xml',
siteUrl: 'https://openmhz.com',
imageUrl: 'https://openmhz.com/podcast/cover.png',
author: 'OpenMHz',
copyright: '© 2026 Robotastic',
language: 'en',
pubDate: 'May 20, 2012 04:00:00 GMT',
ttl: 60,
itunesAuthor: 'OpenMHz',
itunesSubtitle: 'I am a sub title',
itunesSummary: 'Real public safety radio recordings, from across the country. OpenMHz is a website that makes it easy to share recordings of public safety radio system. This podcast is a collection of interesting events that has been curated by the OpenMHz community.',
itunesOwner: { name: 'Luke Berndt', email: 'support@openmhz.com' },
itunesExplicit: false,
itunesCategory: [{
text: 'Government'
}, { text: "Daily News" }, { text: "True Crime" }],
itunesImage: 'https://openmhz.com/podcast/cover.png'
});
for (const podcast of podcasts) {
let dates = dateRange(new Date(podcast.startTime), new Date(podcast.endTime))
let description = dates.part1 + " → " + dates.part2 + " \n" + podcast.description + `
Radio Systems:
`;
for (const system of podcast.systems) {
description = description + " - " + system + "\n"
}
feed.addItem({
title: podcast.title,
description: description,
enclosure: {
url: podcast.downloadUrl, // link to the item
},
author: 'OpenMHz', // optional - defaults to feed author property
url: podcast.eventUrl,
date: podcast.startTime, // any format that js Date can parse.
itunesAuthor: 'OpenMHz',
itunesExplicit: false,
itunesSummary: description,
itunesDuration: podcast.len
});
}
const xml = feed.buildXml();
res.set('Content-Type', 'text/xml');
res.send(xml);
});
} catch (err) {
console.error(err);
return;
}
}
async function getCalls(req, res, next) {
if (req.query && req.query["call-id"]) {
var objectId = req.query["call-id"];
try {
var o_id = ObjectID.createFromHexString(objectId);
} catch (err) {
next()
return;
}
try {
db.get().collection('calls', function (err, transCollection) {
transCollection.findOne({
'_id': o_id
},
async function (err, item) {
if (item) {
var time = new Date(item.time);
var timeString = time.toLocaleTimeString('en-US', { timeZone: "America/New_York" });
var dateString = time.toDateString('en-US', { timeZone: "America/New_York" });
//console.log(item)
const tg_coll = db.get().collection('talkgroups');
const tg = await tg_coll.findOne({ "num": item.talkgroupNum, 'shortName': req.params.shortName.toLowerCase() })
var title = item.len + " second transmission"
if (tg) {
//console.log(tg)
title = tg.description;
}
const callId = req.query["call-id"];
const callUrl = "https://s3.us-west-1.wasabisys.com/openmhz-west/media/dcfd-1039-1613917169.m4a"
const twitterMeta = `
<meta name="twitter:card" content="player"/>
<meta name="twitter:site" content="@openmhz"/>
<meta name="twitter:title" content="${title}"/>
<meta name="twitter:description" content="${timeString} ${dateString}" />
<meta name="twitter:image" content="https://openmhz.com/radio-400x400.jpg"/>
<meta name="twitter:player" content="${process.env['REACT_APP_FRONTEND_SERVER']}/cards/${callId}"/>
<meta name="twitter:player:stream" content="${item.url}"/>
<meta name="twitter:player:stream:content_type" content="audio/mp4"/>
<meta name="twitter:player:width" content="425"/>
<meta name="twitter:player:height" content="165"/>`
res.render("index.ejs", { TWITTER_META: twitterMeta })
} else {
console.warn("Error - /card/:id Could not find Item " + err);
res.send(404, 'Sorry, we cannot find that!');
}
});
});
} catch (err) {
console.error(err);
next()
return;
}
} else {
next()
}
}
// -------------------------------------------
app.use(express.static(path.join(__dirname, "public")));
//app.get("/system/:shortName", getCalls)
//app.get("/cards/:id", getCard)
app.get("/rss.xml", getPodcast);
app.get("*", (req, res, next) => {
res.sendFile(__dirname + '/public/index.html');
});
// start listening to incoming requests
app.listen(app.get("port"), app.get("host"), (err) => {
if (err) {
console.err(err.stack)
} else {
console.log(`App listening on port ${app.get("port")} [${process.env.NODE_ENV} mode]`)
}
})