Libpurple: When service.web_directory and service.web_url is set, PURPLE_MESSAGE_IMAGES are stored to web_directory and link is forwarded to the user. Tested only with Facebook for now. Fix #106
This commit is contained in:
parent
408413abf2
commit
65d5b4fe99
2 changed files with 99 additions and 18 deletions
|
@ -9,6 +9,7 @@
|
|||
#include "purple.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "transport/NetworkPlugin.h"
|
||||
#include "transport/Logging.h"
|
||||
|
@ -1123,6 +1124,32 @@ static void conv_write(PurpleConversation *conv, const char *who, const char *al
|
|||
}
|
||||
}
|
||||
|
||||
static char *calculate_data_hash(guchar *data, size_t len,
|
||||
const gchar *hash_algo)
|
||||
{
|
||||
PurpleCipherContext *context;
|
||||
static gchar digest[129]; /* 512 bits hex + \0 */
|
||||
|
||||
context = purple_cipher_context_new_by_name(hash_algo, NULL);
|
||||
if (context == NULL)
|
||||
{
|
||||
purple_debug_error("jabber", "Could not find %s cipher\n", hash_algo);
|
||||
g_return_val_if_reached(NULL);
|
||||
}
|
||||
|
||||
/* Hash the data */
|
||||
purple_cipher_context_append(context, data, len);
|
||||
if (!purple_cipher_context_digest_to_str(context, sizeof(digest), digest, NULL))
|
||||
{
|
||||
purple_debug_error("jabber", "Failed to get digest for %s cipher.\n",
|
||||
hash_algo);
|
||||
g_return_val_if_reached(NULL);
|
||||
}
|
||||
purple_cipher_context_destroy(context);
|
||||
|
||||
return g_strdup(digest);
|
||||
}
|
||||
|
||||
static void conv_write_im(PurpleConversation *conv, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime) {
|
||||
// Don't forwards our own messages.
|
||||
if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM && (flags & PURPLE_MESSAGE_SEND || flags & PURPLE_MESSAGE_SYSTEM)) {
|
||||
|
@ -1130,23 +1157,77 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
|
|||
}
|
||||
PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
|
||||
|
||||
// char *striped = purple_markup_strip_html_wrapped(message);
|
||||
// std::string msg = striped;
|
||||
// g_free(striped);
|
||||
std::string message_;
|
||||
std::string xhtml_;
|
||||
|
||||
if (flags & PURPLE_MESSAGE_IMAGES && !CONFIG_STRING(config, "service.web_directory").empty() && !CONFIG_STRING(config, "service.web_url").empty() ) {
|
||||
LOG4CXX_INFO(logger, "Received image body='" << msg << "'");
|
||||
std::string body = msg;
|
||||
std::string plain = msg;
|
||||
size_t i;
|
||||
while ((i = body.find("<img id=\"")) != std::string::npos) {
|
||||
int from = i + strlen("<img id=\"");
|
||||
int to = body.find("\"", from + 1);
|
||||
std::string id = body.substr(from, to - from);
|
||||
LOG4CXX_INFO(logger, "Image ID = '" << id << "' " << from << " " << to);
|
||||
|
||||
// Escape HTML characters.
|
||||
char *newline = purple_strdup_withhtml_wrapped(msg);
|
||||
char *strip, *xhtml;
|
||||
purple_markup_html_to_xhtml_wrapped(newline, &xhtml, &strip);
|
||||
// xhtml_linkified = spectrum_markup_linkify(xhtml);
|
||||
std::string message_(strip);
|
||||
PurpleStoredImage *image = purple_imgstore_find_by_id(atoi(id.c_str()));
|
||||
if (!image) {
|
||||
LOG4CXX_ERROR(logger, "Cannot find image with id " << id << ".");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string xhtml_(xhtml);
|
||||
g_free(newline);
|
||||
g_free(xhtml);
|
||||
// g_free(xhtml_linkified);
|
||||
g_free(strip);
|
||||
std::string ext = "icon";
|
||||
std::string name;
|
||||
guchar * data = (guchar *) purple_imgstore_get_data_wrapped(image);
|
||||
size_t len = purple_imgstore_get_size_wrapped(image);
|
||||
if (len < 300000 && data) {
|
||||
ext = purple_imgstore_get_extension(image);
|
||||
char *hash = calculate_data_hash(data, len, "sha1");
|
||||
if (!hash) {
|
||||
return;
|
||||
}
|
||||
name = hash;
|
||||
g_free(hash);
|
||||
|
||||
std::ofstream output;
|
||||
output.open(std::string(CONFIG_STRING(config, "service.web_directory") + "/" + name + "." + ext).c_str(), std::ios::out | std::ios::binary);
|
||||
output.write((char *)data, len);
|
||||
output.close();
|
||||
}
|
||||
else {
|
||||
purple_imgstore_unref_wrapped(image);
|
||||
return;
|
||||
}
|
||||
purple_imgstore_unref_wrapped(image);
|
||||
|
||||
std::string src = CONFIG_STRING(config, "service.web_url") + "/" + name + "." + ext;
|
||||
std::string img = "<img src=\"" + src + "\"/>";
|
||||
boost::replace_all(body, "<img id=\"" + id + "\">", img);
|
||||
boost::replace_all(plain, "<img id=\"" + id + "\">", src);
|
||||
}
|
||||
LOG4CXX_INFO(logger, "New image body='" << body << "'");
|
||||
char *strip, *xhtml;
|
||||
purple_markup_html_to_xhtml_wrapped(body.c_str(), &xhtml, &strip);
|
||||
message_ = strip;
|
||||
if (message_.empty()) {
|
||||
message_ = plain;
|
||||
}
|
||||
xhtml_ = xhtml;
|
||||
g_free(xhtml);
|
||||
g_free(strip);
|
||||
}
|
||||
else {
|
||||
// Escape HTML characters.
|
||||
char *newline = purple_strdup_withhtml_wrapped(msg);
|
||||
char *strip, *xhtml;
|
||||
purple_markup_html_to_xhtml_wrapped(newline, &xhtml, &strip);
|
||||
message_ = strip;
|
||||
xhtml_ = xhtml;
|
||||
g_free(newline);
|
||||
g_free(xhtml);
|
||||
g_free(strip);
|
||||
}
|
||||
|
||||
// AIM and XMPP adds <body>...</body> here...
|
||||
if (xhtml_.find("<body>") == 0) {
|
||||
|
@ -1167,8 +1248,6 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
|
|||
timestamp = buf;
|
||||
}
|
||||
|
||||
// LOG4CXX_INFO(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "'");
|
||||
|
||||
if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM) {
|
||||
std::string w = purple_normalize_wrapped(account, who);
|
||||
std::string n;
|
||||
|
@ -1177,11 +1256,11 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
|
|||
n = w.substr((int) pos + 1, w.length() - (int) pos);
|
||||
w.erase((int) pos, w.length() - (int) pos);
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << w);
|
||||
LOG4CXX_INFO(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "' name='" << w << "'");
|
||||
np->handleMessage(np->m_accounts[account], w, message_, n, xhtml_, timestamp);
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << purple_conversation_get_name_wrapped(conv) << "' " << who);
|
||||
LOG4CXX_INFO(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "' name='" << purple_conversation_get_name_wrapped(conv) << "' " << who);
|
||||
np->handleMessage(np->m_accounts[account], purple_conversation_get_name_wrapped(conv), message_, who, xhtml_, timestamp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,8 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
|
|||
("service.vip_only", value<bool>()->default_value(false), "")
|
||||
("service.vip_message", value<std::string>()->default_value(""), "")
|
||||
("service.reconnect_all_users", value<bool>()->default_value(false), "")
|
||||
("service.web_directory", value<std::string>()->default_value(""), "Full path to directory used to save files to which the links are sent to users.")
|
||||
("service.web_url", value<std::string>()->default_value(""), "URL on which files in web_directory are accessible.")
|
||||
("vhosts.vhost", value<std::vector<std::string> >()->multitoken(), "")
|
||||
("identity.name", value<std::string>()->default_value("Spectrum 2 Transport"), "Name showed in service discovery.")
|
||||
("identity.category", value<std::string>()->default_value("gateway"), "Disco#info identity category. 'gateway' by default.")
|
||||
|
|
Loading…
Add table
Reference in a new issue