Gilles has uploaded a new change for review.

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

Change subject: [WIP] Track the most recent upload time for performance events
......................................................................

[WIP] Track the most recent upload time for performance events

Change-Id: I673f9487deea15dc148452a3a4d6b91563a2c417
Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/975
---
M MultimediaViewer.php
M resources/mmv/logging/mmv.logging.PerformanceLogger.js
M resources/mmv/mmv.js
M resources/mmv/mmv.lightboximage.js
M resources/mmv/model/mmv.model.Image.js
M resources/mmv/provider/mmv.provider.Image.js
6 files changed, 56 insertions(+), 41 deletions(-)


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

diff --git a/MultimediaViewer.php b/MultimediaViewer.php
index 7a47510..dae2dad 100644
--- a/MultimediaViewer.php
+++ b/MultimediaViewer.php
@@ -1052,7 +1052,7 @@
 $wgHooks['EventLoggingRegisterSchemas'][] = function( array &$schemas ) {
        $schemas += array(
                'MediaViewer' => 10536413,
-               'MultimediaViewerNetworkPerformance' => 7917896,
+               'MultimediaViewerNetworkPerformance' => 10596581,
                'MultimediaViewerDuration' => 10427980,
                'MultimediaViewerAttribution' => 9758179,
                'MultimediaViewerDimensions' => 10014238,
diff --git a/resources/mmv/logging/mmv.logging.PerformanceLogger.js 
b/resources/mmv/logging/mmv.logging.PerformanceLogger.js
index bfde462..d665996 100644
--- a/resources/mmv/logging/mmv.logging.PerformanceLogger.js
+++ b/resources/mmv/logging/mmv.logging.PerformanceLogger.js
@@ -62,9 +62,10 @@
         * cached by the browser, as it will consume unnecessary bandwidth for 
the user.
         * @param {string} type the type of request to be measured
         * @param {string} url URL to be measured
+        * @param {jQuery.Promise.<string>} uploadDateTimePromise A promise 
which resolves to the image upload timestamp.
         * @returns {jQuery.Promise} A promise that resolves when the contents 
of the URL have been fetched
         */
-       PL.record = function ( type, url ) {
+       PL.record = function ( type, url, uploadDateTimePromise ) {
                var deferred = $.Deferred(),
                        request,
                        perf = this,
@@ -89,7 +90,7 @@
                                if ( request.readyState === 4 ) {
                                        deferred.notify( request.response, 100 
);
                                        deferred.resolve( request.response );
-                                       perf.recordEntryDelayed( type, total, 
url, request );
+                                       perf.recordEntryDelayed( type, total, 
url, request, uploadDateTimePromise );
                                }
                        };
 
@@ -111,9 +112,11 @@
         * @param {number} total the total load time tracked with a basic 
technique
         * @param {string} url URL of that was measured
         * @param {XMLHttpRequest} request HTTP request that just completed
+        * @param {jQuery.Promise.<string>} uploadDateTimePromise A promise 
which resolves to the image upload timestamp.
         */
-       PL.recordEntry = function ( type, total, url, request ) {
+       PL.recordEntry = function ( type, total, url, request, 
uploadDateTimePromise ) {
                var matches,
+                       logger = this,
                        stats = { type: type,
                                contentHost: window.location.host,
                                isHttps: window.location.protocol === 'https:',
@@ -165,7 +168,17 @@
                        }
                }
 
-               this.log( stats );
+               if ( uploadDateTimePromise ) { // Only defined for images
+                       uploadDateTimePromise.done( function ( uploadDateTime ) 
{
+                               stats.uploadTimestamp = uploadDateTime;
+                               logger.log( stats );
+                       } )
+                       .fail( function() {
+                               logger.log( stats );
+                       } );
+               } else {
+                       this.log( stats );
+               }
        };
 
        /**
@@ -305,14 +318,15 @@
         * @param {number} total the total load time tracked with a basic 
technique
         * @param {string} url URL of that was measured
         * @param {XMLHttpRequest} request HTTP request that just completed
+        * @param {jQuery.Promise.<string>} uploadDateTimePromise A promise 
which resolves to the image upload timestamp.
         */
-       PL.recordEntryDelayed = function ( type, total, url, request ) {
+       PL.recordEntryDelayed = function ( type, total, url, request, 
uploadDateTimePromise ) {
                var perf = this;
 
                // The timeout is necessary because if there's an entry in 
window.performance,
                // it hasn't been added yet at this point
                setTimeout( function() {
-                       perf.recordEntry( type, total, url, request );
+                       perf.recordEntry( type, total, url, request, 
uploadDateTimePromise );
                }, 0 );
        };
 
@@ -402,6 +416,15 @@
                return new XMLHttpRequest();
        };
 
+       /**
+        * @override
+        * @inheritdoc
+        */
+       PL.log = function ( data ) {
+               mw.log( 'mw.mmv.logging.PerformanceLogger', data );
+               return mw.mmv.logging.Logger.prototype.log.call( this, data );
+       }
+
        new PerformanceLogger().init();
 
        mw.mmv.logging.PerformanceLogger = PerformanceLogger;
diff --git a/resources/mmv/mmv.js b/resources/mmv/mmv.js
index 99ebb92..74afe4f 100644
--- a/resources/mmv/mmv.js
+++ b/resources/mmv/mmv.js
@@ -306,15 +306,8 @@
                                                return;
                                        }
 
-                                       uploadTimestamp = 
imageInfo.uploadDateTime.toString();
-                                       // Convert to "timestamp" format 
commonly used in EventLogging
-                                       uploadTimestamp = 
uploadTimestamp.replace( /[:\s]/g, '' );
-                                       // Anonymise the timestamp to avoid 
making the file identifiable
-                                       // We only need to know the day
-                                       uploadTimestamp = 
uploadTimestamp.substr( 0, uploadTimestamp.length - 6 ) + '000000';
-
                                        mw.mmv.durationLogger.record( 
'click-to-first-image', {
-                                               uploadTimestamp: uploadTimestamp
+                                               uploadTimestamp: 
imageInfo.uploadDateTime
                                        } );
                                } );
                        }
