jenkins-bot has submitted this change and it was merged.

Change subject: Add "page" external data support
......................................................................


Add "page" external data support

Bug: T137930
Change-Id: I933fdb5de26e905e6e7fa6e3dbfd0293c9267b53
---
M i18n/en.json
M i18n/qqq.json
M includes/SimpleStyleParser.php
M lib/wikimedia-mapdata.js
M schemas/geojson.json
M tests/parserTests.txt
M tests/phpunit/ValidationTest.php
A tests/phpunit/data/bad-schemas/58-externaldata.json
D tests/phpunit/data/bad-schemas/58-featurecollection-non-nestable.json
A tests/phpunit/data/bad-schemas/59-externaldata.json
D tests/phpunit/data/bad-schemas/59-featurecollection-non-nestable.json
M tests/phpunit/data/bad-schemas/60-featurecollection-non-nestable.json
M tests/phpunit/data/bad-schemas/61-featurecollection-non-nestable.json
A tests/phpunit/data/bad-schemas/62-featurecollection-non-nestable.json
A tests/phpunit/data/bad-schemas/63-featurecollection-non-nestable.json
M tests/phpunit/data/good-schemas/08-externaldata.json
16 files changed, 168 insertions(+), 88 deletions(-)

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



diff --git a/i18n/en.json b/i18n/en.json
index 04d61d9..193add7 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -27,7 +27,7 @@
        "kartographer-error-bad_attr": "Attribute \"$1\" has an invalid value",
        "kartographer-error-bad_data": "The JSON content is not valid 
GeoJSON+simplestyle",
        "kartographer-error-latlon": "Either both \"latitude\" and 
\"longitude\" parameters should be supplied or neither of them",
-       "kartographer-error-service-name": "Invalid cartographic service 
\"$1\"",
+       "kartographer-error-title": "Title \"$1\" is not a valid map data page",
        "kartographer-tracking-category": 
"{{#switch:{{NAMESPACE}}|{{ns:File}}=Files|#default=Pages}} with maps",
        "kartographer-tracking-category-desc": "The page includes a map",
        "kartographer-coord-combined": "$1 $2",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index eb386fd..06a721f 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -31,7 +31,7 @@
        "kartographer-error-bad_attr": "Error shown instead of a map in case of 
a problem with parameters.\n\nParameters:\n* $1 - non-localized attribute name, 
such as 'height', 'latitude', etc",
        "kartographer-error-bad_data": "This error is shown if the content of 
the tag is syntactically valid JSON however it does not adhere to GeoJSON and 
simplestyle specifications",
        "kartographer-error-latlon": "Error shown by <maplink> or 
<mapframe> when certain parameters are incorrect",
-       "kartographer-error-service-name": "Error shown by <maplink> or 
<mapframe>. Parameters:\n* $1 - service name.",
+       "kartographer-error-title": "Error shown by <maplink> or 
<mapframe>. Parameters:\n* $1 - page title.",
        "kartographer-tracking-category": "Name of the tracking category",
        "kartographer-tracking-category-desc": "Description on 
[[Special:TrackingCategories]] for the 
{{msg-mw|kartographer-tracking-category}} tracking category.",
        "kartographer-coord-combined": "{{optional}}\nJoins two parts of 
geogrpahical coordinates. $1 and $2 are latitude and longitude, respectively.",
diff --git a/includes/SimpleStyleParser.php b/includes/SimpleStyleParser.php
index d773ef2..a688501 100644
--- a/includes/SimpleStyleParser.php
+++ b/includes/SimpleStyleParser.php
@@ -3,7 +3,10 @@
 namespace Kartographer;
 
 use FormatJson;
+use JsonConfig\JCMapDataContent;
+use JsonConfig\JCSingleton;
 use JsonSchema\Validator;
+use LogicException;
 use MediaWiki\MediaWikiServices;
 use Parser;
 use PPFrame;
