jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] Editor: Support spaces, delete always and warn on \n (etc)
......................................................................
[FIX] Editor: Support spaces, delete always and warn on \n (etc)
This support spaces in the editor file name and warns if it contains a
string literal like \n with Windows because the backslash was used as a
path delimiter without escaping them.
The pywikibot.editor.TextEditor.command method has been deprecated,
because outside scripts don't require access anyway and this makes it
possible to return a list of command segments.
This now deletes the temporary file on any case, also when there were no
changes done. And it uses the more secure 'mkstemp' function.
Bug: T86481
Change-Id: If7e9feee49acd1147c5554cdd74a7ad0758397c5
---
M pywikibot/config2.py
M pywikibot/editor.py
2 files changed, 58 insertions(+), 32 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index e7df241..6e1a27e 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -886,6 +886,17 @@
elif transliteration_target in ('None', 'none'):
transliteration_target = None
+if sys.platform == 'win32' and editor:
+ # single character string literals from
+ # https://docs.python.org/2/reference/lexical_analysis.html#string-literals
+ # encode('unicode-escape') also changes Unicode characters
+ if set(editor) & set('\a\b\f\n\r\t\v'):
+ print('WARNING: The editor path contains probably invalid escaped '
+ 'characters. Make sure to use a raw-string (r"..." or r\'...\'),
'
+ 'forward slashs as a path delimiter or to escape the normal '
+ 'path delimiter.')
+
+
# Fix up default site
if family == 'wikipedia' and mylang == 'language':
print("WARNING: family and mylang are not set.\n"
diff --git a/pywikibot/editor.py b/pywikibot/editor.py
index d3e268a..b928dc7 100644
--- a/pywikibot/editor.py
+++ b/pywikibot/editor.py
@@ -11,50 +11,64 @@
__version__ = '$Id$'
#
-import os
-import tempfile
import codecs
+import os
+import subprocess
+import tempfile
+
import pywikibot
from pywikibot import config
+from pywikibot.tools import deprecated
class TextEditor(object):
"""Text editor."""
- def command(self, tempFilename, text, jumpIndex=None):
+ def _command(self, file_name, text, jump_index=None):
"""Return editor selected in user-config.py."""
- command = config.editor
- if jumpIndex:
+ if jump_index:
# Some editors make it possible to mark occurrences of substrings,
# or to jump to the line of the first occurrence.
# TODO: Find a better solution than hardcoding these, e.g. a config
# option.
- line = text[:jumpIndex].count('\n')
- column = jumpIndex - (text[:jumpIndex].rfind('\n') + 1)
+ line = text[:jump_index].count('\n')
+ column = jump_index - (text[:jump_index].rfind('\n') + 1)
else:
line = column = 0
# Linux editors. We use startswith() because some users might use
# parameters.
if config.editor.startswith('kate'):
- command += " -l %i -c %i" % (line + 1, column + 1)
+ command = ['-l', '%i' % (line + 1), '-c', '%i' % (column + 1)]
elif config.editor.startswith('gedit'):
- command += " +%i" % (line + 1) # seems not to support columns
+ command = ['+%i' % (line + 1)] # seems not to support columns
elif config.editor.startswith('emacs'):
- command += " +%i" % (line + 1) # seems not to support columns
+ command = ['+%i' % (line + 1)] # seems not to support columns
elif config.editor.startswith('jedit'):
- command += " +line:%i" % (line + 1) # seems not to support columns
+ command = ['+line:%i' % (line + 1)] # seems not to support columns
elif config.editor.startswith('vim'):
- command += " +%i" % (line + 1) # seems not to support columns
+ command = ['+%i' % (line + 1)] # seems not to support columns
elif config.editor.startswith('nano'):
- command += " +%i,%i" % (line + 1, column + 1)
+ command = ['+%i,%i' % (line + 1, column + 1)]
# Windows editors
elif config.editor.lower().endswith('notepad++.exe'):
- command += " -n%i" % (line + 1) # seems not to support columns
+ command = ['-n%i' % (line + 1)] # seems not to support columns
+ else:
+ command = []
- command += ' %s' % tempFilename
- pywikibot.log(u'Running editor: %s' % command)
+ command = [config.editor] + command + [file_name]
+ pywikibot.log(u'Running editor: %s' % TextEditor._concat(command))
return command
+
+ @staticmethod
+ def _concat(command):
+ return ' '.join("'{0}'".format(part) if ' ' in part else part
+ for part in command)
+
+ @deprecated('_command (should not be used from the outside)')
+ def command(self, tempFilename, text, jumpIndex=None):
+ """Return editor selected in user-config.py."""
+ return TextEditor._concat(self._command(tempFilename, text, jumpIndex))
def edit(self, text, jumpIndex=None, highlight=None):
"""
@@ -73,24 +87,25 @@
@rtype: unicode or None
"""
if config.editor:
- tempFilename = '%s.%s' % (tempfile.mktemp(),
+ tempFilename = '%s.%s' % (tempfile.mkstemp()[1],
config.editor_filename_extension)
- with codecs.open(tempFilename, 'w',
- encoding=config.editor_encoding) as tempFile:
- tempFile.write(text)
- creationDate = os.stat(tempFilename).st_mtime
- command = self.command(tempFilename, text, jumpIndex)
- os.system(command)
- lastChangeDate = os.stat(tempFilename).st_mtime
- if lastChangeDate == creationDate:
- # Nothing changed
- return None
- else:
- with codecs.open(tempFilename, 'r',
- encoding=config.editor_encoding) as temp_file:
- newcontent = temp_file.read()
+ try:
+ with codecs.open(tempFilename, 'w',
+ encoding=config.editor_encoding) as tempFile:
+ tempFile.write(text)
+ creationDate = os.stat(tempFilename).st_mtime
+ subprocess.call(self._command(tempFilename, text, jumpIndex))
+ lastChangeDate = os.stat(tempFilename).st_mtime
+ if lastChangeDate == creationDate:
+ # Nothing changed
+ return None
+ else:
+ with codecs.open(tempFilename, 'r',
+ encoding=config.editor_encoding) as
temp_file:
+ newcontent = temp_file.read()
+ return newcontent
+ finally:
os.unlink(tempFilename)
- return newcontent
try:
import gui # noqa
--
To view, visit https://gerrit.wikimedia.org/r/184241
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: If7e9feee49acd1147c5554cdd74a7ad0758397c5
Gerrit-PatchSet: 4
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Ladsgroup <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: XZise <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits