root > WikiSense-trunk > web > CheckUsage.php

CheckUsage.php

application/x-php, 35584 bytes (load raw)
<?php

/*
CheckUsage.php, checks where images located on the Wikimedia Commons
are used in other Wikimedia projects. Inspired by scripts originally
written by Avatar and Arnomane.

Copyright (C) 2005, Daniel Kinzler aka Duesentrieb, brightbyte.de

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/


define("WS_WEB",true);
require_once( "common/WebInit.php" );
require_once( "WikiSenseLocalizer.php" );
require_once( "WikiAccess.php" );

function getImageInfo( $image, $wiki, &$db ) {
  $dbname= $wiki->dbname;
 
  $timage= "$dbname.image";
 
  if (is_array($image)) {
      $img= makeSqlSet($image, $db);

      $sql = "SELECT * FROM $timage
              WHERE img_name IN $img"
;
  }
  else { 
      $sql = "SELECT * FROM $timage
              WHERE img_name = "
. $db->addQuotes($image);
  }
 
  $res= $db->query($sql, 'getImageInfo');
 
  if (is_array($image)) {
      $info= array();
     
      while ($i= $db->fetchObject( $res )) {
          if (@$wiki->is_broken && $i) $i->is_broken= true;
          $info[$i->img_name]= $i;
      }
  }
  else {
      $info= $db->fetchObject( $res );
      if (@$wiki->is_broken && $info) $info->is_broken= true;
         
      if ( !$info ) $info= false;
  }
 
  $db->freeResult( $res );
 
  return $info;
}

function makeSqlSet($values, &$db) {
    $s= "";
    foreach ($values as $v) {
        if ($s) $s.= ", ";
        $s.= $db->addQuotes($v);
    }
   
    $s= "( $s )";
    return $s;
}

define('IMAGE_USAGE_LIMIT',100);
define('RAW_IMAGE_USAGE_LIMIT',5000); #FIXME: this is sometimes too much!

#TODO: make the limits above configurable via URL
#TODO: make it possible to ignore usage on commons

/**
* Uses query.php to fetch usage info from wikis without an up-to-date database
* Thanks to Magnus Manske for the idea
*/

function getImageUsageLive( $image, &$wiki, $filter = NULL ) {
    global $wsgFileNamespace;

    $img= $image;
    if (is_string($img)) $img= explode('|', $img);
   
    $bulk= is_array($image);
   
    $img= $wsgFileNamespace.':'.implode('|'.$wsgFileNamespace.':', $img);
   
    $u = "http://{$wiki->domain}{$wiki->script_path}query.php?format=php&what=imagelinks&illimit={$GLOBALS['usageLimit']}&titles=" . urlencodeTitle( $img ) ;
   
    $data= file_get_contents($u); #TODO: use CURL here to bypass as many squids as possible! (use WikiBot?!)
    if (!$data) {
        print "<p class='error'>Failed to fetch $u!</p>";
        return false;
    }
   
    $data= unserialize($data);
    if (!$data) {
        print "<p class='error'>Failed to unserialize data from $u (broken)!</p>";
        return false;
    }
   
    if (@$data['error']) {
        print "<p class='error'>$u returned Error: ".escapeHtml(@$data['error']['*'])."</p>";
        return false;
    }
   
    if (!@$data['pages']) {
        print "<p class='error'>Failed to unserialize data from $u (strange)!</p>";
        print "<!-- "; print_r($data); print " -->";
        return false;
    }
   
    $usage= array();
   
    foreach ( $data['pages'] as $image ) {
        if (!isset($image['ns']) || $image['ns']!=6) continue;
        if (isset($image['refid'])) continue;
        if (!@$image['imagelinks']) continue;
       
        list( $dummy, $i )= explode(':', $image['title'], 2);
        $i= str_replace(' ','_',$i);
       
        foreach ( $image['imagelinks'] as $pg ) {
            $t= $pg['*'];
            $t= str_replace(' ','_',$t);
            #FIXME: apply filter here!!! <--------------------------------------------------
           
            if ($bulk) {
                if (!isset($usage[$t])) $usage[$t]= array();
                $usage[$t][]= $i;
            }
            else $usage[]= $t;
        }
    }
   
    if ($bulk) {
        $urecords= array();
       
        foreach ($usage as $t => $imgs) {
            $urecords[]= array(
              'page' => $t,
              'images' => $imgs
            );
        }
       
        return $urecords;
    }
    else {
        return $usage;
    }
}

