jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/834501 )

Change subject: [IMPR] Enable pagegenerators options with 'move' and 'remove' 
actions
......................................................................

[IMPR] Enable pagegenerators options with 'move' and 'remove' actions

- enable GeneratorFactory usage with 'move' and 'remove' actions
- add generator option to CategoryMoveRobot which may hold page generators
- chain the category page generators
- intersect the  category page generators with page generators before
  processing
- call __init__ and exit() methods to enable BaseBot counters
- add counters to the methods
- update documentation

Bug: T318239
Change-Id: I65a06133c8afbc328d8c2b73e3a40839424db161
---
M scripts/category.py
1 file changed, 75 insertions(+), 17 deletions(-)

Approvals:
  Xqt: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/scripts/category.py b/scripts/category.py
index 7c22710..4402d2d 100755
--- a/scripts/category.py
+++ b/scripts/category.py
@@ -10,9 +10,11 @@
 *add*
     mass-add a category to a list of pages.
 *remove*
-    remove category tag from all pages in a category.
+    remove category tag from all pages in a category. If a pagegenerators
+    option is given, the intersection with category pages is processed.
 *move*
-    move all pages in a category to another category.
+    move all pages in a category to another category. If a pagegenerators
+    option is given, the intersection with category pages is processed.
 *tidy*
     tidy up a category by moving its pages into subcategories.
 *tree*
@@ -87,10 +89,7 @@
                 Also, the category to make a list of in the listify option.
  -to:         - The category to move to (for the move option).
               - Also, the name of the list to make in the listify option.
-       NOTE: If the category names have spaces in them you may need to use
-       a special syntax in your shell so that the names aren't treated as
-       separate parameters. For instance, in BASH, use single quotes,
-       e.g. -from:'Polar bears'.
+
  -batch       - Don't prompt to delete emptied categories (do it
                 automatically).
  -summary:    - Pick a custom edit summary for the bot.
@@ -106,7 +105,13 @@
  -depth:      - The max depth limit beyond which no subcategories will be
                 listed.

-If action is "add", the following additional options are supported:
+.. note:: If the category names have spaces in them you may need to use
+   a special syntax in your shell so that the names aren't treated as
+   separate parameters. For instance, in BASH, use single quotes, e.g.
+   ``-from:'Polar bears'``.
+
+If action is "add", "move" or "remove, the following additional options are
+supported:

 &params;

@@ -126,6 +131,16 @@
     python pwb.py category move -from:US -to:"United States"

 This will move all pages in the category US to the category United States.
+
+A pagegenerators option can be given with ``move`` and ``remove`` action:
+
+    pwb category -site:wikipedia:en remove -from:Hydraulics -cat:Pneumatics
+
+The sample above would remove 'Hydraulics' category from all pages which
+are also in 'Pneumatics' category.
+
+.. versionchanged:: 8.0
+   :mod:`pagegenerators` are supported with "move" and "remove" action.
 """
 #
 # (C) Pywikibot team, 2004-2022
@@ -138,6 +153,7 @@
 import pickle
 import re
 from contextlib import suppress
+from itertools import chain
 from operator import methodcaller
 from textwrap import fill
 from typing import Optional, Union
@@ -161,6 +177,7 @@
     PageSaveRelatedError,
 )
 from pywikibot.tools import open_archive
+from pywikibot.tools.itertools import intersect_generators


 # This is required for the text that is shown when you run this script
@@ -549,6 +566,9 @@
     empty.

     Per default the operation applies to pages and subcategories.
+
+    .. versionadded:: 8.0
+       The ``generator`` parameter.
     """

     DELETION_COMMENT_AUTOMATIC = 0
@@ -564,13 +584,14 @@
                  title_regex=None,
                  history: bool = False,
                  pagesonly: bool = False,
-                 deletion_comment: Union[int,
-                                         str] = DELETION_COMMENT_AUTOMATIC,
+                 deletion_comment: Union[
+                     int, str] = DELETION_COMMENT_AUTOMATIC,
                  move_comment=None,
                  wikibase: bool = True,
                  allow_split: bool = False,
                  move_together: bool = False,
-                 keep_sortkey=None) -> None:
+                 keep_sortkey=None,
+                 generator=None) -> None:
         """Store all given parameters in the objects attributes.

         :param oldcat: The move source.
@@ -603,7 +624,10 @@
         :param move_together: If True moves the pages/subcategories only if
             page and talk page could be moved or both source page and target
             page don't exist.
+        :param generator: a generator from pagegenerators.GeneratorFactory.
+            If given an intersection to the oldcat category members is used.
         """
+        super().__init__()
         self.site = pywikibot.Site()
         self.can_move_cats = self.site.has_right('move-categorypages')
         self.noredirect = delete_oldcat \
@@ -632,6 +656,7 @@
         self.allow_split = allow_split
         self.move_together = move_together
         self.keep_sortkey = keep_sortkey
+        self.generator = generator

         if not self.can_move_cats:
             repo = self.site.data_repository()
@@ -691,7 +716,13 @@
         - _hist()
         - _change()
         - _delete()
