jenkins-bot has submitted this change and it was merged.
Change subject: [FIX/IMPROV] Add option class to output the list
......................................................................
[FIX/IMPROV] Add option class to output the list
The alternatives output by `listAlternatives` are zero-based while the option
is one-based since 9c590fed. This adds the option class `OutputProxyOption`
which just calls `output` of the class used for it.
One class which can be used is `SequenceOutputter` which can be used together
with `ListOption` and does just create a string listing the contents of a list.
That class is creating a one-based string which is output. It also has a
flexible indentation depending on the number of alternatives.
Using the separate `SequenceOutputter` class has the advantage that it's
possible to create such strings without being tied into using an option.
Bug: T107272
Change-Id: If843cb0af86292b6a6ab426662d4831503ea47b5
---
M pywikibot/bot.py
M pywikibot/bot_choice.py
A pywikibot/tools/formatter.py
M scripts/solve_disambiguation.py
A tests/tools_formatter_tests.py
5 files changed, 122 insertions(+), 21 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 9b15a39..c0a119c 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -86,7 +86,7 @@
from pywikibot import version
from pywikibot.bot_choice import ( # noqa: unused imports
Option, StandardOption, NestedOption, IntegerOption, ContextOption,
- ListOption, HighlightContextOption,
+ ListOption, OutputProxyOption, HighlightContextOption,
ChoiceException, QuitKeyboardInterrupt,
)
from pywikibot.logging import CRITICAL, ERROR, INFO, WARNING # noqa: unused
@@ -360,6 +360,7 @@
add_init_routine(init_handlers)
+
# User input functions
diff --git a/pywikibot/bot_choice.py b/pywikibot/bot_choice.py
index 5a56915..95e2144 100755
--- a/pywikibot/bot_choice.py
+++ b/pywikibot/bot_choice.py
@@ -125,6 +125,20 @@
self.option.lower() == value.lower())
+class OutputProxyOption(OutputOption, StandardOption):
+
+ """An option which calls output of the given output
class."""
+
+ def __init__(self, option, shortcut, output):
+ """Create a new option for the given sequence."""
+ super(OutputProxyOption, self).__init__(option, shortcut)
+ self._outputter = output
+
+ def output(self):
+ """Output the contents."""
+ self._outputter.output()
+
+
class NestedOption(OutputOption, StandardOption):
"""
diff --git a/pywikibot/tools/formatter.py b/pywikibot/tools/formatter.py
new file mode 100644
index 0000000..d2f15e2
--- /dev/null
+++ b/pywikibot/tools/formatter.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+"""Module containing various formatting related
utilities."""
+#
+# (C) Pywikibot team, 2015
+#
+# Distributed under the terms of the MIT license.
+#
+from __future__ import absolute_import, unicode_literals
+
+__version__ = '$Id$'
+
+import math
+
+from pywikibot.logging import output
+
+
+class SequenceOutputter(object):
+
+ """
+ A class formatting a list of items.
+
+ It is possible to customize the appearance by changing C{format_string}
+ which is used by C{str.format} with C{index}, C{width} and C{item}. Each
+ line is joined by the separator and the complete text is surrounded by the
+ prefix and the suffix. All three are by default a new line. The index starts
+ at 1 and for the width it's using the width of the sequence's length written
+ as a decimal number. So a length of 100 will result in a with of 3 and a
+ length of 99 in a width of 2.
+
+ It is iterating over C{self.sequence} to generate the text. That sequence
+ can be any iterator but the result is better when it has an order.
+ """
+
+ format_string = ' {index:>{width}} - {item}'
+ separator = '\n'
+ prefix = '\n'
+ suffix = '\n'
+
+ def __init__(self, sequence):
+ """Create a new instance with a reference to the
sequence."""
+ super(SequenceOutputter, self).__init__()
+ self.sequence = sequence
+
+ def format_list(self):
+ """Create the text with one item on each line."""
+ if self.sequence:
+ # Width is only defined when the length is greater 0
+ width = int(math.log10(len(self.sequence))) + 1
+ content = self.separator.join(
+ self.format_string.format(index=i, item=item, width=width)
+ for i, item in enumerate(self.sequence, start=1))
+ else:
+ content = ''
+ return self.prefix + content + self.suffix
+
+ def output(self):
+ """Output the text of the current sequence."""
+ output(self.format_list())
diff --git a/scripts/solve_disambiguation.py b/scripts/solve_disambiguation.py
index 2e71f1a..cca88ab 100755
--- a/scripts/solve_disambiguation.py
+++ b/scripts/solve_disambiguation.py
@@ -91,8 +91,9 @@
from pywikibot import pagegenerators, config, i18n
from pywikibot.bot import (
Bot, QuitKeyboardInterrupt,
- StandardOption, HighlightContextOption, ListOption,
+ StandardOption, HighlightContextOption, ListOption, OutputProxyOption,
)
+from pywikibot.tools.formatter import SequenceOutputter
# Disambiguation Needed template
dn_template = {
@@ -452,28 +453,14 @@
pass
-class ListAlternativesOption(StandardOption):
-
- """List the alternatives."""
-
- def __init__(self, option, shortcut, bot):
- """Constructor."""
- super(ListAlternativesOption, self).__init__(option, shortcut, False)
- self._bot = bot
-
- def result(self, value):
- """List the alternatives."""
- self._bot.listAlternatives()
-
-
-class AddAlternativeOption(ListAlternativesOption):
+class AddAlternativeOption(OutputProxyOption):
"""Add a new alternative."""
def result(self, value):
"""Add the alternative and then list them."""
newAlternative = pywikibot.input(u'New alternative:')
- self._bot.alternatives.append(newAlternative)
+ self._outputter.sequence.append(newAlternative)
super(AddAlternativeOption, self).result(value)
@@ -763,8 +750,11 @@
if not edited:
options += [ShowPageOption('show disambiguation page',
'd',
m.start(), disambPage)]
- options += [ListAlternativesOption('list', 'l', self),
- AddAlternativeOption('add new', 'a', self)]
+ options += [
+ OutputProxyOption('list', 'l',
+ SequenceOutputter(self.alternatives)),
+ AddAlternativeOption('add new', 'a',
+ SequenceOutputter(self.alternatives))]
if edited:
options += [StandardOption('save in this form',
'x')]
@@ -1054,7 +1044,7 @@
self.alternatives.sort(key=lambda x: x.lower())
else:
self.alternatives.sort()
- self.listAlternatives()
+ SequenceOutputter(self.alternatives).output()
gen = ReferringPageGeneratorWithIgnore(disambPage, self.primary,
minimum=self.minimum)
diff --git a/tests/tools_formatter_tests.py b/tests/tools_formatter_tests.py
new file mode 100644
index 0000000..256f2ed
--- /dev/null
+++ b/tests/tools_formatter_tests.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+"""Tests for the C{pywikibot.tools.formatter} module."""
+#
+# (C) Pywikibot team, 2015
+#
+# Distributed under the terms of the MIT license.
+#
+from __future__ import unicode_literals
+
+__version__ = '$Id$'
+#
+from pywikibot.tools import formatter
+
+from tests.aspects import unittest, TestCase
+
+
+class TestListOutputter(TestCase):
+
+ """Test ListFormatter class."""
+
+ net = False
+
+ def test_SequenceOutputter(self):
+ """Test format method."""
+ options = ['foo', 'bar']
+ outputter = formatter.SequenceOutputter(options)
+ self.assertEqual(outputter.format_list(), '\n 1 - foo\n 2 - bar\n')
+ outputter.format_string = '({index} {width} {item})'
+ self.assertEqual(outputter.format_list(), '\n(1 1 foo)\n(2 1 bar)\n')
+ outputter.format_string = '{item}'
+ self.assertEqual(outputter.format_list(), '\nfoo\nbar\n')
+
+
+if __name__ == '__main__':
+ try:
+ unittest.main()
+ except SystemExit:
+ pass
--
To view, visit
https://gerrit.wikimedia.org/r/227679
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: If843cb0af86292b6a6ab426662d4831503ea47b5
Gerrit-PatchSet: 6
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>