diff --git a/config.example.toml b/config.example.toml index e584010..e9a2b0b 100644 --- a/config.example.toml +++ b/config.example.toml @@ -5,11 +5,15 @@ country = "Your country"# Optional log_level = "debug" # debug, info, warn, error -log_dir = "/path/to/logs" root_dir = "/path/to/server" health_check = "/health" +[logging] +level = "debug" +db_path = "/path/to/logs.sqlite3" +log_dir = "/path/to/logs" + [public] schema = "https" domain = "example.com" diff --git a/content b/content index d1c89d6..2744e36 160000 --- a/content +++ b/content @@ -1 +1 @@ -Subproject commit d1c89d66381dfe0e520678d98e2ab0042d11d9c8 +Subproject commit 2744e36b95be401210a142eb2471220237cf0497 diff --git a/src/routes/index.js b/src/routes/index.js index c3aeb11..c1eb186 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -8,13 +8,13 @@ const errorPage = require("../controllers/errorPageController"); const admin = require("./admin"); const tags = require("./tags"); -const presentation = require("./presentation"); const resume = require("./resume"); const contact = require("./contact"); const sitemap = require("./sitemap"); const { blogPost, blogIndex } = require("../controllers/blogControllers"); const pages = require("./pages"); +const projects = require("./projects"); const docs = require("./docs"); const rssFeedController = require("../controllers/rssFeedController"); const HttpError = require("../utils/HttpError"); @@ -90,8 +90,8 @@ router.use("/resume", resume); router.use(sitemap); router.use(pages); +router.use(projects); router.use(tags); -router.use("/projects/website-presentation", presentation); router.use("/docs", docs); router.get("/blog/:year/:month/:name", blogPost); diff --git a/src/routes/pages.js b/src/routes/pages.js index 3b75f99..b935eb2 100644 --- a/src/routes/pages.js +++ b/src/routes/pages.js @@ -5,22 +5,15 @@ const MarkdownRoutes = require("../utils/MarkdownRoutes"); const HtmlRoutes = require("../utils/htmlRoutes"); const csrfToken = require("../middleware/csrfToken"); +const newsletter = require("./newsletter"); const { meta } = require("../config/loader"); const construction = new ConstructionRoutes(); const html = new HtmlRoutes(); const markdown = new MarkdownRoutes(); -const { node_env } = meta; -if (node_env === "production" || node_env === "testing") { - // construction.register("/newsletter", "Newsletter"); - construction.register("/projects", "Projects"); -} else { - markdown.register("/projects", "projects"); -} markdown.register("/about/blog", "about-blog"); -const newsletter = require("./newsletter"); router.use(newsletter, csrfToken); construction.register("/changelog", "Changelog"); @@ -28,7 +21,6 @@ markdown.register("/tools", "tools", "tools"); markdown.register("/about/me", "about-me"); -html.register("/games/word-guesser", "word-guesser"); router.use(construction.getRouter()); router.use(html.getRouter()); diff --git a/src/routes/projects.js b/src/routes/projects.js new file mode 100644 index 0000000..ee7d90c --- /dev/null +++ b/src/routes/projects.js @@ -0,0 +1,35 @@ +// src/routes/pages.js +const express = require("express"); +const router = express.Router(); +const ConstructionRoutes = require("../utils/ConstructionRoutes"); +const MarkdownRoutes = require("../utils/MarkdownRoutes"); +const HtmlRoutes = require("../utils/htmlRoutes"); +const csrfToken = require("../middleware/csrfToken"); +const presentation = require("./presentation"); +const { meta } = require("../config/loader"); + +const construction = new ConstructionRoutes(); +const html = new HtmlRoutes(); +const markdown = new MarkdownRoutes(); + +const { node_env } = meta; +if (node_env === "production" || node_env === "testing") { + // construction.register("/newsletter", "Newsletter"); + construction.register("/projects", "Projects"); +} else { + markdown.register("/projects", "projects"); +} + +router.use("/projects/website-presentation", presentation); +html.register("/games/word-guesser", "word-guesser"); + +markdown.register("/projects/lisp-interpreter", "projects/lisp_interpreter"); +markdown.register("/projects/pipeline-runner", "projects/pipeline_runner"); +markdown.register("/projects/telemetry", "projects/telemetry"); +markdown.register("/projects/xmonad", "projects/xmonad"); + +router.use(construction.getRouter()); +router.use(html.getRouter()); +router.use(markdown.getRouter()); + +module.exports = router; diff --git a/src/utils/MarkdownRoutes.js b/src/utils/MarkdownRoutes.js index e91a4b4..5946a01 100644 --- a/src/utils/MarkdownRoutes.js +++ b/src/utils/MarkdownRoutes.js @@ -4,6 +4,7 @@ const path = require("path"); const matter = require("gray-matter"); const { marked } = require("marked"); +const { getProjectDates } = require("../utils/gitDates"); // Import the utility class MarkdownRoutes extends BaseRoute { constructor() { @@ -15,13 +16,40 @@ try { const filePath = path.join( __dirname, - `../../content/pages/${markdownFile}.md` + `../../content/pages/${markdownFile}.md`, ); const fileContent = await fs.readFile(filePath, "utf8"); const { data: frontmatter, content } = matter(fileContent); + + // --- Start Git Polling Logic --- + const needsCreated = + !frontmatter.created || frontmatter.created.trim() === ""; + const needsUpdated = + !frontmatter.updated || frontmatter.updated.trim() === ""; + + if (frontmatter.repository && (needsCreated || needsUpdated)) { + // Extract repo name from URL (e.g., "pipeline_runner" from "https://github.com/jpoage1/pipeline_runner") + const repoName = frontmatter.repository + .split("/") + .pop() + .replace(".git", ""); + const localRepoPath = path.resolve( + __dirname, + `../../projects_src/${repoName}`, + ); + + const gitDates = getProjectDates(localRepoPath); + + // Apply Git dates only if the frontmatter fields are blank + if (needsCreated) frontmatter.created = gitDates.created; + if (needsUpdated) frontmatter.updated = gitDates.updated; + } + // --- End Git Polling Logic --- + const htmlContent = marked(content); const context = { - title: frontmatter.title, + // title: frontmatter.title, + ...frontmatter, content: htmlContent, }; res.renderWithBaseContext(`pages/${handlebarsFile}`, context); diff --git a/src/utils/gitDates.js b/src/utils/gitDates.js new file mode 100644 index 0000000..3bb0a7b --- /dev/null +++ b/src/utils/gitDates.js @@ -0,0 +1,30 @@ +// src/utils/gitDates.js +const { execSync } = require("child_process"); +const path = require("path"); + +/** + * Polls the local git history of a project folder. + * @param {string} projectPath - Path to the project submodule/folder + */ +const getProjectDates = (projectPath) => { + try { + // Get ISO date of the first commit (Created) + const created = execSync( + `git -C ${projectPath} log --reverse --format=%ad --date=short | head -1`, + { encoding: "utf8" }, + ).trim(); + + // Get ISO date of the last commit (Updated) + const updated = execSync( + `git -C ${projectPath} log -1 --format=%ad --date=short`, + { encoding: "utf8" }, + ).trim(); + + return { created, updated }; + } catch (err) { + console.error(`Git poll failed for ${projectPath}:`, err.message); + return { created: null, updated: null }; + } +}; + +module.exports = { getProjectDates }; diff --git a/src/views/pages/page.handlebars b/src/views/pages/page.handlebars index 9032a35..107dd42 100644 --- a/src/views/pages/page.handlebars +++ b/src/views/pages/page.handlebars @@ -8,6 +8,7 @@ {{/section}} + {{#section "scripts"}} {{#each extraScripts}} @@ -15,6 +16,11 @@ {{/each}} {{/section}} +{{#if repository}} + {{> git_metadata }} +{{/if}} + +