@@ -15,8 +18,6 @@
  */
 class SimpleStyleParser {
        private static $parsedProps = [ 'title', 'description' ];
-
-       private static $services = [ 'geoshape', 'geoline', 'geomask' ];
 
        /** @var Parser */
        private $parser;
@@ -139,7 +140,7 @@
         * @param mixed $json
         * @return Status
         */
-       private function validateContent( $json ) {
+       protected function validateContent( $json ) {
                $schema = self::loadSchema();
                $validator = new Validator();
                $validator->check( $json, $schema );
@@ -158,7 +159,7 @@
         *
         * @param object|array $json
         */
-       private function sanitize( &$json ) {
+       protected function sanitize( &$json ) {
                if ( is_array( $json ) ) {
                        foreach ( $json as &$element ) {
                                $this->sanitize( $element );
@@ -185,7 +186,7 @@
         * @param array $json
         * @return Status
         */
-       private function normalize( array &$json ) {
+       protected function normalize( array &$json ) {
                $status = Status::newGood();
                foreach ( $json as &$object ) {
                        if ( $object->type === 'ExternalData' ) {
@@ -204,38 +205,59 @@
         * @return Status
         */
        private function normalizeExternalData( &$object ) {
-               if ( !in_array( $object->service, self::$services ) ) {
-                       return Status::newFatal( 
'kartographer-error-service-name', $object->service );
-               }
 
                $ret = (object)[
                        'type' => 'ExternalData',
                        'service' => $object->service,
                ];
 
-               $query = [
-                       'getgeojson' => 1
-               ];
+               switch ( $object->service ) {
+                       case 'geoshape':
+                       case 'geoline':
+                       case 'geomask':
+                               $query = [ 'getgeojson' => 1 ];
+                               if ( property_exists( $object, 'ids' ) ) {
+                                       $query['ids'] =
+                                               is_array( $object->ids ) ? 
join( ',', $object->ids )
+                                                       : preg_replace( 
'/\s*,\s*/', ',', $object->ids );
+                               }
+                               if ( property_exists( $object, 'query' ) ) {
+                                       $query['query'] = $object->query;
+                               }
+                               // 'geomask' service is the same as inverted 
geoshape service
+                               // Kartotherian does not support it, request it 
as geoshape
+                               $service = $object->service === 'geomask' ? 
'geoshape' : $object->service;
 
-               if ( property_exists( $object, 'ids' ) ) {
-                       $query['ids'] = is_array( $object->ids )
-                               ? join( ',', $object->ids )
-                               : preg_replace( '/\s*,\s*/', ',', $object->ids 
);
-               }
-               if ( property_exists( $object, 'query' ) ) {
-                       $query['query'] = $object->query;
-               }
+                               $ret->url = "{$this->mapService}/{$service}?" . 
wfArrayToCgi( $query );
+                               if ( property_exists( $object, 'properties' ) ) 
{
+                                       $ret->properties = $object->properties;
+                               }
+                               break;
 
-               // 'geomask' service is the same as inverted geoshape service
-               // Kartotherian does not support it, request it as geoshape
-               $service = $object->service === 'geomask' ? 'geoshape' : 
$object->service;
-               $ret->url = "{$this->mapService}/{$service}?" . wfArrayToCgi( 
$query );
-               if ( property_exists( $object, 'properties' ) ) {
-                       $ret->properties = $object->properties;
+                       case 'page':
+                               if ( !class_exists( 'JsonConfig\\JCSingleton' ) 
) {
+                                       return Status::newFatal( 
'kartographer-error-service-name', $object->service );
+                               }
+                               $jct = JCSingleton::parseTitle( $object->title, 
NS_DATA );
+                               if ( !$jct || JCSingleton::getContentClass( 
$jct->getConfig()->model ) !==
+                                                         
JCMapDataContent::class
+                               ) {
+                                       return Status::newFatal( 
'kartographer-error-title', $object->title );
+                               }
+                               $query = [
+                                       'format' => 'json',
+                                       'formatversion' => '2',
+                                       'action' => 'jsondata',
+                                       'title' => $jct->getText(),
+                               ];
+                               $ret->url = wfScript( 'api' ) . '?' . 
wfArrayToCgi( $query );
+                               break;
+
+                       default:
+                               throw new LogicException( "Unexpected service 
name '{$object->service}'" );
                }
 
                $object = $ret;
-
                return Status::newGood();
        }
 
diff --git a/lib/wikimedia-mapdata.js b/lib/wikimedia-mapdata.js
index d1652f9..add9dfa 100644
--- a/lib/wikimedia-mapdata.js
+++ b/lib/wikimedia-mapdata.js
@@ -195,6 +195,13 @@
 
       switch ( data.service ) {
 
+        case 'page':
+          if ( geodata.jsondata && geodata.jsondata.data ) {
+            extend( data, geodata.jsondata.data );
+          }
+          // FIXME: error reporting, at least to console.log
+          break;
+
         case 'geomask':
           // Mask-out the entire world 10 times east and west,
           // and add each result geometry as a hole
@@ -255,6 +262,8 @@
       if ( mwMsg ) {
         group.parseAttribution();
       }
+    }, function () {
+      group.failed = true;
     } );
 
     return group.promise;
@@ -268,6 +277,10 @@
         uri = mwUri( group.geoJSON.url );
 
     switch ( group.geoJSON.service ) {
+      case 'page':
+        // FIXME: add link to commons page
+        break;
+
       case 'geoshape':
       case 'geoline':
         if ( uri.query.query ) {
@@ -471,6 +484,8 @@
       return group.parse( apiGeoJSON ).then( function ( group ) {
         return group.fetchExternalGroups();
       } );
+    }, function () {
+      group.failed = true;
     } );
     return group.promise;
   };
@@ -551,7 +566,11 @@
     }
     for ( i = 0; i < groupIds.length; i++ ) {
       group = DataStore$$1.get( groupIds[ i ] ) || DataStore$$1.add( new 
InternalGroup( groupIds[ i ] ) );
-      promises.push( group.fetch() );
+      /* jshint loopfunc:true */
+      promises.push( wrappers.createPromise( function ( resolve ) {
+        group.fetch().then( resolve, resolve );
+      } ) );
+      /* jshint loopfunc:false */
     }
 
     DataLoader$$1.fetch();
@@ -564,7 +583,7 @@
       for ( i = 0; i < groupIds.length; i++ ) {
 
         group = DataStore$$1.get( groupIds[ i ] );
-        if ( !wrappers.isEmptyObject( group.getGeoJSON() ) ) {
+        if ( group.failed || !wrappers.isEmptyObject( group.getGeoJSON() ) ) {
           groupList = groupList.concat( group );
         }
         groupList = groupList.concat( group.externals );
diff --git a/schemas/geojson.json b/schemas/geojson.json
index e750152..a6092a6 100644
--- a/schemas/geojson.json
+++ b/schemas/geojson.json
@@ -157,30 +157,44 @@
                        "description": "WMF extension - reference to external 
geometries",
                        "required": [ "type", "service" ],
 
-                       "anyOf": [
-                               { "required": [ "query" ] },
-                               { "required": [ "ids" ] }
+                       "oneOf": [
+                               {
+                                       "required": [ "title" ],
+                                       "properties": {
+                                               "service": { "enum": [ "page" ] 
},
+                                               "title": { "type": "string" }
+                                       }
+                               },
+                               {
+                                       "anyOf": [
+                                               { "required": [ "query" ] },
+                                               { "required": [ "ids" ] }
+                                       ],
+                                       "properties": {
+                                               "service": { "enum": [ 
"geoshape", "geoline", "geomask" ] },
+                                               "query": { "type": "string" },
+                                               "ids": {
+                                                       "oneOf": [
+                                                               {
+                                                                       "type": 
"array",
+                                                                       
"items": {
+                                                                               
"type": "string",
+                                                                               
"pattern": "^Q[1-9]\\d{0,19}$"
+                                                                       }
+                                                               },
+                                                               {
+                                                                       "type": 
"string",
+                                                                       
"pattern": "^Q[1-9]\\d{0,19}(\\s*,\\s*Q[1-9]\\d{0,19})*$"
+                                                               }
+                                                       ]
+                                               }
+                                       }
+                               }
                        ],
 
                        "properties": {
                                "type": { "enum": [ "ExternalData" ] },
                                "service": { "type": "string" },
-                               "query": { "type": "string" },
-                               "ids": {
-                                       "oneOf": [
-                                               {
-                                                       "type": "array",
-                                                       "items": {
-                                                               "type": 
"string",
-                                                               "pattern": 
"^Q[1-9]\\d{0,19}$"
-                                                       }
-                                               },
-                                               {
-                                                       "type": "string",
-                                                       "pattern": 
"^Q[1-9]\\d{0,19}(\\s*,\\s*Q[1-9]\\d{0,19})*$"
-                                               }
-                                       ]
-                               },
                                "properties": { "$ref": 
"#/definitions/simplestyle" }
                        }
                },
diff --git a/tests/parserTests.txt b/tests/parserTests.txt
index ee40be5..49e1ffb 100644
--- a/tests/parserTests.txt
+++ b/tests/parserTests.txt
@@ -392,10 +392,6 @@
 ]
 </maplink>
 !! result
-<div class="mw-kartographer-error"><p>&lt;maplink&gt; problems:
-</p>
-<ul><li> Invalid cartographic service "fail"</li>
-<li> Invalid cartographic service "lulzifier"</li></ul>
-</div>
+<div class="mw-kartographer-error">&lt;maplink&gt;: The JSON content is not 
valid GeoJSON+simplestyle</div>
 
 !! end
diff --git a/tests/phpunit/ValidationTest.php b/tests/phpunit/ValidationTest.php
index ca520df..391fcbc 100644
--- a/tests/phpunit/ValidationTest.php
+++ b/tests/phpunit/ValidationTest.php
@@ -6,6 +6,7 @@
 use MediaWikiTestCase;
 use Parser;
 use ParserOptions;
+use Status;
 use Title;
 
 /**
@@ -27,7 +28,7 @@
                $options = new ParserOptions();
                $title = Title::newMainPage();
                $parser->startExternalParse( $title, $options, Parser::OT_HTML 
);
-               $validator = new SimpleStyleParser( $parser );
+               $validator = new MockSimpleStyleParser( $parser );
 
                $file = $this->basePath . '/' . $fileName;
                $content = file_get_contents( $file );
@@ -59,3 +60,12 @@
                return $result;
        }
 }
+
+class MockSimpleStyleParser extends SimpleStyleParser {
+       protected function sanitize( &$json ) {
+       }
+
+       protected function normalize( array &$json ) {
+               return Status::newGood( $json );
+       }
+}
diff --git a/tests/phpunit/data/bad-schemas/58-externaldata.json 
b/tests/phpunit/data/bad-schemas/58-externaldata.json
new file mode 100644
index 0000000..ca3ba70
--- /dev/null
+++ b/tests/phpunit/data/bad-schemas/58-externaldata.json
@@ -0,0 +1,7 @@
+[
+       {
+               "type": "ExternalData",
+               "service": "geoline",
+               "title": "foo"
+       }
+]
diff --git 
a/tests/phpunit/data/bad-schemas/58-featurecollection-non-nestable.json 
b/tests/phpunit/data/bad-schemas/58-featurecollection-non-nestable.json
deleted file mode 100644
index 9190b11..0000000
--- a/tests/phpunit/data/bad-schemas/58-featurecollection-non-nestable.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-       "type": "FeatureCollection",
-       "features": [
-               {
-                       "type": "FeatureCollection",
-                       "features": []
-               }
-       ]
-}
diff --git a/tests/phpunit/data/bad-schemas/59-externaldata.json 
b/tests/phpunit/data/bad-schemas/59-externaldata.json
new file mode 100644
index 0000000..e07073d
--- /dev/null
+++ b/tests/phpunit/data/bad-schemas/59-externaldata.json
@@ -0,0 +1,7 @@
+[
+       {
+               "type": "ExternalData",
+               "service": "page",
+               "query": "foo"
+       }
+]
diff --git 
a/tests/phpunit/data/bad-schemas/59-featurecollection-non-nestable.json 
b/tests/phpunit/data/bad-schemas/59-featurecollection-non-nestable.json
deleted file mode 100644
index c1fe860..0000000
--- a/tests/phpunit/data/bad-schemas/59-featurecollection-non-nestable.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-       "type": "FeatureCollection",
-       "features": [
-               {
-                       "type": "Feature",
-                       "geometry": {
-                               "type": "FeatureCollection",
-                               "features": []
-                       }
-               }
-       ]
-}
diff --git 
a/tests/phpunit/data/bad-schemas/60-featurecollection-non-nestable.json 
b/tests/phpunit/data/bad-schemas/60-featurecollection-non-nestable.json
index aa17859..9190b11 100644
--- a/tests/phpunit/data/bad-schemas/60-featurecollection-non-nestable.json
+++ b/tests/phpunit/data/bad-schemas/60-featurecollection-non-nestable.json
@@ -2,13 +2,8 @@
        "type": "FeatureCollection",
        "features": [
                {
-                       "type": "GeometryCollection",
-                       "geometries": [
-                               {
-                                       "type": "FeatureCollection",
-                                       "features": []
-                               }
-                       ]
+                       "type": "FeatureCollection",
+                       "features": []
                }
        ]
 }
diff --git 
a/tests/phpunit/data/bad-schemas/61-featurecollection-non-nestable.json 
b/tests/phpunit/data/bad-schemas/61-featurecollection-non-nestable.json
index 9368a9b..c1fe860 100644
--- a/tests/phpunit/data/bad-schemas/61-featurecollection-non-nestable.json
+++ b/tests/phpunit/data/bad-schemas/61-featurecollection-non-nestable.json
@@ -1,7 +1,12 @@
 {
-       "type": "Feature",
-       "geometry": {
-               "type": "FeatureCollection",
-               "features": []
-       }
+       "type": "FeatureCollection",
+       "features": [
+               {
+                       "type": "Feature",
+                       "geometry": {
+                               "type": "FeatureCollection",
+                               "features": []
+                       }
+               }
+       ]
 }
diff --git 
a/tests/phpunit/data/bad-schemas/62-featurecollection-non-nestable.json 
b/tests/phpunit/data/bad-schemas/62-featurecollection-non-nestable.json
new file mode 100644
index 0000000..aa17859
--- /dev/null
+++ b/tests/phpunit/data/bad-schemas/62-featurecollection-non-nestable.json
@@ -0,0 +1,14 @@
+{
+       "type": "FeatureCollection",
+       "features": [
+               {
+                       "type": "GeometryCollection",
+                       "geometries": [
+                               {
+                                       "type": "FeatureCollection",
+                                       "features": []
+                               }
+                       ]
+               }
+       ]
+}
diff --git 
a/tests/phpunit/data/bad-schemas/63-featurecollection-non-nestable.json 
b/tests/phpunit/data/bad-schemas/63-featurecollection-non-nestable.json
new file mode 100644
index 0000000..9368a9b
--- /dev/null
+++ b/tests/phpunit/data/bad-schemas/63-featurecollection-non-nestable.json
@@ -0,0 +1,7 @@
+{
+       "type": "Feature",
+       "geometry": {
+               "type": "FeatureCollection",
+               "features": []
+       }
+}
diff --git a/tests/phpunit/data/good-schemas/08-externaldata.json 
b/tests/phpunit/data/good-schemas/08-externaldata.json
index 945069b..24e1936 100644
--- a/tests/phpunit/data/good-schemas/08-externaldata.json
+++ b/tests/phpunit/data/good-schemas/08-externaldata.json
@@ -74,5 +74,10 @@
                "service": "geomask",
                "query": "lalala",
                "ids": "Q1"
+       },
+       {
+               "type": "ExternalData",
+               "service": "page",
+               "title": "lalala"
        }
 ]

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I933fdb5de26e905e6e7fa6e3dbfd0293c9267b53
Gerrit-PatchSet: 11
Gerrit-Project: mediawiki/extensions/Kartographer
Gerrit-Branch: master
Gerrit-Owner: Yurik <yu...@wikimedia.org>
Gerrit-Reviewer: MaxSem <maxsem.w...@gmail.com>
Gerrit-Reviewer: Siebrand <siebr...@kitano.nl>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to