def test_strip_cfd_templates_does_nothing_when_no_templates(self):
     """Test when the're no CFD templates, the page text is not changed."""
     bot = CategoryMoveRobot(oldcat='Old', newcat='New')
     bot.newcat.text = 'Nothing should change.\n\nAnother line.'
     bot._strip_cfd_templates(commit=False)
     self.assertEqual(bot.newcat.text,
                      'Nothing should change.\n\nAnother line.')
 def test_strip_cfd_templates_does_nothing_when_no_templates(self):
     """Test that when there are no CFD templates, the page text is not changed."""
     bot = CategoryMoveRobot(oldcat='Old', newcat='New')
     bot.newcat.text = "Nothing should change.\n\nAnother line."
     bot._strip_cfd_templates(commit=False)
     self.assertEqual(bot.newcat.text,
                      "Nothing should change.\n\nAnother line.")
 def _runtest_strip_cfd_templates(self, template_start, template_end):
     """Run a CFD template stripping test with the given CFD start/end templates."""
     bot = CategoryMoveRobot(oldcat='Old', newcat='New')
     bot.newcat.text = '\n'.join(
         ('Preamble', template_start, 'Random text inside template',
          'Even another template: {{cfr-speedy}}', template_end,
          'Footer stuff afterwards', '', '[[Category:Should remain]]'))
     expected = '\n'.join(('Preamble', 'Footer stuff afterwards', '',
                           '[[Category:Should remain]]'))
     bot._strip_cfd_templates(commit=False)
     self.assertEqual(bot.newcat.text, expected)
 def _runtest_strip_cfd_templates(self, template_start, template_end):
     """Run a CFD template stripping test with the given CFD start/end templates."""
     bot = CategoryMoveRobot(oldcat="Old", newcat="New")
     bot.newcat.text = "\n".join(
         (
             "Preamble",
             template_start,
             "Random text inside template",
             "Even another template: {{cfr-speedy}}",
             template_end,
             "Footer stuff afterwards",
             "",
             "[[Category:Should remain]]",
         )
     )
     expected = "\n".join(("Preamble", "Footer stuff afterwards", "", "[[Category:Should remain]]"))
     bot._strip_cfd_templates(commit=False)
     self.assertEqual(bot.newcat.text, expected)
Example #5
0
def one_cat(OLDCAT):
    oldcatObject = pywikibot.Page(site, "Kategorija:{}".format(OLDCAT))

    if not oldcatObject.isRedirectPage():
        return 0
    #

    NEWCAT = oldcatObject.getRedirectTarget().title(withNamespace=False)
    #pywikibot.output(NEWCAT)

    SUMMARY = 'kategorija "{}" → "{}"'.format(OLDCAT.replace('_', ' '),
                                              NEWCAT.replace('_', ' '))
    q = CategoryMoveRobot(OLDCAT,
                          NEWCAT,
                          batch=True,
                          comment=SUMMARY,
                          inplace=True,
                          delete_oldcat=False)
    q.run()
 def _runtest_strip_cfd_templates(self, template_start, template_end):
     """Run a CFD template stripping test with the given CFD start/end templates."""
     bot = CategoryMoveRobot(oldcat='Old', newcat='New')
     bot.newcat.text = '\n'.join((
         'Preamble',
         template_start,
         'Random text inside template',
         'Even another template: {{cfr-speedy}}',
         template_end,
         'Footer stuff afterwards',
         '',
         '[[Category:Should remain]]'
     ))
     expected = '\n'.join((
         'Preamble',
         'Footer stuff afterwards',
         '',
         '[[Category:Should remain]]'
     ))
     bot._strip_cfd_templates(commit=False)
     self.assertEqual(bot.newcat.text, expected)
Example #7
0
    def ProcessDataBlock(self, data):
        """Process data block given by RunQuery()."""
        if 'query' not in data or 'pages' not in data['query']:
            return

        firstItem = True
        for pageID, page in data['query']['pages'].items():
            printed = False
            title = page['title']
            self.currentTitle = title
            if 'missing' in page:
                continue
            if firstItem:
                if self.lastLetter != title[0]:
                    pywikibot.ui.output('Processing %s\n' % title)
                    self.lastLetter = title[0]
                firstItem = False
            if self.titles:
                err = self.ProcessTitle(title)
                if err:
                    changed = False
                    if self.replace:
                        if len(err[1]) == 1:
                            newTitle = err[1][0]
                            editSummary = i18n.twtranslate(
                                self.site, 'casechecker-rename')
                            dst = self.Page(newTitle)

                            if 'redirect' in page:
                                src = self.Page(title)
                                redir = src.getRedirectTarget()
                                redirTitle = redir.title(as_link=True,
                                                         textlink=True)

                                if not dst.exists():
                                    src.move(newTitle, editSummary,
                                             movesubpages=True)
                                    changed = True

                                replErrors = False
                                for p in src.getReferences(
                                        follow_redirects=False):
                                    if p.namespace() == 2:
                                        continue
                                    oldText = p.text
                                    newText = self.ReplaceLink(oldText, title,
                                                               newTitle)
                                    if not self.PutNewPage(
                                        p, newText, [
                                            self.MakeMoveSummary(title,
                                                                 newTitle)]):
                                        replErrors = True
                                if not replErrors:
                                    editSummary = i18n.twtranslate(
                                        self.site,
                                        'casechecker-delete-summary')
                                    newText = i18n.twtranslate(
                                        self.site,
                                        'casechecker-delete-reason',
                                        redirTitle)
                                    if newText:
                                        src.text = '{{delete}}\n\n' + newText
                                        src.save(editSummary, minor=False)
                                        changed = True

                            elif not dst.exists():
                                src = self.Page(title)
                                if page['ns'] == 14:
                                    dst = self.Page(newTitle)
                                    bot = CategoryMoveBot(
                                        src.title(with_ns=False),
                                        dst.title(with_ns=False),
                                        self.autonomous,
                                        editSummary + ' '
                                        + self.MakeMoveSummary(title,
                                                               newTitle),
                                        True)
                                    bot.run()
                                else:
                                    src.move(newTitle, editSummary,
                                             movesubpages=True)
                                changed = True

                    if not changed:
                        if len(err[1]) > 0:
                            self.AppendLineToLog(self.failedTitles, title)
                        else:
                            self.AddNoSuggestionTitle(title)

                        self.WikiLog('* ' + err[0])
                        printed = True

            if self.links:
                allLinks = None
                if 'links' in page:
                    allLinks = page['links']
                if 'categories' in page:
                    if allLinks:
                        allLinks = allLinks + page['categories']
                    else:
                        allLinks = page['categories']

                if allLinks:
                    pageObj = None
                    pageTxt = None
                    msg = []
                    foundSuggestions = False

                    for l in allLinks:
                        ltxt = l['title']
                        err = self.ProcessTitle(ltxt)
                        if err:
                            if len(err[1]) > 0:
                                foundSuggestions = True
                            elif self.AddNoSuggestionTitle(ltxt):
                                continue

                            newTitle = None
                            if self.replace:
                                newTitle = self.PickTarget(title, ltxt, err[1])
                                if newTitle:
                                    if pageObj is None:
                                        pageObj = self.Page(title)
                                        pageTxt = pageObj.get()

                                    msg.append(self.MakeMoveSummary(ltxt,
                                                                    newTitle))

                                    pageTxt = self.ReplaceLink(pageTxt, ltxt,
                                                               newTitle)
                            if not newTitle:
                                if not printed:
                                    self.WikiLog('* {}: link to {}'
                                                 .format(self.MakeLink(title,
                                                                       False),
                                                         err[0]))
                                    printed = True
                                else:
                                    self.WikiLog('** link to {}'
                                                 .format(err[0]))
                    if pageObj is not None:
                        if self.PutNewPage(pageObj, pageTxt, msg):
                            # done, no need to log anything
                            foundSuggestions = False

                    if foundSuggestions:
                        self.AppendLineToLog(self.failedTitles, title)
            if self.stopAfter > 0:
                self.stopAfter -= 1
                if self.stopAfter == 0:
                    raise ValueError('Stopping because we are done')
    def ProcessDataBlock(self, data):
        """Process data block given by RunQuery()."""
        if 'query' not in data or 'pages' not in data['query']:
            return

        firstItem = True
        for pageID, page in data['query']['pages'].items():
            printed = False
            title = page['title']
            self.currentTitle = title
            if 'missing' in page:
                continue
            if firstItem:
                if self.lastLetter != title[0]:
                    pywikibot.ui.output('Processing %s\n' % title)
                    self.lastLetter = title[0]
                firstItem = False
            if self.titles:
                err = self.ProcessTitle(title)
                if err:
                    changed = False
                    if self.replace:
                        if len(err[1]) == 1:
                            newTitle = err[1][0]
                            editSummary = i18n.twtranslate(
                                self.site, "casechecker-rename")
                            dst = self.Page(newTitle)

                            if 'redirect' in page:
                                src = self.Page(title)
                                redir = src.getRedirectTarget()
                                redirTitle = redir.title(asLink=True,
                                                         textlink=True)

                                if not dst.exists():
                                    src.move(newTitle, editSummary,
                                             movesubpages=True)
                                    changed = True

                                replErrors = False
                                for p in src.getReferences(
                                        follow_redirects=False):
                                    if p.namespace() == 2:
                                        continue
                                    oldText = p.text
                                    newText = self.ReplaceLink(oldText, title,
                                                               newTitle)
                                    if not self.PutNewPage(
                                        p, newText, [
                                            self.MakeMoveSummary(title,
                                                                 newTitle)]):
                                        replErrors = True
                                if not replErrors:
                                    editSummary = i18n.twtranslate(
                                        self.site, "casechecker-delete-summary")
                                    newText = i18n.twtranslate(
                                        self.site,
                                        "casechecker-delete-reason", redirTitle)
                                    if newText:
                                        src.text = u'{{delete}}\n\n' + newText
                                        src.save(editSummary, minor=False)
                                        changed = True

                            elif not dst.exists():
                                src = self.Page(title)
                                if page['ns'] == 14:
                                    dst = self.Page(newTitle)
                                    bot = CategoryMoveBot(
                                        src.title(withNamespace=False),
                                        dst.title(withNamespace=False),
                                        self.autonomous,
                                        editSummary + u' ' +
                                        self.MakeMoveSummary(title, newTitle),
                                        True)
                                    bot.run()
                                else:
                                    src.move(newTitle, editSummary,
                                             movesubpages=True)
                                changed = True

                    if not changed:
                        if len(err[1]) > 0:
                            self.AppendLineToLog(self.failedTitles, title)
                        else:
                            self.AddNoSuggestionTitle(title)

                        self.WikiLog(u"* " + err[0])
                        printed = True

            if self.links:
                allLinks = None
                if 'links' in page:
                    allLinks = page['links']
                if 'categories' in page:
                    if allLinks:
                        allLinks = allLinks + page['categories']
                    else:
                        allLinks = page['categories']

                if allLinks:
                    pageObj = None
                    pageTxt = None
                    msg = []
                    foundSuggestions = False

                    for l in allLinks:
                        ltxt = l['title']
                        err = self.ProcessTitle(ltxt)
                        if err:
                            if len(err[1]) > 0:
                                foundSuggestions = True
                            elif self.AddNoSuggestionTitle(ltxt):
                                continue

                            newTitle = None
                            if self.replace:
                                newTitle = self.PickTarget(title, ltxt, err[1])
                                if newTitle:
                                    if pageObj is None:
                                        pageObj = self.Page(title)
                                        pageTxt = pageObj.get()

                                    msg.append(self.MakeMoveSummary(ltxt,
                                                                    newTitle))

                                    pageTxt = self.ReplaceLink(pageTxt, ltxt,
                                                               newTitle)
                            if not newTitle:
                                if not printed:
                                    self.WikiLog(u"* %s: link to %s"
                                                 % (self.MakeLink(title, False),
                                                    err[0]))
                                    printed = True
                                else:
                                    self.WikiLog(u"** link to %s" % err[0])
                    if pageObj is not None:
                        if self.PutNewPage(pageObj, pageTxt, msg):
                                # done, no need to log anything
                                foundSuggestions = False

                    if foundSuggestions:
                        self.AppendLineToLog(self.failedTitles, title)
            if self.stopAfter > 0:
                self.stopAfter -= 1
                if self.stopAfter == 0:
                    raise ValueError(u'Stopping because we are done')
