mlmmj-rbarchiver 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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>