geo/backend/app/services/distribution/rule_service.py

208 lines
6.0 KiB
Python

"""平台规则管理服务 - 提供规则 CRUD 和内容验证功能"""
import logging
import json
import re
from datetime import datetime
from typing import Optional, Any
from app.services.distribution.platform_rules import (
PLATFORM_RULES,
PlatformRuleEngine,
rule_engine as default_rule_engine,
AI_PATTERNS,
)
logger = logging.getLogger(__name__)
class PlatformRuleService:
"""平台规则管理服务"""
def __init__(self):
self._engine = default_rule_engine
def get_all_platforms(self, enabled_only: bool = True) -> list[dict]:
"""获取所有平台列表
Args:
enabled_only: 是否只返回启用的平台
Returns:
平台列表
"""
return self._engine.get_platforms(enabled_only=enabled_only)
def get_platform_detail(self, platform_id: str) -> Optional[dict]:
"""获取平台详情
Args:
platform_id: 平台标识
Returns:
平台完整规则,如果不存在返回 None
"""
return self._engine.get_platform_rules(platform_id)
def get_rule_category(
self, platform_id: str, rule_category: str
) -> Optional[dict]:
"""获取特定规则类别
Args:
platform_id: 平台标识
rule_category: 规则类别
Returns:
规则配置
"""
return self._engine.get_platform_rule(platform_id, rule_category)
def validate_content(
self, content: str, title: str, platform_id: str
) -> dict:
"""验证内容是否符合平台规则
Args:
content: 内容正文
title: 标题
platform_id: 平台标识
Returns:
验证结果
"""
return self._engine.validate_content(content, title, platform_id)
def detect_ai_patterns(self, content: str, platform_id: str) -> list[dict]:
"""检测内容中的AI写作模式
Args:
content: 待检测内容
platform_id: 平台标识
Returns:
检测到的AI模式列表
"""
ai_config = self._engine.get_ai_humanization_config(platform_id)
if not ai_config:
return []
detected = []
banned_patterns = ai_config.get("banned_patterns", [])
for pattern in banned_patterns:
if pattern in content:
detected.append({
"pattern": pattern,
"type": "banned_word",
"severity": "high",
})
# 检测禁用结构
banned_structures = ai_config.get("banned_structures", [])
for structure in banned_structures:
if re.search(structure, content):
detected.append({
"pattern": structure,
"type": "banned_structure",
"severity": "medium",
})
return detected
def get_ai_humanization_config(self, platform_id: str) -> Optional[dict]:
"""获取平台去AI化配置"""
return self._engine.get_ai_humanization_config(platform_id)
def get_sensitive_words_config(self, platform_id: str) -> Optional[dict]:
"""获取平台敏感词配置"""
return self._engine.get_sensitive_words_config(platform_id)
def get_seo_config(self, platform_id: str) -> Optional[dict]:
"""获取平台SEO配置"""
return self._engine.get_seo_config(platform_id)
def get_html_config(self, platform_id: str) -> Optional[dict]:
"""获取平台HTML配置"""
return self._engine.get_html_config(platform_id)
def get_optimization_tips(self, platform_id: str) -> list[str]:
"""获取平台优化建议"""
return self._engine.get_optimization_tips(platform_id)
def compare_rules(
self, platform_id: str, old_rules: dict, new_rules: dict
) -> list[dict]:
"""对比规则变更
Args:
platform_id: 平台标识
old_rules: 旧规则
new_rules: 新规则
Returns:
差异列表
"""
diffs = []
def flatten_dict(d: dict, parent_key: str = "") -> dict:
"""将嵌套字典展平为点分隔的键值对"""
items = []
for k, v in d.items():
new_key = f"{parent_key}.{k}" if parent_key else k
if isinstance(v, dict):
items.extend(flatten_dict(v, new_key).items())
else:
items.append((new_key, v))
return dict(items)
old_flat = flatten_dict(old_rules)
new_flat = flatten_dict(new_rules)
all_keys = set(old_flat.keys()) | set(new_flat.keys())
for key in all_keys:
old_val = old_flat.get(key)
new_val = new_flat.get(key)
if old_val != new_val:
diffs.append({
"field": key,
"old_value": old_val,
"new_value": new_val,
})
return diffs
def format_content_for_platform(
self, content: str, platform_id: str, target_format: str = "html"
) -> str:
"""将内容格式化为平台特定格式
Args:
content: 原始内容
platform_id: 目标平台
target_format: 目标格式 (html/markdown/plain)
Returns:
格式化后的内容
"""
rules = self._engine.get_platform_rules(platform_id)
if not rules:
return content
html_config = rules.get("html_rules", {})
supported_tags = html_config.get("supported_tags", [])
banned_tags = html_config.get("banned_tags", [])
# 移除禁用的标签
formatted = content
for tag in banned_tags:
formatted = re.sub(f"<{tag}[^>]*>.*?</{tag}>", "", formatted, flags=re.DOTALL)
formatted = re.sub(f"<{tag}[^>]*/?>", "", formatted)
return formatted
# 导出单例
platform_rule_service = PlatformRuleService()