Example #1
0
def choosecats(pagetext):
    """Coose categories."""
    chosen = []
    done = False
    length = 1000
    # TODO: → input_choice
    pywikibot.output("""Give the new categories, one per line.
Empty line: if the first, don't change. Otherwise: Ready.
-: I made a mistake, let me start over.
?: Give the text of the page with GUI.
??: Give the text of the page in console.
xx: if the first, remove all categories and add no new.
q: quit.""")
    while not done:
        choice = pywikibot.input('?')
        if choice == '':
            done = True
        elif choice == '-':
            chosen = choosecats(pagetext)
            done = True
        elif choice == '?':
            from pywikibot import editor as editarticle
            editor = editarticle.TextEditor()
            editor.edit(pagetext)
        elif choice == '??':
            pywikibot.output(pagetext[0:length])
            length = length + 500
        elif choice == 'xx' and not chosen:
            chosen = None
            done = True
        elif choice == 'q':
            raise QuitKeyboardInterrupt
        else:
            chosen.append(choice)
    return chosen
Example #2
0
 def result(self, value):
     """Open a text editor and let the user change it."""
     editor = editarticle.TextEditor()
     self.new_text = editor.edit(self._text,
                                 jumpIndex=self._start,
                                 highlight=self._title)
     return super(EditOption, self).result(value)
Example #3
0
def choosecats(pagetext):
    chosen = []
    done = False
    length = 1000
    print("""Give the new categories, one per line.
Empty line: if the first, don't change. Otherwise: Ready.
-: I made a mistake, let me start over.
?: Give the text of the page with GUI.
??: Give the text of the page in console.
xx: if the first, remove all categories and add no new.
q: quit.""")
    while not done:
        choice = pywikibot.input(u"?")
        if choice == "":
            done = True
        elif choice == "-":
            chosen = choosecats(pagetext)
            done = True
        elif choice == "?":
            from pywikibot import editor as editarticle
            editor = editarticle.TextEditor()
            editor.edit(pagetext)
        elif choice == "??":
            pywikibot.output(pagetext[0:length])
            length = length + 500
        elif choice == "xx" and chosen == []:
            chosen = None
            done = True
        elif choice == "q":
            print "quit..."
            sys.exit()
        else:
            chosen.append(choice)
    return chosen
def showQuest(page):
    """Ask for an editor and invoke it."""
    quest = pywikibot.input_choice(
        u'Do you want to open the page?',
        [('with browser', 'b'), ('with gui', 'g'), ('no', 'n')], 'n',
        automatic_quit=False)
    if quest == 'b':
        webbrowser.open('%s?redirect=no' % page.full_url())
    elif quest == 'g':
        from pywikibot import editor as editarticle
        editor = editarticle.TextEditor()
        editor.edit(page.text)
Example #5
0
def showQuest(site, page):
    quest = pywikibot.inputChoice(u'Do you want to open the page?',
                                  ['with browser', 'with gui', 'no'],
                                  ['b', 'g', 'n'], 'n')
    pathWiki = site.family.nicepath(site.lang)
    url = 'http://%s%s%s?&redirect=no' % (pywikibot.getSite().hostname(),
                                          pathWiki, page.urlname())
    if quest == 'b':
        webbrowser.open(url)
    elif quest == 'g':
        from pywikibot import editor as editarticle
        editor = editarticle.TextEditor()
        text = editor.edit(page.get())
Example #6
0
def showQuest(page):
    quest = pywikibot.inputChoice(u'Do you want to open the page?',
                                  ['with browser', 'with gui', 'no'],
                                  ['b', 'g', 'n'], 'n')
    site = page.site
    url = '%s://%s%s?redirect=no' % (site.protocol(), site.hostname(),
                                     site.nice_get_address(
                                         page.title(asUrl=True)))
    if quest == 'b':
        webbrowser.open(url)
    elif quest == 'g':
        from pywikibot import editor as editarticle
        editor = editarticle.TextEditor()
        editor.edit(page.text)
Example #7
0
def showQuest(page):
    """Ask for an editor and invoke it."""
    quest = pywikibot.input_choice(u'Do you want to open the page?',
                                   [('with browser', 'b'), ('with gui', 'g'),
                                    ('no', 'n')],
                                   'n',
                                   automatic_quit=False)
    site = page.site
    url = '%s://%s%s?redirect=no' % (site.protocol(), site.hostname(),
                                     site.nice_get_address(
                                         page.title(asUrl=True)))
    if quest == 'b':
        webbrowser.open(url)
    elif quest == 'g':
        from pywikibot import editor as editarticle
        editor = editarticle.TextEditor()
        editor.edit(page.text)
Example #8
0
    def run(self) -> None:
        pages = [self.parent] + self.children
        for page in pages:
            original_text = page.text
            new_text = page.get_newtext()
            if original_text == new_text:
                break

            while True:
                pywikibot.output(color_format(
                    '\n\n>>> {lightpurple}{0}{default} <<<', page.title()))
                pywikibot.showDiff(original_text, new_text)
                choice = pywikibot.input_choice('この変更を投稿しますか', [('はい', 'y'), ('いいえ', 'n'), ('エディタで編集する', 'e')])
                if choice == 'n':
                    break
                if choice == 'e':
                    editor = editarticle.TextEditor()
                    as_edited = editor.edit(new_text)
                    if as_edited:
                        new_text = as_edited
                    continue
                if choice == 'y':
                    page.text = new_text
                    page.save(
                        'Botによる: [[User:YuukinBot#作業内容2|カテゴリの整備]]',
                        asynchronous=True,
                        callback=self._async_callback,
                        quiet=True)
                    self._pending_processing_titles.put(page.title(as_link=True))
                while not self._pending_processed_titles.empty():
                    proc_title, res = self._pending_processed_titles.get()
                    pywikibot.output('{0}{1}'.format(proc_title, 'が投稿されました' if res else 'は投稿されませんでした'))
                break

        while not all((self._pending_processing_titles.empty(), self._pending_processed_titles.empty())):
            proc_title, res = self._pending_processed_titles.get()
            pywikibot.output('{0}{1}'.format(proc_title, 'が投稿されました' if res else 'は投稿されませんでした'))

        pywikibot.output(f'{self.changed_pages} ページ編集しました')
        pywikibot.output(f'{self.parent.title(as_link=True)} 関連の整備が完了しました')
