Skip to content

Commit 9843a49

Browse files
authored
merge: pull request #230 from texonom/codex/refactor-data-export-and-enhance-visualization
feat: cli treemap & statistics export
2 parents d8980c7 + 671d266 commit 9843a49

File tree

4 files changed

+53
-14
lines changed

4 files changed

+53
-14
lines changed

packages/cli/src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ cli.runExit(process.argv.slice(2), Cli.defaultContext)
1616

1717
export * from './notion/export'
1818
export * from './notion/index'
19+
export * from './treemap'
20+
export * from './stats'

packages/cli/src/notion/export.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Option, Command } from 'clipanion'
22
import { NotionExporter } from './index'
3+
import { generateTreemaps, PageNode } from '../treemap'
4+
import { computeStats, writeStats } from '../stats'
35

46
export class NotionExportCommand extends Command {
57
static paths = [['export']]
@@ -38,6 +40,12 @@ export class NotionExportCommand extends Command {
3840
dataset = Option.Boolean('-d, --dataset', {
3941
description: 'Export as dataset for LLM learning'
4042
})
43+
treemap = Option.Boolean('--treemap', {
44+
description: 'Generate HTML treemap after export'
45+
})
46+
stats = Option.Boolean('--stats', {
47+
description: 'Generate statistics JSON after export'
48+
})
4149
token = Option.String('-t,--token', {
4250
description: 'Notion Access Token'
4351
})
@@ -59,5 +67,15 @@ export class NotionExportCommand extends Command {
5967
token: this.token
6068
})
6169
await exporter.execute()
70+
71+
if (this.treemap || this.stats) if (!exporter.pageTree) await exporter.loadRaw()
72+
73+
const tree = exporter.pageTree as unknown as PageNode
74+
if (this.treemap && tree) await generateTreemaps(this.folder, tree)
75+
76+
if (this.stats && tree) {
77+
const stats = computeStats(tree)
78+
await writeStats(`${this.folder}/stats.json`, stats)
79+
}
6280
}
6381
}

packages/cli/src/stats.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { PageNode } from './treemap'
2+
3+
export interface ExportStats {
4+
totalPages: number
5+
totalBlocks: number
6+
maxDepth: number
7+
}
8+
9+
export function computeStats(pageTree: PageNode): ExportStats {
10+
let totalPages = 0
11+
let totalBlocks = 0
12+
let maxDepth = 0
13+
14+
function traverse(node: PageNode, depth: number) {
15+
totalPages += node.pages || 0
16+
totalBlocks += node.blocks || 0
17+
if (depth > maxDepth) maxDepth = depth
18+
if (node.children) for (const child of node.children) traverse(child, depth + 1)
19+
}
20+
21+
traverse(pageTree, 1)
22+
return { totalPages, totalBlocks, maxDepth }
23+
}
24+
25+
export async function writeStats(file: string, stats: ExportStats) {
26+
const fs = await import('fs/promises')
27+
await fs.writeFile(file, JSON.stringify(stats, null, 2), 'utf8')
28+
}

packages/cli/src/treemap.ts

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,26 @@
11
import fs from 'fs'
22
import { promisify } from 'util'
3-
import { loadRaw } from './notion'
43

5-
const writeFile = promisify(fs.writeFile)
6-
7-
interface PageNode {
4+
export interface PageNode {
85
id: string
96
blocks: number
107
pages: number
118
title: string
129
children?: PageNode[]
1310
}
1411

15-
async function main() {
16-
const { pageTree } = await loadRaw('texonom-raw')
12+
const writeFile = promisify(fs.writeFile)
1713

18-
// Generate treemap for page counts
14+
export async function generateTreemaps(folder: string, pageTree: PageNode) {
1915
const treemapDataPages = computeMetrics(pageTree, 'pages')
2016
const titlePages = 'Texonom PageTree'
21-
const outputPathPages = 'texonom-raw/pagetree.html'
17+
const outputPathPages = `${folder}/pagetree.html`
2218
await generateTreemapHTML(treemapDataPages, titlePages, outputPathPages)
2319

24-
// Generate treemap for block counts
2520
const treemapDataBlocks = computeMetrics(pageTree, 'blocks')
2621
const titleBlocks = 'Texonom BlockMap'
27-
const outputPathBlocks = 'texonom-raw/blocktree.html'
22+
const outputPathBlocks = `${folder}/blocktree.html`
2823
await generateTreemapHTML(treemapDataBlocks, titleBlocks, outputPathBlocks)
29-
30-
console.info('Treemap HTML files generated successfully.')
3124
}
3225

3326
interface TreemapNode {
@@ -353,5 +346,3 @@ async function generateTreemapHTML(data: TreemapNode, title: string, outputPath:
353346

354347
await writeFile(outputPath, htmlContent, 'utf8')
355348
}
356-
357-
main().catch(error => console.error(error))

0 commit comments

Comments
 (0)