[ Index ] |
|
Code source de GeekLog 1.4.1 |
1 <?php 2 /** 3 * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download, 4 * clear-cache commands) 5 * 6 * PHP versions 4 and 5 7 * 8 * LICENSE: This source file is subject to version 3.0 of the PHP license 9 * that is available through the world-wide-web at the following URI: 10 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 11 * the PHP License and are unable to obtain it through the web, please 12 * send a note to license@php.net so we can mail you a copy immediately. 13 * 14 * @category pear 15 * @package PEAR 16 * @author Stig Bakken <ssb@php.net> 17 * @author Greg Beaver <cellog@php.net> 18 * @copyright 1997-2006 The PHP Group 19 * @license http://www.php.net/license/3_0.txt PHP License 3.0 20 * @version CVS: $Id: Remote.php,v 1.90.2.3 2006/06/04 12:27:55 pajoye Exp $ 21 * @link http://pear.php.net/package/PEAR 22 * @since File available since Release 0.1 23 */ 24 25 /** 26 * base class 27 */ 28 require_once 'PEAR/Command/Common.php'; 29 require_once 'PEAR/REST.php'; 30 31 /** 32 * PEAR commands for remote server querying 33 * 34 * @category pear 35 * @package PEAR 36 * @author Stig Bakken <ssb@php.net> 37 * @author Greg Beaver <cellog@php.net> 38 * @copyright 1997-2006 The PHP Group 39 * @license http://www.php.net/license/3_0.txt PHP License 3.0 40 * @version Release: 1.4.11 41 * @link http://pear.php.net/package/PEAR 42 * @since Class available since Release 0.1 43 */ 44 class PEAR_Command_Remote extends PEAR_Command_Common 45 { 46 // {{{ command definitions 47 48 var $commands = array( 49 'remote-info' => array( 50 'summary' => 'Information About Remote Packages', 51 'function' => 'doRemoteInfo', 52 'shortcut' => 'ri', 53 'options' => array(), 54 'doc' => '<package> 55 Get details on a package from the server.', 56 ), 57 'list-upgrades' => array( 58 'summary' => 'List Available Upgrades', 59 'function' => 'doListUpgrades', 60 'shortcut' => 'lu', 61 'options' => array(), 62 'doc' => '[preferred_state] 63 List releases on the server of packages you have installed where 64 a newer version is available with the same release state (stable etc.) 65 or the state passed as the second parameter.' 66 ), 67 'remote-list' => array( 68 'summary' => 'List Remote Packages', 69 'function' => 'doRemoteList', 70 'shortcut' => 'rl', 71 'options' => array( 72 'channel' => 73 array( 74 'shortopt' => 'c', 75 'doc' => 'specify a channel other than the default channel', 76 'arg' => 'CHAN', 77 ) 78 ), 79 'doc' => ' 80 Lists the packages available on the configured server along with the 81 latest stable release of each package.', 82 ), 83 'search' => array( 84 'summary' => 'Search remote package database', 85 'function' => 'doSearch', 86 'shortcut' => 'sp', 87 'options' => array( 88 'channel' => 89 array( 90 'shortopt' => 'c', 91 'doc' => 'specify a channel other than the default channel', 92 'arg' => 'CHAN', 93 ) 94 ), 95 'doc' => '[packagename] [packageinfo] 96 Lists all packages which match the search parameters. The first 97 parameter is a fragment of a packagename. The default channel 98 will be used unless explicitly overridden. The second parameter 99 will be used to match any portion of the summary/description', 100 ), 101 'list-all' => array( 102 'summary' => 'List All Packages', 103 'function' => 'doListAll', 104 'shortcut' => 'la', 105 'options' => array( 106 'channel' => 107 array( 108 'shortopt' => 'c', 109 'doc' => 'specify a channel other than the default channel', 110 'arg' => 'CHAN', 111 ) 112 ), 113 'doc' => ' 114 Lists the packages available on the configured server along with the 115 latest stable release of each package.', 116 ), 117 'download' => array( 118 'summary' => 'Download Package', 119 'function' => 'doDownload', 120 'shortcut' => 'd', 121 'options' => array( 122 'nocompress' => array( 123 'shortopt' => 'Z', 124 'doc' => 'download an uncompressed (.tar) file', 125 ), 126 ), 127 'doc' => '<package>... 128 Download package tarballs. The files will be named as suggested by the 129 server, for example if you download the DB package and the latest stable 130 version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.', 131 ), 132 'clear-cache' => array( 133 'summary' => 'Clear Web Services Cache', 134 'function' => 'doClearCache', 135 'shortcut' => 'cc', 136 'options' => array(), 137 'doc' => ' 138 Clear the XML-RPC/REST cache. See also the cache_ttl configuration 139 parameter. 140 ', 141 ), 142 ); 143 144 // }}} 145 // {{{ constructor 146 147 /** 148 * PEAR_Command_Remote constructor. 149 * 150 * @access public 151 */ 152 function PEAR_Command_Remote(&$ui, &$config) 153 { 154 parent::PEAR_Command_Common($ui, $config); 155 } 156 157 // }}} 158 159 function _checkChannelForStatus($channel, $chan) 160 { 161 if (PEAR::isError($chan)) { 162 $this->raiseError($chan); 163 } 164 if (!is_a($chan, 'PEAR_ChannelFile')) { 165 return $this->raiseError('Internal corruption error: invalid channel "' . 166 $channel . '"'); 167 } 168 $rest = new PEAR_REST($this->config); 169 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 170 $a = $rest->downloadHttp('http://' . $channel . 171 '/channel.xml', $chan->lastModified()); 172 PEAR::staticPopErrorHandling(); 173 if (!PEAR::isError($a) && $a) { 174 $this->ui->outputData('WARNING: channel "' . $channel . '" has ' . 175 'updated its protocols, use "channel-update ' . $channel . 176 '" to update'); 177 } 178 } 179 180 // {{{ doRemoteInfo() 181 182 function doRemoteInfo($command, $options, $params) 183 { 184 if (sizeof($params) != 1) { 185 return $this->raiseError("$command expects one param: the remote package name"); 186 } 187 $savechannel = $channel = $this->config->get('default_channel'); 188 $reg = &$this->config->getRegistry(); 189 $package = $params[0]; 190 $parsed = $reg->parsePackageName($package, $channel); 191 if (PEAR::isError($parsed)) { 192 return $this->raiseError('Invalid package name "' . $package . '"'); 193 } 194 195 $channel = $parsed['channel']; 196 $this->config->set('default_channel', $channel); 197 $chan = $reg->getChannel($channel); 198 if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { 199 return $e; 200 } 201 if ($chan->supportsREST($this->config->get('preferred_mirror')) && 202 $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { 203 $rest = &$this->config->getREST('1.0', array()); 204 $info = $rest->packageInfo($base, $parsed['package']); 205 } else { 206 $r = &$this->config->getRemote(); 207 $info = $r->call('package.info', $parsed['package']); 208 } 209 if (PEAR::isError($info)) { 210 $this->config->set('default_channel', $savechannel); 211 return $this->raiseError($info); 212 } 213 if (!isset($info['name'])) { 214 return $this->raiseError('No remote package "' . $package . '" was found'); 215 } 216 217 $installed = $reg->packageInfo($info['name'], null, $channel); 218 $info['installed'] = $installed['version'] ? $installed['version'] : '- no -'; 219 if (is_array($info['installed'])) { 220 $info['installed'] = $info['installed']['release']; 221 } 222 223 $this->ui->outputData($info, $command); 224 $this->config->set('default_channel', $savechannel); 225 226 return true; 227 } 228 229 // }}} 230 // {{{ doRemoteList() 231 232 function doRemoteList($command, $options, $params) 233 { 234 $savechannel = $channel = $this->config->get('default_channel'); 235 $reg = &$this->config->getRegistry(); 236 if (isset($options['channel'])) { 237 $channel = $options['channel']; 238 if ($reg->channelExists($channel)) { 239 $this->config->set('default_channel', $channel); 240 } else { 241 return $this->raiseError('Channel "' . $channel . '" does not exist'); 242 } 243 } 244 $chan = $reg->getChannel($channel); 245 if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { 246 return $e; 247 } 248 $list_options = false; 249 if ($this->config->get('preferred_state') == 'stable') { 250 $list_options = true; 251 } 252 if ($chan->supportsREST($this->config->get('preferred_mirror')) && 253 $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { 254 // use faster list-all if available 255 $rest = &$this->config->getREST('1.1', array()); 256 $available = $rest->listAll($base, $list_options); 257 } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && 258 $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { 259 $rest = &$this->config->getREST('1.0', array()); 260 $available = $rest->listAll($base, $list_options); 261 } else { 262 $r = &$this->config->getRemote(); 263 if ($channel == 'pear.php.net') { 264 // hack because of poor pearweb design 265 $available = $r->call('package.listAll', true, $list_options, false); 266 } else { 267 $available = $r->call('package.listAll', true, $list_options); 268 } 269 } 270 if (PEAR::isError($available)) { 271 $this->config->set('default_channel', $savechannel); 272 return $this->raiseError($available); 273 } 274 $i = $j = 0; 275 $data = array( 276 'caption' => 'Channel ' . $channel . ' Available packages:', 277 'border' => true, 278 'headline' => array('Package', 'Version'), 279 ); 280 if (count($available)==0) { 281 $data = '(no packages available yet)'; 282 } else { 283 foreach ($available as $name => $info) { 284 $data['data'][] = array($name, (isset($info['stable']) && $info['stable']) 285 ? $info['stable'] : '-n/a-'); 286 } 287 } 288 $this->ui->outputData($data, $command); 289 $this->config->set('default_channel', $savechannel); 290 return true; 291 } 292 293 // }}} 294 // {{{ doListAll() 295 296 function doListAll($command, $options, $params) 297 { 298 $savechannel = $channel = $this->config->get('default_channel'); 299 $reg = &$this->config->getRegistry(); 300 if (isset($options['channel'])) { 301 $channel = $options['channel']; 302 if ($reg->channelExists($channel)) { 303 $this->config->set('default_channel', $channel); 304 } else { 305 return $this->raiseError("Channel \"$channel\" does not exist"); 306 } 307 } 308 $list_options = false; 309 if ($this->config->get('preferred_state') == 'stable') { 310 $list_options = true; 311 } 312 $chan = $reg->getChannel($channel); 313 if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { 314 return $e; 315 } 316 if ($chan->supportsREST($this->config->get('preferred_mirror')) && 317 $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { 318 // use faster list-all if available 319 $rest = &$this->config->getREST('1.1', array()); 320 $available = $rest->listAll($base, $list_options, false); 321 } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && 322 $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { 323 $rest = &$this->config->getREST('1.0', array()); 324 $available = $rest->listAll($base, $list_options, false); 325 } else { 326 $r = &$this->config->getRemote(); 327 if ($channel == 'pear.php.net') { 328 // hack because of poor pearweb design 329 $available = $r->call('package.listAll', true, $list_options, false); 330 } else { 331 $available = $r->call('package.listAll', true, $list_options); 332 } 333 } 334 if (PEAR::isError($available)) { 335 $this->config->set('default_channel', $savechannel); 336 return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")'); 337 } 338 $data = array( 339 'caption' => 'All packages:', 340 'border' => true, 341 'headline' => array('Package', 'Latest', 'Local'), 342 ); 343 $local_pkgs = $reg->listPackages($channel); 344 345 foreach ($available as $name => $info) { 346 $installed = $reg->packageInfo($name, null, $channel); 347 if (is_array($installed['version'])) { 348 $installed['version'] = $installed['version']['release']; 349 } 350 $desc = $info['summary']; 351 if (isset($params[$name])) { 352 $desc .= "\n\n".$info['description']; 353 } 354 if (isset($options['mode'])) 355 { 356 if ($options['mode'] == 'installed' && !isset($installed['version'])) { 357 continue; 358 } 359 if ($options['mode'] == 'notinstalled' && isset($installed['version'])) { 360 continue; 361 } 362 if ($options['mode'] == 'upgrades' 363 && (!isset($installed['version']) || version_compare($installed['version'], 364 $info['stable'], '>='))) { 365 continue; 366 } 367 } 368 $pos = array_search(strtolower($name), $local_pkgs); 369 if ($pos !== false) { 370 unset($local_pkgs[$pos]); 371 } 372 373 if (isset($info['stable']) && !$info['stable']) { 374 $info['stable'] = null; 375 } 376 $data['data'][$info['category']][] = array( 377 $reg->channelAlias($channel) . '/' . $name, 378 @$info['stable'], 379 @$installed['version'], 380 @$desc, 381 @$info['deps'], 382 ); 383 } 384 385 if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) { 386 $this->config->set('default_channel', $savechannel); 387 $this->ui->outputData($data, $command); 388 return true; 389 } 390 foreach ($local_pkgs as $name) { 391 $info = &$reg->getPackage($name, $channel); 392 $data['data']['Local'][] = array( 393 $reg->channelAlias($channel) . '/' . $info->getPackage(), 394 '', 395 $info->getVersion(), 396 $info->getSummary(), 397 $info->getDeps() 398 ); 399 } 400 401 $this->config->set('default_channel', $savechannel); 402 $this->ui->outputData($data, $command); 403 return true; 404 } 405 406 // }}} 407 // {{{ doSearch() 408 409 function doSearch($command, $options, $params) 410 { 411 if ((!isset($params[0]) || empty($params[0])) 412 && (!isset($params[1]) || empty($params[1]))) 413 { 414 return $this->raiseError('no valid search string supplied'); 415 }; 416 417 $savechannel = $channel = $this->config->get('default_channel'); 418 $reg = &$this->config->getRegistry(); 419 $package = $params[0]; 420 $summary = isset($params[1]) ? $params[1] : false; 421 if (isset($options['channel'])) { 422 $reg = &$this->config->getRegistry(); 423 $channel = $options['channel']; 424 if ($reg->channelExists($channel)) { 425 $this->config->set('default_channel', $channel); 426 } else { 427 return $this->raiseError('Channel "' . $channel . '" does not exist'); 428 } 429 } 430 $chan = $reg->getChannel($channel); 431 if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { 432 return $e; 433 } 434 if ($chan->supportsREST($this->config->get('preferred_mirror')) && 435 $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { 436 $rest = &$this->config->getREST('1.0', array()); 437 $available = $rest->listAll($base, false, false, $package, $summary); 438 } else { 439 $r = &$this->config->getRemote(); 440 $available = $r->call('package.search', $package, $summary, true, 441 $this->config->get('preferred_state') == 'stable', true); 442 } 443 if (PEAR::isError($available)) { 444 $this->config->set('default_channel', $savechannel); 445 return $this->raiseError($available); 446 } 447 if (!$available) { 448 return $this->raiseError('no packages found that match pattern "' . $package . '"'); 449 } 450 $data = array( 451 'caption' => 'Matched packages, channel ' . $channel . ':', 452 'border' => true, 453 'headline' => array('Package', 'Stable/(Latest)', 'Local'), 454 ); 455 456 foreach ($available as $name => $info) { 457 $installed = $reg->packageInfo($name, null, $channel); 458 $desc = $info['summary']; 459 if (isset($params[$name])) 460 $desc .= "\n\n".$info['description']; 461 462 $unstable = ''; 463 if ($info['unstable']) { 464 $unstable = '/(' . $info['unstable'] . ' ' . $info['state'] . ')'; 465 } 466 if (!isset($info['stable']) || !$info['stable']) { 467 $info['stable'] = 'none'; 468 } 469 $version = is_array($installed['version']) ? $installed['version']['release'] : 470 $installed['version']; 471 $data['data'][$info['category']][] = array( 472 $name, 473 $info['stable'] . $unstable, 474 $version, 475 $desc, 476 ); 477 } 478 $this->ui->outputData($data, $command); 479 $this->config->set('default_channel', $channel); 480 return true; 481 } 482 483 // }}} 484 function &getDownloader($options) 485 { 486 if (!class_exists('PEAR_Downloader')) { 487 require_once 'PEAR/Downloader.php'; 488 } 489 $a = &new PEAR_Downloader($this->ui, $options, $this->config); 490 return $a; 491 } 492 // {{{ doDownload() 493 494 function doDownload($command, $options, $params) 495 { 496 // make certain that dependencies are ignored 497 $options['downloadonly'] = 1; 498 // eliminate error messages for preferred_state-related errors 499 $options['ignorepreferred_state'] = 1; 500 $downloader = &$this->getDownloader($options); 501 $downloader->setDownloadDir(getcwd()); 502 $errors = array(); 503 $downloaded = array(); 504 $err = $downloader->download($params); 505 if (PEAR::isError($err)) { 506 return $err; 507 } 508 $errors = $downloader->getErrorMsgs(); 509 if (count($errors)) { 510 foreach ($errors as $error) { 511 $this->ui->outputData($error); 512 } 513 return $this->raiseError("$command failed"); 514 } 515 $downloaded = $downloader->getDownloadedPackages(); 516 foreach ($downloaded as $pkg) { 517 $this->ui->outputData("File $pkg[file] downloaded", $command); 518 } 519 return true; 520 } 521 522 function downloadCallback($msg, $params = null) 523 { 524 if ($msg == 'done') { 525 $this->bytes_downloaded = $params; 526 } 527 } 528 529 // }}} 530 // {{{ doListUpgrades() 531 532 function doListUpgrades($command, $options, $params) 533 { 534 require_once 'PEAR/Common.php'; 535 if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) { 536 return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"'); 537 } 538 $savechannel = $channel = $this->config->get('default_channel'); 539 $reg = &$this->config->getRegistry(); 540 foreach ($reg->listChannels() as $channel) { 541 $inst = array_flip($reg->listPackages($channel)); 542 if (!count($inst)) { 543 continue; 544 } 545 if ($channel == '__uri') { 546 continue; 547 } 548 $this->config->set('default_channel', $channel); 549 if (empty($params[0])) { 550 $state = $this->config->get('preferred_state'); 551 } else { 552 $state = $params[0]; 553 } 554 $caption = $channel . ' Available Upgrades'; 555 $chan = $reg->getChannel($channel); 556 if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { 557 return $e; 558 } 559 if ($chan->supportsREST($this->config->get('preferred_mirror')) && 560 $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { 561 $rest = &$this->config->getREST('1.0', array()); 562 if (empty($state) || $state == 'any') { 563 $state = false; 564 } else { 565 $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; 566 } 567 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 568 $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg); 569 PEAR::staticPopErrorHandling(); 570 } else { 571 $remote = &$this->config->getRemote(); 572 $remote->pushErrorHandling(PEAR_ERROR_RETURN); 573 if (empty($state) || $state == 'any') { 574 $latest = $remote->call("package.listLatestReleases"); 575 } else { 576 $latest = $remote->call("package.listLatestReleases", $state); 577 $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; 578 } 579 $remote->popErrorHandling(); 580 } 581 if (PEAR::isError($latest)) { 582 $this->ui->outputData($latest->getMessage()); 583 continue; 584 } 585 $caption .= ':'; 586 if (PEAR::isError($latest)) { 587 $this->config->set('default_channel', $savechannel); 588 return $latest; 589 } 590 $data = array( 591 'caption' => $caption, 592 'border' => 1, 593 'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'), 594 ); 595 foreach ((array)$latest as $pkg => $info) { 596 $package = strtolower($pkg); 597 if (!isset($inst[$package])) { 598 // skip packages we don't have installed 599 continue; 600 } 601 extract($info); 602 $inst_version = $reg->packageInfo($package, 'version', $channel); 603 $inst_state = $reg->packageInfo($package, 'release_state', $channel); 604 if (version_compare("$version", "$inst_version", "le")) { 605 // installed version is up-to-date 606 continue; 607 } 608 if ($filesize >= 20480) { 609 $filesize += 1024 - ($filesize % 1024); 610 $fs = sprintf("%dkB", $filesize / 1024); 611 } elseif ($filesize > 0) { 612 $filesize += 103 - ($filesize % 103); 613 $fs = sprintf("%.1fkB", $filesize / 1024.0); 614 } else { 615 $fs = " -"; // XXX center instead 616 } 617 $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs); 618 } 619 if (empty($data['data'])) { 620 $this->ui->outputData('Channel ' . $channel . ': No upgrades available'); 621 } else { 622 $this->ui->outputData($data, $command); 623 } 624 } 625 $this->config->set('default_channel', $savechannel); 626 return true; 627 } 628 629 // }}} 630 // {{{ doClearCache() 631 632 function doClearCache($command, $options, $params) 633 { 634 $cache_dir = $this->config->get('cache_dir'); 635 $verbose = $this->config->get('verbose'); 636 $output = ''; 637 if (!($dp = @opendir($cache_dir))) { 638 return $this->raiseError("opendir($cache_dir) failed: $php_errormsg"); 639 } 640 if ($verbose >= 1) { 641 $output .= "reading directory $cache_dir\n"; 642 } 643 $num = 0; 644 while ($ent = readdir($dp)) { 645 if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent) || 646 preg_match('/rest.cache(file|id)$/', $ent)) { 647 $path = $cache_dir . DIRECTORY_SEPARATOR . $ent; 648 $ok = @unlink($path); 649 if ($ok) { 650 if ($verbose >= 2) { 651 $output .= "deleted $path\n"; 652 } 653 $num++; 654 } elseif ($verbose >= 1) { 655 $output .= "failed to delete $path\n"; 656 } 657 } 658 } 659 closedir($dp); 660 if ($verbose >= 1) { 661 $output .= "$num cache entries cleared\n"; 662 } 663 $this->ui->outputData(rtrim($output), $command); 664 return $num; 665 } 666 667 // }}} 668 } 669 670 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |