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