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="https://crux.nu/bugs/?do=details&id=%s";
18 // Path of the subversion repository
19 $repo_path = "/home/crux/repo";
20
21 // Subversion commands
22 $svn_cmd = "/usr/bin/svn --non-interactive --config-dir /";
23 $svnlook_cmd = "/usr/bin/svnlook";
24
25 // Url of the online repo viewer
26 $svn_url = "http://crux.nu/svnweb/CRUX/revision/?rev=%s";
27
28 // Path of the recent changes pmwiki file
29 $wiki_file = "/home/crux/public_html/wiki.d/Site.AllRecentChanges";
30
31 // Map svn users to wiki profiles
32 $username_map = array(
33 "jaeger" => "jaeger",
34 "jue" => "JuergenDaubert",
35 "jw" => "JohannesWinkelmann",
36 "sip" => "SimoneRota" ,
37 "jdolan" => "JasonThomasDolan",
38 "jheino" => "JukkaHeino",
39 "tilman" => "TilmanSauerbeck",
40 "viper" => "SimonGloßner",
41 "sten" => "NickSteeves",
42 "falk" => "FalkHamann",
43 "aon" => "AnttiNykänen",
44 );
45
46 // Event: cache_id, tstamp, type(icon), date, time, user, url, description, notes
47 $events = array();
48
49 /**************** Last cached events *******************/
50
51 $dbc =& DB::connect($dsnc);
52 if (DB::isError($dbc)) die("Cannot connect to S database");
53 $dbc->setFetchMode(DB_FETCHMODE_ASSOC);
54 $last_cached_sql = "select cache_id from events where event_type='svn_commit' order by cache_id desc";
55 $res =& $dbc->limitQuery($last_cached_sql,0,1);
56 if (DB::isError($res)) die("Query error");
57 if ($res->numRows() === 0) {
58 $last_svn = 0;
59 } else {
60 $row =& $res->fetchRow();
61 $last_svn = $row['cache_id'];
62 }
63 $last_cached_sql = "select cache_id from events where event_type like 'task%' order by cache_id desc";
64 $res =& $dbc->limitQuery($last_cached_sql,0,1);
65 if (DB::isError($res)) die("Query error");
66 if ($res->numRows() === 0) {
67 $last_task = 0;
68 } else {
69 $row =& $res->fetchRow();
70 $last_task = $row['cache_id'];
71 }
72 $last_cached_sql = "select cache_id from events where event_type = 'wiki_changed' order by cache_id desc";
73 $res =& $dbc->limitQuery($last_cached_sql,0,1);
74 if (DB::isError($res)) die("Query error");
75 if ($res->numRows() === 0) {
76 $last_wiki = 0;
77 } else {
78 $row =& $res->fetchRow();
79 $last_wiki = $row['cache_id'];
80 }
81 /**************** Flyspray events ***********************/
82
83 $db =& DB::connect($dsn);
84 if (DB::isError($db)) die("Cannot connect to M database");
85 $db->setFetchMode(DB_FETCHMODE_ASSOC);
86
87 $sql = "select history_id, event_date, event_type, user_name, flyspray_history.task_id, item_summary, closure_comment
88 from flyspray_history
89 join flyspray_users on flyspray_users.user_id = flyspray_history.user_id
90 join flyspray_tasks on flyspray_tasks.task_id = flyspray_history.task_id
91 where history_id > $last_task";
92
93 $res =& $db->Query($sql);
94 if (DB::isError($res)) die("Query error");
95
96 while ($row =& $res->fetchRow()) {
97 // $etype = $fs_events[$row['event_type']];
98 $etype = $row['event_type'];
99 $euser = $row['user_name'];
100 $etid = $row['task_id'];
101 $edate = $row['event_date'];
102 $cache_id = $row['history_id'];
103 $description = "";
104 $date = date("Y-m-d", $edate);
105 $time = date("H:i", $edate);
106 $url = sprintf($task_url,$etid);
107 switch ($etype) {
108 case "1": // new task
109 $icon = "task_opened";
110 $description = "New task [[$url|$etid]] opened by $euser";
111 $notes = $row['item_summary'];
112 break;
113 case "2": // task closed
114 $icon = "task_closed";
115 $description = "Task [[$url|$etid]] closed by $euser";
116 if ($row['closure_comment'] != "" && $row['closure_comment'] != 0) { // weird flyspray!
117 $notes = $row['closure_comment'];
118 } else {
119 $notes = "";
120 }
121 break;
122 case "3": // task edited : fields, comments, attachments, ownership, related tasks, etc.
123 case "4":
124 case "5":
125 case "6":
126 case "7":
127 case "8":
128 case "14":
129 case "15":
130 case "16":
131 case "22":
132 case "23":
133 case "24":
134 case "25":
135 $icon = "task_changed";
136 $description = "Task [[$url|$etid]] modified by $euser";
137 $notes = "";
138 break;
139 }
140 if ($description !== "") {
141 $events[] = array( 'cache_id' => $cache_id, 'tstamp' => $edate, 'icon' => $icon, 'date' => $date,
142 'time' => $time, 'user' => $euser, 'url'=> $url, 'description' => $description, 'notes' => $notes,);
143 }
144 }
145
146
147 /**************** Subversion events ********************/
148 $out = array();
149 $res = 0;
150 exec("$svnlook_cmd youngest $repo_path", $out, $res);
151 $svn_latest = trim($out[0]);
152 if ($svn_latest != $last_svn) {
153 $last_svn++;
154 exec("$svn_cmd log file://$repo_path -r$last_svn:HEAD", $out, $res);
155 foreach ($out as $line) {
156 if ($line != "" && substr($line, 0, 5) != "-----") {
157 $revline = split("\|", $line);
158 if (count($revline) == 4) {
159 $rev = substr(trim($revline[0]),1);
160 $user = trim($revline[1]);
161 if (array_key_exists($user, $username_map)) {
162 $wikiname = $username_map[$user];
163 $user = "[[~" . $wikiname . "|" . $user . "]]";
164 }
165 $date = substr($revline[2],1,10);
166 $time = substr($revline[2],12,5);
167 $url = sprintf($svn_url, $rev);
168 $revurl = "[[$url|$rev]]";
169 $description = "Revision $revurl committed by $user";
170 $tstamp = strtotime("$date $time:00");
171 } else {
172 $icon = "svn_commit";
173 $notes = trim($line);
174 $events[] = array( 'cache_id' => $rev, 'tstamp' => $tstamp, 'icon' => $icon, 'date' => $date,
175 'time' => $time, 'user' => $user, 'url'=>$url, 'description' => $description, 'notes' => $notes);
176 }
177 }
178 }
179 }
180
181 /****************** PmWiki events *********************/
182 $lines = file($wiki_file);
183 $chline = "";
184 foreach ($lines as $line) {
185 if (substr($line,0,5) == "text=") {
186 $chline = substr($line,7);
187 }
188 }
189 if ($chline != "") {
190 $wikiedits = split('\*', $chline);
191 $icon = "wiki_changed";
192 foreach ($wikiedits as $ed) {
193 preg_match('/\[\[.*\]\] ./', $ed, $matches);
194 $page = $matches[0];
195 preg_match('/by \[\[.*\]\]/', $ed, $matches);
196 $user = $matches[0];
197 preg_match("/\=(.*)\=/s",$ed,$matches);
198 $notes = $matches[1];
199 preg_match("/\. \. \. (.*?) by/s",$ed,$matches);
200 $date = $matches[1];
201 $date = str_replace(", at", "", $date); // old entry format
202 $tstamp = strtotime($date);
203 preg_match('/(..\:..)/',$date,$matches);
204 $time = $matches[0];
205 $date = date("Y-m-d", $tstamp);
206 $action = "?action=diff#" . urlencode($date . " " . $time) . "|diff";
207 $page_diff = trim(str_replace("]]", $action."]]", $page));
208 preg_match('/\[\[(.*)\|diff\]\]/', $page_diff, $matches);
209 $url = $matches[1];
210 $url = "http://crux.nu/".str_replace(".","/", $url);
211 $description = "Wiki page $page edited $user ($page_diff)";
212 if ($tstamp > $last_wiki) {
213 $events[] = array( 'cache_id' => $tstamp, 'tstamp' => $tstamp, 'icon' => $icon, 'date' => $date,
214 'time' => $time, 'user' => $user, 'url' => $url, 'description' => $description, 'notes' => $notes);
215 }
216 }
217 }
218
219 /*************** Finally, all events *********************/
220 $sth = $dbc->prepare("insert into events values (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
221 foreach ($events as $evt) {
222 $res = $dbc->execute($sth, $evt);
223 if (DB::isError($res)) die("Query error");
224 }
225
226 ?>
|