summaryrefslogtreecommitdiffstats
path: root/lurker
diff options
context:
space:
mode:
Diffstat (limited to 'lurker')
-rw-r--r--lurker/common/ConfigFile.cpp9
-rw-r--r--lurker/common/ConfigFile.h1
-rw-r--r--lurker/lurker.conf.in7
-rw-r--r--lurker/render/message.cpp77
-rw-r--r--lurker/ui/default.css3
-rw-r--r--lurker/ui/message.xsl3
6 files changed, 80 insertions, 20 deletions
diff --git a/lurker/common/ConfigFile.cpp b/lurker/common/ConfigFile.cpp
index b781cc7..874ed73 100644
--- a/lurker/common/ConfigFile.cpp
+++ b/lurker/common/ConfigFile.cpp
@@ -925,6 +925,15 @@ int Config::process_command(const string& file, int c, const string& keys, const
}
xslt = val;
}
+ else if (key == "html_filter")
+ {
+ if (lc != "")
+ {
+ ERROR << "html_filter command cannot be localized" << endl;
+ return -1;
+ }
+ html_filter = val;
+ }
else if (key == "delete_message")
{
if (lc != "")
diff --git a/lurker/common/ConfigFile.h b/lurker/common/ConfigFile.h
index 81c3bea..353eb92 100644
--- a/lurker/common/ConfigFile.h
+++ b/lurker/common/ConfigFile.h
@@ -161,6 +161,7 @@ class Config
string dbdir;
int db_umask;
string xslt;
+ string html_filter;
string delete_message;
string pgpv_mime;
string pgpv_inline;
diff --git a/lurker/lurker.conf.in b/lurker/lurker.conf.in
index 3071c4f..c1ee408 100644
--- a/lurker/lurker.conf.in
+++ b/lurker/lurker.conf.in
@@ -45,6 +45,13 @@ admin_address = nill@bitbucket.org
xslt = xsltproc --nonet -
+# The command invoked to clean html of unwanted tags
+#
+# The deafult is to do nothing! All HTML from HTML bodies is embedded
+# into the archive.
+#
+# htmlfilt =
+
# The command invoked to delete a message.
#
# Lurker will feed a password from the UI into this command via stdin.
diff --git a/lurker/render/message.cpp b/lurker/render/message.cpp
index 481d89c..12fff34 100644
--- a/lurker/render/message.cpp
+++ b/lurker/render/message.cpp
@@ -47,6 +47,7 @@
#include <fstream>
#include <cstdio>
#include <cstring>
+#include <cstdlib>
#include <cerrno>
#include <unistd.h>
@@ -385,6 +386,39 @@ bool handle_signed_mime(ostream& o, DwEntity& e)
return true;
}
+string shell_filter(const string &shell_cmd, const string &html)
+{
+ char tempname[] = "/tmp/lurkerXXXXXX";
+ int fd_tmp = mkstemp(tempname);
+
+ if (fd_tmp == -1)
+ error(_("Unable to create temporary file: "), strerror(errno),
+ _("This was needed to do some HTML filtering. Bummer!"));
+
+ char fd_txt[10];
+ sprintf(fd_txt, " >&%d", fd_tmp);
+ string cmd = shell_cmd + fd_txt;
+
+ FILE *filt = popen(cmd.c_str(), "w");
+
+ if (filt == 0)
+ error(_("Unable to open command pipe: "), cmd + " (" + strerror(errno) + ")",
+ _("Oops!"));
+
+
+ if (fputs(html.c_str(), filt) == EOF)
+ error(_("Error writing HTML data to command pipe: "), cmd + " (" + strerror(errno) + ")",
+ _("Oops!"));
+
+ pclose(filt);
+ close(fd_tmp);
+
+ std::ifstream readtmp(tempname);
+ string new_html((std::istreambuf_iterator<char>(readtmp)), std::istreambuf_iterator<char>());
+ remove(tempname);
+ return new_html;
+}
+
void process_text(ostream& o, bool html, const string& charset, const DwString& out, const Config& cfg)
{
CharsetEscape decode(charset.c_str());
@@ -398,21 +432,28 @@ void process_text(ostream& o, bool html, const string& charset, const DwString&
if (html)
{
- string::size_type start, end;
-
- start = 0;
- while ((end = utf8.find('<', start)) != string::npos)
- {
- my_service_process(o, utf8.c_str()+start, end-start, cfg);
- start = utf8.find('>', end);
+ if (cfg.html_filter != "") {
+ utf8 = shell_filter(cfg.html_filter, utf8);
+ o << "<![CDATA[";
+ o << utf8;
+ o << "]]>";
+ } else {
+ string::size_type start, end;
- if (start == string::npos) break;
- ++start;
+ start = 0;
+ while ((end = utf8.find('<', start)) != string::npos)
+ {
+ my_service_process(o, utf8.c_str()+start, end-start, cfg);
+ start = utf8.find('>', end);
+
+ if (start == string::npos) break;
+ ++start;
+ }
+
+ // deal with half-open tag at end of input
+ if (start != string::npos)
+ my_service_process(o, utf8.c_str()+start, utf8.length()-start, cfg);
}
-
- // deal with half-open tag at end of input
- if (start != string::npos)
- my_service_process(o, utf8.c_str()+start, utf8.length()-start, cfg);
}
else
{
@@ -578,18 +619,18 @@ void message_build(ostream& o, DwEntity& e,
for (DwBodyPart* p = e.Body().FirstBodyPart(); p != 0; p = p->Next())
{
- bool plain = false;
+ bool html = false;
if (p->Headers().HasContentType())
{
DwMediaType& mt = p->Headers().ContentType();
- plain = mt.Type() == DwMime::kTypeText &&
- mt.Subtype() == DwMime::kSubtypePlain;
+ html = mt.Type() == DwMime::kTypeText &&
+ mt.Subtype() == DwMime::kSubtypeHtml;
}
if (t.Subtype() != DwMime::kSubtypeAlternative ||
- p->Next() == 0 || plain)
- { // display all parts, or plain, or last
+ p->Next() == 0 || html)
+ { // display all parts, or html, or last
message_build(o, *p, charset, dump, x, cfg);
// if we printed something, we are done
diff --git a/lurker/ui/default.css b/lurker/ui/default.css
index 0f54507..c2a2989 100644
--- a/lurker/ui/default.css
+++ b/lurker/ui/default.css
@@ -135,8 +135,7 @@ div.messageBody i.quote {
}
div.messageBody pre {
- font-family: monospace;
- font-size: 100%;
+ white-space: pre-wrap;
}
/* opsbar = row of them */
diff --git a/lurker/ui/message.xsl b/lurker/ui/message.xsl
index d3abec7..b3a20ff 100644
--- a/lurker/ui/message.xsl
+++ b/lurker/ui/message.xsl
@@ -128,6 +128,9 @@
<br/>
<xsl:apply-templates/>
</xsl:template>
+<xsl:template mode="body" match="mime[@type='text/html']">
+ <xsl:value-of select="." disable-output-escaping="yes"/>
+</xsl:template>
<xsl:template match="tab" mode="body">
<xsl:text>&#160;&#160;&#160;&#160;</xsl:text>
</xsl:template>