Gergő Tisza has uploaded a new change for review.

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

Change subject: Userinfo provider
......................................................................

Userinfo provider

* userinfo api requests are cached now
* we use jsonp only if we have to (makes gender api calls measurable on WMF 
wikis)
* all API calls use providers now, provider.Api constructor can be used to
  wrap mw.Api with metrics

Does not return a proper model, and gender API calls are not preloaded together
with the rest of the calls. Maybe next time.

Change-Id: I9b3ea73c65eef57e160ac8636d9e45d349150884
---
M MultimediaViewer.php
M MultimediaViewerHooks.php
M resources/mmv/mmv.js
A resources/mmv/provider/mmv.provider.UserInfo.js
A tests/qunit/provider/mmv.provider.UserInfo.test.js
5 files changed, 224 insertions(+), 23 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MultimediaViewer 
refs/changes/64/111664/1

diff --git a/MultimediaViewer.php b/MultimediaViewer.php
index 6e07f1b..f92656c 100644
--- a/MultimediaViewer.php
+++ b/MultimediaViewer.php
@@ -152,6 +152,7 @@
                        'mmv.provider.ImageInfo.js',
                        'mmv.provider.FileRepoInfo.js',
                        'mmv.provider.ThumbnailInfo.js',
+                       'mmv.provider.UserInfo.js',
                        'mmv.provider.Image.js',
                ),
 
diff --git a/MultimediaViewerHooks.php b/MultimediaViewerHooks.php
index 9ab089a..b5afc72 100644
--- a/MultimediaViewerHooks.php
+++ b/MultimediaViewerHooks.php
@@ -128,6 +128,7 @@
                                
'tests/qunit/provider/mmv.provider.ImageInfo.test.js',
                                
'tests/qunit/provider/mmv.provider.FileRepoInfo.test.js',
                                
'tests/qunit/provider/mmv.provider.ThumbnailInfo.test.js',
+                               
'tests/qunit/provider/mmv.provider.UserInfo.test.js',
                                
'tests/qunit/provider/mmv.provider.Image.test.js',
                                'tests/qunit/mmv.lightboxinterface.test.js',
                                'tests/qunit/mmv.ui.categories.test.js',
diff --git a/resources/mmv/mmv.js b/resources/mmv/mmv.js
index 9d8f930..aefdce6 100755
--- a/resources/mmv/mmv.js
+++ b/resources/mmv/mmv.js
@@ -122,6 +122,12 @@
                this.thumbnailInfoProvider = new mw.mmv.provider.ThumbnailInfo( 
this.api );
 
                /**
+                * @property {mw.mmv.provider.UserInfo}
+                * @private
+                */
+               this.userInfoProvider = new mw.mmv.provider.UserInfo( this.api 
);
+
+               /**
                 * @property {mw.mmv.provider.ImageUsage}
                 * @private
                 */
