]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - plugins/pythondemo
release candidate
[git.ikiwiki.info.git] / plugins / pythondemo
index 6d632d5247ab866ca8af3eb9f4448705c0ce3ce8..5e031805be260e8409c0fa81ffdc0ec3795216e0 100755 (executable)
@@ -1,17 +1,38 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 #
 # pythondemo — demo Python ikiwiki plugin
 #
 # Copyright © martin f. krafft <madduck@madduck.net>
 # -*- coding: utf-8 -*-
 #
 # pythondemo — demo Python ikiwiki plugin
 #
 # Copyright © martin f. krafft <madduck@madduck.net>
-# Released under the terms of the GNU GPL version 2
-#
+# 
+#  Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# .
+# THIS SOFTWARE IS PROVIDED BY IKIWIKI AND CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
+# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# 
 __name__ = 'pythondemo'
 __description__ = 'demo Python ikiwiki plugin'
 __version__ = '0.1'
 __author__ = 'martin f. krafft <madduck@madduck.net>'
 __copyright__ = 'Copyright © ' + __author__
 __name__ = 'pythondemo'
 __description__ = 'demo Python ikiwiki plugin'
 __version__ = '0.1'
 __author__ = 'martin f. krafft <madduck@madduck.net>'
 __copyright__ = 'Copyright © ' + __author__
-__licence__ = 'GPLv2'
+__licence__ = 'BSD-2-clause'
 
 from proxy import IkiWikiProcedureProxy
 
 
 from proxy import IkiWikiProcedureProxy
 
@@ -27,7 +48,7 @@ def _arglist_to_dict(args):
         raise ValueError, 'odd number of arguments, cannot convert to dict'
     return dict([args[i:i+2] for i in xrange(0, len(args), 2)])
 
         raise ValueError, 'odd number of arguments, cannot convert to dict'
     return dict([args[i:i+2] for i in xrange(0, len(args), 2)])
 
-def getopt_demo(*args):
+def getopt_demo(proxy, *args):
     # This allows for plugins to perform their own processing of command-line
     # options and so add options to the ikiwiki command line. It's called
     # during command line processing, with @ARGV full of any options that
     # This allows for plugins to perform their own processing of command-line
     # options and so add options to the ikiwiki command line. It's called
     # during command line processing, with @ARGV full of any options that
@@ -37,40 +58,44 @@ def getopt_demo(*args):
     # it sees an option it cannot process, and should just skip over those
     # options and leave them in @ARGV.
     #
     # it sees an option it cannot process, and should just skip over those
     # options and leave them in @ARGV.
     #
-    # TODO: See
-    # http://ikiwiki.info/bugs/external_plugins_cannot_access_ARGV_needed_for_getopt
     debug("hook `getopt' called with arguments %s" % str(args))
     debug("hook `getopt' called with arguments %s" % str(args))
-    raise NotImplementedError
-#proxy.hook('getopt', getopt_demo)
+    args = proxy.getargv()
+    if '--demo' in args:
+        args = [i for i in args if i != '--demo']
+    proxy.setargv(args)
+proxy.hook('getopt', getopt_demo)
 
 
-def checkconfig_demo(*args):
+def checkconfig_demo(proxy, *args):
     # This is useful if the plugin needs to check for or modify ikiwiki's
     # configuration. It's called early in the startup process. The function is
     # passed no values. It's ok for the function to call error() if something
     # isn't configured right.
     # This is useful if the plugin needs to check for or modify ikiwiki's
     # configuration. It's called early in the startup process. The function is
     # passed no values. It's ok for the function to call error() if something
     # isn't configured right.
-    # TODO: how do we tell ikiwiki about errors?
     debug("hook `checkconfig' called with arguments %s" % str(args))
     debug("hook `checkconfig' called with arguments %s" % str(args))
