Revision: 5914
Author: wikipedian
Date: 2008-09-22 16:15:37 +0000 (Mon, 22 Sep 2008)
Log Message:
-----------
Fixed the Esperanto X-convention bug [ 2006208 ] by rolling back many changes that
concerned Esperanto X-conv.
I fixed this on 2008-08-21 already, but somehow my commit seems to have failed
(sorry), so now I retry to commit it.
Modified Paths:
--------------
trunk/pywikipedia/families/wikipedia_family.py
trunk/pywikipedia/wikipedia.py
Modified: trunk/pywikipedia/families/wikipedia_family.py
===================================================================
--- trunk/pywikipedia/families/wikipedia_family.py 2008-09-22 09:58:41 UTC (rev 5913)
+++ trunk/pywikipedia/families/wikipedia_family.py 2008-09-22 16:15:37 UTC (rev 5914)
@@ -966,16 +966,4 @@
return self.code2encoding(code),
def shared_image_repository(self, code):
- return ('commons', 'commons')
-
- def post_get_convert(self, site, getText):
- if site.lang == 'eo':
- return wikipedia.decodeEsperantoX(getText)
- else:
- return getText
-
- def pre_put_convert(self, site, getText):
- if site.lang == 'eo':
- return wikipedia.encodeEsperantoX(getText)
- else:
- return getText
+ return ('commons', 'commons')
\ No newline at end of file
Modified: trunk/pywikipedia/wikipedia.py
===================================================================
--- trunk/pywikipedia/wikipedia.py 2008-09-22 09:58:41 UTC (rev 5913)
+++ trunk/pywikipedia/wikipedia.py 2008-09-22 16:15:37 UTC (rev 5914)
@@ -799,12 +799,12 @@
else:
self._isWatched = False
# Now process the contents of the textarea
- # Unescape HTML characters, strip whitespace and postconvert
- pagetext = text[i1:i2]
- pagetext = unescape(pagetext)
- pagetext = pagetext.rstrip()
- pagetext = self.site().post_get_convert(pagetext)
-
+ # Unescape HTML characters, strip whitespace
+ pagetext = text[i1:i2]
+ pagetext = unescape(pagetext)
+ pagetext = pagetext.rstrip()
+ if self.site().lang == 'eo':
+ pagetext = decodeEsperantoX(pagetext)
m = self.site().redirectRegex().match(pagetext)
if m:
# page text matches the redirect pattern
@@ -1295,7 +1295,12 @@
import watchlist
watchArticle = watchlist.isWatched(self.title(), site = self.site())
newPage = not self.exists()
- newtext = self.site().pre_put_convert(newtext)
+ # if posting to an Esperanto wiki, we must e.g. write Bordeauxx instead
+ # of Bordeaux
+ if self.site().lang == 'eo':
+ newtext = encodeEsperantoX(newtext)
+ comment = encodeEsperantoX(comment)
+
return self._putPage(newtext, comment, watchArticle, minorEdit,
newPage, self.site().getToken(sysop = sysop), sysop = sysop)
@@ -2237,7 +2242,7 @@
reason = input(u'Please enter a reason for the deletion:')
answer = 'y'
if prompt and not hasattr(self.site(), '_noDeletePrompt'):
- answer = inputChoice(u'Do you want to delete %s?' % self.aslink(forceInterwiki = True), ['Yes', 'No', 'All'], ['Y', 'N', 'A'], 'N')
+ answer = inputChoice(u'Do you want to delete %s?' % self.aslink(forceInterwiki = True), ['yes', 'no', 'all'], ['y', 'N', 'a'], 'N')
if answer == 'a':
answer = 'y'
self.site()._noDeletePrompt = True
@@ -2939,6 +2944,9 @@
def getData(self):
address = self.site.export_address()
pagenames = [page.sectionFreeTitle() for page in self.pages]
+ # We need to use X convention for requested page titles.
+ if self.site.lang == 'eo':
+ pagenames = [encodeEsperantoX(pagetitle) for pagetitle in pagenames]
pagenames = u'\r\n'.join(pagenames)
if type(pagenames) is not unicode:
output(u'Warning: xmlreader.WikipediaXMLHandler.getData() got non-unicode page names. Please report this.')
@@ -3995,11 +4003,6 @@
linktrail: Return regex for trailing chars displayed as part of a link.
disambcategory: Category in which disambiguation pages are listed.
- post_get_convert: Converts text data from the site immediatly after get
- i.e. EsperantoX -> unicode
- pre_put_convert: Converts text data from the site immediatly before put
- i.e. unicode -> EsperantoX
-
Methods that yield Page objects derived from a wiki's Special: pages
(note, some methods yield other information in a tuple along with the
Pages; see method docs for details) --
@@ -5840,12 +5843,6 @@
"""Return regex for trailing chars displayed as part of a link."""
return self.family.linktrail(self.lang)
- def post_get_convert(self, getText):
- return self.family.post_get_convert(self, getText)
-
- def pre_put_convert(self, putText):
- return self.family.pre_put_convert(self, putText)
-
def language(self):
"""Return Site's language code."""
return self.lang
Bugs item #2137018, was opened at 2008-09-29 23:06
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=603138&aid=2137018&group_…
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Purodha B Blissenbach (purodha)
Assigned to: Nobody/Anonymous (nobody)
Summary: special_page_limit not honored
Initial Comment:
In the config, I have:
special_page_limit = 5000
but my recentechanges bot only operates on 1000 entries, then it stops. Maybe, the limitation
is within MediaWiki, or the bot must be run with
admin powers or something else, I have not
investigated.
I do not really know, when this was changed, but
some months ago, it would work as expected, and
nothing was changed in the config file since.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=603138&aid=2137018&group_…
Hi all,
(I'm re-posting this message because I sent it from the wrong eMail
account.)
The page http://no.wikipedia.org/wiki/MmHg uses a non-capitalized title,
which is realized via {{DISPLAYTITLE:mmHg}}.
This has caused a massive bot editwar, see:
http://de.wikipedia.org/w/index.php?title=Torr&action=history
Some people are already making fun of this at:
http://de.wikipedia.org/wiki/Wikipedia:Kurier
AFAIK, the standard PyWikipediaBot ignores the {{DISPLAYTITLE}} tag, and
would therefore use [[no:MmHg]]. Are some people (Ptbotgourou, Louperibot,
Loveless, MystBot, SieBot, TXiKiBoT) a modified version which respects
{{DISPLAYTITLE}}? Or is there an older release that behaves different from
the current version?
I don't care if bots set [[no:mmHg]] or [[no:MmHg]], but they should all
work consistently so that there are no edit wars.
Cheers
Daniel
Revision: 5923
Author: cydeweys
Date: 2008-09-29 02:58:20 +0000 (Mon, 29 Sep 2008)
Log Message:
-----------
Getting rid of the obsolete catmove.pl Perl script (probably not suitable
for a Python bot anyway) and replacing it with a more capable bot written
purely in Python. This is the same code running Cydebot on the English
Wikipedia and should be easily adaptable for other languages' wikis if
they have the same concept of a CFD working page.
Added Paths:
-----------
trunk/pywikipedia/cfd.py
Removed Paths:
-------------
trunk/pywikipedia/catmove.pl
Deleted: trunk/pywikipedia/catmove.pl
===================================================================
--- trunk/pywikipedia/catmove.pl 2008-09-28 17:59:40 UTC (rev 5922)
+++ trunk/pywikipedia/catmove.pl 2008-09-29 02:58:20 UTC (rev 5923)
@@ -1,86 +0,0 @@
-#!/usr/bin/perl
-# $Id$
-
-# This Perl script takes a list of category moves or removes to make and uses category.py.
-# The input format is as follows:
-# * Category:US to Category:United States
-# OR
-# * Category:US
-# Just copy-paste the list of categories to move or remove from the Wiki, put them in a
-# text-file, and redirect to stdin, i.e., perl catmove.pl < catmoves.txt
-# If you want to use an edit summary, then pass it in as a parameter, i.e.,
-# perl catmove.pl "Emptying dead category" < catmoves.txt
-# Note that if your summary has multiple words in it then enclose it in quotes.
-#
-# To set edit summaries, you can also preface a line with a semicolon ;
-# That will be the edit summary for all subsequent executions ... unless you modify the
-# edit summary again with another semicolon. In this way you can take care of many days
-# worth of WP:CFD backlog with a single execution.
-
-#Necessary for thread handling.
-use POSIX ":sys_wait_h";
-
-#Preliminary setup.
-my $editSummary = '';
-my $customSummary = 0;
-my $throttle = 6;
-my $sysCall = '';
-my $errorLog = "";
-if ($#ARGV >= 0) {
- $customSummary = 1;
- $editSummary = shift;
-}
-
-#my $args = "-batch -putthrottle:$throttle -inplace";
-my $args = "-batch -putthrottle:$throttle";
-
-#Loop through all standard input.
-while (<STDIN>) {
- #Matches category moves and category removals.
- if ($_ =~ m/^\s*[\#\*]?\s*[Cc]ategory:(.*?)\s*to\s*[Cc]ategory:(.*?)\s*$/ || $_ =~ m/^\s*[\#\*]?\s*[Cc]ategory:(.*?)\s*$/) {
- #Matches category moves.
- if ($_ =~ m/^\s*[\#\*]?\s*[Cc]ategory:(.*?)\s*to\s*[Cc]ategory:(.*?)\s*$/) {
- my $from = $1;
- my $to = $2;
- if ($customSummary == 0) {
- $sysCall = "python category.py move -from:\"$from\" -to:\"$to\"";
- } else {
- $sysCall = "python category.py move -from:\"$from\" -to:\"$to\" -summary:\"$editSummary\"";
- }
- }
- #Matches category removals.
- elsif ($_ =~ m/^\s*[\#\*]?\s*[Cc]ategory:(.*?)\s*$/) {
- my $from = $1;
- if ($customSummary == 0) {
- $sysCall = "python category.py remove -from:\"$from\"";
- } else {
- $sysCall = "python category.py remove -from:\"$from\" -summary:\"$editSummary\"";
- }
- }
-
- #Fork off the execution of the Python bot as its own thread. Errors will be skipped and execution continues
- #through the whole list. Ctrl-C will quit everything immediately, though. (This is why we can't use the
- #much simpler system() function).
- print "Executing: $sysCall $args\n";
- defined (my $pid = fork) or die "Cannot fork: $!";
- unless ($pid) {
- exec("$sysCall $args");
- }
- waitpid($pid, 0);
- #If the Python script terminates abnormally print something to that effect.
- if ($? == 256) {
- $errorLog .= "* $sysCall $args\n";
- }
- }
- #Setting the edit summary.
- elsif ($_ =~ m/^\s*;\s*(.*)\s*$/) {
- $customSummary = 1;
- $editSummary = $1;
- } else {
- print "Invalid line: $_\n";
- }
-}
-
-if ($errorLog ne "") {
- print "Errors detected with the following commands:\n$errorLog";
-}
Added: trunk/pywikipedia/cfd.py
===================================================================
--- trunk/pywikipedia/cfd.py (rev 0)
+++ trunk/pywikipedia/cfd.py 2008-09-29 02:58:20 UTC (rev 5923)
@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+"""
+This script processes the Categories for discussion working page. It parses
+out the actions that need to be taken as a result of CFD discussions (as posted
+to the working page by an administrator) and performs them.
+
+Syntax: python cfd.py
+
+"""
+
+# (C) Ben McIlwain, 2008
+#
+# Distributed under the terms of the MIT license.
+
+import wikipedia
+import re
+import category
+
+# Regular expression declarations
+# See the en-wiki CFD working page at [[Wikipedia:Categories for discussion/Working]]
+# to see how these work in context. To get this bot working on other wikis you will
+# need to adjust these regular expressions at the very least.
+nobots = re.compile(r"NO\s*BOTS", re.IGNORECASE);
+example = re.compile(r"\[\[\:Category\:(.)\1\1\1\1\]\]", re.IGNORECASE);
+speedymode = re.compile(r"^===*\s*Speedy Moves\s*===*\s*$", re.IGNORECASE);
+movemode = re.compile(r"^===*\s*Move\/Merge then delete\s*===*\s*$", re.IGNORECASE);
+emptymode = re.compile(r"^===*\s*Empty then delete\s*===*\s*$", re.IGNORECASE)
+deletemode = re.compile(r"^===*\s*Ready for deletion\s*===*\s*$", re.IGNORECASE)
+maintenance = re.compile(r"^===*\s*Old by month categories with entries\s*===*\s*$", re.IGNORECASE)
+dateheader = re.compile(r"(\[\[Wikipedia\:Categories[_ ]for[_ ](?:discussion|deletion)\/Log\/([^\]]*?)\]\])", re.IGNORECASE)
+movecat = re.compile(r"\[\[\:Category\:([^\]]*?)\]\][^\]]*?\[\[\:Category\:([^\]]*?)\]\]", re.IGNORECASE)
+deletecat = re.compile(r"\[\[\:Category\:([^\]]*?)\]\]", re.IGNORECASE)
+findday = re.compile(r"\[\[(Wikipedia\:Categories for (?:discussion|deletion)\/Log\/\d{4} \w+ \d+)#", re.IGNORECASE)
+
+class ReCheck:
+ def __init__(self):
+ self.result = None
+ def check(self, pattern, text):
+ self.result = pattern.search(text)
+ return self.result
+
+def main():
+ wikipedia.handleArgs();
+
+ page = wikipedia.Page(wikipedia.getSite(), 'Wikipedia:Categories for discussion/Working')
+
+ # Variable declarations
+ day = "None"
+ mode = "None"
+ src = "None"
+ dest = "None"
+ line = ""
+ summary = ""
+ robot = None
+
+ m = ReCheck()
+ for line in page.get().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)
+ elif (m.check(movecat, line)):
+ src = m.result.group(1)
+ dest = m.result.group(2)
+ if (mode == "Move" and day != "None"):
+ summary = "Robot - Moving category " + src + " to " + dest + " per [[WP:CFD|CFD]] at " + findDay(src, day) + "."
+ elif (mode == "Speedy"):
+ summary = "Robot - Speedily moving category " + src + " to " + dest + " per [[WP:CFD|CFD]]."
+ else:
+ continue
+ robot = category.CategoryMoveRobot(oldCatTitle=src, newCatTitle=dest, batchMode=True,
+ editSummary=summary, inPlace=True, moveCatPage=True,
+ deleteEmptySourceCat=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.
+ if ((mode == "Empty" or mode == "Delete") and day != "None"):
+ summary = "Robot - Removing category " + src + " per [[WP:CFD|CFD]] at " + findDay(src, day) + "."
+ else:
+ continue
+ robot = category.CategoryRemoveRobot(catTitle=src, batchMode=True, editSummary=summary,
+ useSummaryForDeletion=True, inPlace=True)
+ else:
+ # This line does not fit any of our regular expressions, so ignore it.
+ pass
+ if (summary != "" and robot != None):
+ wikipedia.output(summary, toStdout=True)
+ # Run, robot, run!
+ robot.run()
+ summary = ""
+ robot = None
+
+# This function grabs the wiki source of a category page and attempts to
+# extract a link to the CFD per-day discussion page from the CFD template.
+# If the CFD template is not there, it will return the value of the second
+# parameter, which is essentially a fallback that is extracted from the
+# per-day subheadings on the working page.
+def findDay(pageTitle, oldDay):
+ page = wikipedia.Page(wikipedia.getSite(), "Category:" + pageTitle)
+ pageSrc = page.get()
+ m = findday.search(pageSrc)
+ if (m != None):
+ return "[[" + m.group(1) + "]]"
+ else:
+ wikipedia.output("Could not find CFD day link on Category:" + pageTitle + "\n", toStdout=True)
+ return oldDay
+
+if __name__ == "__main__":
+ try:
+ main()
+ except:
+ wikipedia.stopme()
+ raise
+ else:
+ wikipedia.stopme()
+
Revision: 5921
Author: russblau
Date: 2008-09-26 19:35:08 +0000 (Fri, 26 Sep 2008)
Log Message:
-----------
Made site.userinfo a property; fixed api.update_page to store page text; added tests, tests, and more tests.
Modified Paths:
--------------
branches/rewrite/pywikibot/data/api.py
branches/rewrite/pywikibot/site.py
branches/rewrite/pywikibot/tests/site_tests.py
Modified: branches/rewrite/pywikibot/data/api.py
===================================================================
--- branches/rewrite/pywikibot/data/api.py 2008-09-26 12:34:30 UTC (rev 5920)
+++ branches/rewrite/pywikibot/data/api.py 2008-09-26 19:35:08 UTC (rev 5921)
@@ -576,14 +576,28 @@
"Page %s has neither 'pageid' nor 'missing' attribute"
% pagedict['title'])
page._redir = 'redirect' in pagedict
- if 'lastrevid' in pagedict:
- page._revid = pagedict['lastrevid']
if 'touched' in pagedict:
page._timestamp = pagedict['touched']
if 'protection' in pagedict:
page._protection = {}
for item in pagedict['protection']:
page._protection[item['type']] = item['level'], item['expiry']
+ if 'revisions' in pagedict:
+ for rev in pagedict['revisions']:
+ revision = pywikibot.page.Revision(
+ revid=rev['revid'],
+ timestamp=rev['timestamp'],
+ user=rev['user'],
+ anon=rev.has_key('anon'),
+ comment=rev.get('comment', u''),
+ minor=rev.has_key('minor'),
+ text=rev.get('*', None)
+ )
+ page._revisions[revision.revid] = revision
+ if 'lastrevid' in pagedict:
+ page._revid = pagedict['lastrevid']
+ if page._revid in page._revisions:
+ page._text = page._revisions[page._revid].text
if __name__ == "__main__":
Modified: branches/rewrite/pywikibot/site.py
===================================================================
--- branches/rewrite/pywikibot/site.py 2008-09-26 12:34:30 UTC (rev 5920)
+++ branches/rewrite/pywikibot/site.py 2008-09-26 19:35:08 UTC (rev 5921)
@@ -207,7 +207,6 @@
return self.family.langs.keys()
-
def validLanguageLinks(self):
"""Return list of language codes that can be used in interwiki links."""
@@ -368,9 +367,6 @@
## Site methods from version 1.0 (as these are implemented in this file,
## or declared deprecated/obsolete, they will be removed from this list)
##########
-## validLanguageLinks: A list of language codes that can be used in interwiki
-## links.
-##
## messages: return True if there are new messages on the site
## cookies: return user's cookies as a string
##
@@ -379,24 +375,8 @@
## postForm: Post form data to an address at this site.
## postData: Post encoded form data to an http address at this site.
##
-## redirect: Return the localized redirect tag for the site.
-## redirectRegex: Return compiled regular expression matching on redirect
-## pages.
-## mediawiki_message: Retrieve the text of a specified MediaWiki message
-## has_mediawiki_message: True if this site defines specified MediaWiki
-## message
-##
## shared_image_repository: Return tuple of image repositories used by this
## site.
-## category_on_one_line: Return True if this site wants all category links
-## on one line.
-## interwiki_putfirst: Return list of language codes for ordering of
-## interwiki links.
-## linkto(title): Return string in the form of a wikilink to 'title'
-## isInterwikiLink(s): Return True if 's' is in the form of an interwiki
-## link.
-## getSite(lang): Return Site object for wiki in same family, language
-## 'lang'.
## version: Return MediaWiki version string from Family file.
## versionnumber: Return int identifying the MediaWiki version.
## live_version: Return version number read from Special:Version.
@@ -413,7 +393,6 @@
## newimages(): Special:Log&type=upload
## longpages(): Special:Longpages
## shortpages(): Special:Shortpages
-## categories(): Special:Categories (yields Category objects)
## deadendpages(): Special:Deadendpages
## ancientpages(): Special:Ancientpages
## lonelypages(): Special:Lonelypages
@@ -459,16 +438,7 @@
return
# ANYTHING BELOW THIS POINT IS NOT YET IMPLEMENTED IN __init__()
- self._mediawiki_messages = {}
self.nocapitalize = self.__code in self.family.nocapitalize
- self._userData = [False, False]
- self._userName = [None, None]
- self._isLoggedIn = [None, None]
- self._isBlocked = [None, None]
- self._messages = [None, None]
- self._rights = [None, None]
- self._token = [None, None]
- self._cookies = [None, None]
# Calculating valid languages took quite long, so we calculate it once
# in initialization instead of each time it is used.
self._validlanguages = []
@@ -482,9 +452,9 @@
@param sysop: if True, require sysop privileges.
"""
- if self.getuserinfo()['name'] != self._username:
+ if self.userinfo['name'] != self._username:
return False
- return (not sysop) or 'sysop' in self.getuserinfo()['groups']
+ return (not sysop) or 'sysop' in self.userinfo['groups']
def loggedInAs(self, sysop = False):
"""Return the current username if logged in, otherwise return None.
@@ -501,7 +471,7 @@
self._getsiteinfo()
# check whether a login cookie already exists for this user
if hasattr(self, "_userinfo"):
- if self._userinfo['name'] == self._username:
+ if self.userinfo['name'] == self._username:
return
if not self.logged_in(sysop):
loginMan = api.LoginManager(site=self, sysop=sysop,
@@ -544,6 +514,8 @@
self._userinfo = uidata['query']['userinfo']
return self._userinfo
+ userinfo = property(fget=getuserinfo, doc=getuserinfo.__doc__)
+
def is_blocked(self, sysop=False):
"""Return true if and only if user is blocked.
@@ -685,6 +657,7 @@
return self._siteinfo
def case(self):
+ """Return this site's capitalization rule."""
return self.siteinfo['case']
@@ -840,7 +813,7 @@
% (len(cache), self)
)
for pagedata in rvgen:
-# logger.debug("Preloading %s" % pagedata)
+ logger.debug("Preloading %s" % pagedata)
try:
if pagedata['title'] not in cache:
raise Error(
@@ -914,7 +887,7 @@
if filterRedirects is not None:
blgen.request["gblfilterredir"] = filterRedirects and "redirects"\
or "nonredirects"
- if followRedirects:
+ if followRedirects: #FIXME This doesn't work correctly
blgen.request["gblredirect"] = ""
return blgen
@@ -1819,22 +1792,22 @@
"deletedrevs: start must be later than end with reverse=False")
if not self.logged_in():
self.login()
- if "deletedhistory" not in self.getuserinfo()['rights']:
+ if "deletedhistory" not in self.userinfo['rights']:
try:
self.login(True)
except NoUsername:
pass
- if "deletedhistory" not in self.getuserinfo()['rights']:
+ if "deletedhistory" not in self.userinfo['rights']:
raise Error(
"deletedrevs: User:%s not authorized to access deleted revisions."
% self.user())
if get_text:
- if "undelete" not in self.getuserinfo()['rights']:
+ if "undelete" not in self.userinfo['rights']:
try:
self.login(True)
except NoUsername:
pass
- if "undelete" not in self.getuserinfo()['rights']:
+ if "undelete" not in self.userinfo['rights']:
raise Error(
"deletedrevs: User:%s not authorized to view deleted content."
% self.user())
@@ -1958,7 +1931,7 @@
req['minor'] = ""
elif notminor:
req['notminor'] = ""
- if 'bot' in self.getuserinfo()['groups']:
+ if 'bot' in self.userinfo['groups']:
req['bot'] = ""
if recreate:
req['recreate'] = ""
Modified: branches/rewrite/pywikibot/tests/site_tests.py
===================================================================
--- branches/rewrite/pywikibot/tests/site_tests.py 2008-09-26 12:34:30 UTC (rev 5920)
+++ branches/rewrite/pywikibot/tests/site_tests.py 2008-09-26 19:35:08 UTC (rev 5921)
@@ -20,93 +20,132 @@
class TestSiteObject(unittest.TestCase):
"""Test cases for Site methods."""
+ def assertType(self, obj, cls):
+ """Assert that obj is an instance of type cls"""
+ return self.assertTrue(isinstance(obj, cls))
+
def testBaseMethods(self):
"""Test cases for BaseSite methods"""
self.assertEqual(mysite.family.name, pywikibot.config.family)
self.assertEqual(mysite.code, pywikibot.config.mylang)
- self.assertTrue(isinstance(mysite.language(), basestring))
- self.assertTrue(isinstance(mysite == pywikibot.Site("en", "wikipedia"),
- bool))
- self.assertTrue(isinstance(mysite.user(), (basestring, type(None))))
+ self.assertType(mysite.lang, basestring)
+ self.assertType(mysite == pywikibot.Site("en", "wikipedia"), bool)
+ self.assertType(mysite.user(), (basestring, type(None)))
self.assertEqual(mysite.sitename(),
- "%s:%s" % (pywikibot.config.family, pywikibot.config.mylang))
+ "%s:%s" % (pywikibot.config.family,
+ pywikibot.config.mylang))
self.assertEqual(repr(mysite),
'Site("%s", "%s")'
% (pywikibot.config.mylang, pywikibot.config.family))
- self.assertTrue(isinstance(mysite.linktrail(), basestring))
+ self.assertType(mysite.linktrail(), basestring)
+ self.assertType(mysite.redirect(default=True), basestring)
+ self.assertType(mysite.disambcategory(), pywikibot.Category)
+ self.assertEqual(mysite.linkto("foo"), u"[[Foo]]")
+ self.assertFalse(mysite.isInterwikiLink("foo"))
+ self.assertType(mysite.redirectRegex().pattern, basestring)
+ self.assertType(mysite.category_on_one_line(), bool)
+ for grp in ("user", "autoconfirmed", "bot", "sysop", "nosuchgroup"):
+ self.assertType(mysite.has_group(grp), bool)
+ for rgt in ("read", "edit", "move", "delete", "rollback", "block",
+ "nosuchright"):
+ self.assertType(mysite.has_right(rgt), bool)
+
+ def testLanguageMethods(self):
+ """Test cases for languages() and related methods"""
+
langs = mysite.languages()
- self.assertTrue(isinstance(langs, list))
+ self.assertType(langs, list)
self.assertTrue(mysite.code in langs)
obs = mysite.family.obsolete
ipf = mysite.interwiki_putfirst()
- self.assertTrue(isinstance(ipf, list))
- for item in ipf:
- self.assertTrue(item in langs or item in obs)
- self.assertEqual(mysite.ns_index("Talk"), 1)
+ self.assertType(ipf, list)
+ self.assertTrue(all(item in langs or item in obs
+ for item in ipf))
+ self.assertTrue(all(item in langs
+ for item in mysite.validLanguageLinks()))
+
+ def testNamespaceMethods(self):
+ """Test cases for methods manipulating namespace names"""
+
+ builtins = {'Talk': 1, # these should work in any MW wiki
+ 'User': 2,
+ 'User talk': 3,
+ 'Project': 4,
+ 'Project talk': 5,
+ 'Image': 6,
+ 'Image talk': 7,
+ 'MediaWiki': 8,
+ 'MediaWiki talk': 9,
+ 'Template': 10,
+ 'Template talk': 11,
+ 'Help': 12,
+ 'Help talk': 13,
+ 'Category': 14,
+ 'Category talk': 15,
+ }
+ self.assertTrue(all(mysite.ns_index(b) == builtins[b]
+ for b in builtins))
ns = mysite.namespaces()
- self.assertTrue(isinstance(ns, dict))
- for x in xrange(0, 16): # built-in namespaces always present
- self.assertTrue(x in ns)
- self.assertTrue(isinstance(ns[x], list))
- self.assertTrue(isinstance(mysite.ns_normalize("project"), basestring))
- self.assertTrue(isinstance(mysite.redirect(), basestring))
- self.assertTrue(isinstance(mysite.disambcategory(), pywikibot.Category))
- self.assertTrue(isinstance(mysite.redirectRegex().pattern, basestring))
- self.assertTrue(isinstance(mysite.category_on_one_line(), bool))
- for grp in ("user", "autoconfirmed", "bot", "sysop", "nosuchgroup"):
- self.assertTrue(isinstance(mysite.has_group(grp), bool))
- for rgt in ("read", "edit", "move", "delete", "rollback", "block",
- "nosuchright"):
- self.assertTrue(isinstance(mysite.has_right(rgt), bool))
-
- def testApiMethods(self):
- """Test generic ApiSite methods"""
-
- self.assertTrue(isinstance(mysite.logged_in(), bool))
- self.assertTrue(isinstance(mysite.getuserinfo(), dict))
- self.assertTrue(isinstance(mysite.is_blocked(), bool))
- self.assertTrue(isinstance(mysite.messages(), bool))
- self.assertTrue(isinstance(mysite.getcurrenttimestamp(), basestring))
- self.assertTrue(isinstance(mysite.siteinfo, dict))
- self.assertTrue(isinstance(mysite.case(), basestring))
- self.assertTrue(isinstance(mysite.namespaces(), dict))
+ self.assertType(ns, dict)
+ self.assertTrue(all(x in ns for x in xrange(0, 16)))
+ # built-in namespaces always present
+ self.assertType(mysite.ns_normalize("project"), basestring)
self.assertTrue(all(isinstance(key, int)
- for key in mysite.namespaces()))
+ for key in ns))
self.assertTrue(all(isinstance(val, list)
- for val in mysite.namespaces().values()))
+ for val in ns.values()))
self.assertTrue(all(isinstance(name, basestring)
- for val in mysite.namespaces().values()
+ for val in ns.values()
for name in val))
self.assertTrue(all(isinstance(mysite.namespace(key), basestring)
- for key in mysite.namespaces()))
+ for key in ns))
self.assertTrue(all(isinstance(mysite.namespace(key, True), list)
- for key in mysite.namespaces()))
+ for key in ns))
self.assertTrue(all(isinstance(item, basestring)
- for key in mysite.namespaces()
+ for key in ns
for item in mysite.namespace(key, True)))
- ver = mysite.live_version()
- self.assertTrue(isinstance(ver, tuple))
- self.assertTrue(all(isinstance(ver[i], int) for i in (0, 1)))
- self.assertTrue(isinstance(ver[2], basestring))
+
+ def testApiMethods(self):
+ """Test generic ApiSite methods"""
+
+ self.assertType(mysite.logged_in(), bool)
+ self.assertType(mysite.logged_in(True), bool)
+ self.assertType(mysite.userinfo, dict)
+ self.assertType(mysite.is_blocked(), bool)
+ self.assertType(mysite.is_blocked(True), bool)
+ self.assertType(mysite.messages(), bool)
+ self.assertType(mysite.has_right("edit"), bool)
+ self.assertFalse(mysite.has_right("nonexistent_right"))
+ self.assertType(mysite.has_right("edit", True), bool)
+ self.assertFalse(mysite.has_right("nonexistent_right", True))
+ self.assertType(mysite.has_group("bots"), bool)
+ self.assertFalse(mysite.has_group("nonexistent_group"))
+ self.assertType(mysite.has_group("bots", True), bool)
+ self.assertFalse(mysite.has_group("nonexistent_group", True))
for msg in ("1movedto2", "about", "aboutpage", "aboutsite",
"accesskey-n-portal"):
self.assertTrue(mysite.has_mediawiki_message(msg))
- self.assertTrue(isinstance(mysite.mediawiki_message(msg),
- basestring))
+ self.assertType(mysite.mediawiki_message(msg), basestring)
self.assertFalse(mysite.has_mediawiki_message("nosuchmessage"))
self.assertRaises(KeyError, mysite.mediawiki_message, "nosuchmessage")
+ self.assertType(mysite.getcurrenttimestamp(), basestring)
+ self.assertType(mysite.siteinfo, dict)
+ self.assertType(mysite.case(), basestring)
+ ver = mysite.live_version()
+ self.assertType(ver, tuple)
+ self.assertTrue(all(isinstance(ver[i], int) for i in (0, 1)))
+ self.assertType(ver[2], basestring)
def testPageMethods(self):
"""Test ApiSite methods for getting page-specific info"""
- self.assertTrue(isinstance(mysite.page_exists(mainpage), bool))
- self.assertTrue(isinstance(mysite.page_restrictions(mainpage), dict))
- self.assertTrue(isinstance(mysite.page_can_be_edited(mainpage), bool))
- self.assertTrue(isinstance(mysite.page_isredirect(mainpage), bool))
+ self.assertType(mysite.page_exists(mainpage), bool)
+ self.assertType(mysite.page_restrictions(mainpage), dict)
+ self.assertType(mysite.page_can_be_edited(mainpage), bool)
+ self.assertType(mysite.page_isredirect(mainpage), bool)
if mysite.page_isredirect(mainpage):
- self.assertTrue(isinstance(mysite.getredirtarget(mainpage),
- pywikibot.Page))
+ self.assertType(mysite.getredirtarget(mainpage), pywikibot.Page)
else:
self.assertRaises(pywikibot.IsNotRedirectPage,
mysite.getredirtarget, mainpage)
@@ -119,9 +158,22 @@
"""Test ability to get page tokens"""
for ttype in ("edit", "move"): # token types for non-sysops
- self.assertTrue(isinstance(mysite.token(mainpage, ttype),
- basestring))
+ self.assertType(mysite.token(mainpage, ttype), basestring)
+ self.assertRaises(KeyError, mysite.token, mainpage, "invalidtype")
+ def testPreload(self):
+ """Test that preloading works"""
+
+ count = 0
+ for page in mysite.preloadpages(mysite.pagelinks(mainpage)):
+ self.assertType(page, pywikibot.Page)
+ self.assertType(page.exists(), bool)
+ if page.exists():
+ self.assertTrue(hasattr(page, "_text"))
+ count += 1
+ if count >= 5:
+ break
+
def testLinkMethods(self):
"""Test site methods for getting links to and from a page"""
@@ -129,25 +181,41 @@
embedded = set(mysite.page_embeddedin(mainpage, namespaces=[0]))
refs = set(mysite.pagereferences(mainpage, namespaces=[0]))
for bl in backlinks:
- self.assertTrue(isinstance(bl, pywikibot.Page))
+ self.assertType(bl, pywikibot.Page)
self.assertTrue(bl in refs)
for ei in embedded:
- self.assertTrue(isinstance(ei, pywikibot.Page))
+ self.assertType(ei, pywikibot.Page)
self.assertTrue(ei in refs)
for ref in refs:
self.assertTrue(ref in backlinks or ref in embedded)
+ # test backlinks arguments
+ self.assertTrue(backlinks.issubset(
+ set(mysite.pagebacklinks(mainpage,
+ followRedirects=True,
+ namespaces=[0]))))
+ self.assertTrue(backlinks.issuperset(
+ set(mysite.pagebacklinks(mainpage,
+ filterRedirects=True,
+ namespaces=[0]))))
+ self.assertTrue(backlinks.issuperset(
+ set(mysite.pagebacklinks(mainpage,
+ filterRedirects=False,
+ namespaces=[0]))))
+ self.assertTrue(backlinks.issubset(
+ set(mysite.pagebacklinks(mainpage, namespaces=[0, 2]))))
+ #
for pl in mysite.pagelinks(mainpage):
- self.assertTrue(isinstance(pl, pywikibot.Page))
+ self.assertType(pl, pywikibot.Page)
for cat in mysite.pagecategories(mainpage):
- self.assertTrue(isinstance(cat, pywikibot.Category))
+ self.assertType(cat, pywikibot.Category)
for cm in mysite.categorymembers(cat):
- self.assertTrue(isinstance(cat, pywikibot.Page))
+ self.assertType(cat, pywikibot.Page)
self.assertTrue(all(isinstance(im, pywikibot.ImagePage)
for im in mysite.pageimages(mainpage)))
self.assertTrue(all(isinstance(te, pywikibot.Page)
for te in mysite.pagetemplates(mainpage)))
for ll in mysite.pagelanglinks(mainpage):
- self.assertTrue(isinstance(ll, pywikibot.Link))
+ self.assertType(ll, pywikibot.Link)
self.assertTrue(all(isinstance(el, basestring)
for el in mysite.page_extlinks(mainpage)))
@@ -165,7 +233,7 @@
ap = list(mysite.allpages(limit=10))
self.assertTrue(len(ap) <= 10)
for page in ap:
- self.assertTrue(isinstance(page, pywikibot.Page))
+ self.assertType(page, pywikibot.Page)
self.assertTrue(mysite.page_exists(page))
# TODO: test various optional arguments to allpages
@@ -192,7 +260,7 @@
au = list(mysite.allusers(limit=10))
self.assertTrue(len(au) <= 10)
for user in au:
- self.assertTrue(isinstance(user, dict))
+ self.assertType(user, dict)
self.assertTrue(user.has_key("name"))
self.assertTrue(user.has_key("editcount"))
self.assertTrue(user.has_key("registration"))
@@ -291,7 +359,7 @@
us = list(mysite.users([mysite.user()]))
self.assertEqual(len(us), 1)
- self.assertTrue(isinstance(us[0], dict))
+ self.assertType(us[0], dict)
def testRandompages(self):
"""Test the site.randompages() method"""