Skip to content

Commit 556e842

Browse files
CopilotTechQuery
andcommitted
Changes before error encountered
Co-authored-by: TechQuery <19969570+TechQuery@users.noreply.github.com>
1 parent d8b3ead commit 556e842

5 files changed

Lines changed: 289 additions & 343 deletions

File tree

models/Wiki.ts

Lines changed: 128 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,146 @@
1-
import { Issue, RepositoryModel } from 'mobx-github';
2-
import { Filter, ListModel } from 'mobx-restful';
3-
import { buildURLData } from 'web-utility';
4-
5-
import { githubClient, GithubSearchData, makeGithubSearchCondition } from './Base';
1+
import { marked } from 'marked';
2+
import { treeFrom } from 'web-utility';
3+
import * as fs from 'fs';
4+
import * as path from 'path';
65

76
export interface WikiNode {
8-
id: number;
7+
name?: string;
98
title: string;
10-
body: string;
11-
html_url: string;
12-
created_at: string;
13-
updated_at: string;
14-
labels: string[];
15-
number: number;
16-
repository?: {
17-
name: string;
18-
full_name: string;
19-
};
9+
path: string;
10+
parent_path?: string;
11+
children?: WikiNode[];
12+
type?: string;
13+
size?: number;
14+
sha?: string;
15+
url?: string;
16+
html_url?: string;
17+
git_url?: string;
18+
download_url?: string;
19+
// Frontmatter fields
20+
metadata?: Record<string, string>;
21+
content?: string;
2022
}
2123

