John Vandenberg has submitted this change and it was merged.
Change subject: Add Page.contributors() and .revision_count()
......................................................................
Add Page.contributors() and .revision_count()
deprecates:
- Page
- contributingUsers
- checkImagesBot
- countEdits
- botolist
- project
- botnick
Change-Id: Iee0fbd7337b70a4091292938e6d81764a5b4ff43
---
M pywikibot/page.py
M scripts/checkimages.py
M tests/page_tests.py
3 files changed, 118 insertions(+), 33 deletions(-)
Approvals:
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py
index f38dc5c..6b89b8a 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -1425,6 +1425,20 @@
step=step, total=total)
]
+ def contributors(self, step=None, total=None):
+ """
+ Compile contributors of this page with edit counts.
+
+ @param step: limit each API call to this number of revisions
+ @param total: iterate no more than this number of revisions in total
+
+ @return: number of edits for each username
+ @rtype: L{collections.Counter}
+ """
+ return Counter(rev.user for rev in
+ self.revisions(step=step, total=total))
+
+ @deprecated('contributors()')
def contributingUsers(self, step=None, total=None):
"""Return a set of usernames (or IPs) of users who edited this
page.
@@ -1432,8 +1446,23 @@
@param total: iterate no more than this number of revisions in total
"""
- return set(entry.user for entry in self.revisions(step=step,
- total=total))
+ return self.contributors(step=step, total=total).keys()
+
+ def revision_count(self, contributors=None):
+ """
+ Determine number of edits from a set of contributors.
+
+ @param contributors: contributor usernames
+ @type contributors: iterable of str
+
+ @return: number of edits for all provided usernames
+ @rtype: int
+ """
+ if not contributors:
+ return len(list(self.revisions()))
+
+ cnt = self.contributors()
+ return sum(cnt[username] for username in contributors)
@deprecated('oldest_revision')
def getCreator(self):
@@ -1446,7 +1475,7 @@
result = self.oldest_revision
return result.user, result.timestamp
- @deprecated('revisions')
+ @deprecated('contributors() or revisions()')
@deprecated_args(limit="total")
def getLatestEditors(self, total=1):
"""Get a list of revision informations of the last total edits.
diff --git a/scripts/checkimages.py b/scripts/checkimages.py
index 41b0aac..9e3377d 100644
--- a/scripts/checkimages.py
+++ b/scripts/checkimages.py
@@ -93,9 +93,11 @@
import sys
import pywikibot
+
from pywikibot import pagegenerators as pg
-from pywikibot import config, i18n
+from pywikibot import i18n
from pywikibot.family import Family
+from pywikibot.tools import deprecated
if sys.version_info[0] > 2:
basestring = (str, )
@@ -312,7 +314,7 @@
}
# This is a list of what bots used this script in your project.
-# NOTE: YOUR Botnick is automatically added. It's not required to add it twice.
+# NOTE: YOUR Bot username will be automatically added.
bot_list = {
'commons': [u'Siebot', u'CommonsDelinker', u'Filbot',
u'John Bot',
u'Sz-iwbot', u'ABFbot'],
@@ -611,20 +613,11 @@
PageWithAllowedTemplates)
self.comment = i18n.translate(self.site, msg_comm, fallback=True)
# Adding the bot's nickname at the notification text if needed.
- botolist = i18n.translate(self.site, bot_list)
- project = site.family.name
- self.project = project
- bot = config.usernames[project]
- try:
- botnick = bot[self.site.code]
- except KeyError:
- raise pywikibot.NoUsername(
- u"You have to specify an username for your bot in this project
"
- u"in the user-config.py file.")
-
- self.botnick = botnick
- botolist.append(botnick)
- self.botolist = botolist
+ self.bots = i18n.translate(self.site, bot_list)
+ if self.bots:
+ self.bots.append(site.username())
+ else:
+ self.bots = [site.username()]
self.sendemailActive = sendemailActive
self.skip_list = []
@@ -633,6 +626,26 @@
self.image_namespace = u"File:"
# Load the licenses only once, so do it once
self.list_licenses = self.load_licenses()
+
+ @property
+ @deprecated
+ def project(self):
+ return self.site.family.name
+
+ @property
+ @deprecated
+ def botolist(self):
+ return self.bots
+
+ @botolist.setter
+ @deprecated
+ def botolist(self, value):
+ self.bots = value
+
+ @property
+ @deprecated
+ def botnick(self):
+ return self.site.username()
def setParameters(self, imageName):
"""
@@ -655,10 +668,10 @@
self.notification2 = notification2
if self.notification:
- self.notification = re.sub(r'__botnick__', self.botnick,
+ self.notification = re.sub(r'__botnick__', self.site.username(),
notification)
if self.notification2:
- self.notification2 = re.sub(r'__botnick__', self.botnick,
+ self.notification2 = re.sub(r'__botnick__', self.site.username(),
notification2)
self.commTalk = commTalk
self.commImage = commImage or self.comment
@@ -771,13 +784,12 @@
pywikibot.output(
u'The latest user that has written something is: %s'
% latest_user)
- for i in self.botolist:
- if latest_user == i:
- second_text = True
- # A block to prevent the second message if the bot also
- # welcomed users...
- if history[0]['timestamp'] ==
history[-1]['timestamp']:
- second_text = False
+ if latest_user in self.bots:
+ second_text = True
+ # A block to prevent the second message if the bot also
+ # welcomed users...
+ if history[0]['timestamp'] == history[-1]['timestamp']:
+ second_text = False
except pywikibot.IsRedirectPage:
pywikibot.output(
u'The user talk is a redirect, trying to get the right talk...')
@@ -878,12 +890,13 @@
if not not_the_oldest:
return imageName
+ @deprecated('Page.revision_count()')
def countEdits(self, pagename, userlist):
"""Function to count the edit of a user or a list of users in a
page."""
if isinstance(userlist, basestring):
userlist = [userlist]
page = pywikibot.Page(self.site, pagename)
- return sum(1 for rev in page.revisions() if rev.user in userlist)
+ return page.revision_count(userlist)
def checkImageOnCommons(self):
"""Checking if the file is on commons."""
@@ -1040,8 +1053,8 @@
# (the last)
if len(images_to_tag_list) > 1:
for image_to_tag in images_to_tag_list[:-1]:
- already_reported_in_past = self.countEdits(
- u'File:%s' % image_to_tag, self.botolist)
+ fp = pywikibot.FilePage(self.site, image_to_tag)
+ already_reported_in_past = fp.revision_count(self.bots)
# if you want only one edit, the edit found should be
# more than 0 -> num - 1
if already_reported_in_past > duplicates_rollback - 1:
@@ -1056,8 +1069,8 @@
commImage=dupComment_image, unver=True)
if len(images_to_tag_list) != 0 and not only_report:
- already_reported_in_past = self.countEdits(
- u'File:%s' % images_to_tag_list[-1], self.botolist)
+ fp = pywikibot.FilePage(self.site, images_to_tag_list[-1])
+ already_reported_in_past = fp.revision_count(self.bots)
from_regex = (r'\n\*\[\[:File:%s\]\]'
% re.escape(self.image.title(asUrl=True)))
# Delete the image in the list where we're write on
diff --git a/tests/page_tests.py b/tests/page_tests.py
index bc77765..4a2facf 100644
--- a/tests/page_tests.py
+++ b/tests/page_tests.py
@@ -620,6 +620,49 @@
% (page.text, page.botMayEdit(), user))
+class TestPageHistory(DefaultSiteTestCase):
+
+ """Test history related functionality."""
+
+ cached = True
+
+ def test_revisions(self):
+ """Test Page.revisions()."""
+ mp = self.get_mainpage()
+ revs = mp.revisions()
+ revs = iter(revs) # implicit assertion
+ revs = list(revs)
+ self.assertGreater(len(revs), 1)
+
+ def test_contributors(self):
+ """Test Page.contributors()."""
+ mp = self.get_mainpage()
+ cnt = mp.contributors()
+ self.assertIsInstance(cnt, dict)
+ self.assertGreater(len(cnt), 1)
+
+ def test_revision_count(self):
+ """Test Page.edit_count()."""
+ mp = self.get_mainpage()
+ rev_count = len(list(mp.revisions()))
+ self.assertEqual(rev_count, mp.revision_count())
+ cnt = mp.contributors()
+ self.assertEqual(rev_count, sum(cnt.values()))
+
+ top_two = cnt.most_common(2)
+ self.assertIsInstance(top_two, list)
+ self.assertEqual(len(top_two), 2)
+ self.assertIsInstance(top_two[0], tuple)
+ self.assertIsInstance(top_two[0][0], basestring)
+ self.assertIsInstance(top_two[0][1], int)
+ top_two_usernames = set([top_two[0][0], top_two[1][0]])
+ self.assertEqual(len(top_two_usernames), 2)
+ top_two_counts = ([top_two[0][1], top_two[1][1]])
+ top_two_edit_count = mp.revision_count(top_two_usernames)
+ self.assertIsInstance(top_two_edit_count, int)
+ self.assertEqual(top_two_edit_count, sum(top_two_counts))
+
+
class TestPageRedirects(TestCase):
"""Test redirects."""
--
To view, visit
https://gerrit.wikimedia.org/r/189110
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Iee0fbd7337b70a4091292938e6d81764a5b4ff43
Gerrit-PatchSet: 8
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>