M4tx has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/182989

Change subject: Add Wikidata support to isbn.py script
......................................................................

Add Wikidata support to isbn.py script

The support is done via a separate Bot class. It can find ISBN-10
and ISBN-13 property IDs or they can be provided manually by the
user.

Bug: T85242
Change-Id: I38cf459d78eb02102da6a169c9c0633ee95b1f3b
---
M scripts/isbn.py
M tests/isbn_tests.py
2 files changed, 152 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core 
refs/changes/89/182989/1

diff --git a/scripts/isbn.py b/scripts/isbn.py
index fa7f472..a59e741 100755
--- a/scripts/isbn.py
+++ b/scripts/isbn.py
@@ -27,6 +27,13 @@
 
 -always           Don't prompt you for each replacement.
 
+-prop-isbn-10     Sets ISBN-10 property ID, so it's not tried to be found
+                  automatically.
+                  The usage is as follows: -prop-isbn-10:propid
+
+-prop-isbn-13     Sets ISBN-13 property ID. The format and purpose is the
+                  same as in -prop-isbn-10.
+
 """
 #
 # (C) Pywikibot team, 2009-2014
@@ -38,7 +45,7 @@
 
 import re
 import pywikibot
-from pywikibot import i18n, pagegenerators, Bot
+from pywikibot import i18n, pagegenerators, Bot, WikidataBot, PropertyPage
 
 docuReplacements = {
     '&params;': pagegenerators.parameterHelp,
@@ -1415,6 +1422,94 @@
             self.treat(page)
 
 
+class IsbnWikibaseBot(WikidataBot):
+
+    """ISBN bot to be run on Wikibase sites."""
+
+    def __init__(self, generator, **kwargs):
+        self.availableOptions.update({
+            'to13': False,
+            'format': False,
+        })
+        self.isbn_10_prop_id = kwargs.pop('prop-isbn-10', None)
+        self.isbn_13_prop_id = kwargs.pop('prop-isbn-13', None)
+
+        super(IsbnWikibaseBot, self).__init__(use_from_page=None, **kwargs)
+
+        self.generator = generator
+        self.comment = i18n.twtranslate(pywikibot.Site(), 'isbn-formatting')
+        if self.isbn_10_prop_id is None:
+            self.isbn_10_prop_id = self._get_isbn_property_id('ISBN-10')
+        if self.isbn_13_prop_id is None:
+            self.isbn_13_prop_id = self._get_isbn_property_id('ISBN-13')
+
+    def _get_isbn_property_id(self, property_name):
+        """
+        Find given property and return its ID.
+
+        Method first uses site.search() and if the property isn't found, then
+        asks user to provide the property ID.
+
+        @param property_name: property to find
+        @type property_name: str
+        """
+        ns = self.site.data_repository().property_namespace
+        for page in self.site.search(property_name, step=1, total=1,
+                                     namespaces=ns):
+            page = PropertyPage(self.site.data_repository(), page.title())
+            pywikibot.output(u"Assuming that %s property is %s (you can "
+                             u"override this with -prop-%s:pid)" %
+                             (property_name, page.id, property_name.lower()))
+            return page.id
+        pywikibot.output(u"Property %s was not found." % property_name)
+        return pywikibot.input(u'Please enter the property ID (e.g. P123) of '
+                               u'it:').upper()
+
+    def treat(self, page, item):
+        if self.isbn_10_prop_id in item.claims:
+            for claim in item.claims[self.isbn_10_prop_id]:
+                try:
+                    isbn = getIsbn(claim.getTarget())
+                except InvalidIsbnException as e:
+                    pywikibot.output(e)
+                    continue
+
+                if self.getOption('format'):
+                    isbn.format()
+
+                if self.getOption('to13'):
+                    isbn = isbn.toISBN13()
+                    pywikibot.output('Removing %s (%s) and adding %s (%s)' %
+                                     (self.isbn_10_prop_id, claim.getTarget(),
+                                      self.isbn_13_prop_id, isbn.code))
+                    new_claim = pywikibot.Claim(self.site.data_repository(),
+                                                self.isbn_13_prop_id)
+                    new_claim.setTarget(isbn.code)
+                    item.removeClaims(claim)
+                    item.addClaim(new_claim)
+                    continue
+
+                pywikibot.output('Changing %s (%s --> %s)'
+                                 % (self.isbn_10_prop_id, claim.getTarget(),
+                                    isbn.code))
+                claim.changeTarget(isbn.code)
+
+        # -format is the only option that has any effect on ISBN13
+        if self.getOption('format') and self.isbn_13_prop_id in item.claims:
+            for claim in item.claims[self.isbn_13_prop_id]:
+                try:
+                    isbn = getIsbn(claim.getTarget())
+                except InvalidIsbnException as e:
+                    pywikibot.output(e)
+                    continue
+
+                isbn.format()
+                pywikibot.output('Changing %s (%s --> %s)'
+                                 % (self.isbn_13_prop_id, claim.getTarget(),
+                                    isbn.code))
+                claim.changeTarget(isbn.code)
+
+
 def main(*args):
     """
     Process command line arguments and invoke bot.
