feat: first cut at the full renderer
This commit is contained in:
@@ -2,8 +2,16 @@ import { dialog } from 'electron';
|
||||
import { getPostEngine } from '../engine/PostEngine';
|
||||
import { getProjectEngine } from '../engine/ProjectEngine';
|
||||
import { getMetaEngine } from '../engine/MetaEngine';
|
||||
import { getMediaEngine } from '../engine/MediaEngine';
|
||||
import { getPostMediaEngine } from '../engine/PostMediaEngine';
|
||||
import { taskManager } from '../engine/TaskManager';
|
||||
import { getBlogGenerationEngine, resolvePublicBaseUrl } from '../engine/BlogGenerationEngine';
|
||||
import {
|
||||
getBlogGenerationEngine,
|
||||
resolvePublicBaseUrl,
|
||||
type BlogGenerationResult,
|
||||
type BlogGenerationSection,
|
||||
} from '../engine/BlogGenerationEngine';
|
||||
import { resolvePageTitle } from '../engine/PageRenderer';
|
||||
|
||||
type SafeHandle = (channel: string, handler: (...args: any[]) => Promise<any>) => void;
|
||||
|
||||
@@ -12,6 +20,8 @@ export function registerBlogHandlers(safeHandle: SafeHandle): void {
|
||||
const projectEngine = getProjectEngine();
|
||||
const postEngine = getPostEngine();
|
||||
const metaEngine = getMetaEngine();
|
||||
const mediaEngine = getMediaEngine();
|
||||
const postMediaEngine = getPostMediaEngine();
|
||||
const blogGenerationEngine = getBlogGenerationEngine();
|
||||
|
||||
const project = await projectEngine.getActiveProject();
|
||||
@@ -22,6 +32,8 @@ export function registerBlogHandlers(safeHandle: SafeHandle): void {
|
||||
const dataDir = projectEngine.getDataDir(project.id, project.dataPath);
|
||||
postEngine.setProjectContext(project.id, dataDir);
|
||||
metaEngine.setProjectContext(project.id, dataDir);
|
||||
mediaEngine.setProjectContext(project.id, dataDir, dataDir);
|
||||
postMediaEngine.setProjectContext(project.id);
|
||||
|
||||
if (!metaEngine.isInitialized()) {
|
||||
await metaEngine.syncOnStartup();
|
||||
@@ -33,27 +45,90 @@ export function registerBlogHandlers(safeHandle: SafeHandle): void {
|
||||
await dialog.showMessageBox({
|
||||
type: 'warning',
|
||||
title: 'Public URL Required',
|
||||
message: 'Sitemap generation requires a public URL.',
|
||||
detail: 'Set Project → Public URL in Settings before generating a sitemap.',
|
||||
message: 'Site rendering requires a public URL.',
|
||||
detail: 'Set Project → Public URL in Settings before rendering the site.',
|
||||
});
|
||||
throw new Error('Project public URL is not configured');
|
||||
}
|
||||
|
||||
const taskId = `sitemap-generate-${Date.now()}`;
|
||||
const taskTimestamp = Date.now();
|
||||
const taskGroupId = `site-render-${taskTimestamp}`;
|
||||
const taskGroupName = 'Render Site';
|
||||
const language = metadata?.mainLanguage?.trim() || 'en';
|
||||
const pageTitle = resolvePageTitle(metadata, project.name, project.description ?? undefined);
|
||||
const baseOptions = {
|
||||
projectId: project.id,
|
||||
projectName: metadata?.name?.trim() || project.name,
|
||||
projectDescription: metadata?.description,
|
||||
dataDir,
|
||||
baseUrl,
|
||||
maxPostsPerPage: metadata?.maxPostsPerPage,
|
||||
language,
|
||||
pageTitle,
|
||||
};
|
||||
|
||||
return taskManager.runTask({
|
||||
id: taskId,
|
||||
name: 'Generate Sitemap',
|
||||
const runSectionTask = async (
|
||||
section: BlogGenerationSection,
|
||||
taskName: string,
|
||||
taskIdPrefix: string,
|
||||
): Promise<BlogGenerationResult> => {
|
||||
return taskManager.runTask({
|
||||
id: `${taskIdPrefix}-${taskTimestamp}`,
|
||||
name: taskName,
|
||||
groupId: taskGroupId,
|
||||
groupName: taskGroupName,
|
||||
execute: async (onProgress) => {
|
||||
return blogGenerationEngine.generate({
|
||||
...baseOptions,
|
||||
sections: [section],
|
||||
}, (progress, message) => onProgress(progress, message || ''));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const mergeResults = (results: BlogGenerationResult[]): BlogGenerationResult => {
|
||||
const first = results[0];
|
||||
return {
|
||||
path: first.path,
|
||||
urlCount: Math.max(...results.map((result) => result.urlCount)),
|
||||
postCount: Math.max(...results.map((result) => result.postCount)),
|
||||
feedPostCount: Math.max(...results.map((result) => result.feedPostCount)),
|
||||
tagCount: Math.max(...results.map((result) => result.tagCount)),
|
||||
categoryCount: Math.max(...results.map((result) => result.categoryCount)),
|
||||
archiveCount: Math.max(...results.map((result) => result.archiveCount)),
|
||||
pagesGenerated: results.reduce((sum, result) => sum + result.pagesGenerated, 0),
|
||||
feeds: {
|
||||
rssPath: first.feeds.rssPath,
|
||||
atomPath: first.feeds.atomPath,
|
||||
},
|
||||
changed: {
|
||||
sitemap: results.some((result) => result.changed.sitemap),
|
||||
rss: results.some((result) => result.changed.rss),
|
||||
atom: results.some((result) => result.changed.atom),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const coreResult = await taskManager.runTask({
|
||||
id: `site-render-core-${taskTimestamp}`,
|
||||
name: 'Render Site Core',
|
||||
groupId: taskGroupId,
|
||||
groupName: taskGroupName,
|
||||
execute: async (onProgress) => {
|
||||
return blogGenerationEngine.generate({
|
||||
projectId: project.id,
|
||||
projectName: metadata?.name?.trim() || project.name,
|
||||
projectDescription: metadata?.description,
|
||||
dataDir,
|
||||
baseUrl,
|
||||
maxPostsPerPage: metadata?.maxPostsPerPage,
|
||||
...baseOptions,
|
||||
sections: ['core'],
|
||||
}, (progress, message) => onProgress(progress, message || ''));
|
||||
},
|
||||
});
|
||||
|
||||
const [singleResult, categoryResult, tagResult, dateResult] = await Promise.all([
|
||||
runSectionTask('single', 'Render Single Posts', 'site-render-single'),
|
||||
runSectionTask('category', 'Render Category Archives', 'site-render-category'),
|
||||
runSectionTask('tag', 'Render Tag Archives', 'site-render-tag'),
|
||||
runSectionTask('date', 'Render Date Archives', 'site-render-date'),
|
||||
]);
|
||||
|
||||
return mergeResults([coreResult, singleResult, categoryResult, tagResult, dateResult]);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user