209 lines
6.1 KiB
Python
209 lines
6.1 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, tags: list[str] | str | None = None
|
|
) -> dict:
|
|
"""验证内容是否符合平台规则
|
|
|
|
Args:
|
|
content: 内容正文
|
|
title: 标题
|
|
platform_id: 平台标识
|
|
tags: 内容标签列表
|
|
|
|
Returns:
|
|
验证结果
|
|
"""
|
|
return self._engine.validate_content(content, title, platform_id, tags=tags)
|
|
|
|
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()
|