Example #9
0
    def process_filename(self):
        """Return base filename portion of self.url"""
        # Isolate the pure name
        filename = self.url
        # Filename may be either a local file path or a URL
        if "://" in filename:
            # extract the path portion of the URL
            filename = urlparse.urlparse(filename).path
        filename = os.path.basename(filename)

        if self.useFilename:
            filename = self.useFilename
        if not self.keepFilename:
            pywikibot.output(
                u"The filename on the target wiki will default to: %s" %
                filename)
            # FIXME: these 2 belong somewhere else, presumably in family
            forbidden = '/'  # to be extended
            allowed_formats = (u'gif', u'jpg', u'jpeg', u'mid', u'midi',
                               u'ogg', u'png', u'svg', u'xcf', u'djvu', u'ogv',
                               u'oga', u'tif', u'tiff')
            # ask until it's valid
            while True:
                newfn = pywikibot.input(
                    u'Enter a better name, or press enter to accept:')
                if newfn == "":
                    newfn = filename
                    break
                ext = os.path.splitext(newfn)[1].lower().strip('.')
                # are any chars in forbidden also in newfn?
                invalid = set(forbidden) & set(newfn)
                if invalid:
                    c = "".join(invalid)
                    print "Invalid character(s): %s. Please try again" % c
                    continue
                if ext not in allowed_formats:
                    choice = pywikibot.inputChoice(
                        u"File format is not one of [%s], but %s. Continue?" %
                        (u' '.join(allowed_formats), ext), ['yes', 'no'],
                        ['y', 'N'], 'N')
                    if choice == 'n':
                        continue
                break
            if newfn != '':
                filename = newfn
        # A proper description for the submission.
        pywikibot.output(u"The suggested description is:")
        pywikibot.output(self.description)
        if self.verifyDescription:
            newDescription = u''
            choice = pywikibot.inputChoice(
                u'Do you want to change this description?', ['Yes', 'No'],
                ['y', 'N'], 'n')
            if choice == 'y':
                from pywikibot import editor as editarticle
                editor = editarticle.TextEditor()
                newDescription = editor.edit(self.description)
            # if user saved / didn't press Cancel
            if newDescription:
                self.description = newDescription
        return filename
Example #10
0
    def handle_bad_page(self, *values):
        """Process one bad page."""
        try:
            self.content = self.page.get()
        except IsRedirectPageError:
            pywikibot.output('Already redirected, skipping.')
            return
        except NoPageError:
            pywikibot.output('Already deleted')
            return

        for d in pywikibot.translate(self.site.code, done):
            if d in self.content:
                pywikibot.output(
                    'Found: "{}" in content, nothing necessary'.format(d))
                return
        pywikibot.output('---- Start content ----------------')
        pywikibot.output(self.content)
        pywikibot.output('---- End of content ---------------')

        # Loop other user answer
        answered = False
        while not answered:
            answer = pywikibot.input(self.question)

            if answer == 'q':
                raise QuitKeyboardInterrupt
            if answer == 'd':
                pywikibot.output('Trying to delete page [[{}]].'
                                 .format(self.page.title()))
                self.page.delete()
                return
            if answer == 'e':
                old = self.content
                new = editor.TextEditor().edit(old)
                msg = pywikibot.input('Summary message:')
                self.userPut(self.page, old, new, summary=msg)
                return
            if answer == 'b':
                pywikibot.output('Blanking page [[{}]].'
                                 .format(self.page.title()))
                try:
                    self.page.put('',
                                  summary=i18n.twtranslate(
                                      self.site.lang,
                                      'followlive-blanking',
                                      {'content': self.content}))
                except EditConflictError:
                    pywikibot.output(
                        'An edit conflict occurred! Automatically retrying')
                    self.handle_bad_page(self)
                return
            if answer == '':
                pywikibot.output('Page correct! Proceeding with next pages.')
                return
            # Check user input:
            if answer[0] == 'u':
                # Answer entered as string
                answer = answer[1:]
            try:
                choices = answer.split(',')
            except ValueError:
                # User entered wrong value
                pywikibot.error('"{}" is not valid'.format(answer))
                continue
            # test input
            for choice in choices:
                try:
                    x = int(choice)
                except ValueError:
                    break
                else:
                    answered = (x >= 1 and x <= len(self.questionlist))
            if not answered:
                pywikibot.error('"{}" is not valid'.format(answer))
                continue
        summary = ''
        for choice in choices:
            answer = int(choice)
            # grab the template parameters
            tpl = pywikibot.translate(self.site,
                                      templates)[self.questionlist[answer]]
            if tpl['pos'] == 'top':
                pywikibot.output(
                    'prepending {}...'.format(self.questionlist[answer]))
                self.content = self.questionlist[answer] + '\n' + self.content
            elif tpl['pos'] == 'bottom':
                pywikibot.output('appending {}...'
                                 .format(self.questionlist[answer]))
                self.content += '\n' + self.questionlist[answer]
            else:
                raise RuntimeError(
                    '"pos" should be "top" or "bottom" for template {}. '
                    'Contact a developer.'.format(self.questionlist[answer]))
            summary += tpl['msg'] + ' '
            pywikibot.output('Probably added ' + self.questionlist[answer])

        self.page.put(self.content, summary=summary)
        pywikibot.output('with comment {}\n'.format(summary))
