Coverage for aipyapp/display/manager.py: 0%

62 statements  

« prev     ^ index     » next       coverage.py v7.10.3, created at 2025-08-11 12:02 +0200

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

4import os 

5from typing import Dict, Type, Optional 

6from rich.console import Console 

7 

8from loguru import logger 

9 

10from .. import T 

11from .base import DisplayPlugin 

12from .themes import get_theme, THEMES 

13 

14class DisplayManager: 

15 """显示效果管理器""" 

16 

17 def __init__(self, display_config, console: Console = None, record: bool = True, quiet: bool = False): 

18 """ 

19 Args: 

20 console: 控制台对象 

21 record: 是否记录输出,控制是否可以保存HTML文件 

22 quiet: 是否安静模式,控制是否输出到控制台,不影响记录功能 

23 display_config: display配置字典,包含style、theme等设置 

24 """ 

25 # 处理display配置 

26 config = display_config or {} 

27 self.console = console 

28 self.plugins = {} 

29 self.style = config.get('style', 'classic') 

30 self.theme = config.get('theme', 'default') 

31 self.record = config.get('record', True) 

32 self.quiet = config.get('quiet', False) 

33 self._record_buffer = console._record_buffer[:] if console else [] 

34 self.logger = logger.bind(src='display_manager') 

35 self.logger.info(f"DisplayManager initialized with style: {self.style}, theme: {self.theme}") 

36 

37 def set_style(self, style: str): 

38 """设置显示风格""" 

39 self.style = style 

40 self.logger.info(f"Display style changed to: {self.style}") 

41 return True 

42 

43 def get_available_styles(self) -> list: 

44 """获取可用的显示风格列表""" 

45 return [name for name in self.plugins.keys() if name not in ['null', 'agent']] 

46 

47 def get_available_themes(self) -> list: 

48 """获取可用的主题列表""" 

49 return list(THEMES.keys()) 

50 

51 def create_display_plugin(self) -> Optional[DisplayPlugin]: 

52 """获取当前显示插件""" 

53 plugin_class = self.plugins[self.style] 

54 

55 if self.quiet: 

56 if not self.record: 

57 quiet = True 

58 else: 

59 quiet = False 

60 file = open(os.devnull, 'w', encoding='utf-8') 

61 else: 

62 quiet = False 

63 file = None 

64 

65 # 获取用户配置的主题 

66 rich_theme = get_theme(self.theme) 

67 console = Console(file=file, record=self.record, quiet=quiet, theme=rich_theme) 

68 console._record_buffer.extend(self._record_buffer) 

69 plugin = plugin_class(console, quiet=self.quiet) 

70 try: 

71 plugin.init() 

72 except Exception as e: 

73 self.logger.error(f"Failed to initialize display plugin {plugin_class.__name__}: {e}") 

74 return None 

75 return plugin 

76 

77 def register_plugin(self, plugin_class: Type[DisplayPlugin], name: str = None): 

78 """注册新的显示效果插件""" 

79 if name is None: 

80 name = plugin_class.name or plugin_class.__class__.__name__ 

81 

82 if name in self.plugins: 

83 self.logger.warning(f"Display plugin {name} already registered") 

84 return False 

85 

86 if not issubclass(plugin_class, DisplayPlugin): 

87 self.logger.warning(f"Display plugin {name} is not a subclass of DisplayPlugin") 

88 return False 

89 

90 self.plugins[name] = plugin_class 

91 return True 

92 

93 def get_plugin_info(self) -> Dict[str, str]: 

94 """获取插件信息""" 

95 info = {} 

96 for name, plugin_class in self.plugins.items(): 

97 info[name] = T(plugin_class.__doc__) or f"{name} display style" 

98 return info 

99 

100