@@ -324,6 +317,8 @@
                } );
 
                metadataPromise.done( function ( imageInfo, repoInfo, userInfo 
) {
+                       image.uploadDateTimePromise.resolve( 
imageInfo.uploadDateTime );
+
                        if ( viewer.currentIndex !== image.index ) {
                                return;
                        }
@@ -337,6 +332,8 @@
                        // File reuse steals a bunch of information from the 
DOM, so do it last
                        viewer.ui.setFileReuseData( imageInfo, repoInfo, 
image.caption );
                } ).fail( function ( error ) {
+                       image.uploadDateTimePromise.reject();
+
                        if ( viewer.currentIndex !== image.index ) {
                                return;
                        }
@@ -729,7 +726,8 @@
                        width,
                        image.src,
                        image.originalWidth,
-                       image.originalHeight
+                       image.originalHeight,
+                       image.uploadDateTimePromise
                );
        };
 
@@ -740,11 +738,12 @@
         * @param {string} [sampleUrl] a thumbnail URL for the same file (but 
with different size) (might be missing)
         * @param {number} [originalWidth] the width of the original, 
full-sized file (might be missing)
         * @param {number} [originalHeight] the height of the original, 
full-sized file (might be missing)
+        * @param {jQuery.Promise.<string>} uploadDateTimePromise Promise that 
resolves to the image's upload timestamp when the metadata is loaded
         * @returns {jQuery.Promise.<mw.mmv.model.Thumbnail, HTMLImageElement>} 
A promise resolving to
         *  a thumbnail model and an <img> element. It might or might not have 
progress events which
         *  return a single number.
         */
-       MMVP.fetchThumbnail = function ( fileTitle, width, sampleUrl, 
originalWidth, originalHeight ) {
+       MMVP.fetchThumbnail = function ( fileTitle, width, sampleUrl, 
originalWidth, originalHeight, uploadDateTimePromise ) {
                var viewer = this,
                        guessing = false,
                        thumbnailPromise,
@@ -771,7 +770,7 @@
                }
 
                imagePromise = thumbnailPromise.then( function ( thumbnail ) {
-                       return viewer.imageProvider.get( thumbnail.url );
+                       return viewer.imageProvider.get( thumbnail.url, 
uploadDateTimePromise );
                } );
 
                if ( guessing ) {
@@ -780,7 +779,7 @@
                        // because thumbnailInfoProvider.get is already called 
above when guessedThumbnailInfoProvider.get fails.
                        imagePromise = imagePromise.then( null, function () {
                                return viewer.thumbnailInfoProvider.get( 
fileTitle, width ).then( function ( thumbnail ) {
-                                       return viewer.imageProvider.get( 
thumbnail.url );
+                                       return viewer.imageProvider.get( 
thumbnail.url, uploadDateTimePromise );
                                } );
                        } );
                }
diff --git a/resources/mmv/mmv.lightboximage.js 
b/resources/mmv/mmv.lightboximage.js
index 0916720..918f886 100644
--- a/resources/mmv/mmv.lightboximage.js
+++ b/resources/mmv/mmv.lightboximage.js
@@ -52,25 +52,10 @@
 
                /** @property {number|undefined} originalHeight Height of the 
full-sized file (read from HTML data attribute, might be missing) */
                this.originalHeight = undefined;
+
+               /** @property {jQuery.Promise.<string>} uploadDateTimePromise 
Promise that resolves to the image's upload timestamp */
+               this.uploadDateTimePromise = $.Deferred();
        }
