jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/346700 )

Change subject: Add support for geo-shape Wikibase data type
......................................................................


Add support for geo-shape Wikibase data type

Introduces the WbGeoShape class to provide handling of geo-shape
data and do some basic validation on indata.

Also add a comment to commonsMedia to the task explaining how
come site is hard-coded to Wikimedia Commons for all Wikibase
installations (which is not the case for geo-shapes).

Bug:T161726
Change-Id: Ia96d35519163307227159ccece5981783ce8b558
---
M pywikibot/__init__.py
M pywikibot/families/wikidata_family.py
M pywikibot/page.py
M pywikibot/site.py
M tests/wikibase_edit_tests.py
M tests/wikibase_tests.py
6 files changed, 171 insertions(+), 3 deletions(-)

Approvals:
  jenkins-bot: Verified
  Xqt: Looks good to me, approved



diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index eff852a..1b6ce51 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -812,6 +812,73 @@
         return cls(wb['text'], wb['language'])
 
 
+class WbGeoShape(_WbRepresentation):
+    """
+    A Wikibase geo-shape representation.
+
+    A temporary implementation until T162336 has been resolved.
+    """
+
+    _items = ('page', )
+
+    def __init__(self, page, site=None):
+        """
+        Create a new WbGeoShape object.
+
+        @param page: page containing the map data
+        @type text: pywikibot.Page
+        @param site: The Wikibase site
+        @type site: pywikibot.site.DataSite
+        """
+        site = site or Site().data_repository()
+        if not isinstance(page, Page):
+            raise ValueError('page must be a pywikibot.Page object.')
+
+        # validate page exists
+        if not page.exists():
+            raise ValueError('page must exist.')
+
+        # validate page is on the right site, and that site supports geo-shapes
+        geo_shape_site = site.geo_shape_repository()
+        if not geo_shape_site:
+            raise ValueError('the provided site does not support geo-shapes.')
+        if page.site != geo_shape_site:
+            raise ValueError('page must be on the image repository site.')
+
+        # validate page title fulfills hard-coded Wikibase requirement
+        # pcre regexp: '/^Data:[^\\[\\]#\\\:{|}]+\.map$/u'
+        # As we have already checked for existence the following simplified
+        # check should be enough.
+        if not page.title().startswith('Data:') or \
+                not page.title().endswith('.map'):
+            raise ValueError(
+                "page must be a '.map' page in the 'Data:' namespace.")
+
+        self.page = page
+
+    def toWikibase(self):
+        """
+        Convert the data to the value required by the Wikibase API.
+
+        @return: title of the geo-shape page incl. namespace
+        @rtype: str
+        """
+        return self.page.title()
+
+    @classmethod
+    def fromWikibase(cls, page_name, site):
+        """
+        Create a WbGeoShape from the JSON data given by the Wikibase API.
+
+        @param page_name: page name from Wikibase value
+        @type page_name: str
+        @rtype: pywikibot.WbGeoShape
+        """
+        geo_shape_site = site.geo_shape_repository()
+        page = Page(geo_shape_site, page_name)
+        return cls(page, site)
+
+
 _sites = {}
 _url_cache = {}  # The code/fam pair for each URL
 
diff --git a/pywikibot/families/wikidata_family.py 
b/pywikibot/families/wikidata_family.py
index f695a20..4b30106 100644
--- a/pywikibot/families/wikidata_family.py
+++ b/pywikibot/families/wikidata_family.py
@@ -50,6 +50,11 @@
         """Default calendar model for WbTime datatype."""
         return 'http://www.wikidata.org/entity/Q1985727'
 