Example #11
0
    def process_filename(self, file_url):
        """Return base filename portion of file_url."""
        # Isolate the pure name
        filename = file_url
        # Filename may be either a URL or a local file path
        if '://' in filename:
            # extract the path portion of the URL
            filename = urlparse(filename).path
        filename = os.path.basename(filename)
        if self.use_filename:
            filename = self.use_filename
        if self.filename_prefix:
            filename = self.filename_prefix + filename
        if not self.keep_filename:
            pywikibot.output(
                '\nThe filename on the target wiki will default to: {}\n'.
                format(filename))
            assert not self.opt.always
            newfn = pywikibot.input(
                'Enter a better name, or press enter to accept:')
            if newfn != '':
                filename = newfn
        # FIXME: these 2 belong somewhere else, presumably in family
        # forbidden characters are handled by pywikibot/page.py
        forbidden = ':*?/\\'  # to be extended
        try:
            allowed_formats = self.target_site.siteinfo.get('fileextensions',
                                                            get_default=False)
        except KeyError:
            allowed_formats = []
        else:
            allowed_formats = [item['ext'] for item in allowed_formats]

        # ask until it's valid
        first_check = True
        while True:
            if not first_check:
                if self.opt.always:
                    filename = None
                else:
                    filename = pywikibot.input('Enter a better name, or press '
                                               'enter to skip the file:')
                if not filename:
                    return None

            first_check = False
            ext = os.path.splitext(filename)[1].lower().strip('.')
            # are any chars in forbidden also in filename?
            invalid = set(forbidden) & set(filename)
            if invalid:
                c = ''.join(invalid)
                pywikibot.output(
                    'Invalid character(s): {}. Please try again'.format(c))
                continue

            if allowed_formats and ext not in allowed_formats:
                if self.opt.always:
                    pywikibot.output('File format is not one of '
                                     '[{}]'.format(' '.join(allowed_formats)))
                    continue

                if not pywikibot.input_yn(
                        'File format is not one of [{}], but {!r}. Continue?'.
                        format(' '.join(allowed_formats), ext),
                        default=False):
                    continue

            potential_file_page = pywikibot.FilePage(self.target_site,
                                                     filename)
            if potential_file_page.exists():
                overwrite = self._handle_warning('exists')
                if overwrite is False:
                    pywikibot.output(
                        'File exists and you asked to abort. Skipping.')
                    return None

                if potential_file_page.has_permission():
                    if overwrite is None:
                        overwrite = not pywikibot.input_yn(
                            'File with name {} already exists. '
                            'Would you like to change the name? '
                            '(Otherwise file will be overwritten.)'.format(
                                filename),
                            default=True,
                            automatic_quit=False)
                    if not overwrite:
                        continue
                    break

                pywikibot.output('File with name {} already exists and '
                                 'cannot be overwritten.'.format(filename))
                continue

            with suppress(NoPageError):
                if potential_file_page.file_is_shared():
                    pywikibot.output(
                        'File with name {} already exists in shared '
                        'repository and cannot be overwritten.'.format(
                            filename))
                    continue
            break

        # A proper description for the submission.
        # Empty descriptions are not accepted.
        if self.description:
            pywikibot.output('The suggested description is:\n{}'.format(
                self.description))

        while not self.description or self.verify_description:
            if not self.description:
                pywikibot.output(
                    color_format(
                        '{lightred}It is not possible to upload a file '
                        'without a description.{default}'))
            assert not self.opt.always
            # if no description, ask if user want to add one or quit,
            # and loop until one is filled.
            # if self.verify_description, ask if user want to change it
            # or continue.
            if self.description:
                question = 'Do you want to change this description?'
            else:
                question = 'No description was given. Add one?'
            if pywikibot.input_yn(question,
                                  default=not self.description,
                                  automatic_quit=self.description):
                from pywikibot import editor as editarticle
                editor = editarticle.TextEditor()
                try:
                    new_description = editor.edit(self.description)
                except ImportError:
                    raise
                except Exception as e:
                    pywikibot.error(e)
                    continue
                # if user saved / didn't press Cancel
                if new_description:
                    self.description = new_description
            elif not self.description:
                raise QuitKeyboardInterrupt
            self.verify_description = False

        return filename
Example #12
0
def edit_page(page, summary, always=False, dry_run=False):
    pywikibot.output(page.title())
    try:
        original_text = page.get()
        if not page.canBeEdited():
            pywikibot.output("You can't edit page " + page.title(as_link=True))
            return always
    except pywikibot.NoPage:
        pywikibot.output(u"Page {0} not found".format(
            page.title(as_link=True)))
        return always
    except pywikibot.IsRedirectPage:
        return always
    new_text = replace_text(original_text)
    if new_text == original_text:
        pywikibot.output('No changes were necessary in ' +
                         page.title(as_link=True))
        return always
    context = 0
    if dry_run:
        pywikibot.showDiff(original_text, new_text, context=context)
        return always

    while True:
        pywikibot.showDiff(original_text, new_text, context=context)
        if always:
            break
        choice = pywikibot.input_choice('Do you want to accept these changes?',
                                        [('Yes', 'y'), ('No', 'n'),
                                         ('Edit original', 'e'),
                                         ('edit Latest', 'l'),
                                         ('open in Browser', 'b'),
                                         ('More context', 'm'), ('All', 'a')],
                                        default='N')
        if choice == 'm':
            context = context * 3 if context else 3
            continue
        if choice == 'e':
            editor = editarticle.TextEditor()
            as_edited = editor.edit(original_text)
            # if user didn't press Cancel
            if as_edited and as_edited != new_text:
                new_text = as_edited
            continue
        if choice == 'l':
            editor = editarticle.TextEditor()
            as_edited = editor.edit(new_text)
            # if user didn't press Cancel
            if as_edited and as_edited != new_text:
                new_text = as_edited
                # prevent changes from being applied again
                last_text = new_text
            continue
        if choice == 'b':
            pywikibot.bot.open_webbrowser(page)
            try:
                original_text = page.get(get_redirect=True, force=True)
            except pywikibot.NoPage:
                pywikibot.output('Page {0} has been deleted.'.format(
                    page.title()))
                break
            new_text = original_text
            last_text = None
            continue
        if choice == 'a':
            always = True
        if choice == 'y':
            page.text = new_text
            page.save(summary=summary)
        break
    if always and new_text != original_text:
        try:
            page.text = new_text
            page.save(summary=summary)
        except pywikibot.EditConflict:
            pywikibot.output('Skipping {0} because of edit conflict'.format(
                page.title(), ))
        except pywikibot.SpamfilterError as e:
            pywikibot.output(
                'Cannot change {0} because of blacklist entry {1}'.format(
                    page.title(), e.url))
        except pywikibot.LockedPage:
            pywikibot.output('Skipping {0} (locked page)'.format(
                page.title(), ))
        except pywikibot.PageNotSaved as error:
            pywikibot.output('Error putting page: {0}'.format(error.args, ))
    return always
