forked from nm3clol/nm3clol-express-app
Updated environment configuration and cleaned up usage of runtime environment.
This commit is contained in:
parent
8a28910b0b
commit
5f4ac46af7
30
.env.example
30
.env.example
|
@ -1,20 +1,27 @@
|
|||
# You will need a .env file to use with the Docker containers. This is set up for localhost use with the Docker Compose fullstack.
|
||||
|
||||
# APP_HTTP_LISTEN_PORT is the TCP port used to access the Node application's HTTP interface (usually by a reverse proxy).
|
||||
APP_HTTP_HOST="nm3clol-express-app"
|
||||
# APP_HTTP_LISTEN_PORT is the TCP port used to access the Node application's HTTP interface (usually by a reverse proxy).
|
||||
APP_HTTP_PORT=3000
|
||||
# APP_URL is the URL used to access the Node application (usually by a reverse proxy).
|
||||
APP_HTTP_URL="http://${APP_HTTP_HOST}:${APP_HTTP_PORT}"
|
||||
|
||||
# SITE_NAME is used for page generation.
|
||||
SITE_NAME="(dev) No Moss 3 Carbo Landfill Online Localhost"
|
||||
# SITE_HOST is used for generating links for the search index. (If you leave this blank it should work using relative paths.)
|
||||
SITE_HOST="localhost"
|
||||
SITE_HOST="${APP_HTTP_HOST}"
|
||||
# SITE_URL is used for generating links for the search index. (If you leave this blank it should work using relative paths.)
|
||||
SITE_URL="https://${SITE_HOST}"
|
||||
# WELCOME_MSG is used for the homepage instead of "Welcome to ${SITE_NAME}!"
|
||||
WELCOME_MSG="Devel' It Up, Developer!"
|
||||
SITE_URL="${APP_HTTP_URL}"
|
||||
# WELCOME_MESSAGE is used for the homepage instead of "Welcome to ${SITE_NAME}!"
|
||||
SITE_WELCOME_MESSAGE="Devel' It Up, Developer!"
|
||||
|
||||
# APP_HTTP_LISTEN_PORT is the TCP port used to access the Node application's HTTP interface (usually by a reverse proxy).
|
||||
APP_HTTP_HOST="nm3clol"
|
||||
# APP_HTTP_LISTEN_PORT is the TCP port used to access the Node application's HTTP interface (usually by a reverse proxy).
|
||||
APP_HTTP_LISTEN_PORT=3000
|
||||
# APP_URL is the URL used to access the Node application (usually by a reverse proxy).
|
||||
APP_HTTP_URL="http://${APP_HTTP_HOST}:${APP_HTTP_LISTEN_PORT}"
|
||||
# PUBLIC_DIR is the relative path to the directory to this project root for the public files
|
||||
PUBLIC_DIR="../nm3clol-public"
|
||||
# PAGES_DIR is the relative path to the directory to this project root for the pages rather than public files
|
||||
PAGES_DIR="pages"
|
||||
# STATIC_DIR is the relative path to the directory to this project root for the static asset files
|
||||
STATIC_DIR="static"
|
||||
|
||||
# SOLR_DOCS_HOST is the host for Apache Solr's core for indexed documents.
|
||||
SOLR_DOCS_HOST="solr"
|
||||
|
@ -40,6 +47,3 @@ TIKA_HOST="tika"
|
|||
TIKA_PORT=9998
|
||||
# TIKA_URL is the URL to access the host running Apache Tika.
|
||||
TIKA_URL="http://${TIKA_HOST}:${TIKA_PORT}"
|
||||
|
||||
# PUBLIC_DIR is the directory relative to this project root for the public files
|
||||
PUBLIC_DIR="../nm3clol-public"
|
||||
|
|
51
app/config.js
Normal file
51
app/config.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
console.log(`Configuring .env and expanding .env to include environment variable references.`);
|
||||
|
||||
const path = require('path');
|
||||
const dotenv = require('dotenv');
|
||||
const dotenvExpand = require('dotenv-expand');
|
||||
|
||||
let env = dotenv.config();
|
||||
dotenvExpand.expand(env);
|
||||
|
||||
const getAppHttpHost = () => env.APP_HTTP_HOST||'nm3clol-express-app';
|
||||
const getAppHttpPort = () => parseInt(env.APP_HTTP_PORT||env.PORT||3000);
|
||||
const getAppHttpUrl = () => {
|
||||
return env.APP_HTTP_URL || `http://${getAppHttpHost() + ((getAppHttpPort() === 80) ? '' : ':' + getAppHttpPort())}`
|
||||
};
|
||||
|
||||
const getSiteName = () => env.SITE_NAME||"(dev) No Moss 3 Carbo Landfill Online Localhost";
|
||||
const getSiteWelcomeMessage = () => env.SITE_WELCOME_MESSAGE||"Devel' It Up, Developer!";
|
||||
const getSiteHost = () => env.SITE_HOST||"localhost";
|
||||
const getSiteUrl = () => env.SITE_URL||getAppHttpUrl();
|
||||
|
||||
const getPublicPath = () => path.join(__dirname, '..', (env.PUBLIC_DIR||path.join('..', 'nm3clol-public')).replaceAll('\\', path.sep).replaceAll('/', path.sep));
|
||||
const getPagesPath = () => path.join(__dirname, '..', (env.PAGES_DIR||'pages').replaceAll('\\', path.sep).replaceAll('/', path.sep));
|
||||
const getStaticPath = () => path.join(__dirname, '..', (env.STATIC_DIR||'static').replaceAll('\\', path.sep).replaceAll('/', path.sep));
|
||||
|
||||
const getSolrDocsHost = () => env.SOLR_DOCS_HOST||'solr';
|
||||
const getSolrDocsPort = () => parseInt(env.SOLR_DOCS_PORT||8983);
|
||||
const getSolrDocsCore = () => env.SOLR_DOCS_CORE||'nm3clol_core';
|
||||
const getSolrLawHost = () => env.SOLR_LAW_HOST||getSolrDocsHost();
|
||||
const getSolrLawPort = () => parseInt(env.SOLR_LAW_PORT||getSolrDocsPort());
|
||||
const getSolrLawCore = () => env.SOLR_LAW_CORE||'vacode_core';
|
||||
|
||||
module.exports = {
|
||||
config: {
|
||||
publicPath: getPublicPath(),
|
||||
pagesPath: getPagesPath(),
|
||||
staticPath: getStaticPath(),
|
||||
siteName: getSiteName(),
|
||||
siteWelcomeMessage: getSiteWelcomeMessage(),
|
||||
siteHost: getSiteHost(),
|
||||
siteUrl: getSiteUrl(),
|
||||
appHttpHost: getAppHttpHost(),
|
||||
appHttpPort: getAppHttpPort(),
|
||||
appHttpUrl: getAppHttpUrl(),
|
||||
solrDocsHost: getSolrDocsHost(),
|
||||
solrDocsPort: getSolrDocsPort(),
|
||||
solrDocsCore: getSolrDocsCore(),
|
||||
solrLawHost: getSolrLawHost(),
|
||||
solrLawPort: getSolrLawPort(),
|
||||
solrLawCore: getSolrLawCore(),
|
||||
}
|
||||
};
|
|
@ -1,9 +1,11 @@
|
|||
console.log(`Loading nm3clol-express-app search router module...`);
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { parse, toString } = require('lucene');
|
||||
const { createClient, Query } = require('solr-client');
|
||||
const solrConfig = { host: process.env.SOLR_DOCS_HOST||'solr', port: process.env.SOLR_DOCS_PORT||8983, core: process.env.SOLR_DOCS_CORE_NAME||'nm3clol_core' };
|
||||
const helpers = require('../views/helpers/functions');
|
||||
const { config } = require('../config');
|
||||
const helpers = require('../../views/helpers/functions');
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
// Extract paging parameters from request query parameters
|
||||
|
@ -37,7 +39,7 @@ router.get('/', (req, res) => {
|
|||
usePhraseHighlighter: true,
|
||||
}});
|
||||
// Create a Solr client
|
||||
const solrClient = createClient({ host: 'solr.services.cleveland.daball.me', port: 8983, core: 'my_core' });
|
||||
const solrClient = createClient({ host: config.solrDocsHost, port: config.solrDocsPort, core: config.solrDocsCore });
|
||||
solrClient.search(solrQuery)
|
||||
.then(solrResponse => {
|
||||
//console.log(require('util').inspect(solrResponse, { showHidden: true, depth: null, colors: true }));
|
|
@ -1,3 +1,5 @@
|
|||
console.log(`Starting up nm3clol-express-app...`);
|
||||
|
||||
const express = require('express');
|
||||
const axios = require('axios');
|
||||
const app = express();
|
||||
|
@ -6,18 +8,13 @@ const path = require('path');
|
|||
const glob = require('glob');
|
||||
const matter = require('gray-matter');
|
||||
const ejs = require('ejs');
|
||||
const { config } = require('./config');
|
||||
const helpers = require('../views/helpers/functions');
|
||||
const search = require('../routes/search');
|
||||
const search = require('./routes/search');
|
||||
const fs = require('fs');
|
||||
const dotenv = require('dotenv');
|
||||
const dotenvExpand = require('dotenv-expand');
|
||||
dotenv.config();
|
||||
dotenvExpand.expand(process.env);
|
||||
// const advancedSearch = require('../routes/advanced-search');
|
||||
const publicPath = path.join(__dirname, '..', process.env.PUBLIC_DIR.replaceAll('\\', path.sep).replaceAll('/', path.sep));
|
||||
|
||||
// Port number for HTTP server
|
||||
const port = process.env.PORT||3000;
|
||||
console.log(`Running app configuration:`, config);
|
||||
|
||||
// Set EJS as the view engine
|
||||
app.set('view engine', 'ejs');
|
||||
|
@ -41,14 +38,14 @@ app.use(express.json());
|
|||
// res.send('Hello World!');
|
||||
// })
|
||||
|
||||
console.log("Setting route for /ads.txt");
|
||||
app.get('/ads.txt', (req, res) => {
|
||||
res.setHeader("Content-Type", "text/plain");
|
||||
res.setHeader("Cache-Control", "no-cache");
|
||||
res.send(`google.com, pub-8937572456576531, DIRECT, f08c47fec0942fa0`);
|
||||
});
|
||||
// console.log("Setting route for /ads.txt");
|
||||
// app.get('/ads.txt', (req, res) => {
|
||||
// res.setHeader("Content-Type", "text/plain");
|
||||
// res.setHeader("Cache-Control", "no-cache");
|
||||
// res.send(`google.com, pub-8937572456576531, DIRECT, f08c47fec0942fa0`);
|
||||
// });
|
||||
|
||||
console.log("Setting route for /robots.txt");
|
||||
console.log(`Serving /robots.txt from memory.`);
|
||||
app.get('/robots.txt', (req, res) => {
|
||||
res.setHeader("Content-Type", "text/plain");
|
||||
res.setHeader("Cache-Control", "no-cache");
|
||||
|
@ -63,25 +60,29 @@ Allow: /
|
|||
});
|
||||
|
||||
// Search endpoints
|
||||
console.log("Setting routes for /search");
|
||||
console.log(`Serving /search using search router.`);
|
||||
app.use('/search', search.router);
|
||||
// app.use('/advanced-search', advancedSearch.router);
|
||||
|
||||
// Endpoints for all the site's pages.
|
||||
console.log("Scanning for pages to create routes");
|
||||
glob.globSync('pages/**/*.md', {
|
||||
cwd: path.join(__dirname, '..'),
|
||||
console.log(`Scanning for pages in ${config.pagesPath} to create routes.`);
|
||||
glob.globSync('**/*.md', {
|
||||
cwd: config.pagesPath,
|
||||
matchBase: true,
|
||||
follow: true,
|
||||
}).forEach((filePath) => {
|
||||
const expressRoutePathFromFilePath = (filePath) => {
|
||||
return filePath.substring('pages'.length, filePath.length - path.extname(filePath).length).replaceAll(path.sep, path.posix.sep);
|
||||
filePath = filePath.substring(0, filePath.length - path.extname(filePath).length).replaceAll(path.sep, path.posix.sep);
|
||||
if (!filePath.startsWith('/') && filePath.length > 0) {
|
||||
filePath = `/${filePath}`;
|
||||
}
|
||||
return filePath;
|
||||
};
|
||||
const route = expressRoutePathFromFilePath(filePath);
|
||||
const fullFilePath = path.join(__dirname, '..', filePath);
|
||||
const fullFilePath = path.join(config.pagesPath, filePath);
|
||||
let paths = route.split(path.posix.sep);
|
||||
paths[0] = 'public';
|
||||
console.log(`Setting route for ${route}`);
|
||||
console.log(`Serving ${route} route as a page at ${fullFilePath}.`);
|
||||
app.get(route, async (req, res) => {
|
||||
const fm = matter.read(fullFilePath);
|
||||
const fmData = { fm: fm.data, excerpt: fm.excerpt };
|
||||
|
@ -91,7 +92,7 @@ glob.globSync('pages/**/*.md', {
|
|||
});
|
||||
});
|
||||
|
||||
// console.log("Scanning for documents to create routes");
|
||||
// console.log("Scanning for documents to create routes.");
|
||||
// glob.globSync('**/*{.pdf,.docx,.xlsx,.pptx,.doc,.xls,.ppt}', {
|
||||
// cwd: path.join(__dirname, '..', 'public'),
|
||||
// matchBase: true,
|
||||
|
@ -114,7 +115,8 @@ glob.globSync('pages/**/*.md', {
|
|||
// });
|
||||
// });
|
||||
|
||||
console.log("Scanning for web archive HTML documents to create routes");
|
||||
//TODO: Rewrite this facility so that it utilizes Git index as a filesystem.
|
||||
console.log("Scanning for web archive HTML documents to create routes.");
|
||||
glob.globSync('Web_Site_Archives/**/*{.htm,.html}', {
|
||||
cwd: path.join(__dirname, '..', 'public'),
|
||||
matchBase: true,
|
||||
|
@ -136,8 +138,8 @@ glob.globSync('Web_Site_Archives/**/*{.htm,.html}', {
|
|||
});
|
||||
|
||||
|
||||
// Endpoints for all the site's YouTube videos.
|
||||
console.log("Scanning for archived videos to create routes");
|
||||
//TODO: Rewrite this facility so that it utilizes Git index as a filesystem.
|
||||
console.log("Scanning for archived videos to create routes.");
|
||||
glob.globSync(['Russell_County/Board_of_Supervisors/YouTube_Archive/**/*.info.json', 'Virginia_Energy/YouTube_Archive/**/*.info.json', 'Virginia_Governor/**/*.info.json'], {
|
||||
cwd: path.join(__dirname, '..', 'public'),
|
||||
matchBase: true,
|
||||
|
@ -187,10 +189,10 @@ glob.globSync(['Russell_County/Board_of_Supervisors/YouTube_Archive/**/*.info.js
|
|||
|
||||
//app.get('/OCR-Encoded-PDFs/Russell-County-Web-Site_2024-02-13_19_50_Modified-With-OCR-Encoding**', rewriter.rewrite('/Web_Site_Archives/Russell_County_Web_Site-2024-02-13_19_50_Modified_With_OCR_Encoding/$1'));
|
||||
|
||||
console.log(`Setting routes for /vendor/**/*`);;
|
||||
console.log(`Serving /vendor/**/* route for all files in ${path.join(config.staticPath, 'vendor')}`);;
|
||||
app.get('/vendor/**/*', async (req, res) => {
|
||||
await serve(req, res, {
|
||||
public: path.join(__dirname, '..', 'static'),
|
||||
public: config.staticPath,
|
||||
symlinks: true,
|
||||
trailingSlash: true,
|
||||
cleanUrls: false,
|
||||
|
@ -204,10 +206,10 @@ app.get('/vendor/**/*', async (req, res) => {
|
|||
});
|
||||
});
|
||||
|
||||
console.log(`Setting routes for /css/*.css`);;
|
||||
console.log(`Serving /css/*.css route for all files in ${path.join(config.staticPath, 'css')}`);;
|
||||
app.get('/css/*.css', async (req, res) => {
|
||||
await serve(req, res, {
|
||||
public: path.join(__dirname, '..', 'static'),
|
||||
public: config.staticPath,
|
||||
symlinks: true,
|
||||
trailingSlash: true,
|
||||
cleanUrls: false,
|
||||
|
@ -221,10 +223,10 @@ app.get('/css/*.css', async (req, res) => {
|
|||
});
|
||||
});
|
||||
|
||||
console.log(`Setting routes for /svg/*.svg`);;
|
||||
console.log(`Serving /svg/*.svg route for all files in ${path.join(config.staticPath, 'svg')}`);;
|
||||
app.get('/svg/*.svg', async (req, res) => {
|
||||
await serve(req, res, {
|
||||
public: path.join(__dirname, '..', 'static'),
|
||||
public: config.staticPath,
|
||||
symlinks: true,
|
||||
trailingSlash: true,
|
||||
cleanUrls: false,
|
||||
|
@ -238,10 +240,11 @@ app.get('/svg/*.svg', async (req, res) => {
|
|||
});
|
||||
});
|
||||
|
||||
console.log(`Setting route for *`);
|
||||
//TODO: Rewrite this facility so that it utilizes Git index as a filesystem.
|
||||
console.log(`Serving * default route for all files in ${config.publicPath}`);;
|
||||
app.get('*', async (req, res) => {
|
||||
await serve(req, res, {
|
||||
public: publicPath,
|
||||
public: config.publicPath,
|
||||
symlinks: true,
|
||||
trailingSlash: true,
|
||||
cleanUrls: false,
|
||||
|
@ -276,6 +279,11 @@ app.get('*', async (req, res) => {
|
|||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, () => {
|
||||
console.log(`no-moss-3-carbo-landfill-library.online app listening on port ${port}`);
|
||||
app.listen(config.appHttpPort, () => {
|
||||
console.log(`nm3clol-express-app HTTP server listening on port ${config.appHttpPort}.`)
|
||||
console.log(`To access your app, you can use the localhost URL, http://localhost:${config.appHttpPort}.`);
|
||||
console.log(`To access your app, you can use the 127.0.0.1 host, http://127.0.0.1:${config.appHttpPort}.`);
|
||||
console.log(`To access your app, you can use the ::1 host, http://[::1]:${config.appHttpPort}.`);
|
||||
console.log(`To access your app, you might can use the app host name, ${config.appHttpUrl}.`);
|
||||
console.log(`This app is configured to use the web site URL, ${config.siteUrl}.`);
|
||||
});
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
<% if (h.shouldShowDirectorySeparator({index})) { %>
|
||||
<span class="separator">› </span>
|
||||
<% } %>
|
||||
<% if (h.shouldShowWelcomeBanner({paths})) { %>
|
||||
<% if (h.shouldShowSiteWelcomeMessage({paths})) { %>
|
||||
<i> </i>
|
||||
<%= h.getWelcomeBanner() %>
|
||||
<%= h.getSiteWelcomeMessage() %>
|
||||
<% } else if (h.shouldOmitLinkOnLastBreadcrumb({paths, index})) { %>
|
||||
<%= h.trimSlashes({path: value.name}).replaceAll('_', ' ') %>
|
||||
<% } else { %>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const path = require('path');
|
||||
const glob = require('glob');
|
||||
const fs = require('fs');
|
||||
const process = require('process');
|
||||
const config = require('../../app/config');
|
||||
const markdownit = require('markdown-it');
|
||||
var markdownItAttrs = require('markdown-it-attrs');
|
||||
const md = markdownit({
|
||||
|
@ -18,9 +18,7 @@ const md = markdownit({
|
|||
);
|
||||
const moment = require('moment-timezone').tz.setDefault("UTC");
|
||||
|
||||
const getSiteName = () => {
|
||||
return process.env.SITE_NAME || '(dev) No Moss 3 Carbo Landfill Online Localhost';
|
||||
}
|
||||
const getSiteName = config.getSiteName;
|
||||
|
||||
const trimSlashes = ({path}) => {
|
||||
return path.replace(/^[\/\\]|[\/\\]$/g, '');
|
||||
|
@ -40,11 +38,9 @@ const getDirectoryTitle = ({directory}) => {
|
|||
.join(' - ');
|
||||
return (directory=="public") ? getSiteName() : `${title} - ${getSiteName()}`;
|
||||
};
|
||||
const getWelcomeBanner = () => {
|
||||
return process.env.WELCOME_MSG || `Welcome to ${getSiteName()}!`;
|
||||
};
|
||||
const getSiteWelcomeMessage = config.getSiteWelcomeMessage;
|
||||
const shouldShowDirectorySeparator = ({index}) => (index > 0);
|
||||
const shouldShowWelcomeBanner = ({paths}) => (paths.length == 1);
|
||||
const shouldShowSiteWelcomeMessage = ({paths}) => (paths.length == 1);
|
||||
const shouldOmitLinkOnLastBreadcrumb = ({paths, index}) => (index == paths.length-1);
|
||||
|
||||
const resolveReadmeFile = ({directory}) => {
|
||||
|
@ -88,7 +84,7 @@ const renderArchive = (html, paths) => {
|
|||
// Header and Footer content
|
||||
const headHeaderContent = ``;
|
||||
const headFooterContent = `
|
||||
<!-- Dynamically Inserted Code by ${process.env.SITE_NAME||'No Moss 3 Carbo Landfill Online Library'} -->
|
||||
<!-- Dynamically Inserted Code by ${getSiteName()} -->
|
||||
<style>
|
||||
.__archived__content__, .__archived__content__ p { background-color: #f44336; color: #fff; font-size: 12pt; font-family: "Noto Serif", Times, "Times New Roman", serif; text-align: center; }
|
||||
.__archived__content__ h1 { font-family: "Cinzel Decorative", Verdana, Arial, sans-serif; color: #fff; font-weight: 700; font-size: 18pt; text-align: center; }
|
||||
|
@ -124,9 +120,9 @@ const renderArchive = (html, paths) => {
|
|||
<!-- End dynamically inserted code -->
|
||||
`;
|
||||
const bodyHeaderContent = `
|
||||
<!-- Dynamically Inserted Code by ${process.env.SITE_NAME||'No Moss 3 Carbo Landfill Online Library'} -->
|
||||
<!-- Dynamically Inserted Code by ${getSiteName()} -->
|
||||
<div class="__archived__content__">
|
||||
<h1>${process.env.SITE_NAME||'No Moss 3 Carbo Landfill Online Library'}</h1>
|
||||
<h1>${getSiteName()}</h1>
|
||||
<h2>Archived Web Site</h2>
|
||||
<p>
|
||||
This is an archived version of the original website. Online features will not be functional. Do not submit any personal information to this archive.
|
||||
|
@ -138,7 +134,7 @@ const renderArchive = (html, paths) => {
|
|||
<!-- End dynamically inserted code -->
|
||||
`;
|
||||
const bodyFooterContent = `
|
||||
<!-- Dynamically Inserted Code by ${process.env.SITE_NAME||'No Moss 3 Carbo Landfill Online Library'} -->
|
||||
<!-- Dynamically Inserted Code by ${getSiteName()} -->
|
||||
<div class="__archived__content__">
|
||||
<p>
|
||||
This is an archived version of the original website. Online features will not be functional. Do not submit any personal information to this archive.
|
||||
|
@ -165,9 +161,9 @@ module.exports = {
|
|||
getSiteName,
|
||||
getDirectoryName,
|
||||
getDirectoryTitle,
|
||||
getWelcomeBanner,
|
||||
getSiteWelcomeMessage,
|
||||
shouldShowDirectorySeparator,
|
||||
shouldShowWelcomeBanner,
|
||||
shouldShowSiteWelcomeMessage,
|
||||
shouldOmitLinkOnLastBreadcrumb,
|
||||
directoryContainsReadme,
|
||||
printReadme,
|
||||
|
|
Loading…
Reference in New Issue
Block a user