diff options
Diffstat (limited to 'www/wiki/extensions/UploadWizard/resources/mw.FlickrChecker.js')
-rw-r--r-- | www/wiki/extensions/UploadWizard/resources/mw.FlickrChecker.js | 764 |
1 files changed, 764 insertions, 0 deletions
diff --git a/www/wiki/extensions/UploadWizard/resources/mw.FlickrChecker.js b/www/wiki/extensions/UploadWizard/resources/mw.FlickrChecker.js new file mode 100644 index 00000000..d6956b87 --- /dev/null +++ b/www/wiki/extensions/UploadWizard/resources/mw.FlickrChecker.js @@ -0,0 +1,764 @@ +/* eslint-disable camelcase, no-underscore-dangle */ +( function ( mw, $, OO ) { + mw.FlickrChecker = function ( ui, selectButton ) { + this.ui = ui; + this.imageUploads = []; + this.apiUrl = mw.UploadWizard.config.flickrApiUrl; + this.apiKey = mw.UploadWizard.config.flickrApiKey; + this.selectButton = selectButton; + }; + + /** + * Static list of all Flickr upload filenames. + * Used to avoid name conflicts. Filenames are not removed when an upload is cancelled, so this can + * contain fakes. Since we only use the list to choose an ugly but more unique file format on conflict, + * and never refuse an upload based on it, that is not really a problem. + * @type {Object} + */ + mw.FlickrChecker.fileNames = {}; + + /** + * Cache for Flickr blacklist lookups. + * Resolves to a hash whose keys are the blacklisted Flickr NSIDs. + * Use `FlickrChecker.getBlacklist()` instead of accessing this directly. + * @type {jQuery.Promise} + */ + mw.FlickrChecker.blacklist = null; + + /** + * Cache for Flickr license lookups. + * @type {jQuery.Promise} + */ + mw.FlickrChecker.licensePromise = null; + + /** + * Flickr licenses. + */ + mw.FlickrChecker.licenseList = []; + + // Map each Flickr license name to the equivalent templates. + // These are the current Flickr license names as of April 26, 2011. + // Live list at http://api.flickr.com/services/rest/?&method=flickr.photos.licenses.getInfo&api_key=... + mw.FlickrChecker.licenseMaps = { + 'All Rights Reserved': 'invalid', + 'Attribution License': '{{FlickrVerifiedByUploadWizard|cc-by-2.0}}{{cc-by-2.0}}', + 'Attribution-NoDerivs License': 'invalid', + 'Attribution-NonCommercial-NoDerivs License': 'invalid', + 'Attribution-NonCommercial License': 'invalid', + 'Attribution-NonCommercial-ShareAlike License': 'invalid', + 'Attribution-ShareAlike License': '{{FlickrVerifiedByUploadWizard|cc-by-sa-2.0}}{{cc-by-sa-2.0}}', + 'No known copyright restrictions': '{{FlickrVerifiedByUploadWizard|Flickr-no known copyright restrictions}}{{Flickr-no known copyright restrictions}}', + 'United States Government Work': '{{FlickrVerifiedByUploadWizard|PD-USGov}}{{PD-USGov}}', + 'Public Domain Dedication (CC0)': '{{FlickrVerifiedByUploadWizard|cc-zero}}{{cc-zero}}', + 'Public Domain Mark': '{{FlickrVerifiedByUploadWizard|Public Domain Mark}}' // T105629 + }; + + mw.FlickrChecker.prototype = { + /** + * If a photo is from Flickr, retrieve its license. If the license is valid, display the license + * to the user, hide the normal license selection interface, and set it as the deed for the upload. + * If the license is not valid, alert the user with an error message. If no recognized license is + * retrieved, do nothing. Note that the license look-up system is fragile on purpose. If Flickr + * changes the name associated with a license ID, it's better for the lookup to fail than to use + * an incorrect license. + * + * @param {string} flickrInputUrl The source URL to check + */ + checkFlickr: function ( flickrInputUrl ) { + var photoIdMatches, albumIdMatches, userCollectionMatches, userPhotostreamMatches, groupPoolMatches, userGalleryMatches, userFavoritesMatches; + + photoIdMatches = flickrInputUrl.match( /flickr\.com\/(?:x\/t\/[^/]+\/)?photos\/[^/]+\/([0-9]+)/ ); + albumIdMatches = flickrInputUrl.match( /flickr\.com\/photos\/[^/]+\/(sets|albums)\/([0-9]+)/ ); + userCollectionMatches = flickrInputUrl.match( /flickr\.com\/(?:x\/t\/[^/]+\/)?photos\/[^/]+\/collections\/?([0-9]+)?/ ); + userPhotostreamMatches = flickrInputUrl.match( /flickr\.com\/(?:x\/t\/[^/]+\/)?photos\/([^/]+)/ ); + groupPoolMatches = flickrInputUrl.match( /flickr\.com\/groups\/[^/]+(?:\/pool\/([^/]+))?/ ); + userGalleryMatches = flickrInputUrl.match( /flickr\.com\/(?:x\/t\/[^/]+\/)?photos\/[^/]+\/galleries\/([0-9]+)/ ); + userFavoritesMatches = flickrInputUrl.match( /flickr\.com\/(?:x\/t\/[^/]+\/)?photos\/([^/]+)\/favorites/ ); + + this.$spinner = $.createSpinner( { size: 'large', type: 'block' } ); + $( '#mwe-upwiz-flickr-select-list-container' ).after( this.$spinner ); + + if ( photoIdMatches === null ) { + // try static urls + photoIdMatches = flickrInputUrl.match( /static\.?flickr\.com\/[^/]+\/([0-9]+)_/ ); + } + if ( albumIdMatches || photoIdMatches || userCollectionMatches || userPhotostreamMatches || + groupPoolMatches || userGalleryMatches || userFavoritesMatches ) { + $( '#mwe-upwiz-upload-add-flickr-container' ).hide(); + this.imageUploads = []; + if ( albumIdMatches && albumIdMatches[ 2 ] > 0 ) { + this.getPhotoset( albumIdMatches, flickrInputUrl ); + } else if ( photoIdMatches && photoIdMatches[ 1 ] > 0 ) { + this.getPhoto( photoIdMatches, flickrInputUrl ); + } else if ( userCollectionMatches ) { + this.getCollection( userCollectionMatches, flickrInputUrl ); + } else if ( userFavoritesMatches && userFavoritesMatches[ 1 ] ) { + this.getPhotostream( 'favorites', userPhotostreamMatches, flickrInputUrl ); + } else if ( userGalleryMatches && userGalleryMatches[ 1 ] ) { + this.getGallery( flickrInputUrl ); + } else if ( userPhotostreamMatches && userPhotostreamMatches[ 1 ] ) { + this.getPhotostream( 'stream', flickrInputUrl ); + } else if ( groupPoolMatches ) { + this.getGroupPool( groupPoolMatches, flickrInputUrl ); + } + } else { + // XXX show user the message that the URL entered was not valid + mw.errorDialog( mw.message( 'mwe-upwiz-url-invalid', 'Flickr' ).escaped() ); + this.$spinner.remove(); + this.ui.flickrInterfaceReset(); + } + }, + + /** + * Returns a suggested filename for the image. + * Usually the filename is just the Flickr title plus an extension, but in case of name conflicts + * or empty title a unique filename is generated. + * + * @param {string} title image title on Flickr + * @param {number} id image id on Flickr + * @param {string} ownername owner name on Flickr + * @return {string} + */ + getFilenameFromItem: function ( title, id, ownername ) { + var fileName; + + if ( title === '' ) { + fileName = ownername + ' - ' + id + '.jpg'; + } else if ( mw.FlickrChecker.fileNames[ title + '.jpg' ] ) { + fileName = title + ' - ' + id + '.jpg'; + } else { + fileName = title + '.jpg'; + } + + return fileName; + }, + + /** + * Reserves a filename; used by `mw.FlickrChecker.getFileNameFromItem()` which tries to + * avoid returning a filename which is already reserved. + * This works even when the filename was reserved in a different FlickrChecker instance. + * + * @param {string} fileName + */ + reserveFileName: function ( fileName ) { + mw.FlickrChecker.fileNames[ fileName ] = true; + }, + + /** + * @param {Object} params + * @return {jQuery.Promise} a promise with the response data + */ + flickrRequest: function ( params ) { + params = $.extend( { + api_key: this.apiKey, + format: 'json', + nojsoncallback: 1 + }, params ); + return $.getJSON( this.apiUrl, params ); + }, + + /* + * Retrieves a list of photos in photostream and displays it. + * @see {@link getPhotos} + * @param {string} mode may be: 'favorites' - user's favorites are retrieved, + * or 'stream' - user's photostream is retrieved + * @param {string} url URL to get the user from. + * @return {jQuery.Promise} + */ + getPhotostream: function ( mode, url ) { + var checker = this; + return this.flickrRequest( { + method: 'flickr.urls.lookupUser', + url: url + } ).then( function ( data ) { + var method; + if ( mode === 'stream' ) { + method = 'flickr.people.getPublicPhotos'; + } else if ( mode === 'favorites' ) { + method = 'flickr.favorites.getPublicList'; + } + return checker.getPhotos( 'photos', { + method: method, + user_id: data.user.id + } ); + } ); + }, + + /** + * Retrieves a list of photos in group pool and displays it. + * + * @param {Object} groupPoolMatches Groups in the input URL + * @param {string} url The URL from which to get the group. + * @see {@link getPhotos} + * @return {jQuery.Promise} + */ + getGroupPool: function ( groupPoolMatches, url ) { + var checker = this; + + return this.flickrRequest( { + method: 'flickr.urls.lookupGroup', + url: url + } ).then( function ( data ) { + var gid = data.group.id; + + if ( groupPoolMatches[ 1 ] ) { // URL contains a user ID + return checker.flickrRequest( { + method: 'flickr.urls.lookupUser', + url: 'http://www.flickr.com/photos/' + groupPoolMatches[ 1 ] + } ).then( function ( data ) { + return checker.getPhotos( 'photos', { + method: 'flickr.groups.pools.getPhotos', + group_id: gid, + user_id: data.user.id + } ); + } ); + } + + return checker.getPhotos( 'photos', { + method: 'flickr.groups.pools.getPhotos', + group_id: gid + } ); + } ); + }, + + /** + * Constructs an unordered list of sets in the collection. + * + * @param {boolean} appendId True if you want to append + * id="mwe-upwiz-files-collection-chooser"; false otherwise + * @param {Object} data The retrieved data + * @see {@link getCollection} + * @return {jQuery} + */ + buildCollectionLinks: function ( appendId, data ) { + var $elem = $( '<ul>' ), + that = this, + li, ul; + if ( appendId ) { + $elem.attr( 'id', 'mwe-upwiz-files-collection-chooser' ); + } + $.each( data.collection, function ( index, value ) { + li = $( '<li>' ); + li.append( value.title ); + if ( value.collection !== undefined ) { + li.append( that.buildCollectionLinks( false, value ) ); + } + if ( value.set !== undefined ) { + ul = $( '<ul>' ); + $.each( value.set, function ( index2, value2 ) { + var link = $( '<a>', { href: '#', role: 'button', 'data-id': value2.id } ); + link.append( value2.title ); + link.click( function () { + $( '#mwe-upwiz-files-collection-chooser' ).remove(); + that.getPhotos( 'photoset', { + method: 'flickr.photosets.getPhotos', + photoset_id: link.data( 'id' ) + } ); + } ); + ul.append( $( '<li>' ).append( link ) ); + } ); + li.append( ul ); + } + $elem.append( li ); + } ); + return $elem; + }, + + /** + * Retrieves a list of sets in a collection and displays it. + * + * @param {Object} userCollectionMatches Result of this.url.match + * @param {string} url URL with which to look up the user. + * @return {jQuery.Promise} + */ + getCollection: function ( userCollectionMatches, url ) { + var checker = this; + + return checker.flickrRequest( { + method: 'flickr.urls.lookupUser', + url: url + } ).then( function ( data ) { + var req = { + method: 'flickr.collections.getTree', + extras: 'license, url_sq, owner_name, original_format, date_taken, geo', + user_id: data.user.id + }; + + if ( userCollectionMatches[ 1 ] ) { + req.collection_id = userCollectionMatches[ 1 ]; + } + + return checker.flickrRequest( req ).then( function ( data ) { + $( '#mwe-upwiz-files' ).append( checker.buildCollectionLinks( true, data.collections ) ); + } ); + } ); + }, + + /** + * Retrieves a list of photos in gallery and displays it. + * + * @see {@link getPhotos} + * @param {string} url URL with which to look up the gallery information. + * @return {jQuery.Promise} + */ + getGallery: function ( url ) { + var checker = this; + + return this.flickrRequest( { + method: 'flickr.urls.lookupGallery', + url: url + } ).then( function ( data ) { + return checker.getPhotos( 'photos', { + method: 'flickr.galleries.getPhotos', + gallery_id: data.gallery.id + } ); + } ); + }, + + /** + * Retrieves a list of photos in photoset and displays it. + * + * @see {@link getPhotos} + * @param {Object} albumIdMatches Result of this.url.match + * @return {jQuery.Promise} + */ + getPhotoset: function ( albumIdMatches ) { + return this.getPhotos( 'photoset', { + method: 'flickr.photosets.getPhotos', + photoset_id: albumIdMatches[ 2 ] + } ); + }, + + /** + * Retrieves a list of photos and displays it. + * + * @param {string} mode may be: 'photoset' - for use with photosets, + * or 'photos' - for use with everything else (the parameter is used + * to determine how the properties in retrieved JSON are named) + * @param {Object} options options to pass to the API call; especially API method + * and some "***_id"s (photoset_id, etc.) + * @return {jQuery.Promise} + */ + getPhotos: function ( mode, options ) { + var checker = this, + flickrPromise, + req = {}; + + this.selectButton.setLabel( mw.message( 'mwe-upwiz-select-flickr' ).text() ); + this.selectButton.setDisabled( true ); + + $.extend( req, options, { + extras: 'license, url_sq, owner_name, original_format, date_taken, geo, path_alias', + per_page: '500' + } ); + + flickrPromise = this.flickrRequest( req ).then( function ( data ) { + var photoset; + if ( mode === 'photoset' ) { + photoset = data.photoset; + } else if ( mode === 'photos' ) { + photoset = data.photos; + } + if ( !photoset ) { + $.Deferred().reject( mw.message( 'mwe-upwiz-url-invalid', 'Flickr' ).escaped() ); + } + return photoset; + } ); + + // would be better to use isBlacklisted(), but didn't find a nice way of combining it with $.each + return $.when( flickrPromise, this.getBlacklist() ).then( function ( photoset, blacklist ) { + var fileName, sourceURL, + checkboxes = [], + checkboxesWidget = new OO.ui.CheckboxMultiselectWidget(), + x = 0; + + checker.$spinner.remove(); + + $.each( photoset.photo, function ( i, item ) { + var flickrUpload, license, licenseValue, ownerId; + + license = checker.checkLicense( item.license, i ); + licenseValue = license.licenseValue; + if ( licenseValue === 'invalid' ) { + return; + } + + if ( mode === 'photoset' ) { + ownerId = photoset.owner; + sourceURL = 'http://www.flickr.com/photos/' + photoset.owner + '/' + item.id + '/'; + } else if ( mode === 'photos' ) { + ownerId = item.owner; + sourceURL = 'http://www.flickr.com/photos/' + item.owner + '/' + item.id + '/'; + } + + if ( ownerId in blacklist || item.pathalias in blacklist ) { + return; + } + + // Limit to maximum of 500 valid images + // (Flickr's API returns a maximum of 500 images anyway.) + if ( x++ >= 500 ) { + return false; + } + + fileName = checker.getFilenameFromItem( item.title, item.id, item.ownername ); + + flickrUpload = { + name: fileName, + url: '', + type: 'JPEG', + fromURL: true, + source: 'flickr', + licenseValue: licenseValue, + licenseMessage: license.licenseMessage, + license: license.licenseName !== 'Public Domain Mark', + photoId: item.id, + location: { + latitude: item.latitude, + longitude: item.longitude + }, + author: item.ownername, + date: item.datetaken, + originalFormat: item.originalformat, + sourceURL: sourceURL, + index: i + }; + // Adding all the Photoset files which have a valid license with the required info to an array so that they can be referenced later + checker.imageUploads[ i ] = flickrUpload; + checker.reserveFileName( fileName ); + + // setting up the thumbnail previews in the Selection list + if ( item.url_sq ) { + checkboxes.push( new OO.ui.CheckboxMultioptionWidget( { + data: i, + label: $( '<img class="lazy-thumbnail" data-original="' + item.url_sq + '">' ) + } ) ); + } + } ); + checkboxesWidget.addItems( checkboxes ); + $( '#mwe-upwiz-flickr-select-list' ).append( checkboxesWidget.$element ); + // Set up checkboxes + checkboxesWidget.on( 'select', function () { + var selectedCount = checkboxesWidget.findSelectedItems().length; + // If at least one item is selected, activate the upload button + checker.selectButton.setDisabled( selectedCount === 0 ); + // Limit the number of selectable images + checkboxesWidget.getItems().forEach( function ( checkbox ) { + if ( !checkbox.isSelected() ) { + checkbox.setDisabled( selectedCount >= mw.UploadWizard.config.maxUploads ); + } + } ); + } ); + // Set up action for 'Upload selected images' button + checker.selectButton.on( 'click', function () { + var uploads = []; + checker.$spinner = $.createSpinner( { size: 'large', type: 'block' } ); + $( '#mwe-upwiz-flickr-select-list-container' ).hide(); + $( '#mwe-upwiz-upload-ctrls' ).show(); + $( '#mwe-upwiz-flickr-select-list-container' ).after( checker.$spinner ); + $.when.apply( $, checkboxesWidget.findSelectedItemsData().map( function ( image ) { + uploads.push( checker.imageUploads[ image ] ); + // For each image, load the description and URL to upload from + return $.when( + checker.setUploadDescription( checker.imageUploads[ image ] ), + checker.setImageURL( image ) + ); + } ) ).done( function () { + checker.ui.emit( 'files-added', uploads ); + } ).always( function () { + // We'll only bind this once, since that selectButton could be + // reused later, with a different flickr set (it is not destroyed) + checker.selectButton.off( 'click' ); + checker.$spinner.remove(); + checker.ui.flickrInterfaceDestroy(); + } ); + } ); + + if ( checker.imageUploads.length === 0 ) { + return $.Deferred().reject( mw.message( 'mwe-upwiz-license-photoset-invalid' ).escaped() ); + } else { + $( '#mwe-upwiz-flickr-select-list-container' ).show(); + // Lazy-load images + $( 'img.lazy-thumbnail' ).lazyload( { + // jQuery considers all images without 'src' to not be ':visible' + skip_invisible: false + } ); + // Trigger initial update (HACK) + setTimeout( function () { + $( window ).triggerHandler( 'resize' ); + } ); + } + } ).fail( function ( message ) { + mw.errorDialog( message ); + checker.$spinner.remove(); + checker.ui.flickrInterfaceReset(); + } ); + }, + + /** + * Get a single photo from Flickr. + * + * @param {Object} photoIdMatches Result of matching input URL against a regex + * for photo IDs. + * @return {jQuery.Promise} + */ + getPhoto: function ( photoIdMatches ) { + var fileName, photoAuthor, sourceURL, + checker = this, + photoId = photoIdMatches[ 1 ]; + + return this.flickrRequest( { + method: 'flickr.photos.getInfo', + photo_id: photoId + } ).then( function ( data ) { + if ( !data.photo ) { + return $.Deferred().reject( mw.message( 'mwe-upwiz-url-invalid', 'Flickr' ).escaped() ); + } + return data.photo; + } ).then( function ( photo ) { + var isBlacklistedPromise = checker.isBlacklisted( photo.owner.nsid, photo.owner.path_alias ); + return isBlacklistedPromise.then( function ( isBlacklisted ) { + if ( isBlacklisted ) { + return $.Deferred().reject( mw.message( 'mwe-upwiz-user-blacklisted', 'Flickr' ).escaped() ); + } else { + return photo; + } + } ); + } ).then( function ( photo ) { + var license, flickrUpload; + + license = checker.checkLicense( photo.license ); + if ( license.licenseValue === 'invalid' ) { + return $.Deferred().reject( license.licenseMessage ); + } + + fileName = checker.getFilenameFromItem( photo.title._content, photo.id, + photo.owner.username ); + + // if owner doesn't have a real name, use username + if ( photo.owner.realname !== '' ) { + photoAuthor = photo.owner.realname; + } else { + photoAuthor = photo.owner.username; + } + // get the URL of the photo page + $.each( photo.urls.url, function ( index, url ) { + if ( url.type === 'photopage' ) { + sourceURL = url._content; + // break each loop + return false; + } + } ); + flickrUpload = { + name: fileName, + url: '', + type: 'JPEG', + fromURL: true, + source: 'flickr', + licenseValue: license.licenseValue, + licenseMessage: license.licenseMessage, + license: license.licenseName !== 'Public Domain Mark', + author: photoAuthor, + originalFormat: photo.originalformat, + date: photo.dates.taken, + location: photo.location, + photoId: photo.id, + sourceURL: sourceURL + }; + + checker.imageUploads.push( flickrUpload ); + checker.reserveFileName( fileName ); + + $.when( + checker.setUploadDescription( flickrUpload, photo.description._content ), + checker.setImageURL( 0 ) + ).done( function () { + checker.ui.emit( 'files-added', [ flickrUpload ] ); + } ).always( function () { + checker.$spinner.remove(); + checker.ui.flickrInterfaceDestroy(); + } ); + } ).fail( function ( message ) { + mw.errorDialog( message ); + checker.$spinner.remove(); + checker.ui.flickrInterfaceReset(); + } ); + }, + + /** + * Checks a user against the blacklist. Both the NSID and the path_alias (if it exists) MUST be + * supplied, as the blacklist will probably only contain one of them. (Users don't have a + * path_alias in the beginning, and must set it manually; if it does not exist, it can be left + * undefined, or an empty string can be supplied (which is what the Flickr API usually returns + * as the path_alias for such users). + * + * @param {string} nsid Flickr NSID of the author + * @param {string} [path_alias] Flickr username of the author (the unchangeable one, in the URL) + * @return {jQuery.Promise} a promise which resolves to a boolean - true if the user is blacklisted + */ + isBlacklisted: function ( nsid, path_alias ) { + path_alias = String( path_alias ); + return this.getBlacklist().then( function ( blacklist ) { + // the blacklist should never contain the empty string, but better safe then sorry + return ( nsid in blacklist || path_alias && path_alias in blacklist ); + } ); + }, + + /** + * Returns a promise for the Flickr user blacklist. + * The promise resolves to a hash with the blacklisted NSIDs/path_alias-es as its keys. + * (path_alias is the username that appears in the URL.) + * The blacklist will usually contain the path_alias or the NSID of the user, but not both; + * it is the caller's responsibility to check against both of them. + * + * @return {jQuery.Promise} + */ + getBlacklist: function () { + var api = new mw.Api(); + if ( !mw.FlickrChecker.blacklist ) { + mw.FlickrChecker.blacklist = api.get( { + action: 'flickrblacklist', + list: 1, + format: 'json' + } ).then( function ( data ) { + var blacklist = {}; + if ( data.flickrblacklist && data.flickrblacklist.list ) { + $.each( data.flickrblacklist.list, function ( i, username ) { + blacklist[ username ] = true; + } ); + } + return blacklist; + } ); + } + return mw.FlickrChecker.blacklist; + }, + + /** + * Retrieve the list of all current Flickr licenses and store it in an array (`mw.FlickrChecker.licenseList`) + * + * @return {jQuery.Promise} + */ + getLicenses: function () { + if ( mw.FlickrChecker.licensePromise ) { + return mw.FlickrChecker.licensePromise; + } + + // Workaround for http://bugs.jquery.com/ticket/8283 + jQuery.support.cors = true; + mw.FlickrChecker.licensePromise = this.flickrRequest( { + method: 'flickr.photos.licenses.getInfo' + } ).then( function ( data ) { + if ( typeof data.licenses !== 'undefined' ) { + $.each( data.licenses.license, function ( index, value ) { + mw.FlickrChecker.licenseList[ value.id ] = value.name; + } ); + } + } ); + + return mw.FlickrChecker.licensePromise; + }, + + /** + * @param {Object} upload + * @param {string} description + * @return {jQuery.Promise} + */ + setUploadDescription: function ( upload, description ) { + if ( description !== undefined ) { + // If a Flickr description has a | character in it, it will + // mess up the MediaWiki description. Escape them. + upload.description = description.replace( /\|/g, '|' ); + return $.Deferred().resolve(); + } else { + return this.setImageDescription( upload ); + } + }, + + /** + * @param {Object} upload + * @return {jQuery.Promise} + */ + setImageDescription: function ( upload ) { + var checker = this, + photoId = upload.photoId; + + return this.flickrRequest( { + method: 'flickr.photos.getInfo', + photo_id: photoId + } ).then( function ( data ) { + checker.setUploadDescription( upload, data.photo.description._content ); + } ); + }, + + /** + * Retrieve the URL of the largest version available on Flickr and set that + * as the upload URL. + * + * @param {number} index Index of the image for which we need to set the URL + * @return {jQuery.Promise} + */ + setImageURL: function ( index ) { + var largestSize, + checker = this, + upload = this.imageUploads[ index ], + photoId = upload.photoId; + + return this.flickrRequest( { + method: 'flickr.photos.getSizes', + photo_id: photoId + } ).then( function ( data ) { + var nameParts; + + if ( + typeof data.sizes !== 'undefined' && + typeof data.sizes.size !== 'undefined' && + data.sizes.size.length > 0 + ) { + // Flickr always returns the largest version as the final size. + // TODO: Make this less fragile by actually comparing sizes. + largestSize = data.sizes.size.pop(); + // Flickr provides the original format for images coming from pro users, hence we need to change the default JPEG to this format + if ( largestSize.label === 'Original' ) { + upload.type = upload.originalFormat; + + nameParts = upload.name.split( '.' ); + if ( nameParts.length > 1 ) { + nameParts.pop(); + } + upload.name = nameParts.join( '.' ) + '.' + upload.originalFormat; + } + upload.url = largestSize.source; + } else { + mw.errorDialog( mw.message( 'mwe-upwiz-error-no-image-retrieved', 'Flickr' ).escaped() ); + checker.$spinner.remove(); + checker.ui.flickrInterfaceReset(); + return $.Deferred().reject(); + } + } ); + }, + + checkLicense: function ( licenseId ) { + var licenseMessage, license, + // The returned data.photo.license is just an ID that we use to look up the license name + licenseName = mw.FlickrChecker.licenseList[ licenseId ], + // Use the license name to retrieve the template values + licenseValue = mw.FlickrChecker.licenseMaps[ licenseName ]; + + // Set the license message to show the user. + if ( licenseValue === 'invalid' ) { + licenseMessage = mw.message( 'mwe-upwiz-license-external-invalid', 'Flickr', licenseName ).escaped(); + } else { + licenseMessage = mw.message( 'mwe-upwiz-license-external', 'Flickr', licenseName ).escaped(); + } + + license = { + licenseName: licenseName, + licenseMessage: licenseMessage, + licenseValue: licenseValue + }; + + return license; + } + }; + +}( mediaWiki, jQuery, OO ) ); |