+    def shared_geo_shape_repository(self, code):
+        """Return Wikimedia Commons as the repository for geo-shapes."""
+        # Per geoShapeStorageFrontendUrl settings in Wikibase
+        return ('commons', 'commons')
+
     def globes(self, code):
         """Supported globes for Coordinate datatype."""
         return {
diff --git a/pywikibot/page.py b/pywikibot/page.py
index 1885aef..e95bab3 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -4318,6 +4318,7 @@
              'monolingualtext': pywikibot.WbMonolingualText,
              'math': basestring,
              'external-id': basestring,
+             'geo-shape': pywikibot.WbGeoShape,
              }
 
     value_types = {'wikibase-item': 'wikibase-entityid',
@@ -4327,6 +4328,7 @@
                    'globe-coordinate': 'globecoordinate',
                    'math': 'string',
                    'external-id': 'string',
+                   'geo-shape': 'string',
                    }
 
     def __init__(self, site, id, datatype=None):
@@ -4457,8 +4459,9 @@
         'wikibase-property': lambda value, site:
             PropertyPage(site, 'P' + str(value['numeric-id'])),
         'commonsMedia': lambda value, site:
-            FilePage(pywikibot.Site('commons', 'commons'), value),
+            FilePage(pywikibot.Site('commons', 'commons'), value),  # T90492
         'globe-coordinate': pywikibot.Coordinate.fromWikibase,
+        'geo-shape': pywikibot.WbGeoShape.fromWikibase,
         'time': lambda value, site: pywikibot.WbTime.fromWikibase(value),
         'quantity': pywikibot.WbQuantity.fromWikibase,
         'monolingualtext': lambda value, site:
@@ -4884,7 +4887,8 @@
         elif self.type == 'commonsMedia':
             value = self.getTarget().title(withNamespace=False)
         elif self.type in ('globe-coordinate', 'time',
-                           'quantity', 'monolingualtext'):
+                           'quantity', 'monolingualtext',
+                           'geo-shape'):
             value = self.getTarget().toWikibase()
         else:
             raise NotImplementedError('%s datatype is not supported yet.'
diff --git a/pywikibot/site.py b/pywikibot/site.py
index c715902..7c04551 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -7231,6 +7231,13 @@
         """
         return self
 
+    def geo_shape_repository(self):
+        """Return Site object for the geo-shapes repository e.g. commons."""
+        # Do this via API instead if T162561 is implemented.
+        code, fam = self.shared_geo_shape_repository()
+        if bool(code or fam):
+            return pywikibot.Site(code, fam, self.username())
+
     def loadcontent(self, identification, *props):
         """
         Fetch the current content of a Wikibase item.
diff --git a/tests/wikibase_edit_tests.py b/tests/wikibase_edit_tests.py
index 670eab9..1361c98 100644
--- a/tests/wikibase_edit_tests.py
+++ b/tests/wikibase_edit_tests.py
@@ -300,6 +300,25 @@
         claim = item.claims['P718'][0]
         self.assertEqual(claim.getTarget(), target)
 
+    def test_WbGeoShape_edit(self):
+        """Attempt adding a geo-shape with valid input."""
+        # Clean the slate in preparation for test.
+        testsite = self.get_repo()
+        item = self._clean_item(testsite, 'P27199')
+
+        # set new claim
+        claim = pywikibot.page.Claim(testsite, 'P27199', datatype='geo-shape')
+        commons_site = pywikibot.Site('commons', 'commons')
+        page = pywikibot.Page(commons_site, 'Data:Lyngby Hovedgade.map')
+        target = pywikibot.WbGeoShape(page)
+        claim.setTarget(target)
+        item.addClaim(claim)
+
+        # confirm new claim
+        item.get(force=True)
+        claim = item.claims['P27199'][0]
+        self.assertEqual(claim.getTarget(), target)
+
 
 class TestWikibaseRemoveQualifier(WikibaseTestCase):
 
diff --git a/tests/wikibase_tests.py b/tests/wikibase_tests.py
index 0006172..98c542d 100644
--- a/tests/wikibase_tests.py
+++ b/tests/wikibase_tests.py
@@ -18,7 +18,7 @@
 import pywikibot
 
 from pywikibot import pagegenerators
-from pywikibot.page import WikibasePage, ItemPage, PropertyPage
+from pywikibot.page import WikibasePage, ItemPage, PropertyPage, Page
 from pywikibot.site import Namespace, NamespacesDict
 from pywikibot.tools import MediaWikiVersion
 
@@ -490,6 +490,72 @@
                           text=None, language='sv')
 
 