function getImageUsage( $image, &$wiki, &$db, $filter = NULL ) {
  global $wgCanonicalNamespaceNames; #HACK!
 
  if (@$GLOBALS['wsgLiveUsageFallback'] && @$wiki->is_broken) {
      return getImageUsageLive($image, $wiki, $filter);
  }

  $dbname= $wiki->dbname;
  $domain= $wiki->domain;
 
  $timagelinks= "$dbname.imagelinks";
  $tpage= "$dbname.page";
 
  $where= "";
 
  if ($filter=='notalk') $where= ' AND (page_namespace % 2) = 0';
  else if ($filter=='main') $where= ' AND page_namespace = 0';
 
  if (is_array($image)) {
      $img= makeSqlSet($image, $db);
 
      $sql = "SELECT page_title, page_namespace,
                     GROUP_CONCAT(DISTINCT il_to SEPARATOR '|') as images
              FROM $timagelinks
              JOIN $tpage ON page_id = il_from
              WHERE il_to in $img
                    $where
              GROUP BY page_namespace, page_title
              ORDER BY page_namespace, page_title
              LIMIT "
. (int)$GLOBALS['usageLimit'];
  }
  else {
      if (strpos($image,'|')!==false) {
          $where= "il_to in " . makeSqlSet( explode('|',$image), $db )." ".$where;
      }
      else {
          $where= "il_to = " . $db->addQuotes($image)." ".$where;
      }
 
      $sql = "SELECT page_title, page_namespace
              FROM $timagelinks
              JOIN $tpage ON page_id = il_from
              WHERE $where
              ORDER BY page_namespace, page_title
              LIMIT "
. (int)$GLOBALS['usageLimit'];
  }
 
  $res= $db->query($sql, 'getImageUsage');
 
  $usage= array();
 
  while ($p= $db->fetchObject( $res )) {
    $t= $p->page_title;
   
    if ( $p->page_namespace ) {
      $ns= @$wgCanonicalNamespaceNames[$p->page_namespace];
      if (!$ns) $ns= getCustomNsText( $domain, $p->page_namespace, true );
     
      if ($ns) $t= "$ns:$t";
      else $t= $p->page_namespace.":$t"; #FIXME: use toolserver-db to resolve custom namespaces
    }

    if (isset($p->images)) {
        $usage[]= array(
            'page' => $t,
            'images' => explode('|', $p->images)
        );
    }
    else {
        $usage[]= $t;
    }
  }
 
  $db->freeResult( $res );
 
  return $usage;
}

function checkWiki( $image, $commonsInfo, &$wiki, &$db, $filter = NULL, $raw = false ) {
    if ($wiki->is_broken && !@$GLOBALS['wsgLiveUsageFallback']) {
        $usage= "*broken*";
        $info= "*broken*";
    }
    else if (!$wiki->ucFirst) {
        #require_once('WikiAccess.php');
   
        if (is_array($image)) {
            $cinf= array();
            $img= array();
       
            for($i=0; $i<sizeof($image); $i+= 1) {
                $x= $image[$i];
                $c= @$commonsInfo[$x];
               
                $ux= WikiAccess::ucfirst($x);
                $lx= WikiAccess::lcfirst($x);
               
                $img[]= $ux;
                $img[]= $lx;
               
                $cinf[$ux]= $c;
                $cinf[$lx]= $c;
            }
           
            $image= $img;
            $commonsInfo= $cinf;
        }
        else {
            $ux= WikiAccess::ucfirst($image);
            $lx= WikiAccess::lcfirst($image);
           
            $uinf= getImageInfo($ux, $wiki, $db);
            $linf= getImageInfo($ux, $wiki, $db);
           
            if (!$uinf && !$linf) {
                #NOTE: don't use bulk mode!
               
                $info= false;
                $usage= getImageUsage("$ux|$lx", $wiki, $db, $filter); #HACK: magic syntax for unified usage!
            }
            else {
                $image= array(
                    $ux,
                    $lx,
                );
               
                $commonsInfo= array(
                    $ux => $commonsInfo,
                    $lx => $commonsInfo,
                );
               
                $info= array(
                    $ux => $uinf,
                    $lx => $linf,
                );
            }
        }
    }
   
    if (!isset($info)) $info= getImageInfo($image, $wiki, $db);
    if (!isset($usage)) $usage= getImageUsage($image, $wiki, $db, $filter);
   
    if ($db->errorCount()) {
        print "<p class='error'>Failed to access DB {$wiki->dbname}!</p>";
        continue;
    }
   
    if (is_string($usage)) $used= printBrokenWiki($wiki->domain, $image, $raw);
    else if (is_array($info)) $used= printBulkUsage($wiki->domain, $image, $usage, $info, $commonsInfo, $raw);
    else $used= printUsage($wiki->domain, $image, $usage, $info, $commonsInfo, $raw);
   
    flush();
   
    return $used;
}


