Files
ChouJuGEO/docs/guides/QUICK_START_GUIDE.md
T
2026-04-30 18:37:46 +08:00

355 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 快速开始指南:实现GitHub发布功能
> 这是最简单的实现示例,可以作为其他平台的基础模板
## 🎯 目标
实现GitHub平台的文章自动发布功能,验证整体架构可行性。
## 📦 步骤1:安装依赖
```bash
pip install httpx pyperclip
```
## 📝 步骤2:扩展数据库
`modules/data_storage.py``_init_sqlite` 方法中添加:
```python
# 平台账号表
cursor.execute("""
CREATE TABLE IF NOT EXISTS platform_accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT NOT NULL,
account_type TEXT NOT NULL,
account_name TEXT,
api_key TEXT,
config_json TEXT,
is_active INTEGER DEFAULT 1,
brand TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
# 发布记录表
cursor.execute("""
CREATE TABLE IF NOT EXISTS publish_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
article_id INTEGER,
platform TEXT NOT NULL,
publish_method TEXT NOT NULL,
publish_status TEXT NOT NULL,
publish_url TEXT,
publish_id TEXT,
error_message TEXT,
published_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
```
## 💻 步骤3:创建GitHub发布器
创建文件 `platform_sync/github_publisher.py`
```python
"""
GitHub发布器 - 最简单的实现示例
"""
import base64
import httpx
from typing import Dict, Any, Optional
class GitHubPublisher:
"""GitHub发布器"""
def __init__(self, api_key: str, repo_owner: str, repo_name: str):
self.api_key = api_key
self.repo_owner = repo_owner
self.repo_name = repo_name
self.base_url = "https://api.github.com"
self.headers = {
"Authorization": f"token {api_key}",
"Accept": "application/vnd.github.v3+json"
}
def publish(self, content: str, title: str, file_path: Optional[str] = None) -> Dict[str, Any]:
"""
发布内容到GitHub
Args:
content: Markdown内容
title: 文章标题
file_path: 文件路径(可选)
Returns:
{
'success': bool,
'publish_url': str,
'publish_id': str,
'error': str
}
"""
try:
# 生成文件路径
if not file_path:
safe_title = title.replace(' ', '_').replace('/', '_')
file_path = f"content/{safe_title}.md"
# 编码内容
content_bytes = content.encode('utf-8')
content_base64 = base64.b64encode(content_bytes).decode('utf-8')
# API URL
url = f"{self.base_url}/repos/{self.repo_owner}/{self.repo_name}/contents/{file_path}"
# 检查文件是否存在
response = httpx.get(url, headers=self.headers)
sha = None
if response.status_code == 200:
sha = response.json().get('sha')
# 准备数据
data = {
"message": f"Publish: {title}",
"content": content_base64,
"branch": "main"
}
if sha:
data["sha"] = sha
# 创建或更新文件
response = httpx.put(url, json=data, headers=self.headers)
if response.status_code in [200, 201]:
result = response.json()
html_url = result.get('content', {}).get('html_url', '')
return {
'success': True,
'publish_url': html_url,
'publish_id': result.get('content', {}).get('sha', ''),
'error': None
}
else:
return {
'success': False,
'publish_url': '',
'publish_id': '',
'error': f"GitHub API错误: {response.text}"
}
except Exception as e:
return {
'success': False,
'publish_url': '',
'publish_id': '',
'error': str(e)
}
def validate_account(self) -> bool:
"""验证GitHub账号"""
try:
response = httpx.get(f"{self.base_url}/user", headers=self.headers)
return response.status_code == 200
except:
return False
```
## 🔧 步骤4:扩展DataStorage
`modules/data_storage.py``DataStorage` 类中添加:
```python
def save_platform_account(self, platform: str, account_config: Dict[str, Any], brand: str):
"""保存平台账号"""
if self.storage_type == "sqlite":
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
INSERT OR REPLACE INTO platform_accounts
(platform, account_type, account_name, api_key, config_json, brand, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
platform,
account_config.get('account_type', 'api'),
account_config.get('account_name', ''),
account_config.get('api_key', ''),
json.dumps(account_config.get('config', {}), ensure_ascii=False),
brand,
datetime.now().isoformat()
))
conn.commit()
conn.close()
def get_platform_account(self, platform: str, brand: str) -> Optional[Dict[str, Any]]:
"""获取平台账号"""
if self.storage_type == "sqlite":
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
SELECT * FROM platform_accounts
WHERE platform = ? AND brand = ? AND is_active = 1
""", (platform, brand))
row = cursor.fetchone()
conn.close()
if row:
return {
'api_key': row[4],
'config': json.loads(row[5] or '{}')
}
return None
def save_publish_record(self, article_id: int, platform: str, publish_method: str,
publish_status: str, publish_url: str = '', publish_id: str = '',
error_message: str = ''):
"""保存发布记录"""
if self.storage_type == "sqlite":
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
INSERT INTO publish_records
(article_id, platform, publish_method, publish_status, publish_url,
publish_id, error_message, published_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", (
article_id, platform, publish_method, publish_status,
publish_url, publish_id, error_message, datetime.now().isoformat()
))
conn.commit()
conn.close()
```
## 🎨 步骤5:添加UI(在geo_tool.py中)
`modules/geo_tool.py` 中添加新的Tab或功能:
```python
# 在Tab定义中添加
tabs = st.tabs([
"1 关键词蒸馏",
"2 内容生成",
"3 内容优化",
"4 AI验证",
"5 历史记录",
"6 平台同步" # 新增
])
with tabs[5]: # 平台同步Tab
st.header("📤 平台文章同步")
# GitHub账号配置
with st.expander("🔐 GitHub账号配置", expanded=True):
github_api_key = st.text_input("GitHub Personal Access Token", type="password")
github_repo_owner = st.text_input("仓库所有者(用户名)")
github_repo_name = st.text_input("仓库名称")
if st.button("保存GitHub配置"):
if github_api_key and github_repo_owner and github_repo_name:
storage.save_platform_account(
platform="GitHub",
account_config={
'account_type': 'api',
'api_key': github_api_key,
'config': {
'repo_owner': github_repo_owner,
'repo_name': github_repo_name
}
},
brand=brand
)
st.success("GitHub配置已保存!")
else:
st.error("请填写完整信息")
# 发布功能
st.subheader("📝 发布到GitHub")
# 选择文章
articles = storage.get_articles(brand=brand)
if articles:
article_options = {f"{a['keyword']} - {a['platform']}": a['id'] for a in articles}
selected_article_key = st.selectbox("选择要发布的文章", list(article_options.keys()))
selected_article_id = article_options[selected_article_key]
if st.button("🚀 发布到GitHub", type="primary"):
# 获取账号配置
account_config = storage.get_platform_account("GitHub", brand)
if not account_config:
st.error("请先配置GitHub账号")
else:
# 获取文章
article = next((a for a in articles if a['id'] == selected_article_id), None)
if article:
# 创建发布器
from platform_sync.github_publisher import GitHubPublisher
publisher = GitHubPublisher(
api_key=account_config['api_key'],
repo_owner=account_config['config']['repo_owner'],
repo_name=account_config['config']['repo_name']
)
# 发布
with st.spinner("正在发布到GitHub..."):
result = publisher.publish(
content=article['content'],
title=article['keyword']
)
# 保存发布记录
storage.save_publish_record(
article_id=selected_article_id,
platform="GitHub",
publish_method="api",
publish_status="success" if result['success'] else "failed",
publish_url=result.get('publish_url', ''),
publish_id=result.get('publish_id', ''),
error_message=result.get('error', '')
)
# 显示结果
if result['success']:
st.success(f"✅ 发布成功!")
st.markdown(f"**发布链接**: {result['publish_url']}")
else:
st.error(f"❌ 发布失败: {result.get('error', '未知错误')}")
else:
st.info("请先生成文章")
# 发布记录
st.subheader("📊 发布记录")
# 这里可以显示发布历史记录
```
## ✅ 步骤6:测试
1. **获取GitHub Token**
- 访问 [https://github.com/settings/tokens](https://github.com/settings/tokens)
- 创建新的 Personal Access Token
- 选择 `repo` 权限
2. **运行测试**
```bash
streamlit run geo_tool.py
```
3. **测试流程**
- 配置GitHub账号
- 生成一篇文章
- 发布到GitHub
- 检查GitHub仓库是否成功创建文件
## 🎉 完成!
如果GitHub发布功能正常工作,说明架构是正确的。接下来可以:
1. 按照相同模式实现其他7个API平台
2. 实现一键复制功能
3. 添加批量发布功能
## 📚 参考
- [GitHub API文档](https://docs.github.com/en/rest)
- [完整实现指南](./PLATFORM_SYNC_IMPLEMENTATION.md)