+class TestWbGeoShapeNonDry(WikidataTestCase):
+
+    """
+    Test Wikibase WbGeoShape data type (non-dry).
+
+    These require non dry tests due to the page.exists() call.
+    """
+
+    def setUp(self):
+        """Setup tests."""
+        self.commons = pywikibot.Site('commons', 'commons')
+        self.page = Page(self.commons, 'Data:Lyngby Hovedgade.map')
+        super(TestWbGeoShapeNonDry, self).setUp()
+
+    def test_WbGeoShape_page(self):
+        """Test WbGeoShape page."""
+        q = pywikibot.WbGeoShape(self.page)
+        q_val = u'Data:Lyngby Hovedgade.map'
+        self.assertEqual(q.toWikibase(), q_val)
+
+    def test_WbGeoShape_page_and_site(self):
+        """Test WbGeoShape from page and site."""
+        q = pywikibot.WbGeoShape(self.page, self.get_repo())
+        q_val = u'Data:Lyngby Hovedgade.map'
+        self.assertEqual(q.toWikibase(), q_val)
+
+    def test_WbGeoShape_equality(self):
+        """Test WbGeoShape equality."""
+        q = pywikibot.WbGeoShape(self.page, self.get_repo())
+        self.assertEqual(q, q)
+
+    def test_WbGeoShape_fromWikibase(self):
+        """Test WbGeoShape.fromWikibase() instantiating."""
+        repo = self.get_repo()
+        q = pywikibot.WbGeoShape.fromWikibase(
+            'Data:Lyngby Hovedgade.map', repo)
+        self.assertEqual(q.toWikibase(), 'Data:Lyngby Hovedgade.map')
+
+    def test_WbGeoShape_error_on_non_page(self):
+        """Test WbGeoShape error handling when given a non-page."""
+        self.assertRaises(ValueError, pywikibot.WbGeoShape,
+                          'A string', self.get_repo())
+
+    def test_WbGeoShape_error_on_non_exitant_page(self):
+        """Test WbGeoShape error handling of a non-existant page."""
+        page = Page(self.commons, 'Non-existant page... really')
+        self.assertRaises(ValueError, pywikibot.WbGeoShape,
+                          page, self.get_repo())
+
+    def test_WbGeoShape_error_on_wrong_site(self):
+        """Test WbGeoShape error handling of a page on non-filerepo site."""
+        repo = self.get_repo()
+        page = Page(repo, 'Q123')
+        self.assertRaises(ValueError, pywikibot.WbGeoShape,
+                          page, self.get_repo())
+
+    def test_WbGeoShape_error_on_wrong_page_type(self):
+        """Test WbGeoShape error handling of a non-map page."""
+        non_data_page = Page(self.commons, 'File:Foo.jpg')
+        non_map_page = Page(self.commons, 'Data:Templatedata/Graph:Lines.tab')
+        self.assertRaises(ValueError, pywikibot.WbGeoShape,
+                          non_data_page, self.get_repo())
+        self.assertRaises(ValueError, pywikibot.WbGeoShape,
+                          non_map_page, self.get_repo())
+
+
 class TestItemPageExtensibility(TestCase):
 
     """Test ItemPage extensibility."""

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia96d35519163307227159ccece5981783ce8b558
Gerrit-PatchSet: 6
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Lokal Profil <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Lokal Profil <[email protected]>
Gerrit-Reviewer: Magul <[email protected]>
Gerrit-Reviewer: Matěj Suchánek <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to