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.'action.php'); 16 17class action_plugin_dokugource extends DokuWiki_Action_Plugin { 18 var $colors = array(); 19 var $log = array(); 20 21 // return some info 22 function getInfo() { 23 return confToHash(dirname(__FILE__).'/INFO'); 24 } 25 26 /** 27 * Register plugin hooks 28 */ 29 function register(&$controller) { 30 $controller->register_hook('IO_WIKIPAGE_WRITE', 'AFTER', $this, 'gourcecolor'); 31 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'evalgourcerequest'); 32 } 33 34 /** 35 * Get gourcecolor 36 * @param &$event dokuwiki event object 37 * @param $args handler arguments 38 */ 39 function gourcecolor(&$event, $args) { 40 global $conf; 41 global $ID; 42 if(preg_match('`~~gourcecolor(<|:|>)#?([0-9a-z]{3}([0-9a-z]{3})?)~~`i', $event->data[0][1], $m)) { 43 $c = strtoupper($m[2]); 44 if(strlen($c) == 3) { 45 $c = str_split($c); 46 $c = $c[0].$c[0].$c[1].$c[1].$c[2].$c[2]; 47 } 48 $ns = $event->data[1].':'.(($m[1] == '<') ? '' : $event->data[2]); 49 $ls = preg_split('`\n+`', trim(@file_get_contents($conf['metadir'].'/gource.colors'))); 50 if($fp = fopen($conf['metadir'].'/gource.colors', 'w')) { 51 foreach($ls as $l) { 52 if(!$l) continue; 53 if(array_shift(preg_split('`\s+`', $l, 2)) != $ns) fwrite($fp, $l."\n"); 54 } 55 fwrite($fp, $ns.' '.$c."\n"); 56 fclose($fp); 57 } 58 } 59 } 60 61 /** 62 * Eval if a gource log is requiered 63 * @param &$event dokuwiki event object 64 * @param $args handler arguments 65 */ 66 function evalgourcerequest(&$event, $args) { 67 global $conf; 68 global $ID; 69 70 // get autorisation 71 if(!isset($_GET['dokugource_key']) || empty($_GET['dokugource_key'])) return; 72 if(!preg_match('`^[a-z0-9]{8,64}$`i', $_GET['dokugource_key'])) die(); 73 $key = $_GET['dokugource_key']; 74 75 $ns = $ID; 76 if($ns) { 77 $ns = str_replace('/', ':', trim($ns, '/:')); 78 if(!@is_dir($conf['datadir'].'/'.str_replace(':', '/', $ns).'/')) { 79 if(@is_file($conf['datadir'].'/'.str_replace(':', '/', $ns).'.txt')) { 80 $ns = preg_replace('`^(.*)\:[^\:]+$`', '$1', $ns); 81 } 82 } 83 } 84 $ns = trim($ns, '/:'); 85 86 $auto = preg_split('`\n+`', @file_get_contents(DOKU_CONF.'/gource.cnf.php')); 87 array_shift($auto); 88 $autons = false; 89 foreach($auto as $l) { 90 if(preg_match('`^'.$key.'(\s+(.*))?$`', $l, $m)) { 91 $autons = trim($m[2], '/:'); 92 } 93 } 94 if($autons === false) die(); 95 if(substr($ns, 0, strlen($autons)) != $autons) die(); 96 97 $from = (isset($_GET['dokugource_from']) && !empty($_GET['dokugource_from'])) ? (int)$_GET['dokugource_from'] : 0; 98 99 $this->colors = array(); 100 foreach(preg_split('`\n+`', trim(@file_get_contents($conf['metadir'].'/gource.colors'))) as $l) { 101 if(!$l) continue; 102 $l = preg_split('`\s+`', $l, 2); 103 $this->colors[$l[0]] = $l[1]; 104 } 105 106 $strip = explode(':', $ns); 107 array_pop($strip); 108 $strip = count($strip) ? strlen(implode(':', $strip)) : 0; 109 $this->crawl($conf['metadir'].($ns ? '/'.str_replace(':', '/', $ns) : ''), $strip, $from); 110 sort($this->log); 111 112 header('Content-Type: text/plain; charset=utf-8'); 113 echo trim(implode("\n", $this->log)."\nDone\n"); 114 exit(); 115 } 116 117 function color($p) { 118 $ns = preg_replace('`^(.*\:)[^\:]+$`', '$1', $p); 119 if(isset($this->colors[$p])) return $this->colors[$p]; 120 if(isset($this->colors[$ns])) return $this->colors[$ns]; 121 122 $this->colors[$p] = sprintf('%02X%02X%02X', rand(0, 255), rand(0, 255), rand(0, 255)); 123 return $this->colors[$p]; 124 } 125 126 function crawl($p, $strip, $from) { 127 if(!@is_dir($p)) return; 128 foreach(scandir($p) as $i) { 129 if($i == '.' || $i == '..') continue; 130 if(is_file($p.'/'.$i)) if(preg_match('`\.changes$`', $i)) { 131 foreach(preg_split('`\n+`', trim(@file_get_contents($p.'/'.$i))) as $l) { 132 if(!$l) continue; 133 if(preg_match('`^\s*([0-9]+)\s+([^\s]+)\s+([a-z]{1,3})\s+([^\s]+)\s+([^\s]+)`i', $l, $m)) { 134 if((int)$m[1] < $from) continue; 135 if(preg_match('`(C|cc|sc)`i', $m[3])) { 136 $m[3] = 'A'; 137 }elseif(preg_match('`(D|dc|hc)`i', $m[3])) { 138 $m[3] = 'D'; 139 }else{ 140 $m[3] = 'M'; 141 } 142 $id = str_replace(':', '/', $m[4]); 143 if($strip) $id = trim(substr($id, $strip), '/:'); 144 $this->log[] = $m[1].'|'.$m[5].'|'.$m[3].'|'.$id.'|'.$this->color($m[4]); 145 } 146 } 147 } 148 149 if(is_dir($p.'/'.$i)) $this->crawl($p.'/'.$i, $strip, $from); 150 } 151 } 152} 153