-    raise NotImplementedError
-#proxy.hook('checkconfig', checkconfig_demo)
+    # check that --url has been set
+    url = proxy.getvar('config', 'url')
+    if url is None or len(url) == 0:
+        proxy.error('--url has not been set')
+proxy.hook('checkconfig', checkconfig_demo)
 
 
-def refresh_demo(*args):
+def refresh_demo(proxy, *args):
     # This hook is called just before ikiwiki scans the wiki for changed
     # files. It's useful for plugins that need to create or modify a source
     # page. The function is passed no values.
     debug("hook `refresh' called with arguments %s" % str(args))
 proxy.hook('refresh', refresh_demo)
 
     # This hook is called just before ikiwiki scans the wiki for changed
     # files. It's useful for plugins that need to create or modify a source
     # page. The function is passed no values.
     debug("hook `refresh' called with arguments %s" % str(args))
 proxy.hook('refresh', refresh_demo)
 
-def needsbuild_demo(*args):
+def needsbuild_demo(proxy, *args):
     # This allows a plugin to manipulate the list of files that need to be
     # built when the wiki is refreshed. The function is passed a reference to
     # an array of pages that will be rebuilt, and can modify the array, either
     # adding or removing files from it.
     # This allows a plugin to manipulate the list of files that need to be
     # built when the wiki is refreshed. The function is passed a reference to
     # an array of pages that will be rebuilt, and can modify the array, either
     # adding or removing files from it.
-    # TODO: how do we modify the array?
+    # TODO: how do we modify the array? Joey sees no solution...
+    # we could just return the array and expect ikiwiki to use that...
     debug("hook `needsbuild' called with arguments %s" % str(args))
     raise NotImplementedError
 #proxy.hook('needsbuild', needsbuild_demo)
 
     debug("hook `needsbuild' called with arguments %s" % str(args))
     raise NotImplementedError
 #proxy.hook('needsbuild', needsbuild_demo)
 
-def filter_demo(*args):
+def filter_demo(proxy, *args):
     # Runs on the raw source of a page, before anything else touches it, and
     # can make arbitrary changes. The function is passed named parameters
     # "page", "destpage", and "content". It should return the filtered
     # Runs on the raw source of a page, before anything else touches it, and
     # can make arbitrary changes. The function is passed named parameters
     # "page", "destpage", and "content". It should return the filtered
@@ -80,7 +105,7 @@ def filter_demo(*args):
     return kwargs['content']
 proxy.hook('filter', filter_demo)
 
     return kwargs['content']
 proxy.hook('filter', filter_demo)
 
-def preprocess_demo(*args):
+def preprocess_demo(proxy, *args):
     # Each time the directive is processed, the referenced function
     # (preprocess in the example above) is called, and is passed named
     # parameters. A "page" parameter gives the name of the page that embedded
     # Each time the directive is processed, the referenced function
     # (preprocess in the example above) is called, and is passed named
     # parameters. A "page" parameter gives the name of the page that embedded
@@ -106,14 +131,19 @@ def preprocess_demo(*args):
     # through markdown (or whatever engine is used to htmlize the page) along
     # with the rest of the page.
     #
     # through markdown (or whatever engine is used to htmlize the page) along
     # with the rest of the page.
     #
-    # TODO: needs to be handled differently, the ID cannot be the plugin name.
     kwargs = _arglist_to_dict(args)
     debug("hook `preprocess' called with arguments %s" % kwargs)
     kwargs = _arglist_to_dict(args)
     debug("hook `preprocess' called with arguments %s" % kwargs)
-    raise NotImplementedError
-    return kwargs['content']
-#proxy.hook('preprocess', preprocess_demo)
+    del kwargs['preview']
+    del kwargs['page']
+    del kwargs['destpage']
+    ret = 'foobar preprocessor called with arguments:'
+    for i in kwargs.iteritems():
+        ret += ' %s=%s' % i
+    return ret
+# put [[!foobar ...]] somewhere to try this
+proxy.hook('preprocess', preprocess_demo, id='foobar')
 
 
-def linkify_demo(*args):
+def linkify_demo(proxy, *args):
     # This hook is called to convert WikiLinks on the page into html links.
     # The function is passed named parameters "page", "destpage", and
     # "content". It should return the linkified content.
     # This hook is called to convert WikiLinks on the page into html links.
     # The function is passed named parameters "page", "destpage", and
     # "content". It should return the linkified content.
@@ -125,7 +155,7 @@ def linkify_demo(*args):
     return kwargs['content']
 proxy.hook('linkify', linkify_demo)
 
     return kwargs['content']
 proxy.hook('linkify', linkify_demo)
 
