| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- """专栏导出工具"""
- import os
- import json
- from typing import Dict, Any
- from datetime import datetime
- class ColumnExporter:
- """专栏导出工具"""
-
- @staticmethod
- def export_to_files(column_data: Dict[str, Any], output_dir: str = "column_output"):
- """
- 导出专栏到文件
-
- Args:
- column_data: 专栏数据
- output_dir: 输出目录
- """
- # 创建输出目录
- os.makedirs(output_dir, exist_ok=True)
-
- print(f"\n{'='*70}")
- print(f"▸ 开始导出专栏文件...")
- print(f"{'='*70}\n")
-
- # 导出完整JSON
- json_path = os.path.join(output_dir, 'column_data.json')
- with open(json_path, 'w', encoding='utf-8') as f:
- json.dump(column_data, f, ensure_ascii=False, indent=2, default=str)
- print(f"▸ 已保存完整数据:{json_path}")
-
- # 导出每篇文章
- for article in column_data['articles']:
- # 安全的文件名
- safe_title = "".join(c for c in article['title'] if c.isalnum() or c in (' ', '-', '_')).strip()
- filename = f"{article['id']}_{safe_title}.md"
- filepath = os.path.join(output_dir, filename)
-
- with open(filepath, 'w', encoding='utf-8') as f:
- # 写入文章内容
- f.write(article['content'])
-
- # 附加元数据
- f.write(f"\n\n---\n\n")
- f.write(f"## 文章元数据\n\n")
- f.write(f"- **文章ID**: {article['id']}\n")
- f.write(f"- **字数**: {article['word_count']}\n")
- f.write(f"- **评审分数**: {article['metadata'].get('review_score', 'N/A')}\n")
- f.write(f"- **评审等级**: {article['metadata'].get('review_grade', 'N/A')}\n")
-
- if article.get('has_revisions'):
- f.write(f"- **修改次数**: {article['revision_count']}\n")
- if 'revision_summary' in article['metadata']:
- f.write(f"- **主要修改**:\n")
- for change in article['metadata']['revision_summary'].get('major_changes', []):
- f.write(f" - {change}\n")
-
- print(f"▸ 已保存文章:{filepath}")
-
- # 导出统计报告
- report_path = os.path.join(output_dir, 'REPORT.md')
- ColumnExporter._export_report(column_data, report_path)
- print(f"▸ 已保存统计报告:{report_path}")
-
- print(f"\n{'='*70}")
- print(f"▸ 导出完成!输出目录:{output_dir}")
- print(f"{'='*70}\n")
-
- @staticmethod
- def _export_report(column_data: Dict[str, Any], filepath: str):
- """导出统计报告"""
- with open(filepath, 'w', encoding='utf-8') as f:
- f.write(f"# {column_data['column_info']['title']}\n\n")
- f.write(f"## 专栏信息\n\n")
- f.write(f"- **简介**: {column_data['column_info']['description']}\n")
- f.write(f"- **目标读者**: {column_data['column_info']['target_audience']}\n")
- f.write(f"- **文章数量**: {column_data['column_info']['topic_count']}\n\n")
-
- f.write(f"## 内容统计\n\n")
- stats = column_data['statistics']
- f.write(f"- **总字数**: {stats['total_words']:,}\n")
- f.write(f"- **平均每篇**: {stats['avg_words_per_article']:,} 字\n")
- f.write(f"- **内容节点**: {stats['total_nodes']}\n")
-
- # 适配旧版字段(如果存在)
- if 'approval_rate' in stats:
- f.write(f"- **直接通过**: {stats.get('approved_nodes', 0)} ({stats['approval_rate']})\n")
- f.write(f"- **修改优化**: {stats.get('revised_nodes', 0)} ({stats['revision_rate']})\n")
-
- # 质量报告(如果有)
- if 'quality_report' in column_data:
- f.write(f"\n## 质量报告\n\n")
- quality = column_data['quality_report']
- f.write(f"- **平均分数**: {quality['average_score']:.1f}/100\n")
- f.write(f"- **分数范围**: {quality['min_score']}-{quality['max_score']}\n")
- f.write(f"- **评估节点数**: {quality['total_evaluated']}\n\n")
-
- f.write(f"### 评级分布\n\n")
- for grade, count in quality['grade_distribution'].items():
- if count > 0:
- percentage = count / quality['total_evaluated'] * 100 if quality['total_evaluated'] > 0 else 0
- f.write(f"- **{grade}**: {count} 个 ({percentage:.1f}%)\n")
-
- # Agent 模式信息(新版)
- if 'agent_modes' in column_data:
- f.write(f"\n## Agent 模式\n\n")
- modes = column_data['agent_modes']
- f.write(f"- **Planner**: {modes.get('planner', 'N/A')}\n")
- f.write(f"- **Writer**: {modes.get('writer', 'N/A')}\n")
-
- # 创作统计
- if 'creation_stats' in column_data:
- creation = column_data['creation_stats']
- if creation.get('start_time') and creation.get('end_time'):
- # 处理可能是字符串或datetime对象的情况
- start_time = creation['start_time']
- end_time = creation['end_time']
-
- if isinstance(start_time, str):
- try:
- start_time = datetime.fromisoformat(start_time)
- end_time = datetime.fromisoformat(end_time)
- except:
- pass
- if isinstance(start_time, datetime) and isinstance(end_time, datetime):
- duration = (end_time - start_time).total_seconds()
-
- f.write(f"\n## 创作统计\n\n")
- f.write(f"- **开始时间**: {start_time.strftime('%Y-%m-%d %H:%M:%S')}\n")
- f.write(f"- **结束时间**: {end_time.strftime('%Y-%m-%d %H:%M:%S')}\n")
- f.write(f"- **总耗时**: {duration:.1f} 秒 ({duration/60:.1f} 分钟)\n")
-
- f.write(f"- **生成调用**: {creation.get('total_generations', 0)}\n")
- if creation.get('total_reviews') > 0:
- f.write(f"- **评审次数**: {creation.get('total_reviews')}\n")
- if creation.get('total_revisions') > 0:
- f.write(f"- **修改次数**: {creation.get('total_revisions')}\n")
-
- f.write(f"\n## 文章列表\n\n")
- for idx, article in enumerate(column_data['articles'], 1):
- f.write(f"{idx}. **{article['title']}** ({article['word_count']} 字)\n")
-
- # 显示 Agent 模式生成的元数据
- meta = article.get('metadata', {})
- if 'agent_mode' in meta:
- f.write(f" - 模式: {meta['agent_mode']}\n")
-
- if 'review_score' in meta:
- f.write(f" - 评分: {meta['review_score']}/100\n")
-
- f.write("\n")
|