r76111 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r76110‎ | r76111 | r76112 >
Date:16:26, 5 November 2010
Author:hartman
Status:resolved (Comments)
Tags:
Comment:
InstantCommons: API caching expires after a day. Now check for existing presence of thumbnail.

* Should save many downloads from uploads.wikimedia.org
* Checks with API if current upload is newer than stored local thumb
* File cache expires after a month and when purging the file page.
Closes bug 25970
Modified paths:
  • /trunk/phase3/includes/filerepo/ForeignAPIRepo.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/filerepo/ForeignAPIRepo.php
@@ -25,16 +25,20 @@
2626 */
2727 class ForeignAPIRepo extends FileRepo {
2828 var $fileFactory = array( 'ForeignAPIFile', 'newFromTitle' );
 29+ /* Check back with Commons after a day */
2930 var $apiThumbCacheExpiry = 86400;
 31+ /* Redownload thumbnail files after a month */
 32+ var $fileCacheExpiry = 2629743;
 33+
3034 protected $mQueryCache = array();
3135 protected $mFileExists = array();
3236
3337 function __construct( $info ) {
3438 parent::__construct( $info );
35 -
36 - // http://commons.wikimedia.org/w/api.php
37 - $this->mApiBase = isset( $info['apibase'] ) ? $info['apibase'] : null;
3839
 40+ // http://commons.wikimedia.org/w/api.php
 41+ $this->mApiBase = isset( $info['apibase'] ) ? $info['apibase'] : null;
 42+
3943 if( isset( $info['apiThumbCacheExpiry'] ) ) {
4044 $this->apiThumbCacheExpiry = $info['apiThumbCacheExpiry'];
4145 }
@@ -119,7 +123,7 @@
120124 array(
121125 'format' => 'json',
122126 'action' => 'query',
123 - 'redirects' => 'true'
 127+ 'redirects' => 'true'
124128 ) );
125129 if ( $this->mApiBase ) {
126130 $url = wfAppendQuery( $this->mApiBase, $query );
@@ -176,10 +180,10 @@
177181 return $ret;
178182 }
179183
180 - function getThumbUrl( $name, $width=-1, $height=-1 ) {
 184+ function getThumbUrl( $name, $width=-1, $height=-1, &$result ) {
181185 $data = $this->fetchImageQuery( array(
182186 'titles' => 'File:' . $name,
183 - 'iiprop' => 'url',
 187+ 'iiprop' => 'url|timestamp',
184188 'iiurlwidth' => $width,
185189 'iiurlheight' => $height,
186190 'prop' => 'imageinfo' ) );
@@ -187,12 +191,23 @@
188192
189193 if( $data && $info && isset( $info['thumburl'] ) ) {
190194 wfDebug( __METHOD__ . " got remote thumb " . $info['thumburl'] . "\n" );
 195+ $result = $info;
191196 return $info['thumburl'];
192197 } else {
193198 return false;
194199 }
195200 }
196201
 202+ /*
 203+ * Return the imageurl from cache if possible
 204+ *
 205+ * If the url has been requested today, get it from cache
 206+ * Otherwise retrieve remote thumb url, check for local file.
 207+ *
 208+ * @param $name String is a dbkey form of a title
 209+ * @param $width
 210+ * @param $height
 211+ */
197212 function getThumbUrlFromCache( $name, $width, $height ) {
198213 global $wgMemc, $wgUploadPath, $wgServer, $wgUploadDirectory;
199214
@@ -201,35 +216,53 @@
202217 }
203218
204219 $key = $this->getLocalCacheKey( 'ForeignAPIRepo', 'ThumbUrl', $name, $width );
 220+
205221 $thumbUrl = $wgMemc->get($key);
206222 if ( $thumbUrl ) {
207223 wfDebug("Got thumb from local cache. $thumbUrl \n");
208224 return $thumbUrl;
209225 }
210226 else {
211 - $foreignUrl = $this->getThumbUrl( $name, $width, $height );
 227+ $metadata = null;
 228+ $foreignUrl = $this->getThumbUrl( $name, $width, $height, $metadata );
 229+ // We need the same filename as the remote one :)
 230+ $fileName = rawurldecode( pathinfo( $foreignUrl, PATHINFO_BASENAME ) );
 231+ $path = 'thumb/' . $this->getHashPath( $name ) . $name . "/";
 232+ $localFilename = $wgUploadDirectory . '/' . $path . $fileName;
 233+ $localUrl = $wgServer . $wgUploadPath . '/' . $path . $fileName;
 234+
212235 if( !$foreignUrl ) {
213236 wfDebug( __METHOD__ . " Could not find thumburl\n" );
214237 return false;
215238 }
 239+ if( file_exists( $localFilename ) && isset( $metadata['timestamp'] ) ) {
 240+ wfDebug( __METHOD__ . " Thumbnail was already downloaded before\n" );
 241+ $modified = filemtime( $localFilename );
 242+ $remoteModified = strtotime( $metadata['timestamp'] );
 243+ $diff = abs( $modified - $remoteModified );
 244+ if( $remoteModified < $modified && $diff < $this->fileCacheExpiry ) {
 245+ /* Use our current already downloaded thumbnail */
 246+ $wgMemc->set( $key, $localUrl, $this->apiThumbCacheExpiry );
 247+ return $localUrl;
 248+ }
 249+ /* There is a new Commons file, or existing thumbnail older than a month */
 250+
 251+ }
216252 $thumb = Http::get( $foreignUrl );
217253 if( !$thumb ) {
218254 wfDebug( __METHOD__ . " Could not download thumb\n" );
219255 return false;
220256 }
221 - // We need the same filename as the remote one :)
222 - $fileName = rawurldecode( pathinfo( $foreignUrl, PATHINFO_BASENAME ) );
223 - $path = 'thumb/' . $this->getHashPath( $name ) . $name . "/";
224257 if ( !is_dir($wgUploadDirectory . '/' . $path) ) {
225258 if( !wfMkdirParents($wgUploadDirectory . '/' . $path) ) {
226259 wfDebug( __METHOD__ . " could not create directory for thumb\n" );
227260 return $foreignUrl;
228261 }
229262 }
230 - $localUrl = $wgServer . $wgUploadPath . '/' . $path . $fileName;
 263+
231264 # FIXME: Delete old thumbs that aren't being used. Maintenance script?
232265 wfSuppressWarnings();
233 - if( !file_put_contents($wgUploadDirectory . '/' . $path . $fileName, $thumb ) ) {
 266+ if( !file_put_contents($localFilename, $thumb ) ) {
234267 wfRestoreWarnings();
235268 wfDebug( __METHOD__ . " could not write to thumb path\n" );
236269 return $foreignUrl;

Follow-up revisions

RevisionCommit summaryAuthorDate
r76160follow up r76111. I had picked the wrong timedifference for the filecache.hartman23:00, 5 November 2010
r76616Followup to r76111. Making the result parameter on getThumbUrl optionalrobla06:25, 13 November 2010
r80415Add comments with how values are calculated. Follow up of r76111hartman16:32, 16 January 2011

Comments

#Comment by RobLa (talk | contribs)   06:11, 13 November 2010

This creates a couple of problems: 1. getThumbUrl previously only required one parameter. By tacking on &$result on the end, all 4 are required. 2. There's a call to getThumbUrl from getThumbUrlFromCache (line 215 in ForeignAPIRepo.php r76111) that misses it.

Seems the preferable way to handle this is to make &$result an optional parameter, since it's not as though we care whether or not the calling code actually does anything with the result anyway.

#Comment by RobLa (talk | contribs)   06:30, 13 November 2010

I went ahead and fixed it in r76616 since I was in a good place to test it.

#Comment by TheDJ (talk | contribs)   11:56, 13 November 2010

Well spotted, good fix.

#Comment by Reedy (talk | contribs)   19:51, 12 January 2011
+	/* Check back with Commons after a day */
 	var $apiThumbCacheExpiry = 86400;
+	/* Redownload thumbnail files after a month */
+	var $fileCacheExpiry = 2629743;

Do we have to use magic numbers here?

Expressing 86400 as 60 * 60 * 24 makes more sense. And I'm struggling how to see where 2629743 comes from

#Comment by Reedy (talk | contribs)   19:54, 12 January 2011
<Nikerabbit> > class AB { var $x = 5 *2; }
<Nikerabbit> Parse error: syntax error, unexpected '*', expecting ',' or ';' in /www/sandwiki/maintenance/eval.php(76) : eval()'d code on line 1
<Bryan> aren't 86400, 3600 and 168 the magic numbers everybody should know? :p
<RoanKattouw> Bryan: var $x = 86400; // 24*60*60

In a comment next to it is fine

#Comment by TheDJ (talk | contribs)   16:33, 16 January 2011

Added comments in r80415

Status & tagging log