-
-       var LIP = LightboxImage.prototype;
-
-       /**
-        * The URL of the image (in the size we intend use to display the it in 
the lightbox)
-        * @type {String}
-        * @protected
-        */
-       LIP.src = null;
-
-       /**
-        * The URL of a placeholder while the image loads. Typically a smaller 
version of the image, which is already
-        * loaded in the browser.
-        * @type {String}
-        * @return {jQuery.Promise.<mw.mmv.LightboxImage, HTMLImageElement>}
-        * @protected
-        */
-       LIP.initialSrc = null;
 
        mw.mmv.LightboxImage = LightboxImage;
 }( mediaWiki, jQuery ) );
diff --git a/resources/mmv/model/mmv.model.Image.js 
b/resources/mmv/model/mmv.model.Image.js
index 8781aa5..18c9780 100644
--- a/resources/mmv/model/mmv.model.Image.js
+++ b/resources/mmv/model/mmv.model.Image.js
@@ -146,7 +146,13 @@
 
                if ( extmeta ) {
                        creationDateTime = this.parseExtmeta( 
extmeta.DateTimeOriginal, 'plaintext' );
-                       uploadDateTime = this.parseExtmeta( extmeta.DateTime, 
'plaintext' );
+                       uploadDateTime = this.parseExtmeta( extmeta.DateTime, 
'plaintext' ).toString();
+                       // Convert to "timestamp" format commonly used in 
EventLogging
+                       uploadDateTime = uploadDateTime.replace( /[:\s]/g, '' );
+                       // Anonymise the timestamp to avoid making the file 
identifiable
+                       // We only need to know the day
+                       uploadDateTime = uploadDateTime.substr( 0, 
uploadDateTime.length - 6 ) + '000000';
+
                        name = this.parseExtmeta( extmeta.ObjectName, 
'plaintext' );
 
                        description = this.parseExtmeta( 
extmeta.ImageDescription, 'string' );
@@ -172,6 +178,7 @@
                        name = title.getNameText();
                }
 
+
                imageData = new Image(
                        title,
                        name,
diff --git a/resources/mmv/provider/mmv.provider.Image.js 
b/resources/mmv/provider/mmv.provider.Image.js
index 2eccd43..4816654 100644
--- a/resources/mmv/provider/mmv.provider.Image.js
+++ b/resources/mmv/provider/mmv.provider.Image.js
@@ -44,11 +44,12 @@
         * Loads an image and returns it. Includes performance metrics via 
mw.mmv.logging.PerformanceLogger.
         * When the browser supports it, the image is loaded as an AJAX request.
         * @param {string} url
+        * @param {jQuery.Promise.<string>} uploadDateTimePromise A promise 
which resolves to the image upload timestamp.
         * @return {jQuery.Promise.<HTMLImageElement>} A promise which resolves 
to the image object.
         *  When loaded via AJAX, it has progress events, which return an array 
with the content loaded
         *  so far and with the progress as a floating-point number between 0 
and 100.
         */
-       Image.prototype.get = function ( url ) {
+       Image.prototype.get = function ( url, uploadDateTimePromise ) {
                var provider = this,
                        cacheKey = url,
                        extraParam = {},
@@ -65,12 +66,12 @@
                if ( !this.cache[cacheKey] ) {
                        if ( this.imagePreloadingSupported() ) {
                                rawGet = $.proxy( provider.rawGet, provider, 
url, true );
-                               this.cache[cacheKey] = this.performance.record( 
'image', url ).then( rawGet, rawGet );
+                               this.cache[cacheKey] = this.performance.record( 
'image', url, uploadDateTimePromise ).then( rawGet, rawGet );
                        } else {
                                start = $.now();
                                this.cache[cacheKey] = this.rawGet( url );
                                this.cache[cacheKey].always( function () {
-                                       provider.performance.recordEntry( 
'image', $.now() - start, url );
+                                       provider.performance.recordEntry( 
'image', $.now() - start, url, undefined, uploadDateTimePromise );
                                } );
                        }
                        this.cache[cacheKey].fail( function ( error ) {

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I673f9487deea15dc148452a3a4d6b91563a2c417
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MultimediaViewer
Gerrit-Branch: master
Gerrit-Owner: Gilles <gdu...@wikimedia.org>

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

Reply via email to