summaryrefslogtreecommitdiff
blob: 8bc0ce2fe5b507a89ef3e7fe4b7bf62bafa880c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<?

//  $verbose = true;
// 	$debug = false;

	/**
	 * This script creates a temporary file in /tmp named znurt[foo] that sets itself
	 * to the mtime of the latest package mtime in the database.  This way, I can simply
	 * use find to do all the heavy lifting to quickly locate any package directories
	 * that were modified since last import.
	 *
	 * Directory names in portage tend to get their mtimes updated on a regular basis;
	 * generally speaking, I'd say that about 50% of them change each sync, though
	 * I can't pin down why.  Packages that haven't been touched in ages get their
	 * directory modified for no reason I can see.
	 *
	 * As a result, the mtime of a package is notoriously unreliable as a reference
	 * for anything.  However, if it does change, it *can* indicate that an ebuild or
	 * file was removed, so, with all due diligence, we will check those later to see
	 * if something was actually taken away, and update the database.
	 */
	
	/**
	 * This is the first file where tables start to have a status column.  There is
	 * only three status levels: 0 - completely imported, and "live", 1 - being updated,
	 * or newly inserted and 2 - flagged to be removed.
	 *
	 * The package table only uses 0 and 1.  The website should ignore the status, since
	 * the changes are only to notify the other scripts that something has changed, and to
	 * look more closely at the files related to the package.
	 */

	require_once 'header.php';
	
	if(!$tree) {
		require_once 'class.portage.tree.php';
		$tree = new PortageTree();
	}
	
	require_once 'class.portage.category.php';
	require_once 'class.portage.package.php';
	require_once 'class.db.package.php';
	
	$arr_update = array();
	
	// Find the packages updated since last time
	$sql = "SELECT COUNT(1) FROM package;";
	$count = $db->getOne($sql);
	if(!$count || $debug)
		$all = true;
	else {
	
		$sql = "SELECT MAX(portage_mtime) FROM package;";
		$max_portage_mtime = $db->getOne($sql);
		
		if(is_null($max_portage_mtime))
			$all = true;
	
	}
	
	if(!$all) {
	
		$categories = $tree->getCategories();
	
		$tmp = tempnam('/tmp', 'znurt');
		touch($tmp, $max_portage_mtime);
		
		$arr = array();
		
		$dir = $tree->getTree();
		
		foreach($categories as $category_name) {
			
			$category_dir = $dir."/".$category_name;
			
			$exec = "find $category_dir -mindepth 1 -maxdepth 1 -type d -newer $tmp";
			$arr = array_merge($arr, shell::cmd($exec));
		}
		unlink($tmp);
		
		foreach($arr as $name) {
		
			$name = str_replace($dir."/", "", $name);
			$tmp = explode("/", $name);
			$arr_update[$tmp[0]][] = $tmp[1];
		
		}
		
	}
	
	$sql = "SELECT id, name FROM category ORDER BY name;";
	$arr_categories = $db->getAssoc($sql);
	
	$sql = "SELECT category, package, category_name, package_name FROM view_package;";
	$arr = $db->getAll($sql);
	foreach($arr as $row) {
		$arr_package_ids[$row['category_name']][$row['package_name']] = $row['package'];
	}
	
	$table = 'package';
	
	foreach($arr_categories as $category_id => $category_name) {
	
		$c = new PortageCategory($category_name);
		$arr_packages = $c->getPackages();
		
		$arr_diff = importDiff('package', $arr_packages, "category = $category_id");
		
		// FIXME Flag to be deleted, execute later
		// This is dangerous to delete right now because 1) it will take a *long* time, and
		// 2) you're breaking the whole "snapshot" approach.
		if(count($arr_diff['delete'])) {
			foreach($arr_diff['delete'] as $package_name) {
				$sql = "DELETE FROM $table WHERE name = ".$db->quote($package_name)." AND category = $category_id;";
				$db->query($sql);
			}
		}
		
		if(count($arr_diff['insert'])) {
		
			foreach($arr_diff['insert'] as $package_name) {
			
				$p = new PortagePackage($category_name, $package_name);
			
 				$arr_insert = array(
 					'category' => $category_id,
 					'name' => $package_name,
 					'changelog' => $p->changelog,
 					'portage_mtime' => $p->portage_mtime,
 					'changelog_mtime' => $p->changelog_mtime,
 					'metadata_mtime' => $p->metadata_mtime,
 				);
				$db->autoExecute($table, $arr_insert, MDB2_AUTOQUERY_INSERT);
			}
		}
	}
	
	unset($c);
	
	foreach($arr_update as $category_name => $arr_packages) {
	
		foreach($arr_packages as $package_name) {
			
			$package_id = $arr_package_ids[$category_name][$package_name];
			
			if($package_id) {
			
				$p = new PortagePackage($category_name, $package_name);
				
				if($p->portage_mtime > $max_portage_mtime || $debug) {
				
					if($debug) {
						shell::msg("Updating $category_name/$package_name id: $package_id");
					}
				
					$db_package = new DBPackage($package_id);
					
					// If the mtime of this directory changed, then a file
					// somewhere has been added or deleted.  Flag the status
					// to make sure we examine that directory later.
					if($p->portage_mtime != $db_package->portage_mtime) {
						$db_package->portage_mtime = $p->portage_mtime;
						$db_package->status = 1;
					}
					
					if($p->changelog_mtime != $db_package->changelog_mtime) {
						$db_package->changelog_mtime = $p->changelog_mtime;
						$db_package->changelog = $p->changelog;
					}
					
					if($p->metadata_mtime != $db_package->metadata_mtime)
						$db_package->metadata_mtime = $p->metadata_mtime;
				
				}
			}
		}
	}
	
?>