$cuConnections = array();

function cuGetConnection( $wiki ) {
        global $cuConnections;

        if (isset($wiki->server)) $id = $wiki->server;
        else if (isset($wiki->dbServerId)) $id = $wiki->dbServerId;
        else $id = 0;

        if (isset($cuConnections[$id])) {
                return $cuConnections[$id];
        }
        else {
                $db = openConnection( $wiki->dbURL );

                if ($db) {
                        #print "<p>connected to $id#{$wiki->dbname}: {$wiki->dbURL}</p>";
                        $cuConnections[$id] = $db;
                }
                else {
                        /*if ($raw) print "##ERROR: Failed to connect to DB {$commons->dbname}!\n";
                        else*/
print "<p class='error'>Failed to connect to DB {$wiki->dbname}!</p>";
                }

                #TODO: ignore errors??
                return $db;
        }
}

function cuCloseConnections() {
        global $cuConnections;

        foreach ( $cuConnections as $db ) {
                $db->close();
        }

        $cuConnections = array();
}

function checkUsage( $image, $wikis, $filter = NULL, $raw = false ) {

  $pages= 0;
  $projects= 0;
  $searched= 0;
  $broken= 0;
 
  #check for the image on the commons
  $commons= WikiAccess::newInstance('commons.wikimedia.org');
 
/*
  $db=& openConnection($commons->dbURL);
  if (!$db) {
      if ($raw) print "##ERROR: Failed to connect to DB {$commons->dbname}!\n";
      else print "<p class='error'>Failed to connect to DB {$commons->dbname}!</p>";
      return NULL; #TODO: error message
  }
  $db->ignoreErrors( true );

*/
 

  $commonsDB = cuGetConnection($commons);
  if (!$commonsDB) {
      if (!$raw) print "<div class='error'>Failed to connect to commons database!</div>";
      //wsfLog("Failed to connect to commons database!" , LL_NORMAL );
      return false;
  }

  $commonsInfo= getImageInfo($image, $commons, $commonsDB);
 
  if (!$raw && $commonsInfo && !is_array($image)) {
      $thumb= $commons->getThumbnailHTML($commonsInfo);
      print "<div class='thumbnail' style='float:right'>$thumb</div>";
  }
 
  $usage= $commonsInfo ? getImageUsage($image, $commons, $commonsDB, $filter) : NULL;
 
  if (is_array($image)) printBulkUsage('commons.wikimedia.org', $image, $usage, $commonsInfo, NULL, $raw);
  else printUsage('commons.wikimedia.org', $image, $usage, $commonsInfo, NULL, $raw);

  if ($usage) {
      $pages+= sizeof($usage);
      $projects+= 1;
  }
 
  $searched+= 1;
  $atleast= false;
   
  #check in every wiki in the list
  foreach ( $wikis as $w ) {
    if ($w->domain == 'commons.wikimedia.org') continue;

    if (!$raw) print "\n".'<script type="text/javascript">setProgress("scanning '.$w->domain.'",'.$searched.','.sizeof($wikis).');</script>'."\n";
   
    $db = cuGetConnection($w);
    if (!$db) {
        if (!$raw) print "<p class='error'>Failed to connect to database for {$w->domain}</p>";
        //wsfLog("Failed to connect to database for {$w->domain}" , LL_NORMAL );
     
        continue;
    }

    $used= checkWiki( $image, $commonsInfo, $w, $db, $filter, $raw )
   
    if ($used==='?') {
        $broken+= 1;
    }
    else {
        if ($used) {
            $pages+= $used;
            if ($used>=$GLOBALS['usageLimit']) $atleast= true;
            $projects+= 1;
        }
       
        $searched+= 1;
    }
  }
 
  cuCloseConnections();
 
  if (!$raw) {
      print "\n<p class='summary' style='clear:both;'>";
      if (!$pages) print "\n$searched wikis searched. ".escapeHtml(is_array($image)?"Images":"$image is")." not used anywhere!";
      else print "\n$searched wikis searched. ".escapeHtml(is_array($image)?"Images":"$image is")." used on ".($atleast?"at least":"")." $pages pages in $projects projects.";
     
      if ($filter=='notalk') print " <br/><b>(not counting talk pages)</b>";
      else if ($filter=='main') print " <br/><b>(only counting articles)</b>";
     
      if ($broken) print "<br/><span class='error'><b>NOTE:</b> $broken broken wiki databases have not been searched. Please check manually!</span>";
     
      if ($pages < 30) print "<script type='text/javascript'>toggleAll(true);</script>";
   
      print "</p>\n";
  }
 
  return true;
}

