jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] Replace with Link if all or only target selected ......................................................................
[FIX] Replace with Link if all or only target selected
The options 'Change link target' and 'Change complete link' previously returned just a string as a shortcut. But with ad2cf8aa if a callback returns a string it's inserted directly.
It adds the option to replace the target and the section but not the label and to replace everything to disambredir.
It also changes the default title behaviour in replace_link that it's using also the section like a link in MW would behave. If the replacement is Link('Foo#Bar') it's interpreted as [[Foo#Bar]] so that the title is Foo#Bar.
Bug: T104805 Change-Id: Ic6f3d1dd0d2e56a639ebf74e89834cf02d7b224a --- M pywikibot/bot.py M pywikibot/textlib.py M scripts/disambredir.py M tests/disambredir_tests.py M tests/link_tests.py M tests/textlib_tests.py 6 files changed, 111 insertions(+), 28 deletions(-)
Approvals: John Vandenberg: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py index 57e8ec0..2f85289 100644 --- a/pywikibot/bot.py +++ b/pywikibot/bot.py @@ -751,19 +751,34 @@
"""A choice returning a mix of the link new and current link."""
- def __init__(self, option, shortcut, replacer, section): + def __init__(self, option, shortcut, replacer, replace_section, + replace_label): """Constructor.""" super(LinkChoice, self).__init__(option, shortcut, replacer) - self._section = section + self._section = replace_section + self._label = replace_label
def handle(self): """Handle by either applying the new section or label.""" + kwargs = {} if self._section: - kwargs = {'section': self.replacer._new.section, - 'label': self.replacer.current_link.anchor} + kwargs['section'] = self.replacer._new.section else: - kwargs = {'section': self.replacer.current_link.section, - 'label': self.replacer._new.anchor} + kwargs['section'] = self.replacer.current_link.section + if self._label: + if self.replacer._new.anchor is None: + kwargs['label'] = self.replacer._new.canonical_title() + if self.replacer._new.section: + kwargs['label'] += '#' + self.replacer._new.section + else: + kwargs['label'] = self.replacer._new.anchor + else: + if self.replacer.current_link.anchor is None: + kwargs['label'] = self.replacer.current_groups['title'] + if self.replacer.current_groups['section']: + kwargs['label'] += '#' + self.replacer.current_groups['section'] + else: + kwargs['label'] = self.replacer.current_link.anchor return pywikibot.Link.create_separated( self.replacer._new.canonical_title(), self.replacer._new.site, **kwargs) @@ -862,14 +877,14 @@ ] if self._new: self._own_choices += [ - ('replace', StaticChoice('Change link target', 't', - self._new.canonical_title())), + ('replace', LinkChoice('Change link target', 't', self, + False, False)), ('replace_section', LinkChoice('Change link target and section', - 's', self, True)), + 's', self, True, False)), ('replace_label', LinkChoice('Change link target and label', - 'l', self, False)), - ('replace_all', StaticChoice('Change complete link', 'c', - self._new)), + 'l', self, False, True)), + ('replace_all', LinkChoice('Change complete link', 'c', self, + True, True)), ]
self.additional_choices = [] diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py index 32b38e7..9984f0f 100644 --- a/pywikibot/textlib.py +++ b/pywikibot/textlib.py @@ -514,6 +514,12 @@ 'a sequence, a Link or a basestring but ' 'is "{0}"'.format(type(replacement)))
+ def title_section(l): + title = l.title + if l.section: + title += '#' + l.section + return title + if isinstance(replace, collections.Sequence): if len(replace) != 2: raise ValueError('When used as a sequence, the "replace" ' @@ -634,20 +640,16 @@ if is_link: # Use link's label link_text = replacement.anchor - if link_text is None: - link_text = new_page_title - must_piped = False - else: - must_piped = True + must_piped = link_text is not None section = replacement.section else: must_piped = True section = groups['section']
if section: - section = '#' + section - else: - section = '' + new_page_title += '#' + section + if link_text is None: + link_text = new_page_title
# Parse the link text and check if it points to the same page parsed_link_text = pywikibot.Link(link_text, replacement.site) @@ -656,15 +658,17 @@ except InvalidTitle: pass else: + parsed_link_title = title_section(parsed_link_text) + replacement_title = title_section(replacement) # compare title, but only with parts if linktrail works - if not linktrail.sub('', parsed_link_text.title[len(replacement.title):]): + if not linktrail.sub('', parsed_link_title[len(replacement_title):]): # TODO: This must also compare everything that was used as a # prefix (in case insensitive) - must_piped = (not parsed_link_text.title.startswith(replacement.title) or + must_piped = (not parsed_link_title.startswith(replacement_title) or parsed_link_text.namespace != replacement.namespace)
- if section or must_piped: - newlink = '[[{0}{1}|{2}]]'.format(new_page_title, section, link_text) + if must_piped: + newlink = '[[{0}|{1}]]'.format(new_page_title, link_text) else: newlink = '[[{0}]]{1}'.format(link_text[:len(new_page_title)], link_text[len(new_page_title):]) diff --git a/scripts/disambredir.py b/scripts/disambredir.py index 46d6afe..0789afc 100755 --- a/scripts/disambredir.py +++ b/scripts/disambredir.py @@ -48,6 +48,8 @@ replace_callback = InteractiveReplace( old, new, default='n', automatic_quit=False) replace_callback.allow_replace_label = True + replace_callback.allow_replace_section = True + replace_callback.allow_replace_all = True return replace_callback
def treat_page(self): diff --git a/tests/disambredir_tests.py b/tests/disambredir_tests.py index 6598a5d..b8487ec 100644 --- a/tests/disambredir_tests.py +++ b/tests/disambredir_tests.py @@ -70,6 +70,7 @@ cls.page = pywikibot.Page(cls.site, 'User:BobBot/Test disambig') cls.page.linkedPages = fixed_generator( [pywikibot.Page(cls.site, 'User:BobBot/Redir'), + pywikibot.Page(cls.site, 'User:BobBot/Redir2'), pywikibot.Page(cls.site, 'Main Page')])
def bot_save(self, page, *args, **kwargs): @@ -83,6 +84,8 @@ super(TestDisambigurationRedirectBot, self).setUp() self.page.text = ('[[User:BobBot/Redir#Foo|Bar]]\n' '[[User:BobBot/Redir|Baz]]\n' + '[[User:BobBot/Redir2]]\n' + '[[user:BobBot/Redir2]]\n' '[[Main Page|Label]]\n') self.bot = disambredir.DisambiguationRedirectBot(generator=[self.page])
@@ -95,6 +98,8 @@ self.assertEqual(self.page.text, '[[User:BobBot/Redir#Foo|Bar]]\n' '[[User:BobBot/Redir|Baz]]\n' + '[[User:BobBot/Redir2]]\n' + '[[user:BobBot/Redir2]]\n' '[[Main Page|Label]]\n')
def test_unlink(self): @@ -102,7 +107,8 @@ self._patch_create_callback('u') self.bot.run() self.assertEqual(self.page.text, - 'Bar\nBaz\n[[Main Page|Label]]\n') + 'Bar\nBaz\nUser:BobBot/Redir2\nuser:BobBot/Redir2\n' + '[[Main Page|Label]]\n')
def test_replace_target(self): """Test replacing just target page.""" @@ -111,15 +117,41 @@ self.assertEqual(self.page.text, '[[Main Page#Foo|Bar]]\n' '[[Main Page|Baz]]\n' + '[[Main Page|User:BobBot/Redir2]]\n' + '[[Main Page|user:BobBot/Redir2]]\n' '[[Main Page|Label]]\n')
- def test_replace_all(self): + def test_replace_label(self): """Test replacing target and label.""" self._patch_create_callback('l') self.bot.run() self.assertEqual(self.page.text, '[[Main Page#Foo|Main Page]]\n' '[[Main Page]]\n' + '[[Main Page|Main Page#What we do on this wiki]]\n' + '[[Main Page|Main Page#What we do on this wiki]]\n' + '[[Main Page|Label]]\n') + + def test_replace_section(self): + """Test replacing target including section.""" + self._patch_create_callback('s') + self.bot.run() + self.assertEqual(self.page.text, + '[[Main Page|Bar]]\n' + '[[Main Page|Baz]]\n' + '[[Main Page#What we do on this wiki|User:BobBot/Redir2]]\n' + '[[Main Page#What we do on this wiki|user:BobBot/Redir2]]\n' + '[[Main Page|Label]]\n') + + def test_replace_all(self): + """Test replacing target including section and label.""" + self._patch_create_callback('c') + self.bot.run() + self.assertEqual(self.page.text, + '[[Main Page]]\n' + '[[Main Page]]\n' + '[[Main Page#What we do on this wiki]]\n' + '[[Main Page#What we do on this wiki]]\n' '[[Main Page|Label]]\n')
diff --git a/tests/link_tests.py b/tests/link_tests.py index 253da43..f271bb5b 100644 --- a/tests/link_tests.py +++ b/tests/link_tests.py @@ -22,6 +22,36 @@ )
+class TestCreateSeparated(DefaultDrySiteTestCase): + + """Test C{Link.create_separated}.""" + + def _test_link(self, link, page, section, label): + """Test the separate contents of the link.""" + self.assertIs(link.site, self.site) + self.assertEqual(link.title, page) + if section is None: + self.assertIsNone(link.section) + else: + self.assertEqual(link.section, section) + if label is None: + self.assertIsNone(link.anchor) + else: + self.assertEqual(link.anchor, label) + + def test(self): + """Test combinations of parameters.""" + self._test_link(Link.create_separated('Foo', self.site), + 'Foo', None, None) + self._test_link(Link.create_separated('Foo', self.site, section='Bar'), + 'Foo', 'Bar', None) + self._test_link(Link.create_separated('Foo', self.site, label='Baz'), + 'Foo', None, 'Baz') + self._test_link(Link.create_separated('Foo', self.site, section='Bar', + label='Baz'), + 'Foo', 'Bar', 'Baz') + + # ---- Tests checking if the parser does (not) accept (in)valid titles
diff --git a/tests/textlib_tests.py b/tests/textlib_tests.py index a08db27..29d2741 100644 --- a/tests/textlib_tests.py +++ b/tests/textlib_tests.py @@ -547,7 +547,7 @@ self._count = 0 # buffer number of found instances self.assertEqual( textlib.replace_links(self.text, callback, self.wp_site), - 'Hello [[World]], [[how|are]] [[1#section|1]]? Are [[2]] a ' + 'Hello [[World]], [[how|are]] [[1#section]]? Are [[2]] a ' '[[bug:1337]]?') del self._count
@@ -641,7 +641,7 @@ textlib.replace_links(source_text, ('Foo', pywikibot.Link('Bar#snafu', self.wp_site)), self.wp_site), - '[[Bar#snafu|Bar]]') + '[[Bar#snafu]]') self.assertEqual( textlib.replace_links(source_text, ('Foo', 'Bar|foo'), self.wp_site), '[[Bar#bar|baz]]')
pywikibot-commits@lists.wikimedia.org