# -*- coding: utf-8 -*-
"""
This bot is used to quickly trawl through candidates for speedy deletion in a
fast and semi-automated fashion. The bot displays the contents of each page
one at a time and provides a prompt for the user to skip or delete the page.
Of course, this will require a sysop account.
Future upcoming options include the ability to untag a page as not being
eligible for speedy deletion, as well as the option to commute its sentence to
Proposed Deletion (see [[en:WP:PROD]] for more details). Also, if the article
text is long, to prevent terminal spamming, it might be a good idea to truncate
it just to the first so many bytes.
WARNING: This tool shows the contents of the top revision only. It is possible
that a vandal has replaced a perfectly good article with nonsense, which has
subsequently been tagged by someone who didn't realize it was previously a good
article. The onus is on you to avoid making these mistakes.
NOTE: This script currently only works for the Wikipedia project.
"""
__version__ = '$Id: speedy_delete.py 8051 2010-04-04 15:33:15Z mfarag $'
#
# Distributed under the terms of the MIT license.
#
import wikipedia
import pagegenerators, catlib
import time
class SpeedyRobot:
"""
This robot will load a list of pages from the category of candidates for speedy
deletion on the language's wiki and give the user an interactive prompt to decide
whether each should be deleted or not.
"""
csd_cat={
'wikipedia':{
'ab':u':Candidates for speedy deletion',
'ak':u'Category:Candidates for speedy deletion',
'ang':u'Flocc:Candidates for speedy deletion',
'ar':u': ',
'arc':u'Category:Candidates for speedy deletion',
'av':u':Candidates for speedy deletion',
'ay':u'Categora:Candidates for speedy deletion',
'az':u'Kateqoriya:Vikipediya:Silinck shiflr',
'ba':u':Delete',
'bar':u'Kategorie:Wikipedia:Schnelllschen',
'bat-smg':u'Kateguorj:Kanddat skob trint',
'be':u': ',
'be-x-old':u':: ',
'bh':u'Category:Candidates for speedy deletion',
'bi':u'Category:Candidates for speedy deletion',
'bn':u':Candidates for speedy deletion',
'bo':u'Category:Candidates for speedy deletion',
'br':u'Rummad:Candidates for speedy deletion',
'bug':u'Kategori:Candidates for speedy deletion',
'bxr':u'Category:Candidates for speedy deletion',
'ca':u'Categoria:Sollicituds de supressi immediata',
'cbk-zam':u'Categora:Candidates for speedy deletion',
'ce':u':Candidates for speedy deletion',
'ch':u'Katigoria:Candidates for speedy deletion',
'chr':u'Category:Candidates for speedy deletion',
'chy':u'Category:Candidates for speedy deletion',
'cr':u'Category:Candidates for speedy deletion',
'cs':u'Kategorie:Strnky ke smazn',
'cu':u': ',
'cv':u': ',
'de':u'Kategorie:Wikipedia:Schnelllschen',
'diq':u'Category:Candidates for speedy deletion',
'dsb':u'Kategorija:Boki k malsnemu laowanju',
'dv':u':Candidates for speedy deletion',
'ee':u'Category:Candidates for speedy deletion',
'en':u'Category:Candidates for speedy deletion',
'es':u'Categora:Wikipedia:Borrar (definitivo)',
'et':u'Kategooria:Kustutada',
'fa':u': ',
'ff':u'Catgorie:Candidates for speedy deletion',
'fi':u'Luokka:Roskaa',
'fj':u'Category:Candidates for speedy deletion',
'fr':u'Catgorie:Wikipdia:Suppression immdiate demande',
'frp':u'Catgorie:Candidates for speedy deletion',
'gd':u'Category:Candidates for speedy deletion',
'glk':u':Candidates for speedy deletion',
'gn':u'emohenda:Candidates for speedy deletion',
'gu':u':Candidates for speedy deletion',
'ha':u'Category:Candidates for speedy deletion',
'hak':u'Category:Candidates for speedy deletion',
'haw':u'Mhele:Candidates for speedy deletion',
'he':u':: ',
'hsb':u'Kategorija:Strony k spnemu wumrnjenju',
'ht':u'Kategori:Candidates for speedy deletion',
'ia':u'Categoria:Wikipedia:Eliminar',
'ie':u'Category:Candidates for speedy deletion',
'ig':u'Category:Candidates for speedy deletion',
'ik':u'Category:Candidates for speedy deletion',
'ilo':u'Category:Candidates for speedy deletion',
'it':u'Categoria:Da cancellare subito',
'iu':u'Category:Candidates for speedy deletion',
'ja':u'Category:',
'jbo':u'Category:Candidates for speedy deletion',
'ka':u': ',
'kg':u'Category:Candidates for speedy deletion',
'ki':u'Category:Candidates for speedy deletion',
'kl':u'Kategori:Candidates for speedy deletion',
'ko':u': ',
'ks':u'Category:Candidates for speedy deletion',
'kv':u':Wikipedia:Candidates for speedy deletion',
'kw':u'Category:Candidates for speedy deletion',
'ky':u'Category:Deletion',
'lad':u'Categora:Candidates for speedy deletion',
'lg':u'Category:Candidates for speedy deletion',
'lij':u'Categora:Candidates for speedy deletion',
'ln':u'Catgorie:Candidates for speedy deletion',
'lt':u'Kategorija:Kandidatai skubiai trinti',
'mg':u'Sokajy:Candidates for speedy deletion',
'mk':u': ',
'ml':u':Candidates for speedy deletion',
'mn':u': ',
'na':u'Category:Candidates for speedy deletion',
'nah':u'Neneuhcytl:Huiquipedia:Borrar (definitivo)',
'nds':u'Kategorie:Wikipedia:Gauweg',
'ng':u'Category:Candidates for speedy deletion',
'nl':u'Categorie:Wikipedia:Nuweg',
'no':u'Kategori:Sider som er foresltt raskt slettet',
'nov':u'Category:Candidates for speedy deletion',
'nrm':u'Category:Candidates for speedy deletion',
'nv':u'T\'hgi t\'ego:Candidates for speedy deletion',
'ny':u'Category:Candidates for speedy deletion',
'om':u'Category:Wikipedia:Candidates for speedy deletion',
'or':u'Category:Candidates for speedy deletion',
'os':u':: ',
'pa':u':Delete',
'pag':u'Category:Candidates for speedy deletion',
'pam':u'Category:Candidates for speedy deletion',
'pdc':u'Kategorie:Wikipedia:Lsche',
'pih':u'Category:Candidates for speedy deletion',
'pl':u'Kategoria:Ekspresowe kasowanko',
'pt':u'Categoria:Pginas para eliminao rpida',
'rn':u'Category:Candidates for speedy deletion',
'ro':u'Categorie:Pagini de ters rapid',
'roa-tara':u'Category:Candidates for speedy deletion',
'ru':u':: ',
'rw':u'Category:Candidates for speedy deletion',
'sa':u':Candidates for speedy deletion',
'sco':u'Category:Candidates for speedy deletion',
'sd':u': ',
'simple':u'Category:Quick deletion requests',
'sl':u'Kategorija:Predlogi za hitro brisanje',
'sm':u'Category:Candidates for speedy deletion',
'sn':u'Category:Candidates for speedy deletion',
'sr':u': ',
'ss':u'Category:Candidates for speedy deletion',
'st':u'Category:Candidates for speedy deletion',
'stq':u'Kategorie:Candidates for speedy deletion',
'sv':u'Kategori:Snabba raderingar',
'sw':u'Jamii:Deleteme',
'te':u':Candidates for speedy deletion',
'tg':u': ',
'th':u':',
'ti':u'Category:Candidates for speedy deletion',
'tk':u'Category:Deleteme',
'tr':u'Kategori:Vikipedi silinecek sayfalar',
'ts':u'Category:Candidates for speedy deletion',
'tt':u'Trkem:Candidates for speedy deletion',
'tum':u'Category:Candidates for speedy deletion',
'tw':u'Category:Candidates for speedy deletion',
'ug':u'Category:Candidates for speedy deletion',
'uk':u': ',
'uz':u'Turkum:Vikipediya:Yoqotilish uchun maqolalar',
've':u'Category:Candidates for speedy deletion',
'vec':u'Categoria:Da canceare subito',
'vi':u'Th loi:Ch xo',
'vls':u'Categorie:Wikipedia:Nuweg',
'vo':u'Klad:Pads mokabik',
'war':u'Category:Candidates for speedy deletion',
'xal':u':Candidates for speedy deletion',
'xh':u'Category:Candidates for speedy deletion',
'yo':u'ka:Candidates for speedy deletion',
'za':u':Candidates for speedy deletion',
'zh':u'Category:',
'zh-classical':u'Category:',
'zh-yue':u'Category:',
'zu':u'Category:Candidates for speedy deletion',
},
'wikinews':{
'ar': u': ',
'en': u'Category:Speedy deletion',
'ja': u'Category:',
'zh': u'Category:',
},
'wikisource':{
'ar': u': ',
'id': u'Kategori:Usulan penghapusan',
'ja': u'Category:',
'no': u'Kategori:Sider som er foresltt raskt slettet',
'pt': u'Categoria:!Pginas para eliminao rpida',
'ro': u'Categorie:Propuneri pentru tergere',
'zh': u'Category:',
},
'wikiversity':{
'beta': u'Category:Candidates for speedy deletion',
'cs': u'Kategorie:Strnky ke smazn',
'de': u'Kategorie:Wikiversity:Lschen',
'el': u': ',
'en': u'Category:Candidates for speedy deletion',
'es': u'Categora:Wikiversidad:Borrar (definitivo)',
'it': u'Categoria:Da cancellare subito',
'ja': u'Category:Candidates for speedy deletion',
'pt': u'Categoria:!Pginas para eliminao rpida',
},
'wikiquote':{
'ar': u': ',
'cs': u'Kategorie:drba:Strnky ke smazn',
'en': u'Category:Candidates for speedy deletion',
'fi': u'Luokka:Roskaa',
'ja': u'Category:',
'ru': u':: ',
'simple': u'Category:Quick deletion requests',
'zh': u'Category:',
},
'wiktionary':{
'ar': u': ',
'en': u'Category:Candidates for speedy deletion',
'fi': u'Luokka:Roskaa',
'fr': u'Catgorie:Pages supprimer rapidement',
'ja': u'Category:',
'simple': u'Category:Quick deletion requests',
'tt': u'Trkem:Candidates for speedy deletion',
'zh': u'Category:',
},
'wikibooks':{
'ar': u': ',
'ca': u'Categoria:Elements a eliminar',
'en': u'Category:Candidates for speedy deletion',
'es': u'Categora:Wikilibros:Borrar',
'it': u'Categoria:Da cancellare subito',
'ja': u'Category:',
'pl': u'Kategoria:Ekspresowe kasowanko',
'zh': u'Category:',
},
'meta':{'meta': u'Category:Deleteme',},
'commons':{'commons':u'Category:Candidates for speedy deletion',},
'incubator':{'incubator': u'Category:Maintenance:Delete',},
'mediawiki':{'mediawiki': u'Category:Candidates for deletion',},
}
# If the site has several templates for speedy deletion, it might be
# possible to find out the reason for deletion by the template used.
# _default will be used if no such semantic template was used.
deletion_messages = {
'wikipedia':{
'ar': {
u'_default': u' [[Project: | ]]',
},
'cs': {
u'_default': u'Bylo oznaeno k [[Wikipedie:Rychl smazn|rychlmu smazn]]',
},
'de': {
u'_default': u'Lsche Artikel mit [[Wikipedia:Schnelllschantrag|Schnelllschantrag]]',
},
'en': {
u'_default': u'Deleting candidate for speedy deletion per [[WP:CSD|CSD]]',
u'Db-author': u'Deleting page per [[WP:CSD|CSD]] G7: Author requests deletion and is its only editor.',
u'Db-nonsense': u'Deleting page per [[WP:CSD|CSD]] G1: Page is patent nonsense or gibberish.',
u'Db-test': u'Deleting page per [[WP:CSD|CSD]] G2: Test page.',
u'Db-nocontext': u'Deleting page per [[WP:CSD|CSD]] A1: Short article that provides little or no context.',
u'Db-empty': u'Deleting page per [[WP:CSD|CSD]] A1: Empty article.',
u'Db-attack': u'Deleting page per [[WP:CSD|CSD]] G10: Page that exists solely to attack its subject.',
u'Db-catempty': u'Deleting page per [[WP:CSD|CSD]] C1: Empty category.',
u'Db-band': u'Deleting page per [[WP:CSD|CSD]] A7: Article about a non-notable band.',
u'Db-banned': u'Deleting page per [[WP:CSD|CSD]] G5: Page created by a banned user.',
u'Db-bio': u'Deleting page per [[WP:CSD|CSD]] A7: Article about a non-notable person.',
u'Db-notenglish': u'Deleting page per [[WP:CSD|CSD]] A2: Article isn\'t written in English.',
u'Db-copyvio': u'Deleting page per [[WP:CSD|CSD]] G12: Page is a blatant copyright violation.',
u'Db-repost': u'Deleting page per [[WP:CSD|CSD]] G4: Recreation of previously deleted material.',
u'Db-vandalism': u'Deleting page per [[WP:CSD|CSD]] G3: Blatant vandalism.',
u'Db-talk': u'Deleting page per [[WP:CSD|CSD]] G8: Talk page of a deleted or non-existent page.',
u'Db-spam': u'Deleting page per [[WP:CSD|CSD]] G11: Blatant advertising.',
u'Db-disparage': u'Deleting page per [[WP:CSD|CSD]] T1: Divisive or inflammatory template.',
u'Db-r1': u'Deleting page per [[WP:CSD|CSD]] R1: Redirect to a deleted or non-existent page.',
u'Db-experiment': u'Deleting page per [[WP:CSD|CSD]] G2: Page was created as an experiment.',
},
'he': {
u'_default': u' [[: | ]]',
u' ': u' .',
},
'ja':{
u'_default': u'[[WP:CSD|]]',
},
'pt': {
u'_default': u'Apagando pgina por [[Wikipedia:Pginas para eliminar|eliminao rpida]]',
},
'pl': {
u'_default': u'Usuwanie artykuu zgodnie z zasadami [[Wikipedia:Ekspresowe kasowanko|ekspresowego kasowania]]',
},
'it': {
u'_default': u'Rimuovo pagina che rientra nei casi di [[Wikipedia:IMMEDIATA|cancellazione immediata]].',
},
'zh':{
u'_default':u'[[WP:CSD]]',
u'Advert': 'ad',
u'Db-blanked': 'auth',
u'Db-spam':u'[[WP:CSD#G11|CSD G11]]: ',
u'Db-rediruser':u'[[WP:CSD#O1|CSD O6]] ',
u'Notchinese':u'[[WP:CSD#G7|CSD G7]]: ',
u'Db-vandalism': 'vand',
u'': 'oprj',
u'': 'oprj',
u'NotChinese': 'oprj',
u'NotMandarin': 'oprj',
u'No source':u'[[WP:CSD#I3|CSD I3]]: ',
u'No license':u'[[WP:CSD#I3|CSD I3]]: ',
u'Unknown':u'[[WP:CSD#I3|CSD I3]]: ',
u'TempPage':u'[[WP:CSD]]: ',
u'NowCommons':'commons',
u'Nowcommons':'commons',
u'RoughTranslation':'mactra',
},
},
'wikinews':{
'en':{
u'_default': u'[[WN:CSD]]',
},
'zh':{
u'_default': u'[[WN:CSD]]',
},
},
}
# Default reason for deleting a talk page.
talk_deletion_msg={
'wikipedia':{
'ar':u' ',
'cs':u'Osiel diskusn strnka',
'de':u'Verwaiste Diskussionsseite',
'en':u'Orphaned talk page',
'fr':u'Page de discussion orpheline',
'he':u' ',
'it':u'Rimuovo pagina di discussione di una pagina gi cancellata',
'pl':u'Osierocona strona dyskusji',
'pt':u'Pgina de discusso rf',
'zh':u'[[WP:CSD#O1|CSD O1 O2 O6]] ',
},
'wikinews':{
'en':u'Orphaned talk page',
'zh':u'[[WN:CSD#O1|CSD O1 O2 O6]] ',
}
}
# A list of often-used reasons for deletion. Shortcuts are keys, and
# reasons are values. If the user enters a shortcut, the associated reason
# will be used.
delete_reasons = {
'wikipedia': {
'de': {
'asdf': u'Tastaturtest',
'egal': u'Eindeutig irrelevant',
'ka': u'Kein Artikel',
'mist': u'Unsinn',
'move': u'Redirectlschung, um Platz fr Verschiebung zu schaffen',
'nde': u'Nicht in deutscher Sprache verfasst',
'pfui': u'Beleidigung',
'redir': u'Unntiger Redirect',
'spam': u'Spam',
'web': u'Nur ein Weblink',
'wg': u'Wiedergnger (wurde bereits zuvor gelscht)',
},
'it': {
'test': u'Si tratta di un test',
'vandalismo': u'Caso di vandalismo',
'copyviol': 'Violazione di copyright',
'redirect': 'Redirect rotto o inutile',
'spam': 'Spam',
'promo': 'Pagina promozionale',
},
'ja':{
'cont':u'[[WP:CSD]] 1 ',
'test':u'[[WP:CSD]] 2 ',
'vand':u'[[WP:CSD]] 3 and/or',
'ad':u'[[WP:CSD]] 4 ',
'rep':u'[[WP:CSD]] 5 ',
'cp':u'[[WP:CSD]] 6 or',
'sh':u'[[WP:CSD]] 1 ',
'nd':u'[[WP:CSD]] 1 ',
'auth':u'[[WP:CSD]] 3 or',
'nr':u'[[WP:CSD]] 1 ',
'nc':u'[[WP:CSD]] 2 [[WP:NC]]',
'ren':u'[[WP:CSD]] 3 ',
'commons':u'[[WP:CSD]] 7 ',
'tmp':u'[[WP:CSD]] 1 ',
'uau':u'[[WP:CSD]] 1 ',
'nuu':u'[[WP:CSD]] 2 ',
'ipu':u'[[WP:CSD]] 3 IP',
},
'zh':{
'empty':u'[[WP:CSD#G1]]: ',
'test':u'[[WP:CSD#G2]]: ',
'vand':u'[[WP:CSD#G3]]: ',
'rep':u'[[WP:CSD#G5]]: ',
'repa':u'[[WP:CSD#G5]]: ',
'oprj':u'[[WP:CSD#G7]]: ',
'move':u'[[WP:CSD#G8]]: [[Wikipedia:]]',
'auth':u'[[WP:CSD#G10]]: ',
'ad':u'[[WP:CSD#G11]]: ',
'adc':u'[[WP:CSD#G11]]: ',
'bio':u'[[WP:CSD#G12]]: ',
'mactra':u'[[WP:CSD#G13]]: ',
'notrans': u'[[WP:CSD#G14]]: ',
'isol':u'[[WP:CSD#G15]]: ',
'isol-f':u'[[WP:CSD#G15]]: -',
'isol-sub':u'[[WP:CSD#G15]]: -',
'cont':u'[[WP:CSD#A1]]: ',
'nocont':u'[[WP:CSD#A2]]: ',
'nc':u'[[WP:CSD#A3]]: ',
'cn':u'[[WP:CSD#R2]]: ',
'wr':u'[[WP:CSD#R3]]: ',
'vdr':u'[[WP:CSD#R4]]: ',
'slr':u'[[WP:CSD#R5]]: ',
'repi':u'[[WP:CSD#I1]]: ',
'lssd':u'[[WP:CSD#I3]]: ',
'nls':u'[[WP:CSD#I3]]: ',
'svg':u'[[WP:CSD#I5]]: SVG',
'ui':u'[[WP:CSD#I6]]: ',
'commons':u'[[WP:CSD#I7]]: [[:commons:|]]',
'urs':u'[[WP:CSD#O1]]: ',
'anou':u'[[WP:CSD#O3]]: ',
'uc':u'[[WP:CSD#O5]]: ',
'tmp':u'[[WP:CSD]]: ',
},
},
#'wikinews':{
# 'en': {
# 'test': u'abcdefg',
# },
# 'zh': {
# 'test': u'',
# },
#},
# There's a template for nearly every possible reason on en:.
# If the bot can't guess the reason from the template, the user should
# enter it manually.
# 'en':
}
def __init__(self):
"""
Arguments:
none yet
"""
self.mySite = wikipedia.getSite()
self.csdCat = catlib.Category(self.mySite, wikipedia.translate(self.mySite, self.csd_cat))
self.savedProgress = None
self.preloadingGen = None
def guessReasonForDeletion(self, page):
reason = None
# TODO: The following check loads the page 2 times. Find a better way to do it.
if page.isTalkPage() and (page.toggleTalkPage().isRedirectPage() or not page.toggleTalkPage().exists()):
# This is probably a talk page that is orphaned because we
# just deleted the associated article.
reason = wikipedia.translate(self.mySite, self.talk_deletion_msg)
else:
# Try to guess reason by the template used
templateNames = page.templates()
reasons = wikipedia.translate(self.mySite, self.deletion_messages)
for templateName in templateNames:
if templateName in reasons:
if type(reasons[templateName]) is not unicode:
#Make alias to delete_reasons
reason = wikipedia.translate(self.mySite, self.delete_reasons)[reasons[templateName]]
else:
reason = reasons[templateName]
break
if not reason:
# Unsuccessful in guessing the reason. Use a default message.
reason = reasons[u'_default']
return reason
def getReasonForDeletion(self, page):
suggestedReason = self.guessReasonForDeletion(page)
wikipedia.output(u'The suggested reason is: \03{lightred}%s\03{default}' % suggestedReason)
# We don't use wikipedia.translate() here because for some languages the
# entry is intentionally left out.
if self.mySite.family.name in self.delete_reasons:
if page.site().lang in self.delete_reasons[self.mySite.family.name]:
localReasons = wikipedia.translate(page.site().lang, self.delete_reasons)
wikipedia.output(u'')
localReasoneKey = localReasons.keys()
localReasoneKey.sort()
for key in localReasoneKey:
wikipedia.output((key + ':').ljust(8) + localReasons[key])
wikipedia.output(u'')
reason = wikipedia.input(u'Please enter the reason for deletion, choose a default reason, or press enter for the suggested message:')
if reason.strip() in localReasons:
reason = localReasons[reason]
else:
reason = wikipedia.input(u'Please enter the reason for deletion, or press enter for the suggested message:')
else:
reason = wikipedia.input(u'Please enter the reason for deletion, or press enter for the suggested message:')
if not reason:
reason = suggestedReason
return reason
def run(self):
"""
Starts the robot's action.
"""
keepGoing = True
startFromBeginning = True
while keepGoing:
if startFromBeginning:
self.savedProgress = None
self.refreshGenerator()
count = 0
for page in self.preloadingGen:
try:
pageText = page.get(get_redirect = True).split("\n")
count += 1
except wikipedia.NoPage:
wikipedia.output(u'Page %s does not exist or has already been deleted, skipping.' % page.aslink())
continue
# Show the title of the page we're working on.
# Highlight the title in purple.
wikipedia.output(u"\n\n>>> \03{lightpurple}%s\03{default} <<<" % page.title())
wikipedia.output(u'- - - - - - - - - ')
if len(pageText) > 75:
wikipedia.output('The page detail is too many lines, only output first 50 lines:')
wikipedia.output(u'- - - - - - - - - ')
wikipedia.output(u'\n'.join(pageText[:50]))
else:
wikipedia.output(u'\n'.join(pageText))
wikipedia.output(u'- - - - - - - - - ')
choice = wikipedia.inputChoice(u'Input action?', ['delete', 'skip', 'update', 'quit'], ['d', 'S', 'u', 'q'], 'S')
if choice == 'q':
keepGoing = False
break
elif choice == 'u':
wikipedia.output(u'Updating from CSD category.')
self.savedProgress = page.title()
startFromBeginning = False
break
elif choice == 'd':
reason = self.getReasonForDeletion(page)
wikipedia.output(u'The chosen reason is: \03{lightred}%s\03{default}' % reason)
page.delete(reason, prompt = False)
else:
wikipedia.output(u'Skipping page %s' % page.title())
startFromBeginning = True
if count == 0:
if startFromBeginning:
wikipedia.output(u'There are no pages to delete.\nWaiting for 30 seconds or press Ctrl+C to quit...')
try:
time.sleep(30)
except KeyboardInterrupt:
keepGoing = False
else:
startFromBeginning = True
wikipedia.output(u'Quitting program.')
def refreshGenerator(self):
generator = pagegenerators.CategorizedPageGenerator(self.csdCat, start = self.savedProgress)
# wrap another generator around it so that we won't produce orphaned talk pages.
generator2 = pagegenerators.PageWithTalkPageGenerator(generator)
self.preloadingGen = pagegenerators.PreloadingGenerator(generator2, pageNumber = 20)
def main():
# read command line parameters
for arg in wikipedia.handleArgs():
pass #No args yet
bot = SpeedyRobot()
bot.run()
if __name__ == "__main__":
try:
main()
finally:
wikipedia.stopme()
|