-def scan_demo(*args):
+def scan_demo(proxy, *args):
     # This hook is called early in the process of building the wiki, and is
     # used as a first pass scan of the page, to collect metadata about the
     # page. It's mostly used to scan the page for WikiLinks, and add them to
     # This hook is called early in the process of building the wiki, and is
     # used as a first pass scan of the page, to collect metadata about the
     # page. It's mostly used to scan the page for WikiLinks, and add them to
@@ -134,13 +164,14 @@ def scan_demo(*args):
     # The function is passed named parameters "page" and "content". Its return
     # value is ignored.
     #
     # The function is passed named parameters "page" and "content". Its return
     # value is ignored.
     #
-    # TODO: how do we add to %links?
     kwargs = _arglist_to_dict(args)
     debug("hook `scan' called with arguments %s" % kwargs)
     kwargs = _arglist_to_dict(args)
     debug("hook `scan' called with arguments %s" % kwargs)
-    raise NotImplementedError
-#proxy.hook('scan', scan_demo)
+    links = proxy.getvar('links', kwargs['page'])
+    debug("links for page `%s' are: %s" % (kwargs['page'], links))
+    proxy.setvar('links', kwargs['page'], links)
+proxy.hook('scan', scan_demo)
 
 
-def htmlize_demo(*args):
+def htmlize_demo(proxy, *args):
     # Runs on the raw source of a page and turns it into html. The id
     # parameter specifies the filename extension that a file must have to be
     # htmlized using this plugin. This is how you can add support for new and
     # Runs on the raw source of a page and turns it into html. The id
     # parameter specifies the filename extension that a file must have to be
     # htmlized using this plugin. This is how you can add support for new and
@@ -153,7 +184,7 @@ def htmlize_demo(*args):
     return kwargs['content']
 proxy.hook('htmlize', htmlize_demo)
 
     return kwargs['content']
 proxy.hook('htmlize', htmlize_demo)
 
-def pagetemplate_demo(*args):
+def pagetemplate_demo(proxy, *args):
     # Templates are filled out for many different things in ikiwiki, like
     # generating a page, or part of a blog page, or an rss feed, or a cgi.
     # This hook allows modifying the variables available on those templates.
     # Templates are filled out for many different things in ikiwiki, like
     # generating a page, or part of a blog page, or an rss feed, or a cgi.
     # This hook allows modifying the variables available on those templates.
@@ -165,27 +196,25 @@ def pagetemplate_demo(*args):
     #
     # The most common thing to do is probably to call $template->param() to
     # add a new custom parameter to the template.
     #
     # The most common thing to do is probably to call $template->param() to
     # add a new custom parameter to the template.
-    # TODO: how do we call $template->param()
+    # TODO: how do we call $template->param()?
     kwargs = _arglist_to_dict(args)
     debug("hook `pagetemplate' called with arguments %s" % kwargs)
     raise NotImplementedError
 #proxy.hook('pagetemplate', pagetemplate_demo)
 
     kwargs = _arglist_to_dict(args)
     debug("hook `pagetemplate' called with arguments %s" % kwargs)
     raise NotImplementedError
 #proxy.hook('pagetemplate', pagetemplate_demo)
 
-def templatefile_demo(*args):
+def templatefile_demo(proxy, *args):
     # This hook allows plugins to change the template that is used for a page
     # in the wiki. The hook is passed a "page" parameter, and should return
     # the name of the template file to use, or undef if it doesn't want to
     # change the default ("page.tmpl"). Template files are looked for in
     # /usr/share/ikiwiki/templates by default.
     #
     # This hook allows plugins to change the template that is used for a page
     # in the wiki. The hook is passed a "page" parameter, and should return
     # the name of the template file to use, or undef if it doesn't want to
     # change the default ("page.tmpl"). Template files are looked for in
     # /usr/share/ikiwiki/templates by default.
     #
-    # TODO: we cannot really pass undef/None via xml-rpc, so what to do?
     kwargs = _arglist_to_dict(args)
     debug("hook `templatefile' called with arguments %s" % kwargs)
     kwargs = _arglist_to_dict(args)
     debug("hook `templatefile' called with arguments %s" % kwargs)
