智慧阅读伴侣 - 个人知识管理系统
- 项目概述
实际应用场景
在信息爆炸的时代,知识工作者、学生和终身学习者都面临着海量阅读的挑战。许多人有以下困扰:
- 读过的书很多,但记不住核心内容
- 不知道该读什么书,缺乏系统性规划
- 阅读时间难以追踪,无法量化学习效果
- 读书笔记零散分布,难以形成知识体系
- 想要寻找同类好书却无从下手
痛点分析
-
阅读管理混乱: 纸质笔记易丢失,电子笔记分散各处
-
缺乏量化指标: 无法客观评估阅读效率和质量
-
推荐系统缺失: 依赖主观判断或单一平台推荐
-
知识沉淀困难: 读完就忘,无法有效转化为个人认知
-
时间管理低效: 阅读计划执行不到位,缺乏监督机制
-
核心逻辑
系统架构
数据采集层 → 数据处理层 → 智能分析层 → 知识图谱层 → 输出展示层 ↓ ↓ ↓ ↓ ↓ 阅读记录 数据清洗 深度分析 关联挖掘 可视化报告
关键算法
-
阅读效率评估: 基于时长、页数、理解度的多维评估
-
知识图谱构建: 书籍主题、作者、概念的关联关系
-
协同过滤推荐: 基于用户行为和相似用户的推荐算法
-
文本相似度计算: TF-IDF + Word2Vec的混合相似度算法
-
阅读路径优化: 基于知识体系的个性化阅读路线规划
-
代码实现
项目结构
smart_reading_companion/ ├── main.py # 主程序入口 ├── config.py # 配置文件 ├── models/ # 数据模型 │ ├── book.py # 书籍类 │ ├── reading_session.py # 阅读会话类 │ ├── note.py # 笔记类 │ └── knowledge_node.py # 知识节点类 ├── services/ # 业务服务 │ ├── tracker.py # 阅读追踪服务 │ ├── analyzer.py # 阅读分析服务 │ ├── recommender.py # 推荐服务 │ ├── knowledge_graph.py # 知识图谱服务 │ └── report_generator.py # 报告生成服务 ├── utils/ # 工具函数 │ ├── text_processor.py # 文本处理工具 │ ├── similarity.py # 相似度计算工具 │ ├── visualization.py # 可视化工具 │ └── exporters.py # 导出工具 ├── data/ # 数据目录 │ ├── books.json # 书籍数据 │ ├── sessions.json # 阅读会话数据 │ ├── notes.json # 笔记数据 │ └── knowledge_graph.json # 知识图谱数据 ├── templates/ # 模板目录 │ ├── report_template.html │ └── mindmap_template.svg └── outputs/ # 输出目录 ├── monthly_reports/ ├── reading_insights/ └── recommendations/
核心代码
main.py - 主程序
#!/usr/bin/env python3 """ 智慧阅读伴侣主程序 智能管理阅读生活,构建个人知识体系 """
import sys import json import argparse from datetime import datetime, timedelta from typing import List, Dict, Optional from pathlib import Path import os
from models.book import Book, ReadingStatus from models.reading_session import ReadingSession from models.note import Note, NoteType from models.knowledge_node import KnowledgeNode from services.tracker import ReadingTracker from services.analyzer import ReadingAnalyzer from services.recommender import BookRecommender from services.knowledge_graph import KnowledgeGraphBuilder from services.report_generator import ReportGenerator from utils.text_processor import TextProcessor from utils.similarity import SimilarityCalculator from utils.visualization import ChartGenerator from config import Config
class SmartReadingCompanion: """智慧阅读伴侣主控制器"""
def __init__(self):
self.config = Config()
self.tracker = ReadingTracker()
self.analyzer = ReadingAnalyzer()
self.recommender = BookRecommender()
self.knowledge_builder = KnowledgeGraphBuilder()
self.report_generator = ReportGenerator()
self.text_processor = TextProcessor()
self.similarity_calculator = SimilarityCalculator()
self.chart_generator = ChartGenerator()
# 加载数据
self.books = self.tracker.load_books()
self.sessions = self.tracker.load_sessions()
self.notes = self.tracker.load_notes()
self.knowledge_graph = self.knowledge_builder.load_knowledge_graph()
print("📚 智慧阅读伴侣启动成功!")
print(f"📖 当前管理 {len(self.books)} 本书籍")
print(f"⏱️ 累计阅读时长 {self._get_total_reading_time():.1f} 小时")
print(f"📝 已记录 {len(self.notes)} 条笔记")
def run(self, mode="interactive"):
"""
运行主程序
Args:
mode: 运行模式 (interactive/batch/report/sync)
"""
try:
if mode == "interactive":
self._run_interactive_mode()
elif mode == "batch":
self._run_batch_mode()
elif mode == "report":
self._generate_reports()
elif mode == "sync":
self._sync_with_platforms()
elif mode == "daemon":
self._run_daemon_mode()
except KeyboardInterrupt:
print("\n\n👋 感谢使用,再见!")
self._save_all_data()
except Exception as e:
print(f"❌ 程序运行出错: {e}")
self._save_all_data()
def _run_interactive_mode(self):
"""交互式模式"""
while True:
self._clear_screen()
print("📚 智慧阅读伴侣")
print("=" * 50)
print("1. 📖 添加书籍")
print("2. ⏱️ 记录阅读")
print("3. 📝 写读书笔记")
print("4. 📊 查看阅读报告")
print("5. 🔍 搜索书籍")
print("6. 🎯 获取推荐")
print("7. 🧠 知识图谱")
print("8. 📈 阅读分析")
print("9. ⚙️ 系统设置")
print("0. 🚪 退出系统")
choice = input("\n请选择操作 (0-9): ").strip()
if choice == "1":
self._add_book()
elif choice == "2":
self._record_reading()
elif choice == "3":
self._write_note()
elif choice == "4":
self._show_reading_report()
elif choice == "5":
self._search_books()
elif choice == "6":
self._get_recommendations()
elif choice == "7":
self._explore_knowledge_graph()
elif choice == "8":
self._show_reading_analysis()
elif choice == "9":
self._system_settings()
elif choice == "0":
break
else:
print("⚠️ 无效选择,请重新输入")
input("\n按回车键继续...")
def _add_book(self):
"""添加书籍"""
self._clear_screen()
print("📖 添加新书籍")
print("-" * 30)
try:
title = input("书名: ").strip()
author = input("作者: ").strip()
isbn = input("ISBN (可选): ").strip()
publisher = input("出版社: ").strip()
publication_year = input("出版年份: ").strip()
genre = input("类别/标签 (用逗号分隔): ").strip()
page_count = int(input("总页数: ") or "0")
language = input("语言 (默认中文): ").strip() or "中文"
# 创建书籍对象
book = Book(
title=title,
author=author,
isbn=isbn,
publisher=publisher,
publication_year=int(publication_year) if publication_year.isdigit() else None,
genres=[g.strip() for g in genre.split(',')] if genre else [],
page_count=page_count,
language=language
)
# 验证书籍信息
if not book.validate():
print("❌ 书籍信息验证失败")
return
# 获取书籍详细信息(调用API)
book_details = self._fetch_book_details(book)
if book_details:
book.update_from_api(book_details)
# 保存书籍
self.books.append(book)
self.tracker.save_books(self.books)
print(f"✅ 成功添加书籍: 《{book.title}》")
print(f"📚 作者: {book.author}")
print(f"🏷️ 标签: {', '.join(book.genres)}")
# 询问是否立即开始阅读
start_reading = input("\n是否立即开始阅读此书?(y/n): ").lower().strip()
if start_reading == 'y':
self._start_reading_session(book)
input("\n按回车键继续...")
except ValueError as e:
print(f"❌ 输入格式错误: {e}")
input("\n按回车键继续...")
except Exception as e:
print(f"❌ 添加失败: {e}")
input("\n按回车键继续...")
def _record_reading(self):
"""记录阅读"""
self._clear_screen()
print("⏱️ 记录阅读")
print("-" * 30)
# 显示正在阅读的书籍
reading_books = [book for book in self.books if book.status == ReadingStatus.READING]
if not reading_books:
print("📚 当前没有正在阅读的书籍")
print("请先添加书籍并开始阅读")
input("\n按回车键继续...")
return
print("正在阅读的书籍:")
for i, book in enumerate(reading_books, 1):
progress = book.get_progress_percentage()
print(f"{i}. 《{book.title}》- 进度: {progress:.1f}%")
try:
book_index = int(input("\n选择要记录的书籍: ")) - 1
if not (0 <= book_index < len(reading_books)):
print("❌ 无效的书籍选择")
return
selected_book = reading_books[book_index]
self._start_reading_session(selected_book)
except ValueError as e:
print(f"❌ 输入错误: {e}")
input("\n按回车键继续...")
def _start_reading_session(self, book: Book):
"""开始阅读会话"""
print(f"\n📖 开始阅读: 《{book.title}》")
try:
# 记录开始时间
start_time = datetime.now()
start_page = int(input("开始页码: ") or "0")
end_page = int(input("结束页码: ") or "0")
reading_location = input("阅读地点: ").strip()
environment = input("阅读环境 (安静/嘈杂/通勤等): ").strip()
mood = input("阅读心情: ").strip()
# 计算阅读时长
input("按回车键结束本次阅读...")
end_time = datetime.now()
duration = (end_time - start_time).total_seconds() / 3600 # 转换为小时
# 创建阅读会话
session = ReadingSession(
book_id=book.book_id,
start_time=start_time,
end_time=end_time,
start_page=start_page,
end_page=end_page,
location=reading_location,
environment=environment,
mood=mood,
pages_read=end_page - start_page,
duration_hours=duration
)
# 验证会话
if not session.validate():
print("❌ 阅读记录验证失败")
return
# 更新书籍信息
book.add_reading_session(session)
book.update_current_page(end_page)
# 保存数据
self.sessions.append(session)
self.tracker.save_sessions(self.sessions)
self.tracker.save_books(self.books)
# 计算阅读速度
wpm = session.get_reading_speed() # words per minute
efficiency_score = session.calculate_efficiency_score()
print(f"\n✅ 阅读记录已保存")
print(f"⏱️ 阅读时长: {duration:.2f} 小时")
print(f"📄 阅读页数: {session.pages_read} 页")
print(f"📈 阅读速度: {wpm:.0f} 字/分钟")
print(f"⭐ 效率评分: {efficiency_score:.1f}/10")
# 提供阅读建议
self._provide_reading_suggestions(book, session)
input("\n按回车键继续...")
except ValueError as e:
print(f"❌ 输入错误: {e}")
input("\n按回车键继续...")
def _write_note(self):
"""写读书笔记"""
self._clear_screen()
print("📝 写读书笔记")
print("-" * 30)
# 显示有阅读进度的书籍
available_books = [book for book in self.books if book.current_page > 0]
if not available_books:
print("📚 没有可写笔记的书籍")
input("\n按回车键继续...")
return
print("可写笔记的书籍:")
for i, book in enumerate(available_books, 1):
print(f"{i}. 《{book.title}》- 已读 {book.current_page} 页")
try:
book_index = int(input("\n选择书籍: ")) - 1
if not (0 <= book_index < len(available_books)):
print("❌ 无效的书籍选择")
return
selected_book = available_books[book_index]
# 获取笔记信息
chapter = input("章节/页码: ").strip()
content = input("笔记内容: ").strip()
note_type = input("笔记类型 (摘抄/感悟/问题/总结,默认摘抄): ").strip() or "摘抄"
# 提取关键词
keywords = self.text_processor.extract_keywords(content)
# 创建笔记
note = Note(
book_id=selected_book.book_id,
content=content,
note_type=NoteType(note_type),
chapter=chapter,
keywords=keywords,
page_reference=selected_book.current_page
)
# 验证笔记
if not note.validate():
print("❌ 笔记内容验证失败")
return
# 更新知识图谱
self._update_knowledge_graph(selected_book, note)
# 保存笔记
self.notes.append(note)
self.tracker.save_notes(self.notes)
print(f"✅ 笔记已保存")
print(f"🏷️ 关键词: {', '.join(keywords)}")
print(f"📊 知识节点已更新")
# 提供写作建议
self._provide_writing_suggestions(note)
input("\n按回车键继续...")
except ValueError as e:
print(f"❌ 输入错误: {e}")
input("\n按回车键继续...")
def _show_reading_report(self):
"""显示阅读报告"""
self._clear_screen()
print("📊 阅读报告")
print("=" * 50)
# 生成各种报告
time_range = input("选择时间范围 (本周/本月/本年/全部,默认本月): ").strip() or "本月"
# 生成综合报告
comprehensive_report = self.analyzer.generate_comprehensive_report(
self.books, self.sessions, self.notes, time_range
)
# 显示报告
self._display_comprehensive_report(comprehensive_report)
# 生成可视化图表
if self.config.enable_visualization:
self._generate_visualizations(comprehensive_report)
# 保存报告
report_path = self.report_generator.save_report(comprehensive_report, time_range)
print(f"\n📄 报告已保存到: {report_path}")
# 询问是否打开报告
open_report = input("\n是否打开报告?(y/n): ").lower().strip()
if open_report == 'y':
self._open_file(report_path)
input("\n按回车键继续...")
def _get_recommendations(self):
"""获取推荐"""
self._clear_screen()
print("🎯 智能推荐")
print("=" * 50)
# 分析用户偏好
user_profile = self.analyzer.analyze_user_preference(
self.books, self.sessions, self.notes
)
print("📈 您的阅读画像:")
print(f" 最爱类别: {user_profile['top_genres']}")
print(f" 平均评分: {user_profile['avg_rating']:.1f}")
print(f" 阅读速度: {user_profile['avg_reading_speed']:.0f} 字/分钟")
print(f" 偏好时段: {user_profile['preferred_time_slots']}")
print("\n🎯 为您推荐:")
# 基于内容的推荐
content_recs = self.recommender.content_based_recommendation(
user_profile, self.books, limit=5
)
# 协同过滤推荐
collaborative_recs = self.recommender.collaborative_filtering_recommendation(
user_profile, limit=5
)
# 混合推荐
hybrid_recs = self.recommender.hybrid_recommendation(
user_profile, self.books, weight_content=0.6, weight_collab=0.4, limit=8
)
# 显示推荐结果
rec_types = [
("📚 内容推荐", content_recs),
("👥 协同推荐", collaborative_recs),
("⚡ 混合推荐", hybrid_recs)
]
for rec_type, recommendations in rec_types:
print(f"\n{rec_type}:")
for i, rec in enumerate(recommendations, 1):
print(f" {i}. 《{rec['title']}》- {rec['author']}")
print(f" 相似度: {rec['similarity_score']:.2f}")
print(f" 推荐理由: {rec['reason']}")
print()
# 询问是否添加到心愿单
add_to_wishlist = input("是否将推荐书籍添加到心愿单?(y/n): ").lower().strip()
if add_to_wishlist == 'y':
self._add_recommendations_to_wishlist(hybrid_recs)
input("\n按回车键继续...")
def _explore_knowledge_graph(self):
"""探索知识图谱"""
self._clear_screen()
print("🧠 知识图谱探索")
print("=" * 50)
if not self.knowledge_graph.nodes:
print("📚 知识图谱为空,请先添加一些笔记")
input("\n按回车键继续...")
return
print("🌐 知识图谱统计:")
stats = self.knowledge_builder.get_graph_statistics()
print(f" 节点数量: {stats['node_count']}")
print(f" 边数量: {stats['edge_count']}")
print(f" 连通分量: {stats['connected_components']}")
print("\n🔍 探索选项:")
print("1. 查看热门概念")
print("2. 搜索特定概念")
print("3. 查看知识网络")
print("4. 发现知识关联")
choice = input("\n请选择 (1-4): ").strip()
if choice == "1":
self._show_popular_concepts()
elif choice == "2":
self._search_concept()
elif choice == "3":
self._show_knowledge_network()
elif choice == "4":
self._discover_connections()
input("\n按回车键继续...")
def _show_reading_analysis(self):
"""显示阅读分析"""
self._clear_screen()
print("📈 深度阅读分析")
print("=" * 50)
# 多维度分析
analysis_results = self.analyzer.perform_deep_analysis(
self.books, self.sessions, self.notes
)
# 显示分析结果
self._display_analysis_results(analysis_results)
# 生成洞察
insights = self.analyzer.generate_insights(analysis_results)
print("\n💡 关键洞察:")
for insight in insights:
print(f" • {insight}")
# 提供改进建议
suggestions = self.analyzer.generate_improvement_suggestions(analysis_results)
print("\n🎯 改进建议:")
for suggestion in suggestions:
print(f" • {suggestion}")
input("\n按回车键继续...")
def _update_knowledge_graph(self, book: Book, note: Note):
"""更新知识图谱"""
# 提取概念
concepts = self.text_processor.extract_concepts(note.content)
for concept in concepts:
# 创建或获取知识节点
node = self.knowledge_graph.get_node(concept)
if not node:
node = KnowledgeNode(
name=concept,
type="concept",
source_books=[book.book_id]
)
self.knowledge_graph.add_node(node)
else:
if book.book_id not in node.source_books:
node.source_books.append(book.book_id)
# 建立书籍-概念关联
self.knowledge_graph.add_edge(
book.book_id, concept, "contains", weight=1.0
)
# 保存知识图谱
self.knowledge_builder.save_knowledge_graph(self.knowledge_graph)
def _provide_reading_suggestions(self, book: Book, session: ReadingSession):
"""提供阅读建议"""
suggestions = []
# 基于阅读速度的建议
avg_speed = self.analyzer.get_user_avg_reading_speed()
if session.get_reading_speed() < avg_speed * 0.8:
suggestions.append("阅读速度偏慢,建议选择更专注的环境或减少干扰")
# 基于时长的建议
if session.duration_hours < 0.5:
suggestions.append("建议每次阅读至少30分钟以保证阅读连贯性")
elif session.duration_hours > 3:
suggestions.append("长时间阅读可能疲劳,建议适当休息")
# 基于进度的建议
if book.get_pages_remaining() < 50:
suggestions.append("接近完成,建议规划写书评或总结")
if suggestions:
print("\n💡 阅读建议:")
for suggestion in suggestions:
print(f" • {suggestion}")
def _provide_writing_suggestions(self, note: Note):
"""提供写作建议"""
suggestions = []
# 基于笔记长度的建议
if len(note.content) < 50:
suggestions.append("可以尝试更详细的记录,包括具体例子和个人思考")
# 基于类型的建议
if note.note_type == NoteType.EXCERPT:
suggestions.append("对于摘抄内容,建议添加自己的理解和评论")
if note.note
如果你觉得这个工具好用,欢迎关注我!