1<?php
2/**
3 * DokuGource Plugin: extract gource log from the wiki
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Etienne Meleard <etienne.meleard@free.fr>
7 *
8 * 2010/05/19 : Creation
9 */
10
11// must be run within Dokuwiki
12if(!defined('DOKU_INC')) die();
13
14if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
15require_once(DOKU_PLUGIN.'admin.php');
16
17/**
18 * All DokuWiki plugins to extend the admin function
19 * need to inherit from this class
20 */
21class admin_plugin_dokugource extends DokuWiki_Admin_Plugin {
22	var $colors = array();
23	var $log = array();
24	var $from = -1;
25	var $ns = '';
26
27	// return some info
28	function getInfo() {
29		return confToHash(dirname(__FILE__).'/INFO');
30	}
31
32	function __construct() {
33		global $conf;
34		$this->disabled = (isset($conf['pluginfarm']) && ($conf['pluginfarm'] == 0));
35	}
36
37	/**
38	 * Return prompt for admin menu
39	 * @param $l language identifier
40	 * @return nothing if not in farmer context, menu title otherwise
41	 */
42	function getMenuText($l) {
43		if(!$this->disabled) return 'Gource Log';
44		return '';
45	}
46
47	/**
48	 * Return sort order for position in admin menu
49	 * @return integer
50	 */
51	function getMenuSort() {
52		return 20;
53	}
54
55	/**
56	 * Handle requests
57	 */
58	function handle() {
59		global $conf;
60
61		// Do nothing if disabled / not installed
62		if($this->disabled) return;
63
64		if(array_key_exists('download', $_GET)) if(@file_exists($conf['metadir'].'gource.log')) {
65			$f = @file_get_contents($conf['metadir'].'gource.log');
66			header('Content-Transfer-Encoding: binary');
67			header('Content-Length: '.strlen($f));
68			header('Content-Disposition: attachment; filename="gource.log"');
69			header('Expires: 0');
70			header('Cache-Control: no-cache, must-revalidate');
71			header('Pragma: no-cache');
72			echo $f;
73			exit();
74 		}
75
76 		if(isset($_POST['dokugource_savecnf'])) {
77			if($fp = fopen(DOKU_CONF.'/gource.cnf.php', 'w')) {
78				fwrite($fp, "<?php exit(); ?>\n\n".trim($_POST['dokugource_cnf']));
79				fclose($fp);
80			}
81		}
82
83 		if(isset($_POST['dokugource_generate'])) {
84			$this->from = (isset($_POST['dokugource_from']) && !empty($_POST['dokugource_from'])) ? strtotime($_POST['dokugource_from']) : 0;
85			if($this->from === false) $this->from = 0;
86
87			$this->ns = (isset($_POST['dokugource_ns']) && !empty($_POST['dokugource_ns'])) ? $_POST['dokugource_ns'] : '';
88			if($this->ns) {
89				$this->ns = str_replace('/', ':', trim($this->ns, '/:'));
90				if(!@is_dir($conf['datadir'].'/'.str_replace(':', '/', $this->ns).'/')) {
91					if(@is_file($conf['datadir'].'/'.str_replace(':', '/', $this->ns).'.txt')) {
92						$this->ns = preg_replace('`^(.*)\:[^\:]+$`', '$1', $this->ns);
93					}
94				}
95			}
96
97			$this->colors = array();
98			foreach(preg_split('`\n+`', trim(@file_get_contents($conf['metadir'].'/gource.colors'))) as $l) {
99				if(!$l) continue;
100				$l = preg_split('`\s+`', $l, 2);
101				$this->colors[$l[0]] = $l[1];
102			}
103
104			$strip = explode(':', $this->ns);
105			array_pop($strip);
106			$strip = count($strip) ? strlen(implode(':', $strip)) : 0;
107			$this->crawl($conf['metadir'].($this->ns ? '/'.str_replace(':', '/', $this->ns) : ''), $strip, $this->from);
108			sort($this->log);
109
110			if($fp = fopen($conf['metadir'].'gource.log', 'w')) {
111				fwrite($fp, trim(implode("\n", $this->log)));
112				fclose($fp);
113			}
114		}
115
116		return true;
117	}
118
119	function color($p) {
120		$ns = preg_replace('`^(.*\:)[^\:]+$`', '$1', $p);
121		if(isset($this->colors[$p])) return $this->colors[$p];
122		if(isset($this->colors[$ns])) return $this->colors[$ns];
123
124		$this->colors[$p] = sprintf('%02X%02X%02X', rand(0, 255), rand(0, 255), rand(0, 255));
125		return $this->colors[$p];
126	}
127
128	function crawl($p, $strip, $from) {
129		if(!@is_dir($p)) return;
130		foreach(scandir($p) as $i) {
131			if($i == '.' || $i == '..') continue;
132			if(is_file($p.'/'.$i)) if(preg_match('`\.changes$`', $i)) {
133				foreach(preg_split('`\n+`', trim(@file_get_contents($p.'/'.$i))) as $l) {
134					if(!$l) continue;
135					if(preg_match('`^\s*([0-9]+)\s+([^\s]+)\s+([a-z]{1,3})\s+([^\s]+)\s+([^\s]+)`i', $l, $m)) {
136						if((int)$m[1] < $from) continue;
137						if(preg_match('`(C|cc|sc)`i', $m[3])) {
138							$m[3] = 'A';
139						}elseif(preg_match('`(D|dc|hc)`i', $m[3])) {
140							$m[3] = 'D';
141						}else{
142							$m[3] = 'M';
143						}
144						$id = str_replace(':', '/', $m[4]);
145						if($strip) $id = trim(substr($id, $strip), '/:');
146						$this->log[] = $m[1].'|'.$m[5].'|'.$m[3].'|'.$id.'|'.$this->color($m[4]);
147					}
148				}
149			}
150
151			if(is_dir($p.'/'.$i)) $this->crawl($p.'/'.$i, $strip, $from);
152		}
153	}
154
155	/**
156	 * Output appropriate html
157	 */
158	function html() {
159		global $conf;
160
161		// Do nothing if disabled / not installed
162		if($this->disabled) return;
163
164		ptln('<h1>Gource Log</h1>');
165		ptln('<form action="?do=admin&amp;page=dokugource" method="post">');
166		ptln('	Start : <input type="text" name="dokugource_from" value="'.date('Y-m-d H:i:s', ($this->from >= 0) ? $this->from : (time() - 5*24*3600)).'" /><br />');
167		ptln('	Namespace : <input type="text" name="dokugource_ns" value="'.($this->ns ? $this->ns : '').'" /><br />');
168		ptln('	<input type="submit" name="dokugource_generate" value="OK" />');
169		ptln('</form>');
170
171		if(isset($_POST['dokugource_generate'])) {
172			if(@file_exists($conf['metadir'].'gource.log')) ptln('<a href="?do=admin&amp;page=dokugource&amp;download">Download</a>');
173			ptln('<textarea style="width:95%;margin:0 auto" rows="20">');
174			ptln(implode("\n", $this->log));
175			ptln('</textarea>');
176		}
177
178		ptln('<h2>Trusted keys autorized namespaces pairs</h2>');
179		ptln('<form action="?do=admin&amp;page=dokugource" method="post">');
180		ptln('	<textarea rows="10" name="dokugource_cnf">'.preg_replace('`\s*<\?php[^\?]+\?>\s*`', '', @file_get_contents(DOKU_CONF.'/gource.cnf.php')).'</textarea><br />');
181		ptln('	<input type="submit" name="dokugource_savecnf" value="OK" />');
182		ptln('</form>');
183	}
184}
185
186?>
187