Revision: 7461 Author: alexsh Date: 2009-10-14 16:22:04 +0000 (Wed, 14 Oct 2009)
Log Message: ----------- Site()._getUserData(): separate API and ordinary page getinfo process
Modified Paths: -------------- trunk/pywikipedia/wikipedia.py
Modified: trunk/pywikipedia/wikipedia.py =================================================================== --- trunk/pywikipedia/wikipedia.py 2009-10-14 16:19:39 UTC (rev 7460) +++ trunk/pywikipedia/wikipedia.py 2009-10-14 16:22:04 UTC (rev 7461) @@ -5335,7 +5335,7 @@ conn.close()
# If a wiki page, get user data - self._getUserData(data, sysop = sysop) + self._getUserDataOld(data, sysop = sysop)
return response, data
@@ -5481,7 +5481,7 @@ text = unicode(text, charset, errors = 'replace')
# If a wiki page, get user data - self._getUserData(text, sysop = sysop) + self._getUserDataOld(text, sysop = sysop)
if back_response: return response, text @@ -5490,230 +5490,236 @@
def _getUserData(self, text, sysop = False, force = True): """ - Get the user data from a wiki page data. + Get the user data from an API query dict.
Parameters: * text - the page text * sysop - is the user a sysop? """ - + index = self._userIndex(sysop) + # Check for blocks + if 'blockedby' in text and not self._isBlocked[index]: + # Write a warning if not shown earlier + if sysop: + account = 'Your sysop account' + else: + account = 'Your account' + output(u'WARNING: %s on %s is blocked. Editing using this account will stop the run.' % (account, self)) + self._isBlocked[index] = 'blockedby' in text
- if type(text) == dict: #text is dict, query from API - # Check for blocks - if 'blockedby' in text and not self._isBlocked[index]: - # Write a warning if not shown earlier + # Check for new messages, the data must had key 'messages' in dict. + if 'messages' in text: + if not self._messages[index]: + # User has *new* messages if sysop: - account = 'Your sysop account' + output(u'NOTE: You have new messages in your sysop account on %s' % self) else: - account = 'Your account' - output(u'WARNING: %s on %s is blocked. Editing using this account will stop the run.' % (account, self)) - self._isBlocked[index] = 'blockedby' in text + output(u'NOTE: You have new messages on %s' % self) + self._messages[index] = True + else: + self._messages[index] = False
- # Check for new messages, the data must had key 'messages' in dict. - if 'messages' in text: - if not self._messages[index]: - # User has *new* messages + # Don't perform other checks if the data was already loaded + if self._userData[index] and not force: + return + + # Get username. + # The data in anonymous mode had key 'anon' + # if 'anon' exist, username is IP address, not to collect it right now + if not 'anon' in text: + self._isLoggedIn[index] = True + self._userName[index] = text['name'] + else: + self._isLoggedIn[index] = False + self._userName[index] = None + + # Get user groups and rights + if 'groups' in text: + self._rights[index] = text['groups'] + self._rights[index].extend(text['rights']) + # Warnings + # Don't show warnings for not logged in users, they will just fail to + # do any action + if self._isLoggedIn[index]: + if 'bot' not in self._rights[index] and config.notify_unflagged_bot: + # Sysop + bot flag = Sysop flag in MediaWiki < 1.7.1? if sysop: - output(u'NOTE: You have new messages in your sysop account on %s' % self) + output(u'Note: Your sysop account on %s does not have a bot flag. Its edits will be visible in the recent changes.' % self) else: - output(u'NOTE: You have new messages on %s' % self) - self._messages[index] = True + output(u'WARNING: Your account on %s does not have a bot flag. Its edits will be visible in the recent changes and it may get blocked.' % self) + if sysop and 'sysop' not in self._rights[index]: + output(u'WARNING: Your sysop account on %s does not seem to have sysop rights. You may not be able to perform any sysop-restricted actions using it.' % self) + else: + # 'groups' is not exists, set default rights + self._rights[index] = [] + if self._isLoggedIn[index]: + # Logged in user + self._rights[index].append('user') + # Assume bot, and thus autoconfirmed + self._rights[index].extend(['bot', 'autoconfirmed']) + if sysop: + # Assume user reported as a sysop indeed has the sysop rights + self._rights[index].append('sysop') + # Assume the user has the default rights if API not query back + self._rights[index].extend(['read', 'createaccount', 'edit', 'upload', 'createpage', 'createtalk', 'move', 'upload']) + #remove Duplicate rights + self._rights[index] = list(set(self._rights[index])) + + # Get token + if 'preferencestoken' in text: + self._token[index] = text['preferencestoken'] + if self._rights[index] is not None: + # Token and rights are loaded - user data is now loaded + self._userData[index] = True + elif self.versionnumber() < 14: + # uiprop 'preferencestoken' is start from 1.14, if 1.8~13, we need to use other way to get token + params = { + 'action': 'query', + 'prop': 'info', + 'titles':'Non-existing page', + 'intoken': 'edit', + } + data = query.GetData(params, self, sysop=sysop)['query']['pages'].values()[0] + if 'edittoken' in data: + self._token[index] = data['edittoken'] + self._userData[index] = True else: - self._messages[index] = False + output(u'WARNING: Token not found on %s. You will not be able to edit any page.' % self) + else: + if not self._isBlocked[index]: + output(u'WARNING: Token not found on %s. You will not be able to edit any page.' % self) + + def _getUserDataOld(self, text, sysop = False, force = True): + """ + Get the user data from a wiki page data.
- # Don't perform other checks if the data was already loaded - if self._userData[index] and not force: - return + Parameters: + * text - the page text + * sysop - is the user a sysop? + """
- # Get username. - # The data in anonymous mode had key 'anon' - # if 'anon' exist, username is IP address, not to collect it right now - if not 'anon' in text: - self._isLoggedIn[index] = True - self._userName[index] = text['name'] - else: - self._isLoggedIn[index] = False - self._userName[index] = None + index = self._userIndex(sysop)
- # Get user groups and rights - if 'groups' in text: - self._rights[index] = text['groups'] - self._rights[index].extend(text['rights']) - # Warnings - # Don't show warnings for not logged in users, they will just fail to - # do any action - if self._isLoggedIn[index]: - if 'bot' not in self._rights[index] and config.notify_unflagged_bot: - # Sysop + bot flag = Sysop flag in MediaWiki < 1.7.1? - if sysop: - output(u'Note: Your sysop account on %s does not have a bot flag. Its edits will be visible in the recent changes.' % self) - else: - output(u'WARNING: Your account on %s does not have a bot flag. Its edits will be visible in the recent changes and it may get blocked.' % self) - if sysop and 'sysop' not in self._rights[index]: - output(u'WARNING: Your sysop account on %s does not seem to have sysop rights. You may not be able to perform any sysop-restricted actions using it.' % self) - else: - # 'groups' is not exists, set default rights - self._rights[index] = [] - if self._isLoggedIn[index]: - # Logged in user - self._rights[index].append('user') - # Assume bot, and thus autoconfirmed - self._rights[index].extend(['bot', 'autoconfirmed']) - if sysop: - # Assume user reported as a sysop indeed has the sysop rights - self._rights[index].append('sysop') - # Assume the user has the default rights if API not query back - self._rights[index].extend(['read', 'createaccount', 'edit', 'upload', 'createpage', 'createtalk', 'move', 'upload']) - #remove Duplicate rights - self._rights[index] = list(set(self._rights[index])) + if '<div id="globalWrapper">' not in text: + # Not a wiki page + return + # Check for blocks - but only if version is 1.11 (userinfo is available) + # and the user data was not yet loaded + if self.versionnumber() >= 11 and (not self._userData[index] or force): + blocked = self._getBlock(sysop = sysop) + if blocked and not self._isBlocked[index]: + # Write a warning if not shown earlier + if sysop: + account = 'Your sysop account' + else: + account = 'Your account' + output(u'WARNING: %s on %s is blocked. Editing using this account will stop the run.' % (account, self)) + self._isBlocked[index] = blocked
- # Get token - if 'preferencestoken' in text: - self._token[index] = text['preferencestoken'] - if self._rights[index] is not None: - # Token and rights are loaded - user data is now loaded - self._userData[index] = True - elif self.versionnumber() < 14: - # uiprop 'preferencestoken' is start from 1.14, if 1.8~13, we need to use other way to get token - params = { - 'action': 'query', - 'prop': 'info', - 'titles':'Non-existing page', - 'intoken': 'edit', - } - data = query.GetData(params, self, sysop=sysop)['query']['pages'].values()[0] - if 'edittoken' in data: - self._token[index] = data['edittoken'] - self._userData[index] = True + # Check for new messages + if '<div class="usermessage">' in text: + if not self._messages[index]: + # User has *new* messages + if sysop: + output(u'NOTE: You have new messages in your sysop account on %s' % self) else: - output(u'WARNING: Token not found on %s. You will not be able to edit any page.' % self) - else: - if not self._isBlocked[index]: - output(u'WARNING: Token not found on %s. You will not be able to edit any page.' % self) + output(u'NOTE: You have new messages on %s' % self) + self._messages[index] = True else: - #ordinary mode to get data from edit page HTMLs and JavaScripts + self._messages[index] = False + # Don't perform other checks if the data was already loaded + if self._userData[index] and not force: + return
- if '<div id="globalWrapper">' not in text: - # Not a wiki page - return - # Check for blocks - but only if version is 1.11 (userinfo is available) - # and the user data was not yet loaded - if self.versionnumber() >= 11 and (not self._userData[index] or force): - blocked = self._getBlock(sysop = sysop) - if blocked and not self._isBlocked[index]: - # Write a warning if not shown earlier - if sysop: - account = 'Your sysop account' - else: - account = 'Your account' - output(u'WARNING: %s on %s is blocked. Editing using this account will stop the run.' % (account, self)) - self._isBlocked[index] = blocked + # Search for the the user page link at the top. + # Note that the link of anonymous users (which doesn't exist at all + # in Wikimedia sites) has the ID pt-anonuserpage, and thus won't be + # found here. + userpageR = re.compile('<li id="pt-userpage"><a href=".+?">(?P<username>.+?)</a></li>') + m = userpageR.search(text) + if m: + self._isLoggedIn[index] = True + self._userName[index] = m.group('username') + else: + self._isLoggedIn[index] = False + # No idea what is the user name, and it isn't important + self._userName[index] = None
- # Check for new messages - if '<div class="usermessage">' in text: - if not self._messages[index]: - # User has *new* messages - if sysop: - output(u'NOTE: You have new messages in your sysop account on %s' % self) - else: - output(u'NOTE: You have new messages on %s' % self) - self._messages[index] = True - else: - self._messages[index] = False + if self.family.name == 'wikitravel': # fix for Wikitravel's user page link. + self = self.family.user_page_link(self,index)
- # Don't perform other checks if the data was already loaded - if self._userData[index] and not force: - return - - # Search for the the user page link at the top. - # Note that the link of anonymous users (which doesn't exist at all - # in Wikimedia sites) has the ID pt-anonuserpage, and thus won't be - # found here. - userpageR = re.compile('<li id="pt-userpage"><a href=".+?">(?P<username>.+?)</a></li>') - m = userpageR.search(text) - if m: - self._isLoggedIn[index] = True - self._userName[index] = m.group('username') - else: - self._isLoggedIn[index] = False - # No idea what is the user name, and it isn't important - self._userName[index] = None - - if self.family.name == 'wikitravel': # fix for Wikitravel's user page link. - self = self.family.user_page_link(self,index) - - # Check user groups, if possible (introduced in 1.10) - groupsR = re.compile(r'var wgUserGroups = ["(.+)"];') - m = groupsR.search(text) - checkLocal = True - if default_code in self.family.cross_allowed: # if current languages in cross allowed list, check global bot flag. - globalgroupsR = re.compile(r'var wgGlobalGroups = ["(.+)"];') - mg = globalgroupsR.search(text) - if mg: # the account had global permission - globalRights = mg.group(1) - globalRights = globalRights.split('","') - self._rights[index] = globalRights - if self._isLoggedIn[index]: - if 'Global_bot' in globalRights: # This account has the global bot flag, no need to check local flags. - checkLocal = False - else: - output(u'Your bot account does not have global the bot flag, checking local flag.') - else: - if verbose: output(u'Note: this language does not allow global bots.') - if m and checkLocal: - rights = m.group(1) - rights = rights.split('", "') - if '*' in rights: - rights.remove('*') - self._rights[index] = rights - # Warnings - # Don't show warnings for not logged in users, they will just fail to - # do any action + # Check user groups, if possible (introduced in 1.10) + groupsR = re.compile(r'var wgUserGroups = ["(.+)"];') + m = groupsR.search(text) + checkLocal = True + if default_code in self.family.cross_allowed: # if current languages in cross allowed list, check global bot flag. + globalgroupsR = re.compile(r'var wgGlobalGroups = ["(.+)"];') + mg = globalgroupsR.search(text) + if mg: # the account had global permission + globalRights = mg.group(1) + globalRights = globalRights.split('","') + self._rights[index] = globalRights if self._isLoggedIn[index]: - if 'bot' not in self._rights[index] and config.notify_unflagged_bot: - # Sysop + bot flag = Sysop flag in MediaWiki < 1.7.1? - if sysop: - output(u'Note: Your sysop account on %s does not have a bot flag. Its edits will be visible in the recent changes.' % self) - else: - output(u'WARNING: Your account on %s does not have a bot flag. Its edits will be visible in the recent changes and it may get blocked.' % self) - if sysop and 'sysop' not in self._rights[index]: - output(u'WARNING: Your sysop account on %s does not seem to have sysop rights. You may not be able to perform any sysop-restricted actions using it.' % self) - else: - # We don't have wgUserGroups, and can't check the rights - self._rights[index] = [] - if self._isLoggedIn[index]: - # Logged in user - self._rights[index].append('user') - # Assume bot, and thus autoconfirmed - self._rights[index].extend(['bot', 'autoconfirmed']) + if 'Global_bot' in globalRights: # This account has the global bot flag, no need to check local flags. + checkLocal = False + else: + output(u'Your bot account does not have global the bot flag, checking local flag.') + else: + if verbose: output(u'Note: this language does not allow global bots.') + if m and checkLocal: + rights = m.group(1) + rights = rights.split('", "') + if '*' in rights: + rights.remove('*') + self._rights[index] = rights + # Warnings + # Don't show warnings for not logged in users, they will just fail to + # do any action + if self._isLoggedIn[index]: + if 'bot' not in self._rights[index] and config.notify_unflagged_bot: + # Sysop + bot flag = Sysop flag in MediaWiki < 1.7.1? if sysop: - # Assume user reported as a sysop indeed has the sysop rights - self._rights[index].append('sysop') - # Assume the user has the default rights - self._rights[index].extend(['read', 'createaccount', 'edit', 'upload', 'createpage', 'createtalk', 'move', 'upload']) - if 'bot' in self._rights[index] or 'sysop' in self._rights[index]: - self._rights[index].append('apihighlimits') - if 'sysop' in self._rights[index]: - self._rights[index].extend(['delete', 'undelete', 'block', 'protect', 'import', 'deletedhistory', 'unwatchedpages']) + output(u'Note: Your sysop account on %s does not have a bot flag. Its edits will be visible in the recent changes.' % self) + else: + output(u'WARNING: Your account on %s does not have a bot flag. Its edits will be visible in the recent changes and it may get blocked.' % self) + if sysop and 'sysop' not in self._rights[index]: + output(u'WARNING: Your sysop account on %s does not seem to have sysop rights. You may not be able to perform any sysop-restricted actions using it.' % self) + else: + # We don't have wgUserGroups, and can't check the rights + self._rights[index] = [] + if self._isLoggedIn[index]: + # Logged in user + self._rights[index].append('user') + # Assume bot, and thus autoconfirmed + self._rights[index].extend(['bot', 'autoconfirmed']) + if sysop: + # Assume user reported as a sysop indeed has the sysop rights + self._rights[index].append('sysop') + # Assume the user has the default rights + self._rights[index].extend(['read', 'createaccount', 'edit', 'upload', 'createpage', 'createtalk', 'move', 'upload']) + if 'bot' in self._rights[index] or 'sysop' in self._rights[index]: + self._rights[index].append('apihighlimits') + if 'sysop' in self._rights[index]: + self._rights[index].extend(['delete', 'undelete', 'block', 'protect', 'import', 'deletedhistory', 'unwatchedpages'])
- # Search for a token - tokenR = re.compile(r"<input type='hidden' value="(.*?)" name="wpEditToken"") - tokenloc = tokenR.search(text) - if tokenloc: - self._token[index] = tokenloc.group(1) - if self._rights[index] is not None: - # In this case, token and rights are loaded - user data is now loaded - self._userData[index] = True - else: + # Search for a token + tokenR = re.compile(r"<input type='hidden' value="(.*?)" name="wpEditToken"") + tokenloc = tokenR.search(text) + if tokenloc: + self._token[index] = tokenloc.group(1) + if self._rights[index] is not None: + # In this case, token and rights are loaded - user data is now loaded + self._userData[index] = True + else: + # Token not found + # Possible reason for this is the user is blocked, don't show a + # warning in this case, otherwise do show a warning + # Another possible reason is that the page cannot be edited - ensure + # there is a textarea and the tab "view source" is not shown + if u'<textarea' in text and u'<li id="ca-viewsource"' not in text and not self._isBlocked[index]: # Token not found - # Possible reason for this is the user is blocked, don't show a - # warning in this case, otherwise do show a warning - # Another possible reason is that the page cannot be edited - ensure - # there is a textarea and the tab "view source" is not shown - if u'<textarea' in text and u'<li id="ca-viewsource"' not in text and not self._isBlocked[index]: - # Token not found - output(u'WARNING: Token not found on %s. You will not be able to edit any page.' % self) + output(u'WARNING: Token not found on %s. You will not be able to edit any page.' % self)
def mediawiki_message(self, key): """Return the MediaWiki message text for key "key" """ @@ -5871,14 +5877,13 @@ params['uiprop'] += '|preferencestoken'
text = query.GetData(params, self, sysop=sysop)['query']['userinfo'] - ##output('%s' % text) # for debug use only + self._getUserData(text, sysop = sysop, force = force) else: url = self.edit_address('Non-existing_page') text = self.getUrl(url, sysop = sysop) + self._getUserDataOld(text, sysop = sysop, force = force) +
- # Parse data - self._getUserData(text, sysop = sysop, force = force) - def search(self, query, number = 10, namespaces = None): """Yield search results (using Special:Search page) for query.""" throttle = True