22-
export type WikiFilter = Filter<WikiNode>;
24+
export class WikiModel {
25+
// For now, only use filesystem reading for simplicity
2326

24-
export class WikiModel extends ListModel<WikiNode, WikiFilter> {
25-
baseURI = 'search/issues';
26-
client = githubClient;
27+
// Method for build-time static generation
28+
async getAllContentStatic(): Promise<WikiNode[]> {
29+
const items: WikiNode[] = [];
30+
const policyDir = path.join(process.cwd(), 'public/wiki/policy/China/政策');
31+
32+
if (!fs.existsSync(policyDir)) {
33+
return items;
34+
}
2735

28-
async loadPage(
29-
page = this.pageIndex,
30-
per_page = this.pageSize,
31-
filter: WikiFilter = {},
32-
) {
33-
// Search for issues labeled as 'wiki' or 'policy' in the Open-Source-Bazaar organization
34-
const searchQuery = [
35-
'org:Open-Source-Bazaar',
36-
'is:issue',
37-
'label:wiki OR label:policy',
38-
'state:open',
39-
].join(' ');
36+
const processDirectory = (dir: string, baseDir: string = '') => {
37+
const files = fs.readdirSync(dir);
38+
39+
for (const file of files) {
40+
const fullPath = path.join(dir, file);
41+
const stat = fs.statSync(fullPath);
42+
43+
if (stat.isDirectory()) {
44+
const subDir = baseDir ? `${baseDir}/${file}` : file;
45+
processDirectory(fullPath, subDir);
46+
} else if (file.endsWith('.md')) {
47+
const relativePath = baseDir ? `${baseDir}/${file}` : file;
48+
const pathParts = relativePath.split('/');
49+
const fileName = pathParts.pop();
50+
const parent_path = pathParts.length > 0 ? pathParts.join('/') : undefined;
51+
52+
const wikiNode: WikiNode = {
53+
name: fileName || '',
54+
path: relativePath.replace('.md', ''),
55+
parent_path,
56+
title: fileName?.replace('.md', '') || '',
57+
type: 'file',
58+
size: stat.size,
59+
sha: '',
60+
url: '',
61+
html_url: `https://github.com/fpsig/open-source-policy/blob/main/China/政策/${relativePath}`,
62+
git_url: '',
63+
download_url: `https://raw.githubusercontent.com/fpsig/open-source-policy/main/China/政策/${relativePath}`,
64+
content: '',
65+
};
66+
67+
items.push(wikiNode);
68+
}
69+
}
70+
};
4071

41-
const { body } = await this.client.get<GithubSearchData<Issue>>(
42-
`${this.baseURI}?${buildURLData({
43-
page,
44-
per_page,
45-
q: searchQuery,
46-
sort: 'updated',
47-
order: 'desc'
48-
})}`,
49-
);
72+
processDirectory(policyDir);
73+
return items;
74+
}
5075

51-
const items: WikiNode[] = body!.items.map(issue => ({
52-
id: issue.id,
53-
title: issue.title,
54-
body: issue.body || '',
55-
html_url: issue.html_url,
56-
created_at: issue.created_at,
57-
updated_at: issue.updated_at,
58-
labels: issue.labels.map(label => typeof label === 'string' ? label : label.name || ''),
59-
number: issue.number,
60-
repository: issue.repository ? {
61-
name: issue.repository.name,
62-
full_name: issue.repository.full_name,
63-
} : undefined,
64-
}));
76+
// Method for all environments - use static reading
77+
async getAllContent(): Promise<WikiNode[]> {
78+
return this.getAllContentStatic();
79+
}
6580

66-
return { pageData: items, totalCount: body!.total_count };
81+
async getContentTree(): Promise<WikiNode[]> {
82+
const allContent = await this.getAllContent();
83+
return treeFrom(allContent, 'path', 'parent_path', 'children');
6784
}
6885

69-
async getAll(): Promise<WikiNode[]> {
70-
const { pageData } = await this.loadPage(1, 100);
71-
return pageData;
86+
async getOne(path: string): Promise<WikiNode> {
87+
return this.getOneStatic(path);
7288
}
7389

74-
async getOne(id: string | number): Promise<WikiNode> {
75-
const all = await this.getAll();
76-
const found = all.find(item => item.id.toString() === id.toString() || item.number.toString() === id.toString());
77-
if (!found) {
78-
throw new Error(`Wiki node with id ${id} not found`);
90+
// Static method for build-time reading
91+
async getOneStatic(pathParam: string): Promise<WikiNode> {
92+
const fullPath = pathParam.endsWith('.md') ? pathParam : `${pathParam}.md`;
93+
const filePath = path.join(process.cwd(), 'public/wiki/policy/China/政策', fullPath);
94+
95+
if (!fs.existsSync(filePath)) {
96+
throw new Error(`Content not found at path: ${pathParam}`);
7997
}
80-
return found;
98+
99+
const fileContent = fs.readFileSync(filePath, 'utf-8');
100+
const stat = fs.statSync(filePath);
101+
102+
// Parse frontmatter
103+
let metadata: Record<string, string> = {};
104+
let markdownContent = '';
105+
106+
if (fileContent.startsWith('---\n')) {
107+
const parts = fileContent.split('\n---\n');
108+
if (parts.length >= 2) {
109+
const frontmatter = parts[0].substring(4); // Remove first '---\n'
110+
markdownContent = parts.slice(1).join('\n---\n');
111+
112+
// Simple YAML parsing for metadata
113+
const lines = frontmatter.split('\n');
114+
for (const line of lines) {
115+
const [key, ...valueParts] = line.split(': ');
116+
if (key && valueParts.length > 0) {
117+
metadata[key.trim()] = valueParts.join(': ').trim();
118+
}
119+
}
120+
}
121+
} else {
122+
markdownContent = fileContent;
123+
}
124+
125+
const pathParts = pathParam.split('/');
126+
const fileName = pathParts.pop();
127+
const parent_path = pathParts.length > 0 ? pathParts.join('/') : undefined;
128+
129+
return {
130+
name: fileName || '',
131+
path: pathParam.replace('.md', ''),
132+
parent_path,
133+
title: metadata['name'] || fileName?.replace('.md', '') || '',
134+
type: 'file',
135+
size: stat.size,
136+
sha: '',
137+
url: '',
138+
html_url: `https://github.com/fpsig/open-source-policy/blob/main/China/政策/${fullPath}`,
139+
git_url: '',
140+
download_url: `https://raw.githubusercontent.com/fpsig/open-source-policy/main/China/政策/${fullPath}`,
141+
content: markdownContent,
142+
metadata,
143+
};
81144
}
82145
}
83146

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@next/mdx": "^15.5.0",
1919
"core-js": "^3.45.1",
2020
"file-type": "^21.0.0",
21+
"github-markdown-css": "^5.8.1",
2122
"idea-react": "^2.0.0-rc.13",
2223
"koa": "^3.0.1",
2324
"koajax": "^3.1.2",

0 commit comments

Comments
 (0)