1 #!/usr/bin/php
2 <?php
3
4 /* Caches the timeline events into a sqlite db */
5
6 require_once('DB.php');
7
8 /**************** Configuration ***********************/
9
10 // PEAR dns for the flyspray db and sqlite cache db,
11 // ie
12 // $dsn = 'mysql://username:password@host/dbname';
13 // $dsnc = 'sqlite:////path/to/database.db';
14 require_once("tlcacher_config.php");
15
16 // Url of the detailed task
17 $task_url="http://crux.nu/bugs/?do=details&task_id=%s";
18
19 // Gitweb url for commits
20 $git_url = "http://crux.nu/gitweb/?p=%s.git;a=commitdiff;h=%s";
21 // append ":branch" to the repo name to restrict logs to 'branch'
22 $git_repos = array("ports/core:3.0", "ports/opt:3.0","ports/xorg:3.0","ports/xfce:3.0","ports/compat-32","tools/pkgutils","tools/prt-get","system/iso:3.0");
23 $git_root = "/home/crux/scm";
24
25 // Map git authors to wiki profiles
26 $git_username_map = array(
27 "Per Lidén" => "PerLiden",
28 "Matt Housh" => "jaeger",
29 "Juergen Daubert" => "JuergenDaubert",
30 "Johannes Winkelmann" => "JohannesWinkelmann",
31 "Simone Rota" => "SimoneRota" ,
32 "Jason Thomas Dolan" => "JasonThomasDolan",
33 "Jukka Heino" => "JukkaHeino",
34 "Tilman Sauerbeck" => "TilmanSauerbeck",
35 "Simon Gloßner" => "SimonGloßner",
36 "Nick Steeves" => "NickSteeves",
37 "Antti Nykänen" => "AnttiNykänen",
38 "Antti Nykanen" => "AnttiNykänen",
39 "Jose V Beneyto" => "JoseVBeneyto",
40 "JoseVBeneyto" => "JoseVBeneyto",
41 "Lucas Hazel" => "LucasHazel",
42 "Thomas Penteker" => "ThomasPenteker",
43 "Fredrik Rinnestam" => "FredrikRinnestam",
44 "Danny Rawlins" => "DannyRawlins",
45 );
46
47 // Path of the recent changes pmwiki file
48 $wiki_file = "/home/crux/public_html/wiki.d/Site.AllRecentChanges";
49
50 // Event: cache_id, tstamp, type(icon), date, time, user, url, description, notes
51 $events = array();
52
53 /**************** Last cached events *******************/
54
55 $dbc =& DB::connect($dsnc);
56 if (DB::isError($dbc)) die("Cannot connect to S database");
57 $dbc->setFetchMode(DB_FETCHMODE_ASSOC);
58 $last_cached_sql = "select cache_id from events where event_type like 'task%' order by cache_id desc";
59 $res =& $dbc->limitQuery($last_cached_sql,0,1);
60 if (DB::isError($res)) die("Query error");
61 if ($res->numRows() === 0) {
62 $last_task = 0;
63 } else {
64 $row =& $res->fetchRow();
65 $last_task = $row['cache_id'];
66 }
67 $last_cached_sql = "select cache_id from events where event_type = 'wiki_changed' order by cache_id desc";
68 $res =& $dbc->limitQuery($last_cached_sql,0,1);
69 if (DB::isError($res)) die("Query error");
70 if ($res->numRows() === 0) {
71 $last_wiki = 0;
72 } else {
73 $row =& $res->fetchRow();
74 $last_wiki = $row['cache_id'];
75 }
76
77 function last_cached_git($repo) {
78 global $dbc;
79 $last_cached_sql = "select cache_id from events where event_type='git_commit_$repo' order by event_tstamp desc";
80 $res =& $dbc->limitQuery($last_cached_sql,0,1);
81 if (DB::isError($res)) die("Query error");
82 if ($res->numRows() === 0) {
83 $last_git = "";
84 } else {
85 $row =& $res->fetchRow();
86 $last_git = $row['cache_id'];
87 }
88 return $last_git;
89 }
90
91 /**************** Flyspray events ***********************/
92
93 $db =& DB::connect($dsn);
94 if (DB::isError($db)) die("Cannot connect to M database");
95 $db->setFetchMode(DB_FETCHMODE_ASSOC);
96
97 $sql = "select history_id, event_date, event_type, flyspray_history.task_id, item_summary, closure_comment, real_name
98 from flyspray_history
99 join flyspray_users on flyspray_users.user_id = flyspray_history.user_id
100 join flyspray_tasks on flyspray_tasks.task_id = flyspray_history.task_id
101 where history_id > $last_task";
102
103 $res =& $db->Query($sql);
104 if (DB::isError($res)) die("Query error");
105
106 while ($row =& $res->fetchRow()) {
107 // $etype = $fs_events[$row['event_type']];
108 $etype = $row['event_type'];
109 $euser = $row['real_name'];
110 $etid = $row['task_id'];
111 $edate = $row['event_date'];
112 $cache_id = $row['history_id'];
113 $description = "";
114 $date = date("Y-m-d", $edate);
115 $time = date("H:i", $edate);
116 $url = sprintf($task_url,$etid);
117 switch ($etype) {
118 case "1": // new task
119 $icon = "task_opened";
120 $description = "New task [[$url|$etid]] opened by $euser";
121 $notes = $row['item_summary'];
122 break;
123 case "2": // task closed
124 $icon = "task_closed";
125 $description = "Task [[$url|$etid]] closed by $euser";
126 if ($row['closure_comment'] != "" && $row['closure_comment'] != 0) { // weird flyspray!
127 $notes = $row['closure_comment'];
128 } else {
129 $notes = "";
130 }
131 break;
132 case "3": // task edited : fields, comments, attachments, ownership, related tasks, etc.
133 case "4":
134 case "5":
135 case "6":
136 case "7":
137 case "8":
138 case "14":
139 case "15":
140 case "16":
141 case "22":
142 case "23":
143 case "24":
144 case "25":
145 $icon = "task_changed";
146 $description = "Task [[$url|$etid]] modified by $euser";
147 $notes = "";
148 break;
149 }
150 if ($description !== "") {
151 $events[] = array( 'cache_id' => $cache_id, 'tstamp' => $edate, 'icon' => $icon, 'date' => $date,
152 'time' => $time, 'user' => $euser, 'url'=> $url, 'description' => $description, 'notes' => $notes,);
153 }
154 }
155
156 /****************** PmWiki events *********************/
157 $lines = file($wiki_file);
158 $chline = "";
159 foreach ($lines as $line) {
160 if (substr($line,0,5) == "text=") {
161 $chline = substr($line,7);
162 }
163 }
164 if ($chline != "") {
165 $wikiedits = split('\*', $chline);
166 $icon = "wiki_changed";
167 foreach ($wikiedits as $ed) {
168 preg_match('/\[\[.*\]\] ./', $ed, $matches);
169 $page = $matches[0];
170 preg_match('/by \[\[.*\]\]/', $ed, $matches);
171 $user = $matches[0];
172 preg_match("/\=(.*)\=/s",$ed,$matches);
173 $notes = $matches[1];
174 preg_match("/\. \. \. (.*?) by/s",$ed,$matches);
175 $date = $matches[1];
176 $date = str_replace(", at", "", $date); // old entry format
177 $tstamp = strtotime($date);
178 preg_match('/(..\:..)/',$date,$matches);
179 $time = $matches[0];
180 $date = date("Y-m-d", $tstamp);
181 $action = "?action=diff#" . urlencode($date . " " . $time) . "|diff";
182 $page_diff = trim(str_replace("]]", $action."]]", $page));
183 preg_match('/\[\[(.*)\|diff\]\]/', $page_diff, $matches);
184 $url = $matches[1];
185 $url = "http://crux.nu/".str_replace(".","/", $url);
186 $description = "Wiki page $page edited $user ($page_diff)";
187 if ($tstamp > $last_wiki) {
188 $events[] = array( 'cache_id' => $tstamp, 'tstamp' => $tstamp, 'icon' => $icon, 'date' => $date,
189 'time' => $time, 'user' => $user, 'url' => $url, 'description' => $description, 'notes' => $notes);
190 }
191 }
192 }
193
194 /******************* Git events ***********************/
195
196 foreach ($git_repos as $repo) {
197 $branch = "";
198 if (strpos($repo, ":") !== FALSE) {
199 $tmp = explode(':', $repo);
200 $repo = $tmp[0];
201 $branch = $tmp[1];
202 }
203 $pos = strpos($repo, "/");
204 $reponame = substr($repo, $pos+1);
205 $last_git = last_cached_git($reponame);
206 $out = array();
207 $res = 0;
208 $done = array();
209 exec("GIT_DIR=$git_root/$repo.git git log -n 1 $branch", $out, $res);
210 $git_latest = trim(str_replace("commit ", "", $out[0]));
211 unset($out);
212 $res = 0;
213 if ($git_latest != $last_git) {
214 if ($last_git == "") {
215 exec("GIT_DIR=$git_root/$repo.git git log $branch", $out, $res);
216 } else {
217 exec("GIT_DIR=$git_root/$repo.git git log $last_git..$git_latest $branch", $out, $res);
218 }
219 $last_git = $git_latest;
220 foreach ($out as $line) {
221 if (substr($line, 0, 7) == "commit ") {
222 $rev = substr($line, 7);
223 $url = sprintf($git_url, $repo, $rev);
224 $compact_rev = substr($rev,0,4)."..".substr($rev,-4,4);
225 $revurl = "[[$url|$compact_rev]]";
226 } else if (substr($line, 0, 7) == "Merge: ") {
227 } else if (substr($line, 0, 8) == "Author: ") {
228 $user = substr($line, 8);
229 $pos = strpos($user, "<");
230 if ($pos !== FALSE)
231 $user = trim(substr($user,0,$pos));
232 if (array_key_exists($user, $git_username_map)) {
233 $wikiname = $git_username_map[$user];
234 $user = "[[~" . $wikiname . "|" . $user . "]]";
235 }
236 $description = "$revurl committed by $user";
237 } else if (substr($line, 0, 8) == "Date: ") {
238 $date = substr($line, 8);
239 $tstamp = strtotime($date);
240 $date = date("Y-m-d", $tstamp);
241 $time = date("H:i", $tstamp);
242 } else if (trim($line) != "" && !array_key_exists($rev, $done)) {
243 $icon = "git_commit_$reponame";
244 $notes = trim($line);
245 $events[] = array( 'cache_id' => $rev, 'tstamp' => $tstamp, 'icon' => $icon, 'date' => $date,
246 'time' => $time, 'user' => $user, 'url'=>$url, 'description' => $description, 'notes' => $notes);
247 $done[$rev] = 1;
248 }
249 }
250 }
251 }
252
253 /*************** Finally, all events *********************/
254 $sth = $dbc->prepare("insert into events values (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
255 foreach ($events as $evt) {
256 $res = $dbc->execute($sth, $evt);
257 if (DB::isError($res)) die ("Query error");
258 }
259
260 ?>
|