-    raise NotImplementedError
-    return None
-#proxy.hook('templatefile', templatefile_demo)
+    return None #leave the default
+proxy.hook('templatefile', templatefile_demo)
 
 
-def sanitize_demo(*args):
+def sanitize_demo(proxy, *args):
     # Use this to implement html sanitization or anything else that needs to
     # modify the body of a page after it has been fully converted to html.
     #
     # Use this to implement html sanitization or anything else that needs to
     # modify the body of a page after it has been fully converted to html.
     #
@@ -196,7 +225,7 @@ def sanitize_demo(*args):
     return kwargs['content']
 proxy.hook('sanitize', sanitize_demo)
 
     return kwargs['content']
 proxy.hook('sanitize', sanitize_demo)
 
-def format_demo(*args):
+def format_demo(proxy, *args):
     # The difference between format and sanitize is that sanitize only acts on
     # the page body, while format can modify the entire html page including
     # the header and footer inserted by ikiwiki, the html document type, etc.
     # The difference between format and sanitize is that sanitize only acts on
     # the page body, while format can modify the entire html page including
     # the header and footer inserted by ikiwiki, the html document type, etc.
@@ -208,21 +237,21 @@ def format_demo(*args):
     return kwargs['content']
 proxy.hook('format', format_demo)
 
     return kwargs['content']
 proxy.hook('format', format_demo)
 
-def delete_demo(*args):
+def delete_demo(proxy, *args):
     # Each time a page or pages is removed from the wiki, the referenced
     # function is called, and passed the names of the source files that were
     # removed.
     debug("hook `delete' called with arguments %s" % str(args))
 proxy.hook('delete', delete_demo)
 
     # Each time a page or pages is removed from the wiki, the referenced
     # function is called, and passed the names of the source files that were
     # removed.
     debug("hook `delete' called with arguments %s" % str(args))
 proxy.hook('delete', delete_demo)
 
-def change_demo(*args):
+def change_demo(proxy, *args):
     # Each time ikiwiki renders a change or addition (but not deletion) to the
     # wiki, the referenced function is called, and passed the names of the
     # source files that were rendered.
     debug("hook `change' called with arguments %s" % str(args))
 proxy.hook('change', change_demo)
 
     # Each time ikiwiki renders a change or addition (but not deletion) to the
     # wiki, the referenced function is called, and passed the names of the
     # source files that were rendered.
     debug("hook `change' called with arguments %s" % str(args))
 proxy.hook('change', change_demo)
 
-def cgi_demo(*args):
+def cgi_demo(proxy, *args):
     # Use this to hook into ikiwiki's cgi script. Each registered cgi hook is
     # called in turn, and passed a CGI object. The hook should examine the
     # parameters, and if it will handle this CGI request, output a page
     # Use this to hook into ikiwiki's cgi script. Each registered cgi hook is
     # called in turn, and passed a CGI object. The hook should examine the
     # parameters, and if it will handle this CGI request, output a page
@@ -234,7 +263,7 @@ def cgi_demo(*args):
     raise NotImplementedError
 #proxy.hook('cgi', cgi_demo)
 
     raise NotImplementedError
 #proxy.hook('cgi', cgi_demo)
 
-def auth_demo(*args):
+def auth_demo(proxy, *args):
     # This hook can be used to implement a different authentication method
     # than the standard web form. When a user needs to be authenticated, each
     # registered auth hook is called in turn, and passed a CGI object and
     # This hook can be used to implement a different authentication method
     # than the standard web form. When a user needs to be authenticated, each
     # registered auth hook is called in turn, and passed a CGI object and
@@ -250,7 +279,7 @@ def auth_demo(*args):
     raise NotImplementedError
 #proxy.hook('auth', auth_demo)
 
     raise NotImplementedError
 #proxy.hook('auth', auth_demo)
 
-def sessioncgi_demo(*args):
+def sessioncgi_demo(proxy, *args):
     # Unlike the cgi hook, which is run as soon as possible, the sessioncgi
     # hook is only run once a session object is available. It is passed both
     # a CGI object and a session object. To check if the user is in fact
     # Unlike the cgi hook, which is run as soon as possible, the sessioncgi
     # hook is only run once a session object is available. It is passed both
     # a CGI object and a session object. To check if the user is in fact
