Erik Grinaker is sharing code with you
Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.
Don't show this againRevelation / src / lib / datahandler / xhtml.py
- commit
- 7ae1f811fd74
- parent
- 2645d2e5e351
- branch
- default
fixed crash in XHTML exporter [Javier Kohen]
1 |
29c5326b470e
|
# |
2 |
78fb3436ec03
|
# Revelation - a password manager for GNOME 2 |
3 |
29c5326b470e
|
# http://oss.codepoet.no/revelation/ |
4 |
29c5326b470e
|
# $Id$ |
5 |
29c5326b470e
|
# |
6 |
29c5326b470e
|
# Module for exporting to XHTML files |
7 |
29c5326b470e
|
# |
8 |
29c5326b470e
|
# |
9 |
d230b54e5239
|
# Copyright (c) 2003-2006 Erik Grinaker |
10 |
29c5326b470e
|
# |
11 |
29c5326b470e
|
# This program is free software; you can redistribute it and/or |
12 |
29c5326b470e
|
# modify it under the terms of the GNU General Public License |
13 |
29c5326b470e
|
# as published by the Free Software Foundation; either version 2 |
14 |
29c5326b470e
|
# of the License, or (at your option) any later version. |
15 |
29c5326b470e
|
# |
16 |
29c5326b470e
|
# This program is distributed in the hope that it will be useful, |
17 |
29c5326b470e
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 |
29c5326b470e
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 |
29c5326b470e
|
# GNU General Public License for more details. |
20 |
29c5326b470e
|
# |
21 |
29c5326b470e
|
# You should have received a copy of the GNU General Public License |
22 |
29c5326b470e
|
# along with this program; if not, write to the Free Software |
23 |
29c5326b470e
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
24 |
29c5326b470e
|
# |
25 |
29c5326b470e
|
|
26 |
c094b5acab4e
|
import base |
27 |
c094b5acab4e
|
from revelation import config, data, entry |
28 |
c094b5acab4e
|
|
29 |
6f6f242dab09
|
import gettext, time |
30 |
6f6f242dab09
|
|
31 |
6f6f242dab09
|
_ = gettext.gettext |
32 |
c094b5acab4e
|
|
33 |
c094b5acab4e
|
|
34 |
c094b5acab4e
|
IMAGEPATH = "http://oss.codepoet.no/revelation/img/fileicons" |
35 |
29c5326b470e
|
|
36 |
29c5326b470e
|
|
37 |
29c5326b470e
|
class XHTML(base.DataHandler): |
38 |
29c5326b470e
|
"Data handler for XHTML export" |
39 |
29c5326b470e
|
|
40 |
29c5326b470e
|
name = "XHTML / CSS" |
41 |
c094b5acab4e
|
importer = False |
42 |
c094b5acab4e
|
exporter = True |
43 |
c094b5acab4e
|
encryption = False |
44 |
29c5326b470e
|
|
45 |
29c5326b470e
|
|
46 |
29c5326b470e
|
def __init__(self): |
47 |
29c5326b470e
|
base.DataHandler.__init__(self) |
48 |
29c5326b470e
|
|
49 |
29c5326b470e
|
|
50 |
29c5326b470e
|
def __generate_css(self): |
51 |
29c5326b470e
|
"Generates a CSS for the XHTML document" |
52 |
29c5326b470e
|
|
53 |
29c5326b470e
|
css = """ |
54 |
29c5326b470e
|
/* containers */ |
55 |
29c5326b470e
|
body { |
56 |
29c5326b470e
|
margin: 20px 10px; |
57 |
29c5326b470e
|
padding: 0px; |
58 |
29c5326b470e
|
|
59 |
29c5326b470e
|
font-family: sans-serif; |
60 |
29c5326b470e
|
font-size: 10pt; |
61 |
29c5326b470e
|
line-height: 1.3; |
62 |
29c5326b470e
|
|
63 |
29c5326b470e
|
color: #333333; |
64 |
29c5326b470e
|
background-color: #ffffff; |
65 |
29c5326b470e
|
} |
66 |
29c5326b470e
|
|
67 |
29c5326b470e
|
div { |
68 |
29c5326b470e
|
margin: 0px; |
69 |
29c5326b470e
|
padding: 0px; |
70 |
29c5326b470e
|
} |
71 |
29c5326b470e
|
|
72 |
29c5326b470e
|
p { |
73 |
29c5326b470e
|
margin: 0px 0px 5px 0px; |
74 |
29c5326b470e
|
padding: 0px; |
75 |
29c5326b470e
|
} |
76 |
29c5326b470e
|
|
77 |
6865ee763d14
|
table { |
78 |
29c5326b470e
|
font-family: sans-serif; |
79 |
29c5326b470e
|
font-size: 10pt; |
80 |
6865ee763d14
|
line-height: 1.3; |
81 |
6865ee763d14
|
|
82 |
6865ee763d14
|
margin: 0px; |
83 |
6865ee763d14
|
border-collapse: collapse; |
84 |
29c5326b470e
|
|
85 |
29c5326b470e
|
color: #333333; |
86 |
29c5326b470e
|
background-color: transparent; |
87 |
29c5326b470e
|
} |
88 |
29c5326b470e
|
|
89 |
6865ee763d14
|
td { |
90 |
29c5326b470e
|
text-align: left; |
91 |
6865ee763d14
|
vertical-align: top; |
92 |
29c5326b470e
|
} |
93 |
29c5326b470e
|
|
94 |
29c5326b470e
|
th { |
95 |
6865ee763d14
|
text-align: left; |
96 |
6865ee763d14
|
vertical-align: top; |
97 |
6865ee763d14
|
|
98 |
29c5326b470e
|
font-weight: bold; |
99 |
29c5326b470e
|
color: #000000; |
100 |
29c5326b470e
|
} |
101 |
29c5326b470e
|
|
102 |
29c5326b470e
|
|
103 |
29c5326b470e
|
|
104 |
29c5326b470e
|
/* headings */ |
105 |
29c5326b470e
|
h1, h2, h3 { |
106 |
29c5326b470e
|
margin: 0px; |
107 |
29c5326b470e
|
padding: 0px; |
108 |
29c5326b470e
|
line-height: 1; |
109 |
29c5326b470e
|
font-weight: bold; |
110 |
29c5326b470e
|
color: #000000; |
111 |
29c5326b470e
|
} |
112 |
29c5326b470e
|
|
113 |
29c5326b470e
|
h1 { |
114 |
6865ee763d14
|
margin-bottom: 20px; |
115 |
29c5326b470e
|
font-size: 16pt; |
116 |
29c5326b470e
|
} |
117 |
29c5326b470e
|
|
118 |
29c5326b470e
|
h2 { |
119 |
29c5326b470e
|
margin-bottom: 5px; |
120 |
29c5326b470e
|
font-size: 14pt; |
121 |
29c5326b470e
|
} |
122 |
29c5326b470e
|
|
123 |
29c5326b470e
|
h3 { |
124 |
29c5326b470e
|
font-size: 10pt; |
125 |
29c5326b470e
|
} |
126 |
29c5326b470e
|
|
127 |
29c5326b470e
|
|
128 |
29c5326b470e
|
|
129 |
29c5326b470e
|
/* content */ |
130 |
29c5326b470e
|
a { |
131 |
29c5326b470e
|
color: #3333cc; |
132 |
29c5326b470e
|
text-decoration: none; |
133 |
29c5326b470e
|
} |
134 |
29c5326b470e
|
|
135 |
29c5326b470e
|
a:hover { |
136 |
29c5326b470e
|
text-decoration: underline; |
137 |
29c5326b470e
|
} |
138 |
29c5326b470e
|
|
139 |
6865ee763d14
|
img { |
140 |
6865ee763d14
|
margin: 0px; |
141 |
6865ee763d14
|
padding: 0px; |
142 |
6865ee763d14
|
border: none; |
143 |
6865ee763d14
|
} |
144 |
6865ee763d14
|
|
145 |
29c5326b470e
|
strong { |
146 |
29c5326b470e
|
color: #000000; |
147 |
29c5326b470e
|
} |
148 |
29c5326b470e
|
|
149 |
29c5326b470e
|
|
150 |
29c5326b470e
|
|
151 |
6865ee763d14
|
/* the content area */ |
152 |
6865ee763d14
|
#content { |
153 |
6865ee763d14
|
margin-right: 220px; |
154 |
6865ee763d14
|
} |
155 |
6865ee763d14
|
|
156 |
6865ee763d14
|
|
157 |
6865ee763d14
|
|
158 |
6865ee763d14
|
/* the sidebar */ |
159 |
6865ee763d14
|
#sidebar { |
160 |
6865ee763d14
|
width: 200px; |
161 |
6865ee763d14
|
float: right; |
162 |
6865ee763d14
|
} |
163 |
6865ee763d14
|
|
164 |
6865ee763d14
|
#sidebar h2 { |
165 |
6865ee763d14
|
margin: 20px 0px 10px 0px; |
166 |
6865ee763d14
|
padding: 0px 0px 5px 0px; |
167 |
6865ee763d14
|
border-bottom: 1px dashed #3366cc; |
168 |
6865ee763d14
|
text-transform: lowercase; |
169 |
6865ee763d14
|
} |
170 |
6865ee763d14
|
|
171 |
6865ee763d14
|
#sidebar h2 img.icon { |
172 |
6865ee763d14
|
width: 24px; |
173 |
6865ee763d14
|
height: 24px; |
174 |
6865ee763d14
|
margin-right: 5px; |
175 |
6865ee763d14
|
vertical-align: middle; |
176 |
6865ee763d14
|
} |
177 |
6865ee763d14
|
|
178 |
6865ee763d14
|
#sidebar h3 { |
179 |
6865ee763d14
|
margin-bottom: 2px; |
180 |
6865ee763d14
|
text-transform: lowercase; |
181 |
6865ee763d14
|
} |
182 |
6865ee763d14
|
|
183 |
6865ee763d14
|
#sidebar p { |
184 |
6865ee763d14
|
margin: 0px 5px 10px 15px; |
185 |
6865ee763d14
|
} |
186 |
6865ee763d14
|
|
187 |
6865ee763d14
|
#sidebar ul { |
188 |
6865ee763d14
|
list-style: none; |
189 |
6865ee763d14
|
padding: 0px; |
190 |
29c5326b470e
|
margin: 0px 0px 10px 0px; |
191 |
29c5326b470e
|
} |
192 |
29c5326b470e
|
|
193 |
6865ee763d14
|
#sidebar ul ul { |
194 |
6865ee763d14
|
margin: 0px 0px 0px 15px; |
195 |
29c5326b470e
|
} |
196 |
29c5326b470e
|
|
197 |
6865ee763d14
|
#sidebar ul.accountlist { |
198 |
6865ee763d14
|
margin-left: 15px; |
199 |
6865ee763d14
|
} |
200 |
6865ee763d14
|
|
201 |
6865ee763d14
|
|
202 |
6865ee763d14
|
|
203 |
6865ee763d14
|
/* the entrylist */ |
204 |
6865ee763d14
|
#entrylist { |
205 |
6865ee763d14
|
width: 99%; |
206 |
6865ee763d14
|
padding: 0px; |
207 |
29c5326b470e
|
margin: 0px; |
208 |
29c5326b470e
|
} |
209 |
29c5326b470e
|
|
210 |
6865ee763d14
|
|
211 |
6865ee763d14
|
|
212 |
6865ee763d14
|
/* the footer */ |
213 |
6865ee763d14
|
#footer { |
214 |
6865ee763d14
|
margin: 50px 220px 10px 0px; |
215 |
6865ee763d14
|
font-size: 8pt; |
216 |
6865ee763d14
|
text-align: center; |
217 |
6865ee763d14
|
color: #aaaaaa; |
218 |
29c5326b470e
|
} |
219 |
29c5326b470e
|
|
220 |
6865ee763d14
|
#footer a { |
221 |
6865ee763d14
|
color: #8888ee; |
222 |
29c5326b470e
|
} |
223 |
29c5326b470e
|
|
224 |
6865ee763d14
|
|
225 |
6865ee763d14
|
|
226 |
6865ee763d14
|
/* folders */ |
227 |
6865ee763d14
|
li.folder { |
228 |
6865ee763d14
|
width: 100%; |
229 |
6865ee763d14
|
list-style-type: none; |
230 |
6865ee763d14
|
} |
231 |
6865ee763d14
|
|
232 |
6865ee763d14
|
li.folder .folder-data { |
233 |
6865ee763d14
|
margin: 0px 0px 10px 0px; |
234 |
6865ee763d14
|
padding: 2px 5px 3px 5px; |
235 |
6865ee763d14
|
|
236 |
6865ee763d14
|
border: 1px solid #3366cc; |
237 |
6865ee763d14
|
background-color: #e5ecf9; |
238 |
6865ee763d14
|
} |
239 |
6865ee763d14
|
|
240 |
6865ee763d14
|
li.folder .folder-data h2 { |
241 |
6865ee763d14
|
margin: 0px; |
242 |
6865ee763d14
|
} |
243 |
6865ee763d14
|
|
244 |
6865ee763d14
|
li.folder .folder-data p { |
245 |
6865ee763d14
|
margin: 0px; |
246 |
6865ee763d14
|
} |
247 |
6865ee763d14
|
|
248 |
6865ee763d14
|
|
249 |
6865ee763d14
|
|
250 |
6865ee763d14
|
/* accounts */ |
251 |
6865ee763d14
|
li.account { |
252 |
6865ee763d14
|
list-style-type: none; |
253 |
6865ee763d14
|
width: 350px; |
254 |
6865ee763d14
|
margin: 0px 0px 10px 0px; |
255 |
6865ee763d14
|
border: 1px solid #3366cc; |
256 |
29c5326b470e
|
} |
257 |
29c5326b470e
|
|
258 |
29c5326b470e
|
li.account .heading { |
259 |
29c5326b470e
|
padding: 2px 5px; |
260 |
29c5326b470e
|
background-color: #e5ecf9; |
261 |
29c5326b470e
|
border-bottom: 1px solid #3366cc; |
262 |
29c5326b470e
|
} |
263 |
29c5326b470e
|
|
264 |
29c5326b470e
|
li.account .heading h2 { |
265 |
29c5326b470e
|
margin: 0px 0px 1px 0px; |
266 |
29c5326b470e
|
} |
267 |
29c5326b470e
|
|
268 |
29c5326b470e
|
li.account .heading img { |
269 |
29c5326b470e
|
float: right; |
270 |
29c5326b470e
|
width: 24px; |
271 |
29c5326b470e
|
height: 24px; |
272 |
29c5326b470e
|
} |
273 |
29c5326b470e
|
|
274 |
6865ee763d14
|
li.account .heading .description { |
275 |
6865ee763d14
|
margin: 0px; |
276 |
6865ee763d14
|
} |
277 |
6865ee763d14
|
|
278 |
29c5326b470e
|
li.account .heading .type { |
279 |
29c5326b470e
|
color: #000000; |
280 |
29c5326b470e
|
font-weight: bold; |
281 |
29c5326b470e
|
} |
282 |
29c5326b470e
|
|
283 |
6865ee763d14
|
li.account .data { |
284 |
6865ee763d14
|
padding: 5px; |
285 |
6865ee763d14
|
} |
286 |
6865ee763d14
|
|
287 |
6865ee763d14
|
li.account .data .fields { |
288 |
6865ee763d14
|
margin: 0px 0px 3px 0px; |
289 |
6865ee763d14
|
} |
290 |
6865ee763d14
|
|
291 |
6865ee763d14
|
li.account .data .fields td { |
292 |
6865ee763d14
|
padding: 1px 0px; |
293 |
6865ee763d14
|
} |
294 |
6865ee763d14
|
|
295 |
6865ee763d14
|
li.account .data .fields th { |
296 |
6865ee763d14
|
padding: 1px 5px 1px 0px; |
297 |
6865ee763d14
|
} |
298 |
6865ee763d14
|
|
299 |
29c5326b470e
|
li.account .updated { |
300 |
29c5326b470e
|
font-size: 8pt; |
301 |
29c5326b470e
|
text-align: right; |
302 |
29c5326b470e
|
margin: 0px; |
303 |
29c5326b470e
|
} |
304 |
29c5326b470e
|
""" |
305 |
29c5326b470e
|
|
306 |
29c5326b470e
|
return css |
307 |
29c5326b470e
|
|
308 |
29c5326b470e
|
|
309 |
29c5326b470e
|
def __generate_entry(self, entrystore, iter, depth = 0): |
310 |
29c5326b470e
|
"Generates xhtml for an entry" |
311 |
29c5326b470e
|
|
312 |
29c5326b470e
|
tabs = "\t" * (depth + 2) |
313 |
c094b5acab4e
|
e = entrystore.get_entry(iter) |
314 |
29c5326b470e
|
|
315 |
c094b5acab4e
|
if e is not None: |
316 |
c094b5acab4e
|
e.path = self.__get_entryid(entrystore, iter) |
317 |
6865ee763d14
|
|
318 |
6865ee763d14
|
|
319 |
29c5326b470e
|
xhtml = "" |
320 |
29c5326b470e
|
|
321 |
c094b5acab4e
|
if e is None: |
322 |
6865ee763d14
|
|
323 |
6865ee763d14
|
xhtml += "<div id=\"content\">\n" |
324 |
6865ee763d14
|
xhtml += " <ul id=\"entrylist\">\n" |
325 |
6865ee763d14
|
|
326 |
6865ee763d14
|
for i in range(entrystore.iter_n_children(iter)): |
327 |
6865ee763d14
|
child = entrystore.iter_nth_child(iter, i) |
328 |
6865ee763d14
|
xhtml += self.__generate_entry(entrystore, child, depth) |
329 |
6865ee763d14
|
|
330 |
6865ee763d14
|
xhtml += " </ul>\n" |
331 |
6865ee763d14
|
xhtml += "</div>\n" |
332 |
6865ee763d14
|
|
333 |
6865ee763d14
|
|
334 |
c094b5acab4e
|
elif type(e) == entry.FolderEntry: |
335 |
c094b5acab4e
|
xhtml += tabs + "<li class=\"folder\" id=\"%s\">\n" % e.path |
336 |
29c5326b470e
|
xhtml += tabs + " <div class=\"folder-data\">\n" |
337 |
c094b5acab4e
|
xhtml += tabs + " <h2>%s</h2>\n" % e.name |
338 |
29c5326b470e
|
|
339 |
c094b5acab4e
|
if e.description != "": |
340 |
c094b5acab4e
|
xhtml += tabs + " <p class=\"description\">%s</p>\n" % e.description |
341 |
29c5326b470e
|
|
342 |
29c5326b470e
|
xhtml += tabs + " </div>\n" |
343 |
29c5326b470e
|
xhtml += tabs + "\n" |
344 |
29c5326b470e
|
xhtml += tabs + " <ul>\n" |
345 |
29c5326b470e
|
|
346 |
29c5326b470e
|
for i in range(entrystore.iter_n_children(iter)): |
347 |
29c5326b470e
|
child = entrystore.iter_nth_child(iter, i) |
348 |
6865ee763d14
|
xhtml += self.__generate_entry(entrystore, child, depth + 2) |
349 |
29c5326b470e
|
|
350 |
29c5326b470e
|
xhtml += tabs + " </ul>\n" |
351 |
29c5326b470e
|
xhtml += tabs + "</li>\n" |
352 |
29c5326b470e
|
xhtml += tabs + "\n" |
353 |
29c5326b470e
|
|
354 |
29c5326b470e
|
|
355 |
29c5326b470e
|
else: |
356 |
6865ee763d14
|
|
357 |
c094b5acab4e
|
xhtml += tabs + "<li class=\"account\" id=\"%s\">\n" % e.path |
358 |
29c5326b470e
|
xhtml += tabs + " <div class=\"heading\">\n" |
359 |
c094b5acab4e
|
xhtml += tabs + " <img src=\"%s/entry/%s.png\" alt=\"%s\" />\n" % ( IMAGEPATH, e.id, e.typename ) |
360 |
c094b5acab4e
|
xhtml += tabs + " <h2>%s</h2>\n" % e.name |
361 |
c094b5acab4e
|
xhtml += tabs + " <p class=\"description\"><span class=\"type\">%s</span>%s</p>\n" % ( e.typename + (e.description != "" and "; " or ""), e.description ) |
362 |
29c5326b470e
|
xhtml += tabs + " </div>\n" |
363 |
29c5326b470e
|
xhtml += tabs + "\n" |
364 |
29c5326b470e
|
|
365 |
29c5326b470e
|
xhtml += tabs + " <div class=\"data\">\n" |
366 |
29c5326b470e
|
|
367 |
6865ee763d14
|
fields = [] |
368 |
c094b5acab4e
|
for field in e.fields: |
369 |
6865ee763d14
|
if field.value != "": |
370 |
6865ee763d14
|
fields.append(field) |
371 |
29c5326b470e
|
|
372 |
6865ee763d14
|
if len(fields) > 0: |
373 |
6865ee763d14
|
xhtml += tabs + " <table class=\"fields\">\n" |
374 |
29c5326b470e
|
|
375 |
6865ee763d14
|
for field in fields: |
376 |
6865ee763d14
|
xhtml += tabs + " <tr>\n" |
377 |
6865ee763d14
|
xhtml += tabs + " <th>" + field.name + ":</th>\n" |
378 |
6865ee763d14
|
xhtml += tabs + " <td>" + field.value + "</td>\n" |
379 |
6865ee763d14
|
xhtml += tabs + " </tr>\n" |
380 |
6865ee763d14
|
|
381 |
6865ee763d14
|
xhtml += tabs + " </table>\n" |
382 |
6865ee763d14
|
|
383 |
c094b5acab4e
|
xhtml += tabs + " <p class=\"updated\">Updated " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(e.updated)) + "</p>\n" |
384 |
29c5326b470e
|
xhtml += tabs + " </div>\n" |
385 |
29c5326b470e
|
xhtml += tabs + "</li>\n" |
386 |
6865ee763d14
|
xhtml += tabs + "\n" |
387 |
29c5326b470e
|
|
388 |
29c5326b470e
|
return xhtml |
389 |
29c5326b470e
|
|
390 |
29c5326b470e
|
|
391 |
29c5326b470e
|
def __generate_footer(self): |
392 |
29c5326b470e
|
"Generates an xhtml footer" |
393 |
29c5326b470e
|
|
394 |
29c5326b470e
|
xhtml = "" |
395 |
6865ee763d14
|
xhtml += "<div id=\"footer\">\n" |
396 |
c094b5acab4e
|
xhtml += " Generated by <a href=\"%s\">%s %s</a>" % ( config.URL, config.APPNAME, config.VERSION ) |
397 |
6865ee763d14
|
xhtml += "</div>\n" |
398 |
29c5326b470e
|
xhtml += "</body>\n" |
399 |
29c5326b470e
|
xhtml += "</html>\n" |
400 |
29c5326b470e
|
|
401 |
29c5326b470e
|
return xhtml |
402 |
29c5326b470e
|
|
403 |
29c5326b470e
|
|
404 |
29c5326b470e
|
def __generate_header(self): |
405 |
29c5326b470e
|
"Generates an xhtml header" |
406 |
29c5326b470e
|
|
407 |
29c5326b470e
|
xhtml = "" |
408 |
29c5326b470e
|
xhtml += "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" |
409 |
29c5326b470e
|
xhtml += "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" |
410 |
29c5326b470e
|
xhtml += "<head>\n" |
411 |
29c5326b470e
|
xhtml += " <title>Revelation account list</title>\n" |
412 |
29c5326b470e
|
xhtml += " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\" />\n" |
413 |
29c5326b470e
|
xhtml += "\n" |
414 |
29c5326b470e
|
xhtml += " <style type=\"text/css\">\n" |
415 |
29c5326b470e
|
xhtml += self.__generate_css() |
416 |
29c5326b470e
|
xhtml += " </style>\n" |
417 |
29c5326b470e
|
xhtml += "</head>\n" |
418 |
29c5326b470e
|
xhtml += "\n" |
419 |
29c5326b470e
|
xhtml += "<body>\n" |
420 |
e1117203c473
|
xhtml += "<h1>" + _('Revelation account list') + "</h1>\n" |
421 |
29c5326b470e
|
xhtml += "\n" |
422 |
29c5326b470e
|
|
423 |
29c5326b470e
|
return xhtml |
424 |
29c5326b470e
|
|
425 |
29c5326b470e
|
|
426 |
29c5326b470e
|
def __generate_sidebar(self, entrystore): |
427 |
29c5326b470e
|
"Generates a sidebar" |
428 |
29c5326b470e
|
|
429 |
6865ee763d14
|
xhtml = "" |
430 |
6865ee763d14
|
xhtml += "<div id=\"sidebar\">\n" |
431 |
6865ee763d14
|
xhtml += self.__generate_sidebar_fileinfo() |
432 |
6865ee763d14
|
xhtml += self.__generate_sidebar_foldertree(entrystore) |
433 |
6865ee763d14
|
xhtml += self.__generate_sidebar_accountlist(entrystore) |
434 |
6865ee763d14
|
xhtml += "</div>\n" |
435 |
6865ee763d14
|
|
436 |
6865ee763d14
|
return xhtml |
437 |
6865ee763d14
|
|
438 |
6865ee763d14
|
|
439 |
6865ee763d14
|
def __generate_sidebar_accountlist(self, entrystore): |
440 |
6865ee763d14
|
"Generates an account list" |
441 |
6865ee763d14
|
|
442 |
29c5326b470e
|
# find the entries |
443 |
29c5326b470e
|
entries = {} |
444 |
c094b5acab4e
|
iter = entrystore.iter_nth_child(None, 0) |
445 |
29c5326b470e
|
|
446 |
6865ee763d14
|
while iter is not None: |
447 |
c094b5acab4e
|
e = entrystore.get_entry(iter) |
448 |
c094b5acab4e
|
e.path = self.__get_entryid(entrystore, iter) |
449 |
29c5326b470e
|
|
450 |
c094b5acab4e
|
if type(e) != entry.FolderEntry: |
451 |
c094b5acab4e
|
if not entries.has_key(type(e)): |
452 |
c094b5acab4e
|
entries[type(e)] = [] |
453 |
29c5326b470e
|
|
454 |
c094b5acab4e
|
entries[type(e)].append(e) |
455 |
29c5326b470e
|
|
456 |
6865ee763d14
|
iter = entrystore.iter_traverse_next(iter) |
457 |
29c5326b470e
|
|
458 |
29c5326b470e
|
|
459 |
29c5326b470e
|
# generate the xhtml |
460 |
29c5326b470e
|
xhtml = "" |
461 |
7ae1f811fd74
|
xhtml += (" <h2><img src=\"%s/sidebar/accountlist.png\" class=\"icon\" alt=\"Account list\" />" + _('Account list') + "</h2>\n") % IMAGEPATH |
462 |
29c5326b470e
|
xhtml += "\n" |
463 |
29c5326b470e
|
|
464 |
c094b5acab4e
|
for entrytype in entry.ENTRYLIST: |
465 |
29c5326b470e
|
if not entries.has_key(entrytype): |
466 |
29c5326b470e
|
continue |
467 |
29c5326b470e
|
|
468 |
dc75ad09464f
|
xhtml += " <h3>%s:</h3>\n" % entrytype().typename |
469 |
29c5326b470e
|
xhtml += "\n" |
470 |
29c5326b470e
|
xhtml += " <ul class=\"accountlist\">\n" |
471 |
29c5326b470e
|
|
472 |
29c5326b470e
|
entrylist = entries[entrytype] |
473 |
29c5326b470e
|
entrylist.sort(lambda x,y: cmp(x.name.lower(), y.name.lower())) |
474 |
29c5326b470e
|
|
475 |
c094b5acab4e
|
for e in entrylist: |
476 |
c094b5acab4e
|
xhtml += " <li><a href=\"#%s\">%s</a></li>\n" % ( str(e.path), e.name ) |
477 |
29c5326b470e
|
|
478 |
29c5326b470e
|
xhtml += " </ul>\n" |
479 |
29c5326b470e
|
xhtml += "\n" |
480 |
29c5326b470e
|
|
481 |
6865ee763d14
|
return xhtml |
482 |
6865ee763d14
|
|
483 |
6865ee763d14
|
|
484 |
6865ee763d14
|
def __generate_sidebar_fileinfo(self): |
485 |
6865ee763d14
|
"Generates file info for the sidebar" |
486 |
6865ee763d14
|
|
487 |
6865ee763d14
|
xhtml = "" |
488 |
c094b5acab4e
|
xhtml += " <h2 style=\"margin-top: 0px;\"><img src=\"%s/sidebar/file.png\" class=\"icon\" alt=\"File info\" />File info</h2>\n" % IMAGEPATH |
489 |
6865ee763d14
|
xhtml += "\n" |
490 |
e1117203c473
|
xhtml += " <h3>" + _('Created:') + "</h3>\n" |
491 |
c094b5acab4e
|
xhtml += " <p>%s</p>\n" % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) |
492 |
6865ee763d14
|
xhtml += "\n" |
493 |
e1117203c473
|
xhtml += " <h3>" + _('Revelation version:') + "</h3>\n" |
494 |
c094b5acab4e
|
xhtml += " <p>%s</p>\n" % config.VERSION |
495 |
29c5326b470e
|
xhtml += "\n" |
496 |
29c5326b470e
|
|
497 |
29c5326b470e
|
return xhtml |
498 |
29c5326b470e
|
|
499 |
29c5326b470e
|
|
500 |
6865ee763d14
|
def __generate_sidebar_foldertree(self, entrystore, parent = None, depth = 0): |
501 |
6865ee763d14
|
"Generates a folder tree for the sidebar" |
502 |
6865ee763d14
|
|
503 |
6865ee763d14
|
tabs = "\t" * ((depth * 2) - 2) |
504 |
6865ee763d14
|
xhtml = "" |
505 |
6865ee763d14
|
|
506 |
6865ee763d14
|
if parent is None: |
507 |
c094b5acab4e
|
xhtml += " <h2><img src=\"%s/sidebar/foldertree.png\" class=\"icon\" alt=\"Folder tree\" />Folder tree</h2>\n" % IMAGEPATH |
508 |
6865ee763d14
|
xhtml += "\n" |
509 |
6865ee763d14
|
|
510 |
6865ee763d14
|
# fetch folder list |
511 |
6865ee763d14
|
folders = [] |
512 |
6865ee763d14
|
for i in range(entrystore.iter_n_children(parent)): |
513 |
6865ee763d14
|
iter = entrystore.iter_nth_child(parent, i) |
514 |
c094b5acab4e
|
e = entrystore.get_entry(iter) |
515 |
c094b5acab4e
|
e.path = self.__get_entryid(entrystore, iter) |
516 |
c094b5acab4e
|
e.iter = iter |
517 |
6865ee763d14
|
|
518 |
c094b5acab4e
|
if type(e) == entry.FolderEntry: |
519 |
c094b5acab4e
|
folders.append(e) |
520 |
6865ee763d14
|
|
521 |
6865ee763d14
|
|
522 |
6865ee763d14
|
# generate xhtml |
523 |
6865ee763d14
|
if len(folders) > 0: |
524 |
6865ee763d14
|
xhtml += tabs + "<ul>\n" |
525 |
6865ee763d14
|
|
526 |
c094b5acab4e
|
for e in folders: |
527 |
c094b5acab4e
|
childxhtml = self.__generate_sidebar_foldertree(entrystore, e.iter, depth + 1) |
528 |
6865ee763d14
|
|
529 |
6865ee763d14
|
if childxhtml != "": |
530 |
6865ee763d14
|
xhtml += tabs + " <li>\n" |
531 |
c094b5acab4e
|
xhtml += tabs + " <a href=\"#%s\">%s</a>\n" % ( str(e.path), e.name ) |
532 |
6865ee763d14
|
xhtml += childxhtml |
533 |
6865ee763d14
|
xhtml += tabs + " </li>\n" |
534 |
6865ee763d14
|
|
535 |
6865ee763d14
|
else: |
536 |
c094b5acab4e
|
xhtml += tabs + " <li><a href=\"#%s\">%s</a></li>\n" % ( str(e.path), e.name ) |
537 |
6865ee763d14
|
|
538 |
6865ee763d14
|
xhtml += tabs + "</ul>\n" |
539 |
6865ee763d14
|
|
540 |
6865ee763d14
|
|
541 |
6865ee763d14
|
return xhtml |
542 |
6865ee763d14
|
|
543 |
6865ee763d14
|
|
544 |
6865ee763d14
|
def __get_entryid(self, entrystore, iter): |
545 |
6865ee763d14
|
"Returns an entry id for an iter" |
546 |
6865ee763d14
|
|
547 |
6865ee763d14
|
path = "entry-" |
548 |
c094b5acab4e
|
|
549 |
6865ee763d14
|
for i in entrystore.get_path(iter): |
550 |
6865ee763d14
|
path += str(i) + "-" |
551 |
c094b5acab4e
|
|
552 |
6865ee763d14
|
path = path[:-1] |
553 |
6865ee763d14
|
|
554 |
6865ee763d14
|
return path |
555 |
6865ee763d14
|
|
556 |
6865ee763d14
|
|
557 |
29c5326b470e
|
def export_data(self, entrystore, password = None): |
558 |
29c5326b470e
|
"Exports data from an entrystore into a XHTML document" |
559 |
29c5326b470e
|
|
560 |
29c5326b470e
|
xhtml = "" |
561 |
29c5326b470e
|
xhtml += self.__generate_header() |
562 |
29c5326b470e
|
xhtml += self.__generate_sidebar(entrystore) |
563 |
6865ee763d14
|
xhtml += self.__generate_entry(entrystore, None) |
564 |
29c5326b470e
|
xhtml += self.__generate_footer() |
565 |
29c5326b470e
|
|
566 |
29c5326b470e
|
return xhtml |
567 |
29c5326b470e
|