*/ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class * * @author Elan Ruusamäe */ class helper_plugin_poldek extends DokuWiki_Plugin { /* * Path to package list cache file * Filled by sync() method. * @var string $cache */ private $cache; /** * Update poldek indexes for active repos * Save down list of packages. * * We create two cache objects, one for updating indexes, which is mtime based * And other for package list, which depends on index file. * And each page depends on the package list file * * Without force, cache is attempted to be used, even if it's stale * * Called by ls command, or from cron */ public function sync($force = false) { // do this once per request if ($this->cache) { return; } global $conf; $idx_cache = new cache($this->getPluginName(), '.idx'); $pkg_cache = new cache($this->getPluginName(), '.txt'); $cache_exists = file_exists($pkg_cache->cache); // check poldek indexes if (!$cache_exists || !$idx_cache->useCache(array('age' => $conf['locktime'], 'files' => getConfigFiles('main')))) { // cache is ok, if it exists and is not empty and does not contain errors $cache_ok = $cache_exists && filesize($pkg_cache->cache) && !preg_grep('/^error:/', file($pkg_cache->cache)); // without force update indexes only if cache is missing if ($force || !$cache_exists) { $lines = $this->exec("--up"); // process output, if we find "Writing ..." line, means we should update ls output as well // Writing /root/.poldek-cache/[...]/packages.ndir.gz... // Index patches size too big // Retrieving whole index ... if (!$cache_exists || !$cache_ok || preg_grep('/^(Writing|Retrieving whole index) /', $lines)) { $idx_cache->storeCache(time()); } else { // freshen timestamp or we keep updating indexes if index // is older than locktime touch($idx_cache->cache); if ($force) { // sleep, so packages cache be newer sleep(1); } // touch also package file, not to trigger it's update touch($pkg_cache->cache); clearstatcache(); } } } // do not update listing, if cache exists and not in cron mode if (($force || !$cache_exists) && !$pkg_cache->useCache(array('files' => array($idx_cache->cache)))) { $lines = $this->shcmd("ls", $rc); // write cache, unless there was an error if (!$rc) { $pkg_cache->storeCache(join("\n", $lines)); } } $this->cache = $pkg_cache->cache; } public function ls($package) { static $cache; if (!$cache) { $cache = array(); // regexp matching is slow. // cache this for cases having more than one instance of our plugin on page foreach (file($this->getCache()) as $line) { if (preg_match('/^(?P.+)-(?P[^-]+)-(?P[^-]+)\.(?P[^.]+)$/', $line, $m)) { $cache[$m['name']] = $line; } elseif (preg_match('/error: (?P.+): no such package or directory/', $line, $m)) { $cache[$m['name']] = $line; } } } if (isset($cache[$package])) { return $cache[$package]; } return "error: $package: no such package"; } /** * Get filename for package list * It ensures that cache file is created, if missing */ public function getCache() { $this->sync(); return $this->cache; } /** * Run command in poldek */ private function shcmd($cmd, &$rc = null) { return $this->exec('-q -Q --shcmd='.escapeshellarg($cmd), $rc); } /** * Run poldek with configured repositories and cachedir * Setups proxies if needed */ private function exec($cmd, &$rc = null) { global $conf; $cachedir = $conf['cachedir'].'/'.$this->getPluginName(); // base poldek command $poldek = 'exec poldek --skip-installed --cachedir=' . escapeshellarg($cachedir); $poldek_conf = DOKU_CONF . 'poldek.conf'; if (file_exists($poldek_conf)) { $poldek .= ' --conf '.escapeshellarg($poldek_conf); } $repos = $this->getConf('repos'); foreach (explode(',', $repos) as $repo) { $poldek .= ' --sn '.escapeshellarg(trim($repo)); } // proxies setup $http_proxy = $this->getConf('http_proxy'); if ($http_proxy) { $poldek .= ' -O '.escapeshellarg("proxy=http: {$http_proxy}"); } $ftp_proxy = $this->getConf('ftp_proxy'); if ($ftp_proxy) { $poldek.= ' -O '.escapeshellarg("proxy=ftp: {$ftp_proxy}"); } $poldek .= " $cmd"; exec($poldek, $lines, $rc); return $lines; } } //Setup VIM: ex: noet ts=4 enc=utf-8 :