Arlolra has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/340453 )
Change subject: Fetch imageinfo for both the file and manualthumb ...................................................................... Fetch imageinfo for both the file and manualthumb * Somewhat redundant for images, but videos are going to need both. Change-Id: I1390bc6fb4225e00b35432116ffb8bdc84033808 --- M lib/wt2html/tt/LinkHandler.js M tests/parserTests.txt M tests/timedMediaHandlerParserTests-blacklist.js 3 files changed, 91 insertions(+), 75 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid refs/changes/53/340453/1 diff --git a/lib/wt2html/tt/LinkHandler.js b/lib/wt2html/tt/LinkHandler.js index 274a373..4006b4d 100644 --- a/lib/wt2html/tt/LinkHandler.js +++ b/lib/wt2html/tt/LinkHandler.js @@ -15,6 +15,7 @@ var TokenHandler = require('./TokenHandler.js'); var DU = require('../../utils/DOMUtils.js').DOMUtils; var JSUtils = require('../../utils/jsutils.js').JSUtils; +var Promise = require('../../utils/promise.js'); // define some constructor shortcuts var KV = defines.KV; @@ -1031,73 +1032,72 @@ }; }; +var extractInfo = function(env, o) { + var data = o.data; + if (env.conf.parsoid.useBatchAPI) { + return data.batchResponse; + } else { + var ns = data.imgns; + // `useVideoInfo` is for legacy requests; batching returns thumbdata. + var prop = env.conf.wiki.useVideoInfo ? 'videoinfo' : 'imageinfo'; + // title is guaranteed to be not null here + var image = data.pages[ns + ':' + o.title.getKey()]; + if (!image || !image[prop] || !image[prop][0] || + // Fallback to adding mw:Error + (image.missing !== undefined && image.known === undefined)) { + return null; + } else { + return image[prop][0]; + } + } +}; + +// Use sane defaults +var errorInfo = function(opts) { + return { + url: './Special:FilePath/' + Util.sanitizeTitleURI(opts.title.v.getKey()), + // Preserve width and height from the wikitext options + // even if the image is non-existent. + width: opts.size.v.width || 220, + height: opts.size.v.height || opts.size.v.width || 220, + }; +}; + // Handle a response to an (image|video)info API request. -WikiLinkHandler.prototype.handleInfo = function(cb, token, title, opts, optSources, err, data) { +WikiLinkHandler.prototype.handleInfo = function(cb, token, opts, optSources, err, resp) { // FIXME: Not doing this till we fix up wt2html error handling // // Bump resource use // this.manager.env.bumpParserResourceUse('image'); - var info; + var info, manualinfo; var errs = []; - if (!err && data) { - if (this.env.conf.parsoid.useBatchAPI) { - info = data.batchResponse; - } else { - var ns = data.imgns; - // `useVideoInfo` is for legacy requests; batching returns thumbdata. - var prop = this.env.conf.wiki.useVideoInfo ? 'videoinfo' : 'imageinfo'; - // title is guaranteed to be not null here - var image = data.pages[ns + ':' + title.getKey()]; - if (!image || !image[prop] || !image[prop][0] || - // Fallback to adding mw:Error - (image.missing !== undefined && image.known === undefined)) { - info = false; - } else { - info = image[prop][0]; + if (err) { + info = errorInfo(opts); + errs.push({ key: 'api-error', message: err }); + } else { + info = extractInfo(this.env, resp[0]); + if (!info) { + info = errorInfo(opts); + errs.push({ key: 'missing-image', message: 'This image does not exist.' }); + } else if (info.hasOwnProperty('thumberror')) { + errs.push({ key: 'thumb-error', message: info.thumberror }); + } + if (opts.manualthumb !== undefined) { + manualinfo = extractInfo(this.env, resp[1]); + if (!manualinfo) { + manualinfo = errorInfo(opts); + errs.push({ + key: 'missing-thumbnail', + message: 'This thumbnail does not exist.', + // Additional error info for clients that could fix the error. + params: { name: opts.manualthumb.v }, + }); + } else if (manualinfo.hasOwnProperty('thumberror')) { + errs.push({ key: 'thumb-error', message: manualinfo.thumberror }); } } - } - - // FIXME: Make sure our filename is never of the form - // 'File:foo.png|Some caption', as is the case for example in - // [[:de:Portal:Thüringen]]. The href is likely templated where - // the expansion includes the pipe and caption. We don't currently - // handle that case and pass the full string including the pipe to - // the API. The API in turn interprets the pipe as two separate - // titles and returns two results for each side of the pipe. The - // full 'filename' does not match any of them, so image is then - // undefined here. So for now (as a workaround) check if we - // actually have an image to work with instead of crashing. - - if (!info) { - // Use sane defaults. - info = { - url: './Special:FilePath/' + (title ? Util.sanitizeTitleURI(title.getKey()) : ''), - // Preserve width and height from the wikitext options - // even if the image is non-existent. - width: opts.size.v.width || 220, - height: opts.size.v.height || opts.size.v.width || 220, - }; - - // Set appropriate error info - if (title && (err || !data)) { - errs.push({"key": "api-error", "message": err || "Empty API info"}); - } else if (opts.manualthumb !== undefined) { - errs.push({ - "key": "missing-thumbnail", - "message": "This thumbnail does not exist.", - // Additional error info for clients that could fix the error. - "params": { - "name": opts.manualthumb.v, - }, - }); - } else { - errs.push({"key": "missing-image", "message": "This image does not exist." }); - } - } else if (info.hasOwnProperty('thumberror')) { - errs.push({ key: 'thumb-error', 'message': info.thumberror }); } var dataMwAttr = token.getAttribute('data-mw'); @@ -1114,6 +1114,7 @@ var o; switch (info.mediatype && info.mediatype.toLowerCase()) { default: + if (manualinfo) { info = manualinfo; } o = this.handleImage(opts, info, dataMw); } @@ -1510,27 +1511,42 @@ optSources = null; } - // reset title if this is a manual thumbnail - if (opts.manualthumb) { - title = env.makeTitleFromText(opts.manualthumb.v, undefined, true); - if (title && title.nskey === '') { - // inherit namespace from main image - title.ns = opts.title.v.ns; - title.nskey = opts.title.v.nskey; - } + if (!env.conf.parsoid.fetchImageInfo) { + return this.handleInfo(cb, token, opts, optSources, + 'Fetch of image info disabled.'); } - if (!env.conf.parsoid.fetchImageInfo) { - return this.handleInfo(cb, token, title, opts, optSources, 'Fetch of image info disabled.'); - } else if (!title) { - return this.handleInfo(cb, token, title, opts, optSources, 'Error creating thumbnail: "' + opts.manualthumb.v + '"'); + var wrapResp = function(aTitle) { + return function(data) { return { title: aTitle, data: data }; }; + }; + + var reqs = [ + env.batcher.imageinfo(title.getKey(), opts.size.v) + .then(wrapResp(title)), + ]; + + // If this is a manual thumbnail, fetch the info for that as well + if (opts.manualthumb) { + var manual = env.makeTitleFromText(opts.manualthumb.v, undefined, true); + if (!manual) { + return this.handleInfo(cb, token, opts, optSources, + 'Error creating thumbnail: "' + opts.manualthumb.v + '"'); + } + if (manual.nskey === '') { + // inherit namespace from main image + manual.ns = title.ns; + manual.nskey = title.nskey; + } + reqs.push( + env.batcher.imageinfo(manual.getKey(), opts.size.v) + .then(wrapResp(manual)) + ); } cb({ async: true }); - env.batcher.imageinfo( - title.getKey(), - opts.size.v - ).nodify(this.handleInfo.bind(this, cb, token, title, opts, optSources)); + + Promise.all(reqs) + .nodify(this.handleInfo.bind(this, cb, token, opts, optSources)); }; diff --git a/tests/parserTests.txt b/tests/parserTests.txt index ba9ab75..fa7f840 100644 --- a/tests/parserTests.txt +++ b/tests/parserTests.txt @@ -17920,7 +17920,7 @@ <div class="thumb tright"><div class="thumbinner" style="width:182px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div> !! html/parsoid -<figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"manualthumb","ak":"thumbnail= "}]}' data-mw='{"errors":[{"key":"missing-thumbnail","message":"This thumbnail does not exist.","params":{"name":""}}],"thumb":""}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="./Special:FilePath/" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"220"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure> +<figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"manualthumb","ak":"thumbnail= "}]}' data-mw='{"errors":[{"key":"api-error","message":"Error creating thumbnail: \"\""}],"thumb":""}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"Image:foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="./Special:FilePath/Foobar.jpg" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"220"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure> !! end !! test diff --git a/tests/timedMediaHandlerParserTests-blacklist.js b/tests/timedMediaHandlerParserTests-blacklist.js index 9885c03..99f9e18 100644 --- a/tests/timedMediaHandlerParserTests-blacklist.js +++ b/tests/timedMediaHandlerParserTests-blacklist.js @@ -46,7 +46,7 @@ add("wt2html", "Video with starttime and endtime offsets", "<p data-parsoid='{\"dsr\":[0,38,0,0]}'><span class=\"mw-default-size\" typeof=\"mw:Error mw:Image\" data-parsoid='{\"optList\":[{\"ck\":\"bogus\",\"ak\":\"start=1:25\"},{\"ck\":\"caption\",\"ak\":\"end=1:35\"}],\"dsr\":[0,38,null,null]}' data-mw='{\"errors\":[{\"key\":\"missing-image\",\"message\":\"This image does not exist.\"}],\"caption\":\"end=1:35\"}'><a href=\"./File:Video.ogv\" data-parsoid='{\"a\":{\"href\":\"./File:Video.ogv\"},\"sa\":{\"href\":\"File:Video.ogv\"}}'><img resource=\"./File:Video.ogv\" src=\"./Special:FilePath/Video.ogv\" height=\"220\" width=\"220\" data-parsoid='{\"a\":{\"resource\":\"./File:Video.ogv\",\"height\":\"220\",\"width\":\"220\"},\"sa\":{\"resource\":\"File:Video.ogv\"}}'/></a></span></p>"); add("wt2html", "Video with unsupported alt", "<p data-parsoid='{\"dsr\":[0,27,0,0]}'><span class=\"mw-default-size\" typeof=\"mw:Error mw:Image\" data-parsoid='{\"optList\":[{\"ck\":\"alt\",\"ak\":\"alt=Test\"}],\"dsr\":[0,27,null,null]}' data-mw='{\"errors\":[{\"key\":\"missing-image\",\"message\":\"This image does not exist.\"}]}'><a href=\"./File:Video.ogv\" data-parsoid='{\"a\":{\"href\":\"./File:Video.ogv\"},\"sa\":{\"href\":\"File:Video.ogv\"}}'><img alt=\"Test\" resource=\"./File:Video.ogv\" src=\"./Special:FilePath/Video.ogv\" height=\"220\" width=\"220\" data-parsoid='{\"a\":{\"alt\":\"Test\",\"resource\":\"./File:Video.ogv\",\"height\":\"220\",\"width\":\"220\"},\"sa\":{\"alt\":\"alt=Test\",\"resource\":\"File:Video.ogv\"}}'/></a></span></p>"); add("wt2html", "Video with unsupported link", "<p data-parsoid='{\"dsr\":[0,31,0,0]}'><span class=\"mw-default-size\" typeof=\"mw:Error mw:Image\" data-parsoid='{\"optList\":[{\"ck\":\"link\",\"ak\":\"link=Example\"}],\"dsr\":[0,31,null,null]}' data-mw='{\"errors\":[{\"key\":\"missing-image\",\"message\":\"This image does not exist.\"}]}'><a href=\"./Example\" data-parsoid='{\"a\":{\"href\":\"./Example\"},\"sa\":{\"href\":\"link=Example\"}}'><img resource=\"./File:Video.ogv\" src=\"./Special:FilePath/Video.ogv\" height=\"220\" width=\"220\" data-parsoid='{\"a\":{\"resource\":\"./File:Video.ogv\",\"height\":\"220\",\"width\":\"220\"},\"sa\":{\"resource\":\"File:Video.ogv\"}}'/></a></span></p>"); -add("wt2html", "Video with different thumb image", "<figure class=\"mw-default-size\" typeof=\"mw:Image/Thumb\" data-parsoid='{\"optList\":[{\"ck\":\"manualthumb\",\"ak\":\"thumb=Foobar.jpg\"}],\"dsr\":[0,35,2,2]}' data-mw='{\"thumb\":\"Foobar.jpg\"}'><a href=\"./File:Video.ogv\" data-parsoid='{\"a\":{\"href\":\"./File:Video.ogv\"},\"sa\":{\"href\":\"File:Video.ogv\"},\"dsr\":[2,33,null,null]}'><img resource=\"./File:Video.ogv\" src=\"//example.com/images/3/3a/Foobar.jpg\" data-file-width=\"1941\" data-file-height=\"220\" data-file-type=\"bitmap\" height=\"220\" width=\"1941\" data-parsoid='{\"a\":{\"resource\":\"./File:Video.ogv\",\"height\":\"220\",\"width\":\"1941\"},\"sa\":{\"resource\":\"File:Video.ogv\"}}'/></a></figure>"); +add("wt2html", "Video with different thumb image", "<figure class=\"mw-default-size\" typeof=\"mw:Error mw:Image/Thumb\" data-parsoid='{\"optList\":[{\"ck\":\"manualthumb\",\"ak\":\"thumb=Foobar.jpg\"}],\"dsr\":[0,35,2,2]}' data-mw='{\"errors\":[{\"key\":\"missing-image\",\"message\":\"This image does not exist.\"}],\"thumb\":\"Foobar.jpg\"}'><a href=\"./File:Video.ogv\" data-parsoid='{\"a\":{\"href\":\"./File:Video.ogv\"},\"sa\":{\"href\":\"File:Video.ogv\"},\"dsr\":[2,33,null,null]}'><img resource=\"./File:Video.ogv\" src=\"//example.com/images/3/3a/Foobar.jpg\" height=\"220\" width=\"1941\" data-parsoid='{\"a\":{\"resource\":\"./File:Video.ogv\",\"height\":\"220\",\"width\":\"1941\"},\"sa\":{\"resource\":\"File:Video.ogv\"}}'/></a></figure>"); add("wt2html", "Simple audio element", "<p data-parsoid='{\"dsr\":[0,18,0,0]}'><span class=\"mw-default-size\" typeof=\"mw:Error mw:Image\" data-parsoid='{\"optList\":[],\"dsr\":[0,18,null,null]}' data-mw='{\"errors\":[{\"key\":\"missing-image\",\"message\":\"This image does not exist.\"}]}'><a href=\"./File:Audio.oga\" data-parsoid='{\"a\":{\"href\":\"./File:Audio.oga\"},\"sa\":{\"href\":\"File:Audio.oga\"}}'><img resource=\"./File:Audio.oga\" src=\"./Special:FilePath/Audio.oga\" height=\"220\" width=\"220\" data-parsoid='{\"a\":{\"resource\":\"./File:Audio.oga\",\"height\":\"220\",\"width\":\"220\"},\"sa\":{\"resource\":\"File:Audio.oga\"}}'/></a></span></p>"); -- To view, visit https://gerrit.wikimedia.org/r/340453 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1390bc6fb4225e00b35432116ffb8bdc84033808 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/services/parsoid Gerrit-Branch: master Gerrit-Owner: Arlolra <abrea...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits