http://www.mediawiki.org/wiki/Special:Code/MediaWiki/56201

Revision: 56201
Author:   btongminh
Date:     2009-09-11 18:28:25 +0000 (Fri, 11 Sep 2009)

Log Message:
-----------
Rewrote this globalusage extension. Still needs a population script and a lot 
of work on the UI.

Modified Paths:
--------------
    trunk/extensions/GlobalUsage/GlobalUsage.i18n.php
    trunk/extensions/GlobalUsage/GlobalUsage.pg.sql
    trunk/extensions/GlobalUsage/GlobalUsage.php
    trunk/extensions/GlobalUsage/GlobalUsage.sql
    trunk/extensions/GlobalUsage/GlobalUsage_body.php
    trunk/extensions/GlobalUsage/readme.txt

Added Paths:
-----------
    trunk/extensions/GlobalUsage/GlobalUsageHooks.php
    trunk/extensions/GlobalUsage/SpecialGlobalUsage.php

Removed Paths:
-------------
    trunk/extensions/GlobalUsage/GlobalUsageDaemon.php
    trunk/extensions/GlobalUsage/populateGlobalUsage.php

Modified: trunk/extensions/GlobalUsage/GlobalUsage.i18n.php
===================================================================
--- trunk/extensions/GlobalUsage/GlobalUsage.i18n.php   2009-09-11 18:22:33 UTC 
(rev 56200)
+++ trunk/extensions/GlobalUsage/GlobalUsage.i18n.php   2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -12,6 +12,7 @@
  */
 $messages['en'] = array(
        'globalusage'      => 'Global file usage',
+       'globalusage-for'  => 'Global usage for "$1"',
        'globalusage-desc' => '[[Special:GlobalUsage|Special page]] to view 
global file usage',
        'globalusage-ok'   => 'Search',
        'globalusage-text' => 'Search global file usage.'

Modified: trunk/extensions/GlobalUsage/GlobalUsage.pg.sql
===================================================================
--- trunk/extensions/GlobalUsage/GlobalUsage.pg.sql     2009-09-11 18:22:33 UTC 
(rev 56200)
+++ trunk/extensions/GlobalUsage/GlobalUsage.pg.sql     2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -4,8 +4,7 @@
        gil_page_namespace TEXT     NOT NULL,
        gil_page_title     TEXT     NOT NULL,
        gil_to             TEXT     NOT NULL,
-       gil_is_local       SMALLINT NOT NULL,
        PRIMARY KEY (gil_wiki, gil_page)
 );
-CREATE INDEX globalimagelinks_wiki ON globalimagelinks(gil_wiki, gil_to);
-CREATE INDEX globalimagelinks_to ON globalimagelinks(gil_to, gil_is_local);
+CREATE INDEX globalimagelinks_wiki ON globalimagelinks(gil_to, gil_wiki);
+

Modified: trunk/extensions/GlobalUsage/GlobalUsage.php
===================================================================
--- trunk/extensions/GlobalUsage/GlobalUsage.php        2009-09-11 18:22:33 UTC 
(rev 56200)
+++ trunk/extensions/GlobalUsage/GlobalUsage.php        2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -1,6 +1,6 @@
 <?php
 /*
- Copyright (c) 2008 Bryan Tong Minh
+ Copyright (c) 2008 - 2009 Bryan Tong Minh
 
  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
@@ -33,37 +33,40 @@
        exit( 1 );
 }
 
-// Defines
-define('GUIW_LOCAL', 0);
-define('GUIW_SERVER', 1);
 
-if (isset($_SERVER) && array_key_exists( 'REQUEST_METHOD', $_SERVER ) ) {
-       $dir = dirname(__FILE__) . '/';
+$dir = dirname(__FILE__) . '/';
 
-       $wgExtensionCredits['specialpage'][] = array(
-               'path' => __FILE__,
-               'name' => 'Global Usage',
-               'author' => 'Bryan Tong Minh',
-               'description' => 'Special page to view global file usage',
-               'descriptionmsg' => 'globalusage-desc',
-               'url' => 'http://www.mediawiki.org/wiki/Extension:GlobalUsage',
-               'version' => '1.1',
-       );
+$wgExtensionCredits['specialpage'][] = array(
+       'path' => __FILE__,
+       'name' => 'Global Usage',
+       'author' => 'Bryan Tong Minh',
+       'description' => 'Special page to view global file usage',
+       'descriptionmsg' => 'globalusage-desc',
+       'url' => 'http://www.mediawiki.org/wiki/Extension:GlobalUsage',
+       'version' => '2.0',
+);
 
-       $wgExtensionMessagesFiles['GlobalUsage'] = $dir . 
'GlobalUsage.i18n.php';
-       $wgAutoloadClasses['GlobalUsage'] = $dir . 'GlobalUsage_body.php';
-       $wgExtensionMessageFiles['GlobalUsage'] = $dir . 'GlobalUsage.i18n.php';
-       $wgExtensionAliasesFiles['GlobalUsage'] = $dir . 
'GlobalUsage.alias.php';
-       $wgSpecialPages['GlobalUsage'] = 'GlobalUsage';
+$wgExtensionMessagesFiles['GlobalUsage'] = $dir . 'GlobalUsage.i18n.php';
+$wgAutoloadClasses['GlobalUsage'] = $dir . 'GlobalUsage_body.php';
+$wgAutoloadClasses['GlobalUsageHooks'] = $dir . 'GlobalUsageHooks.php';
+$wgAutoloadClasses['SpecialGlobalUsage'] = $dir . 'SpecialGlobalUsage.php';
+$wgExtensionMessageFiles['GlobalUsage'] = $dir . 'GlobalUsage.i18n.php';
+$wgExtensionAliasesFiles['GlobalUsage'] = $dir . 'GlobalUsage.alias.php';
+$wgSpecialPages['GlobalUsage'] = 'SpecialGlobalUsage';
 
-       $wgHooks['LinksUpdate'][] = array( 'GlobalUsage', 'updateLinks' );
-       $wgHooks['ArticleDeleteComplete'][] = array( 'GlobalUsage', 
'articleDeleted' );
-       $wgHooks['FileDeleteComplete'][] = array( 'GlobalUsage', 'fileDeleted' 
);
-       $wgHooks['FileUndeleteComplete'][] = array( 'GlobalUsage', 
'fileUndeleted' );
-       $wgHooks['UploadComplete'][] = array( 'GlobalUsage', 'imageUploaded' );
-       $wgHooks['SpecialMovepageAfterMove'][] = array( 'GlobalUsage', 
'articleMoved' );
-}
+/* Things that can cause link updates:
+ * - Local LinksUpdate
+ * - Local article deletion (remove from table)
+ * - Local article move (update page title)
+ * - Local file upload/deletion/move (toggle is_local flag)
+ */
+$wgHooks['LinksUpdateComplete'][] = 'GlobalUsageHooks::onLinksUpdate';
+$wgHooks['ArticleDelete'][] = 'GlobalUsageHooks::onArticleDelete';
+$wgHooks['FileUndeleteComplete'][] = 'GlobalUsageHooks::onFileUndelete';
+$wgHooks['UploadComplete'][] = 'GlobalUsageHooks::onUpload';
+$wgHooks['TitleMoveComplete'][] = 'GlobalUsageHooks::onTitleMove';
 