@@ -438,32 +444,11 @@
                if ( imageData.lastUploader ) {
                        gfpid = this.profileStart( 'gender-fetch' );
 
-                       // TODO: Reuse the api member, fix everywhere.
-                       // Fetch the gender from the uploader's home wiki
-                       // TODO this is ugly as hell, let's fix this in core.
-                       new mw.Api( {
-                               ajax: {
-                                       url: repoData.apiUrl || 
mw.util.wikiScript( 'api' ),
-                                       dataType: 'jsonp'
-                               }
-                       } ).get( {
-                               action: 'query',
-                               list: 'users',
-                               ususers: imageData.lastUploader,
-                               usprop: 'gender'
-                       } ).done( function ( data ) {
-                               var gender = 'unknown';
-
+                       this.userInfoProvider.get( imageData.lastUploader, 
repoData ).done( function ( gender ) {
                                viewer.profileEnd( gfpid );
-
-                               if ( data && data.query && data.query.users &&
-                                               data.query.users[0] && 
data.query.users[0].gender ) {
-                                       gender = data.query.users[0].gender;
-                               }
-
                                ui.setUserPageLink( repoData, 
imageData.lastUploader, gender );
                        } ).fail( function () {
-                               mw.log( 'Gender fetch with ID ' + gfpid + ' 
failed, probably due to cross-domain API request.' );
+                               mw.log( 'Gender fetch with ID ' + gfpid + ' 
failed' );
                                ui.setUserPageLink( repoData, 
imageData.lastUploader, 'unknown' );
                        } );
                }
diff --git a/resources/mmv/provider/mmv.provider.UserInfo.js 
b/resources/mmv/provider/mmv.provider.UserInfo.js
new file mode 100644
index 0000000..a6de2be
--- /dev/null
+++ b/resources/mmv/provider/mmv.provider.UserInfo.js
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the MediaWiki extension MultimediaViewer.
+ *
+ * MultimediaViewer is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MultimediaViewer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MultimediaViewer.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+( function ( mw, oo, $ ) {
+
+       /**
+        * @class mw.mmv.provider.UserInfo
+        * Gets user information (currently just the gender).
+        * See https://www.mediawiki.org/wiki/API:Users
+        * @extends mw.mmv.provider.Api
+        * @inheritdoc
+        * @param {mw.Api} api
+        */
+       function UserInfo( api ) {
+               mw.mmv.provider.Api.call( this, api );
+       }
+       oo.inheritClass( UserInfo, mw.mmv.provider.Api );
+
+       /**
+        * @method
+        * Runs an API GET request to get the user info.
+        * @param {string} username
+        * @param {mw.mmv.model.Repo} repoInfo
+        * @return {jQuery.Promise<mw.mmv.provider.UserInfo.Gender>} gender
+        */
+       UserInfo.prototype.get = function( username, repoInfo ) {
+               var provider = this,
+                       ajaxOptions = {},
+                       cacheKey = username;
+
+               // For local/shared db images the user should be visible via a 
local API request,
+               // maybe. (In practice we have Wikimedia users who haven't 
completed the SUL
+               // merge process yet, and other sites might even use a shared 
DB for images
+               // without CentralAuth. Too bad for them.)
+               // For InstantCommons images we need to get user data directly 
from the repo's API.
+               if ( repoInfo.apiUrl ) {
+                       ajaxOptions.url = repoInfo.apiUrl;
+                       ajaxOptions.dataType = 'jsonp';
+                       cacheKey = cacheKey + '|' + repoInfo.apiUrl; // local 
and remote user names could conflict
+               }
+
+               if ( !this.cache[cacheKey] ) {
+                       this.cache[cacheKey] = this.api.get( {
+                               action: 'query',
+                               list: 'users',
+                               ususers: username,
+                               usprop: 'gender'
+                       }, ajaxOptions ).then( function( data ) {
+                               return provider.getQueryField( 'users', data );
+                       } ).then( function( users ) {
+                               if ( users[0] && users[0].gender ) {
+                                       return users[0].gender;
+                               } else {
+                                       return $.Deferred().reject( 'error in 
provider, user info not found' );
+                               }
+                       } );
+               }
+
+               return this.cache[cacheKey];
+       };
+
+       /**
+        * Gender of the user (can be set at preferences, UNKNOWN means they 
did not set it).
+        * This is mainly used for translations, so in wikis where there are no 
grammatic genders
+        * it is not used much.
+        * (This should really belong to a model, but there is no point in 
having a user model if we
+        * only need a single property.)
+        * @enum {string} mw.mmv.provider.UserInfo.Gender
+        */
+       UserInfo.prototype.Gender = {
+               MALE: 'male',
+               FEMALE: 'female',
+               UNKNOWN: 'unknown'
+       };
+
+       mw.mmv.provider.UserInfo = UserInfo;
+}( mediaWiki, OO, jQuery ) );
diff --git a/tests/qunit/provider/mmv.provider.UserInfo.test.js 
b/tests/qunit/provider/mmv.provider.UserInfo.test.js
new file mode 100644
index 0000000..c1e5665
--- /dev/null
+++ b/tests/qunit/provider/mmv.provider.UserInfo.test.js
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the MediaWiki extension MultimediaViewer.
+ *
+ * MultimediaViewer is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MultimediaViewer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MultimediaViewer.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+( function ( mw, $ ) {
+       QUnit.module( 'mmv.provider.UserInfo', QUnit.newMwEnvironment() );
+
+       QUnit.test( 'UserInfo constructor sanity check', 1, function ( assert ) 
{
+               var api = { get: function() {} },
+                       userInfoProvider = new mw.mmv.provider.UserInfo( api );
+
+               assert.ok( userInfoProvider );
+       } );
+
+       QUnit.asyncTest( 'UserInfo get test', 5, function ( assert ) {
+               var apiCallCount = 0,
+                       api = { get: function() {
+                               apiCallCount++;
+                               return $.Deferred().resolve( {
+                                       query: {
+                                               users: [
+                                                       {
+                                                               userid: 4587601,
+                                                               name: 'Catrope',
+                                                               gender: 'male'
+                                                       }
+                                               ]
+                                       }
+                               } );
+                       } },
+                       username = 'Catrope',
+                       repoInfo = {},
+                       foreignRepoInfo = { apiUrl: 
'http://example.com/api.php' },
+                       userInfoProvider = new mw.mmv.provider.UserInfo( api );
+
+               userInfoProvider.get( username, repoInfo ).then( function( 
gender ) {
+                       assert.strictEqual( gender, 
mw.mmv.provider.UserInfo.Gender.MALE, 'gender is set correctly' );
+               } ).then( function() {
+                       assert.strictEqual( apiCallCount, 1 );
+                       // call the data provider a second time to check caching
+                       return userInfoProvider.get( username, repoInfo );
+               } ).then( function() {
+                       assert.strictEqual( apiCallCount, 1 );
+                       // call a third time with a different user to check 
caching
+                       return userInfoProvider.get( 'OtherUser', repoInfo );
+               } ).then( function() {
+                       assert.strictEqual( apiCallCount, 2 );
+                       // call again with a different repo to check caching
+                       return userInfoProvider.get( username, foreignRepoInfo 
);
+               } ).then( function() {
+                       assert.strictEqual( apiCallCount, 3 );
+                       QUnit.start();
+               } );
+       } );
+
+       QUnit.asyncTest( 'UserInfo missing data test', 1, function ( assert ) {
+               var api = { get: function() {
+                               return $.Deferred().resolve( {} );
+                       } },
+                       username = 'Catrope',
+                       repoInfo = {},
+                       userInfoProvider = new mw.mmv.provider.UserInfo( api );
+
+               userInfoProvider.get( username, repoInfo ).fail( function() {
+                       assert.ok( true, 'promise rejected when no data is 
returned' );
+                       QUnit.start();
+               } );
+       } );
+
+       QUnit.asyncTest( 'UserInfo missing user test', 1, function ( assert ) {
+               var api = { get: function() {
+                               return $.Deferred().resolve( {
+                                       query: {
+                                               users: []
+                                       }
+                               } );
+                       } },
+                       username = 'Catrope',
+                       repoInfo = {},
+                       userInfoProvider = new mw.mmv.provider.UserInfo( api );
+
+               userInfoProvider.get( username, repoInfo ).fail( function() {
+                       assert.ok( true, 'promise rejected when user is 
missing' );
+                       QUnit.start();
+               } );
+       } );
+
+       QUnit.asyncTest( 'UserInfo missing gender test', 1, function ( assert ) 
{
+               var api = { get: function() {
+                               return $.Deferred().resolve( {
+                                       query: {
+                                               users: [
+                                                       {
+                                                               userid: 4587601,
+                                                               name: 'Catrope'
+                                                       }
+                                               ]
+                                       }
+                               } );
+                       } },
+                       username = 'Catrope',
+                       repoInfo = {},
+                       userInfoProvider = new mw.mmv.provider.UserInfo( api );
+
+               userInfoProvider.get( username, repoInfo ).fail( function() {
+                       assert.ok( true, 'promise rejected when gender is 
missing' );
+                       QUnit.start();
+               } );
+       } );
+}( mediaWiki, jQuery ) );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9b3ea73c65eef57e160ac8636d9e45d349150884
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MultimediaViewer
Gerrit-Branch: master
Gerrit-Owner: GergÅ‘ Tisza <[email protected]>

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

Reply via email to