更新书签处理逻辑,生成用户自定义的 bookmarks.user.yml 配置文件
This commit is contained in:
62
.github/workflows/deploy.yml
vendored
62
.github/workflows/deploy.yml
vendored
@@ -53,21 +53,51 @@ jobs:
|
||||
|
||||
- name: Process bookmark file
|
||||
if: steps.check_bookmark_files.outputs.found == 'true'
|
||||
run: node src/bookmark-processor.js
|
||||
run: |
|
||||
echo "Processing bookmark files..."
|
||||
node src/bookmark-processor.js
|
||||
|
||||
- name: Debug directory contents
|
||||
if: steps.check_bookmark_files.outputs.found == 'true'
|
||||
run: |
|
||||
echo "Current directory contents:"
|
||||
ls -la
|
||||
echo "Does bookmarks.user.yml exist?"
|
||||
if [ -f bookmarks.user.yml ]; then
|
||||
echo "YES - bookmarks.user.yml exists"
|
||||
cat bookmarks.user.yml | head -n 10
|
||||
else
|
||||
echo "NO - bookmarks.user.yml does not exist"
|
||||
fi
|
||||
|
||||
- name: Commit bookmarks.yml changes
|
||||
- name: Commit bookmarks.user.yml changes
|
||||
if: steps.check_bookmark_files.outputs.found == 'true'
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action (Bookmarks)"
|
||||
# 检查 bookmarks.yml 是否真的被修改了
|
||||
if ! git diff --quiet bookmarks.yml; then
|
||||
echo "bookmarks.yml changed, committing..."
|
||||
git add bookmarks.yml
|
||||
git commit -m "Update bookmarks.yml from imported bookmarks"
|
||||
# 不需要push,因为构建步骤会使用当前工作区的内容
|
||||
|
||||
# Check if the file exists
|
||||
if [ -f bookmarks.user.yml ]; then
|
||||
# Check if file is already tracked by git
|
||||
if git ls-files --error-unmatch bookmarks.user.yml 2>/dev/null; then
|
||||
echo "bookmarks.user.yml exists and is tracked by git"
|
||||
# Check if it has changes
|
||||
if ! git diff --quiet bookmarks.user.yml; then
|
||||
echo "bookmarks.user.yml has changes, committing..."
|
||||
git add bookmarks.user.yml
|
||||
git commit -m "Update bookmarks.user.yml from imported bookmarks"
|
||||
else
|
||||
echo "No changes to bookmarks.user.yml"
|
||||
fi
|
||||
else
|
||||
echo "bookmarks.user.yml exists but is not tracked by git (new file)"
|
||||
git add bookmarks.user.yml
|
||||
git commit -m "Add bookmarks.user.yml from imported bookmarks"
|
||||
fi
|
||||
else
|
||||
echo "No changes to bookmarks.yml"
|
||||
echo "ERROR: bookmarks.user.yml does not exist! Bookmark processing may have failed."
|
||||
echo "Current directory contents:"
|
||||
ls -la
|
||||
fi
|
||||
|
||||
- name: Clean up processed bookmark files
|
||||
@@ -97,6 +127,20 @@ jobs:
|
||||
# 使用 GITHUB_TOKEN 推送
|
||||
if: steps.check_bookmark_files.outputs.found == 'true'
|
||||
run: |
|
||||
echo "Checking git status before pushing..."
|
||||
git status
|
||||
|
||||
echo "Checking bookmarks.user.yml existence before pushing..."
|
||||
if [ -f bookmarks.user.yml ]; then
|
||||
echo "bookmarks.user.yml exists with content:"
|
||||
ls -la bookmarks.user.yml
|
||||
echo "First 5 lines:"
|
||||
head -n 5 bookmarks.user.yml
|
||||
else
|
||||
echo "WARNING: bookmarks.user.yml does not exist before pushing!"
|
||||
fi
|
||||
|
||||
echo "Pushing changes to repository..."
|
||||
git push "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" HEAD:${{ github.ref_name }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
16
README.md
16
README.md
@@ -206,14 +206,15 @@ npm run dev
|
||||
- 系统会扫描 `bookmarks` 目录,查找最新的HTML书签文件
|
||||
- 解析书签文件中的链接和文件夹结构
|
||||
- 自动为书签分配适当的图标
|
||||
- 生成 `bookmarks.yml` 配置文件
|
||||
- 生成 `bookmarks.user.yml` 配置文件(而不是直接修改 `bookmarks.yml`)
|
||||
- 处理完成后会自动清空 `bookmarks` 目录(防止重复处理)
|
||||
- 重新构建并部署网站
|
||||
|
||||
4. **注意事项**
|
||||
- 每次只处理一个书签文件,如有多个文件,系统会选择最新的那个
|
||||
- 书签导入是构建时的一次性操作,不会在浏览器中保存或同步您的书签
|
||||
- 如果想要更新书签,可以直接编辑 `bookmarks.yml`,或重新导出书签文件并重新导入
|
||||
- 如果想要更新书签,可以直接编辑 `bookmarks.user.yml`,或重新导出书签文件并重新导入
|
||||
- 系统会优先使用 `bookmarks.user.yml`,如果同时存在 `bookmarks.yml`,它们的内容会被合并(用户配置优先)
|
||||
|
||||
### 自动化工作流程详解
|
||||
|
||||
@@ -226,7 +227,7 @@ MeNav使用单一的GitHub Actions工作流处理书签导入与网站部署,
|
||||
2. **书签处理步骤**:
|
||||
- 自动检测 `bookmarks` 目录中的HTML文件
|
||||
- 使用 `bookmark-processor.js` 脚本处理书签文件
|
||||
- 生成/更新 `bookmarks.yml` 配置文件
|
||||
- 生成/更新 `bookmarks.user.yml` 配置文件
|
||||
- 提交更改(如有)并保存至仓库
|
||||
- 自动清理已处理的HTML书签文件
|
||||
|
||||
@@ -241,10 +242,10 @@ MeNav使用单一的GitHub Actions工作流处理书签导入与网站部署,
|
||||
|
||||
### 书签配置自定义
|
||||
|
||||
处理后生成的 `bookmarks.yml` 文件可以手动编辑以进一步自定义:
|
||||
处理后生成的 `bookmarks.user.yml` 文件可以手动编辑以进一步自定义:
|
||||
|
||||
```yaml
|
||||
# 自动生成的书签配置示例
|
||||
# 自动生成的书签配置示例(用户自定义版本)
|
||||
title: 我的书签
|
||||
subtitle: 从浏览器导入的书签收藏
|
||||
categories:
|
||||
@@ -265,7 +266,10 @@ categories:
|
||||
- 重新组织书签分类结构
|
||||
- 添加或删除特定书签
|
||||
|
||||
**提示**: 尽管自动处理会清理原始HTML文件,但修改后的 `bookmarks.yml` 会被保留,您可以随时手动编辑它来更新书签内容。
|
||||
**提示**:
|
||||
- 尽管自动处理会清理原始HTML文件,但修改后的 `bookmarks.user.yml` 会被保留,您可以随时手动编辑它来更新书签内容
|
||||
- 如果项目中同时存在 `bookmarks.yml` 和 `bookmarks.user.yml`,系统会合并两者的内容,以 `bookmarks.user.yml` 中的配置为优先
|
||||
- 这种设计允许您在更新源仓库时保留自己的书签配置
|
||||
|
||||
### 模板说明
|
||||
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
git push
|
||||
```
|
||||
|
||||
4. GitHub Actions将自动处理书签文件,生成`bookmarks.yml`,并重新构建站点
|
||||
4. GitHub Actions将自动处理书签文件,生成`bookmarks.user.yml`,并重新构建站点
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 仅支持标准HTML格式的书签文件
|
||||
- 每次只会处理目录中最新的一个书签文件
|
||||
- 处理完成后,书签文件会被自动清除,以防止重复处理
|
||||
- 已导入的书签可以在生成的`bookmarks.yml`文件中查看和编辑
|
||||
- 已导入的书签可以在生成的`bookmarks.user.yml`文件中查看和编辑
|
||||
- 系统会优先使用`bookmarks.user.yml`的配置,如果存在`bookmarks.yml`,会自动合并两者的内容(用户配置优先)
|
||||
@@ -2,10 +2,12 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
// 书签文件夹路径
|
||||
const BOOKMARKS_DIR = path.join(__dirname, '..', 'bookmarks');
|
||||
// 输出配置文件路径
|
||||
const OUTPUT_FILE = path.join(__dirname, '..', 'bookmarks.yml');
|
||||
// 书签文件夹路径 - 使用相对路径
|
||||
const BOOKMARKS_DIR = 'bookmarks';
|
||||
// 输出配置文件路径 - 使用相对路径
|
||||
const OUTPUT_FILE = 'bookmarks.user.yml';
|
||||
// 默认书签配置文件路径 - 使用相对路径
|
||||
const DEFAULT_BOOKMARKS_FILE = 'bookmarks.yml';
|
||||
|
||||
// 图标映射,根据URL关键字匹配合适的图标
|
||||
const ICON_MAPPING = {
|
||||
@@ -191,9 +193,10 @@ function generateBookmarksYaml(bookmarks) {
|
||||
|
||||
// 添加注释
|
||||
const yamlWithComment =
|
||||
`# 自动生成的书签配置文件 - 请勿手动编辑
|
||||
`# 自动生成的书签配置文件 - 用户自定义版本
|
||||
# 由bookmark-processor.js生成于 ${new Date().toISOString()}
|
||||
# 若要更新,请将新的书签HTML文件放入bookmarks/目录
|
||||
# 注意:此文件会覆盖bookmarks.yml中的同名配置
|
||||
|
||||
${yamlString}`;
|
||||
|
||||
@@ -206,8 +209,8 @@ ${yamlString}`;
|
||||
|
||||
// 更新现有config.yml中的导航,添加书签页面
|
||||
function updateConfigWithBookmarks() {
|
||||
const configFile = path.join(__dirname, '..', 'config.yml');
|
||||
const userConfigFile = path.join(__dirname, '..', 'config.user.yml');
|
||||
const configFile = 'config.yml';
|
||||
const userConfigFile = 'config.user.yml';
|
||||
|
||||
// 优先使用用户配置文件,如果存在
|
||||
const targetConfigFile = fs.existsSync(userConfigFile) ? userConfigFile : configFile;
|
||||
@@ -245,6 +248,10 @@ function updateConfigWithBookmarks() {
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
console.log('Starting bookmark processing...');
|
||||
console.log(`Current working directory: ${process.cwd()}`);
|
||||
console.log(`Output file will be: ${OUTPUT_FILE} (absolute: ${path.resolve(OUTPUT_FILE)})`);
|
||||
|
||||
// 获取最新的书签文件
|
||||
const bookmarkFile = getLatestBookmarkFile();
|
||||
if (!bookmarkFile) {
|
||||
@@ -254,21 +261,67 @@ async function main() {
|
||||
|
||||
try {
|
||||
// 读取文件内容
|
||||
console.log(`Reading bookmark file: ${bookmarkFile}`);
|
||||
const htmlContent = fs.readFileSync(bookmarkFile, 'utf8');
|
||||
|
||||
// 解析书签
|
||||
const bookmarks = parseBookmarks(htmlContent);
|
||||
console.log(`Found ${bookmarks.categories.length} categories with bookmarks`);
|
||||
if (bookmarks.categories.length === 0) {
|
||||
console.error('ERROR: No bookmark categories found in the HTML file. Processing aborted.');
|
||||
return;
|
||||
}
|
||||
console.log('Categories found:');
|
||||
bookmarks.categories.forEach(cat => {
|
||||
console.log(`- ${cat.name}: ${cat.sites.length} sites`);
|
||||
});
|
||||
|
||||
// 生成YAML
|
||||
const yaml = generateBookmarksYaml(bookmarks);
|
||||
if (yaml) {
|
||||
if (!yaml) {
|
||||
console.error('ERROR: Failed to generate YAML from bookmarks. Processing aborted.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示将要写入的YAML前几行
|
||||
console.log('Generated YAML preview (first 5 lines):');
|
||||
console.log(yaml.split('\n').slice(0, 5).join('\n') + '\n...');
|
||||
|
||||
try {
|
||||
// 确保目标目录存在
|
||||
const outputDir = path.dirname(OUTPUT_FILE);
|
||||
if (!fs.existsSync(outputDir) && outputDir !== '.') {
|
||||
console.log(`Creating output directory: ${outputDir}`);
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 保存YAML文件
|
||||
console.log(`Writing to: ${OUTPUT_FILE}`);
|
||||
fs.writeFileSync(OUTPUT_FILE, yaml, 'utf8');
|
||||
console.log(`Saved bookmarks configuration to ${OUTPUT_FILE}`);
|
||||
|
||||
// 验证文件是否确实被创建
|
||||
if (fs.existsSync(OUTPUT_FILE)) {
|
||||
const stats = fs.statSync(OUTPUT_FILE);
|
||||
console.log(`Successfully saved bookmarks configuration to ${OUTPUT_FILE}`);
|
||||
console.log(`Verified file exists: ${OUTPUT_FILE}`);
|
||||
console.log(`File size: ${stats.size} bytes`);
|
||||
console.log(`File permissions: ${stats.mode.toString(8)}`);
|
||||
|
||||
// 列出当前目录内容以确认
|
||||
console.log('Current directory contains:');
|
||||
fs.readdirSync('.').forEach(file => {
|
||||
console.log(`- ${file}`);
|
||||
});
|
||||
} else {
|
||||
console.error(`ERROR: File was not created: ${OUTPUT_FILE}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 更新导航
|
||||
updateConfigWithBookmarks();
|
||||
} catch (writeError) {
|
||||
console.error(`ERROR writing file ${OUTPUT_FILE}:`, writeError);
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing bookmark file:', error);
|
||||
|
||||
@@ -17,40 +17,45 @@ function escapeHtml(unsafe) {
|
||||
|
||||
// 读取配置文件
|
||||
function loadConfig() {
|
||||
let config = {};
|
||||
let config = null;
|
||||
|
||||
// 读取默认配置
|
||||
try {
|
||||
const defaultConfigFile = fs.readFileSync('config.yml', 'utf8');
|
||||
config = yaml.load(defaultConfigFile);
|
||||
} catch (e) {
|
||||
console.error('Error loading default config file:', e);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 尝试读取用户配置并合并
|
||||
try {
|
||||
// 优先尝试读取用户配置
|
||||
if (fs.existsSync('config.user.yml')) {
|
||||
const userConfigFile = fs.readFileSync('config.user.yml', 'utf8');
|
||||
const userConfig = yaml.load(userConfigFile);
|
||||
// 深度合并配置,用户配置优先
|
||||
config = mergeConfigs(config, userConfig);
|
||||
config = yaml.load(userConfigFile);
|
||||
console.log('Using user configuration from config.user.yml');
|
||||
} else {
|
||||
}
|
||||
// 如果没有用户配置,则使用默认配置
|
||||
else {
|
||||
const defaultConfigFile = fs.readFileSync('config.yml', 'utf8');
|
||||
config = yaml.load(defaultConfigFile);
|
||||
console.log('No user configuration found, using default config.yml');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading user config file:', e);
|
||||
console.log('Falling back to default configuration');
|
||||
console.error('Error loading configuration file:', e);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 尝试读取书签配置并合并
|
||||
// 尝试读取书签配置
|
||||
try {
|
||||
if (fs.existsSync('bookmarks.yml')) {
|
||||
let bookmarksConfig = null;
|
||||
|
||||
// 优先尝试读取用户书签配置
|
||||
if (fs.existsSync('bookmarks.user.yml')) {
|
||||
const userBookmarksFile = fs.readFileSync('bookmarks.user.yml', 'utf8');
|
||||
bookmarksConfig = yaml.load(userBookmarksFile);
|
||||
console.log('Using user bookmarks configuration from bookmarks.user.yml');
|
||||
}
|
||||
// 如果没有用户书签配置,则尝试读取默认书签配置
|
||||
else if (fs.existsSync('bookmarks.yml')) {
|
||||
const bookmarksFile = fs.readFileSync('bookmarks.yml', 'utf8');
|
||||
const bookmarksConfig = yaml.load(bookmarksFile);
|
||||
|
||||
// 添加书签页面配置
|
||||
bookmarksConfig = yaml.load(bookmarksFile);
|
||||
console.log('Using default bookmarks configuration from bookmarks.yml');
|
||||
}
|
||||
|
||||
// 添加书签页面配置
|
||||
if (bookmarksConfig) {
|
||||
config.bookmarks = bookmarksConfig;
|
||||
|
||||
// 确保导航中有书签页面
|
||||
@@ -63,8 +68,6 @@ function loadConfig() {
|
||||
active: false
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Loaded bookmarks configuration from bookmarks.yml');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading bookmarks configuration:', e);
|
||||
@@ -73,23 +76,6 @@ function loadConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
// 深度合并配置对象
|
||||
function mergeConfigs(defaultConfig, userConfig) {
|
||||
if (!userConfig) return defaultConfig;
|
||||
|
||||
const merged = { ...defaultConfig };
|
||||
|
||||
for (const key in userConfig) {
|
||||
if (typeof userConfig[key] === 'object' && !Array.isArray(userConfig[key])) {
|
||||
merged[key] = mergeConfigs(defaultConfig[key] || {}, userConfig[key]);
|
||||
} else {
|
||||
merged[key] = userConfig[key];
|
||||
}
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
// 生成导航菜单
|
||||
function generateNavigation(navigation) {
|
||||
return navigation.map(nav => `
|
||||
|
||||
Reference in New Issue
Block a user