diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7031058..b490b8f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -36,22 +36,19 @@ jobs: - name: Install dependencies run: npm install - # --- 书签处理步骤开始 --- - - name: Create bookmarks directory if not exists - run: mkdir -p bookmarks - - - name: Check for bookmark files + # --- 书签处理步骤 --- + - name: Check for bookmark HTML files id: check_bookmark_files run: | - if [ "$(find bookmarks -type f -name "*.html" 2>/dev/null)" ]; then + if [ -d bookmarks ] && [ "$(find bookmarks -type f -name "*.html" 2>/dev/null)" ]; then echo "found=true" >> $GITHUB_OUTPUT - echo "Found bookmark files to process" + echo "Bookmark HTML files found, will process them." else echo "found=false" >> $GITHUB_OUTPUT - echo "No bookmark files found" + echo "No bookmark HTML files found, skipping bookmark processing." fi - - - name: Process bookmark file + + - name: Process bookmark files if: steps.check_bookmark_files.outputs.found == 'true' run: | echo "Processing bookmark files..." @@ -62,42 +59,57 @@ jobs: 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 + echo "Checking config/user/pages directory:" + if [ -d config/user/pages ]; then + echo "Directory exists, listing contents:" + ls -la config/user/pages/ + if [ -f config/user/pages/bookmarks.yml ]; then + echo "✓ bookmarks.yml exists in config/user/pages/" + cat config/user/pages/bookmarks.yml | head -n 10 + else + echo "✗ bookmarks.yml does not exist in config/user/pages/" + fi else - echo "NO - bookmarks.user.yml does not exist" + echo "✗ config/user/pages directory does not exist" fi - - name: Commit bookmarks.user.yml changes + - name: Commit bookmark configuration 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)" - # 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 config/user/pages/bookmarks.yml exists + if [ -f config/user/pages/bookmarks.yml ]; then + # Check if this is a new file or it has changes + if git ls-files --error-unmatch config/user/pages/bookmarks.yml 2>/dev/null; then + echo "config/user/pages/bookmarks.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" + if ! git diff --quiet config/user/pages/bookmarks.yml; then + echo "config/user/pages/bookmarks.yml has changes, committing..." + git add config/user/pages/bookmarks.yml + git commit -m "Update bookmarks configuration from imported bookmarks" else - echo "No changes to bookmarks.user.yml" + echo "No changes to bookmarks configuration" 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" + echo "config/user/pages/bookmarks.yml exists but is not tracked by git (new file)" + git add config/user/pages/bookmarks.yml + git commit -m "Add bookmarks configuration from imported bookmarks" + fi + + # Also check for navigation file changes + if [ -f config/user/navigation.yml ]; then + if ! git diff --quiet config/user/navigation.yml; then + echo "config/user/navigation.yml has changes, committing..." + git add config/user/navigation.yml + git commit -m "Update navigation to include bookmarks page" + fi fi else - echo "ERROR: bookmarks.user.yml does not exist! Bookmark processing may have failed." + echo "ERROR: config/user/pages/bookmarks.yml does not exist! Bookmark processing may have failed." echo "Current directory contents:" - ls -la + ls -la config/user/pages/ || echo "Directory does not exist" fi - name: Clean up processed bookmark files @@ -130,14 +142,12 @@ jobs: 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 + echo "Checking config/user/pages directory before pushing..." + if [ -d config/user/pages ]; then + echo "✓ config/user/pages directory exists" + ls -la config/user/pages/ else - echo "WARNING: bookmarks.user.yml does not exist before pushing!" + echo "✗ WARNING: config/user/pages directory does not exist before pushing!" fi echo "Pushing changes to repository..." diff --git a/bookmarks.yml b/bookmarks.yml deleted file mode 100644 index e2d97aa..0000000 --- a/bookmarks.yml +++ /dev/null @@ -1,79 +0,0 @@ -# 自动生成的书签配置文件 - 请勿手动编辑 -# 由bookmark-processor.js生成于 2025-05-01T13:43:27.486Z -# 若要更新,请将新的书签HTML文件放入bookmarks/目录 - -title: 我的书签 -subtitle: 从浏览器导入的书签收藏 -categories: - - name: 技术资源 - icon: fas fa-folder - sites: - - name: GitHub - url: https://github.com/ - icon: fab fa-github - description: "从书签导入: GitHub" - - name: Stack Overflow - url: https://stackoverflow.com/ - icon: fab fa-stack-overflow - description: "从书签导入: Stack Overflow" - - name: MDN Web Docs - url: https://developer.mozilla.org/ - icon: fas fa-link - description: "从书签导入: MDN Web Docs" - - name: freeCodeCamp - url: https://www.freecodecamp.org/ - icon: fas fa-link - description: "从书签导入: freeCodeCamp" - - name: LeetCode - url: https://leetcode.com/ - icon: fas fa-link - description: "从书签导入: LeetCode" - - name: 社交媒体 - icon: fas fa-folder - sites: - - name: Twitter - url: https://twitter.com/ - icon: fab fa-twitter - description: "从书签导入: Twitter" - - name: LinkedIn - url: https://www.linkedin.com/ - icon: fab fa-linkedin - description: "从书签导入: LinkedIn" - - name: Reddit - url: https://www.reddit.com/ - icon: fab fa-reddit - description: "从书签导入: Reddit" - - name: Instagram - url: https://www.instagram.com/ - icon: fab fa-instagram - description: "从书签导入: Instagram" - - name: 新闻与资讯 - icon: fas fa-folder - sites: - - name: Hacker News - url: https://news.ycombinator.com/ - icon: fas fa-link - description: "从书签导入: Hacker News" - - name: TechCrunch - url: https://techcrunch.com/ - icon: fas fa-link - description: "从书签导入: TechCrunch" - - name: The Verge - url: https://www.theverge.com/ - icon: fas fa-link - description: "从书签导入: The Verge" - - name: 工具 - icon: fas fa-folder - sites: - - name: Notion - url: https://www.notion.so/ - icon: fas fa-link - description: "从书签导入: Notion" - - name: Trello - url: https://trello.com/ - icon: fab fa-trello - description: "从书签导入: Trello" - - name: Figma - url: https://www.figma.com/ - icon: fas fa-link - description: "从书签导入: Figma" diff --git a/config.yml b/config.yml deleted file mode 100644 index e099835..0000000 --- a/config.yml +++ /dev/null @@ -1,297 +0,0 @@ -site: - title: 我的导航 - description: 个人网络导航站 - author: Your Name - favicon: favicon.ico - logo_text: 导航站 -fonts: - title: - family: Poppins - weight: 600 - source: google - subtitle: - family: Quicksand - weight: 500 - source: google - body: - family: Noto Sans SC - weight: 400 - source: google -profile: - title: Hello, - subtitle: Welcome to My Navigation - description: 导航菜单 -navigation: - - name: 首页 - icon: fas fa-home - id: home - active: true - - name: 项目 - icon: fas fa-project-diagram - id: projects - - name: 文章 - icon: fas fa-book - id: articles - - name: 朋友 - icon: fas fa-users - id: friends - - name: 书签 - icon: fas fa-bookmark - id: bookmarks -social: - - name: GitHub - url: https://github.com - icon: fab fa-github - - name: Telegram - url: https://t.me - icon: fab fa-telegram - - name: Twitter - url: https://twitter.com - icon: fab fa-twitter - - name: Steam - url: https://steam.com - icon: fab fa-steam -categories: - - name: 常用网站 - icon: fas fa-star - sites: - - name: Linux.do - url: https://linux.do/ - icon: fab fa-linux - description: 新的理想型社区 - - name: Google - url: https://www.google.com - icon: fab fa-google - description: 全球最大的搜索引擎 - - name: GitHub - url: https://www.github.com - icon: fab fa-github - description: 代码托管平台 - - name: Stack Overflow - url: https://stackoverflow.com - icon: fab fa-stack-overflow - description: 程序员问答社区 - - name: ChatGPT - url: https://chat.openai.com - icon: fas fa-robot - description: AI智能助手 - - name: 学习资源 - icon: fas fa-graduation-cap - sites: - - name: 哔哩哔哩 - url: https://www.bilibili.com - icon: fas fa-play-circle - description: 视频学习平台 - - name: 知乎 - url: https://www.zhihu.com - icon: fas fa-question-circle - description: 问答社区 - - name: 掘金 - url: https://juejin.cn - icon: fas fa-book - description: 高质量技术社区 - - name: LeetCode - url: https://leetcode.cn - icon: fas fa-code - description: 算法刷题平台 - - name: 开发工具 - icon: fas fa-tools - sites: - - name: VS Code - url: https://code.visualstudio.com - icon: fas fa-code - description: 强大的代码编辑器 - - name: Postman - url: https://www.postman.com - icon: fas fa-paper-plane - description: API调试工具 - - name: Git - url: https://git-scm.com - icon: fab fa-git-alt - description: 版本控制工具 - - name: Docker - url: https://www.docker.com - icon: fab fa-docker - description: 容器化平台 - - name: 设计资源 - icon: fas fa-palette - sites: - - name: Figma - url: https://www.figma.com - icon: fab fa-figma - description: 在线设计工具 - - name: Dribbble - url: https://dribbble.com - icon: fab fa-dribbble - description: 设计师社区 - - name: Behance - url: https://www.behance.net - icon: fab fa-behance - description: 创意设计平台 - - name: IconFont - url: https://www.iconfont.cn - icon: fas fa-icons - description: 图标资源库 - - name: 在线工具 - icon: fas fa-wrench - sites: - - name: JSON Editor - url: https://jsoneditoronline.org - icon: fas fa-code-branch - description: JSON在线编辑器 - - name: Can I Use - url: https://caniuse.com - icon: fas fa-browser - description: 浏览器兼容性查询 - - name: TinyPNG - url: https://tinypng.com - icon: fas fa-compress - description: 图片压缩工具 - - name: Carbon - url: https://carbon.now.sh - icon: fas fa-code - description: 代码图片生成器 -projects: - title: 我的项目 - subtitle: 这里展示了我的一些个人项目和开源贡献 - categories: - - name: 个人项目 - icon: fas fa-code - sites: - - name: 个人导航站 - icon: fas fa-compass - description: 一个简洁美观的个人导航页面 - url: "#" - - name: Todo List - icon: fas fa-tasks - description: 基于Vue3的待办事项管理器 - url: "#" - - name: 个人博客 - icon: fas fa-blog - description: 使用Hexo搭建的技术博客 - url: "#" - - name: 开源贡献 - icon: fas fa-code-branch - sites: - - name: Project A - icon: fab fa-github - description: 开源项目贡献 - url: "#" - - name: Project B - icon: fab fa-github - description: 开源项目贡献 - url: "#" -articles: - title: 技术文章 - subtitle: 分享我的技术文章和学习笔记 - categories: - - name: 最新文章 - icon: fas fa-pen - sites: - - name: Vue3最佳实践 - icon: fab fa-vuejs - description: Vue3组合式API的使用技巧 - url: "#" - - name: JavaScript进阶 - icon: fab fa-js - description: JavaScript高级特性解析 - url: "#" - - name: Git使用技巧 - icon: fab fa-git-alt - description: Git常用命令和工作流 - url: "#" - - name: Docker入门 - icon: fab fa-docker - description: Docker基础知识和实践 - url: "#" - - name: 学习笔记 - icon: fas fa-book - sites: - - name: React Hooks - icon: fab fa-react - description: React Hooks最佳实践 - url: "#" - - name: Node.js实战 - icon: fab fa-node-js - description: Node.js服务端开发笔记 - url: "#" - - name: CSS技巧 - icon: fab fa-css3 - description: CSS常用技巧总结 - url: "#" - - name: 数据库设计 - icon: fas fa-database - description: 数据库架构和优化笔记 - url: "#" - - name: 源码解析 - icon: fas fa-code - sites: - - name: Vue源码解析 - icon: fab fa-vuejs - description: Vue.js核心原理解析 - url: "#" - - name: React原理 - icon: fab fa-react - description: React核心机制解析 - url: "#" -friends: - title: 友情链接 - subtitle: 优秀的博主和朋友们 - categories: - - name: 技术博主 - icon: fas fa-user-friends - sites: - - name: 小明的博客 - icon: fas fa-code - description: 全栈开发工程师,分享技术心得 - url: "#" - - name: 小红的前端 - icon: fas fa-paint-brush - description: 专注前端开发与设计 - url: "#" - - name: 小张的后端 - icon: fas fa-server - description: 分享后端开发经验 - url: "#" - - name: 小李的移动端 - icon: fas fa-mobile-alt - description: 移动应用开发专家 - url: "#" - - name: 技术社区 - icon: fas fa-laptop-code - sites: - - name: GitHub - icon: fab fa-github - description: 开源代码托管平台 - url: https://github.com - - name: Stack Overflow - icon: fab fa-stack-overflow - description: 程序员问答社区 - url: https://stackoverflow.com - - name: 掘金 - icon: fas fa-book - description: 高质量技术社区 - url: https://juejin.cn - - name: V2EX - icon: fas fa-comments - description: 创意工作者社区 - url: https://v2ex.com - - name: 休闲娱乐 - icon: fas fa-coffee - sites: - - name: 哔哩哔哩 - icon: fas fa-play-circle - description: 视频弹幕网站 - url: https://www.bilibili.com - - name: 知乎 - icon: fas fa-question-circle - description: 问答社区 - url: https://www.zhihu.com - - name: 豆瓣 - icon: fas fa-film - description: 文艺生活社区 - url: https://www.douban.com - - name: 网易云音乐 - icon: fas fa-music - description: 音乐平台 - url: https://music.163.com diff --git a/package.json b/package.json index c603e7b..1af0c85 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "dev": "node src/generator.js && serve dist", "clean": "rm -rf dist", "build": "npm run clean && npm run generate", - "restructure": "node restructure.js" + "restructure": "node restructure.js", + "migrate-config": "node src/migrate-config.js", + "import-bookmarks": "node src/bookmark-processor.js" }, "keywords": [ "navigation", diff --git a/src/bookmark-processor.js b/src/bookmark-processor.js index 805239b..4d74f56 100644 --- a/src/bookmark-processor.js +++ b/src/bookmark-processor.js @@ -4,12 +4,12 @@ const yaml = require('js-yaml'); // 书签文件夹路径 - 使用相对路径 const BOOKMARKS_DIR = 'bookmarks'; -// 输出配置文件路径 - 使用相对路径 -const OUTPUT_FILE = 'bookmarks.user.yml'; +// 模块化配置目录 +const CONFIG_USER_DIR = 'config/user'; +// 模块化页面配置目录 +const CONFIG_USER_PAGES_DIR = path.join(CONFIG_USER_DIR, 'pages'); // 模块化输出配置文件路径 -const MODULAR_OUTPUT_FILE = 'config/user/pages/bookmarks.yml'; -// 默认书签配置文件路径 - 使用相对路径 -const DEFAULT_BOOKMARKS_FILE = 'bookmarks.yml'; +const MODULAR_OUTPUT_FILE = path.join(CONFIG_USER_PAGES_DIR, 'bookmarks.yml'); // 模块化默认书签配置文件路径 const MODULAR_DEFAULT_BOOKMARKS_FILE = 'config/_default/pages/bookmarks.yml'; @@ -197,10 +197,10 @@ function generateBookmarksYaml(bookmarks) { // 添加注释 const yamlWithComment = -`# 自动生成的书签配置文件 - 用户自定义版本 +`# 自动生成的书签配置文件 # 由bookmark-processor.js生成于 ${new Date().toISOString()} # 若要更新,请将新的书签HTML文件放入bookmarks/目录 -# 注意:此文件会覆盖bookmarks.yml中的同名配置 +# 此文件使用模块化配置格式,位于config/user/pages/目录下 ${yamlString}`; @@ -211,58 +211,96 @@ ${yamlString}`; } } -// 更新现有config.yml中的导航,添加书签页面 -function updateConfigWithBookmarks() { - // 传统配置文件 - const configFile = 'config.yml'; - const userConfigFile = 'config.user.yml'; +// 更新导航以包含书签页面 +function updateNavigationWithBookmarks() { + console.log('Checking navigation configuration for bookmarks page...'); // 模块化配置文件 - const modularNavFile = 'config/_default/navigation.yml'; - const modularUserNavFile = 'config/user/navigation.yml'; + const modularUserNavFile = path.join(CONFIG_USER_DIR, 'navigation.yml'); + const modularDefaultNavFile = 'config/_default/navigation.yml'; let navigationUpdated = false; // 按优先级顺序尝试更新导航配置 - // 1. 最高优先级: 模块化用户导航配置 + // 1. 首选: 模块化用户导航配置 if (fs.existsSync(modularUserNavFile)) { navigationUpdated = updateNavigationFile(modularUserNavFile); if (navigationUpdated) { - console.log(`Updated modular user navigation file: ${modularUserNavFile} (highest priority)`); + console.log(`Updated modular user navigation file: ${modularUserNavFile}`); } } - - // 2. 次高优先级: 传统用户配置 - if (!navigationUpdated && fs.existsSync(userConfigFile)) { - navigationUpdated = updateTraditionalConfig(userConfigFile); - if (navigationUpdated) { - console.log(`Updated legacy user config file: ${userConfigFile}`); + // 2. 其次: 模块化默认导航配置 + else if (fs.existsSync(modularDefaultNavFile)) { + // 如果用户导航文件不存在,我们需要先创建它,然后基于默认文件更新 + try { + // 读取默认导航文件 + const defaultNavContent = fs.readFileSync(modularDefaultNavFile, 'utf8'); + const defaultNav = yaml.load(defaultNavContent); + + // 确保目录存在 + if (!fs.existsSync(CONFIG_USER_DIR)) { + fs.mkdirSync(CONFIG_USER_DIR, { recursive: true }); + } + + // 写入用户导航文件 + fs.writeFileSync(modularUserNavFile, defaultNavContent, 'utf8'); + console.log(`Created user navigation file based on default: ${modularUserNavFile}`); + + // 更新新创建的文件 + navigationUpdated = updateNavigationFile(modularUserNavFile); + if (navigationUpdated) { + console.log(`Updated newly created navigation file: ${modularUserNavFile}`); + } + } catch (error) { + console.error(`Error creating user navigation file:`, error); } } - - // 3. 次低优先级: 模块化默认导航 - if (!navigationUpdated && fs.existsSync(modularNavFile)) { - navigationUpdated = updateNavigationFile(modularNavFile); - if (navigationUpdated) { - console.log(`Updated modular default navigation file: ${modularNavFile}`); - } - } - - // 4. 最低优先级: 传统默认配置 - if (!navigationUpdated && fs.existsSync(configFile)) { - navigationUpdated = updateTraditionalConfig(configFile); - if (navigationUpdated) { - console.log(`Updated legacy default config file: ${configFile} (lowest priority)`); + // 3. 如果都不存在,创建一个基本的导航文件 + else { + try { + // 确保目录存在 + if (!fs.existsSync(CONFIG_USER_DIR)) { + fs.mkdirSync(CONFIG_USER_DIR, { recursive: true }); + } + + // 创建基本导航配置 + const basicNav = [ + { + name: "首页", + icon: "fas fa-home", + id: "home", + active: true + }, + { + name: "书签", + icon: "fas fa-bookmark", + id: "bookmarks", + active: false + } + ]; + + // 写入用户导航文件 + fs.writeFileSync( + modularUserNavFile, + yaml.dump(basicNav, { indent: 2, lineWidth: -1, quotingType: '"' }), + 'utf8' + ); + console.log(`Created basic navigation file: ${modularUserNavFile}`); + navigationUpdated = true; + } catch (error) { + console.error(`Error creating basic navigation file:`, error); } } if (!navigationUpdated) { - console.log('Did not find any configuration file to update with bookmarks navigation'); + console.log('Did not update any navigation configuration with bookmarks page'); } + + return navigationUpdated; } -// 更新单个导航配置文件(模块化版本) +// 更新单个导航配置文件 function updateNavigationFile(filePath) { try { const content = fs.readFileSync(filePath, 'utf8'); @@ -304,55 +342,9 @@ function updateNavigationFile(filePath) { } } -// 更新传统配置文件(整体配置) -function updateTraditionalConfig(filePath) { - try { - const configContent = fs.readFileSync(filePath, 'utf8'); - const config = yaml.load(configContent); - - // 检查导航中是否已有书签页面 - const hasBookmarksNav = config.navigation && - Array.isArray(config.navigation) && - config.navigation.some(nav => nav.id === 'bookmarks'); - - if (!hasBookmarksNav) { - // 确保navigation数组存在 - if (!config.navigation) { - config.navigation = []; - } - - // 添加书签页面到导航 - config.navigation.push({ - name: '书签', - icon: 'fas fa-bookmark', - id: 'bookmarks', - active: false - }); - - // 更新配置文件 - const updatedYaml = yaml.dump(config, { - indent: 2, - lineWidth: -1, - quotingType: '"' - }); - - fs.writeFileSync(filePath, updatedYaml, 'utf8'); - return true; - } - - return false; // 无需更新 - } catch (error) { - console.error(`Error updating config file ${filePath}:`, error); - return false; - } -} - // 主函数 async function main() { console.log('Starting bookmark processing...'); - console.log(`Current working directory: ${process.cwd()}`); - console.log(`Legacy output file will be: ${OUTPUT_FILE} (absolute: ${path.resolve(OUTPUT_FILE)})`); - console.log(`Modular output file will be: ${MODULAR_OUTPUT_FILE} (absolute: ${path.resolve(MODULAR_OUTPUT_FILE)})`); // 获取最新的书签文件 const bookmarkFile = getLatestBookmarkFile(); @@ -390,58 +382,37 @@ async function main() { 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 }); + // 确保目标目录存在 + if (!fs.existsSync(CONFIG_USER_PAGES_DIR)) { + console.log(`Creating output directory structure: ${CONFIG_USER_PAGES_DIR}`); + fs.mkdirSync(CONFIG_USER_PAGES_DIR, { recursive: true }); } - // 确保模块化目标目录存在 - const modularOutputDir = path.dirname(MODULAR_OUTPUT_FILE); - if (!fs.existsSync(modularOutputDir)) { - console.log(`Creating modular output directory structure: ${modularOutputDir}`); - fs.mkdirSync(modularOutputDir, { recursive: true }); - } - - // 保存YAML到传统位置 - console.log(`Writing to legacy location: ${OUTPUT_FILE}`); - fs.writeFileSync(OUTPUT_FILE, yaml, 'utf8'); - // 保存YAML到模块化位置 - console.log(`Writing to modular location: ${MODULAR_OUTPUT_FILE}`); + console.log(`Writing bookmarks configuration to: ${MODULAR_OUTPUT_FILE}`); fs.writeFileSync(MODULAR_OUTPUT_FILE, yaml, 'utf8'); // 验证文件是否确实被创建 - let success = false; - - if (fs.existsSync(OUTPUT_FILE)) { - const stats = fs.statSync(OUTPUT_FILE); - console.log(`Successfully saved bookmarks configuration to ${OUTPUT_FILE}`); - console.log(`File size: ${stats.size} bytes`); - success = true; - } else { - console.error(`ERROR: Legacy file was not created: ${OUTPUT_FILE}`); - } - if (fs.existsSync(MODULAR_OUTPUT_FILE)) { const stats = fs.statSync(MODULAR_OUTPUT_FILE); - console.log(`Successfully saved bookmarks configuration to ${MODULAR_OUTPUT_FILE}`); - console.log(`File size: ${stats.size} bytes`); - success = true; + console.log(`Successfully saved bookmarks configuration (${stats.size} bytes)`); } else { - console.error(`ERROR: Modular file was not created: ${MODULAR_OUTPUT_FILE}`); - } - - if (!success) { - console.error('ERROR: No output files were created successfully'); + console.error(`ERROR: File was not created: ${MODULAR_OUTPUT_FILE}`); process.exit(1); } // 更新导航 - updateConfigWithBookmarks(); + updateNavigationWithBookmarks(); + + // 处理完成后,删除原始HTML文件以防止重复处理 + try { + fs.unlinkSync(bookmarkFile); + console.log(`Deleted processed HTML file: ${bookmarkFile}`); + } catch (deleteError) { + console.warn(`Warning: Could not delete processed HTML file: ${deleteError.message}`); + } } catch (writeError) { - console.error(`ERROR writing files:`, writeError); + console.error(`ERROR writing file:`, writeError); process.exit(1); } } catch (error) { @@ -450,8 +421,10 @@ async function main() { } } -// 执行主函数 -main().catch(error => { - console.error('Unhandled error:', error); - process.exit(1); -}); \ No newline at end of file +// 启动处理 +if (require.main === module) { + main().catch(err => { + console.error('Unhandled error in bookmark processing:', err); + process.exit(1); + }); +} \ No newline at end of file diff --git a/src/generator.js b/src/generator.js index 20f7a78..9a46839 100644 --- a/src/generator.js +++ b/src/generator.js @@ -131,24 +131,17 @@ function loadConfig() { categories: [] }; - // 检查所有可能的配置来源是否存在 + // 检查模块化配置来源是否存在 const hasUserModularConfig = fs.existsSync('config/user'); - const hasUserLegacyConfig = fs.existsSync('config.user.yml'); const hasDefaultModularConfig = fs.existsSync('config/_default'); - const hasDefaultLegacyConfig = fs.existsSync('config.yml'); // 根据优先级顺序选择最高优先级的配置 if (hasUserModularConfig) { // 1. 最高优先级: config/user/ 目录 console.log('Using modular user configuration from config/user/ (highest priority)'); config = loadModularConfig('config/user'); - } else if (hasUserLegacyConfig) { - // 2. 次高优先级: config.user.yml (传统用户配置) - console.log('Using legacy user configuration from config.user.yml'); - const userConfigFile = fs.readFileSync('config.user.yml', 'utf8'); - config = yaml.load(userConfigFile); } else if (hasDefaultModularConfig) { - // 3. 其次优先级: config/_default/ 目录 + // 2. 其次优先级: config/_default/ 目录 console.log('Using modular default configuration from config/_default/'); // 从模块化默认配置加载 @@ -174,11 +167,6 @@ function loadConfig() { console.error(`Error loading home.yml: ${e.message}`); } } - } else if (hasDefaultLegacyConfig) { - // 4. 最低优先级: config.yml (传统默认配置) - console.log('Using legacy default config.yml'); - const defaultConfigFile = fs.readFileSync('config.yml', 'utf8'); - config = yaml.load(defaultConfigFile); } else { console.log('No configuration found, using default empty config'); } @@ -191,43 +179,29 @@ function loadConfig() { config.social = config.social || []; config.categories = config.categories || []; - // 处理书签文件(保持现有功能,但使用新逻辑) + // 处理书签文件 try { let bookmarksConfig = null; let bookmarksSource = null; - // 按照相同的优先级顺序处理书签配置 + // 按照优先级顺序处理书签配置 // 1. 模块化用户书签配置 (最高优先级) if (fs.existsSync('config/user/pages/bookmarks.yml')) { const userBookmarksFile = fs.readFileSync('config/user/pages/bookmarks.yml', 'utf8'); bookmarksConfig = yaml.load(userBookmarksFile); bookmarksSource = 'config/user/pages/bookmarks.yml'; } - // 2. 传统用户书签配置 - else if (fs.existsSync('bookmarks.user.yml')) { - const userBookmarksFile = fs.readFileSync('bookmarks.user.yml', 'utf8'); - bookmarksConfig = yaml.load(userBookmarksFile); - bookmarksSource = 'bookmarks.user.yml'; - } - // 3. 模块化默认书签配置 + // 2. 模块化默认书签配置 else if (fs.existsSync('config/_default/pages/bookmarks.yml')) { const defaultBookmarksFile = fs.readFileSync('config/_default/pages/bookmarks.yml', 'utf8'); bookmarksConfig = yaml.load(defaultBookmarksFile); bookmarksSource = 'config/_default/pages/bookmarks.yml'; } - // 4. 传统默认书签配置 (最低优先级) - else if (fs.existsSync('bookmarks.yml')) { - const bookmarksFile = fs.readFileSync('bookmarks.yml', 'utf8'); - bookmarksConfig = yaml.load(bookmarksFile); - bookmarksSource = 'bookmarks.yml'; - } // 添加书签页面配置 if (bookmarksConfig) { config.bookmarks = bookmarksConfig; console.log(`Using bookmarks configuration from ${bookmarksSource}`); - - // 移除自动添加书签页面到导航的逻辑 } } catch (e) { console.error('Error loading bookmarks configuration:', e); diff --git a/src/migrate-config.js b/src/migrate-config.js new file mode 100644 index 0000000..9aa43be --- /dev/null +++ b/src/migrate-config.js @@ -0,0 +1,178 @@ +/** + * MeNav 配置迁移工具 + * 将旧版双文件配置转换为新版模块化配置 + */ + +const fs = require('fs'); +const path = require('path'); +const yaml = require('js-yaml'); + +// 配置文件路径 +const LEGACY_CONFIG_FILE = 'config.yml'; +const LEGACY_USER_CONFIG_FILE = 'config.user.yml'; +const LEGACY_BOOKMARKS_FILE = 'bookmarks.yml'; +const LEGACY_USER_BOOKMARKS_FILE = 'bookmarks.user.yml'; + +// 模块化配置目录 +const CONFIG_USER_DIR = 'config/user'; +const CONFIG_USER_PAGES_DIR = path.join(CONFIG_USER_DIR, 'pages'); + +/** + * 迁移旧式配置文件到模块化格式 + */ +function migrateConfiguration() { + console.log('\n======== MeNav 配置迁移工具 ========'); + console.log('将旧式双文件配置转换为模块化配置\n'); + + // 检查是否存在旧式配置文件 + const hasUserConfig = fs.existsSync(LEGACY_USER_CONFIG_FILE); + const hasDefaultConfig = fs.existsSync(LEGACY_CONFIG_FILE); + const hasUserBookmarks = fs.existsSync(LEGACY_USER_BOOKMARKS_FILE); + const hasDefaultBookmarks = fs.existsSync(LEGACY_BOOKMARKS_FILE); + + if (!hasUserConfig && !hasDefaultConfig && !hasUserBookmarks && !hasDefaultBookmarks) { + console.log('未找到任何旧式配置文件,无需迁移。'); + return; + } + + // 确保目标目录存在 + if (!fs.existsSync(CONFIG_USER_DIR)) { + fs.mkdirSync(CONFIG_USER_DIR, { recursive: true }); + } + + if (!fs.existsSync(CONFIG_USER_PAGES_DIR)) { + fs.mkdirSync(CONFIG_USER_PAGES_DIR, { recursive: true }); + } + + // 优先使用用户配置,如果不存在则使用默认配置 + const configFile = hasUserConfig ? LEGACY_USER_CONFIG_FILE : hasDefaultConfig ? LEGACY_CONFIG_FILE : null; + + // 迁移主配置文件 + if (configFile) { + try { + console.log(`迁移配置文件: ${configFile}`); + const configContent = fs.readFileSync(configFile, 'utf8'); + const config = yaml.load(configContent); + + // 提取站点配置 + if (config.site) { + const siteConfig = { + title: config.site.title || '', + description: config.site.description || '', + author: config.site.author || '', + favicon: config.site.favicon || 'favicon.ico' + }; + + // 添加字体配置 + if (config.fonts) { + siteConfig.fonts = config.fonts; + } + + // 添加个人资料配置 + if (config.profile) { + siteConfig.profile = config.profile; + } + + // 添加社交媒体配置 + if (config.social && config.social.length > 0) { + siteConfig.social = config.social; + } + + // 写入站点配置 + const siteYaml = yaml.dump(siteConfig, { indent: 2, lineWidth: -1, quotingType: '"' }); + fs.writeFileSync( + path.join(CONFIG_USER_DIR, 'site.yml'), + `# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${siteYaml}`, + 'utf8' + ); + console.log('✓ 已创建站点配置文件: site.yml'); + } + + // 提取导航配置 + if (config.navigation && config.navigation.length > 0) { + const navigationYaml = yaml.dump(config.navigation, { indent: 2, lineWidth: -1, quotingType: '"' }); + fs.writeFileSync( + path.join(CONFIG_USER_DIR, 'navigation.yml'), + `# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${navigationYaml}`, + 'utf8' + ); + console.log('✓ 已创建导航配置文件: navigation.yml'); + } + + // 提取所有页面配置 + const pageIds = config.navigation ? config.navigation.map(nav => nav.id) : []; + pageIds.forEach(pageId => { + if (config[pageId]) { + const pageConfig = { ...config[pageId] }; + + // 特殊处理首页的categories + if (pageId === 'home' && !pageConfig.categories && config.categories) { + pageConfig.categories = config.categories; + } + + const pageYaml = yaml.dump(pageConfig, { indent: 2, lineWidth: -1, quotingType: '"' }); + fs.writeFileSync( + path.join(CONFIG_USER_PAGES_DIR, `${pageId}.yml`), + `# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${pageYaml}`, + 'utf8' + ); + console.log(`✓ 已创建页面配置文件: ${pageId}.yml`); + } + }); + + // 如果首页不在pageIds中但存在categories,创建一个home.yml + if (!pageIds.includes('home') && config.categories) { + const homeConfig = { + title: '我的导航', + subtitle: '个人收藏网址', + categories: config.categories + }; + + const homeYaml = yaml.dump(homeConfig, { indent: 2, lineWidth: -1, quotingType: '"' }); + fs.writeFileSync( + path.join(CONFIG_USER_PAGES_DIR, 'home.yml'), + `# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${homeYaml}`, + 'utf8' + ); + console.log('✓ 已创建首页配置文件: home.yml'); + } + } catch (error) { + console.error(`迁移配置文件${configFile}时出错:`, error); + } + } + + // 迁移书签配置文件 + const bookmarksFile = hasUserBookmarks ? LEGACY_USER_BOOKMARKS_FILE : hasDefaultBookmarks ? LEGACY_BOOKMARKS_FILE : null; + + if (bookmarksFile) { + try { + console.log(`\n迁移书签配置文件: ${bookmarksFile}`); + + // 直接复制书签配置文件 + fs.copyFileSync( + bookmarksFile, + path.join(CONFIG_USER_PAGES_DIR, 'bookmarks.yml') + ); + console.log('✓ 已创建书签配置文件: bookmarks.yml'); + } catch (error) { + console.error(`迁移书签配置文件${bookmarksFile}时出错:`, error); + } + } + + console.log('\n迁移完成!'); + console.log('您现在可以删除旧的配置文件:'); + if (hasUserConfig) console.log(`- ${LEGACY_USER_CONFIG_FILE}`); + if (hasDefaultConfig) console.log(`- ${LEGACY_CONFIG_FILE}`); + if (hasUserBookmarks) console.log(`- ${LEGACY_USER_BOOKMARKS_FILE}`); + if (hasDefaultBookmarks) console.log(`- ${LEGACY_BOOKMARKS_FILE}`); + console.log('\n新的模块化配置文件位于:'); + console.log(`- ${CONFIG_USER_DIR}/`); + console.log(`- ${CONFIG_USER_PAGES_DIR}/`); +} + +// 如果直接运行该脚本,则执行迁移 +if (require.main === module) { + migrateConfiguration(); +} + +module.exports = { migrateConfiguration }; \ No newline at end of file