summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGaute Hope <eg@gaute.vetsj.com>2019-04-03 15:50:12 +0200
committerGaute Hope <eg@gaute.vetsj.com>2019-04-07 14:07:15 +0200
commit9dbb881e8d59f6c17a934e8ba54724dbd5d2c36b (patch)
tree5c610d4df03d218528b84416316f8643522ff7d5
parent24cece6368164b935566f9b8f58f6fc8f4aa395e (diff)
reply, forward: use lynx (or configurable program) to convert HTML parts to text when quoting
-rw-r--r--src/compose_message.cc3
-rw-r--r--src/config.cc2
-rw-r--r--src/message_thread.cc62
-rw-r--r--src/message_thread.hh1
-rw-r--r--src/modes/edit_message.cc2
-rw-r--r--src/modes/forward_message.cc2
-rw-r--r--src/modes/reply_message.cc2
-rw-r--r--src/utils/cmd.cc57
-rw-r--r--src/utils/cmd.hh10
9 files changed, 130 insertions, 11 deletions
diff --git a/src/compose_message.cc b/src/compose_message.cc
index 9633008..a139e92 100644
--- a/src/compose_message.cc
+++ b/src/compose_message.cc
@@ -157,7 +157,7 @@ namespace Astroid {
sf << s.rdbuf ();
s.close ();
if (account->signature_separate) {
- md_body_content += "-- \n";
+ md_body_content += "-- \n";
}
md_body_content += sf.str ();
}
@@ -228,6 +228,7 @@ namespace Astroid {
contentStream = g_mime_stream_mem_new_with_buffer(_html.c_str(), _html.size());
}
+ g_spawn_close_pid (pid);
} catch (Glib::SpawnError &ex) {
LOG (error) << "cm: md: failed to spawn markdown processor: " << ex.what ();
diff --git a/src/config.cc b/src/config.cc
index 3830ace..0b71440 100644
--- a/src/config.cc
+++ b/src/config.cc
@@ -235,6 +235,8 @@ namespace Astroid {
default_config.put ("editor.markdown_processor", "cmark");
default_config.put ("editor.markdown_on", false); // default
+ default_config.put ("mail.reply.quote_processor", "w3m -dump -T text/html"); // e.g. lynx -dump
+
/* mail composition */
default_config.put ("mail.reply.quote_line", "Excerpts from %1's message of %2:"); // %1 = author, %2 = pretty_verbose_date
default_config.put ("mail.reply.mailinglist_reply_to_sender", true);
diff --git a/src/message_thread.cc b/src/message_thread.cc
index a9c7712..fee5295 100644
--- a/src/message_thread.cc
+++ b/src/message_thread.cc
@@ -11,6 +11,7 @@
# include "message_thread.hh"
# include "chunk.hh"
# include "utils/utils.hh"
+# include "utils/cmd.hh"
# include "utils/date_utils.hh"
# include "utils/address.hh"
# include "utils/ustring_utils.hh"
@@ -367,6 +368,67 @@ namespace Astroid {
return body;
}
+ ustring Message::quote () {
+ if (missing_content) {
+ LOG (warn) << "message: missing content, no text.";
+ return "";
+ }
+
+ ustring body;
+
+ function< void (refptr<Chunk>) > app_body =
+ [&] (refptr<Chunk> c)
+ {
+ /* check if we're the preferred sibling */
+ bool use = false;
+
+ if (c->siblings.size() >= 1) {
+ if (c->is_content_type ("text", "plain") || c->is_content_type ("text", "html")) {
+ use = true;
+ } else {
+ /* check if there are any other preferred */
+ if (all_of (c->siblings.begin (),
+ c->siblings.end (),
+ [](refptr<Chunk> c) { return !(c->is_content_type ("text", "plain") || c->is_content_type("text", "html")); })) {
+ use = true; // no
+ } else {
+ use = false;
+ }
+ }
+ } else {
+ use = true;
+ }
+
+ if (use) {
+ if (c->viewable && (c->is_content_type ("text", "plain") || c->is_content_type ("text", "html"))) {
+ /* will output html if HTML part */
+ if (c->is_content_type ("text", "html")) {
+ ustring quote_cmd = astroid->config ().get<string>("mail.reply.quote_processor");
+
+ if (!quote_cmd.empty()) {
+ ustring h = c->viewable_text (false);
+ ustring _stdout, _stderr;
+ Cmd::pipe (quote_cmd, h, _stdout, _stderr);
+
+ body += _stdout;
+ }
+
+ } else {
+ body += c->viewable_text (false);
+ }
+ }
+
+ for_each (c->kids.begin(),
+ c->kids.end (),
+ app_body);
+ }
+ };
+
+ app_body (root);
+
+ return body;
+ }
+
vector<refptr<Chunk>> Message::attachments () {
/* return a flat vector of attachments */
diff --git a/src/message_thread.hh b/src/message_thread.hh
index f3b6ee3..4bee766 100644
--- a/src/message_thread.hh
+++ b/src/message_thread.hh
@@ -68,6 +68,7 @@ namespace Astroid {
std::vector<ustring> tags;
ustring plain_text (bool fallback_html = false);
+ ustring quote ();
std::vector<refptr<Chunk>> attachments ();
refptr<Chunk> get_chunk_by_id (int id);
diff --git a/src/modes/edit_message.cc b/src/modes/edit_message.cc
index f5a4d50..e0fa3bc 100644
--- a/src/modes/edit_message.cc
+++ b/src/modes/edit_message.cc
@@ -1258,7 +1258,7 @@ namespace Astroid {
if (tmpfile.fail()) {
LOG (error) << "em: error: could not create tmpfile!";
- throw runtime_error ("em: coult not create tmpfile!");
+ throw runtime_error ("em: could not create tmpfile!");
}
tmpfile.close ();
diff --git a/src/modes/forward_message.cc b/src/modes/forward_message.cc
index 8343b42..e1b55c2 100644
--- a/src/modes/forward_message.cc
+++ b/src/modes/forward_message.cc
@@ -67,7 +67,7 @@ namespace Astroid {
quoted << "Cc: " << AddressList(msg->cc()).str () << endl;
quoted << endl;
- string vt = msg->plain_text (false);
+ string vt = msg->quote ();
quoted << vt;
body = ustring(quoted.str());
diff --git a/src/modes/reply_message.cc b/src/modes/reply_message.cc
index 915c18e..6fae745 100644
--- a/src/modes/reply_message.cc
+++ b/src/modes/reply_message.cc
@@ -56,7 +56,7 @@ namespace Astroid {
quoted << quoting_a.raw ()
<< endl;
- string vt = msg->plain_text (false);
+ string vt = msg->quote ();
stringstream sstr (vt);
while (sstr.good()) {
string line;
diff --git a/src/utils/cmd.cc b/src/utils/cmd.cc
index 49c2983..a9dba49 100644
--- a/src/utils/cmd.cc
+++ b/src/utils/cmd.cc
@@ -8,6 +8,7 @@
using std::endl;
using std::string;
+
namespace bfs = boost::filesystem;
namespace Astroid {
@@ -44,9 +45,8 @@ namespace Astroid {
ustring c = (!undo ? cmd : undo_cmd);
LOG (info) << "cmd: running: " << c;
- string _stdout;
- string _stderr;
int exit;
+ string _stdout, _stderr;
string _cmd = c;
try {
@@ -71,6 +71,7 @@ namespace Astroid {
return (exit == 0);
}
+
ustring Cmd::substitute (const ustring _cmd) {
ustring ncmd = _cmd;
@@ -82,6 +83,58 @@ namespace Astroid {
return ncmd;
}
+
+ bool Cmd::pipe (ustring cmd, const ustring& _stdin, ustring& _stdout, ustring &_stderr) {
+ LOG (info) << "cmd: running: " << cmd;
+
+ try {
+ int pid;
+ int stdin;
+ int stdout;
+ int stderr;
+ std::vector<std::string> args = Glib::shell_parse_argv (cmd);
+
+ Glib::spawn_async_with_pipes ("",
+ args,
+ Glib::SPAWN_DO_NOT_REAP_CHILD |
+ Glib::SPAWN_SEARCH_PATH,
+ sigc::slot <void> (),
+ &pid,
+ &stdin,
+ &stdout,
+ &stderr
+ );
+
+ refptr<Glib::IOChannel> ch_stdin;
+ refptr<Glib::IOChannel> ch_stdout;
+ refptr<Glib::IOChannel> ch_stderr;
+ ch_stdin = Glib::IOChannel::create_from_fd (stdin);
+ ch_stdout = Glib::IOChannel::create_from_fd (stdout);
+ ch_stderr = Glib::IOChannel::create_from_fd (stderr);
+
+ ch_stdin->write (_stdin);
+ ch_stdin->close ();
+
+ ch_stderr->read_to_end (_stderr);
+ ch_stderr->close ();
+
+ if (!_stderr.empty ()) {
+ LOG (error) << "cmd: " << _stderr;
+ }
+
+ ch_stdout->read_to_end (_stdout);
+ ch_stdout->close ();
+
+ g_spawn_close_pid (pid);
+
+ } catch (Glib::SpawnError &ex) {
+ LOG (error) << "cmd: failed to execute: '" << cmd << "': " << ex.what ();
+ return false;
+ }
+
+
+ return true;
+ }
}
diff --git a/src/utils/cmd.hh b/src/utils/cmd.hh
index cc28c02..c65e9cf 100644
--- a/src/utils/cmd.hh
+++ b/src/utils/cmd.hh
@@ -1,11 +1,7 @@
# pragma once
# include "astroid.hh"
-
-# include <mutex>
-# include <chrono>
-# include <glibmm/threads.h>
-# include <glibmm/iochannel.h>
+# include <string>
namespace Astroid {
class Cmd {
@@ -25,8 +21,12 @@ namespace Astroid {
ustring undo_cmd;
int execute (bool undo); /* currently only in sync */
+ int execute (bool undo, std::string& _stdout, std::string& _stderr); /* currently only in sync */
ustring substitute (ustring);
+
+ public:
+ static bool pipe (ustring cmd, const ustring& _stdin, ustring& _stdout, ustring& _stderr);
};
}