diff options
-rw-r--r-- | lurker/common/ConfigFile.cpp | 9 | ||||
-rw-r--r-- | lurker/common/ConfigFile.h | 1 | ||||
-rw-r--r-- | lurker/lurker.conf.in | 7 | ||||
-rw-r--r-- | lurker/render/message.cpp | 77 | ||||
-rw-r--r-- | lurker/ui/default.css | 3 | ||||
-rw-r--r-- | lurker/ui/message.xsl | 3 |
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>    </xsl:text> </xsl:template> |