diff --git a/app/config.mts b/app/config.mts index 3ab4eedd..9ff45f88 100644 --- a/app/config.mts +++ b/app/config.mts @@ -2,188 +2,186 @@ * The `ProcessEnv` interface represents the imported environment variables to input from `process.env` dictionary. */ export interface ProcessEnv { - /** - * `APP_HTTP_LISTEN_HOST` is the host for the HTTP web app. - */ - APP_HTTP_HOST?: string; - /** - * `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?: string; - /** - * `APP_URL` is the URL used to access the Node application (usually by a reverse proxy). - */ - APP_HTTP_URL?: string; - /** - * `SITE_NAME` is used for page generation. - */ - SITE_NAME?: string; - /** - * `SITE_HOST` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) - */ - SITE_WELCOME_MESSAGE?: string; - /** - * `SITE_URL` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) - */ - SITE_HOST?: string; - /** - * `WELCOME_MESSAGE` is used for the homepage instead of `"Welcome to ${SITE_NAME}!"` - */ - SITE_URL?: string; - /** - * `PUBLIC_PATH` is the relative path to the directory to this project root for the public files. - */ - PUBLIC_PATH?: string; - /** - * `PAGES_PATH` is the relative path to the directory to this project root for the pages rather than public files. - */ - PAGES_PATH?: string; - /** - * `ASSETS_PATH` is the relative path to the directory to this project root for the static asset files. - */ - ASSETS_PATH?: string; - /** - * `SOLR_DOCS_HOST` is the host for Apache Solr's core for indexed documents. - */ - SOLR_DOCS_HOST?: string; - /** - * `SOLR_DOCS_PORT` is the port for Apache Solr's core for indexed documents. - */ - SOLR_DOCS_PORT?: string; - /** - * `SOLR_DOCS_CORE` is the core name for Apache Solr's core for indexed documents. - */ - SOLR_DOCS_CORE?: string; - /** - * `SOLR_DOCS_URL` is the URL to access Apache Solr's core for indexed documents. It is used by Gulp and the Search feature. - */ - SOLR_DOCS_URL?: string; - /** - * `SOLR_LAW_HOST` is the host for Apache Solr's core for indexed laws. - */ - SOLR_LAW_HOST?: string; - /** - * `SOLR_LAW_PORT` is the port for Apache Solr's core for indexed laws. - */ - SOLR_LAW_PORT?: string; - /** - * `SOLR_LAW_CORE` is the core name for Apache Solr's core for indexed laws. - */ - SOLR_LAW_CORE?: string; - /** - * `SOLR_LAW_URL` is the URL to access Apache Solr's core for indexed laws. It is used by Gulp and the Search feature. - */ - SOLR_LAW_URL?: string; - /** - * `TIKA_HOST` is the host to access the Apache Tika app. - */ - TIKA_HOST?: string; - /** - * `TIKA_PORT` is the port to access the Apache Tika app. - */ - TIKA_PORT?: string; - /** - * `TIKA_URL` is the URL to access the Apache Tika app. - */ - TIKA_URL?: string; + /** + * `APP_HTTP_LISTEN_HOST` is the host for the HTTP web app. + */ + APP_HTTP_HOST?: string; + /** + * `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?: string; + /** + * `APP_URL` is the URL used to access the Node application (usually by a reverse proxy). + */ + APP_HTTP_URL?: string; + /** + * `SITE_NAME` is used for page generation. + */ + SITE_NAME?: string; + /** + * `SITE_HOST` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) + */ + SITE_WELCOME_MESSAGE?: string; + /** + * `SITE_URL` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) + */ + SITE_HOST?: string; + /** + * `WELCOME_MESSAGE` is used for the homepage instead of `"Welcome to ${SITE_NAME}!"` + */ + SITE_URL?: string; + /** + * `PUBLIC_PATH` is the relative path to the directory to this project root for the public files. + */ + PUBLIC_PATH?: string; + /** + * `PAGES_PATH` is the relative path to the directory to this project root for the pages rather than public files. + */ + PAGES_PATH?: string; + /** + * `ASSETS_PATH` is the relative path to the directory to this project root for the static asset files. + */ + ASSETS_PATH?: string; + /** + * `SOLR_DOCS_HOST` is the host for Apache Solr's core for indexed documents. + */ + SOLR_DOCS_HOST?: string; + /** + * `SOLR_DOCS_PORT` is the port for Apache Solr's core for indexed documents. + */ + SOLR_DOCS_PORT?: string; + /** + * `SOLR_DOCS_CORE` is the core name for Apache Solr's core for indexed documents. + */ + SOLR_DOCS_CORE?: string; + /** + * `SOLR_DOCS_URL` is the URL to access Apache Solr's core for indexed documents. It is used by Gulp and the Search feature. + */ + SOLR_DOCS_URL?: string; + /** + * `SOLR_LAW_HOST` is the host for Apache Solr's core for indexed laws. + */ + SOLR_LAW_HOST?: string; + /** + * `SOLR_LAW_PORT` is the port for Apache Solr's core for indexed laws. + */ + SOLR_LAW_PORT?: string; + /** + * `SOLR_LAW_CORE` is the core name for Apache Solr's core for indexed laws. + */ + SOLR_LAW_CORE?: string; + /** + * `SOLR_LAW_URL` is the URL to access Apache Solr's core for indexed laws. It is used by Gulp and the Search feature. + */ + SOLR_LAW_URL?: string; + /** + * `TIKA_HOST` is the host to access the Apache Tika app. + */ + TIKA_HOST?: string; + /** + * `TIKA_PORT` is the port to access the Apache Tika app. + */ + TIKA_PORT?: string; + /** + * `TIKA_URL` is the URL to access the Apache Tika app. + */ + TIKA_URL?: string; } /** * The `Config` interface represents the imported environment variables after imported from `process.env` dictionary. */ export interface Config { - /** - * `appHttpHost` is the host for the HTTP web app. - */ - appHttpHost: string; - /** - * `appHttpPort` is the TCP port used to access the Node application's HTTP interface (usually by a reverse proxy). - */ - appHttpPort: number|string; - /** - * `appHttpUrl` is the URL used to access the Node application (usually by a reverse proxy). - */ - appHttpUrl: string; - /** - * `siteName` is used for page generation. - */ - siteName: string; - /** - * `siteWelcomeMessage` is used for the homepage instead of `"Welcome to ${process.env['SITE_NAME']}!"` - */ - siteWelcomeMessage: string; - /** - * `siteHost` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) - */ - siteHost: string; - /** - * `siteUrl` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) - */ - siteUrl: string; - /** - * `publicPath` is the relative path to the directory to this project root for the public files. - */ - publicPath: string; - /** - * `pagesPath` is the relative path to the directory to this project root for the pages rather than public files. - */ - pagesPath: string; - /** - * `assetsPath` is the relative path to the directory to this project root for the static asset files. - */ - assetsPath: string; - /** - * `viewsPath' is the relative path to the directory to this project root for the view templates. - */ - viewsPath: string; - /** - * `solrDocsHost` is the host for Apache Solr's core for indexed documents. - */ - solrDocsHost: string; - /** - * `solrDocsPort` is the port for Apache Solr's core for indexed documents. - */ - solrDocsPort: number|string; - /** - * `solrDocsCore` is the core name for Apache Solr's core for indexed documents. - */ - solrDocsCore: string; - /** - * `solrDocsUrl` is the URL to access Apache Solr's core for indexed documents. It is used by Gulp and the Search feature. - */ - solrDocsUrl: string; - /** - * `solrLawHost` is the host for Apache Solr's core for indexed laws. - */ - solrLawHost: string; - /** - * `solrLawPort` is the port for Apache Solr's core for indexed laws. - */ - solrLawPort: number|string; - /** - * `solrLawCore` is the core name for Apache Solr's core for indexed laws. - */ - solrLawCore: string; - /** - * `solrLawUrl` is the URL to access Apache Solr's core for indexed laws. It is used by Gulp and the Search feature. - */ - solrLawUrl: string; - /** - * `tikaHost` is the host to access the Apache Tika app. - */ - tikaHost: string; - /** - * `tikaPort` is the port to access the Apache Tika app. - */ - tikaPort: string|number; - /** - * `tikaUrl` is the URL to access the Apache Tika app. - */ - tikaUrl: string; + /** + * `appHttpHost` is the host for the HTTP web app. + */ + appHttpHost: string; + /** + * `appHttpPort` is the TCP port used to access the Node application's HTTP interface (usually by a reverse proxy). + */ + appHttpPort: number|string; + /** + * `appHttpUrl` is the URL used to access the Node application (usually by a reverse proxy). + */ + appHttpUrl: string; + /** + * `siteName` is used for page generation. + */ + siteName: string; + /** + * `siteWelcomeMessage` is used for the homepage instead of `"Welcome to ${process.env['SITE_NAME']}!"` + */ + siteWelcomeMessage: string; + /** + * `siteHost` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) + */ + siteHost: string; + /** + * `siteUrl` is used for generating links for the search index. (If you leave this blank it should work using relative paths.) + */ + siteUrl: string; + /** + * `publicPath` is the relative path to the directory to this project root for the public files. + */ + publicPath: string; + /** + * `pagesPath` is the relative path to the directory to this project root for the pages rather than public files. + */ + pagesPath: string; + /** + * `assetsPath` is the relative path to the directory to this project root for the static asset files. + */ + assetsPath: string; + /** + * `viewsPath' is the relative path to the directory to this project root for the view templates. + */ + viewsPath: string; + /** + * `solrDocsHost` is the host for Apache Solr's core for indexed documents. + */ + solrDocsHost: string; + /** + * `solrDocsPort` is the port for Apache Solr's core for indexed documents. + */ + solrDocsPort: number|string; + /** + * `solrDocsCore` is the core name for Apache Solr's core for indexed documents. + */ + solrDocsCore: string; + /** + * `solrDocsUrl` is the URL to access Apache Solr's core for indexed documents. It is used by Gulp and the Search feature. + */ + solrDocsUrl: string; + /** + * `solrLawHost` is the host for Apache Solr's core for indexed laws. + */ + solrLawHost: string; + /** + * `solrLawPort` is the port for Apache Solr's core for indexed laws. + */ + solrLawPort: number|string; + /** + * `solrLawCore` is the core name for Apache Solr's core for indexed laws. + */ + solrLawCore: string; + /** + * `solrLawUrl` is the URL to access Apache Solr's core for indexed laws. It is used by Gulp and the Search feature. + */ + solrLawUrl: string; + /** + * `tikaHost` is the host to access the Apache Tika app. + */ + tikaHost: string; + /** + * `tikaPort` is the port to access the Apache Tika app. + */ + tikaPort: string|number; + /** + * `tikaUrl` is the URL to access the Apache Tika app. + */ + tikaUrl: string; } -console.log(`Configuring .env and expanding .env to include environment variable references.`); - import path from 'path'; import dotenv from 'dotenv'; import dotenvExpand from 'dotenv-expand'; @@ -195,20 +193,20 @@ const __dirname = path.dirname(__filename); const env: ProcessEnv = {}; let dotEnvConfig = dotenv.config({ - path: path.join(__dirname, '.env'), - processEnv: dotenv.config({ - path: path.join(__dirname, '..', '..', '.env'), - processEnv: env as dotenv.DotenvPopulateInput}) as dotenv.DotenvPopulateInput - }); + path: path.join(__dirname, '.env'), + processEnv: dotenv.config({ + path: path.join(__dirname, '..', '..', '.env'), + processEnv: env as dotenv.DotenvPopulateInput}) as dotenv.DotenvPopulateInput + }); dotEnvConfig = dotenvExpand.expand({ - parsed: env as dotenvExpand.DotenvParseInput, - processEnv: process.env as dotenvExpand.DotenvParseInput + parsed: env as dotenvExpand.DotenvParseInput, + processEnv: process.env as dotenvExpand.DotenvParseInput }); export const getAppHttpHost = () => env.APP_HTTP_HOST||'nm3clol-express-app'; export const getAppHttpPort = () => process.env.PORT||env.APP_HTTP_PORT||3000; export const getAppHttpUrl = () => { - return env.APP_HTTP_URL || `http://${getAppHttpHost() + ((getAppHttpPort() == '80') ? '' : ':' + getAppHttpPort())}` + return env.APP_HTTP_URL || `http://${getAppHttpHost() + ((getAppHttpPort() == '80') ? '' : ':' + getAppHttpPort())}` }; export const getSiteName = () => env.SITE_NAME||"(dev) No Moss 3 Carbo Landfill Online Localhost"; @@ -237,31 +235,31 @@ export const getTikaPort = () => parseInt(env.TIKA_PORT||'9998'); export const getTikaUrl = () => env.TIKA_URL||`http://${getTikaHost()}:${getTikaPort()}`; export const config: Config = { - appHttpHost: getAppHttpHost(), - appHttpPort: getAppHttpPort(), - appHttpUrl: getAppHttpUrl(), + appHttpHost: getAppHttpHost(), + appHttpPort: getAppHttpPort(), + appHttpUrl: getAppHttpUrl(), - siteName: getSiteName(), - siteWelcomeMessage: getSiteWelcomeMessage(), - siteHost: getSiteHost(), - siteUrl: getSiteUrl(), + siteName: getSiteName(), + siteWelcomeMessage: getSiteWelcomeMessage(), + siteHost: getSiteHost(), + siteUrl: getSiteUrl(), - publicPath: getPublicPath(), - pagesPath: getPagesPath(), - assetsPath: getAssetsPath(), - viewsPath: getViewsPath(), + publicPath: getPublicPath(), + pagesPath: getPagesPath(), + assetsPath: getAssetsPath(), + viewsPath: getViewsPath(), - solrDocsHost: getSolrDocsHost(), - solrDocsPort: getSolrDocsPort(), - solrDocsCore: getSolrDocsCore(), - solrDocsUrl: getSolrDocsUrl(), + solrDocsHost: getSolrDocsHost(), + solrDocsPort: getSolrDocsPort(), + solrDocsCore: getSolrDocsCore(), + solrDocsUrl: getSolrDocsUrl(), - solrLawHost: getSolrLawHost(), - solrLawPort: getSolrLawPort(), - solrLawCore: getSolrLawCore(), - solrLawUrl: getSolrLawCore(), + solrLawHost: getSolrLawHost(), + solrLawPort: getSolrLawPort(), + solrLawCore: getSolrLawCore(), + solrLawUrl: getSolrLawCore(), - tikaHost: getTikaHost(), - tikaPort: getTikaPort(), - tikaUrl: getTikaUrl(), + tikaHost: getTikaHost(), + tikaPort: getTikaPort(), + tikaUrl: getTikaUrl(), }; diff --git a/app/helpers/breadcrumbs.mts b/app/helpers/breadcrumbs.mts index 3580bdc4..f2586fea 100644 --- a/app/helpers/breadcrumbs.mts +++ b/app/helpers/breadcrumbs.mts @@ -1,4 +1,4 @@ export interface Breadcrumb { - title: string; - url: string; -} + title: string; + url: string; +} \ No newline at end of file diff --git a/app/helpers/functions.mts b/app/helpers/functions.mts index 13907508..5c6e2000 100644 --- a/app/helpers/functions.mts +++ b/app/helpers/functions.mts @@ -186,6 +186,14 @@ const renderArchive = (html: string, paths: string[]) => { return html; } +const isMsOfficeViewerSupported = (file: string) => { + return path.extname(file).search(/^((?:.pptx)|(?:.docx)|(?:.xlsx)|(?:.ppt)|(?:.doc)|(?:.xls))$/ig) != -1; +} + +const isGoogleDocsViewerSupported = (file: string) => { + return isMsOfficeViewerSupported(file) || path.extname(file).search(/^((?:.pdf))$/ig) != -1; +} + export default { leftTrimFirstDirectory, trimSlashes, @@ -205,4 +213,6 @@ export default { inspect, md, moment, + isMsOfficeViewerSupported, + isGoogleDocsViewerSupported, }; \ No newline at end of file diff --git a/app/page/glob-slash.mts b/app/page/glob-slash.mts index 6491d648..ac29d935 100644 --- a/app/page/glob-slash.mts +++ b/app/page/glob-slash.mts @@ -5,4 +5,4 @@ import path from 'path'; export const normalize = (value: string) => path.posix.normalize(path.posix.join('/', value));; -export default (value: string) => (value.charAt(0) === '!' ? `!${normalize(value.substr(1))}` : normalize(value)); +export default (value: string) => (value.charAt(0) === '!' ? `!${normalize(value.substr(1))}` : normalize(value)); \ No newline at end of file diff --git a/app/page/router.mts b/app/page/router.mts index 65dfb26c..bd072740 100644 --- a/app/page/router.mts +++ b/app/page/router.mts @@ -78,7 +78,7 @@ export default function () { } }); const renderData = { breadcrumbs, content, filePath, fullFilePath, paths, req, route, ...fmData }; - res.render("page", { h: helpers, ...renderData }); + res.render("page", { h: helpers, path, config, ...renderData }); }); }); @@ -122,7 +122,7 @@ export default function () { console.log(`Setting route for ${route}`); pageRouter.get(route, async (req, res) => { const html = fs.readFileSync(fullFilePath).toString(); - const renderData = { route, filePath, fullFilePath, req, paths, html }; + const renderData = { route, filePath, fullFilePath, req, paths, html, path, config }; res.render("archive", { h: helpers, ...renderData }); }); }); @@ -183,7 +183,7 @@ export default function () { } }); const renderData = { breadcrumbs, route, filePath, fullFilePath, req, paths, directory: path.join('public', directory), videoURL, subtitleURL, subtitleVTT, info }; - res.render("video-player", { h: helpers, ...renderData }); + res.render("video-player", { h: helpers, path, config, ...renderData }); } }); }); diff --git a/app/page/vercel-serve.mts b/app/page/vercel-serve.mts index 1308e953..98524f1c 100644 --- a/app/page/vercel-serve.mts +++ b/app/page/vercel-serve.mts @@ -81,15 +81,15 @@ export interface ServeHandlerOptions { * current working directory. * * For example, if serving a Jekyll app, it would look like this: - * { - * "public": "_site" - * } + * { + * "public": "_site" + * } * * Using absolute path: * - * { - * "public": "/path/to/your/_site" - * } + * { + * "public": "/path/to/your/_site" + * } * * NOTE: The path cannot contain globs or regular expressions. */ @@ -101,17 +101,17 @@ export interface ServeHandlerOptions { * with status code 301 to the same path, but with the extension dropped. * * You can disable the feature like follows: - * { - * "cleanUrls": false - * } + * { + * "cleanUrls": false + * } * * However, you can also restrict it to certain paths: - * { - * "cleanUrls": [ - * "/app/**", - * "/!components/**" - * ] - * } + * { + * "cleanUrls": [ + * "/app/**", + * "/!components/**" + * ] + * } * * NOTE: The paths can only contain globs that are matched using minimatch. */ @@ -121,19 +121,19 @@ export interface ServeHandlerOptions { * different one behind the curtains, this option is what you need. * * It's perfect for single page applications (SPAs), for example: - * { - * "rewrites": [ - * { "source": "app/**", "destination": "/index.html" }, - * { "source": "projects/edit", "destination": "/edit-project.html" } - * ] - * } + * { + * "rewrites": [ + * { "source": "app/**", "destination": "/index.html" }, + * { "source": "projects/edit", "destination": "/edit-project.html" } + * ] + * } * * You can also use so-called "routing segments" as follows: - * { - * "rewrites": [ - * { "source": "/projects/:id/edit", "destination": "/edit-project-:id.html" }, - * ] - * } + * { + * "rewrites": [ + * { "source": "/projects/:id/edit", "destination": "/edit-project-:id.html" }, + * ] + * } * * Now, if a visitor accesses /projects/123/edit, it will respond with the file /edit-project-123.html. * @@ -184,8 +184,9 @@ export const directoryTemplate = (vals: ServeDirectoryTemplateParameters) => { }); } return new Promise((resolve, reject) => { - ejs.renderFile(path.join(config.viewsPath, 'directory.ejs'), { breadcrumbs, h: helpers, ...vals }, (err, str) => { + ejs.renderFile(path.join(config.viewsPath, 'directory.ejs'), { h: helpers, path, config, breadcrumbs, ...vals }, (err, str) => { if (err) { + console.error(err); reject(err); } else { resolve(str); @@ -196,8 +197,9 @@ export const directoryTemplate = (vals: ServeDirectoryTemplateParameters) => { export const errorTemplate = (vals: ServeErrorTemplateParameters) => { return new Promise((resolve, reject) => { - ejs.renderFile(path.join(config.viewsPath, 'error.ejs'), { h: helpers, ...vals }, (err, str) => { + ejs.renderFile(path.join(config.viewsPath, 'error.ejs'), { h: helpers, path, config, ...vals }, (err, str) => { if (err) { + console.error(err); reject(err); } else { resolve(str); @@ -1012,4 +1014,4 @@ export default async (request: Request, response: ServerResponse, serveConfig: S response.writeHead(response.statusCode || 200, headers); stream.pipe(response); -}; +}; \ No newline at end of file diff --git a/app/search/solr-doc.mts b/app/search/solr-doc.mts index 7c10e40a..f7f4de23 100644 --- a/app/search/solr-doc.mts +++ b/app/search/solr-doc.mts @@ -2,24 +2,24 @@ * Needed until the conversion is completed. */ export interface IncorrectStyleSolrDocument { - id: string; - sha256sum: string[]; - url: string[]; - content_length: number[]; - content_type: string[]; - text: string[]; - _version_?: number; + id: string; + sha256sum: string[]; + url: string[]; + content_length: number[]; + content_type: string[]; + text: string[]; + _version_?: number; } /** * Describes Solr full-text search properties for a document file in the public repository. */ export interface SolrDocument { - id: string; - sha256sum: string; - url: string; - content_length: number; - content_type: string; - text: string; - _version_?: number; + id: string; + sha256sum: string; + url: string; + content_length: number; + content_type: string; + text: string; + _version_?: number; } diff --git a/app/server.mts b/app/server.mts index 782ac3db..b90eaccf 100644 --- a/app/server.mts +++ b/app/server.mts @@ -38,5 +38,5 @@ app.listen(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}.`); -}); + console.log(`This app is configured to use the web site URL for URL generation, as needed, ${config.siteUrl}. Certain site features won't work correctly unless this is on a publicly accessible URL.`); +}); \ No newline at end of file diff --git a/app/tika/client.mts b/app/tika/client.mts index 378d722d..80305f55 100644 --- a/app/tika/client.mts +++ b/app/tika/client.mts @@ -1,11 +1,11 @@ import { ReadStream } from 'fs' import fetch from 'node-fetch' let join = (...args: String[]) => { - let output = ""; - args.forEach((arg) => { - output += arg; - }) - return output; + let output = ""; + args.forEach((arg) => { + output += arg; + }) + return output; }; import { ContentResource, MetadataResource } from './types.mjs' import { Writable } from 'stream'; diff --git a/app/tika/types.mts b/app/tika/types.mts index 1ad11bb8..2b3ce2d4 100644 --- a/app/tika/types.mts +++ b/app/tika/types.mts @@ -1,81 +1,81 @@ export interface MetadataResource { - 'pdf:unmappedUnicodeCharsPerPage': string[] - 'pdf:PDFVersion': string - 'xmp:CreatorTool': string - 'pdf:hasXFA': string - 'access_permission:modify_annotations': string - 'access_permission:can_print_degraded': string - 'X-TIKA:Parsed-By-Full-Set': string[] - 'pdf:num3DAnnotations': string - 'dcterms:created': string - 'language': string - 'dcterms:modified': string - 'dc:format': string - 'pdf:docinfo:creator_tool': string - 'pdf:overallPercentageUnmappedUnicodeChars': string - 'access_permission:fill_in_form': string - 'pdf:docinfo:modified': string - 'pdf:hasCollection': string - 'pdf:encrypted': string - 'pdf:containsNonEmbeddedFont': string - 'Content-Length': string - 'pdf:hasMarkedContent': string - 'Content-Type': string - 'pdf:producer': string - 'pdf:totalUnmappedUnicodeChars': string - 'access_permission:extract_for_accessibility': string - 'access_permission:assemble_document': string - 'xmpTPg:NPages': string - 'pdf:hasXMP': string - 'pdf:charsPerPage': string[] - 'access_permission:extract_content': string - 'access_permission:can_print': string - 'X-TIKA:Parsed-By': string[] - 'pdf:annotationTypes': string - 'access_permission:can_modify': string - 'pdf:docinfo:producer': string - 'pdf:docinfo:created': string - 'pdf:annotationSubtypes': string - 'pdf:containsDamagedFont': string - } - - export interface ContentResource { - 'pdf:unmappedUnicodeCharsPerPage': string[] - 'pdf:PDFVersion': string - 'xmp:CreatorTool': string - 'pdf:hasXFA': string - 'access_permission:modify_annotations': string - 'access_permission:can_print_degraded': string - 'X-TIKA:Parsed-By-Full-Set': string[] - 'pdf:num3DAnnotations': string - 'dcterms:created': string - 'dcterms:modified': string - 'dc:format': string - 'pdf:docinfo:creator_tool': string - 'pdf:overallPercentageUnmappedUnicodeChars': string - 'access_permission:fill_in_form': string - 'pdf:docinfo:modified': string - 'pdf:hasCollection': string - 'pdf:encrypted': string - 'pdf:containsNonEmbeddedFont': string - 'Content-Length': string - 'pdf:hasMarkedContent': string - 'Content-Type': string - 'pdf:producer': string - 'pdf:totalUnmappedUnicodeChars': string - 'access_permission:extract_for_accessibility': string - 'access_permission:assemble_document': string - 'xmpTPg:NPages': string - 'pdf:hasXMP': string - 'pdf:charsPerPage': string[] - 'access_permission:extract_content': string - 'access_permission:can_print': string - 'X-TIKA:Parsed-By': string[] - 'X-TIKA:content': string - 'pdf:annotationTypes': string - 'access_permission:can_modify': string - 'pdf:docinfo:producer': string - 'pdf:docinfo:created': string - 'pdf:annotationSubtypes': string - 'pdf:containsDamagedFont': string - } \ No newline at end of file + 'pdf:unmappedUnicodeCharsPerPage': string[] + 'pdf:PDFVersion': string + 'xmp:CreatorTool': string + 'pdf:hasXFA': string + 'access_permission:modify_annotations': string + 'access_permission:can_print_degraded': string + 'X-TIKA:Parsed-By-Full-Set': string[] + 'pdf:num3DAnnotations': string + 'dcterms:created': string + 'language': string + 'dcterms:modified': string + 'dc:format': string + 'pdf:docinfo:creator_tool': string + 'pdf:overallPercentageUnmappedUnicodeChars': string + 'access_permission:fill_in_form': string + 'pdf:docinfo:modified': string + 'pdf:hasCollection': string + 'pdf:encrypted': string + 'pdf:containsNonEmbeddedFont': string + 'Content-Length': string + 'pdf:hasMarkedContent': string + 'Content-Type': string + 'pdf:producer': string + 'pdf:totalUnmappedUnicodeChars': string + 'access_permission:extract_for_accessibility': string + 'access_permission:assemble_document': string + 'xmpTPg:NPages': string + 'pdf:hasXMP': string + 'pdf:charsPerPage': string[] + 'access_permission:extract_content': string + 'access_permission:can_print': string + 'X-TIKA:Parsed-By': string[] + 'pdf:annotationTypes': string + 'access_permission:can_modify': string + 'pdf:docinfo:producer': string + 'pdf:docinfo:created': string + 'pdf:annotationSubtypes': string + 'pdf:containsDamagedFont': string +} + +export interface ContentResource { + 'pdf:unmappedUnicodeCharsPerPage': string[] + 'pdf:PDFVersion': string + 'xmp:CreatorTool': string + 'pdf:hasXFA': string + 'access_permission:modify_annotations': string + 'access_permission:can_print_degraded': string + 'X-TIKA:Parsed-By-Full-Set': string[] + 'pdf:num3DAnnotations': string + 'dcterms:created': string + 'dcterms:modified': string + 'dc:format': string + 'pdf:docinfo:creator_tool': string + 'pdf:overallPercentageUnmappedUnicodeChars': string + 'access_permission:fill_in_form': string + 'pdf:docinfo:modified': string + 'pdf:hasCollection': string + 'pdf:encrypted': string + 'pdf:containsNonEmbeddedFont': string + 'Content-Length': string + 'pdf:hasMarkedContent': string + 'Content-Type': string + 'pdf:producer': string + 'pdf:totalUnmappedUnicodeChars': string + 'access_permission:extract_for_accessibility': string + 'access_permission:assemble_document': string + 'xmpTPg:NPages': string + 'pdf:hasXMP': string + 'pdf:charsPerPage': string[] + 'access_permission:extract_content': string + 'access_permission:can_print': string + 'X-TIKA:Parsed-By': string[] + 'X-TIKA:content': string + 'pdf:annotationTypes': string + 'access_permission:can_modify': string + 'pdf:docinfo:producer': string + 'pdf:docinfo:created': string + 'pdf:annotationSubtypes': string + 'pdf:containsDamagedFont': string +} \ No newline at end of file diff --git a/app/views/directory.ejs b/app/views/directory.ejs index edfe52dd..adb96576 100644 --- a/app/views/directory.ejs +++ b/app/views/directory.ejs @@ -4,18 +4,13 @@ <%=h.getDirectoryTitle(directory)%> <%- include('./includes/common-head.ejs') %> - - <%- include('./includes/top-navbar.ejs') %> - <%- include('./includes/no-trash-svg.ejs') %> -
<%- include('./includes/breadcrumbs.ejs') %>
- <% if (h.directoryContainsReadme(directory)) {%>
@@ -27,13 +22,69 @@ Document Date: <%= h.moment(h.readmeFm(directory).docDate).format('MMMM D, YYYY') %> <% } %> <%if (typeof h.readmeFm(directory).file !== 'undefined') { %> - Attached Document: <%- h.readmeFm(directory).file %> + Document: <%- h.readmeFm(directory).file %> <% } %>

<% } %> <% if (typeof h.readmeFm(directory).file !== 'undefined') { %> - + +
+ <% if (h.isMsOfficeViewerSupported(h.readmeFm(directory).file)) { %> +
+ +
+ <% } %> + <% if (h.isGoogleDocsViewerSupported(h.readmeFm(directory).file)) { %> +
+ +
+ <% } %> +
+ +
+ + <% if (!h.isMsOfficeViewerSupported(h.readmeFm(directory).file) && !h.isGoogleDocsViewerSupported(h.readmeFm(directory).file)) { %> + + <% } %> +
<% } else { %> <%- h.printReadme(directory) %> <% } %> @@ -54,7 +105,6 @@
<% } %> <% } %> -
- <%- include('./includes/bottom-navbar.ejs') %> <%- include('./includes/bottom-scripts.ejs') %> diff --git a/app/views/error.ejs b/app/views/error.ejs index 91181817..4b9af003 100644 --- a/app/views/error.ejs +++ b/app/views/error.ejs @@ -1,122 +1,105 @@ - - + - - - + +
-
- <% if (typeof statusCode !== 'undefined') { %><%= statusCode %><% } %> -

<% if (typeof message !== 'undefined') { %><%= message %><% } %>

-
+
+ <% if (typeof statusCode !== 'undefined') { %><%= statusCode %><% } %> +

<% if (typeof message !== 'undefined') { %><%= message %><% } %>

+
- - - + + \ No newline at end of file diff --git a/app/views/includes/bottom-navbar.ejs b/app/views/includes/bottom-navbar.ejs index 5d2df91c..ae233c08 100644 --- a/app/views/includes/bottom-navbar.ejs +++ b/app/views/includes/bottom-navbar.ejs @@ -9,4 +9,4 @@ Your use of this search feature constitutes your agreement with the Search Policy.

- + \ No newline at end of file diff --git a/app/views/includes/bottom-scripts.ejs b/app/views/includes/bottom-scripts.ejs index c0bfd4da..71577113 100644 --- a/app/views/includes/bottom-scripts.ejs +++ b/app/views/includes/bottom-scripts.ejs @@ -1,6 +1,5 @@ - - + \ No newline at end of file diff --git a/app/views/includes/breadcrumbs.ejs b/app/views/includes/breadcrumbs.ejs index 06e8165d..267d8d2a 100644 --- a/app/views/includes/breadcrumbs.ejs +++ b/app/views/includes/breadcrumbs.ejs @@ -9,4 +9,4 @@ <%=breadcrumb.title%> <% } %> <% }) %> - + \ No newline at end of file diff --git a/app/views/includes/common-head.ejs b/app/views/includes/common-head.ejs index 7188b755..64a86044 100644 --- a/app/views/includes/common-head.ejs +++ b/app/views/includes/common-head.ejs @@ -10,7 +10,6 @@ - @@ -26,3 +25,4 @@ + diff --git a/app/views/includes/no-trash-svg.ejs b/app/views/includes/no-trash-svg.ejs index 8a32995e..e333a91d 100644 --- a/app/views/includes/no-trash-svg.ejs +++ b/app/views/includes/no-trash-svg.ejs @@ -1,18 +1,18 @@ \ No newline at end of file diff --git a/app/views/includes/top-navbar.ejs b/app/views/includes/top-navbar.ejs index e2430a77..fcba03bd 100644 --- a/app/views/includes/top-navbar.ejs +++ b/app/views/includes/top-navbar.ejs @@ -13,4 +13,4 @@ - + \ No newline at end of file diff --git a/app/views/page.ejs b/app/views/page.ejs index be4d05d1..6fc892a9 100644 --- a/app/views/page.ejs +++ b/app/views/page.ejs @@ -4,18 +4,13 @@ <%= (typeof fm.title !== 'undefined') ? `${fm.title} - ${h.getSiteName()}` : h.getSiteName() %> <%- include('./includes/common-head.ejs') %> - - <%- include('./includes/top-navbar.ejs') %> - <%- include('./includes/no-trash-svg.ejs') %> -
<%- include('./includes/breadcrumbs.ejs') %>
- <% if (typeof content !== 'undefined') {%>
@@ -29,7 +24,6 @@
<% } %> -
- <%- include('./includes/bottom-navbar.ejs') %> <%- include('./includes/bottom-scripts.ejs') %> diff --git a/app/views/search-error.ejs b/app/views/search-error.ejs index 54adcd00..89578bcd 100644 --- a/app/views/search-error.ejs +++ b/app/views/search-error.ejs @@ -1,35 +1,34 @@ - - Search Error for <%- query %> - <%- h.getSiteName() %> - <%- include('./includes/common-head.ejs') %> - - - <%- include('./includes/top-navbar.ejs') %> - <%- include('./includes/no-trash-svg.ejs') %> -
-
- <%- include('./includes/breadcrumbs.ejs') %> -
-
-

- Disclaimer: Use of the search feature is subject to both the Search - Policy and the Privacy Policy. -

-
-
- <% if (typeof error !== 'undefined') {%> -

An error occurred while attempting to perform a search.

- <% if (typeof query !== 'undefined') {%>

Search Query: <%= query %>

<% } %> - <% if (typeof error.code !== 'undefined') {%>

Error Code: <%= error.code %>

<% } %> - <% if (typeof error.message !== 'undefined') {%>

Error Message: <%= error.message %>

<% } %> - <% if (typeof error.innerError !== 'undefined' && typeof error.innerError.error !== 'undefined') { %> - <% if (typeof error.innerError.error.msg !== 'undefined') {%>

Inner Error Message: <%- error.innerError.error.msg.replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", '
') %>

<% } %> + + Search Error for <%- query %> - <%- h.getSiteName() %> + <%- include('./includes/common-head.ejs') %> + + + <%- include('./includes/top-navbar.ejs') %> + <%- include('./includes/no-trash-svg.ejs') %> +
+
+ <%- include('./includes/breadcrumbs.ejs') %> +
+
+

+ Disclaimer: Use of the search feature is subject to both the Search + Policy and the Privacy Policy. +

+
+
+ <% if (typeof error !== 'undefined') {%> +

An error occurred while attempting to perform a search.

+ <% if (typeof query !== 'undefined') {%>

Search Query: <%= query %>

<% } %> + <% if (typeof error.code !== 'undefined') {%>

Error Code: <%= error.code %>

<% } %> + <% if (typeof error.message !== 'undefined') {%>

Error Message: <%= error.message %>

<% } %> + <% if (typeof error.innerError !== 'undefined' && typeof error.innerError.error !== 'undefined') { %> + <% if (typeof error.innerError.error.msg !== 'undefined') {%>

Inner Error Message: <%- error.innerError.error.msg.replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", '
') %>

<% } %> + <% } %> <% } %> - <% } %> -
- - <%- include('./includes/bottom-navbar.ejs') %> - <%- include('./includes/bottom-scripts.ejs') %> - - +
+ <%- include('./includes/bottom-navbar.ejs') %> + <%- include('./includes/bottom-scripts.ejs') %> + + \ No newline at end of file diff --git a/app/views/search-results.ejs b/app/views/search-results.ejs index 0ac46ae9..f3cad141 100644 --- a/app/views/search-results.ejs +++ b/app/views/search-results.ejs @@ -1,73 +1,72 @@ - - Search Results for <%- query %> - <%- h.getSiteName() %> - <%- include('./includes/common-head.ejs') %> - - - <%- include('./includes/top-navbar.ejs') %> - <%- include('./includes/no-trash-svg.ejs') %> -
-
- <%- include('./includes/breadcrumbs.ejs') %> -
-
-

- Disclaimer: Use of the search feature is subject to both the Search - Policy and the Privacy Policy. -

-
- <% if (typeof response !== "undefined" && typeof response.numFound !== "undefined" && typeof response.docs !== "undefined" && typeof highlighting !== "undefined") { %> -
- - <% if (response.numFound == 0) { %> -

No documents found matching the search query.

- <% } else { %> -
    - <% response.docs.forEach(doc => { %> -
  • -
    <%= doc.title %>
    - <% if (highlighting[doc.id] && highlighting[doc.id].text) { %> - <% highlighting[doc.id].text.forEach(snippet => { %> -
    <%- h.stripWebVTT(snippet) %>
    - <% }); %> - <% } else { %> - - <% } %> - <%= doc.url %> -
  • - <% }); %> -
- <% } %> -
+ + Search Results for <%- query %> - <%- h.getSiteName() %> + <%- include('./includes/common-head.ejs') %> + + + <%- include('./includes/top-navbar.ejs') %> + <%- include('./includes/no-trash-svg.ejs') %> +
+
+ <%- include('./includes/breadcrumbs.ejs') %> +
+
+

+ Disclaimer: Use of the search feature is subject to both the Search + Policy and the Privacy Policy. +

- <% } %> - - <% if (typeof totalPages !== "undefined" && totalPages) { %> - -

Page <%= page %> out of <%= totalPages %>. Displaying results <%= (page-1)*pageSize+1 %> through <%= Math.min(page*pageSize, totalResults) %> out of <%= totalResults %> total results.

- <% } %> -
- - <%- include('./includes/bottom-navbar.ejs') %> - <%- include('./includes/bottom-scripts.ejs') %> - - + <% if (typeof response !== "undefined" && typeof response.numFound !== "undefined" && typeof response.docs !== "undefined" && typeof highlighting !== "undefined") { %> +
+ + <% if (response.numFound == 0) { %> +

No documents found matching the search query.

+ <% } else { %> +
    + <% response.docs.forEach(doc => { %> +
  • +
    <%= doc.title %>
    + <% if (highlighting[doc.id] && highlighting[doc.id].text) { %> + <% highlighting[doc.id].text.forEach(snippet => { %> +
    <%- h.stripWebVTT(snippet) %>
    + <% }); %> + <% } else { %> + + <% } %> + <%= doc.url %> +
  • + <% }); %> +
+ <% } %> +
+ + <% } %> + + <% if (typeof totalPages !== "undefined" && totalPages) { %> + +

Page <%= page %> out of <%= totalPages %>. Displaying results <%= (page-1)*pageSize+1 %> through <%= Math.min(page*pageSize, totalResults) %> out of <%= totalResults %> total results.

+ <% } %> +
+ <%- include('./includes/bottom-navbar.ejs') %> + <%- include('./includes/bottom-scripts.ejs') %> + + \ No newline at end of file diff --git a/app/views/video-player.ejs b/app/views/video-player.ejs index fb47e710..1e87e13c 100644 --- a/app/views/video-player.ejs +++ b/app/views/video-player.ejs @@ -4,17 +4,13 @@ <%=h.getDirectoryTitle(directory)%> <%- include('./includes/common-head.ejs') %> - - <%- include('./includes/top-navbar.ejs') %> <%- include('./includes/no-trash-svg.ejs') %> -
<%- include('./includes/breadcrumbs.ejs') %>
- <% if (typeof videoURL !== 'undefined') {%>
@@ -49,7 +45,6 @@
<% } %> - <% if (typeof subtitleVTT !== 'undefined') {%>
@@ -65,9 +60,7 @@
<% } %> -
- <%- include('./includes/bottom-navbar.ejs') %> <%- include('./includes/bottom-scripts.ejs') %>