+
+        .. versionchanged:: 8.0
+           if a page generator is given to the bot, the intersection
+           with :func:`pagegenerators.CategorizedPageGenerator` or
+           :func:`pagegenerators.SubCategoriesPageGenerator` is used.
         """
+        self._start_ts = pywikibot.Timestamp.now()
         # can_move_* determines if the page can be moved safely (target
         # doesn't exist but source does), move_items determines if the
         # items (pages/subcategories) of the category could be moved into
@@ -700,6 +731,7 @@
             'category page', self.oldcat, self.newcat)
         can_move_talk = CategoryMoveRobot.check_move(
             'category talk page', self.oldtalk, self.newtalk)
+
         if not self.newcat:  # delete
             move_items = True
         else:
@@ -707,6 +739,7 @@
             if not self.allow_split:
                 can_move_page = can_move_page and move_items
                 can_move_talk = can_move_talk and move_items
+
         if self.newcat and self.move_oldcat:
             if self.can_move_cats:
                 if can_move_page:
@@ -730,21 +763,36 @@
                     self._movetalk()
                 if self.wikibase:
                     self._update_wikibase_item()
+
             if self.history and can_move_page:
                 self._hist()

         if move_items:
-            self._change(pagegenerators.CategorizedPageGenerator(self.oldcat))
+            gens = [pagegenerators.CategorizedPageGenerator(self.oldcat)]
             if not self.pagesonly:
-                self._change(
+                gens.append(
                     pagegenerators.SubCategoriesPageGenerator(self.oldcat))
+            gen = chain(*gens)
+
+            if self.generator:
+                pywikibot.info('Retrieving intersection of generators.')
+                # Allow duplicates if no subcategories are loaded to reduce
+                # memory usage. We can assume that there are no duplicates
+                # retrieved from CategorizedPageGenerator.
+                gen = intersect_generators(gen, self.generator,
+                                           allow_duplicates=self.pagesonly)
+            self._change(gen)
+
         else:
             pywikibot.log("Didn't move pages/subcategories, because the "
                           "category page hasn't been moved.")
+
         if self.oldcat.isEmptyCategory() and self.delete_oldcat \
            and (self.newcat and self.move_oldcat or not self.newcat):
             self._delete(can_move_page, can_move_talk)

+        self.exit()
+
     def _delete(self, moved_page, moved_talk) -> None:
         """Private function to delete the category page and its talk page.

@@ -760,9 +808,11 @@
         if moved_page and self.oldcat.exists():
             self.oldcat.delete(self.deletion_comment, not self.batch,
                                mark=True)
+        self.counter['delete'] += 1
         if moved_talk and self.oldtalk.exists():
             self.oldtalk.delete(self.deletion_comment, not self.batch,
                                 mark=True)
+        self.counter['delete talk'] += 1

     def _change(self, gen) -> None:
         """
@@ -773,6 +823,9 @@
         :param gen: Generator containing pages or categories.
         """
         for page in pagegenerators.PreloadingGenerator(gen):
+            self.counter['read'] += 1
+            count_key = 'move' if self.newcat else 'remove'
+
             if not self.title_regex or re.search(self.title_regex,
                                                  page.title()):

@@ -780,6 +833,7 @@
                                      summary=self.comment,
                                      in_place=self.inplace,
                                      sort_key=self.keep_sortkey)
+                self.counter[count_key] += 1

                 doc_page = self.determine_template_target(page)
                 if doc_page != page and (not self.title_regex
@@ -790,13 +844,13 @@
                                              in_place=self.inplace,
                                              include=self.includeonly,
                                              sort_key=self.keep_sortkey)
+                    self.counter[count_key + ' talk'] += 1

     @staticmethod
-    def check_move(name, old_page, new_page) -> bool:
+    def check_move(name: str, old_page, new_page) -> bool:
         """Return if the old page can be safely moved to the new page.

         :param name: Title of the new page
-        :type name: str
         :param old_page: Page to be moved
         :type old_page: pywikibot.page.BasePage
         :param new_page: Page to be moved to
@@ -1538,7 +1592,7 @@
             pg_options.append(arg)

     enabled = ['namespace'] if action in ('tidy', 'listify') else None
-    if action in ('add', 'listify', 'tidy'):
+    if action in ('add', 'listify', 'move', 'remove', 'tidy'):
         gen_factory = pagegenerators.GeneratorFactory(enabled_options=enabled)
         unknown += gen_factory.handle_args(pg_options)
     else:
@@ -1564,6 +1618,7 @@
             options['from'] = \
                 pywikibot.input('Please enter the name of the '
                                 'category that should be removed:')
+        gen = gen_factory.getCombinedGenerator()
         bot = CategoryMoveRobot(oldcat=options.get('from'),
                                 batch=batch,
                                 comment=summary,
@@ -1572,7 +1627,8 @@
                                 title_regex=title_regex,
                                 history=history,
                                 pagesonly=pagesonly,
-                                deletion_comment=use_deletion_summary)
+                                deletion_comment=use_deletion_summary,
+                                generator=gen)
     elif action == 'move':
         if 'from' not in options:
             options['from'] = pywikibot.input(
@@ -1585,6 +1641,7 @@
                 CategoryMoveRobot.DELETION_COMMENT_SAME_AS_EDIT_COMMENT
         else:
             deletion_comment = CategoryMoveRobot.DELETION_COMMENT_AUTOMATIC
+        gen = gen_factory.getCombinedGenerator()
         bot = CategoryMoveRobot(oldcat=options.get('from'),
                                 newcat=options.get('to'),
                                 batch=batch,
@@ -1598,7 +1655,8 @@
                                 wikibase=wikibase,
                                 allow_split=allow_split,
                                 move_together=move_together,
-                                keep_sortkey=keep_sortkey)
+                                keep_sortkey=keep_sortkey,
+                                generator=gen)
     elif action == 'tidy':
         bot = CategoryTidyRobot(options.get('from'), cat_db,
                                 gen_factory.namespaces, summary)

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/834501
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I65a06133c8afbc328d8c2b73e3a40839424db161
Gerrit-Change-Number: 834501
Gerrit-PatchSet: 6
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: D3r1ck01 <[email protected]>
Gerrit-Reviewer: Vladis13 <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to