Example #13
0
 def run(self):
     """
     Starts the bot.
     """
     # Run the generator which will yield Pages which might need to be
     # changed.
     for page in self.generator:
         if self.isTitleExcepted(page.title()):
             pywikibot.output(
                 u'Skipping %s because the title is on the exceptions list.'
                 % page.title(asLink=True))
             continue
         try:
             # Load the page's text from the wiki
             original_text = page.get(get_redirect=True)
             if not page.canBeEdited():
                 pywikibot.output(u"You can't edit page %s" %
                                  page.title(asLink=True))
                 continue
         except pywikibot.NoPage:
             pywikibot.output(u'Page %s not found' %
                              page.title(asLink=True))
             continue
         new_text = original_text
         while True:
             if self.isTextExcepted(new_text):
                 pywikibot.output(u'Skipping %s because it contains text '
                                  u'that is on the exceptions list.' %
                                  page.title(asLink=True))
                 break
             new_text = self.doReplacements(new_text)
             if new_text == original_text:
                 pywikibot.output(u'No changes were necessary in %s' %
                                  page.title(asLink=True))
                 break
             if self.recursive:
                 newest_text = self.doReplacements(new_text)
                 while (newest_text != new_text):
                     new_text = newest_text
                     newest_text = self.doReplacements(new_text)
             if hasattr(self, "addedCat"):
                 cats = page.categories(nofollow_redirects=True)
                 if self.addedCat not in cats:
                     cats.append(self.addedCat)
                     new_text = pywikibot.replaceCategoryLinks(
                         new_text, cats)
             # Show the title of the page we're working on.
             # Highlight the title in purple.
             pywikibot.output(
                 u"\n\n>>> \03{lightpurple}%s\03{default} <<<" %
                 page.title())
             pywikibot.showDiff(original_text, new_text)
             if self.acceptall:
                 break
             choice = pywikibot.inputChoice(
                 u'Do you want to accept these changes?',
                 ['Yes', 'No', 'Edit', 'open in Browser', 'All', 'Quit'],
                 ['y', 'N', 'e', 'b', 'a', 'q'], 'N')
             if choice == 'e':
                 editor = editarticle.TextEditor()
                 as_edited = editor.edit(original_text)
                 # if user didn't press Cancel
                 if as_edited and as_edited != new_text:
                     new_text = as_edited
                 continue
             if choice == 'b':
                 webbrowser.open(
                     "http://%s%s" %
                     (page.site.hostname(),
                      page.site.nice_get_address(page.title(asUrl=True))))
                 i18n.input('pywikibot-enter-finished-browser')
                 try:
                     original_text = page.get(get_redirect=True, force=True)
                 except pywikibot.NoPage:
                     pywikibot.output(u'Page %s has been deleted.' %
                                      page.title())
                     break
                 new_text = original_text
                 continue
             if choice == 'q':
                 return
             if choice == 'a':
                 self.acceptall = True
             if choice == 'y':
                 page.put_async(new_text, self.summary)
             # choice must be 'N'
             break
         if self.acceptall and new_text != original_text:
             try:
                 page.put(new_text, self.summary)
             except pywikibot.EditConflict:
                 pywikibot.output(u'Skipping %s because of edit conflict' %
                                  (page.title(), ))
             except pywikibot.SpamfilterError as e:
                 pywikibot.output(
                     u'Cannot change %s because of blacklist entry %s' %
                     (page.title(), e.url))
             except pywikibot.PageNotSaved as error:
                 pywikibot.output(u'Error putting page: %s' %
                                  (error.args, ))
             except pywikibot.LockedPage:
                 pywikibot.output(u'Skipping %s (locked page)' %
                                  (page.title(), ))
Example #14
0
 def run(self):
     """Start the bot."""
     # Run the generator which will yield Pages which might need to be
     # changed.
     for page in self.generator:
         if self.isTitleExcepted(page.title()):
             pywikibot.output(
                 'Skipping {0} because the title is on the exceptions list.'
                 .format(page.title(as_link=True)))
             continue
         try:
             # Load the page's text from the wiki
             original_text = page.get(get_redirect=True)
             if not page.canBeEdited():
                 pywikibot.output("You can't edit page " +
                                  page.title(as_link=True))
                 continue
         except pywikibot.NoPage:
             pywikibot.output('Page {0} not found'.format(
                 page.title(as_link=True)))
             continue
         applied = set()
         new_text = original_text
         last_text = None
         context = 0
         while True:
             if self.isTextExcepted(new_text):
                 pywikibot.output('Skipping {0} because it contains text '
                                  'that is on the exceptions list.'.format(
                                      page.title(as_link=True)))
                 break
             while new_text != last_text:
                 last_text = new_text
                 new_text = self.apply_replacements(last_text, applied,
                                                    page)
                 if not self.recursive:
                     break
             if new_text == original_text:
                 pywikibot.output('No changes were necessary in ' +
                                  page.title(as_link=True))
                 break
             if hasattr(self, 'addedCat'):
                 # Fetch only categories in wikitext, otherwise the others
                 # will be explicitly added.
                 cats = textlib.getCategoryLinks(new_text, site=page.site)
                 if self.addedCat not in cats:
                     cats.append(self.addedCat)
                     new_text = textlib.replaceCategoryLinks(new_text,
                                                             cats,
                                                             site=page.site)
             # Show the title of the page we're working on.
             # Highlight the title in purple.
             pywikibot.output(
                 color_format('\n\n>>> {lightpurple}{0}{default} <<<',
                              page.title()))
             pywikibot.showDiff(original_text, new_text, context=context)
             if self.getOption('always'):
                 break
             choice = pywikibot.input_choice(
                 'Do you want to accept these changes?',
                 [('Yes', 'y'), ('No', 'n'), ('Edit original', 'e'),
                  ('edit Latest', 'l'), ('open in Browser', 'b'),
                  ('More context', 'm'), ('All', 'a')],
                 default='N')
             if choice == 'm':
                 context = context * 3 if context else 3
                 continue
             if choice == 'e':
                 editor = editarticle.TextEditor()
                 as_edited = editor.edit(original_text)
                 # if user didn't press Cancel
                 if as_edited and as_edited != new_text:
                     new_text = as_edited
                 continue
             if choice == 'l':
                 editor = editarticle.TextEditor()
                 as_edited = editor.edit(new_text)
                 # if user didn't press Cancel
                 if as_edited and as_edited != new_text:
                     new_text = as_edited
                     # prevent changes from being applied again
                     last_text = new_text
                 continue
             if choice == 'b':
                 pywikibot.bot.open_webbrowser(page)
                 try:
                     original_text = page.get(get_redirect=True, force=True)
                 except pywikibot.NoPage:
                     pywikibot.output('Page {0} has been deleted.'.format(
                         page.title()))
                     break
                 new_text = original_text
                 last_text = None
                 continue
             if choice == 'a':
                 self.options['always'] = True
             if choice == 'y':
                 page.text = new_text
                 page.save(summary=self.generate_summary(applied),
                           asynchronous=True,
                           callback=self._replace_async_callback,
                           quiet=True)
             while not self._pending_processed_titles.empty():
                 proc_title, res = self._pending_processed_titles.get()
                 pywikibot.output('Page {0}{1} saved'.format(
                     proc_title, '' if res else ' not'))
             # choice must be 'N'
             break
         if self.getOption('always') and new_text != original_text:
             try:
                 page.text = new_text
                 page.save(summary=self.generate_summary(applied),
                           callback=self._replace_sync_callback,
                           quiet=True)
             except pywikibot.EditConflict:
                 pywikibot.output(
                     'Skipping {0} because of edit conflict'.format(
                         page.title(), ))
             except pywikibot.SpamfilterError as e:
                 pywikibot.output(
                     'Cannot change {0} because of blacklist entry {1}'.
                     format(page.title(), e.url))
             except pywikibot.LockedPage:
                 pywikibot.output('Skipping {0} (locked page)'.format(
                     page.title(), ))
             except pywikibot.PageNotSaved as error:
                 pywikibot.output('Error putting page: {0}'.format(
                     error.args, ))
             if self._pending_processed_titles.qsize() > 50:
                 while not self._pending_processed_titles.empty():
                     proc_title, res = self._pending_processed_titles.get()
                     pywikibot.output('Page {0}{1} saved'.format(
                         proc_title, '' if res else ' not'))
