1# -*- coding: iso-8859-1 -*- 2""" 3 MoinMoin - LocalSiteMap action 4 5 The LocalSiteMap action gives you a page that shows 6 nearby links. This is an example of what appears on the 7 page (names are linkable on the real page): 8 9 MoinMoin 10 GarthKidd 11 OrphanedPages 12 WantedPages 13 JoeDoe 14 CategoryHomepage 15 CategoryCategory 16 WikiHomePage 17 JoeWishes 18 WikiWiki 19 OriginalWiki 20 21 @copyright: 2001 Steve Howell <showell@zipcon.com>, 22 2001-2004 Juergen Hermann <jh@web.de> 23 @license: GNU GPL, see COPYING for details. 24""" 25 26from MoinMoin import wikiutil 27from MoinMoin.Page import Page 28 29class MaxNodesReachedException(Exception): 30 pass 31 32def execute(pagename, request): 33 _ = request.getText 34 35 # This action generate data using the user language 36 request.setContentLanguage(request.lang) 37 38 request.theme.send_title(_('Local Site Map for "%s"') % (pagename), pagename=pagename) 39 40 # Start content - IMPORTANT - witout content div, there is no 41 # direction support! 42 request.write(request.formatter.startContent("content")) 43 44 request.write(LocalSiteMap(pagename).output(request)) 45 46 request.write(request.formatter.endContent()) # end content div 47 request.theme.send_footer(pagename) 48 request.theme.send_closing_html() 49 50class LocalSiteMap: 51 def __init__(self, name): 52 self.name = name 53 self.result = [] 54 55 def output(self, request): 56 tree = PageTreeBuilder(request).build_tree(self.name) 57 #self.append("<small>") 58 tree.depth_first_visit(request, self) 59 #self.append("</small>") 60 return """ 61<p> 62%s 63</p> 64""" % ''.join(self.result) 65 66 def visit(self, request, name, depth): 67 """ Visit a page, i.e. create a link. 68 """ 69 if not name: 70 return 71 _ = request.getText 72 pg = Page(request, name) 73 action = __name__.split('.')[-1] 74 self.append(' ' * (5*depth+1)) 75 self.append(pg.link_to(request, querystr={'action': action})) 76 self.append(" <small>[") 77 self.append(pg.link_to(request, _('view'))) 78 self.append("</small>]<br>") 79 80 def append(self, text): 81 self.result.append(text) 82 83 84class PageTreeBuilder: 85 def __init__(self, request): 86 self.request = request 87 self.children = {} 88 self.numnodes = 0 89 self.maxnodes = 35 90 91 def mark_child(self, name): 92 self.children[name] = 1 93 94 def child_marked(self, name): 95 return name in self.children 96 97 def is_ok(self, child): 98 if not self.child_marked(child): 99 if not self.request.user.may.read(child): 100 return 0 101 if Page(self.request, child).exists(): 102 self.mark_child(child) 103 return 1 104 return 0 105 106 def new_kids(self, name): 107 # does not recurse 108 kids = [] 109 for child in Page(self.request, name).getPageLinks(self.request): 110 if self.is_ok(child): 111 kids.append(child) 112 return kids 113 114 def new_node(self): 115 self.numnodes = self.numnodes + 1 116 if self.numnodes == self.maxnodes: 117 raise MaxNodesReachedException 118 119 def build_tree(self, name): 120 self.mark_child(name) 121 tree = Tree(name) 122 try: 123 self.recurse_build([tree], 1) 124 except MaxNodesReachedException: 125 pass 126 return tree 127 128 def recurse_build(self, trees, depth): 129 all_kids = [] 130 for tree in trees: 131 kids = self.new_kids(tree.node) 132 for kid in kids: 133 newTree = Tree(kid) 134 tree.append(newTree) 135 self.new_node() 136 all_kids.append(newTree) 137 if len(all_kids): 138 self.recurse_build(all_kids, depth+1) 139 140class Tree: 141 def __init__(self, node): 142 self.node = node 143 self.children = [] 144 145 def append(self, node): 146 self.children.append(node) 147 148 def depth_first_visit(self, request, visitor, depth=0): 149 visitor.visit(request, self.node, depth) 150 for c in self.children: 151 c.depth_first_visit(request, visitor, depth+1) 152 153