diff options
Diffstat (limited to 'lib/plugins/importoldchangelog/action.php')
-rw-r--r-- | lib/plugins/importoldchangelog/action.php | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/lib/plugins/importoldchangelog/action.php b/lib/plugins/importoldchangelog/action.php new file mode 100644 index 000000000..400ff6a18 --- /dev/null +++ b/lib/plugins/importoldchangelog/action.php @@ -0,0 +1,177 @@ +<?php +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); +require_once(DOKU_PLUGIN.'action.php'); + +class action_plugin_importoldchangelog extends DokuWiki_Action_Plugin { + + function getInfo(){ + return array( + 'author' => 'Ben Coburn', + 'email' => 'btcoburn@silicodon.net', + 'date' => '2006-08-30', + 'name' => 'Import Old Changelog', + 'desc' => 'Imports and converts the single file changelog '. + 'from the 2006-03-09b release to the new format. '. + 'Also reconstructs missing changelog data from '. + 'old revisions kept in the attic.', + 'url' => 'http://wiki.splitbrain.org/wiki:changelog' + ); + } + + function register(&$controller) { + $controller->register_hook('TEMPORARY_CHANGELOG_UPGRADE_EVENT', 'BEFORE', $this, 'run_import'); + } + + function importOldLog($line, &$logs) { + global $lang; + /* + // Note: old log line format + //$info['date'] = $tmp[0]; + //$info['ip'] = $tmp[1]; + //$info['id'] = $tmp[2]; + //$info['user'] = $tmp[3]; + //$info['sum'] = $tmp[4]; + */ + $oldline = @explode("\t", $line); + if ($oldline!==false && count($oldline)>1) { + // trim summary + $wasMinor = (substr($oldline[4], 0, 1)==='*'); + $sum = rtrim(substr($oldline[4], 1), "\n"); + // guess line type + $type = 'E'; + if ($wasMinor) { $type = 'e'; } + if ($sum===$lang['created']) { $type = 'C'; } + if ($sum===$lang['deleted']) { $type = 'D'; } + // build new log line + $tmp = array(); + $tmp['date'] = $oldline[0]; + $tmp['ip'] = $oldline[1]; + $tmp['type'] = $type; + $tmp['id'] = $oldline[2]; + $tmp['user'] = $oldline[3]; + $tmp['sum'] = $sum; + $tmp['extra'] = ''; + // order line by id + if (!isset($logs[$tmp['id']])) { $logs[$tmp['id']] = array(); } + $logs[$tmp['id']][$tmp['date']] = $tmp; + } + } + + function importFromAttic(&$logs) { + global $conf, $lang; + $base = $conf['olddir']; + $stack = array(''); + $context = ''; // namespace + while (count($stack)>0){ + $context = array_pop($stack); + $dir = dir($base.'/'.str_replace(':', '/', $context)); + + while (($file = $dir->read()) !== false) { + if ($file==='.' || $file==='..') { continue; } + $matches = array(); + if (preg_match('/([^.]*)\.([^.]*)\..*/', $file, $matches)===1) { + $id = (($context=='')?'':$context.':').$matches[1]; + $date = $matches[2]; + + // check if page & revision are already logged + if (!isset($logs[$id])) { $logs[$id] = array(); } + if (!isset($logs[$id][$date])) { + $tmp = array(); + $tmp['date'] = $date; + $tmp['ip'] = '127.0.0.1'; // original ip lost + $tmp['type'] = 'E'; + $tmp['id'] = $id; + $tmp['user'] = ''; // original user lost + $tmp['sum'] = '('.$lang['restored'].')'; // original summary lost + $tmp['extra'] = ''; + $logs[$id][$date] = $tmp; + } + + } else if (is_dir($dir->path.'/'.$file)) { + array_push($stack, (($context=='')?'':$context.':').$file); + } + + } + + $dir->close(); + } + + } + + function savePerPageChanges($id, &$changes, &$recent, $trim_time) { + $out_lines = array(); + ksort($changes); // ensure correct order of changes from attic + foreach ($changes as $tmp) { + $line = implode("\t", $tmp)."\n"; + array_push($out_lines, $line); + if ($tmp['date']>$trim_time) { + $recent[$tmp['date']] = $line; + } + } + io_saveFile(metaFN($id, '.changes'), implode('', $out_lines)); + } + + function resetTimer() { + // Add 5 minutes to the script execution timer... + // This should be much more than needed. + set_time_limit(5*60); + // Note: Has no effect in safe-mode! + } + + function run_import(&$event, $args) { + global $conf; + register_shutdown_function('importoldchangelog_plugin_shutdown'); + touch($conf['changelog'].'_importing'); // changelog importing lock + io_saveFile($conf['changelog'], ''); // pre-create changelog + io_lock($conf['changelog']); // hold onto the lock + // load old changelog + $this->resetTimer(); + $log = array(); + $oldlog = file($conf['changelog_old']); + foreach ($oldlog as $line) { + $this->importOldLog($line, $log); + } + unset($oldlog); // free memory + // look in the attic for unlogged revisions + $this->resetTimer(); + $this->importFromAttic($log); + // save per-page changelogs + $this->resetTimer(); + $recent = array(); + $trim_time = time() - $conf['recent_days']*86400; + foreach ($log as $id => $page) { + $this->savePerPageChanges($id, $page, $recent, $trim_time); + } + // save recent changes cache + $this->resetTimer(); + ksort($recent); // ensure correct order of recent changes + io_unlock($conf['changelog']); // hand off the lock to io_saveFile + io_saveFile($conf['changelog'], implode('', $recent)); + unlink($conf['changelog'].'_importing'); // changelog importing unlock + } + +} + +function importoldchangelog_plugin_shutdown() { + global $conf; + $path = array(); + $path['changelog'] = $conf['changelog']; + $path['importing'] = $conf['changelog'].'_importing'; + $path['failed'] = $conf['changelog'].'_failed'; + $path['import_ok'] = $conf['changelog'].'_import_ok'; + io_unlock($path['changelog']); // guarantee unlocking + if (file_exists($path['importing'])) { + // import did not finish + rename($path['importing'], $path['failed']) or trigger_error('Importing changelog failed.', E_USER_WARNING); + @unlink($path['import_ok']); + } else { + // import successful + touch($path['import_ok']); + @unlink($path['failed']); + } +} + + |