+
 // If set to false, the local database contains the globalimagelinks table
 // Else set to something understandable to LBFactory
-$wgguMasterDatabase = false;
+$wgGlobalUsageDatabase = false;

Modified: trunk/extensions/GlobalUsage/GlobalUsage.sql
===================================================================
--- trunk/extensions/GlobalUsage/GlobalUsage.sql        2009-09-11 18:22:33 UTC 
(rev 56200)
+++ trunk/extensions/GlobalUsage/GlobalUsage.sql        2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -9,16 +9,12 @@
        gil_page_title varchar(255) not null,
        -- Image name
        gil_to varchar(255) not null,
-       -- Exists locally
-       gil_is_local tinyint(1) not null,
+
        
        -- Note: You might want to shorten the gil_wiki part of the indices.
        -- If the domain format is used, only the "en.wikip" part is needed for 
an
        -- unique lookup
        
        PRIMARY KEY (gil_wiki, gil_page, gil_to),
-       -- On gil_is_local change
-       INDEX (gil_wiki, gil_to),
-       -- On the special page itself
-       INDEX (gil_to, gil_is_local)
-) /*$wgDBTableOptions*/;
\ No newline at end of file
+       INDEX (gil_to, gil_wiki)
+) /*$wgDBTableOptions*/;

Deleted: trunk/extensions/GlobalUsage/GlobalUsageDaemon.php
===================================================================
--- trunk/extensions/GlobalUsage/GlobalUsageDaemon.php  2009-09-11 18:22:33 UTC 
(rev 56200)
+++ trunk/extensions/GlobalUsage/GlobalUsageDaemon.php  2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -1,434 +0,0 @@
-<?php
-
-class GlobalUsageDaemon {
-       // This daemon supports updating from multiple wikis
-
-       // Array of wiki => timestamp pairs
-       public $timestamps;
-       // Array of database key => database pairs
-       private $databases;
-       // Array of localized namespaces
-       private $namespaces;
-       // Location of the log file
-       private $log;
-       // Stderr pointer
-       private $stderr;
-       // Array of wikis containing config settings
-       private $wikiList;
-
-       public function __construct($log, $wikiList, $silent = false) {
-               $this->databases = array();
-               $this->timestamps = array();
-               $this->namespaces = array();
-               $this->log = $log;
-               $this->wikiList = $wikiList;
-               
-               if (!$silent)
-                       $this->stderr = fopen('php://stderr', 'w');
-               else
-                       $this->stderr = null;
-               
-               if (($fp = fopen($this->log, 'r')) !== false) {
-                       flock($fp, LOCK_EX);
-                       while (!feof($fp)) {
-                               $line = fgets($fp);
-                               if (strpos($line, "\t") !== false) {
-                                       list($lw, $lt) = explode("\t", $line, 
2);
-                                       $this->timestamps[$lw] = trim($lt);
-                               }
-                       }
-                       fclose($fp);
-               }
-               $this->debug("Read previous data from {$log}");
-               $this->debug('Position is defined for the following wikis: '.
-                       implode(', ', array_keys($this->timestamps)));
-       }
-
-       public function debug($string) {
-               if ($this->stderr) fwrite($this->stderr, "{$string}\n");
-       }
-
-       /* 
-       * Populate the globalimagelinks table from the local imagelinks
-       */
-       public function populateGlobalUsage($wiki, $interval, $throttle = 
1000000, $maxLag) {
-               $this->debug("Populating globalimagelinks on {$wiki}");
-
-               if (!isset($this->namespaces[$wiki]))
-                       $this->fetchNamespaces($wiki);
-               $namespaces = $this->namespaces[$wiki];
-               
-               $dbw = GlobalUsage::getDatabase(DB_MASTER);
-               $dbw->immediateBegin();
-               $dbw->delete('globalimagelinks', array('gil_wiki' => $wiki), 
__METHOD__);
-
-               $dbr = $this->getDatabase($wiki);
-               
-               // Account for slave lag
-               $res = $dbr->select('recentchanges', 'MAX(rc_timestamp) AS 
timestamp');
-               $row = $res->fetchRow();
-               $timestamp = substr(substr($row['timestamp'], 0, 14 - 
$interval).
-                       '00000000000000', 0, 14);
-               $res->free();
-               
-               $prevPage = 0;
-               $prevImage = '';
-               $limit = 2000;
-               do {
-                       $loopStart = microtime(true);
-                       
-                       $sql = 
-                               // Join order is important for sorting
-                               'SELECT STRAIGHT_JOIN '.
-                               'page_id, page_namespace, page_title, il_to, 
img_name IS NOT NULL AS is_local '.
-                               'FROM '.$dbr->tableName('imagelinks').' '.
-                               // MySQL will choose the il_to index from il_to 
> 'O'
-                               // TODO: Doesn't work on the Toolserver
-                               'FORCE INDEX(il_from) '.
-                               'LEFT JOIN '.$dbr->tableName('image').' ON 
il_to = img_name '.
-                               'JOIN '.$dbr->tableName('page').' ON page_id = 
il_from '.
-                               'WHERE il_from >= '.$prevPage.' AND il_to > 
'.$dbr->addQuotes($prevImage).
-                               'ORDER BY il_from, il_to ';
-                       $query = $dbr->limitResult($sql, $limit, 0);
-                       $res = $dbr->query($query, __METHOD__);
-                       
-                       $count = 0;
-                       $rows = array();
-                       while ($row = $res->fetchRow()) {
-                               $count++;
-                               $rows[] = array(
-                                       'gil_wiki' => $wiki,
-                                       'gil_page' => $row['page_id'],
-                                       'gil_page_namespace' => 
$namespaces[$row['page_namespace']],
-                                       'gil_page_title' => $row['page_title'],
-                                       'gil_to' => $row['il_to'],
-                                       'gil_is_local' => $row['is_local']
-                               );
-                               $prevPage = $row['page_id'];
-                               $prevImage = $row['il_to'];
-                       }
-                       $res->free();
-                               
-                       $dbw->insert( 'globalimagelinks', $rows, __METHOD__, 
'IGNORE' );
-                       
-                       $timeTaken = microtime(true) - $loopStart;
-                       $rps = $count / $timeTaken;
-                       $this->debug("Inserted {$count} rows in {$timeTaken} 
seconds; {$rps} rows per second");
-                       if ($rps > $throttle) {
-                               $sleepTime = ($rps / $throttle - 1) * 
$timeTaken;
-                               $this->debug("Throttled {$sleepTime} seconds");
-                               sleep($sleepTime);
-                       }
-                       if ($maxLag) {
-                               $lb = wfGetLB($wiki);
-                               do {
-                                       list($host, $lag) = $lb->getMaxLag();
-                                       if ($lag > $maxLag) {
-                                               $this->debug("Waiting for 
{$host}; lagged {$lag} seconds");
-                                               sleep($lag - $maxLag);
-                                       }
-                               } while ($lag > $maxLag);
-                       }
-               } while ($count == $limit);
-               $dbw->immediateCommit();
-               
-               $this->setTimestamp($wiki, $timestamp);
-       }
-       
-       /*
-       * Populate the globalimagelinks table from the recentchanges
-       */
-       public function processRecentChanges($wiki, $interval = 2) {
-               global $wgDBtype;
-               $dbr = $this->getDatabase($wiki);
-               $dbw = GlobalUsage::getDatabase(DB_MASTER);
-               
-               $tables = array(
-                       'img' => $dbr->tableName('image'),
-                       'il' => $dbr->tableName('imagelinks'),
-                       'log' => $dbr->tableName('logging'),
-                       'page' => $dbr->tableName('page'),
-                       'rc' => $dbr->tableName('recentchanges'),
-               );
-               
-               // Get timestamp
-               $timestamp = substr($this->timestamps[$wiki], 0, 14 - 
$interval);
-
-               $dbw->immediateBegin();
-                       
-               $timestamp_like_rc = $wgDBtype === 'postgres'
-                       ? "TO_CHAR(rc_timestamp, 'YYYYMMDDHH24MISS') = 
'$timestamp'"
-                       : "rc_timestamp LIKE '{$timestamp}%'";
-
-               // Update links on all recentchanges
-               $query = 'SELECT DISTINCT '.
-                       'page_id AS id, rc_namespace AS ns, rc_title AS title '.
-                       "FROM {$tables['rc']}, {$tables['page']} ".
-                       'WHERE page_namespace = rc_namespace AND page_title = 
rc_title '.
-                       'AND rc_namespace <> -1 '.
-                       "AND $timestamp_like_rc";
-                       
-               $res = $dbr->query($query, __METHOD__);
-               
-               $rows = array();
-               while($row = $res->fetchRow())
-                       $rows[] = $row;
-               $res->free();
-               $this->processRows($rows, $wiki, $dbr, $dbw);
-                       
-               $timestamp_like_log = $wgDBtype === 'postgres'
-                       ? "TO_CHAR(log_timestamp, 'YYYYMMDDHH24MISS') = 
'$timestamp'"
-                       : "log_timestamp LIKE '{$timestamp}%'";
-
-               // Update links on deletion or undeletion of an article
-               $query = 'SELECT '.
-                       'page_id AS id, log_namespace AS ns, log_title AS 
title, '.
-                       'page_id IS NOT NULL AS is_local '.
-                       "FROM {$tables['log']} ".
-                       "LEFT JOIN {$tables['page']} ON ".
-                       'page_namespace = log_namespace AND '.
-                       'page_title = log_title '.
-                       "WHERE log_action = 'delete' ".
-                       "AND $timestamp_like_log";
-               
-               $res = $dbr->query($query, __METHOD__);
-                       
-               $rows = array();
-               while($row = $res->fetchRow()) {
-                       if ($row['is_local']) {
-                               $rows[] = $row;
-                       } else {
-                               $dbw->delete( 'globalimagelinks', array(
-                                       'gil_wiki' => $wiki,
-                                       'gil_page' => $row['id'],
-                                       ), __METHOD__);
-                       }
-               }
-               $res->free();
-               $this->processRows($rows, $wiki, $dbr, $dbw);
-               
-               // Set the is_local flag on images
-               $query = 'SELECT DISTINCT '.
-                       'log_title, img_name IS NOT NULL AS is_local '.
-                       "FROM {$tables['log']}, {$tables['il']} ".
-                       "LEFT JOIN {$tables['img']} ON il_to = img_name ".
-                       "WHERE log_namespace = 6 AND log_type IN ('upload', 
'delete') ".
-                       "AND $timestamp_like_log";
-
-               $res = $dbr->query($query, __METHOD__);
-                       
-               while($row = $res->fetchRow()) {
-                       $dbw->update( 'globalimagelinks', 
-                               array( 'gil_is_local' => $row['is_local'] ), 
-                               array(
-                                       'gil_wiki' => $wiki,
-                                       'gil_to' => $row['log_title']
-                               ), 
-                               __METHOD__ );
-               }
-               $res->free();
-                       
-               // Update titles on page move
-               $res = $dbr->select('logging', 
-                       array('log_namespace', 'log_title', 'log_params'),
-                       "log_type = 'move' AND $timestamp_like_log",
-                       __METHOD__);
-                               
-               while($row = $res->fetchRow()) {
-                       $namespace = '';
-                       $title = $row['log_params'];
-                       if (strpos($row['log_params'], ':') !== false) {
-                               $new_title = explode(':', $row['log_params'], 
2);
-                               if (in_array($new_title[0], 
$this->namespaces[$wiki])) {
-                                       list($namespace, $title) = $new_title;
-                               }
-                       }
-                       // FIXME: Unindexed update!
-                       $dbw->update( 'globalimagelinks', array(
-                               'gil_page_namespace' => $namespace,
-                               'gil_page_title' => $title
-                       ), array(
-                               'gil_wiki' => $wiki,
-                               'gil_page_namespace' => $row['log_namespace'],
-                               'gil_page_title' => $row['log_title']
-                       ), __METHOD__ );
-               }
-               $res->free();
-                       
-               $dbw->immediateCommit();
-                       
-               // Set new timestamp
-               $newTs = wfTimestamp(TS_MW, $this->incrementTimestamp(
-                       $this->timestamps[$wiki], $interval));
-               $this->setTimestamp($wiki, $newTs);
-               
-               // Return when this function should be called again
-               $waitUntil = wfTimestamp(TS_MW, 
$this->incrementTimestamp($newTs, $interval));
-               
-               $res = $dbr->select('recentchanges', 'MAX(rc_timestamp) AS r', 
'', __METHOD__);
-               $row = $res->fetchRow();
-               $res->free();
-               return array($waitUntil, $row['r'] > $waitUntil);
-
-       }
-       
-       /* 
-       * Call doUpdate
-       */
-       private function processRows($rows, $wiki, $dbr, $dbw) {
-               if (count($rows)) {
-                       foreach ($rows as $row)
-                               GlobalUsage::doUpdate($row['id'], $wiki,
-                                       $row['ns'], $row['title'], $dbr, $dbw);
-               }
-       }
-       
-       /*
-       * Get namespace names
-       */
-       private function fetchNamespaces($wiki) {
-               global $wgContLang;
-               if ($wiki == GlobalUsage::getLocalInterwiki()) {
-                       $this->namespaces[$wiki] = 
$wgContLang->getFormattedNamespaces();
-               } else {
-                       // Not the current wiki, need to fetch using the API
-                       $this->debug("Fetching namespaces from external wiki 
{$wiki}");
-                       
-                       if (!isset($this->wikiList[$wiki])) {
-                               // Raise error
-                       }
-                       $address = $this->wikiList[$wiki];
-                       $address .= 
'?action=query&meta=siteinfo&siprop=namespaces&format=php';
-                       
-                       $curl = curl_init($address);
-                       curl_setopt($curl, CURLOPT_USERAGENT, 
'GlobalUsage/1.0');
-                       curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
-                       $data = unserialize(curl_exec($curl));
-                       curl_close($curl);
-                       if (!$data) return false;
-                       
-                       $this->namespaces[$wiki] = array();
-                       foreach ($data['query']['namespaces'] as $id => $value) 
-                               $this->namespaces[$wiki][$id] = $value['*'];
-                       return true;
-               }
-       }
-       
-       /* 
-       * Get database object for reading
-       */
-       private function getDatabase($wiki) {
-               if ($wiki == GlobalUsage::getLocalInterwiki())
-                       return wfGetDB(DB_SLAVE);
-               else
-                       return wfGetDB(DB_SLAVE, array(), $wiki);
-       }
-       
-       /* 
-       * Save timestamp to a logfile to continue after
-       */
-       private function setTimestamp($wiki, $timestamp) {
-               $written = false;
-               if (($fp = fopen($this->log, 'r+')) === false) {
-                       // Raise an error
-               }
-               
-               flock($fp, LOCK_EX);
-               fseek($fp, 0, SEEK_SET);
-               while (!feof($fp)) {
-                       $line = fgets($fp);
-                       if (strpos($line, "\t") !== false) {
-                               list($lw, $lt) = explode("\t", $line, 2);
-                               if ($lw == $wiki) {
-                                       fseek($fp, ftell($fp) - 15, SEEK_SET);
-                                       fwrite($fp, $timestamp);
-                                       $written = true;
-                               }
-                       }
-               }
-               if (!$written) fwrite($fp, "{$wiki}\t{$timestamp}\n");
-               fclose($fp);
-               
-               $this->timestamps[$wiki] = $timestamp;
-       }
-       private function incrementTimestamp($timestamp, $interval) {
-               $timestamp = (string)((int)$timestamp + pow(10, $interval));
-               return gmmktime(
-                       substr($timestamp, 8, 2),
-                       substr($timestamp, 10, 2),
-                       substr($timestamp, 12, 2),
-                       substr($timestamp, 4, 2),
-                       substr($timestamp, 6, 2),
-                       substr($timestamp, 0, 4)
-               );
-       }
-       
-       public function runLocalDaemon($wiki, $interval) {
-               $this->debug("Running local daemon on {$wiki}");
-               
-               // Fetch namespaces
-               if (!isset($this->namespaces[$wiki]))
-                       if (!$this->fetchNamespaces($wiki))
-                               die("Could not fetch namespaces for {$wiki}\n");
-               $dbr = $this->getDatabase($wiki);
-                       
-               while (true) {
-                       list($waitUntil, $hasMore) = 
$this->processRecentChanges($wiki, $interval);
-                       while (wfTimestamp(TS_UNIX, $waitUntil) > time() - 
$dbr->getLag()) {
-                               $sleepTime = max(wfTimestamp(TS_UNIX, 
$waitUntil) + $dbr->getLag() - time(), 0);
-                               $this->debug("Sleeping {$sleepTime} seconds: ".
-                                       'need to wait until '.$waitUntil.
-                                       '; now is '.wfTimestamp(TS_MW));
-                               sleep($sleepTime);
-                       }
-               }
-       }
-       public function runDaemon($interval) {
-               $waitUntil = array();
-               
-               foreach ($this->wikiList as $wiki => $info)
-                       $waitUntil[$wiki] = 0;
-               
-               $this->debug("Running GlobalUsage daemon on the following 
wikis: ".
-                       implode(', ', array_keys($waitUntil)));
-               while (true) {
-                       // Sort by time
-                       asort($waitUntil);
-                       reset($waitUntil);
-                       
-                       $dbr = $this->getDatabase(key($waitUntil));
-                       if (current($waitUntil) != 0) {
-                               $waitUntilTime = wfTimestamp(TS_UNIX, 
current($waitUntil));
-                               $lag = $dbr->getLag();
-                               while ($waitUntilTime > time() - $lag) {
-                                       $sleepTime = max($waitUntilTime - 
time() + $lag, 0);
-                                       $this->debug("Sleeping {$sleepTime} 
seconds: ".
-                                               'need to wait until 
'.current($waitUntil).
-                                               '; now is '.wfTimestamp(TS_MW, 
time() - $lag));
-                                       sleep($sleepTime);
-                               }
-                       }
-                       
-                       $wiki = key($waitUntil);
-                       
-                       // Fetch namespaces
-                       if (!isset($this->namespaces[$wiki]))
-                               if (!$this->fetchNamespaces($wiki)) {
-                                       $this->debug("Could not fetch 
namespaces for {$wiki}");
-                                       unset($waitUntil[$wiki]);
-                                       continue;
-                               }
-                       
-                       $this->debug("Processing recentchanges for {$wiki}");
-                       $now = time();
-                       list($waitUntil[$wiki], $hasMore) = 
$this->processRecentChanges($wiki, $interval);
-                       if (!$hasMore) {
-                               // There are no more entries. Set the timestamp 
to *now* to avoid locking
-                               // of other wikis by rarely updated wikis
-                               $next = substr(substr(wfTimestamp(TS_MW, $now - 
$dbr->getLag()),
-                                       0, 14 - $interval).'00000000000000', 0, 
14);
-                               $waitUntil[$wiki] = wfTimestamp(TS_MW, 
$this->incrementTimestamp($next, $interval));
-                       }
-               }
-       }
-}

Added: trunk/extensions/GlobalUsage/GlobalUsageHooks.php
===================================================================
--- trunk/extensions/GlobalUsage/GlobalUsageHooks.php                           
(rev 0)
+++ trunk/extensions/GlobalUsage/GlobalUsageHooks.php   2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -0,0 +1,78 @@
+<?php
+class GlobalUsageHooks {
+       private static $gu = null;
+       
+       /**
+        * Hook to LinksUpdateComplete
+        * Deletes old links from usage table and insert new ones.
+        */
+       public static function onLinksUpdate( $linksUpdater ) {
+               $title = $linksUpdater->getTitle();
+               
+               // Create a list of locally existing images
+               $images = array_keys( $linksUpdater->getExistingImages() );
+               $localFiles = array_keys( 
RepoGroup::singleton()->getLocalRepo()->findFiles( $images ) );
+               
+               $gu = self::getGlobalUsage();
+               $gu->deleteFrom( $title->getArticleId( GAID_FOR_UPDATE ) );
+               $gu->setUsage( $title, array_diff( $images, $localFiles ) );
+               
+               return true;
+       }
+       /**
+        * Hook to TitleMoveComplete
+        * Sets the page title in usage table to the new name.
+        */
+       public static function onTitleMove( $ot, $nt, $user, $pageid, $redirid 
) {
+               $gu = self::getGlobalUsage();
+               $gu->moveTo( $pageid, $nt );
+               return true;
+       }
+       /**
+        * Hook to ArticleDeleteComplete
+        * Deletes entries from usage table.
+        * In case of an image, copies the local link table to the global.
+        */
+       public static function onArticleDelete( $article, $user, $reason ) {
+               $title = $article->getTitle();
+               $gu = self::getGlobalUsage();
+               $gu->deleteFrom( $title->getArticleId( GAID_FOR_UPDATE ) );
+               if ( $title->getNamespace() == NS_FILE ) {
+                       $gu->copyFromLocal( $title );
+               }
+               return true;
+       }
+
+       /**
+        * Hook to FileUndeleteComplete
+        * Deletes the file from the global link table.
+        */
+       public static function onFileUndelete( $title, $versions, $user, 
$reason ) { 
+               $gu = self::getGlobalUsage();
+               $gu->deleteTo( $title );
+               return true;
+       }
+       /**
+        * Hook to UploadComplete
+        * Deletes the file from the global link table.
+        */
+       public static function onUpload( $upload ) {
+               $gu = self::getGlobalUsage();
+               $gu->deleteTo( $upload->getTitle() );
+               return true;
+       }
+       
+       /**
+        * Initializes a GlobalUsage object for the current wiki.
+        */
+       private static function getGlobalUsage() {
+               global $wgLocalInterwiki, $wgGlobalUsageDatabase;
+               if ( is_null( self::$gu ) ) {
+                       self::$gu = new GlobalUsage( $wgLocalInterwiki, 
+                                       wfGetDB( DB_MASTER, array(), 
$wgGlobalUsageDatabase ) 
+                       );
+               }
+               
+               return self::$gu;
+       }
+}
\ No newline at end of file


Property changes on: trunk/extensions/GlobalUsage/GlobalUsageHooks.php
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: trunk/extensions/GlobalUsage/GlobalUsage_body.php
===================================================================
--- trunk/extensions/GlobalUsage/GlobalUsage_body.php   2009-09-11 18:22:33 UTC 
(rev 56200)
+++ trunk/extensions/GlobalUsage/GlobalUsage_body.php   2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -1,185 +1,121 @@
 <?php
 
-class GlobalUsage extends SpecialPage {
-       private static $database = array();
-       private static $interwiki = null;
+class GlobalUsage {
+       private $interwiki;
+       private $db;
 
-       function __construct() {
-               parent::__construct('GlobalUsage');
-               wfLoadExtensionMessages( 'GlobalUsage' );
+       /**
+        * Construct a GlobalUsage instance for a certain wiki.
+        * 
+        * @param $interwiki string Interwiki prefix of the wiki
+        * @param $db mixed Database object
+        */
+       public function __construct( $interwiki, $db ) {
+               $this->interwiki = $interwiki;
+               $this->db = $db;
        }
        
-       static function getDatabase( $dbFlags = DB_MASTER ) {
-               global $wgguIsMaster, $wgguMasterDatabase;
-               if ( !isset( self::$database[$dbFlags] ) )
-                       self::$database[$dbFlags] = wfGetDB( $dbFlags, array(), 
$wgguMasterDatabase );
-               return self::$database[$dbFlags];
-       }
-       static function getLocalInterwiki() {
-               global $wgguInterwikiStyle, $wgLocalInterwiki, $wgServerName;
-               if (!self::$interwiki) {
-                       switch ($wgguInterwikiStyle) {
-                               case GUIW_LOCAL:
-                                       self::$interwiki = $wgLocalInterwiki;
-                                       break;
-                               case GUIW_SERVER_NAME:
-                                       self::$interwiki = $wgServerName;
-                                       break;
-                               default:
-                                       self::$interwiki = $wgLocalInterwiki;
-                       }
+       /**
+        * Sets the images used by a certain page
+        * 
+        * @param $title Title Title of the page
+        * @param $images array Array of db keys of images used
+        */
+       public function setUsage( $title, $images ) {
+               $insert = array();
+               foreach ( $images as $name ) {
+                       $insert[] = array(
+                               'gil_wiki' => $this->interwiki,
+                               'gil_page' => $title->getArticleID( 
GAID_FOR_UPDATE ),
+                               'gil_page_namespace' => $title->getNsText(),
+                               'gil_page_title' => $title->getText(),
+                               'gil_to' => $name
+                       );
                }
-               return self::$interwiki;
+               $this->db->insert( 'globalimagelinks', $insert, __METHOD__ );
        }
-       
-       static function updateLinks( $linksUpdater ) {
-               $title = $linksUpdater->getTitle();
-               $dbr = wfGetDB(DB_SLAVE);
-               $dbw = self::getDatabase();
-               $dbw->immediateBegin();
-               self::doUpdate($title->getArticleID(), 
self::getLocalInterwiki(),
-                       $title->getNsText(), $title->getDBkey(), $dbr, $dbw );
-               $dbw->immediateCommit();
-               
-               return true;
+       /**
+        * Deletes all entries from a certain page
+        * 
+        * @param $id int Page id of the page
+        */
+       public function deleteFrom( $id ) {
+               $this->db->delete(
+                               'globalimagelinks',
+                               array(
+                                       'gil_wiki' => $this->interwiki,
+                                       'gil_page' => $id
+                               ),
+                               __METHOD__
+               );
        }
+       /**
+        * Deletes all entries to a certain image
+        * 
+        * @param $title Title Title of the file
+        */
+       public function deleteTo( $title ) {
+               $this->db->delete(
+                               'globalimagelinks',
+                               array(
+                                       'gil_wiki' => $this->interwiki,
+                                       'gil_to' => $title->getDBkey()
+                               ),
+                               __METHOD__
+               );              
+       }
        
-       /*
-        * Perform the update for a certain page on a certain database. The 
caller is
-        * responsible for creating a master datbase object and performing 
-        * immediateBegin() and immediateCommit().
+       /**
+        * Copy local links to global table
+        * 
+        * @param $title Title Title of the file to copy entries from.
         */
-       static function doUpdate( $pageId, $wiki, $pageNamespace, $pageTitle, 
-                       &$dbr, &$dbw ) {
-               $query = 'SELECT il_to, img_name IS NOT NULL AS is_local '.
-                       'FROM '.$dbr->tableName('imagelinks').' '.
-                       'LEFT JOIN '.$dbr->tableName('image').' ON '. 
-                       'il_to = img_name WHERE il_from = '.$pageId;
-               $res = $dbr->query($query, __METHOD__);
+       public function copyFromLocal( $title ) {
+               global $wgContLang;
                
-               $rows = array();
-               while ($row = $res->fetchRow()) {
-                       $rows[] = array(
-                               "gil_wiki" => $wiki, 
-                               "gil_page" => $pageId,
-                               "gil_page_namespace" => $pageNamespace,
-                               "gil_page_title" => $pageTitle,
-                               "gil_to" => $row['il_to'],
-                               "gil_is_local" => $row['is_local']);
+               $dbr = wfGetDB( DB_SLAVE );
+               $res = $dbr->select( 
+                               array( 'imagelinks', 'page' ), 
+                               array( 'il_to', 'page_id', 'page_namespace', 
'page_title' ),
+                               array( 'il_from = page_id', 'il_to' => 
$title->getDBkey() ),
+                               __METHOD__
+               );
+               $insert = array();
+               foreach ( $res as $row ) {
+                       $insert[] = array(
+                               'gil_wiki' => $this->interwiki,
+                               'gil_page' => $row->page_id,
+                               'gil_page_namespace' => $wgContLang->getNsText( 
$row->page_namespace ),
+                               'gil_page_title' => $row->page_title,
+                               'gil_to' => $row->il_to,
+                       );
                }
-               $res->free();
-               
-               $dbw->delete('globalimagelinks', array(
-                       'gil_wiki' => $wiki, 'gil_page' => $pageId),
-                       __METHOD__);
-               $dbw->insert( 'globalimagelinks', $rows, __METHOD__, 'IGNORE' );
+               $this->db->insert( 'globalimagelinks', $insert, __METHOD__ );
        }
        
-       
-       // Set gil_is_local for an image
-       static function setLocalFlag( $imageName, $isLocal ) {
-               $dbw = self::getDatabase();
-               $dbw->immediateBegin();
-               $dbw->update( 'globalimagelinks', array( 'gil_is_local' => 
$isLocal ), array(
-                               'gil_wiki' => self::getLocalInterwiki(),
-                               'gil_to' => $imageName),
-                       __METHOD__ );
-               $dbw->immediateCommit();
+       /**
+        * Changes the page title
+        * 
+        * @param $id int Page id of the page
+        * @param $title Title New title of the page
+        */
+       public function moveTo( $id, $title ) {
+               $this->db->update(
+                               'globalimagelinks',
+                               array( 
+                                       'gil_page_namespace' => 
$title->getNsText(),
+                                       'gil_page_title' => $title->getText()
+                               ),
+                               array(
+                                       'gil_wiki' => $this->interwiki,
+                                       'gil_page' => $id
+                               ),
+                               __METHOD__
+               );
        }
        
-       // Set gil_is_local to false
-       static function fileDeleted( &$file, &$oldimage, &$article, &$user, 
$reason ) {
-               if ( !$oldimage ) 
-                       self::setLocalFlag( $article->getTitle()->getDBkey(), 0 
);
-               return true;
-       }
-       // Set gil_is_local to true
-       static function fileUndeleted( &$title, $versions, &$user, $reason ) {
-               self::setLocalFlag( $title->getDBkey(), 1 );
-               return true;
-       }
-       static function imageUploaded( $uploadForm ) {
-               $imageName = $uploadForm->mLocalFile->getTitle()->getDBkey();   
        
-               self::setLocalFlag( $imageName, 1 );
-               return true;            
-       }       
        
-               
-       static function articleDeleted( &$article, &$user, $reason ) {
-               $dbw = self::getDatabase();
-               $dbw->immediateBegin();
-               $dbw->delete( 'globalimagelinks', array(
-                               'gil_wiki' => self::getLocalInterwiki(),
-                               // Use GAID_FOR_UPDATE to make sure the old id 
is fetched from 
-                               // the link cache
-                               'gil_page' => 
$article->getTitle()->getArticleId(GAID_FOR_UPDATE)),
-                       __METHOD__ );
-               $dbw->immediateCommit();
-               
-               return true;
-       }
        
-       static function articleMoved( &$movePageForm, &$from, &$to ) {
-               $dbw = self::getDatabase();
-               $dbw->immediateBegin();
-               $dbw->update( 'globalimagelinks', array(
-                               'gil_page_namespace' => $to->getNsText(),
-                               'gil_page_title' => $to->getDBkey()
-                       ), array(
-                               'gil_wiki' => self::getLocalInterwiki(),
-                               'gil_page' => $to->getArticleId()
-                       ), __METHOD__ );
-               $dbw->immediateCommit();
-               
-               return true;
-       }
 
-       public function execute( $par ) {       
-               global $wgOut, $wgScript, $wgRequest;
-               
-               $this->setHeaders();
-               
-               $self = Title::makeTitle( NS_SPECIAL, 'GlobalUsage' );
-               $target= Title::makeTitleSafe( NS_IMAGE, $wgRequest->getText( 
'target', $par ) );
-               
-               $wgOut->addWikiText( wfMsg( 'globalusage-text' ) );
-               
-               $form = Xml::openElement( 'form', array( 
-                       'id' => 'mw-globalusage-form',
-                       'method' => 'get', 
-                       'action' => $wgScript ));
-               $form .= Xml::hidden( 'title', $self->getPrefixedDbKey() );
-               $form .= Xml::openElement( 'fieldset' );
-               $form .= Xml::element( 'legend', array(), wfMsg( 'globalusage' 
));
-               $form .= Xml::inputLabel( wfMsg( 'filename' ), 'target', 
-                       'target', 50, $target->getDBkey() );
-               $form .= Xml::submitButton( wfMsg( 'globalusage-ok' ) );
-               $form .= Xml::closeElement( 'fieldset' );
-               $form .= Xml::closeElement( 'form' );
-               
-               $wgOut->addHTML( $form );
-               
-               if ( !$target->getDBkey() ) return;
-               
-               $dbr = self::getDatabase( DB_SLAVE );
-               $res = $dbr->select( 'globalimagelinks',
-                       array( 'gil_wiki', 'gil_page_namespace', 
'gil_page_title' ),
-                       array( 'gil_to' => $target->getDBkey(), 'gil_is_local' 
=> 0 ),
-                       __METHOD__ );
-                       
-               // Quick dirty list output
-               while ( $row = $dbr->fetchObject($res) )
-                       $wgOut->addWikiText(self::formatItem( $row ) );
-               $dbr->freeResult($res);
-       }
-       
-       public static function formatItem( $row ) {
-               $out = '* [[';
-               if ( self::getLocalInterwiki() != $row->gil_wiki )
-                       $out .= ':'.$row->gil_wiki;
-               if ( $row->gil_page_namespace )
-                       $out .= ':'.str_replace('_', ' ', 
$row->gil_page_namespace);
-               $out .= ':'.str_replace('_', ' ', $row->gil_page_title)."]]\n";
-               return $out;
-       }
+
 }

Added: trunk/extensions/GlobalUsage/SpecialGlobalUsage.php
===================================================================
--- trunk/extensions/GlobalUsage/SpecialGlobalUsage.php                         
(rev 0)
+++ trunk/extensions/GlobalUsage/SpecialGlobalUsage.php 2009-09-11 18:28:25 UTC 
(rev 56201)
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Crappy ui towards globalimagelinks
+ */
+
+class SpecialGlobalUsage extends SpecialPage {
+       public function __construct() {
+               parent::__construct( 'GlobalUsage', 'globalusage' );
+               
+               wfLoadExtensionMessages( 'globalusage' );
+       } 
+       
+       public function execute( $par ) {
+               global $wgOut, $wgRequest;
+               
+               $target = $par ? $par : $wgRequest->getVal( 'target' );
+               $title = Title::newFromText( $target, NS_FILE );
+               
+               $this->setHeaders();
+               
+               if ( is_null( $title ) )
+               {
+                       $wgOut->setPageTitle( wfMsg( 'globalusage' ) );
+                       return;                 
+               }
+               
+               $wgOut->setPageTitle( wfMsg( 'globalusage-for', 
$title->getPrefixedText() ) );
+               
+               $pager = new GlobalUsagePager( $title );
+               
+               $wgOut->addHTML(
+                       '<p>' . $pager->getNavigationBar() . '</p>' .
+                       '<ul>' . $pager->getBody() . '</ul>' .
+                       '<p>' . $pager->getNavigationBar() . '</p>' );
+       }
+}
+
+/**
+ * Pager for globalimagelinks.
+ */
+class GlobalUsagePager extends IndexPager {
+       public function __construct( $title = null ) {
+               // Initialize parent first
+               parent::__construct();
+               
+               $this->title = $title;
+               
+               // Override the DB
+               global $wgGlobalUsageDatabase;
+               $this->mDb = wfGetDB( DB_SLAVE, array(), $wgGlobalUsageDatabase 
);
+       }
+       public function formatRow( $row ) {
+               return '<li>'
+                               . htmlspecialchars( $row->gil_wiki ) . ':'
+                               . htmlspecialchars( $row->gil_page_namespace ) 
. ':'
+                               . htmlspecialchars( $row->gil_page_title ) 
+                               . "</li>\n";
+       }
+       public function getQueryInfo() {
+               $info = array(
+                               'tables' => array( 'globalimagelinks' ),
+                               'fields' => array( 
+                                               'gil_wiki', 
+                                               'gil_page_namespace', 
+                                               'gil_page_title', 
+                               ),      
+               );
+               if ( !is_null( $this->title ) && $this->title->getNamespace() 
== NS_FILE ) {
+                       $info['conds'] = array( 'gil_to' => 
$this->title->getDBkey() );
+               }
+               return $info;
+       }
+       public function getIndexField() {
+               // FIXME: This is non-unique! Needs a hack in IndexPager to 
sort on (wiki, page)
+               return 'gil_wiki';
+       }
+
+       
+       public function getNavigationBar() {
+               global $wgLang;
+
+               if ( isset( $this->mNavigationBar ) ) {
+                       return $this->mNavigationBar;
+               }
+               $fmtLimit = $wgLang->formatNum( $this->mLimit );
+               $linkTexts = array(
+                       'prev' => wfMsgExt( 'whatlinkshere-prev', array( 
'escape', 'parsemag' ), $fmtLimit ),
+                       'next' => wfMsgExt( 'whatlinkshere-next', array( 
'escape', 'parsemag' ), $fmtLimit ),
+                       'first' => wfMsgHtml( 'page_first' ),
+                       'last' => wfMsgHtml( 'page_last' )
+               );
+
+               $pagingLinks = $this->getPagingLinks( $linkTexts );
+               $limitLinks = $this->getLimitLinks();
+               $limits = $wgLang->pipeList( $limitLinks );
+
+               $this->mNavigationBar = "(" . $wgLang->pipeList( array( 
$pagingLinks['first'], $pagingLinks['last'] ) ) . ") " .
+                       wfMsgExt( 'viewprevnext', array( 'parsemag', 'escape', 
'replaceafter' ), $pagingLinks['prev'], $pagingLinks['next'], $limits );
+               return $this->mNavigationBar;
+       }
+}
\ No newline at end of file


Property changes on: trunk/extensions/GlobalUsage/SpecialGlobalUsage.php
___________________________________________________________________
Added: svn:eol-style
   + native

Deleted: trunk/extensions/GlobalUsage/populateGlobalUsage.php
===================================================================
--- trunk/extensions/GlobalUsage/populateGlobalUsage.php        2009-09-11 
18:22:33 UTC (rev 56200)
+++ trunk/extensions/GlobalUsage/populateGlobalUsage.php        2009-09-11 
18:28:25 UTC (rev 56201)
@@ -1,116 +0,0 @@
-<?php
-
-$wgguWikiList = array();
-
-$optionsWithArgs = array( 'wiki', 'interval', 'log', 'throttle' );
-
-require_once 'maintenance/commandLine.inc';
-require_once 'extensions/GlobalUsage/GlobalUsage.php';
-require_once 'extensions/GlobalUsage/GlobalUsage_body.php';
-require_once 'extensions/GlobalUsage/GlobalUsageDaemon.php';
-
-/*
- * We might want to use stdout later to to output useful data, so output error
- * messages to stderr where they belong.
- */
-function dieInit($msg, $exitCode = 1) {
-       $fp = fopen('php://stderr', 'w');
-       fwrite($fp, $msg);
-       fwrite($fp, "\n");
-       fclose($fp);
-       exit($exitCode);
-}
-
-if(isset($options['help']) || !isset($options['log']))
-       dieInit(
-"This script will populate the GlobalUsage table from the local imagelinks 
-table. It will then continue to keep the table up to data using the logging 
-and recentchanges tables.
-
-Usage:
-       php extensions/GlobalUsage/populateGlobalUsage.inc --log <file>
-               [--wiki <wiki>] [--interval <interval>] [--daemon]
-               [--verbose] [--help]
-               
-       --log           File to log current timestamp to
-       
-       --wiki          The wiki to populate from. If this is equal to 
-                       \$wgLocalInterwiki the database settings will be read
-                       from LocalSettings.php. If this is not equal, a config
-                       variable \$wgguWikiList[\$wiki] is expected with the 
-                       url of the API entry point.
-       --interval      Pull interval in powers of 10.
-       --throttle      Maximum number of rows per second the populator is
-                       allowed to insert.
-       --wait-for-slaves
-                       Seconds to wait for slaves. Default 0, disabled.
-       
-       --daemon        Run as daemon processing all wikis in \$wgguWikiList.
-                       Useful when the extension can't be installed.
-       --no-daemon     Does not run a daemon after population
-       
-       --silent        Don't print information to stderr
-       --help          Show this help
-", 
-       // Only exit with code 0 when no actual error occured
-       intval(!isset($options['help'])));
-
-$defaults = array(
-       'wiki' => GlobalUsage::getLocalInterwiki(),
-       'interval' => 2,
-       'daemon' => false,
-       'no-daemon' => false,
-       'silent' => false,
-       'throttle' => 1000000,
-       'wait-for-slaves' => 0,
-);
-
-$options = array_merge( $defaults, $options );
-
-/*
- * Check whether the passed parameters are sane
- */
-
-// Check whether the log file is writable
-if (!touch($options['log']))
-       dieInit("Unable to modify {$options['log']}");
-
-// Check whether the specified wiki is known
-if ($options['wiki'] != GlobalUsage::getLocalInterwiki()
-               && !isset($wgguWikiList[$options['wiki']])
-               && !$options['daemon'])
-       dieInit("Unknown wiki '{$options['wiki']}' in \$wgguWikiList");
-       
-// Check whether interval is within bounds
-$options['interval'] = intval($options['interval']);
-if ($options['interval'] < 1 || $options['interval'] > 13)
-       dieInit("Interval must be at > 0 and < 14");
-
-// Check the throttle
-$options['throttle'] = intval($options['throttle']);
-if ($options['throttle'] < 1)
-       dieInit("Throttle must be >= 1");
-
-if (!$options['daemon']) {
-       // Remove all but the specified wiki
-       $wgguWikiList = array($options['wiki'] => 
$wgguWikiList[$options['wiki']]);
-}
-
-// Create the daemon object
-$daemon = new GlobalUsageDaemon($options['log'], $wgguWikiList, 
$options['silent']);
-
-// Populate all unpopulated wikis
-foreach($wgguWikiList as $wiki => $info) {
-       if (!isset($daemon->timestamps[$wiki]))
-               $daemon->populateGlobalUsage($wiki, $options['interval'], 
-                       $options['throttle'], 
intval($options['wait-for-slaves']));
-}
-
-// Run the daemon
-if ($options['no-daemon']) exit(0);
-if ($options['daemon'])
-       $daemon->runDaemon($options['interval']);
-else
-       $daemon->runLocalDaemon($options['wiki'], $options['interval']);
-
-// This point is never reached
\ No newline at end of file

Modified: trunk/extensions/GlobalUsage/readme.txt
===================================================================
--- trunk/extensions/GlobalUsage/readme.txt     2009-09-11 18:22:33 UTC (rev 
56200)
+++ trunk/extensions/GlobalUsage/readme.txt     2009-09-11 18:28:25 UTC (rev 
56201)
@@ -11,21 +11,4 @@
 may use different namespaces, the namespace name needs to be included in the 
 link as well.
 
-There should be one globalimagelinks table per farm, even if multiple shared
-image repositories are used. The field gil_is_local indicates whether the file
-exists locally.
 
-== GlobalUsageDaemon and populating the table ==
-This extension provides a daemon which can be used when for some reason hooks
-can not be used, like on the Toolserver. This daemon will readout recentchanges
-to fill the globalimagelinks table.
-
-This daemon is also useful for populating the globalimagelinks table. Using
-this method it is possible to get an as consistent as posible database. To do
-so first create the table on the master wiki. Then, on each project separately:
-* Run extensions/GlobalUsage/populateGlobalUsage.php on that wiki. See
-  php extensions/GlobalUsage/populateGlobalUsage.php --help for information.
-* When the daemon has finished populating the table from the local imagelinks
-  and started to follow recentchanges, enable the extension.
-* When the daemon has reached the time at which the extension was enabled, 
-  the daemon can be stopped.
\ No newline at end of file



_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to