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:2.7","ports/opt:2.7","ports/xorg:2.7","ports/xfce:2.7","tools/pkgutils","tools/prt-get","system/iso:2.7");
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 );
45
46 // Path of the recent changes pmwiki file
47 $wiki_file = "/home/crux/public_html/wiki.d/Site.AllRecentChanges";
48
49 // Event: cache_id, tstamp, type(icon), date, time, user, url, description, notes
50 $events = array();
51
52 /**************** Last cached events *******************/
53
54 $dbc =& DB::connect($dsnc);
55 if (DB::isError($dbc)) die("Cannot connect to S database");
56 $dbc->setFetchMode(DB_FETCHMODE_ASSOC);
57 $last_cached_sql = "select cache_id from events where event_type like 'task%' order by cache_id desc";
58 $res =& $dbc->limitQuery($last_cached_sql,0,1);
59 if (DB::isError($res)) die("Query error");
60 if ($res->numRows() === 0) {
61 $last_task = 0;
62 } else {
63 $row =& $res->fetchRow();
64 $last_task = $row['cache_id'];
65 }
66 $last_cached_sql = "select cache_id from events where event_type = 'wiki_changed' order by cache_id desc";
67 $res =& $dbc->limitQuery($last_cached_sql,0,1);
68 if (DB::isError($res)) die("Query error");
69 if ($res->numRows() === 0) {
70 $last_wiki = 0;
71 } else {
72 $row =& $res->fetchRow();
73 $last_wiki = $row['cache_id'];
74 }
75
76 function last_cached_git($repo) {
77 global $dbc;
78 $last_cached_sql = "select cache_id from events where event_type='git_commit_$repo' order by event_tstamp desc";
79 $res =& $dbc->limitQuery($last_cached_sql,0,1);
80 if (DB::isError($res)) die("Query error");
81 if ($res->numRows() === 0) {
82 $last_git = "";
83 } else {
84 $row =& $res->fetchRow();
85 $last_git = $row['cache_id'];
86 }
87 return $last_git;
88 }
89
90 /**************** Flyspray events ***********************/
91
92 $db =& DB::connect($dsn);
93 if (DB::isError($db)) die("Cannot connect to M database");
94 $db->setFetchMode(DB_FETCHMODE_ASSOC);
95
96 $sql = "select history_id, event_date, event_type, user_name, flyspray_history.task_id, item_summary, closure_comment
97 from flyspray_history
98 join flyspray_users on flyspray_users.user_id = flyspray_history.user_id
99 join flyspray_tasks on flyspray_tasks.task_id = flyspray_history.task_id
100 where history_id > $last_task";
101
102 $res =& $db->Query($sql);
103 if (DB::isError($res)) die("Query error");
104
105 while ($row =& $res->fetchRow()) {
106 // $etype = $fs_events[$row['event_type']];
107 $etype = $row['event_type'];
108 $euser = $row['user_name'];
109 $etid = $row['task_id'];
110 $edate = $row['event_date'];
111 $cache_id = $row['history_id'];
112 $description = "";
113 $date = date("Y-m-d", $edate);
114 $time = date("H:i", $edate);
115 $url = sprintf($task_url,$etid);
116 switch ($etype) {
117 case "1": // new task
118 $icon = "task_opened";
119 $description = "New task [[$url|$etid]] opened by $euser";
120 $notes = $row['item_summary'];
121 break;
122 case "2": // task closed
123 $icon = "task_closed";
124 $description = "Task [[$url|$etid]] closed by $euser";
125 if ($row['closure_comment'] != "" && $row['closure_comment'] != 0) { // weird flyspray!
126 $notes = $row['closure_comment'];
127 } else {
128 $notes = "";
129 }
130 break;
131 case "3": // task edited : fields, comments, attachments, ownership, related tasks, etc.
132 case "4":
133 case "5":
134 case "6":
135 case "7":
136 case "8":
137 case "14":
138 case "15":
139 case "16":
140 case "22":
141 case "23":
142 case "24":
143 case "25":
144 $icon = "task_changed";
145 $description = "Task [[$url|$etid]] modified by $euser";
146 $notes = "";
147 break;
148 }
149 if ($description !== "") {
150 $events[] = array( 'cache_id' => $cache_id, 'tstamp' => $edate, 'icon' => $icon, 'date' => $date,
151 'time' => $time, 'user' => $euser, 'url'=> $url, 'description' => $description, 'notes' => $notes,);
152 }
153 }
154
155 /****************** PmWiki events *********************/
156 $lines = file($wiki_file);
157 $chline = "";
158 foreach ($lines as $line) {
159 if (substr($line,0,5) == "text=") {
160 $chline = substr($line,7);
161 }
162 }
163 if ($chline != "") {
164 $wikiedits = split('\*', $chline);
165 $icon = "wiki_changed";
166 foreach ($wikiedits as $ed) {
167 preg_match('/\[\[.*\]\] ./', $ed, $matches);
168 $page = $matches[0];
169 preg_match('/by \[\[.*\]\]/', $ed, $matches);
170 $user = $matches[0];
171 preg_match("/\=(.*)\=/s",$ed,$matches);
172 $notes = $matches[1];
173 preg_match("/\. \. \. (.*?) by/s",$ed,$matches);
174 $date = $matches[1];
175 $date = str_replace(", at", "", $date); // old entry format
176 $tstamp = strtotime($date);
177 preg_match('/(..\:..)/',$date,$matches);
178 $time = $matches[0];
179 $date = date("Y-m-d", $tstamp);
180 $action = "?action=diff#" . urlencode($date . " " . $time) . "|diff";
181 $page_diff = trim(str_replace("]]", $action."]]", $page));
182 preg_match('/\[\[(.*)\|diff\]\]/', $page_diff, $matches);
183 $url = $matches[1];
184 $url = "http://crux.nu/".str_replace(".","/", $url);
185 $description = "Wiki page $page edited $user ($page_diff)";
186 if ($tstamp > $last_wiki) {
187 $events[] = array( 'cache_id' => $tstamp, 'tstamp' => $tstamp, 'icon' => $icon, 'date' => $date,
188 'time' => $time, 'user' => $user, 'url' => $url, 'description' => $description, 'notes' => $notes);
189 }
190 }
191 }
192
193 /******************* Git events ***********************/
194
195 foreach ($git_repos as $repo) {
196 $branch = "";
197 if (strpos($repo, ":") !== FALSE) {
198 $tmp = explode(':', $repo);
199 $repo = $tmp[0];
200 $branch = $tmp[1];
201 }
202 $pos = strpos($repo, "/");
203 $reponame = substr($repo, $pos+1);
204 $last_git = last_cached_git($reponame);
205 $out = array();
206 $res = 0;
207 $done = array();
208 exec("GIT_DIR=$git_root/$repo.git git log -n 1 $branch", $out, $res);
209 $git_latest = trim(str_replace("commit ", "", $out[0]));
210 unset($out);
211 $res = 0;
212 if ($git_latest != $last_git) {
213 if ($last_git == "") {
214 exec("GIT_DIR=$git_root/$repo.git git log $branch", $out, $res);
215 } else {
216 exec("GIT_DIR=$git_root/$repo.git git log $last_git..$git_latest $branch", $out, $res);
217 }
218 $last_git = $git_latest;
219 foreach ($out as $line) {
220 if (substr($line, 0, 7) == "commit ") {
221 $rev = substr($line, 7);
222 $url = sprintf($git_url, $repo, $rev);
223 $compact_rev = substr($rev,0,4)."..".substr($rev,-4,4);
224 $revurl = "[[$url|$compact_rev]]";
225 } else if (substr($line, 0, 7) == "Merge: ") {
226 } else if (substr($line, 0, 8) == "Author: ") {
227 $user = substr($line, 8);
228 $pos = strpos($user, "<");
229 if ($pos !== FALSE)
230 $user = trim(substr($user,0,$pos));
231 if (array_key_exists($user, $git_username_map)) {
232 $wikiname = $git_username_map[$user];
233 $user = "[[~" . $wikiname . "|" . $user . "]]";
234 }
235 $description = "$revurl committed by $user";
236 } else if (substr($line, 0, 8) == "Date: ") {
237 $date = substr($line, 8);
238 $tstamp = strtotime($date);
239 $date = date("Y-m-d", $tstamp);
240 $time = date("H:i", $tstamp);
241 } else if (trim($line) != "" && !array_key_exists($rev, $done)) {
242 $icon = "git_commit_$reponame";
243 $notes = trim($line);
244 $events[] = array( 'cache_id' => $rev, 'tstamp' => $tstamp, 'icon' => $icon, 'date' => $date,
245 'time' => $time, 'user' => $user, 'url'=>$url, 'description' => $description, 'notes' => $notes);
246 $done[$rev] = 1;
247 }
248 }
249 }
250 }
251
252 /*************** Finally, all events *********************/
253 $sth = $dbc->prepare("insert into events values (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
254 foreach ($events as $evt) {
255 $res = $dbc->execute($sth, $evt);
256 if (DB::isError($res)) die ("Query error");
257 }
258
259 ?>
|