| 688 return g_strdup(purple_date_format_long(&tm)); |
689 return g_strdup(purple_date_format_long(&tm)); |
| 689 else |
690 else |
| 690 return g_strdup(purple_time_format(&tm)); |
691 return g_strdup(purple_time_format(&tm)); |
| 691 } |
692 } |
| 692 |
693 |
| |
694 /* NOTE: This can return msg (which you may or may not want to g_free()) |
| |
695 * NOTE: or a newly allocated string which you MUST g_free(). */ |
| |
696 static char * |
| |
697 convert_image_tags(const PurpleLog *log, const char *msg) |
| |
698 { |
| |
699 const char *tmp; |
| |
700 const char *start; |
| |
701 const char *end; |
| |
702 GData *attributes; |
| |
703 GString *newmsg = NULL; |
| |
704 |
| |
705 tmp = msg; |
| |
706 |
| |
707 newmsg = g_string_new(""); |
| |
708 |
| |
709 while (purple_markup_find_tag("img", tmp, &start, &end, &attributes)) { |
| |
710 int imgid = 0; |
| |
711 char *idstr = NULL; |
| |
712 |
| |
713 if (newmsg == NULL) |
| |
714 newmsg = g_string_new(""); |
| |
715 |
| |
716 /* copy any text before the img tag */ |
| |
717 if (tmp < start) |
| |
718 g_string_append_len(newmsg, tmp, start - tmp); |
| |
719 |
| |
720 idstr = g_datalist_get_data(&attributes, "id"); |
| |
721 |
| |
722 imgid = atoi(idstr); |
| |
723 if (imgid != 0) |
| |
724 { |
| |
725 FILE *image_file; |
| |
726 char *dir; |
| |
727 PurpleStoredImage *image; |
| |
728 gconstpointer image_data; |
| |
729 char *new_filename = NULL; |
| |
730 char *path = NULL; |
| |
731 size_t image_byte_count; |
| |
732 |
| |
733 image = purple_imgstore_find_by_id(imgid); |
| |
734 if (image == NULL) |
| |
735 { |
| |
736 /* This should never happen. */ |
| |
737 g_string_free(newmsg, TRUE); |
| |
738 g_return_val_if_reached((char *)msg); |
| |
739 } |
| |
740 |
| |
741 image_data = purple_imgstore_get_data(image); |
| |
742 image_byte_count = purple_imgstore_get_size(image); |
| |
743 dir = purple_log_get_log_dir(log->type, log->name, log->account); |
| |
744 new_filename = purple_util_get_image_filename(image_data, image_byte_count); |
| |
745 |
| |
746 path = g_build_filename(dir, new_filename, NULL); |
| |
747 |
| |
748 /* Only save unique files. */ |
| |
749 if (!g_file_test(path, G_FILE_TEST_EXISTS)) |
| |
750 { |
| |
751 if ((image_file = g_fopen(path, "wb")) != NULL) |
| |
752 { |
| |
753 if (!fwrite(image_data, image_byte_count, 1, image_file)) |
| |
754 { |
| |
755 purple_debug_error("log", "Error writing %s: %s\n", |
| |
756 path, strerror(errno)); |
| |
757 fclose(image_file); |
| |
758 |
| |
759 /* Attempt to not leave half-written files around. */ |
| |
760 unlink(path); |
| |
761 } |
| |
762 else |
| |
763 { |
| |
764 purple_debug_info("log", "Wrote image file: %s\n", path); |
| |
765 fclose(image_file); |
| |
766 } |
| |
767 } |
| |
768 else |
| |
769 { |
| |
770 purple_debug_error("log", "Unable to create file %s: %s\n", |
| |
771 path, strerror(errno)); |
| |
772 } |
| |
773 } |
| |
774 |
| |
775 /* Write the new image tag */ |
| |
776 g_string_append_printf(newmsg, "<IMG SRC=\"%s\">", new_filename); |
| |
777 g_free(new_filename); |
| |
778 g_free(path); |
| |
779 } |
| |
780 |
| |
781 /* Continue from the end of the tag */ |
| |
782 tmp = end + 1; |
| |
783 } |
| |
784 |
| |
785 if (newmsg == NULL) |
| |
786 { |
| |
787 /* No images were found to change. */ |
| |
788 return (char *)msg; |
| |
789 } |
| |
790 |
| |
791 /* Append any remaining message data */ |
| |
792 g_string_append(newmsg, tmp); |
| |
793 |
| |
794 return g_string_free(newmsg, FALSE); |
| |
795 } |
| |
796 |
| 693 void purple_log_common_writer(PurpleLog *log, const char *ext) |
797 void purple_log_common_writer(PurpleLog *log, const char *ext) |
| 694 { |
798 { |
| 695 PurpleLogCommonLoggerData *data = log->logger_data; |
799 PurpleLogCommonLoggerData *data = log->logger_data; |
| 696 |
800 |
| 697 if (data == NULL) |
801 if (data == NULL) |
| 1189 |
1293 |
| 1190 static gsize html_logger_write(PurpleLog *log, PurpleMessageFlags type, |
1294 static gsize html_logger_write(PurpleLog *log, PurpleMessageFlags type, |
| 1191 const char *from, time_t time, const char *message) |
1295 const char *from, time_t time, const char *message) |
| 1192 { |
1296 { |
| 1193 char *msg_fixed; |
1297 char *msg_fixed; |
| |
1298 char *image_corrected_msg; |
| 1194 char *date; |
1299 char *date; |
| 1195 char *header; |
1300 char *header; |
| 1196 PurplePlugin *plugin = purple_find_prpl(purple_account_get_protocol_id(log->account)); |
1301 PurplePlugin *plugin = purple_find_prpl(purple_account_get_protocol_id(log->account)); |
| 1197 PurpleLogCommonLoggerData *data = log->logger_data; |
1302 PurpleLogCommonLoggerData *data = log->logger_data; |
| 1198 gsize written = 0; |
1303 gsize written = 0; |
| 1229 |
1334 |
| 1230 /* if we can't write to the file, give up before we hurt ourselves */ |
1335 /* if we can't write to the file, give up before we hurt ourselves */ |
| 1231 if(!data->file) |
1336 if(!data->file) |
| 1232 return 0; |
1337 return 0; |
| 1233 |
1338 |
| 1234 purple_markup_html_to_xhtml(message, &msg_fixed, NULL); |
1339 image_corrected_msg = convert_image_tags(log, message); |
| |
1340 purple_markup_html_to_xhtml(image_corrected_msg, &msg_fixed, NULL); |
| |
1341 |
| |
1342 /* Yes, this breaks encapsulation. But it's a static function and |
| |
1343 * this saves a needless strdup(). */ |
| |
1344 if (image_corrected_msg != message) |
| |
1345 g_free(image_corrected_msg); |
| |
1346 |
| 1235 date = log_get_timestamp(log, time); |
1347 date = log_get_timestamp(log, time); |
| 1236 |
1348 |
| 1237 if(log->type == PURPLE_LOG_SYSTEM){ |
1349 if(log->type == PURPLE_LOG_SYSTEM){ |
| 1238 written += fprintf(data->file, "---- %s @ %s ----<br/>\n", msg_fixed, date); |
1350 written += fprintf(data->file, "---- %s @ %s ----<br/>\n", msg_fixed, date); |
| 1239 } else { |
1351 } else { |