From b4702736fc52780cb848d699d06e73ec3165290b Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Mon, 19 Nov 2018 12:10:49 +0100 Subject: Update to new dokuwiki version, replace smarty with twig --- .gitignore | 2 +- lib/hostinfo.php | 60 ++++++ lib/twig.php | 129 ++++++++++++ plugins/function.parse_service.php | 26 --- plugins/modifier.contact_info.php | 12 -- plugins/modifier.count.php | 8 - plugins/modifier.group_by.php | 23 -- plugins/modifier.key_not_exists.php | 15 -- plugins/prefilter.whitespace_control.php | 63 ------ plugins/resource.dokuwiki.php | 33 --- update.php | 351 ++++++++++++------------------- 11 files changed, 323 insertions(+), 399 deletions(-) create mode 100644 lib/hostinfo.php create mode 100644 lib/twig.php delete mode 100644 plugins/function.parse_service.php delete mode 100644 plugins/modifier.contact_info.php delete mode 100644 plugins/modifier.count.php delete mode 100644 plugins/modifier.group_by.php delete mode 100644 plugins/modifier.key_not_exists.php delete mode 100644 plugins/prefilter.whitespace_control.php delete mode 100644 plugins/resource.dokuwiki.php diff --git a/.gitignore b/.gitignore index 689da03..ee00630 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -templates_c/*.php +templates_c/* diff --git a/lib/hostinfo.php b/lib/hostinfo.php new file mode 100644 index 0000000..33b87d5 --- /dev/null +++ b/lib/hostinfo.php @@ -0,0 +1,60 @@ +path = $path; + if (!file_exists("$this->path/metadata/hosts")) { + throw new Exception("Invalid hostinfo path: $this->path"); + } + + $this->hosts = null; + $this->_data = array(); + } + + protected function load_hosts() + { + $hosts = Yaml::parse( + file_get_contents("$this->path/metadata/hosts")); + $this->hosts = $hosts['hosts']; + } + + protected function load_host($host) + { + $this->_data[$host] = Yaml::parse( + file_get_contents("$this->path/$host")); + } + + public function get_hosts() + { + if ($this->hosts === null) { + $this->load_hosts(); + } + + return $this->hosts; + } + + public function get_host($host) + { + if (!array_key_exists($host, $this->_data)) { + $this->load_host($host); + } + + return $this->_data[$host]; + } + + public function get_data() + { + $data = array(); + foreach ($this->get_hosts() as $host) { + $data[$host] = $this->get_host($host); + } + return $data; + } +} + +// vim: set ts=4 sw=4 tw=0 et : diff --git a/lib/twig.php b/lib/twig.php new file mode 100644 index 0000000..db1354d --- /dev/null +++ b/lib/twig.php @@ -0,0 +1,129 @@ +build_pagename($name); + return rawWiki($page); + } + + public function getCacheKey($name) + { + return $this->build_pagename($name); + } + + public function isFresh($name, $time) + { + $page = $this->build_pagename($name); + $last_change = p_get_metadata($page, 'last_change date'); + return $last_change < $time; + } + + public function exists($name) + { + $page = $this->build_pagename($name); + return page_exists($page); + } +} + +class Hostinfo_Twig_Extension extends Twig_Extension +{ + public function getFilters() + { + return array( + new Twig_SimpleFilter('contact_info', function($value) { + if (is_array($value)) { + return '[[' . current($value) . '|' . key($value) . ']]'; + } + + return '[[' . $value . '@spline.inf.fu-berlin.de' . '|' . $value . ']]'; + }), + + new Twig_SimpleFilter('parse_service', function($value) { + if (is_array($value)) { + return array( + 'port' => current($value), + 'name' => key($value), + ); + } + + return array( + 'name' => $value, + 'port' => $null, + ); + }), + + new Twig_SimpleFilter('group_by', function($value, $key) { + $array = array(); + + foreach ($value as $k => $v) { + if (array_key_exists($key, $v)) { + if (is_array($v[$key])) { + foreach ($v[$key] as $key_part) { + $array[$key_part][$k] = $v; + } + } + else { + $array[$v[$key]][$k] = $v; + } + } + } + + return $array; + }), + + new Twig_SimpleFilter('key_not_exists', function($value, $key) { + if (!is_array($value)) { + return array(); + } + + return array_filter($value, + function($v) use ($key) { + return !array_key_exists($key, $v); + }); + }), + + new Twig_SimpleFilter('count', function($value) { + return count($value); + }), + + new Twig_SimpleFilter('length', function($value) { + return strlen($value); + }), + ); + } + + public function getName() + { + return 'hostinfo'; + } +} + +class Twig +{ + function __construct() + { + $loader = new Twig_Loader_Dokuwiki(); + $this->twig = new Twig_Environment($loader, array( + 'cache' => __DIR__ . '/../templates_c/', + 'auto_reload' => true, + )); + $this->twig->addExtension(new Hostinfo_Twig_Extension()); + } + + public function render($template, $vars=null) + { + $tmpl = $this->twig->loadTemplate($template . '.tpl'); + return $tmpl->render($vars); + } +} + +// vim: set ts=4 sw=4 tw=0 et : diff --git a/plugins/function.parse_service.php b/plugins/function.parse_service.php deleted file mode 100644 index aa9983d..0000000 --- a/plugins/function.parse_service.php +++ /dev/null @@ -1,26 +0,0 @@ -assign($params['var'], array('name' => $name, 'port' => $port)); -} - -?> diff --git a/plugins/modifier.contact_info.php b/plugins/modifier.contact_info.php deleted file mode 100644 index 6537b7a..0000000 --- a/plugins/modifier.contact_info.php +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/plugins/modifier.count.php b/plugins/modifier.count.php deleted file mode 100644 index c077c11..0000000 --- a/plugins/modifier.count.php +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/plugins/modifier.group_by.php b/plugins/modifier.group_by.php deleted file mode 100644 index 74bf045..0000000 --- a/plugins/modifier.group_by.php +++ /dev/null @@ -1,23 +0,0 @@ - $v) { - if (array_key_exists($key, $v)) { - if (is_array($v[$key])) { - foreach ($v[$key] as $key_part) { - $array[$key_part][$k] = $v; - } - } - else { - $array[$v[$key]][$k] = $v; - } - } - } - - return $array; -} - -?> diff --git a/plugins/modifier.key_not_exists.php b/plugins/modifier.key_not_exists.php deleted file mode 100644 index f29e077..0000000 --- a/plugins/modifier.key_not_exists.php +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/plugins/prefilter.whitespace_control.php b/plugins/prefilter.whitespace_control.php deleted file mode 100644 index fa6b854..0000000 --- a/plugins/prefilter.whitespace_control.php +++ /dev/null @@ -1,63 +0,0 @@ - "text \n\n{tag}" - * "text \n\n\t text\t {-tag}" -> "text \n\n\t text{tag}" - * {--tag} remove white space infront of tag up to the previous non-whitespace character - * "text \n\n\t {--tag}" -> "text{tag}" - * "text \n\n\t text\t {--tag}" -> "text \n\n\t text{tag}" - * {+-tag} - * {-+tag} replace white space infront of tag up to the previous non-whitespace character by a single line-break - * "text \n\n\t {-+tag}" -> "text\n{tag}" - * "text \n\n\t text\t {-+tag}" -> "text \n\n\t text\n{tag}" - * - * {tag-} remove white space after tag up to the next non-whitespace character or end of the line - * "{tag-} \n\n\t text" -> "{tag}\n\n\t text" - * "{tag-} text \n\n\t text" -> "{tag}text \n\n\t text" - * {tag--} remove white space after tag up to the next non-whitespace character - * "{tag--} \n\n\t text" -> "{tag}text" - * "{tag--} text \n\n\t text" -> "{tag}text \n\n\t text" - * {tag+-} - * {tag-+} replace white space after tag up to the next non-whitespace character by a single line-break - * "{tag-+} \n\n\t text" -> "{tag}\n\ntext" - * "{tag-+} text \n\n\t text" -> "{tag}\n\ntext \n\n\t text" - * - * {tag+} replace white space after tag up to the end of the line with an additional line-break - * "{tag+} \n\t text" -> "{tag}\n\n\t text" - * "{tag+} text \n\n\t text" -> "{tag}\n\ntext \n\n\t text" - * - * Any combination of the above, say {--tag+} is possible. Any + modifiers are executed before - modifiers, so - * "{tag+-}{--tag}" will lead to "{tag}{tag}" - * - * NOTE: {tag+} and {tag-+} cause two trailing \n. This is done because PHP itself throws away the first \n. - * So \n\n in the template will lead to \n in the output - * - * @param string $string raw template source - * @param Smarty_Internal_Template $template Template instance - * @return string raw template source after whitespace control was applied - * @author Rodney Rehm - */ -function smarty_prefilter_whitespace_control($string, Smarty_Internal_Template $template) { - $ldelim = $template->smarty->left_delimiter; - $rdelim = $template->smarty->right_delimiter; - $_ldelim = preg_quote($ldelim); - $_rdelim = preg_quote($rdelim); - - // remove preceeding whitepsace preserving a single line-break - $string = preg_replace('#\s*'. $_ldelim .'(?:-\+|\+-)#', "\n" . $ldelim, $string); - // remove trailing whitespace preserving s single line-break - $string = preg_replace('#(?:\+-|-\+)'. $_rdelim .'\s*#', $rdelim . "\n\n", $string); - - // remove preceeding whitepsace - $string = preg_replace('#\s*'. $_ldelim .'--|[^\S\r\n]*'. $_ldelim .'-#', $ldelim, $string); - // remove trailing whitespace - $string = preg_replace('#--'. $_rdelim .'\s*|-'. $_rdelim .'[^\S\r\n]*#', $rdelim, $string); - - // force trailing line-break - $string = preg_replace('#\+'. $_rdelim .'(?:\s*[\r\n]|[^\S\r\n]*)#', $rdelim . "\n\n", $string); - - return $string; -} diff --git a/plugins/resource.dokuwiki.php b/plugins/resource.dokuwiki.php deleted file mode 100644 index 4842524..0000000 --- a/plugins/resource.dokuwiki.php +++ /dev/null @@ -1,33 +0,0 @@ -build_pagename($name); - if (page_exists($page)) { - $source = rawWiki($page); - $mtime = p_get_metadata($page, 'last_change date'); - } - else { - $source = null; - $mtime = null; - } - } - - protected function fetchTimestamp($name) { - $page = $this->build_pagename($name); - if (page_exists($page)) { - return p_get_metadata($page, 'last_change date'); - } - else { - return null; - } - } -} - -?> diff --git a/update.php b/update.php index c9082af..b406546 100755 --- a/update.php +++ b/update.php @@ -9,65 +9,30 @@ $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; ini_set('memory_limit','128M'); if(!defined('DOKU_INC')) define('DOKU_INC', '/usr/share/dokuwiki/'); require_once(DOKU_INC.'inc/init.php'); -require_once(DOKU_INC.'inc/cliopts.php'); -require_once('smarty3/Smarty.class.php'); -require_once('Symfony/Component/Yaml/Yaml.php'); -require_once('Symfony/Component/Yaml/Parser.php'); -require_once('Symfony/Component/Yaml/Inline.php'); -require_once('Symfony/Component/Yaml/Unescaper.php'); - session_write_close(); -#------------------------------------------------------------------------------ -# handle options - -$short_opts = 'hcq'; -$long_opts = array('help', 'clear', 'quiet'); -$OPTS = Doku_Cli_Opts::getOptions(__FILE__, $short_opts, $long_opts); -if ( $OPTS->isError() ) { - fwrite( STDERR, $OPTS->getMessage() . "\n"); - _usage(); - exit(1); -} -$CLEAR = false; -$QUIET = false; -$PAGES = array(); - -foreach ($OPTS->options as $key => $val) { - switch ($key) { - case 'h': - case 'help': - _usage(); - exit; - case 'c': - case 'clear': - $CLEAR = true; - break; - case 'q': - case 'quiet': - $QUIET = true; - break; - } -} +require_once(DOKU_INC.'vendor/autoload.php'); +use splitbrain\phpcli\CLI; +use splitbrain\phpcli\Options; -if (!$OPTS->hasArgs()) { - _usage(); - exit; -} +require_once(__DIR__ . '/lib/twig.php'); +require_once(__DIR__ . '/lib/hostinfo.php'); #------------------------------------------------------------------------------ # Doku_Indexer_Mass_Remover -class Doku_Indexer_Mass_Remover extends Doku_Indexer { - function deletePages($pages) { +class Doku_Indexer_Mass_Remover extends Doku_Indexer +{ + function deletePages($cli, $pages) + { if (!$this->lock()) { - die('Locked'); + $cli->fatal('Cannot lock index!'); } foreach($pages as $page) { - _quietecho('Removing from index: ' . $page); + $cli->debug("Removing page from index: $page"); $this->deletePageNoLock($page); - _quietecho(" done.\n"); + $cli->info("Removed page from index: $page"); } $this->unlock(); @@ -75,207 +40,157 @@ class Doku_Indexer_Mass_Remover extends Doku_Indexer { } #------------------------------------------------------------------------------ -# Smarty - -class Smarty_Hostinfo extends Smarty { +# CLI - function __construct() - { +class UpdateHostinfo extends CLI +{ + function __construct() + { parent::__construct(); - $this->setCompileDir(__DIR__ . '/templates_c/'); - - $this->addPluginsDir(__DIR__ . '/plugins/'); - $this->default_resource_type = 'dokuwiki'; - $this->loadFilter("pre", 'whitespace_control'); - - $this->caching = Smarty::CACHING_OFF; - } -} -$smarty = new Smarty_Hostinfo(); - -#------------------------------------------------------------------------------ -# main() - -$path_to_hostinfo = $OPTS->arg(0); -_load_hostinfo_data($path_to_hostinfo); - -_find_current_pages(); -if (!$CLEAR) { - _update_content(); - _render('start', 'start', array('HOSTINFO' => $HOSTINFO)); - _update_index(); -} -_remove_outdated(); - - -#------------------------------------------------------------------------------ -# _find_current_pages - -function _find_current_pages() { - global $conf, $PAGES; - - $data = array(); - $opts = array( - 'skipacl' => true, - - // ignore pages in subnamespaces (templates) - 'depth' => 2, - ); - search($data, $conf['datadir'], 'search_allpages', $opts, 'hostinfo'); + $this->twig = new Twig(); + $this->pages = array(); + } - foreach ($data as $page) { - $PAGES[$page['id']] = 'delete'; + protected function setup(Options $options) + { + $options->setHelp('Updates the hostinfo information by '. + 'first generating all changed pages and add them '. + 'to the fulltext index. Pages that should not '. + 'exists anymore are removed (also from the '. + 'fulltext index) afterwards. When the -c option '. + 'is given the index is only cleared and nothing '. + 'is updated.'); + + $options->registerOption( + 'clear', + 'Only clear the index.', + 'c' + ); + + $options->registerArgument( + 'PATH', + 'Path to hostinfo source files.' + ); } -} -#------------------------------------------------------------------------------ -# _load_hostinfo_data + protected function main(Options $options) + { + $this->pages = $this->find_current_pages(); -function _load_hostinfo_data($path) { - global $HOSTINFO; + $hostinfo_path = $options->getArgs()[0]; + $hostinfo = new Hostinfo($hostinfo_path); - $hosts_file = $path . '/metadata/hosts'; - if (!file_exists($hosts_file)) { - die("Invalid hostinfo path: $path\n"); + if (!$options->getOpt('clear')) { + $this->render_pages($hostinfo); + $this->render('start', 'start', array('HOSTINFO' => $hostinfo)); + $this->update_index(); + } + $this->remove_pages(); } - $hosts = Symfony\Component\Yaml\Yaml::parse($hosts_file); - foreach ($hosts['hosts'] as $host) { - $HOSTINFO[$host] = Symfony\Component\Yaml\Yaml::parse($path . '/' . $host); - } -} + protected function find_current_pages() { + global $conf; -#------------------------------------------------------------------------------ -# _update_content + $data = array(); + $opts = array( + 'skipacl' => true, -function _update_content() { - global $conf, $HOSTINFO; + // ignore pages in subnamespaces (templates) + 'depth' => 2, + ); + search($data, $conf['datadir'], 'search_allpages', $opts, 'hostinfo'); - // render sites - foreach ($HOSTINFO as $host => $host_data) { - _render($host, 'host', $host_data); + $pages = array(); + foreach ($data as $page) { + $pages[$page['id']] = 'delete'; + } + $this->info('Found ' . count($pages) . ' current pages.'); + return $pages; } -} - -#------------------------------------------------------------------------------ -# _render -function _render($target, $file, $vars=null) { - global $conf, $PAGES; + protected function remove_pages() + { + foreach ($this->pages as $page => $state) { + if ($state == 'delete') { + $this->debug("Removing old page: $page"); + unlink(wikiFN($page)); + $this->info("Removed old page: $page"); + } + } + $this->success('Removed outdated pages.'); - _quietecho("Rendering $file into $target"); - $content = _render_template($file, $vars); - if ($content === false) { - _quietecho(" FAILED (missing template)\n"); - return false; + $this->remove_index(); } - else { - $pagename = cleanID('hostinfo:' . $target); - $page = wikiFN($pagename); - $old_content = ''; - if (file_exists($page)) { - $old_content = file_get_contents($page); + protected function remove_index() + { + $data = array(); + foreach ($this->pages as $page => $state) { + if ($state == 'delete') { + $data[] = $page; + } } - if ($content != $old_content) { - $PAGES[$pagename] = 'update'; - saveWikiText($pagename, $content, 'auto generated'); - _quietecho(" done\n"); - } - else { - unset($PAGES[$pagename]); - _quietecho(" no change\n"); - } - return true; + $idx = new Doku_Indexer_Mass_Remover(); + $idx->deletePages($this, $data); + $this->success('Removed outdated index.'); } -} - -#------------------------------------------------------------------------------ -# _render_template - -function _render_template($template, $vars=null) { - global $smarty; - - $smarty->clearAllAssign(); - $smarty->assign($vars); - return $smarty->fetch($template . '.tpl'); -} -#------------------------------------------------------------------------------ -# _update_index - -function _update_index() { - global $conf, $PAGES; - - - foreach ($PAGES as $page => $state) { - if ($state != 'delete') { - _quietecho('Add to index: ' . $page); - idx_addPage($page, false, true); - _quietecho(" done.\n"); + protected function update_index() + { + foreach ($this->pages as $page => $state) { + if ($state != 'delete') { + $this->debug("Adding page to index: $page"); + idx_addPage($page, false, true); + $this->info("Added page to index: $page"); + } } } -} - -#------------------------------------------------------------------------------ -# _remove_index - -function _remove_index() { - global $PAGES; - $data = array(); - foreach ($PAGES as $page => $state) { - if ($state == 'delete') { - $data[] = $page; + protected function render_pages($hostinfo) + { + // render sites + foreach ($hostinfo->get_hosts() as $host) { + $this->render($host, 'host', $hostinfo->get_host($host)); } } - $idx = new Doku_Indexer_Mass_Remover(); - $idx->deletePages($data); -} - -#------------------------------------------------------------------------------ -# _remove_outdated - -function _remove_outdated() { - global $PAGES; - - foreach ($PAGES as $page => $state) { - if ($state == 'delete') { - _quietecho('Removing old page: ' . $page); - unlink(wikiFN($page)); - _quietecho(" done.\n"); + protected function render($target, $file, $vars=null) + { + $this->debug("Render $file into $target"); + $content = $this->twig->render($file, $vars); + if ($content === false) { + $this->critical("Cannot render $file! Maybe the template is missing?"); + return false; + } + else { + $this->debug("Rendered $file, checking existing content"); + $pagename = cleanID('hostinfo:' . $target); + $page = wikiFN($pagename); + + $old_content = ''; + if (file_exists($page)) { + $old_content = file_get_contents($page); + } + + if ($content != $old_content) { + $this->debug("Content of $target changed, updating page"); + $this->pages[$pagename] = 'update'; + saveWikiText($pagename, $content, 'auto generated'); + $this->success("Rendered $file into $target"); + } + else { + unset($this->pages[$pagename]); + $this->debug("Content of $target unchanged"); + } + + return true; } } - _remove_index(); -} - -#------------------------------------------------------------------------------ -# _usage - -function _usage() { - print "Usage: update.php [OPTIONS] - -Updates the hostinfo information by first generating all changed pages and -add them to the fulltext index. Pages that should not exists anymore are -removed (also from the fulltext index) afterwards. -When the -c option is given the index is only cleared and nothing is updated. - -OPTIONS - -h, --help show this help and exit - -c, --clear only clear the index - -q, --quiet don't produce any output -"; } -#------------------------------------------------------------------------------ -# _quietecho - -function _quietecho($msg) { - global $QUIET; - if(!$QUIET) echo $msg; -} +$cli = new UpdateHostinfo(); +$cli->run(); -?> +// vim: set ts=4 sw=4 tw=0 et : -- cgit v1.2.3-1-g7c22