Mercurial > pidgin
diff libpurple/log.c @ 18039:c588a4a9d287
A patch from David Grohmann (dave1g) to log embedded images.
Closes #725
| author | Richard Laager <rlaager@wiktel.com> |
|---|---|
| date | Mon, 04 Jun 2007 05:47:06 +0000 |
| parents | 30b906ba3974 |
| children | 4ca97b26a8fb |
line wrap: on
line diff
--- a/libpurple/log.c Mon Jun 04 04:52:41 2007 +0000 +++ b/libpurple/log.c Mon Jun 04 05:47:06 2007 +0000 @@ -32,6 +32,7 @@ #include "prefs.h" #include "util.h" #include "stringref.h" +#include "imgstore.h" static GSList *loggers = NULL; @@ -690,6 +691,109 @@ return g_strdup(purple_time_format(&tm)); } +/* NOTE: This can return msg (which you may or may not want to g_free()) + * NOTE: or a newly allocated string which you MUST g_free(). */ +static char * +convert_image_tags(const PurpleLog *log, const char *msg) +{ + const char *tmp; + const char *start; + const char *end; + GData *attributes; + GString *newmsg = NULL; + + tmp = msg; + + newmsg = g_string_new(""); + + while (purple_markup_find_tag("img", tmp, &start, &end, &attributes)) { + int imgid = 0; + char *idstr = NULL; + + if (newmsg == NULL) + newmsg = g_string_new(""); + + /* copy any text before the img tag */ + if (tmp < start) + g_string_append_len(newmsg, tmp, start - tmp); + + idstr = g_datalist_get_data(&attributes, "id"); + + imgid = atoi(idstr); + if (imgid != 0) + { + FILE *image_file; + char *dir; + PurpleStoredImage *image; + gconstpointer image_data; + char *new_filename = NULL; + char *path = NULL; + size_t image_byte_count; + + image = purple_imgstore_find_by_id(imgid); + if (image == NULL) + { + /* This should never happen. */ + g_string_free(newmsg, TRUE); + g_return_val_if_reached((char *)msg); + } + + image_data = purple_imgstore_get_data(image); + image_byte_count = purple_imgstore_get_size(image); + dir = purple_log_get_log_dir(log->type, log->name, log->account); + new_filename = purple_util_get_image_filename(image_data, image_byte_count); + + path = g_build_filename(dir, new_filename, NULL); + + /* Only save unique files. */ + if (!g_file_test(path, G_FILE_TEST_EXISTS)) + { + if ((image_file = g_fopen(path, "wb")) != NULL) + { + if (!fwrite(image_data, image_byte_count, 1, image_file)) + { + purple_debug_error("log", "Error writing %s: %s\n", + path, strerror(errno)); + fclose(image_file); + + /* Attempt to not leave half-written files around. */ + unlink(path); + } + else + { + purple_debug_info("log", "Wrote image file: %s\n", path); + fclose(image_file); + } + } + else + { + purple_debug_error("log", "Unable to create file %s: %s\n", + path, strerror(errno)); + } + } + + /* Write the new image tag */ + g_string_append_printf(newmsg, "<IMG SRC=\"%s\">", new_filename); + g_free(new_filename); + g_free(path); + } + + /* Continue from the end of the tag */ + tmp = end + 1; + } + + if (newmsg == NULL) + { + /* No images were found to change. */ + return (char *)msg; + } + + /* Append any remaining message data */ + g_string_append(newmsg, tmp); + + return g_string_free(newmsg, FALSE); +} + void purple_log_common_writer(PurpleLog *log, const char *ext) { PurpleLogCommonLoggerData *data = log->logger_data; @@ -1191,6 +1295,7 @@ const char *from, time_t time, const char *message) { char *msg_fixed; + char *image_corrected_msg; char *date; char *header; PurplePlugin *plugin = purple_find_prpl(purple_account_get_protocol_id(log->account)); @@ -1231,7 +1336,14 @@ if(!data->file) return 0; - purple_markup_html_to_xhtml(message, &msg_fixed, NULL); + image_corrected_msg = convert_image_tags(log, message); + purple_markup_html_to_xhtml(image_corrected_msg, &msg_fixed, NULL); + + /* Yes, this breaks encapsulation. But it's a static function and + * this saves a needless strdup(). */ + if (image_corrected_msg != message) + g_free(image_corrected_msg); + date = log_get_timestamp(log, time); if(log->type == PURPLE_LOG_SYSTEM){
