Attachment 'PageDicts-0.3.py'
Download 1 """
2 MoinMoin - PageDicts
3
4 This macro uses the wikidicts mechanism for treating pages as dicts to
5 then display a selection of pages in a table.
6
7 Use it like this:
8 [[PageDicts(Bug0, Description, Status, Status ~= open)]]
9
10 This will draw a table with the columns pages, Description and
11 Status for all pages whos titles match Bug0 with Status matching
12 open. This can be used in many different scenarios, with
13 appropriate templates.
14
15 @copyright: 2006 by michael cohen <scudette@users.sourceforge.net>
16 @license: GNU GPL, see COPYING for details.
17 History:
18 0.3: Fix typo, allow the "transpose" keyword to change the table layout
19 0.2: original version
20 """
21 import re
22 from MoinMoin import wikiutil, wikidicts
23 from MoinMoin.Page import Page
24 from MoinMoin.util.dataset import TupleDataset, Column
25 from MoinMoin.widget.browser import DataBrowserWidget
26
27 Dependencies = ["pages"]
28
29 def parse_condition(arg):
30 """ arg is a string which will be parsed into a condition dict.
31
32 A condition is a way of enforcing a requirement on a dict d. For example:
33
34 ## This will match if regex matches d['column_name']
35 column_name ~= regex
36
37 ## This will not match if regexp matches (inverse of above)
38 column_name !~= regex
39 """
40 if '!~=' in arg:
41 tmp = arg.split("!~=",1)
42 result=dict(
43 column= tmp[0].strip(),
44 regex= re.compile(tmp[1].strip(), re.IGNORECASE),
45 func = lambda condition,dictionary: not condition['regex'].search(dictionary[condition['column']])
46 )
47
48 return result
49 elif '~=' in arg:
50 tmp = arg.split("~=",1)
51 result = dict(
52 column = tmp[0].strip(),
53 regex = re.compile(tmp[1].strip(), re.IGNORECASE),
54 func = lambda condition,dictionary: condition['regex'].search(dictionary[condition['column']])
55 )
56
57 return result
58
59 def match_conditions(conditions, dictionary):
60 """ Returns true if all conditions match, false if any fail to match """
61 for condition in conditions:
62 if not condition['func'](condition,dictionary):
63 return False
64
65 return True
66
67 def execute(macro, args):
68 request = macro.request
69 args = [ arg.strip() for arg in args.split(',') ]
70 conditions = []
71 transpose = 0 ## if we transpose the results
72 needle = args[0]
73 if not needle:
74 return macro.formatter.text("It is probably not a good idea to parse all pages as dicts? You must specify a title filter")
75
76 try:
77 args = args[1:]
78 except IndexError:
79 args = []
80
81 ## Remove the args which are conditions and look for transpose flag
82 for i in range(len(args)):
83 condition = parse_condition(args[i])
84 if condition:
85 conditions.append(c)
86 args[i]=None
87 elif 'transpose' in args[i]:
88 transpose = 1
89 args[i]=None
90
91 results = request.rootpage.getPageList(filter=re.compile(needle).search)
92 results.sort()
93
94 table = TupleDataset()
95 table.addRow( [ '', ] + [ arg for arg in args if arg ])
96
97 ## Look at all the pages that matched our string
98 for page in results:
99 dictionary = wikidicts.Dict(request, page)
100
101 ## Check to make sure that the conditons are matched
102 if not match_conditions(conditions, dictionary):
103 continue
104
105 ## Add the row to the table
106 row = [ Page(request, page).link_to(request) ]
107 cols = [ dictionary.get(column,'') for column in args if column ]
108
109 ## look if we have something in a column at all
110 found = [ 1 for col in cols if col ]
111
112 ## only print the row if it has something
113 if found:
114 table.addRow(row + cols)
115
116 if transpose:
117 ## transpose table (make column rows and rows columns)
118 table.data = map(None, zip(*table.data))
119 ## create the top columns
120 table.columns = [ Column(col, label=col, align='right') for col in table.data[0] ]
121 ## remove the row extracted as the column
122 table.data = table.data[1:]
123 tmp = DataBrowserWidget(request)
124 tmp.setData(table)
125 return tmp.toHTML()
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.