Skip to content

Commit d02effe

Browse files
Merge dc23104 into 0be9ee0
2 parents 0be9ee0 + dc23104 commit d02effe

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

source/globalCommands.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#A part of NonVisual Desktop Access (NVDA)
44
#This file is covered by the GNU General Public License.
55
#See the file COPYING for more details.
6-
#Copyright (C) 2006-2018 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Rui Batista, Joseph Lee, Leonard de Ruijter, Derek Riemer, Babbage B.V., Davy Kager, Ethan Holliger, Łukasz Golonka
6+
#Copyright (C) 2006-2020 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Rui Batista, Joseph Lee, Leonard de Ruijter, Derek Riemer, Babbage B.V., Davy Kager, Ethan Holliger, Łukasz Golonka, Accessolutions, Julien Cochuyt
77

88
import time
99
import itertools
@@ -1618,6 +1618,42 @@ def script_navigatorObject_devInfo(self,gesture):
16181618
script_navigatorObject_devInfo.__doc__ = _("Logs information about the current navigator object which is useful to developers and activates the log viewer so the information can be examined.")
16191619
script_navigatorObject_devInfo.category=SCRCAT_TOOLS
16201620

1621+
@script(
1622+
# Translators: Input help mode message for a command to delimit then
1623+
# copy a fragment of the log to clipboard
1624+
description=_(
1625+
"Mark the current end of the log as the start of the fragment to be"
1626+
" copied to clipboard by pressing again."
1627+
),
1628+
category=SCRCAT_TOOLS,
1629+
gesture="kb:NVDA+control+shift+f1"
1630+
)
1631+
def script_log_markStartThenCopy(self, gesture):
1632+
if globalVars.appArgs.secure:
1633+
return
1634+
if log.fragmentStart is None:
1635+
if log.markFragmentStart():
1636+
# Translators: Message when marking the start of a fragment of the log file for later copy
1637+
# to clipboard
1638+
ui.message(_("Log fragment start position marked, press again to copy to clipboard"))
1639+
else:
1640+
# Translators: Message when failed to mark the start of a
1641+
# fragment of the log file for later copy to clipboard
1642+
ui.message(_("Unable to mark log position"))
1643+
return
1644+
text = log.getFragment()
1645+
if not text:
1646+
# Translators: Message when attempting to copy an empty fragment of the log file
1647+
ui.message(_("No new log entry to copy"))
1648+
return
1649+
if api.copyToClip(text):
1650+
# Translators: Message when a fragment of the log file has been
1651+
# copied to clipboard
1652+
ui.message(_("Log fragment copied to clipboard"))
1653+
else:
1654+
# Translators: Presented when unable to copy to the clipboard because of an error.
1655+
ui.message(_("Unable to copy"))
1656+
16211657
@script(
16221658
# Translators: Input help mode message for Open user configuration directory command.
16231659
description=_("Opens NVDA configuration directory for the current user."),
@@ -1628,6 +1664,7 @@ def script_openUserConfigurationDirectory(self, gesture):
16281664
return
16291665
import systemUtils
16301666
systemUtils.openUserConfigurationDirectory()
1667+
>>>>>>> master
16311668

16321669
def script_toggleProgressBarOutput(self,gesture):
16331670
outputMode=config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]

source/logHandler.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# 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
33
# This file is covered by the GNU General Public License.
44
# See the file COPYING for more details.
55

@@ -113,6 +113,11 @@ class Logger(logging.Logger):
113113
DEBUGWARNING = 15
114114
OFF = 100
115115

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+
116121
def _log(self, level, msg, args, exc_info=None, extra=None, codepath=None, activateLogViewer=False, stack_info=None):
117122
if not extra:
118123
extra={}
@@ -189,6 +194,52 @@ def exception(self, msg="", exc_info=True, **kwargs):
189194
return
190195
self._log(level, msg, (), exc_info=exc_info, **kwargs)
191196

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+
192243
class RemoteHandler(logging.Handler):
193244

194245
def __init__(self):

0 commit comments

Comments
 (0)