Example #9
0
def main(*args):
    """
    Process command line arguments and perform task.

    If args is an empty list, sys.argv is used.

    @param args: command line arguments
    @type args: str
    """
    cfd_page = DEFAULT_CFD_PAGE
    local_args = pywikibot.handle_args(args)

    for arg in local_args:
        if arg.startswith('-page'):
            if len(arg) == len('-page'):
                cfd_page = pywikibot.input(
                    'Enter the CFD working page to use:')
            else:
                cfd_page = arg[len('-page:'):]

    page = pywikibot.Page(pywikibot.Site(), cfd_page)
    try:
        page.get()
    except pywikibot.NoPage:
        pywikibot.error(
            'CFD working page "{0}" does not exist!'.format(cfd_page))
        sys.exit(1)

    # Variable declarations
    day = 'None'
    mode = 'None'
    summary = ''
    robot = None

    m = ReCheck()
    for line in page.text.split('\n'):
        if nobots.search(line) or example.search(line):
            # NO BOTS or example line
            continue
        if speedymode.search(line):
            mode = 'Speedy'
            day = 'None'
        elif movemode.search(line):
            mode = 'Move'
            day = 'None'
        elif emptymode.search(line):
            mode = 'Empty'
            day = 'None'
        elif deletemode.search(line):
            mode = 'Delete'
            day = 'None'
        elif maintenance.search(line):
            # It's probably best not to try to handle these in an automated
            # fashion.
            mode = 'None'
            day = 'None'
        elif m.check(dateheader, line):
            day = m.result.group(1)
            pywikibot.output('Found day header: {}'.format(day))
        elif m.check(movecat, line):
            src = m.result.group(1)
            dest = m.result.group(2)
            thisDay = findDay(src, day)
            if mode == 'Move' and thisDay != 'None':
                summary = ('Robot - Moving category ' + src +
                           ' to [[:Category:' + dest +
                           ']] per [[WP:CFD|CFD]] at ' + thisDay + '.')
                action_summary = \
                    'Robot - Result of [[WP:CFD|CFD]] at ' + thisDay + '.'
            elif mode == 'Speedy':
                summary = ('Robot - Speedily moving category ' + src +
                           ' to [[:Category:' + dest +
                           ']] per [[WP:CFDS|CFDS]].')
                action_summary = 'Robot - Speedily moved per [[WP:CFDS|CFDS]].'
            else:
                continue
            # If the category is redirect, we do NOT want to move articles to
            # it. The safest thing to do here is abort and wait for human
            # intervention.
            destpage = pywikibot.Page(page.site, dest, ns=14)
            if destpage.isCategoryRedirect():
                summary = 'CANCELED. Destination is redirect: ' + summary
                pywikibot.stdout(summary)
                robot = None
            else:
                deletion_comment_same = (
                    CategoryMoveBot.DELETION_COMMENT_SAME_AS_EDIT_COMMENT)
                robot = CategoryMoveBot(oldcat=src,
                                        newcat=dest,
                                        batch=True,
                                        comment=summary,
                                        inplace=True,
                                        move_oldcat=True,
                                        delete_oldcat=True,
                                        deletion_comment=deletion_comment_same,
                                        move_comment=action_summary)
        elif m.check(deletecat, line):
            src = m.result.group(1)
            # I currently don't see any reason to handle these two cases
            # separately, though if are guaranteed that the category in the
            # "Delete" case is empty, it might be easier to call delete.py on
            # it.
            thisDay = findDay(src, day)
            if (mode == 'Empty' or mode == 'Delete') and thisDay != 'None':
                summary = ('Robot - Removing category {0} per [[WP:CFD|CFD]] '
                           'at {1}.'.format(src, thisDay))
                action_summary = \
                    'Robot - Result of [[WP:CFD|CFD]] at ' + thisDay + '.'
            else:
                continue
            robot = CategoryMoveBot(oldcat=src,
                                    batch=True,
                                    comment=summary,
                                    deletion_comment=action_summary,
                                    inplace=True)
        if summary and robot is not None:
            pywikibot.stdout(summary)
            # Run, robot, run!
            robot.run()
        summary = ''
        robot = None
