mlmmj-rbarchiver 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,151 @@
1
+ mlmmj-rbarchive
2
+ ===============
3
+
4
+ Small Ruby program for properly archiving a mlmmj-managed
5
+ mailinglist.
6
+
7
+ Requirements
8
+ ------------
9
+
10
+ * [Ruby](http://ruby-lang.org) 1.9.3+
11
+ * [MHonArc](http://mhonarc.org)
12
+ * The `mail` gem
13
+ * The `paint` gem
14
+
15
+ Usage
16
+ -----
17
+
18
+ You can choose between using mlmmj-rbarchive as a library or as a
19
+ commandline program.
20
+
21
+ ### Commandline ###
22
+
23
+ The `mlmmj-rbarchiver` program allows to process any given mlmmj ML
24
+ directory directly into a browsable HTML mailinglist archive. It is
25
+ intended to be run regularly from Cron so it is able to cumulatively
26
+ add any new messages delivered to your ML to the HTML archive.
27
+
28
+ An example call may look like this:
29
+
30
+ ```
31
+ $ mlmmj-rbarchiver -i /var/spool/mlmmj/mymailinglist -o /var/www/mlarchive
32
+ ```
33
+
34
+ This will take all mails found in
35
+ `/var/spool/mlmmj/mymailinglist/archive` and output them to
36
+ `/var/www/mlarchive/mymailinglist` in a month-year-ordered
37
+ format. Note you still have to provide a toplevel `index.html`
38
+ yourself.
39
+
40
+ The program features a good number of commandline options; run it with
41
+ `-h` to get a summary. For styling you might especially be interested
42
+ in the `-s` option. You might also use a configuration file with `-c`
43
+ that allows you to specify some options once and for all; see the
44
+ `rbarchiver.conf` file in the `extra/` directory for an example of how
45
+ it could look like.
46
+
47
+ ### Library ###
48
+
49
+ To use it as a library, first create a new archiver:
50
+
51
+ ``` ruby
52
+ require "mlmmj-archiver"
53
+
54
+ a = MlmmjArchiver::Archiver.new("output", # Target directory for all the messages
55
+ header: "<p>My ML archive</p>", # HTML to display at the top
56
+ stylefile: "/stylesheets/archive.css") # CSS stylesheet to reference from the HTML files
57
+ ```
58
+
59
+ This will create an archiver that places the resulting HTML files
60
+ below a directory `output` below the current directory. To actually
61
+ add an mlmmj ML do the following:
62
+
63
+ ``` ruby
64
+ a << "/var/spool/mlmmj/my-ml
65
+ ```
66
+
67
+ Note you don’t have to specify the "archive" directory below `my-ml`
68
+ manually. Next, create an empty file `my-ml/control/webarchive`. This
69
+ signals mlmmj-rbarchive that you really want this ML to be processed;
70
+ without this file, the directory is skipped even though you have added
71
+ it to the archiver.
72
+
73
+ You can now preprocess the mails into a hierarchical year-month
74
+ directory structure so that before the messages get passed to MHonArc
75
+ they are already nicely sorted:
76
+
77
+ ``` ruby
78
+ a.preprocess_mlmmj_mails!
79
+ ```
80
+
81
+ After having prepared all existing mail, you can now watch the ML’s
82
+ +archive+ directories for changes rather than running the
83
+ Archiver#preprocess_mlmmj_mails! method periodically:
84
+
85
+ ``` ruby
86
+ a.watch_mlmmj_mails!
87
+ ```
88
+
89
+ Note that the above only works if you have the `rb-inotify` gem
90
+ installed. Finally, start the conversion process:
91
+
92
+ ``` ruby
93
+ a.archive!
94
+ ```
95
+
96
+ You can run this periodically if you want, already processed
97
+ messages will not be processed again, only new messages are
98
+ added to the web archive.
99
+
100
+ #### I want more output! ####
101
+
102
+ Do this before you start adding mailinglists to the
103
+ archiver:
104
+
105
+ ``` ruby
106
+ a.debug_mode = true
107
+ ```
108
+
109
+ Docs?
110
+ -----
111
+
112
+ To get a more thorough documentation, run this:
113
+
114
+ ```
115
+ $ rdoc archiver.rb
116
+ ```
117
+
118
+ You will then end up with some more detailed docs in a directory `doc`
119
+ below the current working directory.
120
+
121
+ Links
122
+ -----
123
+
124
+ * [Online docs](http://quintus.github.io/mlmmj-rbarchiver)
125
+ * [Repository](https://github.com/Quintus/mlmmj-rbarchiver)
126
+ * [Issue tracker](https://github.com/Quintus/mlmmj-rbarchiver/issues)
127
+
128
+ License
129
+ -------
130
+
131
+ mlmmj-rbarchive makes a web archive from your mlmmj-archive.
132
+ Copyright (C) 2013-2014 Marvin Gülker
133
+
134
+ This program is free software: you can redistribute it and/or modify
135
+ it under the terms of the GNU General Public License as published by
136
+ the Free Software Foundation, either version 3 of the License, or
137
+ (at your option) any later version.
138
+
139
+ This program is distributed in the hope that it will be useful,
140
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
141
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
142
+ GNU General Public License for more details.
143
+
144
+ You should have received a copy of the GNU General Public License
145
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
146
+
147
+ The MHonArc template file is based on mlmmj-archiver by Andreas Schneider,
148
+ which can be found here: http://git.cryptomilk.org/projects/mlmmj-webarchiver.git.
149
+ It is GPL-copyrighted free software, hence this is also GPL’ed free software.
150
+
151
+ You can contact me at quintus ät quintilianus döt eu.
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ # This file is part of mlmmj-rbarchive.
4
+ #
5
+ # mlmmj-rbarchive makes a web archive from your mlmmj-archive.
6
+ # Copyright (C) 2014 Marvin Gülker
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+
22
+ require "optparse"
23
+ require_relative "../lib/mlmmj-archiver"
24
+
25
+ ########################################
26
+ # Helpers
27
+
28
+ def info(str)
29
+ puts(str)
30
+ end
31
+
32
+ def warn(str)
33
+ puts Paint[str, :yellow]
34
+ end
35
+
36
+ def error(str)
37
+ puts Paint[str, :red]
38
+ end
39
+
40
+ def error!(exception)
41
+ error(exception.to_s)
42
+ raise(exception)
43
+ end
44
+
45
+ ########################################
46
+ # Argument parsing
47
+
48
+ options = {}
49
+
50
+ OptionParser.new do |op|
51
+ op.banner =<<-EOF
52
+ This program archives mlmmj mailinglists into HTML archives.
53
+
54
+ Usage: mlmmj-rbarchiver [Options] -i MLDIR -o OUTDIR
55
+ EOF
56
+
57
+ op.separator ""
58
+ op.separator "Options:"
59
+
60
+ op.on("-a", "--admin EMAIL", "E-Mail address of the administrator"){ |addr| options[:archiveadmin] = addr }
61
+ op.on("-c", "--config-file FILE", "Read configuration from FILE"){ |path| options[:configfile] = Pathname.new(path).expand_path }
62
+ op.on("-C", "--cachedir DIR", "Sorted cache directory"){ |path| options[:cachedir] = Pathname.new(path).expand_path }
63
+ op.on("-h", "--help", "Print this help and exit."){ puts(op); exit }
64
+ op.on("-H", "--header STRING", "HTML code shown above everyhing"){ |str| options[:header] = str }
65
+ op.on("-i", "--indir PATH", "mlmmj mailinglist to archive"){ |path| options[:indir] = Pathname.new(path).expand_path }
66
+ op.on("-l", "--levels NUM", Integer, "Maxmimum message nest before flattening"){ |num| options[:tlevels] = num }
67
+ op.on("-m", "--mhonarc PATH", "Path to the mhonarc executable"){ |path| options[:mhonarc] = Pathname.new(path).expand_path }
68
+ op.on("-o", "--outdir PATH", "Target directory for the output HTML files"){ |path| options[:outdir] = Pathname.new(path).expand_path }
69
+ op.on("-s", "--style STRING", "Path to a CSS file referenced from the HTML.", "This is copied as-is!"){ |str| options[:stylefile] = str }
70
+ op.on("-S", "--search URL", "Search target location"){ |url| options[:searchtarget] = url }
71
+ op.on("-v", "--version", "Print version number and exit"){ puts(MlmmjArchiver::VERSION); exit }
72
+ op.on("-V", "--[no-]verbose", "Turn on verbose mode"){ |bool| options[:verbose] = bool }
73
+ op.on("-x", "--[no-]checknoarchive", "Check the mails' X-No-Archive header"){ |bool| options[:checknoarchive] = bool }
74
+ end.parse!(ARGV)
75
+
76
+ ########################################
77
+ # Configfile
78
+
79
+ if options[:configfile]
80
+ confighash = Hash[YAML.load_file(options[:configfile].to_s).map{|k, v| [k.to_sym, v]}]
81
+ options.update(confighash){|k, v1, v2| v1}
82
+ end
83
+
84
+ ########################################
85
+ # Checking
86
+
87
+ error!("Required option -i missing") unless options[:indir]
88
+ error!("Required option -o missing") unless options[:outdir]
89
+
90
+ if options[:verbose]
91
+ puts "Specified options:"
92
+ options.each{|k, v| puts("#{k}: #{v}")}
93
+ end
94
+
95
+ ########################################
96
+ # Start of program
97
+
98
+ archiver = MlmmjArchiver::Archiver.new(options.delete(:outdir), options)
99
+ archiver.debug_mode = true if options[:verbose]
100
+ archiver << options.delete(:indir)
101
+ archiver.preprocess_mlmmj_mails!
102
+ archiver.archive!
@@ -0,0 +1,465 @@
1
+ <!-- Autogenerated MHonArc RC file, do not touch -->
2
+ <!-- ------------------------------------------------------------------ -->
3
+ <!-- TLEVELS: -->
4
+ <!-- -->
5
+ <!-- TLEVELS defines the maximum number of nested listings in a thread -->
6
+ <!-- index. Any threads that go over TLEVELS in depth are flattened to -->
7
+ <!-- the value of TLEVELS. This resource is helpful in preventing huge -->
8
+ <!- indentations in deep threads which may cause text to be squished -->
9
+ <!-- on the right-side of an HTML viewer. -->
10
+ <!-- -->
11
+
12
+ <TLEVELS>
13
+ <%= tlevels %>
14
+ </TLEVELS>
15
+
16
+ <!-- ------------------------------------------------------------------ -->
17
+ <!-- MIMEExcs: -->
18
+ <!-- -->
19
+ <!-- we don't want HTML messages at all. -->
20
+
21
+ <MIMEExcs>
22
+ text/html
23
+ text/x-html
24
+ </MIMEExcs>
25
+
26
+ <!-- ------------------------------------------------------------------ -->
27
+ <!-- NOMAILTO: -->
28
+ <!-- -->
29
+ <!-- If the MAILTO resource is on, mail addresses in message headers -->
30
+ <!-- will be converted into mailto URL links as defined by the -->
31
+ <!-- MAILTOURL resource. -->
32
+ <!-- -->
33
+
34
+ <NOMAILTO>
35
+ </NOMAILTO>
36
+
37
+ <!-- ------------------------------------------------------------------ -->
38
+ <!-- MHPATTERN: -->
39
+ <!-- -->
40
+ <!-- This is needed to have MHonArc grok maildir folders -->
41
+ <!-- -->
42
+
43
+ <MHPATTERN>
44
+ ^[^\.]
45
+ </MHPATTERN>
46
+
47
+ <!-- ------------------------------------------------------------------ -->
48
+ <!-- TIDXFNAME: -->
49
+ <!-- -->
50
+ <!-- Name of the threads index file -->
51
+ <!-- -->
52
+
53
+ <TIDXFNAME>
54
+ index.html
55
+ </TIDXFNAME>
56
+
57
+ <!-- ------------------------------------------------------------------ -->
58
+ <!-- IDXFNAME: -->
59
+ <!-- -->
60
+ <!-- Name of the message index file -->
61
+ <!-- -->
62
+
63
+ <IDXFNAME>
64
+ seq.html
65
+ </IDXFNAME>
66
+
67
+ <!-- ------------------------------------------------------------------ -->
68
+ <!-- MSGPREFIX: -->
69
+ <!-- -->
70
+ <!-- Prefix for message files -->
71
+ <!-- -->
72
+
73
+ <MSGPREFIX>
74
+ 00
75
+ </MSGPREFIX>
76
+
77
+ <!-- ------------------------------------------------------------------ -->
78
+ <!-- NODOC: -->
79
+ <!-- -->
80
+ <!-- Remove link to MHonArc documentation from bottom of pages -->
81
+ <!-- -->
82
+
83
+ <NODOC>
84
+ </NODOC>
85
+
86
+ <SPAMMODE>
87
+
88
+ <!-- ------------------------------------------------------------------ -->
89
+ <!-- CHECKNOARCHIVE: -->
90
+ <!-- -->
91
+ <!-- If CHECKNOARCHIVE is set, MHonArc will check each message for the -->
92
+ <!-- "no archive" flag. If present, MHonArc will not add the message to -->
93
+ <!-- the archive. MHonArc looks for one of the following in a message -->
94
+ <!-- header to determine if message should not be archived: -->
95
+ <!-- -->
96
+ <!-- X-no-archive: yes -->
97
+ <!-- Restrict: no-external-archive -->
98
+ <!-- -->
99
+ <!-- If either header field is present with the given value, and -->
100
+ <!-- CHECKNOARCHIVE is set, MHonArc will skip the message. -->
101
+ <!-- -->
102
+
103
+ <%= checknoarchive %>
104
+
105
+ <!-- ------------------------------------------------------------------ -->
106
+ <!-- FIELDORDER: -->
107
+ <!-- -->
108
+ <!-- The FIELDORDER resource allows you to control the order the -->
109
+ <!-- message header fields appear in the HTML output. -->
110
+ <!-- -->
111
+ <!-- If -extra- is not specified, then only the fields listed will be -->
112
+ <!-- displayed. -->
113
+
114
+ <FIELDORDER>
115
+ subject
116
+ from
117
+ reply-to
118
+ date
119
+ to
120
+ cc
121
+ </FIELDORDER>
122
+
123
+ <!-- ------------------------------------------------------------------ -->
124
+ <!-- MIMEArgs -->
125
+ <!-- Define options for the MIME filters in use. We want to wrap -->
126
+ <!-- long lines of text automatically. -->
127
+
128
+ <MIMEArgs>
129
+ m2h_text_plain::filter; maxwidth=80 fancyquote quoteclass=mlquote
130
+ </MIMEArgs>
131
+
132
+ <!-- ------------------------------------------------------------------ -->
133
+ <!-- HTMLEXT: -->
134
+ <!-- -->
135
+ <!-- HTMLEXT defines the extension for all HTML files generated by -->
136
+ <!-- MHonArc. -->
137
+ <!-- -->
138
+
139
+ <HTMLEXT>
140
+ html
141
+ </HTMLEXT>
142
+
143
+
144
+ <!-- ------------------------------------------------------------------ -->
145
+ <!-- MSGPGBEGIN, MSGPGEND: -->
146
+ <!-- -->
147
+ <!-- MSGPGBEGIN defines the beginning markup of each message page. It -->
148
+ <!-- allows you to redefine the opening HTML element, HEAD element, -->
149
+ <!-- TITLE element, opening BODY element, etc. -->
150
+ <!-- -->
151
+ <!-- MSGPGEND defines the ending markup of each message page. -->
152
+ <!-- -->
153
+
154
+ <MSGPGBEGIN>
155
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
156
+ <html lang="en">
157
+ <head>
158
+ <title>$SUBJECTNA$</title>
159
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
160
+ <link rel="stylesheet" type="text/css" media="screen" href="<%= stylefile %>">
161
+ </head>
162
+ <body>
163
+ <div id="banner">
164
+ <div id="header">
165
+ <%= header %>
166
+ </div>
167
+ <div id="toplinks">
168
+ $BUTTON(PREV)$ $BUTTON(NEXT)$ $BUTTON(TPREV)$ $BUTTON(TNEXT)$ [<a
169
+ href="$IDXFNAME$#$MSGNUM$">Date Index</a>] [<a
170
+ href="$TIDXFNAME$#$MSGNUM$">Thread Index</a>]
171
+ <% if searchtarget %>
172
+ [<a href="<%= searchtarget %>">Search</a>]
173
+ <% end %>
174
+ </div>
175
+ </div>
176
+ <div id="mailinglists">
177
+ <div id="main">
178
+ </MSGPGBEGIN>
179
+
180
+ <MSGPGEND>
181
+ <!-- FIXME <address>Archive administrator: postmaster@mlmmj-webarchiver</address> -->
182
+ </div>
183
+ </div>
184
+ </body>
185
+ </html>
186
+ </MSGPGEND>
187
+
188
+
189
+ <!-- ------------------------------------------------------------------ -->
190
+ <!-- IDXPGBEGIN, IDXPGEND: -->
191
+ <!-- -->
192
+ <!-- The IDXPGBEGIN resource defines the beginning markup for the main -->
193
+ <!-- index page. I.e. You can control the opening <HTML> tag, the HEAD -->
194
+ <!-- element contents, the opening <BODY> tag, etc. Therefore, if you -->
195
+ <!-- are not satisfied with the default behavior of how the TITLE -->
196
+ <!-- resource is used, or have other needs that require control over -->
197
+ <!-- the beginning markup, you can set the IDXPGBEGIN resource to what -->
198
+ <!-- you desire. -->
199
+ <!-- -->
200
+ <!-- The IDXPGEND resource defines the end markup for the main index -->
201
+ <!-- page. -->
202
+
203
+ <IDXPGBEGIN>
204
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
205
+ <html lang="en">
206
+ <head>
207
+ <title>$IDXTITLE$</title>
208
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
209
+ <link rel="stylesheet" type="text/css" media="screen" href="<%= stylefile %>">
210
+ </head>
211
+ <body>
212
+ </IDXPGBEGIN>
213
+
214
+ <IDXPGEND>
215
+ </body>
216
+ </html>
217
+ </IDXPGEND>
218
+
219
+
220
+ <!-- ------------------------------------------------------------------ -->
221
+ <!-- TIDXPGBEGIN, TIDXPGEND -->
222
+ <!-- -->
223
+ <!-- The TIDXPGBEGIN resource defines the beginning markup for the -->
224
+ <!-- thread index pages. I.e. You can control the opening <HTML> tag, -->
225
+ <!-- the HEAD element contents, the opening <BODY> tag, etc. Therefore, -->
226
+ <!-- if you are not satisfied with the default behavior of how the -->
227
+ <!-- TTITLE resource is used, or have other needs that require control -->
228
+ <!-- on the beginning markup, you can set the TIDXPGBEGIN resource to -->
229
+ <!-- what you desire. -->
230
+ <!-- -->
231
+ <!-- The TIDXPGEND resource defines the end markup for the thread index -->
232
+ <!-- pages. -->
233
+ <!-- -->
234
+
235
+ <TIDXPGBEGIN>
236
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
237
+ <html lang="en">
238
+ <head>
239
+ <title>$TIDXTITLE$</title>
240
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
241
+ <link rel="stylesheet" type="text/css" media="screen" href="<%= stylefile %>">
242
+ </head>
243
+ <body>
244
+ </TIDXPGBEGIN>
245
+
246
+ <TIDXPGEND>
247
+ </body>
248
+ </html>
249
+ </TIDXPGEND>
250
+
251
+ <!-- ------------------------------------------------------------------ -->
252
+ <!-- LISTBEGIN, LITEMPLATE, LISTEND: -->
253
+ <!-- -->
254
+ <!-- The LISTBEGIN resource specifies the markup to begin the message -->
255
+ <!-- list. This resource works in conjuction with LITEMPLATE and -->
256
+ <!-- LISTEND resources to format the main index page(es). -->
257
+ <!-- -->
258
+ <!-- The LITEMPLATE resource specifies the markup for an entry in the -->
259
+ <!-- main index message list. This resource works in conjuction with -->
260
+ <!-- LITEMPLATE and LISTEND resources to format the main index page(es) -->
261
+ <!-- http://www.mhonarc.org/MHonArc/doc/resources/litemplate.html -->
262
+ <!-- -->
263
+ <!-- The LISTEND resource specifies the markup to end the message list -->
264
+ <!-- in the main index. This resource works in conjuction with -->
265
+ <!-- LISTBEGIN and LITEMPLATE resources to format the main index -->
266
+ <!-- page(es). -->
267
+ <!-- -->
268
+
269
+ <LISTBEGIN>
270
+ <div id="banner">
271
+ <div id="header">
272
+ <%= header %>
273
+ </div>
274
+ <div id="topnav">
275
+ <a href="/">Home</a>
276
+ |
277
+ <a href="../..">Month and Year Index</a>
278
+ |
279
+ <a href="$TIDXFNAME$">Thread Index</a>
280
+ |
281
+ <a href="$IDXFNAME$">Date Index</a>
282
+ <% if searchtarget %>
283
+ |
284
+ <a href="<%= searchtarget %>">Search</a>
285
+ <% end %>
286
+ </div>
287
+ </div>
288
+ <div id="mailinglists">
289
+ <div id="main">
290
+ <h1>Date Index</h1>
291
+ <div id="didx">
292
+ <ul>
293
+ </LISTBEGIN>
294
+
295
+ <LITEMPLATE>
296
+ <li><strong>$SUBJECT$</strong> $MSGLOCALDATE(CUR;%Y-%m-%d %H:%M)$
297
+ <ul>
298
+ <li><em>From</em>: $FROM$</li></ul>
299
+ </li>
300
+ </LITEMPLATE>
301
+
302
+ <LISTEND>
303
+ </ul>
304
+ </div>
305
+ <!-- FIXME <address>Archive administrator: postmaster@mlmmj-webarchiver</address> -->
306
+ </div>
307
+ </div>
308
+ </LISTEND>
309
+
310
+
311
+ <!-- ------------------------------------------------------------------ -->
312
+ <!-- THEAD, TFOOT -->
313
+ <!-- -->
314
+ <!-- THEAD defines the header markup of thread index pages. It is also -->
315
+ <!-- responsible for defining the opening markup for the thread -->
316
+ <!-- listings. -->
317
+ <!-- -->
318
+ <!-- TFOOT defines the footer markup of thread index pages. It is also -->
319
+ <!-- responsible for defining the closing markup for the thread listing -->
320
+ <!-- -->
321
+
322
+ <THEAD>
323
+ <div id="banner">
324
+ <div id="header">
325
+ <%= header %>
326
+ </div>
327
+ <div id="topnav">
328
+ <a href="/">Home</a>
329
+ |
330
+ <a href="../..">Month and Year Index</a>
331
+ |
332
+ <a href="$TIDXFNAME$">Thread Index</a>
333
+ |
334
+ <a href="$IDXFNAME$">Date Index</a>
335
+ <% if searchtarget %>
336
+ |
337
+ <a href="<%= searchtarget %>">Search</a>
338
+ <% end %>
339
+ </div>
340
+ </div>
341
+ <div id="mailinglists">
342
+ <div id="main">
343
+ <h1>Thread Index</h1>
344
+ <div id="tidx">
345
+ <ul>
346
+ </THEAD>
347
+
348
+ <TFOOT>
349
+ </ul>
350
+ </div>
351
+ <address>Archive administrator: <%= archiveadmin %></address>
352
+ </div>
353
+ </div>
354
+ </TFOOT>
355
+
356
+ <!-- ------------------------------------------------------------------ -->
357
+ <!-- BOTLINKS -->
358
+ <!-- -->
359
+ <!-- BOTLINKS defines the markup for the links at the bottom of a -->
360
+ <!-- message page. Its usage is analagous to the TOPLINKS resource, but -->
361
+ <!-- tends to be more verbose. However, you can define the resource -->
362
+ <!-- anyway you desire. -->
363
+ <!-- -->
364
+
365
+ <BOTLINKS>
366
+ <!-- No BOTLINKS -->
367
+ </BOTLINKS>
368
+
369
+ <!-- ------------------------------------------------------------------ -->
370
+ <!-- FOLUPBEGIN, FOLUPLITXT and FOLUPEND -->
371
+ <!-- -->
372
+ <!-- FOLUPBEGIN defines the markup to start the explicit follow-up -->
373
+ <!-- links after the message body on a message page. -->
374
+ <!-- -->
375
+ <!-- FOLUPLITXT defines the markup for an entry in the explicit -->
376
+ <!-- follow-up links list after the message body on a message page. -->
377
+ <!-- -->
378
+ <!-- FOLUPEND defines the ending markup for the the explicit follow-up -->
379
+ <!-- links after the message body on a message page. -->
380
+ <!-- -->
381
+
382
+ <FOLUPBEGIN>
383
+ <div class="followups">
384
+ <h2>Followups:</h2>
385
+ <ul>
386
+ </FOLUPBEGIN>
387
+
388
+ <FOLUPLITXT>
389
+ <li><strong>$SUBJECT$</strong> (<em>$FROM$</em>)</li>
390
+ </FOLUPLITXT>
391
+
392
+ <FOLUPEND>
393
+ </ul>
394
+ </div>
395
+ </FOLUPEND>
396
+
397
+ <!-- ------------------------------------------------------------------ -->
398
+ <!-- REFSBEGIN, REFSLITXT and REFSEND -->
399
+ <!-- -->
400
+ <!-- REFSBEGIN defines the markup to start the explicit reference links -->
401
+ <!-- after the message body on a message page. -->
402
+ <!-- -->
403
+ <!-- REFSLITXT defines the markup for an entry in the explicit -->
404
+ <!-- reference links list after the message body on a message page. -->
405
+ <!-- -->
406
+ <!-- REFSEND defines the ending markup for the the explicit reference -->
407
+ <!-- links after the message body on a message page. -->
408
+ <!-- -->
409
+
410
+ <REFSBEGIN>
411
+ <div class="references">
412
+ <h2>References:</h2>
413
+ <ul>
414
+ </REFSBEGIN>
415
+
416
+ <REFSLITXT>
417
+ <li><strong>$SUBJECT$</strong> (<em>$FROM$</em>)</li>
418
+ </REFSLITXT>
419
+
420
+ <REFSEND>
421
+ </ul>
422
+ </div>
423
+ </REFSEND>
424
+
425
+ <!-- ------------------------------------------------------------------ -->
426
+ <!-- SUBJECTHEADER: -->
427
+ <!-- -->
428
+ <!-- SUBJECTHEADER defines the markup for the main subject line above -->
429
+ <!-- the message header of message pages. -->
430
+ <!-- -->
431
+
432
+ <SUBJECTHEADER>
433
+ <h1>$SUBJECTNA$</h1>
434
+ </SUBJECTHEADER>
435
+
436
+ <!-- Thread element -->
437
+ <!-- Add dates to every line in the thread view -->
438
+ <TLiTxt>
439
+ <li><strong>$SUBJECT$</strong>,
440
+ <em>$FROMNAME$</em>, $MSGLOCALDATE(CUR;%Y-%m-%d %H:%M)$
441
+ </TLiTxt>
442
+
443
+ <TTopBegin>
444
+ <li><strong>$SUBJECT$</strong>,
445
+ <em>$FROMNAME$</em>, $MSGLOCALDATE(CUR;%Y-%m-%d %H:%M)$
446
+ </TTopBegin>
447
+
448
+ <TSingleTxt>
449
+ <li><strong>$SUBJECT$</strong>,
450
+ <em>$FROMNAME$</em>, $MSGLOCALDATE(CUR;%d.%m %H:%M)$
451
+ </TSingleTxt>
452
+
453
+ <!-- ------------------------------------------------------------------ -->
454
+
455
+ <FieldsBeg>
456
+ <ul class="message-headers">
457
+ </FieldsBeg>
458
+
459
+ <FieldsEnd>
460
+ </ul>
461
+ </FieldsEnd>
462
+
463
+ <TopLinks>
464
+ <div></div>
465
+ </TopLinks>