jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/750788 )
Change subject: [FEAT] Add support for API:Redirects ......................................................................
[FEAT] Add support for API:Redirects
Change-Id: I282b91d510cf7934be585393535c23d215c09f61 --- M pywikibot/page/__init__.py M pywikibot/site/__init__.py M pywikibot/site/_generators.py M pywikibot/site/_namespace.py M tests/site_tests.py 5 files changed, 119 insertions(+), 2 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/page/__init__.py b/pywikibot/page/__init__.py index 346698d..903d7c0 100644 --- a/pywikibot/page/__init__.py +++ b/pywikibot/page/__init__.py @@ -65,7 +65,7 @@ ) from pywikibot.page._decorators import allow_asynchronous from pywikibot.page._revision import Revision -from pywikibot.site import DataSite, Namespace +from pywikibot.site import DataSite, Namespace, NamespaceArgType from pywikibot.tools import ( ComparableMixin, compute_file_hash, @@ -964,6 +964,34 @@ content=content )
+ def redirects( + self, + *, + filter_fragments: Optional[bool] = None, + namespaces: NamespaceArgType = None, + total: Optional[int] = None, + content: bool = False + ) -> 'Iterable[pywikibot.Page]': + """ + Return an iterable of redirects to this page. + + :param filter_fragments: If True, only return redirects with fragments. + If False, only return redirects without fragments. If None, return + both (no filtering). + :param namespaces: only return redirects from these namespaces + :param total: maximum number of redirects to retrieve in total + :param content: load the current content of each redirect + + .. versionadded:: 7.0 + """ + return self.site.page_redirects( + self, + filter_fragments=filter_fragments, + namespaces=namespaces, + total=total, + content=content, + ) + def protection(self) -> dict: """Return a dictionary reflecting page protections.""" return self.site.page_restrictions(self) diff --git a/pywikibot/site/__init__.py b/pywikibot/site/__init__.py index a009065..55ddc66 100644 --- a/pywikibot/site/__init__.py +++ b/pywikibot/site/__init__.py @@ -8,6 +8,7 @@ from pywikibot.site._basesite import BaseSite from pywikibot.site._datasite import DataSite from pywikibot.site._namespace import Namespace, NamespacesDict +from pywikibot.site._namespace import NamespaceArgType # noqa: F401 from pywikibot.site._obsoletesites import ClosedSite, RemovedSite from pywikibot.site._siteinfo import Siteinfo from pywikibot.site._tokenwallet import TokenWallet diff --git a/pywikibot/site/_generators.py b/pywikibot/site/_generators.py index d73e8fa..d40a54c 100644 --- a/pywikibot/site/_generators.py +++ b/pywikibot/site/_generators.py @@ -14,7 +14,7 @@
import pywikibot import pywikibot.family -from pywikibot.backports import Dict, List +from pywikibot.backports import Dict, Iterable, List from pywikibot.data import api from pywikibot.exceptions import ( APIError, @@ -25,6 +25,7 @@ UserRightsError, ) from pywikibot.site._decorators import need_right, need_version +from pywikibot.site._namespace import NamespaceArgType from pywikibot.tools import ( deprecated, filter_unique, @@ -288,6 +289,39 @@ namespaces=namespaces, total=total, g_content=content, **eiargs)
+ @need_version('1.24') + def page_redirects( + self, + page: 'pywikibot.Page', + *, + filter_fragments: Optional[bool] = None, + namespaces: NamespaceArgType = None, + total: Optional[int] = None, + content: bool = False + ) -> 'Iterable[pywikibot.Page]': + """Iterale all redirects to the given page. + + :see: https://www.mediawiki.org/wiki/API:Redirects + + :param page: The Page to get redirects for. + :param filter_fragments: If True, only return redirects with fragments. + If False, only return redirects without fragments. If None, return + both (no filtering). + :param namespaces: Only return redirects from the namespaces + :param total: maximum number of redirects to retrieve in total + :param content: load the current content of each redirect + + .. versionadded:: 7.0 + """ + rdargs = { + 'titles': page.title(with_section=False).encode(self.encoding()), + } + if filter_fragments is not None: + rdargs['grdshow'] = ('' if filter_fragments else '!') + 'fragment' + return self._generator(api.PageGenerator, type_arg='redirects', + namespaces=namespaces, total=total, + g_content=content, **rdargs) + def pagereferences(self, page, *, follow_redirects=False, filter_redirects=None, with_template_inclusion=True, only_template_inclusion=False, namespaces=None, diff --git a/pywikibot/site/_namespace.py b/pywikibot/site/_namespace.py index 4f7adba..dbc51de 100644 --- a/pywikibot/site/_namespace.py +++ b/pywikibot/site/_namespace.py @@ -12,6 +12,10 @@ from pywikibot.tools import ComparableMixin, SelfCallMixin
+NamespaceIDType = 'Union[int, str, Namespace]' +NamespaceArgType = 'Union[NamespaceIDType, Iterable[NamespaceIDType], None]' + + class BuiltinNamespace(IntEnum):
"""Builtin namespace enum.""" diff --git a/tests/site_tests.py b/tests/site_tests.py index 73eac0b..4ee3dad 100644 --- a/tests/site_tests.py +++ b/tests/site_tests.py @@ -369,6 +369,56 @@ self.assertLessEqual(no_redirs, embedded_ns_0) self.assertLessEqual(embedded_ns_0, embedded_ns_0_2)
+ def test_page_redirects(self): + """Test Site.page_redirects.""" + if self.get_site().mw_version < '1.24': + self.skipTest('site.page_redirects() needs mw 1.24') + + redirects_ns_0 = set(self.site.page_redirects( + self.mainpage, + namespaces=0, + )) + redirects_ns_0_4 = set(self.site.page_redirects( + self.mainpage, + namespaces=[0, 4], + )) + redirects_ns_0_frag = set(self.site.page_redirects( + self.mainpage, + filter_fragments=True, + namespaces=0, + )) + redirects_ns_0_nofrag = set(self.site.page_redirects( + self.mainpage, + filter_fragments=False, + namespaces=0, + )) + + self.assertLessEqual(redirects_ns_0, redirects_ns_0_4) + self.assertLessEqual(redirects_ns_0_frag, redirects_ns_0) + self.assertLessEqual(redirects_ns_0_nofrag, redirects_ns_0) + + for redirect in redirects_ns_0_4: + self.assertIsInstance(redirect, pywikibot.Page) + self.assertIn(redirect.namespace(), [0, 4]) + self.assertTrue(redirect.isRedirectPage()) + + for redirect in redirects_ns_0: + self.assertEqual(redirect.namespace(), 0) + + for redirect in redirects_ns_0_frag: + redirect_target = redirect.getRedirectTarget() + self.assertIsNotNone(redirect_target.section()) + redirect_target = pywikibot.Page( + redirect_target.site, + redirect_target.title(with_section=False) + ) + self.assertEqual(redirect_target, self.mainpage) + + for redirect in redirects_ns_0_nofrag: + redirect_target = redirect.getRedirectTarget() + self.assertIsNone(redirect_target.section()) + self.assertEqual(redirect_target, self.mainpage) + def test_pagecategories(self): """Test Site.pagecategories.""" for cat in self.site.pagecategories(self.mainpage):
pywikibot-commits@lists.wikimedia.org