Example #10
0
def main(*args):
    """
    Process command line arguments and perform task.

    If args is an empty list, sys.argv is used.

    @param args: command line arguments
    @type args: list of unicode
    """
    pywikibot.handle_args(args)

    if config.family != 'wikipedia' or config.mylang != 'en':
        pywikibot.warning('CFD does work only on the English Wikipedia.')
        return

    page = pywikibot.Page(pywikibot.Site(), cfdPage)

    # Variable declarations
    day = 'None'
    mode = 'None'
    summary = ''
    action_summary = ''
    robot = None

    m = ReCheck()
    for line in page.text.split("\n"):
        if nobots.search(line):
            # NO BOTS!!!
            pass
        elif example.search(line):
            # Example line
            pass
        elif speedymode.search(line):
            mode = "Speedy"
            day = "None"
        elif movemode.search(line):
            mode = "Move"
            day = "None"
        elif emptymode.search(line):
            mode = "Empty"
            day = "None"
        elif deletemode.search(line):
            mode = "Delete"
            day = "None"
        elif maintenance.search(line):
            # It's probably best not to try to handle these in an automated fashion.
            mode = "None"
            day = "None"
        elif m.check(dateheader, line):
            day = m.result.group(1)
            pywikibot.output("Found day header: %s" % day)
        elif m.check(movecat, line):
            src = m.result.group(1)
            dest = m.result.group(2)
            thisDay = findDay(src, day)
            if mode == "Move" and thisDay != "None":
                summary = (
                    'Robot - Moving category ' + src + ' to [[:Category:' +
                    dest + ']] per [[WP:CFD|CFD]] at ' + thisDay + '.')
                action_summary = 'Robot - Result of [[WP:CFD|CFD]] at ' + thisDay + '.'
            elif mode == "Speedy":
                summary = (
                    'Robot - Speedily moving category ' + src +
                    ' to [[:Category:' + dest + ']] per [[WP:CFDS|CFDS]].')
                action_summary = 'Robot - Speedily moved per [[WP:CFDS|CFDS]].'
            else:
                continue
            # If the category is redirect, we do NOT want to move articles to
            # it. The safest thing to do here is abort and wait for human
            # intervention.
            destpage = pywikibot.Page(page.site, dest, ns=14)
            if destpage.isCategoryRedirect():
                summary = 'CANCELED. Destination is redirect: ' + summary
                pywikibot.stdout(summary)
                robot = None
            else:
                deletion_comment_same = (
                    CategoryMoveBot.DELETION_COMMENT_SAME_AS_EDIT_COMMENT)
                robot = CategoryMoveBot(oldcat=src, newcat=dest, batch=True,
                                        comment=summary, inplace=True,
                                        move_oldcat=True, delete_oldcat=True,
                                        deletion_comment=deletion_comment_same,
                                        move_comment=action_summary)
        elif m.check(deletecat, line):
            src = m.result.group(1)
            # I currently don't see any reason to handle these two cases
            # separately, though if are guaranteed that the category in the
            # "Delete" case is empty, it might be easier to call delete.py on
            # it.
            thisDay = findDay(src, day)
            if (mode == "Empty" or mode == "Delete") and thisDay != "None":
                summary = (
                    'Robot - Removing category {0} per [[WP:CFD|CFD]] '
                    'at {1}.'.format(src, thisDay))
                action_summary = 'Robot - Result of [[WP:CFD|CFD]] at ' + thisDay + '.'
            else:
                continue
            robot = CategoryMoveBot(oldcat=src, batch=True, comment=summary,
                                    deletion_comment=action_summary,
                                    inplace=True)
        else:
            # This line does not fit any of our regular expressions,
            # so ignore it.
            pass
        if summary != "" and robot is not None:
            pywikibot.stdout(summary)
            # Run, robot, run!
            robot.run()
        summary = ""
        robot = None
