0;"; $db->query($sql); // Check to see if there are any ebuilds $sql = "SELECT COUNT(1) FROM ebuild WHERE status = 0;"; $count = $db->getOne($sql); // If there aren't any, then import *all* packages if(!$count || $debug) $all = true; else { // If there are, get the last modified time $sql = "SELECT MAX(portage_mtime) AS max_portage_mtime, MAX(cache_mtime) AS max_cache_mtime FROM ebuild WHERE status = 0;"; $row = $db->getRow($sql); if(is_array($row)) { extract($row); if(is_null($max_portage_mtime) || is_null($max_cache_mtime)) $all = true; else $min = min($max_portage_mtime, $max_cache_mtime); } } $tree = new PortageTree(); $categories = $tree->getCategories(); $arr_import = array(); // Find all the ebuilds that are currently in the db $arr = $arr_db = array(); if(!$all) { // Find all the packages that have been updated in the last 24 hours // Need to check the packages themselves, because something may have // been deleted. $portage = $tree->getTree(); $cache = $tree->getTree()."/metadata/cache/"; $tmp = tempnam('/tmp', 'znurt'); touch($tmp, $min); $exec = "find $cache -type f -newer $tmp"; $arr = shell::cmd($exec); unlink($tmp); if($verbose) { shell::msg($exec); shell::msg("(".count($arr).") new/updated ebuilds found since last sync."); } foreach($arr as $dir) { $atom = str_replace($tree->getTree()."/metadata/cache/", "", $dir); $e = new PortageEbuild($atom); $arr_import[$e->category][] = $e->pn; $arr_import[$e->category] = array_unique($arr_import[$e->category]); } // Also add any packages that were flagged when importing those $sql = "SELECT c.name AS category_name, p.name AS package_name FROM package p INNER JOIN category c ON c.id = p.category WHERE p.status = 1;"; $arr = $db->getAll($sql); if(count($arr)) { foreach($arr as $row) { $arr_import[$row['category_name']][] = $row['package_name']; $arr_import[$row['category_name']] = array_unique($arr_import[$row['category_name']]); } } ksort($arr_import); } elseif($all) { foreach($categories as $name) { $c = new PortageCategory($name); $arr_import[$name] = $c->getPackages(); } } if($debug || $all) { shell::msg("Checking ALL categories"); } elseif($verbose) { shell::msg("(".count($arr_import).") RECENTLY MODIFIED categories "); } // Get the package IDs for reference // and the mtimes of the ebuilds for verification $sql = "SELECT p.id AS package_id, c.name AS category_name, p.name AS package_name, e.pf AS ebuild_name, e.id AS ebuild FROM ebuild e RIGHT OUTER JOIN package p ON e.package = p.id INNER JOIN category c ON p.category = c.id ORDER BY c.name, p.name;"; $arr = $db->getAll($sql); if(count($arr)) { foreach($arr as $row) { extract($row); $arr_db[$category_name][$package_name] = $package_id; if($ebuild_name) { $arr_ebuild_ids[$category_name][$package_name][$ebuild_name] = $ebuild; } } } if(count($arr_import)) { foreach($arr_import as $category_name => $arr_category) { foreach($arr_category as $package_name) { if($debug) shell::msg("[$category_name/$package_name]"); $arr_insert = array(); $arr_delete = array(); $arr_update = array(); if(count($arr_ebuild_ids[$category_name][$package_name])) $arr_db_ebuilds = array_keys($arr_ebuild_ids[$category_name][$package_name]); else $arr_db_ebuilds = array(); $p = new PortagePackage($category_name, $package_name); $package_id =& $arr_db[$category_name][$package_name]; // If there are any old ebuilds (in the DB), then compare the new (in portage) if(count($arr_db_ebuilds)) { $arr_fs_ebuilds = $p->getEbuilds(); // Check old against new $arr_delete = array_diff($arr_db_ebuilds, $arr_fs_ebuilds); $arr_insert = array_diff($arr_fs_ebuilds, $arr_db_ebuilds); // Next, look at the mtimes and see if any need to be updated if(count($arr_fs_ebuilds)) { foreach($arr_fs_ebuilds as $ebuild_name) { $e = new PortageEbuild("$category_name/$ebuild_name"); $ebuild = $arr_ebuild_ids[$category_name][$package_name][$ebuild_name]; if($ebuild) { $db_ebuild = new DBEbuild($ebuild); if(($e->portage_mtime != $db_ebuild->portage_mtime) || ($e->cache_mtime != $db_ebuild->cache_mtime)) { $arr_update[] = $ebuild_name; $arr_insert[] = $ebuild_name; // Normally I'd add this here, but instead, just go ahead and mark it // right away, and avoid having it run twice. $db_ebuild->status = 2; if($verbose) { shell::msg("[update] $category_name/$ebuild_name"); } } } } } // FIXME just pass the IDs if(count($arr_delete)) { foreach($arr_delete as $ebuild_name) { if($verbose) shell::msg("[delete] $category_name/$ebuild_name"); $ebuild = $arr_ebuild_ids[$category_name][$package_name][$ebuild_name]; if($ebuild) { $tmp_update = array('status' => 2); $db->autoExecute('ebuild', $tmp_update, MDB2_AUTOQUERY_UPDATE, "id = ".$db->quote($id)); } } } } // Otherwise, insert all of them else { $arr_insert = $p->getEbuilds(); } if(count($arr_insert)) { $arr_insert = array_unique($arr_insert); foreach($arr_insert as $ebuild_name) { if($verbose) shell::msg("[insert] $category_name/$ebuild_name"); $e = new PortageEbuild("$category_name/$ebuild_name"); if(in_array($ebuild_name, $arr_update)) { $udate = $now; } else $udate = null; $arr = array( 'package' => $package_id, 'pf' => $e->pf, 'pv' => $e->pv, 'pr' => $e->pr, 'pvr' => $e->pvr, 'alpha' => $e->_alpha, 'beta' => $e->_beta, 'pre' => $e->_pre, 'rc' => $e->_rc, 'p' => $e->_p, 'version' => $e->version, 'slot' => $e->slot, 'portage_mtime' => $e->portage_mtime, 'cache_mtime' => $e->cache_mtime, 'status' => 1, 'udate' => $udate, 'source' => $e->source, ); $db->autoExecute('ebuild', $arr, MDB2_AUTOQUERY_INSERT); } } } } } unset($e); unset($p); unset($db_ebuild); unset($db_package); // Update the package_recent entries $sql = "DELETE FROM package_recent WHERE status = 1;"; $db->query($sql); $sql = "INSERT INTO package_recent SELECT DISTINCT package, MAX(cache_mtime), 1 FROM ebuild e GROUP BY package ORDER BY MAX(cache_mtime) DESC, package;"; $db->query($sql); ?>