function printToggle($id, $expanded) {
    $label= $expanded ? '&ndash;' : '+';
    $title= $expanded ? 'hide' : 'show';
    $state= $expanded ? 'false' : 'true';

    $js= "toggleBlock('$id',$state)";

    print '<span class="toggle">[<a href="javascript:'.escapeHtml($js).'" title="'.escapeHtml($title).'" id="toggle-'.$id.'">'.escapeHtml($label).'</a>]</span>';
}

function printExpand($id, $expanded) {
    $display= $expanded ? 'block' : 'none';
    print "\n".'<script type="text/javascript">e= document.getElementById("'.addslashes($id).'"); if (e) e.style.display="'.$display.'"; wikis.push("'.addslashes($id).'");</script>'."\n";
}

function isSameImage($a, $b) {
    if ( $a->img_size == $b->img_size
        && $a->img_width == $b->img_width
        && $a->img_height == $b->img_height
        && $a->img_minor_mime == $b->img_minor_mime
        && $a->img_metadata  == $b->img_metadata ) {
       
            return true;
        }
    else {
            return false;
    }
}

function printUsage($domain, $image, $usage, $info, $commonsInfo, $raw) {
  global $wsgUserLang, $wsgFileNamespace;

  $used= false;
  $found= true;
  $status= '';
 
  if (!$info) {
      if ($commonsInfo) {
          $status= '';
         
          if ($usage) $used= true;
          else return false; #TODO: optionally show this!
      }
      else {
          $status= NULL;
          $found= false;
          if (!$usage) return false; #TODO: optionally show this!
      }
  }
  else {
      $status= ceil($info->img_size/1024) . " KB";
     
      if ($info->img_media_type == 'BITMAP') {
        $status.= ", " . $info->img_width . "x" . $info->img_height . " pixels";
      }
     
      $status= escapeHtml($status);
     
      if (!$commonsInfo) $status= "found: $status";
      else if ( isSameImage($info, $commonsInfo) ) {
          $status= "local duplicate";
          #if ($raw) return false; #TODO!
      }
      else {
          $status= "different image ($status) ";
          if (!$raw) $status= "<b>$status</b>";
          #if ($raw) return false; #TODO!
      }
  }
 
  $u= 0;
 
  if (@$info->is_broken) {
      $status.= '<span style="color:red"> (out of sync) </span>';
  }
 
  if (!$found) {
    $status.= "not found!";
    if (!$raw) $status.= "<b>$status</b>";
   
    if ($domain=='commons.wikimedia.org') $style= 'color:red; font-weight:bold;';
    else if (!$usage) $style= 'font-size:66%;';
    else {
        $style= 'color:red; font-weight:bold;';
        $status.= "not found, but used!";
        if (!$raw) $status.= "<b>$status</b>";
    }
  }
  else if (!$usage) {
      if ($domain=='commons.wikimedia.org') $style= '';
      else $style= 'font-size:66%;';
      $status.= ' - not used';
  }
  else {
      $style= '';
      $u= sizeof($usage);
      if ( $u >= $GLOBALS['usageLimit'] ) {
          if ($raw) $u= "$u+";
          else $u= "at least ".$GLOBALS['usageLimit'];
      }
     
      $status.= ' - used on '.$u.' pages';
  }
 
  $url= "http://$domain/wiki/";
 
  $id= $domain;
 
  if ($raw) {
      print "[$domain]\t$u\t$status\n";
      foreach ($usage as $p) {
          print "$p\n";
      }
      print "\n";
  }
  else {
      ?>
      <div id='project-<?=$domain?>' class='project' style='<?= $style ?>'>
     
      <b><a href="<?=$url . "$wsgFileNamespace:" . urlencode($image) . '?uselang=' . $wsgUserLang?>"><?=escapeHtml($domain)?></a>:</b>
     
        <i><?=$status?></i>
       
        <? if ($usage) printToggle($id,false); ?>
       
        <? if ($usage): ?>
        <div class='usage' id='<?= $id ?>'>
          <?
          if ($usage) printExpand($id,false);
         
          foreach ($usage as $p) {
            ?>
            <div class='page'><a href="<?=$url . str_replace('%2F','/',urlencode($p)) . '?uselang=' . $wsgUserLang?>"><?= str_replace('_',' ',escapeHtml($p))?></a></div>
            <?
          }
          ?>
        </div>
        <? endif; ?>
      </div>
      <?
  }
 
  if ($used) return sizeof($usage);
  else return 0;
}