Example #15
0
    def process_filename(self):
        """Return base filename portion of self.url."""
        # Isolate the pure name
        filename = self.url
        # Filename may be either a local file path or a URL
        if "://" in filename:
            # extract the path portion of the URL
            filename = urlparse(filename).path
        filename = os.path.basename(filename)

        if self.useFilename:
            filename = self.useFilename
        if not self.keepFilename:
            pywikibot.output(
                u"The filename on the target wiki will default to: %s"
                % filename)
            # FIXME: these 2 belong somewhere else, presumably in family
            forbidden = '/'  # to be extended
            allowed_formats = (u'gif', u'jpg', u'jpeg', u'mid', u'midi',
                               u'ogg', u'png', u'svg', u'xcf', u'djvu',
                               u'ogv', u'oga', u'tif', u'tiff')
            # ask until it's valid
            while True:
                newfn = pywikibot.input(
                    u'Enter a better name, or press enter to accept:')
                if newfn == "":
                    newfn = filename
                    break
                ext = os.path.splitext(newfn)[1].lower().strip('.')
                # are any chars in forbidden also in newfn?
                invalid = set(forbidden) & set(newfn)
                if invalid:
                    c = "".join(invalid)
                    pywikibot.output(
                        'Invalid character(s): %s. Please try again' % c)
                    continue
                if ext not in allowed_formats:
                    if not pywikibot.input_yn(
                            u"File format is not one of [%s], but %s. Continue?"
                            % (u' '.join(allowed_formats), ext),
                            default=False, automatic_quit=False):
                        continue
                break
            if newfn != '':
                filename = newfn
        # A proper description for the submission.
        # Empty descriptions are not accepted.
        pywikibot.output(u'The suggested description is:\n%s'
                         % self.description)

        # Description must be set and verified
        if not self.description:
            self.verifyDescription = True

        while not self.description or self.verifyDescription:
            if not self.description:
                pywikibot.output(
                    u'\03{lightred}It is not possible to upload a file '
                    'without a summary/description.\03{default}')

            # if no description, default is 'yes'
            if pywikibot.input_yn(
                    u'Do you want to change this description?',
                    default=not self.description):
                from pywikibot import editor as editarticle
                editor = editarticle.TextEditor()
                try:
                    newDescription = editor.edit(self.description)
                except Exception as e:
                    pywikibot.error(e)
                    continue
                # if user saved / didn't press Cancel
                if newDescription:
                    self.description = newDescription
            self.verifyDescription = False

        return filename
    def process_filename(self, file_url=None):
        """Return base filename portion of file_url."""
        if not file_url:
            file_url = self.url
            pywikibot.warning("file_url is not given. "
                              "Set to self.url by default.")

        always = self.getOption('always')
        # Isolate the pure name
        filename = file_url
        # Filename may be either a URL or a local file path
        if "://" in filename:
            # extract the path portion of the URL
            filename = urlparse(filename).path
        filename = os.path.basename(filename)
        if self.useFilename:
            filename = self.useFilename
        if not self.keepFilename:
            pywikibot.output(
                u"The filename on the target wiki will default to: %s" %
                filename)
            assert not always
            newfn = pywikibot.input(
                u'Enter a better name, or press enter to accept:')
            if newfn != "":
                filename = newfn
        # FIXME: these 2 belong somewhere else, presumably in family
        # forbidden characters are handled by pywikibot/page.py
        forbidden = ':*?/\\'  # to be extended
        try:
            allowed_formats = self.targetSite.siteinfo.get('fileextensions',
                                                           get_default=False)
        except KeyError:
            allowed_formats = []
        else:
            allowed_formats = [item['ext'] for item in allowed_formats]

        # ask until it's valid
        first_check = True
        while True:
            if not first_check:
                if always:
                    filename = None
                else:
                    filename = pywikibot.input('Enter a better name, or press '
                                               'enter to skip the file:')
                if not filename:
                    return None
            first_check = False
            ext = os.path.splitext(filename)[1].lower().strip('.')
            # are any chars in forbidden also in filename?
            invalid = set(forbidden) & set(filename)
            if invalid:
                c = "".join(invalid)
                pywikibot.output('Invalid character(s): %s. Please try again' %
                                 c)
                continue
            if allowed_formats and ext not in allowed_formats:
                if always:
                    pywikibot.output('File format is not one of '
                                     '[{0}]'.format(' '.join(allowed_formats)))
                    continue
                elif not pywikibot.input_yn(
                        u"File format is not one of [%s], but %s. Continue?" %
                    (u' '.join(allowed_formats), ext),
                        default=False,
                        automatic_quit=False):
                    continue
            potential_file_page = pywikibot.FilePage(self.targetSite, filename)
            if potential_file_page.exists():
                overwrite = self._handle_warning('exists')
                if overwrite is False:
                    pywikibot.output(
                        "File exists and you asked to abort. Skipping.")
                    return None
                if potential_file_page.canBeEdited():
                    if overwrite is None:
                        overwrite = not pywikibot.input_yn(
                            "File with name %s already exists. "
                            "Would you like to change the name? "
                            "(Otherwise file will be overwritten.)" % filename,
                            default=True,
                            automatic_quit=False)
                    if not overwrite:
                        continue
                    else:
                        break
                else:
                    pywikibot.output(u"File with name %s already exists and "
                                     "cannot be overwritten." % filename)
                    continue
            else:
                try:
                    if potential_file_page.fileIsShared():
                        pywikibot.output(
                            u"File with name %s already exists in shared "
                            "repository and cannot be overwritten." % filename)
                        continue
                    else:
                        break
                except pywikibot.NoPage:
                    break

        # A proper description for the submission.
        # Empty descriptions are not accepted.
        pywikibot.output(u'The suggested description is:\n%s' %
                         self.description)

        # Description must be set and verified
        if not self.description:
            self.verifyDescription = True

        while not self.description or self.verifyDescription:
            if not self.description:
                pywikibot.output(
                    color_format(
                        '{lightred}It is not possible to upload a file '
                        'without a summary/description.{default}'))

            assert not always
            # if no description, default is 'yes'
            if pywikibot.input_yn(u'Do you want to change this description?',
                                  default=not self.description):
                from pywikibot import editor as editarticle
                editor = editarticle.TextEditor()
                try:
                    newDescription = editor.edit(self.description)
                except Exception as e:
                    pywikibot.error(e)
                    continue
                # if user saved / didn't press Cancel
                if newDescription:
                    self.description = newDescription
            self.verifyDescription = False

        return filename
