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&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&page=dokugource&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&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