1
/* $Id: mindex.cpp,v 1.14 2004/08/27 15:04:05 terpstra Exp $
3
* mindex.cpp - Handle a mindex/ command
5
* Copyright (C) 2002 - Wesley W. Terpstra
9
* Authors: 'Wesley W. Terpstra' <wesley@terpstra.ca>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; version 2.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#define _XOPEN_SOURCE 500
26
#define _FILE_OFFSET_BITS 64
32
#include <MessageId.h>
41
int mindex_format_error(const string& param)
43
cout << "Status: 200 OK\r\n";
44
cout << "Content-Type: text/html\r\n\r\n";
45
cout << error(_("Bad request"), param,
46
_("The given parameter was not of the correct format. "
47
"A mindex request must be formatted like: "
48
"mindex/list@YYYYMMDD.HHMMSS.hashcode.xml where list "
49
"is the id of an indexed mailing list."));
53
int handle_mindex(const Config& cfg, ESort::Reader* db, const string& param)
55
Request req = parse_request(param);
56
cfg.options = req.options;
58
string::size_type o = req.options.find('@');
59
if (o == string::npos ||
60
!MessageId::is_full(req.options.c_str()+o+1) ||
61
req.options.length() != o+1+MessageId::full_len)
62
return mindex_format_error(param);
64
MessageId id(req.options.c_str()+o+1);
65
string listn(req.options, 0, o);
67
if (cfg.lists.find(listn) == cfg.lists.end())
69
cout << "Status: 200 OK\r\n";
70
cout << "Content-Type: text/html\r\n\r\n";
71
cout << error(_("No such list"), listn,
72
_("The specified mailing list is not available in this "
73
"archive. Perhaps you misspelled it or went to the "
78
const List& list = cfg.lists.find(listn)->second;
80
// Right! Everything the user did is ok.
82
vector<Summary> forward, backward, queue;
84
Search backwardk(cfg, db, Backward, id);
85
backwardk.keyword(LU_KEYWORD_LIST + list.mbox);
87
Search forwardk (cfg, db, Forward, id);
88
forwardk .keyword(LU_KEYWORD_LIST + list.mbox);
92
if (!forwardk .pull(35, forward ) ||
93
!backwardk.pull(35, backward))
95
cout << "Status: 200 OK\r\n";
96
cout << "Content-Type: text/html\r\n\r\n";
97
cout << error(_("Database mindex seek failure"), "pull",
98
_("Something internal to the database failed. "
99
"Please contact the lurker user mailing list for "
100
"furth assistence."));
104
vector<Summary>::size_type left, right, i;
105
if (forward.size() + backward.size() < 20)
107
left = backward.size();
108
right = forward.size();
110
else if (forward.size() < 10)
112
right = forward.size();
115
else if (backward.size() < 10)
117
left = backward.size();
125
assert (left <= backward.size());
126
assert (right <= forward .size());
128
for (i = left; i > 0; --i) queue.push_back(backward[i-1]);
129
for (i = 0; i < right; ++i) queue.push_back(forward[i]);
131
for (i = 0; i < queue.size(); ++i)
132
if ((ok = queue[i].load(db, cfg)) != "")
137
cout << "Status: 200 OK\r\n";
138
cout << "Content-Type: text/html\r\n\r\n";
139
cout << error(_("Database mindex pull failure"), ok,
140
_("Something internal to the database failed. "
141
"Please contact the lurker user mailing list for "
142
"further assistence."));
146
Cache cache(cfg, "mindex", param, req.ext);
148
cache.o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
149
<< "<?xml-stylesheet type=\"text/xsl\" href=\"../fmt/mindex.xsl\"?>\n"
150
<< "<mindex xml:lang=\"" << req.language << "\">\n"
151
<< " " << cfg(req.language) << "\n"
152
<< " " << list(req.language) << "\n";
154
if (right < forward.size())
155
{ // we need a next link
156
i = min(right+9, forward.size()-1);
157
MessageId nd(forward[i].id());
158
nd.increment(); // hope that it doesn't exist (-> skips one)
159
cache.o << " <next>" << nd.serialize() << "</next>\n";
162
if (left < backward.size())
163
{ // we need a prev link
164
i = min(left+10, backward.size()-1);
165
MessageId pd(backward[i].id());
167
cache.o << " <prev>" << pd.serialize() << "</prev>\n";
170
for (i = 0; i < queue.size(); ++i)
172
if (queue[i].id() == id)
173
cache.o << " <row selected=\"true\">";
174
else cache.o << " <row>";
175
cache.o << queue[i] << "</row>\n";
178
cache.o << "</mindex>\n";