about summary refs log tree commit diff stats
path: root/wiki/bin/wantedpages.php
diff options
context:
space:
mode:
authorahriman <ahriman@falte.red>2018-12-03 19:22:25 -0500
committerahriman <ahriman@falte.red>2018-12-03 19:22:25 -0500
commit0ae8cbf5c0b1a198b963490985b7738392ebcb97 (patch)
treeb2c77ae72c6b717e2b97492065196ac5ffb2d9e2 /wiki/bin/wantedpages.php
parentf57f6cc5a2d159f90168d292437dc4bd8cd7f934 (diff)
downloadsite-0ae8cbf5c0b1a198b963490985b7738392ebcb97.tar.gz
installed dokuwiki, added to navbar, updated news
Diffstat (limited to 'wiki/bin/wantedpages.php')
-rwxr-xr-xwiki/bin/wantedpages.php186
1 files changed, 186 insertions, 0 deletions
diff --git a/wiki/bin/wantedpages.php b/wiki/bin/wantedpages.php
new file mode 100755
index 0000000..0240eb9
--- /dev/null
+++ b/wiki/bin/wantedpages.php
@@ -0,0 +1,186 @@
+#!/usr/bin/php
+<?php
+
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+/**
+ * Find wanted pages
+ */
+class WantedPagesCLI extends CLI {
+
+    const DIR_CONTINUE = 1;
+    const DIR_NS = 2;
+    const DIR_PAGE = 3;
+
+    private $skip = false;
+    private $sort = 'wanted';
+
+    private $result = array();
+
+    /**
+     * Register options and arguments on the given $options object
+     *
+     * @param Options $options
+     * @return void
+     */
+    protected function setup(Options $options) {
+        $options->setHelp(
+            'Outputs a list of wanted pages (pages that do not exist yet) and their origin pages ' .
+            ' (the pages that are linkin to these missing pages).'
+        );
+        $options->registerArgument(
+            'namespace',
+            'The namespace to lookup. Defaults to root namespace',
+            false
+        );
+
+        $options->registerOption(
+            'sort',
+            'Sort by wanted or origin page',
+            's',
+            '(wanted|origin)'
+        );
+
+        $options->registerOption(
+            'skip',
+            'Do not show the second dimension',
+            'k'
+        );
+    }
+
+    /**
+     * Your main program
+     *
+     * Arguments and options have been parsed when this is run
+     *
+     * @param Options $options
+     * @return void
+     */
+    protected function main(Options $options) {
+        $args = $options->getArgs();
+        if($args) {
+            $startdir = dirname(wikiFN($args[0] . ':xxx'));
+        } else {
+            $startdir = dirname(wikiFN('xxx'));
+        }
+
+        $this->skip = $options->getOpt('skip');
+        $this->sort = $options->getOpt('sort');
+
+        $this->info("searching $startdir");
+
+        foreach($this->get_pages($startdir) as $page) {
+            $this->internal_links($page);
+        }
+        ksort($this->result);
+        foreach($this->result as $main => $subs) {
+            if($this->skip) {
+                print "$main\n";
+            } else {
+                $subs = array_unique($subs);
+                sort($subs);
+                foreach($subs as $sub) {
+                    printf("%-40s %s\n", $main, $sub);
+                }
+            }
+        }
+    }
+
+    /**
+     * Determine directions of the search loop
+     *
+     * @param string $entry
+     * @param string $basepath
+     * @return int
+     */
+    protected function dir_filter($entry, $basepath) {
+        if($entry == '.' || $entry == '..') {
+            return WantedPagesCLI::DIR_CONTINUE;
+        }
+        if(is_dir($basepath . '/' . $entry)) {
+            if(strpos($entry, '_') === 0) {
+                return WantedPagesCLI::DIR_CONTINUE;
+            }
+            return WantedPagesCLI::DIR_NS;
+        }
+        if(preg_match('/\.txt$/', $entry)) {
+            return WantedPagesCLI::DIR_PAGE;
+        }
+        return WantedPagesCLI::DIR_CONTINUE;
+    }
+
+    /**
+     * Collects recursively the pages in a namespace
+     *
+     * @param string $dir
+     * @return array
+     * @throws DokuCLI_Exception
+     */
+    protected function get_pages($dir) {
+        static $trunclen = null;
+        if(!$trunclen) {
+            global $conf;
+            $trunclen = strlen($conf['datadir'] . ':');
+        }
+
+        if(!is_dir($dir)) {
+            throw new DokuCLI_Exception("Unable to read directory $dir");
+        }
+
+        $pages = array();
+        $dh = opendir($dir);
+        while(false !== ($entry = readdir($dh))) {
+            $status = $this->dir_filter($entry, $dir);
+            if($status == WantedPagesCLI::DIR_CONTINUE) {
+                continue;
+            } else if($status == WantedPagesCLI::DIR_NS) {
+                $pages = array_merge($pages, $this->get_pages($dir . '/' . $entry));
+            } else {
+                $page = array(
+                    'id' => pathID(substr($dir . '/' . $entry, $trunclen)),
+                    'file' => $dir . '/' . $entry,
+                );
+                $pages[] = $page;
+            }
+        }
+        closedir($dh);
+        return $pages;
+    }
+
+    /**
+     * Parse instructions and add the non-existing links to the result array
+     *
+     * @param array $page array with page id and file path
+     */
+    function internal_links($page) {
+        global $conf;
+        $instructions = p_get_instructions(file_get_contents($page['file']));
+        $cns = getNS($page['id']);
+        $exists = false;
+        $pid = $page['id'];
+        foreach($instructions as $ins) {
+            if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink')) {
+                $mid = $ins[1][0];
+                resolve_pageid($cns, $mid, $exists);
+                if(!$exists) {
+                    list($mid) = explode('#', $mid); //record pages without hashes
+
+                    if($this->sort == 'origin') {
+                        $this->result[$pid][] = $mid;
+                    } else {
+                        $this->result[$mid][] = $pid;
+                    }
+                }
+            }
+        }
+    }
+}
+
+// Main
+$cli = new WantedPagesCLI();
+$cli->run();
>-address n3:tagged-value-address/deref) (n:integer <- add n:integer 1:literal) (loop) } ]) (function consumer [ ; consume and print integers from a channel (default-space:space-address <- new space:literal 30:literal) (chan:channel-address <- next-input) { begin ; read a tagged value from the channel (x:tagged-value chan:channel-address/deref <- read chan:channel-address) ; unbox the tagged value into an integer (n2:integer <- maybe-coerce x:tagged-value integer:literal) ; other threads might get between these prints ($print (("consume: " literal))) (print-integer nil:literal/terminal n2:integer) ($print (("\n" literal))) (loop) } ]) (function main [ (default-space:space-address <- new space:literal 30:literal) (chan:channel-address <- init-channel 3:literal) ; create two background 'routines' that communicate by a channel (routine1:integer <- fork consumer:fn nil:literal/globals nil:literal/limit chan:channel-address) (routine2:integer <- fork producer:fn nil:literal/globals nil:literal/limit chan:channel-address) (sleep until-routine-done:literal routine1:integer) (sleep until-routine-done:literal routine2:integer) ])