新增主题信息获取功能,完善 Discourse 同步机制

- 在 DiscourseAPI 中添加 fetchTopicInfo 和 fetchTopicTags 方法
- 更新发布流程,支持从 Discourse 同步最新标签和分类信息
- 在更新帖子时自动获取并同步 Discourse 上的标签和分类
- 扩展 Front Matter,新增 discourse_category_id 和 discourse_category 字段
- 优化更新逻辑,确保本地文件与 Discourse 内容保持一致
This commit is contained in:
wood chen 2025-03-10 20:09:08 +08:00
parent 53d30650b5
commit d6221a4f91
2 changed files with 85 additions and 3 deletions

View File

@ -387,4 +387,46 @@ export class DiscourseAPI {
};
}
}
// 获取特定主题的标签和分类信息
async fetchTopicInfo(topicId: number): Promise<{ tags: string[], categoryId?: number }> {
try {
const url = `${this.settings.baseUrl}/t/${topicId}.json`;
const headers = {
"Api-Key": this.settings.apiKey,
"Api-Username": this.settings.disUser,
};
const response = await requestUrl({
url,
method: "GET",
headers,
throw: false
});
if (response.status === 200) {
const data = response.json;
return {
tags: data?.tags || [],
categoryId: data?.category_id
};
}
return { tags: [] };
} catch (error) {
new NotifyUser(this.app, `Exception while fetching topic info: ${error}`).open();
return { tags: [] };
}
}
// 获取特定主题的标签
async fetchTopicTags(topicId: number): Promise<string[]> {
try {
const topicInfo = await this.fetchTopicInfo(topicId);
return topicInfo.tags;
} catch (error) {
new NotifyUser(this.app, `Exception while fetching topic tags: ${error}`).open();
return [];
}
}
}

View File

@ -94,12 +94,15 @@ export default class PublishToDiscourse extends Plugin implements PluginInterfac
// 使用expandEmbeds处理嵌入内容
const content = await expandEmbeds(this.app, targetFile);
const fm = getFrontMatter(content);
const postId = fm?.discourse_post_id;
const topicId = fm?.discourse_topic_id;
const isUpdate = postId !== undefined && topicId !== undefined;
// 初始化activeFile对象
this.activeFile = {
name: targetFile.basename,
content: content,
postId: fm?.discourse_post_id,
postId: postId,
// 从frontmatter中获取标签如果没有则使用空数组
tags: fm?.discourse_tags || []
};
@ -110,6 +113,32 @@ export default class PublishToDiscourse extends Plugin implements PluginInterfac
this.api.fetchTags()
]);
// 如果是更新帖子先从Discourse获取最新标签和分类
if (isUpdate) {
try {
const topicInfo = await this.api.fetchTopicInfo(topicId);
// 用Discourse上的标签覆盖本地标签
if (topicInfo.tags.length > 0) {
this.activeFile.tags = topicInfo.tags;
console.log(`Updated tags from Discourse: ${topicInfo.tags.join(', ')}`);
}
// 如果获取到了分类ID更新设置中的分类
if (topicInfo.categoryId) {
// 查找分类名称
const category = categories.find(c => c.id === topicInfo.categoryId);
if (category) {
this.settings.category = category.id;
console.log(`Updated category from Discourse: ${category.name} (${category.id})`);
}
}
} catch (error) {
console.error("Failed to fetch topic info from Discourse:", error);
// 如果获取失败,继续使用本地标签和分类
}
}
if (categories.length > 0) {
new SelectCategoryModal(this.app, this, categories, tags).open();
}
@ -219,6 +248,13 @@ export default class PublishToDiscourse extends Plugin implements PluginInterfac
const fm = getFrontMatter(content);
const discourseUrl = `${this.settings.baseUrl}/t/${topicId}`;
// 获取当前分类信息
const categoryId = this.settings.category;
// 查找分类名称
const categories = await this.api.fetchCategories();
const category = categories.find(c => c.id === categoryId);
const categoryName = category ? category.name : '';
let newContent: string;
if (fm) {
// 更新现有Front Matter
@ -227,7 +263,9 @@ export default class PublishToDiscourse extends Plugin implements PluginInterfac
discourse_post_id: postId,
discourse_topic_id: topicId,
discourse_url: discourseUrl,
discourse_tags: tags
discourse_tags: tags,
discourse_category_id: categoryId,
discourse_category: categoryName
};
newContent = content.replace(/^---\n[\s\S]*?\n---\n/, `---\n${yaml.stringify(updatedFm)}---\n`);
} else {
@ -236,7 +274,9 @@ export default class PublishToDiscourse extends Plugin implements PluginInterfac
discourse_post_id: postId,
discourse_topic_id: topicId,
discourse_url: discourseUrl,
discourse_tags: tags
discourse_tags: tags,
discourse_category_id: categoryId,
discourse_category: categoryName
};
newContent = `---\n${yaml.stringify(newFm)}---\n${content}`;
}