aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/conventionalrp/renderers/json_renderer.py
blob: 42d5fd4c1ea3001e2814ba44c534ec1a5a929a95 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import json
from typing import Any, Dict, List
from .base import BaseRenderer


class JSONRenderer(BaseRenderer):
    def __init__(self, pretty: bool = True, indent: int = 2, sort_keys: bool = False):
        super().__init__()
        self.pretty = pretty
        self.indent = indent if pretty else None
        self.sort_keys = sort_keys
        self.style = {}
    
    def render(self, data: Any) -> str:
        if self.pretty and isinstance(data, list):
            output = {
                "metadata": {
                    "total_entries": len(data),
                    "renderer": "ConventionalRP JSONRenderer",
                    "version": "1.0.0",
                },
                "statistics": self._calculate_stats(data),
                "data": data,
            }
        else:
            output = data
        
        return json.dumps(
            output,
            ensure_ascii=False,
            indent=self.indent,
            sort_keys=self.sort_keys,
        )
    
    def _calculate_stats(self, data: List[Dict[str, Any]]) -> Dict[str, Any]:
        stats = {
            "dialogue": 0,
            "dice": 0,
            "narration": 0,
            "system": 0,
            "success": 0,
            "failure": 0,
            "other": 0,
        }
        
        speakers = set()
        
        for item in data:
            if not isinstance(item, dict):
                continue
            
            token_type = item.get("type", "unknown")
            if token_type in stats:
                stats[token_type] += 1
            else:
                stats["other"] += 1
            
            if "speaker" in item and item["speaker"]:
                speakers.add(item["speaker"])
        
        stats["unique_speakers"] = len(speakers)
        stats["speakers"] = sorted(list(speakers))
        
        return stats

    def set_style(self, style):
        self.style = style
        
        # 从 style 中提取设置
        if isinstance(style, dict):
            if "pretty" in style:
                self.pretty = style["pretty"]
                self.indent = 2 if self.pretty else None
            if "indent" in style:
                self.indent = style["indent"]
            if "sort_keys" in style:
                self.sort_keys = style["sort_keys"]