* * @category Main * @package FedoraClient * * @author Remi Collet * @author Johan Cwiklinski * @copyright 2010 Remi Collet * @license http://www.gnu.org/licenses/lgpl-2.1.txt LGPL License 2.1 or (at your option) any later version * @link http://github.com/remicollet/rpmphp/ * @since The begining of times. */ define('FEDORACLIENT_VERSION', '0.1.0-dev'); if (!function_exists('curl_version')) { die("curl extension required\n"); } require_once 'Cache/Lite.php'; abstract class FedoraClient { private $url; private $agent; private $debug = 0; protected $cache; function __construct ($url, array $options) { $dir = "/tmp/cachelite-".posix_getlogin()."/"; @mkdir($dir); $this->cache = new Cache_Lite( array( 'memoryCaching' => true, 'cacheDir' => $dir, 'automaticSerialization' => true ) ); $this->url = $url; if (isset($options['agent']) && !empty($options['agent'])) { $this->agent = $options['agent']; } else { $this->agent = 'Fedora PHPClient/'.FEDORACLIENT_VERSION; } if (isset($options['debug']) && intval($options['debug'])>0) { $this->debug = intval($options['debug']); } $this->logDebug( 3, __CLASS__."::".__FUNCTION__.": url='$url', agent='".$this->agent."'" ); } function logDebug($level, $msg) { if ($this->debug>=$level) { echo "[debug][$level] $msg\n"; } } function sendRequest($method, array $options=array()) { $curl = curl_init(); // And join to make our url. $url = $this->url.$method; curl_setopt($curl, CURLOPT_URL, $url); // Boilerplate so pycurl processes cookies curl_setopt($curl, CURLOPT_COOKIEFILE, '/dev/null'); //# Associate with the response to accumulate data $this->data=''; curl_setopt($curl, CURLOPT_WRITEFUNCTION, array($this, 'receive')); // Follow redirect curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_MAXREDIRS, 5); // Set standard headers curl_setopt( $curl, CURLOPT_HTTPHEADER, array('User-agent: '.$this->agent, 'Accept: application/json') ); // run the request $this->logDebug( 2, __CLASS__."::".__FUNCTION__.": call '$url'" ); curl_exec($curl); // Check for auth failures // Note: old TG apps returned 403 Forbidden on authentication failures. // Updated apps return 401 Unauthorized // We need to accept both until all apps are updated to return 401. $http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($http_status==401 || $http_status==403) { $this->logDebug( 1, __CLASS__."::".__FUNCTION__. ": http_status '$http_status' Authentication failed logging in" ); return array(); } else if ($http_status>=400) { $this->logDebug( 1, __CLASS__."::".__FUNCTION__. ": http_status '$http_status' Unknown HTTP Server Response" ); return array(); } else { $this->logDebug( 2, __CLASS__."::".__FUNCTION__.": http_status '$http_status'" ); } $this->logDebug( 2, __CLASS__."::".__FUNCTION__.": close connexion" ); curl_close($curl); return json_decode($this->data, true); } function receive($curl, $data) { $this->logDebug( 9, __CLASS__."::".__FUNCTION__.": $data" ); $this->data .= $data; return strlen($data); } } class FedoraPkgdb extends FedoraClient { function __construct (array $options=array()) { parent::__construct('https://admin.fedoraproject.org/pkgdb/', $options); $this->logDebug( 3, __CLASS__."::".__FUNCTION__ ); } function getBranches($refresh=false) { $rep = ($refresh ? false : $this->cache->get(__FUNCTION__, __CLASS__)); if ($rep) { $this->logDebug( 2, __CLASS__."::".__FUNCTION__."() get from cache" ); } else { $rep =$this->sendRequest('collections'); $this->cache->save($rep, __FUNCTION__, __CLASS__); $this->logDebug( 2, __CLASS__."::".__FUNCTION__."() save to cache" ); } $branches = array(); if (isset($rep['collections'])) { foreach ($rep['collections'] as $coll) { if (isset($coll[0]['branchname'])) { $branches[$coll[0]['branchname']] = $coll[0]; } } } return $branches; } function getPackageInfo($name, $refresh=false) { $url="acls/name/$name"; $rep = ($refresh ? false : $this->cache->get($url, __CLASS__)); if ($rep) { $this->logDebug( 2, __CLASS__."::".__FUNCTION__."($name) get from cache" ); } else { $rep =$this->sendRequest($url); $this->cache->save($rep, $url, __CLASS__); $this->logDebug( 2, __CLASS__."::".__FUNCTION__."($name) save to cache" ); } if (isset($rep['status']) && !$rep['status']) { $this->logDebug( 1, __CLASS__."::".__FUNCTION__."($name) ".$rep['message'] ); return false; } $branches = array(); foreach ($rep['packageListings'] as $pack) { $branches[$pack['collection']['branchname']] = $pack; } return $branches; } function getBranch($name, $refresh=false) { $branches = $this->getBranches($refresh); if (isset($branches[$name])) { return $branches[$name]; } return false; } function getCritPath($refresh=false) { $url="lists/critpath"; $rep = ($refresh ? false : $this->cache->get($url, __CLASS__)); if ($rep) { $this->logDebug( 2, __CLASS__."::".__FUNCTION__." get from cache" ); } else { $rep =$this->sendRequest($url); $this->cache->save($rep, $url, __CLASS__); $this->logDebug( 2, __CLASS__."::".__FUNCTION__." save to cache" ); } return $rep['pkgs']; } } ?>