function printBrokenWiki($domain, $image, $raw) {
  global $wsgUserLang, $wsgFileNamespace;
 
  if ($raw) {
      print "[$domain]\t*broken*\n\n";
  }
  else {
      $style= 'color:red; font-weight:bold;';
      $status= 'The database copy for this wiki is marked as broken, please check manually!';
      $url= "http://$domain/wiki/";
      if (!is_array($image)) $url .= $wsgFileNamespace . ":" . urlencode($image) . '?uselang=' . $wsgUserLang;
      ?>
      <div id='project-<?=$domain?>' class='project' style='<?= $style ?>'>
     
        <b><a href="<?=$url ?>"><?=escapeHtml($domain)?></a>:</b>
        <i><?=$status?></i>
      </div>
      <?
  }
 
  return '?';
}

function printBulkUsage($domain, $images, $usage, $infos, $commonsInfos, $raw) {
  global $wsgUserLang, $wsgFileNamespace;
 
  $used= 0;
 
  if (!$usage) return 0;
 
  $url= "http://$domain/wiki/";
 
  $id= $domain;
 
  $u= sizeof($usage);
  if ( $u >= $GLOBALS['usageLimit'] ) {
      if ($raw) $u= "$u+";
      else $u= "at least ".$GLOBALS['usageLimit'];
  }
 
  $status= ' - '.$u.' pages';
  $style= '';
 
  if ($raw) {
      print "[$domain]\t$u\n";
      foreach ($usage as $p) {
        $images= $p['images'];
        $p= $p['page'];
       
        print "$p";
        $uses= false;
       
        foreach ($images as $i) {
            if (!@$infos[$i] || $domain == 'commons.wikimedia.org') {
                print "\t$i";
                $uses= true;
            }
        }
       
        print "\n";
        if ($uses) $used+= 1;
      }
     
      print "\n";
     
      return $used;
  }

  #print " <pre> ";
  #print_r($images);
  #print_r($infos);
  #print_r($commonsInfos);
  #print " </pre>\n ";
 
  ?>
  <div id='project-<?=$domain?>' class='project' style='<?= $style ?>'>
 
  <b><?=escapeHtml($domain)?>:</b>
 
  <i><?=$status?></i>
   
    <? if ($usage) printToggle($id,false); ?>
   
    <? if ($usage): ?>
    <div class='usage' id='<?= $id ?>'>
      <?
      if ($usage) printExpand($id,false);
     
      foreach ($usage as $p) {
        $images= $p['images'];
        $p= $p['page'];
       
        ?>
        <div class='page'><a href="<?=$url . str_replace('%2F','/',urlencode($p)) . '?uselang=' . $wsgUserLang?>"><?= str_replace('_',' ',escapeHtml($p))?></a>
        <? 
            print " <span class='bulk-use'> uses: ";
            $first= true;
            $uses= false;
           
            foreach ($images as $i) {
                $status= '';
                $style= '';
               
                unset($info);
                unset($cinfo);
               
                $info= NULL;
                $cinfo= NULL;
               
                if (isset($infos[$i])) $info= &$infos[$i];
                if (isset($commonsInfos[$i])) $cinfo= &$commonsInfos[$i];
               
                #print "( $i | $info | $cinfo )";
               
                if (@$info->is_broken) {
                    $status.= '<span style="color:red"> (out of sync) </span>';
                }
               
                if (!$info) {
                    if (!$cinfo) $status.= "<span style='color:red; font-weight:bold;'>not found!</span>";
                    else {
                        $uses= true;
                    }
                }
                else {
                    if (!$cinfo) $status= '';
                    else if (isSameImage($info, $cinfo)) {
                        $status.= "<b>dupe</b>";
                        $style= "text-decoration: line-through;";
                    }
                    else {
                        $status.= "<b>different</b>";
                        $style= "text-decoration: line-through;";
                    }
                }
               
                if ($first) $first= false;
                else print ", ";
               
                ?><a href="<?=$url . $wsgFileNamespace . ':' . urlencode($i) . '?uselang=' . $wsgUserLang?>" style="<?= $style?>"><?=escapeHtml($i)?></a><?
               
                if ($status) print " <i>($status)</i>";
            }
           
            if ($uses) $used+= 1;
            print "</span>";
        ?>
        </div>
        <?
      }
      ?>
    </div>
    <? endif; ?>
  </div>
  <?
 
  return $used;
}

$knownLanguages= array('en');
$wsgCheckUsageText=& WikiSenseLocalizer::initialize('CheckUsage', $knownLanguages, $wgRequest->getVal('set-userlang'));
if (!in_array($wsgUserLang, $knownLanguages)) $wsgUserLang= $knownLanguages[0];

$filters= array(
  '' => 'all pages',
  'notalk' => 'no talk pages',
  'main' => 'only articles',
);

# get image name from request
$image= $wgRequest->getVal('i');
$wikirq= $wgRequest->getVal('w','_160');
$more= $wgRequest->getVal('m');
$filter= $wgRequest->getVal('x');
$bulk= $wgRequest->getVal('b',0);
$raw= $wgRequest->getCheck('r');
$sortByName= $wgRequest->getCheck('byname');

$usageLimit= $raw ? RAW_IMAGE_USAGE_LIMIT : IMAGE_USAGE_LIMIT;

if (!$bulk && $wgRequest->getVal('setbulk')) {
    $bulk= 1;
    $image= NULL;
}

if ($bulk && $wgRequest->getVal('setnobulk')) {
    $bulk= 0;
    $image= NULL;
}

if ($image) {
    $image= preg_split('/\s*[|\n]\s*/',$image,-1,PREG_SPLIT_NO_EMPTY);
   
    for ($i= 0; $i<sizeof($image); $i+= 1) {
        $m= array();
        if (preg_match('/^.*?:(.*)$/',$image[$i],$m)) $image[$i]= $m[1];
       
        $image[$i]= wsfDBTitle($image[$i]);
    }
   
    if (sizeof($image)===0) $image= NULL;
    else if (sizeof($image)===1 && !$raw) $image= $image[0];
}

$wikis= $wikirq;

if ($wikis) {
    $fam= NULL;
   
    if (preg_match('/^_wp_/',$wikis)) {
        $fam= 'wikipedia';
        $wikis= substr($wikis,3);
    }
   
    if (preg_match('/^_/',$wikis)) {
        $n= substr($wikis,1);
        $wikis= getLargestWikis($n,$fam);
        if ($sortByName) usort($wikis, 'compareWikiInfoByDomain');
    }
    else {
        $more.= ',' . $wikis;
        $wikis= array();
    }
}
else $wikis= array();

if ($more) {
    $m= preg_split('! *[,;/| ] *!',$more);
   
    foreach ($m as $w) {
        if (!$w) continue;
       
        $w= getWikiInfoFromDomain($w);
        if ($w) $wikis[$w->domain]= $w;
    }
}

if ($raw && $image && $wikis) {
    header('Content-Type: text/plain; charset=utf-8'); #TODO: use tsv mime type?!
   
    if (is_array($image) && sizeof($image)>1000) {
        print "##ERROR: refused bulk check on more than 1000 images!\n";
    }
    else {
        checkUsage($image, $wikis, $filter, true);
    }
   
    exit;
}


