Coverage for src/robotide/parserlog/parserlog.py: 45%

75 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2019- Robot Framework Foundation 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15import atexit 

16import builtins 

17import glob 

18import io 

19import os 

20import sys 

21import tempfile 

22import uuid 

23 

24import wx 

25 

26from .. import context 

27from .. import widgets 

28from ..log import LogWindow, message_to_string 

29from ..pluginapi import Plugin 

30from ..action import ActionInfo 

31from ..publish.messages import RideParserLogMessage 

32 

33_ = wx.GetTranslation # To keep linter/code analyser happy 

34builtins.__dict__['_'] = wx.GetTranslation 

35 

36 

37class ParserLogPlugin(Plugin): 

38 """Viewer for parser log messages.""" 

39 

40 def __init__(self, app): 

41 Plugin.__init__(self, app, default_settings={ 

42 'log_to_console': False, 

43 'log_to_file': True 

44 }) 

45 self.title = _('Parser Log') 

46 self._log = [] 

47 self._panel = None 

48 self._path = os.path.join( 

49 tempfile.gettempdir(), '{}-ride_parser.log'.format(uuid.uuid4())) 

50 self._outfile = None 

51 self._remove_old_log_files() 

52 atexit.register(self._close) 

53 

54 def _close(self): 

55 if self._outfile is not None: 

56 self._outfile.close() 

57 

58 @staticmethod 

59 def _remove_old_log_files(): 

60 for fname in glob.glob( 60 ↛ 62line 60 didn't jump to line 62 because the loop on line 60 never started

61 os.path.join(tempfile.gettempdir(), '*-ride_parser.log')): 

62 try: 

63 os.remove(fname) 

64 except (OSError, IOError) as e: 

65 sys.stderr.write(f"Removing old *-ride_parser.log files failed with: {repr(e)}\n") 

66 

67 @property 

68 def _logfile(self): 

69 if self._outfile is None: 

70 self._outfile = io.open(self._path, 'w', encoding='utf8') 

71 return self._outfile 

72 

73 def enable(self): 

74 self._create_menu() 

75 self.subscribe(self._log_message, RideParserLogMessage) 

76 

77 def disable(self): 

78 self.unsubscribe_all() 

79 self.unregister_actions() 

80 if self._panel: 

81 self._panel.close(self.notebook) 

82 

83 def _create_menu(self): 

84 self.unregister_actions() 

85 self.register_action(ActionInfo(_('Tools'), _('View Parser Log'), self.on_view_log, position=83)) 

86 

87 def _log_message(self, message): 

88 self._log.append(message) 

89 if self._panel: 

90 self._panel.update_log() 

91 if self.log_to_console: 

92 print("{}".format(message_to_string(message, True))) # >> sys.stdout, _message_to_string(message) 

93 if self.log_to_file: 

94 self._logfile.write(message_to_string(message, True)) 

95 self._outfile.flush() 

96 if message.notify_user: 

97 font_size = 13 if context.IS_MAC else -1 

98 widgets.HtmlDialog(message.level, message.message, 

99 padding=10, font_size=font_size).Show() 

100 self.on_view_log(message, show_tab=False) 

101 

102 def on_view_log(self, event, show_tab=True): 

103 __ = event 

104 if not self._panel: 

105 self._panel = LogWindow(self.notebook, self.title, self._log) 

106 self.notebook.SetPageTextColour(self.notebook.GetPageCount()-1, wx.Colour(255, 165, 0)) 

107 self._panel.update_log() 

108 self.register_shortcut('CtrlCmd-C', lambda e: self._panel.Copy()) 

109 if show_tab: 

110 self.notebook.show_tab(self._panel)