@@ -1430,8 +1525,17 @@
     local_args = pywikibot.handle_args(args)
     genFactory = pagegenerators.GeneratorFactory()
 
+    # Check whether we're running on Wikibase site or not
+    # FIXME: See T85483 and run() in WikidataBot
+    site = pywikibot.Site()
+    data_site = site.data_repository()
+    use_wikibase = (data_site.family == site.family and
+                    data_site.code == site.code)
+
     for arg in local_args:
-        if arg.startswith('-') and arg[1:] in ('always', 'to13', 'format'):
+        if arg.startswith('-prop-') and arg[6:13] in ('isbn-10', 'isbn-13'):
+            options[arg[1:13]] = arg[len('-prop-isbn-1X:'):]
+        elif arg.startswith('-') and arg[1:] in ('always', 'to13', 'format'):
             options[arg[1:]] = True
         else:
             genFactory.handleArg(arg)
@@ -1439,7 +1543,10 @@
     gen = genFactory.getCombinedGenerator()
     if gen:
         preloadingGen = pagegenerators.PreloadingGenerator(gen)
-        bot = IsbnBot(preloadingGen, **options)
+        if use_wikibase:
+            bot = IsbnWikibaseBot(preloadingGen, **options)
+        else:
+            bot = IsbnBot(preloadingGen, **options)
         bot.run()
     else:
         pywikibot.showHelp()
diff --git a/tests/isbn_tests.py b/tests/isbn_tests.py
index cd2c513..86e7643 100644
--- a/tests/isbn_tests.py
+++ b/tests/isbn_tests.py
@@ -12,7 +12,7 @@
 from scripts.isbn import ISBN10, ISBN13, InvalidIsbnException as IsbnExc, \
     getIsbn, hyphenateIsbnNumbers, convertIsbn10toIsbn13, main
 from tests.aspects import TestCase, unittest
-from pywikibot import Bot
+from pywikibot import Bot, Claim, ItemPage, PropertyPage
 
 
 class TestIsbn(TestCase):
@@ -123,5 +123,46 @@
     TestIsbnBot.newtext = newtext
 
 
+class TestIsbnWikibaseBot(TestCase):
+
+    """Test isbnbot on Wikibase site with non-write patching."""
+
+    family = 'wikidata'
+    code = 'test'
+
+    def setUp(self):
+        self._original_changeTarget = Claim.changeTarget
+        Claim.changeTarget = changeTarget_dummy
+        self._original_removeClaims = ItemPage.removeClaims
+        ItemPage.removeClaims = removeClaims_dummy
+        self._original_addClaim = ItemPage.addClaim
+        ItemPage.addClaim = addClaim_dummy
+        super(TestIsbnWikibaseBot, self).setUp()
+
+    def tearDown(self):
+        Claim.changeTarget = self._original_changeTarget
+        ItemPage.removeClaims = self._original_removeClaims
+        ItemPage.addClaim = self._original_addClaim
+        super(TestIsbnWikibaseBot, self).tearDown()
+
+    def test_isbn(self):
+        main('-page:Q943', '-always', '-format')
+        self.assertEqual(self.changeTarget_value, '0-9752298-0-X')
+        main('-page:Q943', '-always', '-to13')
+        self.assertEqual(self.removeClaims_claim.getTarget(), '097522980x')
+        self.assertEqual(self.addClaim_claim.getTarget(), '978-0975229804')
+
+
+def changeTarget_dummy(self, value=None, snaktype='value', **kwargs):
+    TestIsbnWikibaseBot.changeTarget_value = value
+
+
+def removeClaims_dummy(self, claims, **kwargs):
+    TestIsbnWikibaseBot.removeClaims_claim = claims
+
+
+def addClaim_dummy(self, claim, bot=True, **kwargs):
+    TestIsbnWikibaseBot.addClaim_claim = claim
+
 if __name__ == "__main__":
     unittest.main()

-- 
To view, visit https://gerrit.wikimedia.org/r/182989
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I38cf459d78eb02102da6a169c9c0633ee95b1f3b
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: M4tx <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to