Example #17
0
 def run(self):
     """Start the bot."""
     # Run the generator which will yield Pages which might need to be
     # changed.
     for page in self.generator:
         if self.isTitleExcepted(page.title()):
             pywikibot.output(
                 u'Skipping %s because the title is on the exceptions list.'
                 % page.title(asLink=True))
             continue
         try:
             # Load the page's text from the wiki
             original_text = page.get(get_redirect=True)
             if not page.canBeEdited():
                 pywikibot.output(u"You can't edit page %s" %
                                  page.title(asLink=True))
                 continue
         except pywikibot.NoPage:
             pywikibot.output(u'Page %s not found' %
                              page.title(asLink=True))
             continue
         applied = set()
         new_text = original_text
         while True:
             if self.isTextExcepted(new_text):
                 pywikibot.output(u'Skipping %s because it contains text '
                                  u'that is on the exceptions list.' %
                                  page.title(asLink=True))
                 break
             last_text = None
             while new_text != last_text:
                 last_text = new_text
                 new_text = self.apply_replacements(last_text, applied)
                 if not self.recursive:
                     break
             if new_text == original_text:
                 pywikibot.output(u'No changes were necessary in %s' %
                                  page.title(asLink=True))
                 break
             if hasattr(self, 'addedCat'):
                 # Fetch only categories in wikitext, otherwise the others will
                 # be explicitly added.
                 cats = textlib.getCategoryLinks(new_text, site=page.site)
                 if self.addedCat not in cats:
                     cats.append(self.addedCat)
                     new_text = textlib.replaceCategoryLinks(new_text,
                                                             cats,
                                                             site=page.site)
             # Show the title of the page we're working on.
             # Highlight the title in purple.
             pywikibot.output(
                 u"\n\n>>> \03{lightpurple}%s\03{default} <<<" %
                 page.title())
             pywikibot.showDiff(original_text, new_text)
             if self.getOption('always'):
                 break
             choice = pywikibot.input_choice(
                 u'Do you want to accept these changes?',
                 [('Yes', 'y'), ('No', 'n'), ('Edit', 'e'),
                  ('open in Browser', 'b'), ('all', 'a')],
                 default='N')
             if choice == 'e':
                 editor = editarticle.TextEditor()
                 as_edited = editor.edit(original_text)
                 # if user didn't press Cancel
                 if as_edited and as_edited != new_text:
                     new_text = as_edited
                 continue
             if choice == 'b':
                 pywikibot.bot.open_webbrowser(page)
                 try:
                     original_text = page.get(get_redirect=True, force=True)
                 except pywikibot.NoPage:
                     pywikibot.output(u'Page %s has been deleted.' %
                                      page.title())
                     break
                 new_text = original_text
                 continue
             if choice == 'a':
                 self.options['always'] = True
             if choice == 'y':
                 page.put_async(new_text,
                                self.generate_summary(applied),
                                callback=self.count_changes)
             # choice must be 'N'
             break
         if self.getOption('always') and new_text != original_text:
             try:
                 page.put(new_text,
                          self.generate_summary(applied),
                          callback=self.count_changes)
             except pywikibot.EditConflict:
                 pywikibot.output(u'Skipping %s because of edit conflict' %
                                  (page.title(), ))
             except pywikibot.SpamfilterError as e:
                 pywikibot.output(
                     u'Cannot change %s because of blacklist entry %s' %
                     (page.title(), e.url))
             except pywikibot.LockedPage:
                 pywikibot.output(u'Skipping %s (locked page)' %
                                  (page.title(), ))
             except pywikibot.PageNotSaved as error:
                 pywikibot.output(u'Error putting page: %s' %
                                  (error.args, ))
