Attachment 'PageDicts-0.6.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 If you prefix the Bug0 with an !-mark, it will search for all user
15 readable pages wich contain Bug0 (allowing for searching a categorie)
16 Also note, that 'open' can be any valid regular expression (include pipes)
17
18 @copyright: 2006 by michael cohen <scudette@users.sourceforge.net>
19 @license: GNU GPL, see COPYING for details.
20 History:
21 0.4: made more usefull by allowing categories and catching some errors
22 by Remco Boerma
23 0.3: Fix typo, allow the "transpose" keyword to change the table layout
24 0.2: original version
25 """
26 import re
27 from MoinMoin import wikiutil, search
28 from MoinMoin.datastruct import WikiDicts
29 from MoinMoin.Page import Page
30 from MoinMoin.util.dataset import TupleDataset, Column
31 from MoinMoin.widget.browser import DataBrowserWidget
32
33 Dependencies = ["pages"]
34
35 def parse_condition(arg):
36 """ arg is a string which will be parsed into a condition dict.
37
38 A condition is a way of enforcing a requirement on a dict d. For example:
39
40 ## This will match if regex matches d['column_name']
41 column_name ~= regex
42
43 ## This will not match if regexp matches (inverse of above)
44 column_name !~= regex
45 """
46 if '!~=' in arg:
47 tmp = arg.split("!~=",1)
48 result=dict(
49 column= tmp[0].strip(),
50 regex= re.compile(tmp[1].strip(), re.IGNORECASE),
51 func = lambda condition,dictionary: not condition['regex'].search(dictionary[condition['column']])
52 )
53
54 return result
55 elif '~=' in arg:
56 tmp = arg.split("~=",1)
57 result = dict(
58 column = tmp[0].strip(),
59 regex = re.compile(tmp[1].strip(), re.IGNORECASE),
60 func = lambda condition,dictionary: condition['regex'].search(dictionary[condition['column']])
61 )
62
63 return result
64
65 def match_conditions(conditions, dictionary):
66 """ Returns true if all conditions match, false if any fail to match """
67 for condition in conditions:
68 try:
69 if not condition['func'](condition,dictionary):
70 return False
71 except KeyError:
72 # Remco: prolly it's a template linking or anything, and this value is not available
73 return False
74
75 return True
76
77 def execute(macro, args):
78 request = macro.request
79 args = [ arg.strip() for arg in args.split(',') ]
80 conditions = []
81 transpose = 0 ## if we transpose the results
82 needle = args[0]
83 if not needle:
84 return macro.formatter.text("It is probably not a good idea to parse all pages as dicts? You must specify a title filter")
85
86 try:
87 args = args[1:]
88 except IndexError:
89 args = []
90
91 ## Remove the args which are conditions and look for transpose flag
92 for i in range(len(args)):
93 condition = parse_condition(args[i])
94 if condition:
95 conditions.append(condition) # remco change
96 args[i]=None
97 elif 'transpose' in args[i]:
98 transpose = 1
99 args[i]=None
100
101
102 # RemcoBoerma -- use internal search for finding the page: allows all contstructs to perform
103 # the search...
104 results = [p.page_name for p in search.searchPages(request, needle, sort='page_name').hits]
105 results = dict([(x,x) for x in results]).keys()
106 #results.sort()
107
108 table = TupleDataset()
109 table.addRow( [ '', ] + [ arg for arg in args if arg ])
110
111 ## Look at all the pages that matched our string
112 for page in results:
113 dictionary = WikiDicts(request).get(page)
114
115 ## Check to make sure that the conditons are matched
116 if not match_conditions(conditions, dictionary):
117 continue
118
119 ## Add the row to the table
120 row = [ Page(request, page).link_to(request) ]
121 cols = [ dictionary.get(column,'') for column in args if column ]
122
123 ## look if we have something in a column at all
124 found = [ 1 for col in cols if col ]
125
126 ## only print the row if it has something
127 if found:
128 table.addRow(row + cols)
129
130 if transpose:
131 ## transpose table (make column rows and rows columns)
132 table.data = map(None, zip(*table.data))
133 ## create the top columns
134 table.columns = [ Column(col, label=col, align='right') for col in table.data[0] ]
135 ## remove the row extracted as the column
136 table.data = table.data[1:]
137 tmp = DataBrowserWidget(request)
138 tmp.setData(table)
139 return tmp.render()
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.