Example #11
0
def main(*args):
    """
    Process command line arguments and perform task.

    If args is an empty list, sys.argv is used.

    @param args: command line arguments
    @type args: list of unicode
    """
    pywikibot.handle_args(args)

    if config.family != 'wikipedia' or config.mylang != 'en':
        pywikibot.warning('CFD does work only on the English Wikipedia.')
        return

    page = pywikibot.Page(pywikibot.Site(), cfdPage)

    # Variable declarations
    day = "None"
    mode = "None"
    summary = ""
    robot = None

    m = ReCheck()
    for line in page.text.split("\n"):
        if nobots.search(line):
            # NO BOTS!!!
            pass
        elif example.search(line):
            # Example line
            pass
        elif speedymode.search(line):
            mode = "Speedy"
            day = "None"
        elif movemode.search(line):
            mode = "Move"
            day = "None"
        elif emptymode.search(line):
            mode = "Empty"
            day = "None"
        elif deletemode.search(line):
            mode = "Delete"
            day = "None"
        elif maintenance.search(line):
            # It's probably best not to try to handle these in an automated fashion.
            mode = "None"
            day = "None"
        elif m.check(dateheader, line):
            day = m.result.group(1)
            pywikibot.output("Found day header: %s" % day)
        elif m.check(movecat, line):
            src = m.result.group(1)
            dest = m.result.group(2)
            thisDay = findDay(src, day)
            if mode == "Move" and thisDay != "None":
                summary = "Robot - Moving category " + src + " to [[:Category:" + dest + "]] per [[WP:CFD|CFD]] at " + \
                          thisDay + "."
            elif mode == "Speedy":
                summary = "Robot - Speedily moving category " + src + " to [[:Category:" + dest + \
                          "]] per [[WP:CFDS|CFDS]]."
            else:
                continue
            # If the category is redirect, we do NOT want to move articles to
            # it. The safest thing to do here is abort and wait for human
            # intervention.
            destpage = pywikibot.Page(
                pywikibot.Site(), dest, ns=14)
            if destpage.isCategoryRedirect():
                summary = 'CANCELED. Destination is redirect: ' + summary
                pywikibot.output(summary, toStdout=True)
                robot = None
            else:
                robot = CategoryMoveBot(oldcat=src, newcat=dest, batch=True,
                                        comment=summary, inplace=True,
                                        move_oldcat=True, delete_oldcat=True,
                                        deletion_comment=True)
        elif m.check(deletecat, line):
            src = m.result.group(1)
            # I currently don't see any reason to handle these two cases separately, though
            # if are guaranteed that the category in the "Delete" case is empty, it might be
            # easier to call delete.py on it.
            thisDay = findDay(src, day)
            if (mode == "Empty" or mode == "Delete") and thisDay != "None":
                summary = 'Robot - Removing category {0} per [[WP:CFD|CFD]] at {1}.'.format(
                    src, thisDay)
            else:
                continue
            robot = CategoryMoveBot(oldcat=src, batch=True, comment=summary,
                                    deletion_comment=True, inplace=True)
        else:
            # This line does not fit any of our regular expressions, so ignore it.
            pass
        if summary != "" and robot is not None:
            pywikibot.output(summary, toStdout=True)
            # Run, robot, run!
            robot.run()
        summary = ""
        robot = None