header('Content-Type: text/html; charset=utf-8');
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
        <head>
                <title>CheckUsage</title>
                <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
               
                <?
                if ($image || $wikis) print '<meta name="robots" content="noindex, nofollow"/>';
                else print '<meta name="robots" content="nofollow"/>';
                ?>
               
                <link rel="stylesheet" href="wikisense.css" type="text/css">
               
                <style type='text/css'>
                        body { font-family: sans-serif; font-size:14px; }
                        div.project { margin:0.5ex; }
                        div.usage { margin:0.5ex; margin-left:2ex; }
                      .bulk-use { font-size:80%; }
                        .error { font-weight:bold; color:red; }
                        .toggle { font-weight:bold; }
                        .toggle a:link { text-decoration:none; color:inherit; }
                        .toggle a:hover { text-decoration:none; color:inherit; }
                        .toggle a:visited { text-decoration:none; color:inherit; }
                        .summary { font-size:120%; font-style:italic; }
                        .box {
                            border:1px solid #AAAAAA;
                            background-color: #EEEEEE;
                            padding:0 1ex 1ex 1ex;
                            margin:0;
                            margin-bottom:1ex;
                        }
                        .summary {
                            border:1px solid #AAAAAA;
                            background-color: #EEEEEE;
                            padding:1ex;
                            margin-top:2ex;
                            margin-bottom:2ex;
                            font-size:120%;
                            text-align:center;
                        }
                       
                        table.box td { text-align:left; vertical-align:top; }
                        table.box th { text-align:right; vertical-align:top; }
                       
                        .progress {
                            border:1px solid #AAAAAA;
                            background-color: #EEEEEE;
                            font-weight:bold;
                            font-size:120%;
                            text-align:center;
                        }
                       
                        button.pseudolink, input.pseudolink {
                            border:none;
                            padding:inherit;
                            background:transparent;
                            color:inherit;
                            cursor:pointer;
                            text-decoration:underline;
                            font-size:inherit;
                            display:inline;
                        }
                       
                        .thumbnail {
                            background-color:#F0F0F0;
                            border:1px solid #666666;
                            padding:1ex;
                            margin:1ex;
                        }
                </style>
                <script type='text/javascript'>
                    wikis= new Array();
                 
                    function toggleBlock(id, expanded) {
                        var e= document.getElementById(id);
                        if (!e) return;
                       
                        e.style.display= expanded ? 'block' : 'none';
                       
                        var toggle= document.getElementById('toggle-'+id);
                   
                        if (toggle) {
                            toggle.innerHTML= expanded ? '&ndash;' : '+';
                            toggle.title= expanded ? 'hide' : 'show';
                            var state= expanded ? 'false' : 'true';
                           
                            toggle.href= 'javascript:toggleBlock("'+id+'",'+state+')';
                        }
                    }
                   
                    function toggleAll(expanded) {
                        for (var i in wikis) {
                            toggleBlock(wikis[i], expanded);
                        }
                    }
                </script>
        </head>
       
        <body>
                   
          <script type='text/javascript'>
              function setProgress(txt, index, total) {
                  var e= document.getElementById('progress');
                 
                  if (total > 0) txt += " ("+Math.floor(index*100/total)+"%)";
                 
                  if (e) e.innerHTML= txt;
                  else alert("progress div not found");
              }
          </script>
         
          <a name='top'></a>
         
              <? wsfHeader(); ?>
            <div id='content' class='centerbox'>
             
              <h1>
                CheckUsage<?
                  if ($image) {
                      if (is_array($image)) print " (bulk)";
                      else print ": ".escapeHtml($image);
                  }
                  ?>
               
                <?
                if ($filter=='notalk') print " (no talk pages)";
                else if ($filter=='main') print " (only articles)";
                ?>
              </h1>

              <?             
              wsfSubtitle( 'CheckUsage' );
             
              $replag= wsfGetReplagHTML();
              if ($replag) {
                print "<div class='replag'>$replag</div>";
              }
              ?>
             
              <form method="<?= ($bulk ? "post" : "get") ?>" action="CheckUsage.php">
                <table class='box' style='width:100%'>
                   
                    <? if ($bulk): ?>
                    <tr>
                        <th>Images to check:<br/><small>one image per line</small></th>
                        <td><textarea type="text" name="i" cols="64" rows="12"><?= escapeHtml(is_array($image)?implode("\n",$image):$image) ?></textarea></td>
                    </tr>
                    <? else: ?>
                    <tr>
                        <th>Image to check:</th>
                        <td><input type="text" name="i" size="64" value="<?= escapeHtml(is_array($image)?implode('|',$image):$image) ?>"/></td>
                    </tr>
                    <? endif; ?>
                   
                    <tr>
                        <th>Wikis to search:</th>
                        <td>
                          <? printRadioButton('w','_20',$wikirq) ?> 20
                          <? printRadioButton('w','_80',$wikirq) ?> 80
                          <? printRadioButton('w','_160',$wikirq) ?> 160 largest,
                          <? printRadioButton('w','_100000',$wikirq) ?> all
                          <? printCheckbox('byname', $sortByName) ?> <label for="byname">by name</label>
                        </td>
                    </tr>
                    <tr>
                        <th>Wikipedias only:</th>
                        <td>
                          <? printRadioButton('w','_wp_20',$wikirq) ?> 20
                          <? printRadioButton('w','_wp_80',$wikirq) ?> 80 largest, 
                          <? printRadioButton('w','_wp_100000',$wikirq) ?> all
                        </td>
                    </tr>
                    <tr>
                        <th>Additional wikis:</th>
                        <td><input type="text" name="m"  size="48" value="<?= escapeHtml($more) ?>"/>
                        <? printRadioButton('w','',$wikirq) ?> only those</td>
                    </tr>
                    <tr>
                        <th>Show:</th>
                        <td><? printSelector('x',$filters,$filter) ?>
                        <input type="submit" name='go' value="Check Usage"/>
                       
                        &nbsp; &nbsp;
                        <span style='font-size:80%'>
                            raw output <input type="checkbox" name="r"/>
                        </span>
                       
                        &nbsp; &nbsp;
                       
                        <span style='font-size:80%'>
                            <a href='javascript:toggleAll(true)'>expand all</a>
                            &nbsp; &nbsp;
                            <a href='javascript:toggleAll(false)'>collapse all</a>
                        </span>
                       
                        &nbsp; &nbsp;
                       
                        <span style='font-size:80%'>
                            <?
                                $switchName= $bulk ? 'setnobulk' : 'setbulk';
                                $switchLabel= $bulk ? 'normal mode...' : 'bulk mode...';
                            ?>
                           
                            <? if (!$wsgBrowser || $wsgBrowser['strict']): ?>
                              <input class='pseudolink' type='submit' name='<?= $switchName ?>' value="<?= $switchLabel ?>"/>
                            <? elseif ($wsgBrowser['msie']): ?>
                              <a href="#"><input class='pseudolink' type='submit' name='<?= $switchName ?>' value="<?= $switchLabel ?>"/></a>
                            <? elseif ($wsgBrowser['khtml']): ?>
                              <a href="#"><button type='submit' class='pseudolink' value="1" name='<?= $switchName ?>'><?= $switchLabel ?></button></a>
                            <? elseif ($wsgBrowser['opera']): ?>
                              <a href="#"><input class='pseudolink' type='submit' name='<?= $switchName ?>' value="<?= $switchLabel ?>"/></a>
                            <? elseif ($wsgBrowser['mozilla']): ?>
                              <button type='submit' class='pseudolink' value="1" name='<?= $switchName ?>'><a href="#"><?= $switchLabel ?></a></button>
                            <? else: ?>
                              <input class='pseudolink' type='submit' name='<?= $switchName ?>' value="<?= $switchLabel ?>"/>
                            <? endif; ?>
                        </span>
                        </td>
                    </tr>
                    <!--<tr>
                        <th>&nbsp;</th>
                        <td><input type="submit" value="Check Usage"/></td>
                    </tr>-->
                </table>
               
                <input type="hidden" name="b" value="<?= $bulk ?>"/>
              </form>
             
              <div class='progress' id='progress'></div>
             
              <?
              flush();
             
              if ($image && $wikis) {
                  if (is_array($image) && sizeof($image)>1000) {
                      print "<div class='error'>refused bulk check on more than 1000 images!</div>";
                  }
                  else {
                    checkUsage($image, $wikis, $filter);
                  }
              }
             
              #print "\n<p style='font-style-italic; font-size:80%;'><a href='#top'>top</a></p>";
              print "\n<script type='text/javascript'>e= document.getElementById('progress'); if (e) e.style.display= 'none';</script>\n";
             
              ?>
              <a name='end'></a>
             
              <? if ($wsgBrowser && !$wsgBrowser['opera'] && !$wsgBrowser['khtml']): ?>
              <script type='text/javascript'>window.location.hash='#end'</script>
              <? endif; ?>
            </div>
            <?  wsfFooter(false); ?>
         
        </body>
</html>