|
1 | 1 | # A part of NonVisual Desktop Access (NVDA) |
2 | | -# Copyright (C) 2007-2020 NV Access Limited, Rui Batista, Joseph Lee, Leonard de Ruijter, Babbage B.V. |
| 2 | +# Copyright (C) 2007-2020 NV Access Limited, Rui Batista, Joseph Lee, Leonard de Ruijter, Babbage B.V., Accessolutions, Julien Cochuyt |
3 | 3 | # This file is covered by the GNU General Public License. |
4 | 4 | # See the file COPYING for more details. |
5 | 5 |
|
@@ -113,6 +113,11 @@ class Logger(logging.Logger): |
113 | 113 | DEBUGWARNING = 15 |
114 | 114 | OFF = 100 |
115 | 115 |
|
| 116 | + #: The start position of a fragment of the log file as marked with |
| 117 | + #: L{markFragmentStart} for later retrieval using L{getFragment}. |
| 118 | + #: @type: C{long} |
| 119 | + fragmentStart = None |
| 120 | + |
116 | 121 | def _log(self, level, msg, args, exc_info=None, extra=None, codepath=None, activateLogViewer=False, stack_info=None): |
117 | 122 | if not extra: |
118 | 123 | extra={} |
@@ -189,6 +194,52 @@ def exception(self, msg="", exc_info=True, **kwargs): |
189 | 194 | return |
190 | 195 | self._log(level, msg, (), exc_info=exc_info, **kwargs) |
191 | 196 |
|
| 197 | + def markFragmentStart(self): |
| 198 | + """Mark the current end of the log file as the start position of a |
| 199 | + fragment to be later retrieved by L{getFragment}. |
| 200 | + @returns: Whether a log file is in use and a position could be marked |
| 201 | + @rtype: bool |
| 202 | + """ |
| 203 | + if ( |
| 204 | + not globalVars.appArgs |
| 205 | + or globalVars.appArgs.secure |
| 206 | + or not globalVars.appArgs.logFileName |
| 207 | + or not self.handlers |
| 208 | + or not isinstance(self.handlers[0], FileHandler) |
| 209 | + ): |
| 210 | + return False |
| 211 | + import codecs |
| 212 | + with codecs.open(globalVars.appArgs.logFileName, "r", encoding="UTF-8") as f: |
| 213 | + # io.IOBase.seek: whence=2 -- end of stream |
| 214 | + f.seek(0, whence=2) |
| 215 | + self.fragmentStart = f.tell() |
| 216 | + return True |
| 217 | + |
| 218 | + def getFragment(self): |
| 219 | + """Retrieve a fragment of the log starting from the position marked using |
| 220 | + L{markFragmentStart}. |
| 221 | + If L{fragmentStart} does not point to the current end of the log file, it |
| 222 | + is reset to C{None} after reading the fragment. |
| 223 | + @returns: The text of the fragment, or C{None} if L{fragmentStart} is None. |
| 224 | + @rtype: str |
| 225 | + """ |
| 226 | + if ( |
| 227 | + self.fragmentStart is None |
| 228 | + or not globalVars.appArgs |
| 229 | + or globalVars.appArgs.secure |
| 230 | + or not globalVars.appArgs.logFileName |
| 231 | + or not self.handlers |
| 232 | + or not isinstance(self.handlers[0], FileHandler) |
| 233 | + ): |
| 234 | + return None |
| 235 | + import codecs |
| 236 | + with codecs.open(globalVars.appArgs.logFileName, "r", encoding="UTF-8") as f: |
| 237 | + f.seek(self.fragmentStart) |
| 238 | + fragment = f.read() |
| 239 | + if fragment: |
| 240 | + self.fragmentStart = None |
| 241 | + return fragment |
| 242 | + |
192 | 243 | class RemoteHandler(logging.Handler): |
193 | 244 |
|
194 | 245 | def __init__(self): |
|
0 commit comments