# -*- coding: utf-8 -*- # # Copyright (C) 2003-2005 Edgewall Software # Copyright (C) 2003-2005 Jonas Borgström # Copyright (C) 2004-2005 Christopher Lenz # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://trac.edgewall.org/wiki/TracLicense. # # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://trac.edgewall.org/log/. # # Author: Jonas Borgström # Christopher Lenz try: import threading except ImportError: import dummy_threading as threading import time import urllib import re from trac.config import BoolOption from trac.core import * from trac.util.html import html class IWikiChangeListener(Interface): """Extension point interface for components that should get notified about the creation, deletion and modification of wiki pages. """ def wiki_page_added(page): """Called whenever a new Wiki page is added.""" def wiki_page_changed(page, version, t, comment, author, ipnr): """Called when a page has been modified.""" def wiki_page_deleted(page): """Called when a page has been deleted.""" def wiki_page_version_deleted(page): """Called when a version of a page has been deleted.""" class IWikiPageManipulator(Interface): """Extension point interface for components that need to to specific pre and post processing of wiki page changes. Unlike change listeners, a manipulator can reject changes being committed to the database. """ def prepare_wiki_page(req, page, fields): """Not currently called, but should be provided for future compatibility.""" def validate_wiki_page(req, page): """Validate a wiki page after it's been populated from user input. Must return a list of `(field, message)` tuples, one for each problem detected. `field` can be `None` to indicate an overall problem with the page. Therefore, a return value of `[]` means everything is OK.""" class IWikiMacroProvider(Interface): """Extension point interface for components that provide Wiki macros.""" def get_macros(): """Return an iterable that provides the names of the provided macros.""" def get_macro_description(name): """Return a plain text description of the macro with the specified name. """ def render_macro(req, name, content): """Return the HTML output of the macro.""" class IWikiSyntaxProvider(Interface): def get_wiki_syntax(): """Return an iterable that provides additional wiki syntax. Additional wiki syntax correspond to a pair of (regexp, cb), the `regexp` for the additional syntax and the callback `cb` which will be called if there's a match. That function is of the form cb(formatter, ns, match). """ def get_link_resolvers(): """Return an iterable over (namespace, formatter) tuples. Each formatter should be a function of the form fmt(formatter, ns, target, label), and should return some HTML fragment. The `label` is already HTML escaped, whereas the `target` is not. """ class WikiSystem(Component): """Represents the wiki system.""" implements(IWikiChangeListener, IWikiSyntaxProvider) change_listeners = ExtensionPoint(IWikiChangeListener) macro_providers = ExtensionPoint(IWikiMacroProvider) syntax_providers = ExtensionPoint(IWikiSyntaxProvider) INDEX_UPDATE_INTERVAL = 5 # seconds ignore_missing_pages = BoolOption('wiki', 'ignore_missing_pages', 'false', """Enable/disable highlighting CamelCase links to missing pages (''since 0.9'').""") split_page_names = BoolOption('wiki', 'split_page_names', 'false', """Enable/disable splitting the WikiPageNames with space characters (''since 0.10'').""") render_unsafe_content = BoolOption('wiki', 'render_unsafe_content', 'false', """Enable/disable the use of unsafe HTML tags such as `