@@ -260,7 +289,7 @@ def sessioncgi_demo(*args):
     raise NotImplementedError
 #proxy.hook('sessioncgi', sessioncgi_demo)
 
     raise NotImplementedError
 #proxy.hook('sessioncgi', sessioncgi_demo)
 
-def canedit_demo(*args):
+def canedit_demo(proxy, *args):
     # This hook can be used to implement arbitrary access methods to control
     # when a page can be edited using the web interface (commits from revision
     # control bypass it). When a page is edited, each registered canedit hook
     # This hook can be used to implement arbitrary access methods to control
     # when a page can be edited using the web interface (commits from revision
     # control bypass it). When a page is edited, each registered canedit hook
@@ -278,13 +307,12 @@ def canedit_demo(*args):
     # since it's sometimes used to test to see which pages in a set of pages
     # a user can edit.
     #
     # since it's sometimes used to test to see which pages in a set of pages
     # a user can edit.
     #
-    # TODO: we cannot return undef/None, see above.
     # TODO: how do we return a function?
     debug("hook `canedit' called with arguments %s" % str(args))
     raise NotImplementedError
 #proxy.hook('canedit', canedit_demo)
 
     # TODO: how do we return a function?
     debug("hook `canedit' called with arguments %s" % str(args))
     raise NotImplementedError
 #proxy.hook('canedit', canedit_demo)
 
-def editcontent_demo(*args):
+def editcontent_demo(proxy, *args):
     # This hook is called when a page is saved (or previewed) using the web
     # interface. It is passed named parameters: content, page, cgi, and
     # session. These are, respectively, the new page content as entered by the
     # This hook is called when a page is saved (or previewed) using the web
     # interface. It is passed named parameters: content, page, cgi, and
     # session. These are, respectively, the new page content as entered by the
@@ -296,7 +324,7 @@ def editcontent_demo(*args):
     return kwargs['content']
 proxy.hook('editcontent', editcontent_demo)
 
     return kwargs['content']
 proxy.hook('editcontent', editcontent_demo)
 
-def formbuilder_setup_demo(*args):
+def formbuilder_setup_demo(proxy, *args):
     # These hooks allow tapping into the parts of ikiwiki that use
     # CGI::FormBuilder to generate web forms. These hooks are passed named
     # parameters: cgi, session, form, and buttons. These are, respectively,
     # These hooks allow tapping into the parts of ikiwiki that use
     # CGI::FormBuilder to generate web forms. These hooks are passed named
     # parameters: cgi, session, form, and buttons. These are, respectively,
@@ -319,7 +347,7 @@ def formbuilder_setup_demo(*args):
     return kwargs['content']
 #proxy.hook('formbuilder_setup', formbuilder_setup_demo)
 
     return kwargs['content']
 #proxy.hook('formbuilder_setup', formbuilder_setup_demo)
 
-def formbuilder_demo(*args):
+def formbuilder_demo(proxy, *args):
     # These hooks allow tapping into the parts of ikiwiki that use
     # CGI::FormBuilder to generate web forms. These hooks are passed named
     # parameters: cgi, session, form, and buttons. These are, respectively,
     # These hooks allow tapping into the parts of ikiwiki that use
     # CGI::FormBuilder to generate web forms. These hooks are passed named
     # parameters: cgi, session, form, and buttons. These are, respectively,
@@ -341,7 +369,7 @@ def formbuilder_demo(*args):
     return kwargs['content']
 #proxy.hook('formbuilder', formbuilder_demo)
 
     return kwargs['content']
 #proxy.hook('formbuilder', formbuilder_demo)
 
-def savestate_demo(*args):
+def savestate_demo(proxy, *args):
     # This hook is called wheneven ikiwiki normally saves its state, just
     # before the state is saved. The function can save other state, modify
     # values before they're saved, etc.
     # This hook is called wheneven ikiwiki normally saves its state, just
     # before the state is saved. The function can save other state, modify
     # values before they're saved, etc.