Skip to content

Commit

Permalink
Fix path to template folder
Browse files Browse the repository at this point in the history
  • Loading branch information
brendannee committed Sep 7, 2024
1 parent f806790 commit 0168228
Showing 3 changed files with 54 additions and 38 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed
- Fix path to template folder

## [2.9.2] - 2024-09-06

### Fixed
16 changes: 7 additions & 9 deletions src/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import path from 'node:path';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { readFileSync } from 'node:fs';
import { map } from 'lodash-es';
@@ -10,6 +10,7 @@ import logger from 'morgan';
import untildify from 'untildify';

import { formatTimetableLabel } from '../lib/formatters.js';
import { getPathToViewsFolder } from '../lib/file-utils.js';
import {
setDefaultConfig,
getTimetablePagesForAgency,
@@ -31,7 +32,7 @@ const app = express();
const router: express.Router = express.Router();

const configPath =
(argv.configPath as string) || new URL('../../config.json', import.meta.url);
(argv.configPath as string) || join(process.cwd(), 'config.json');
const selectedConfig = JSON.parse(readFileSync(configPath, 'utf8'));

const config = setDefaultConfig(selectedConfig);
@@ -120,31 +121,28 @@ router.get('/timetables/:timetablePageId', async (request, response, next) => {
}
});

app.set('views', path.join(fileURLToPath(import.meta.url), '../../../views'));
app.set('views', getPathToViewsFolder(config));
app.set('view engine', 'pug');

app.use(logger('dev'));

// Serve static assets
const staticAssetPath =
config.templatePath === undefined
? path.join(fileURLToPath(import.meta.url), '../../../views/default')
? getPathToViewsFolder(config)
: untildify(config.templatePath);

app.use(express.static(staticAssetPath));
app.use(
'/js',
express.static(
path.join(fileURLToPath(import.meta.url), '../../../node_modules/pbf/dist'),
join(dirname(fileURLToPath(import.meta.resolve('pbf'))), 'dist'),
),
);
app.use(
'/js',
express.static(
path.join(
fileURLToPath(import.meta.url),
'../../../node_modules/gtfs-realtime-pbf-js-module',
),
dirname(fileURLToPath(import.meta.resolve('gtfs-realtime-pbf-js-module'))),
),
);

71 changes: 42 additions & 29 deletions src/lib/file-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import path from 'node:path';
import { dirname, join, resolve } from 'node:path';
import { createWriteStream } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { access, cp, copyFile, mkdir, readFile, rm } from 'node:fs/promises';
@@ -29,7 +29,7 @@ export async function getConfig(argv) {
let config;

try {
data = await readFile(path.resolve(untildify(argv.configPath)), 'utf8');
data = await readFile(resolve(untildify(argv.configPath)), 'utf8');
} catch (error) {
throw new Error(
`Cannot find configuration file at \`${argv.configPath}\`. Use config-sample.json as a starting point, pass --configPath option`,
@@ -56,21 +56,41 @@ export async function getConfig(argv) {
}

/*
* Get the full path of the template file for generating timetables based on
* config.
* Get the full path to the views folder.
*/
function getTemplatePath(templateFileName, config) {
let fullTemplateFileName = templateFileName;
if (config.noHead !== true) {
fullTemplateFileName += '_full';
export function getPathToViewsFolder(config) {
if (config.templatePath) {
return untildify(config.templatePath);
}

const templatePath =
config.templatePath === undefined
? path.join(fileURLToPath(import.meta.url), '../../../views/default')
: untildify(config.templatePath);
const __dirname = dirname(fileURLToPath(import.meta.url));

// Dynamically calculate the path to the views directory
let viewsFolderPath;
if (__dirname.endsWith('/dist/bin') || __dirname.endsWith('/dist/app')) {
// When the file is in 'dist/bin' or 'dist/app'
viewsFolderPath = resolve(__dirname, '../../views/default');
} else if (__dirname.endsWith('/dist')) {
// When the file is in 'dist'
viewsFolderPath = resolve(__dirname, '../views/default');
} else {
// In case it's neither, fallback to project root
viewsFolderPath = resolve(__dirname, 'views/default');
}

return path.join(templatePath, `${fullTemplateFileName}.pug`);
return viewsFolderPath;
}

/*
* Get the full path of a template file.
*/
function getPathToTemplateFile(templateFileName: string, config) {
const fullTemplateFileName =
config.noHead !== true
? `${templateFileName}_full.pug`
: `${templateFileName}.pug`;

return join(getPathToViewsFolder(config), fullTemplateFileName);
}

/*
@@ -95,38 +115,31 @@ export async function prepDirectory(exportPath) {
* Copy needed CSS and JS to export path.
*/
export async function copyStaticAssets(config, exportPath) {
const staticAssetPath =
config.templatePath === undefined
? path.join(fileURLToPath(import.meta.url), '../../../views/default')
: untildify(config.templatePath);
const viewsFolderPath = getPathToViewsFolder(config);

const foldersToCopy = ['css', 'js', 'img'];

for (const folder of foldersToCopy) {
if (
await access(path.join(staticAssetPath, folder))
await access(join(viewsFolderPath, folder))
.then(() => true)
.catch(() => false)
) {
await cp(
path.join(staticAssetPath, folder),
path.join(exportPath, folder),
{
recursive: true,
},
);
await cp(join(viewsFolderPath, folder), join(exportPath, folder), {
recursive: true,
});
}
}

// Add libraries needed for GTFS-Realtime if present
if (config.hasGtfsRealtime) {
await copyFile(
'node_modules/pbf/dist/pbf.js',
path.join(exportPath, 'js/pbf.js'),
join(exportPath, 'js/pbf.js'),
);
await copyFile(
'node_modules/gtfs-realtime-pbf-js-module/gtfs-realtime.browser.proto.js',
path.join(exportPath, 'js/gtfs-realtime.browser.proto.js'),
join(exportPath, 'js/gtfs-realtime.browser.proto.js'),
);
}
}
@@ -135,7 +148,7 @@ export async function copyStaticAssets(config, exportPath) {
* Zips the content of the specified folder.
*/
export function zipFolder(exportPath) {
const output = createWriteStream(path.join(exportPath, 'timetables.zip'));
const output = createWriteStream(join(exportPath, 'timetables.zip'));
const archive = archiver('zip');

return new Promise((resolve, reject) => {
@@ -187,7 +200,7 @@ export function generateFolderName(timetablePage) {
* Render the HTML for a timetable based on the config.
*/
export async function renderTemplate(templateFileName, templateVars, config) {
const templatePath = getTemplatePath(templateFileName, config);
const templatePath = getPathToTemplateFile(templateFileName, config);

// Make template functions, lodash and marked available inside pug templates.
const html = await renderFile(templatePath, {

0 comments on commit 0168228

Please sign in to comment.