Example #18
0
    def treat(self, refPage, disambPage):
        """
        Parameters:
            disambPage - The disambiguation page or redirect we don't want
                anything to link to
            refPage - A page linking to disambPage
        Returns False if the user pressed q to completely quit the program.
        Otherwise, returns True.

        """
        # TODO: break this function up into subroutines!

        dn_template_str = i18n.translate(self.mysite, dn_template)
        include = False
        unlink = False
        new_targets = []
        try:
            text = refPage.get(throttle=False)
            ignoreReason = self.checkContents(text)
            if ignoreReason:
                pywikibot.output(
                    '\n\nSkipping %s because it contains %s.\n\n' %
                    (refPage.title(), ignoreReason))
            else:
                include = True
        except pywikibot.IsRedirectPage:
            pywikibot.output(u'%s is a redirect to %s' %
                             (refPage.title(), disambPage.title()))
            if disambPage.isRedirectPage():
                target = self.alternatives[0]
                choice = pywikibot.inputChoice(
                    u'Do you want to make redirect %s point to %s?' %
                    (refPage.title(), target), ['yes', 'no'], ['y', 'N'], 'N')
                if choice == 'y':
                    redir_text = '#%s [[%s]]' \
                                 % (self.mysite.redirect(default=True), target)
                    try:
                        refPage.put_async(redir_text, comment=self.comment)
                    except pywikibot.PageNotSaved as error:
                        pywikibot.output(u'Page not saved: %s' % error.args)
            else:
                choice = pywikibot.inputChoice(
                    u'Do you want to work on pages linking to %s?' %
                    refPage.title(), ['yes', 'no', 'change redirect'],
                    ['y', 'N', 'c'], 'N')
                if choice == 'y':
                    gen = ReferringPageGeneratorWithIgnore(
                        refPage, self.primary)
                    preloadingGen = pagegenerators.PreloadingGenerator(gen)
                    for refPage2 in preloadingGen:
                        # run until the user selected 'quit'
                        if not self.treat(refPage2, refPage):
                            break
                elif choice == 'c':
                    text = refPage.get(throttle=False, get_redirect=True)
                    include = "redirect"
        except pywikibot.NoPage:
            pywikibot.output(
                u'Page [[%s]] does not seem to exist?! Skipping.' %
                refPage.title())
            include = False
        if include in (True, "redirect"):
            # make a backup of the original text so we can show the changes later
            original_text = text
            n = 0
            curpos = 0
            dn = False
            edited = False
            # This loop will run until we have finished the current page
            while True:
                m = self.linkR.search(text, pos=curpos)
                if not m:
                    if n == 0:
                        pywikibot.output(u"No changes necessary in %s" %
                                         refPage.title())
                        return True
                    else:
                        # stop loop and save page
                        break
                # Make sure that next time around we will not find this same hit.
                curpos = m.start() + 1
                try:
                    foundlink = pywikibot.Link(m.group('title'),
                                               disambPage.site)
                except pywikibot.Error:
                    continue
                # ignore interwiki links
                if foundlink.site != disambPage.site:
                    continue
                # Check whether the link found is to disambPage.
                try:
                    if foundlink.canonical_title() != disambPage.title():
                        continue
                except pywikibot.Error:
                    # must be a broken link
                    pywikibot.log(u"Invalid link [[%s]] in page [[%s]]" %
                                  (m.group('title'), refPage.title()))
                    continue
                n += 1
                # how many bytes should be displayed around the current link
                context = 60
                #there's a {{dn}} here already
                already_dn = text[m.end():m.end() + 8].find(
                    dn_template_str[:4]) > -1
                if already_dn and self.dnSkip:
                    continue

                # This loop will run while the user doesn't choose an option
                # that will actually change the page
                while True:
                    self.current_page = refPage

                    if not self.always:
                        # at the beginning of the link, start red color.
                        # at the end of the link, reset the color to default
                        pywikibot.output(text[max(0,
                                                  m.start() -
                                                  context):m.start()] +
                                         '\03{lightred}' +
                                         text[m.start():m.end()] +
                                         '\03{default}' +
                                         text[m.end():m.end() + context])
                        if edited:
                            choice = pywikibot.input(
                                u"Option (#, r#, [s]kip link, [e]dit page, [n]ext page, [u]nlink, [q]uit,\n"
                                u"        [t]ag template " + dn_template_str +
                                ",\n"
                                u"        [m]ore context, [l]ist, [a]dd new, x=save in this form):"
                            )
                        else:
                            choice = pywikibot.input(
                                u"Option (#, r#, [s]kip link, [e]dit page, [n]ext page, [u]nlink, [q]uit,\n"
                                u"        [t]ag template " + dn_template_str +
                                ",\n"
                                u"        [m]ore context, show [d]isambiguation page, [l]ist, [a]dd new):"
                            )
                    else:
                        choice = self.always
                    if choice in ['a', 'A']:
                        newAlternative = pywikibot.input(u'New alternative:')
                        self.alternatives.append(newAlternative)
                        self.listAlternatives()
                    elif choice in ['e', 'E']:
                        editor = editarticle.TextEditor()
                        newText = editor.edit(text,
                                              jumpIndex=m.start(),
                                              highlight=disambPage.title())
                        # if user didn't press Cancel
                        if newText and newText != text:
                            text = newText
                            break
                    elif choice in ['d', 'D']:
                        editor = editarticle.TextEditor()
                        if disambPage.isRedirectPage():
                            disambredir = disambPage.getRedirectTarget()
                            editor.edit(disambredir.get(),
                                        jumpIndex=m.start(),
                                        highlight=disambredir.title())
                        else:
                            editor.edit(disambPage.get(),
                                        jumpIndex=m.start(),
                                        highlight=disambPage.title())
                    elif choice in ['l', 'L']:
                        self.listAlternatives()
                    elif choice in ['m', 'M']:
                        # show more text around the link we're working on
                        context *= 2
                    else:
                        break

                if choice in ['e', 'E']:
                    # user has edited the page and then pressed 'OK'
                    edited = True
                    curpos = 0
                    continue
                elif choice in ['n', 'N']:
                    # skip this page
                    if self.primary:
                        # If run with the -primary argument, skip this
                        # occurence next time.
                        self.primaryIgnoreManager.ignore(refPage)
                    return True
                elif choice in ['q', 'Q']:
                    # quit the program
                    self.quit()
                elif choice in ['s', 'S']:
                    # Next link on this page
                    n -= 1
                    continue
                elif choice in ['x', 'X'] and edited:
                    # Save the page as is
                    break

                # The link looks like this:
                # [[page_title|link_text]]trailing_chars
                page_title = m.group('title')
                link_text = m.group('label')

                if not link_text:
                    # or like this: [[page_title]]trailing_chars
                    link_text = page_title
                if m.group('section') is None:
                    section = ''
                else:
                    section = m.group('section')
                trailing_chars = m.group('linktrail')
                if trailing_chars:
                    link_text += trailing_chars
                # '?', '/' for old choice
                if choice in ['t', 'T', '?', '/']:
                    # small chunk of text to search
                    search_text = text[m.end():m.end() + context]
                    # figure out where the link (and sentance) ends, put note
                    # there
                    end_of_word_match = re.search("\s", search_text)
                    if end_of_word_match:
                        position_split = end_of_word_match.start(0)
                    else:
                        position_split = 0
                    #insert dab needed template
                    text = (text[:m.end() + position_split] + dn_template_str +
                            text[m.end() + position_split:])
                    dn = True
                    continue
                elif choice in ['u', 'U']:
                    # unlink - we remove the section if there's any
                    text = text[:m.start()] + link_text + text[m.end():]
                    unlink = True
                    continue
                else:
                    if len(choice) > 0 and choice[0] == 'r':
                        # we want to throw away the original link text
                        replaceit = True
                        choice = choice[1:]
                    elif include == "redirect":
                        replaceit = True
                    else:
                        replaceit = False

                    try:
                        choice = int(choice)
                    except ValueError:
                        pywikibot.output(u"Unknown option")
                        # step back to ask the user again what to do with the
                        # current link
                        curpos -= 1
                        continue
                    if choice >= len(self.alternatives) or choice < 0:
                        pywikibot.output(
                            u"Choice out of range. Please select a number "
                            u"between 0 and %i." %
                            (len(self.alternatives) - 1))
                        # show list of possible choices
                        self.listAlternatives()
                        # step back to ask the user again what to do with the
                        # current link
                        curpos -= 1
                        continue
                    new_page_title = self.alternatives[choice]
                    repPl = pywikibot.Page(
                        pywikibot.Link(new_page_title, disambPage.site))
                    if (new_page_title[0].isupper() or link_text[0].isupper()):
                        new_page_title = repPl.title()
                    else:
                        new_page_title = repPl.title()
                        new_page_title = (new_page_title[0].lower() +
                                          new_page_title[1:])
                    if new_page_title not in new_targets:
                        new_targets.append(new_page_title)
                    if replaceit and trailing_chars:
                        newlink = "[[%s%s]]%s" % (new_page_title, section,
                                                  trailing_chars)
                    elif replaceit or (new_page_title == link_text
                                       and not section):
                        newlink = "[[%s]]" % new_page_title
                    # check if we can create a link with trailing characters
                    # instead of a pipelink
                    elif ((len(new_page_title) <= len(link_text))
                          and (firstcap(link_text[:len(new_page_title)])
                               == firstcap(new_page_title))
                          and (re.sub(self.trailR, '',
                                      link_text[len(new_page_title):]) == '')
                          and (not section)):
                        newlink = "[[%s]]%s" \
                                  % (link_text[:len(new_page_title)],
                                     link_text[len(new_page_title):])
                    else:
                        newlink = "[[%s%s|%s]]" \
                                  % (new_page_title, section, link_text)
                    text = text[:m.start()] + newlink + text[m.end():]
                    continue

                pywikibot.output(text[max(0, m.start() - 30):m.end() + 30])
            if text == original_text:
                pywikibot.output(u'\nNo changes have been made:\n')
            else:
                pywikibot.output(u'\nThe following changes have been made:\n')
                pywikibot.showDiff(original_text, text)
                pywikibot.output(u'')
                # save the page
                self.setSummaryMessage(disambPage, new_targets, unlink, dn)
                try:
                    refPage.put_async(text, comment=self.comment)
                except pywikibot.LockedPage:
                    pywikibot.output(u'Page not saved: page is locked')
                except pywikibot.PageNotSaved as error:
                    pywikibot.output(u'Page not saved: %s' % error.args)
        return True