Example #12
0
def main(*args):
    """
    Process command line arguments and perform task.

    If args is an empty list, sys.argv is used.

    @param args: command line arguments
    @type args: list of unicode
    """
    cfd_page = DEFAULT_CFD_PAGE
    local_args = pywikibot.handle_args(args)

    for arg in local_args:
        if arg.startswith('-page'):
            if len(arg) == len('-page'):
                cfd_page = pywikibot.input('Enter the CFD working page to use:')
            else:
                cfd_page = arg[len('-page:'):]

    page = pywikibot.Page(pywikibot.Site(), cfd_page)
    try:
        page.get()
    except pywikibot.NoPage:
        pywikibot.error(
            'CFD working page "{0}" does not exist!'.format(cfd_page))
        sys.exit(1)

    # Variable declarations
    day = 'None'
    mode = 'None'
    summary = ''
    action_summary = ''
    robot = None

    m = ReCheck()
    for line in page.text.split("\n"):
        if nobots.search(line):
            # NO BOTS!!!
            pass
        elif example.search(line):
            # Example line
            pass
        elif speedymode.search(line):
            mode = "Speedy"
            day = "None"
        elif movemode.search(line):
            mode = "Move"
            day = "None"
        elif emptymode.search(line):
            mode = "Empty"
            day = "None"
        elif deletemode.search(line):
            mode = "Delete"
            day = "None"
        elif maintenance.search(line):
            # It's probably best not to try to handle these in an automated fashion.
            mode = "None"
            day = "None"
        elif m.check(dateheader, line):
            day = m.result.group(1)
            pywikibot.output("Found day header: %s" % day)
        elif m.check(movecat, line):
            src = m.result.group(1)
            dest = m.result.group(2)
            thisDay = findDay(src, day)
            if mode == "Move" and thisDay != "None":
                summary = (
                    'Robot - Moving category ' + src + ' to [[:Category:' +
                    dest + ']] per [[WP:CFD|CFD]] at ' + thisDay + '.')
                action_summary = 'Robot - Result of [[WP:CFD|CFD]] at ' + thisDay + '.'
            elif mode == "Speedy":
                summary = (
                    'Robot - Speedily moving category ' + src +
                    ' to [[:Category:' + dest + ']] per [[WP:CFDS|CFDS]].')
                action_summary = 'Robot - Speedily moved per [[WP:CFDS|CFDS]].'
            else:
                continue
            # If the category is redirect, we do NOT want to move articles to
            # it. The safest thing to do here is abort and wait for human
            # intervention.
            destpage = pywikibot.Page(page.site, dest, ns=14)
            if destpage.isCategoryRedirect():
                summary = 'CANCELED. Destination is redirect: ' + summary
                pywikibot.stdout(summary)
                robot = None
            else:
                deletion_comment_same = (
                    CategoryMoveBot.DELETION_COMMENT_SAME_AS_EDIT_COMMENT)
                robot = CategoryMoveBot(oldcat=src, newcat=dest, batch=True,
                                        comment=summary, inplace=True,
                                        move_oldcat=True, delete_oldcat=True,
                                        deletion_comment=deletion_comment_same,
                                        move_comment=action_summary)
        elif m.check(deletecat, line):
            src = m.result.group(1)
            # I currently don't see any reason to handle these two cases
            # separately, though if are guaranteed that the category in the
            # "Delete" case is empty, it might be easier to call delete.py on
            # it.
            thisDay = findDay(src, day)
            if (mode == "Empty" or mode == "Delete") and thisDay != "None":
                summary = (
                    'Robot - Removing category {0} per [[WP:CFD|CFD]] '
                    'at {1}.'.format(src, thisDay))
                action_summary = 'Robot - Result of [[WP:CFD|CFD]] at ' + thisDay + '.'
            else:
                continue
            robot = CategoryMoveBot(oldcat=src, batch=True, comment=summary,
                                    deletion_comment=action_summary,
                                    inplace=True)
        if summary and robot is not None:
            pywikibot.stdout(summary)
            # Run, robot, run!
            robot.run()
        summary = ""
        robot = None