Example #19
0
 def result(self, value):
     """Open a text editor and show the text."""
     editor = editarticle.TextEditor()
     editor.edit(self._page.text,
                 jumpIndex=self._start,
                 highlight=self._page.title())
Example #20
0
    def treat(self, page):
        """Work on each page retrieved from generator."""
        original_text = page.text
        applied = set()
        new_text = original_text
        last_text = None
        context = 0
        while True:
            if self.isTextExcepted(new_text):
                pywikibot.output(
                    'Skipping {} because it contains text '
                    'that is on the exceptions list.'.format(page))
                return

            while new_text != last_text:
                last_text = new_text
                new_text = self.apply_replacements(last_text, applied, page)
                if not self.opt.recursive:
                    break

            if new_text == original_text:
                pywikibot.output('No changes were necessary in ' +
                                 page.title(as_link=True))
                return

            if self.opt.addcat:
                # Fetch only categories in wikitext, otherwise the others
                # will be explicitly added.
                cats = textlib.getCategoryLinks(new_text, site=page.site)
                if self.opt.addcat not in cats:
                    cats.append(self.opt.addcat)
                    new_text = textlib.replaceCategoryLinks(new_text,
                                                            cats,
                                                            site=page.site)
            # Show the title of the page we're working on.
            # Highlight the title in purple.
            self.current_page = page
            pywikibot.showDiff(original_text, new_text, context=context)
            if self.opt.always:
                break

            choice = pywikibot.input_choice(
                'Do you want to accept these changes?',
                [('Yes', 'y'), ('No', 'n'), ('Edit original', 'e'),
                 ('edit Latest', 'l'), ('open in Browser', 'b'),
                 ('More context', 'm'), ('All', 'a')],
                default='N')
            if choice == 'm':
                context = context * 3 if context else 3
                continue
            if choice in ('e', 'l'):
                text_editor = editor.TextEditor()
                edit_text = original_text if choice == 'e' else new_text
                as_edited = text_editor.edit(edit_text)
                # if user didn't press Cancel
                if as_edited and as_edited != new_text:
                    new_text = as_edited
                    if choice == 'l':
                        # prevent changes from being applied again
                        last_text = new_text
                continue
            if choice == 'b':
                pywikibot.bot.open_webbrowser(page)
                try:
                    original_text = page.get(get_redirect=True, force=True)
                except pywikibot.NoPage:
                    pywikibot.output('Page {0} has been deleted.'.format(
                        page.title()))
                    break
                new_text = original_text
                last_text = None
                continue
            if choice == 'a':
                self.opt.always = True
            if choice == 'y':
                self.save(page,
                          original_text,
                          new_text,
                          applied,
                          show_diff=False,
                          quiet=True,
                          callback=self._replace_async_callback,
                          asynchronous=True)
            while not self._pending_processed_titles.empty():
                proc_title, res = self._pending_processed_titles.get()
                pywikibot.output('Page {0}{1} saved'.format(
                    proc_title, '' if res else ' not'))
            # choice must be 'N'
            break

        if self.opt.always and new_text != original_text:
            self.save(page,
                      original_text,
                      new_text,
                      applied,
                      show_diff=False,
                      asynchronous=False)