Now that the History API is here, remove the purple logging api
Testing Done:
Sent ims in both pidgin3 and finch3, also joined a chat in pidgin3 and verified that the preferences window is okay.
Reviewed at https://reviews.imfreedom.org/r/1077/
--- a/ChangeLog.API Fri Oct 22 03:33:32 2021 -0500
+++ b/ChangeLog.API Sat Oct 23 01:06:57 2021 -0500
@@ -320,7 +320,9 @@
* PurpleAccountPrefsUiOps
* purple_account_add_buddies_with_invite
* purple_account_add_buddy_with_invite
+ * purple_account_destroy_log * purple_account_get_check_mail
+ * purple_account_get_log * purple_account_get_password. Use
purple_credential_manager_read_password_async instead.
* purple_account_get_public_alias
@@ -367,8 +369,10 @@
* purple_conv_custom_smiley_write
* purple_conversation_add_smiley
+ * purple_conversation_close_logs * purple_conversation_get_remote_smileys
* purple_conversation_get_smiley
+ * purple_conversation_is_logging * purple_conversations_add. Use purple_conversation_manager_register
* purple_conversations_remove. Use
@@ -383,6 +387,7 @@
purple_conversation_manager_find_chat instead.
* purple_conversations_find_chat. Use
purple_conversation_manager_find_chat_by_id instead.
+ * purple_conversation_set_logging * purple_core_ensure_single_instance. Check via GApplication
or whatever is appropriate for your UI.
--- a/doc/reference/libpurple/libpurple-docs.xml Fri Oct 22 03:33:32 2021 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml Sat Oct 23 01:06:57 2021 -0500
@@ -138,7 +138,6 @@
<xi:include href="xml/purplemessage.xml" />
<xi:include href="xml/purpleattachment.xml" />
- <xi:include href="xml/log.xml" />
<xi:include href="xml/cmds.xml" />
--- a/finch/gntblist.c Fri Oct 22 03:33:32 2021 -0500
+++ b/finch/gntblist.c Sat Oct 23 01:06:57 2021 -0500
@@ -131,7 +131,6 @@
static int blist_node_compare_position(PurpleBlistNode *n1, PurpleBlistNode *n2);
static int blist_node_compare_text(PurpleBlistNode *n1, PurpleBlistNode *n2);
static int blist_node_compare_status(PurpleBlistNode *n1, PurpleBlistNode *n2);
-static int blist_node_compare_log(PurpleBlistNode *n1, PurpleBlistNode *n2);
static int color_available;
@@ -1843,9 +1842,6 @@
} else if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "status")) {
gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
(GCompareFunc)blist_node_compare_status);
- } else if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "log")) {
- gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
- (GCompareFunc)blist_node_compare_log);
list = purple_blist_get_default();
@@ -2228,49 +2224,6 @@
-get_contact_log_size(PurpleBlistNode *c)
- for (node = purple_blist_node_get_first_child(c); node; node = purple_blist_node_get_sibling_next(node)) {
- PurpleBuddy *b = (PurpleBuddy*)node;
- log += purple_log_get_total_size(PURPLE_LOG_IM, purple_buddy_get_name(b),
- purple_buddy_get_account(b));
-blist_node_compare_log(PurpleBlistNode *n1, PurpleBlistNode *n2)
- if (G_OBJECT_TYPE(n1) != G_OBJECT_TYPE(n2))
- return blist_node_compare_position(n1, n2);
- if (PURPLE_IS_BUDDY(n1)) {
- ret = purple_log_get_total_size(PURPLE_LOG_IM, purple_buddy_get_name(b2), purple_buddy_get_account(b2)) -
- purple_log_get_total_size(PURPLE_LOG_IM, purple_buddy_get_name(b1), purple_buddy_get_account(b1));
- } else if (PURPLE_IS_CONTACT(n1)) {
- ret = get_contact_log_size(n2) - get_contact_log_size(n1);
- return blist_node_compare_position(n1, n2);
- ret = blist_node_compare_text(n1, n2);
plugin_action(GntMenuItem *item, gpointer data)
--- a/finch/gntconv.c Fri Oct 22 03:33:32 2021 -0500
+++ b/finch/gntconv.c Sat Oct 23 01:06:57 2021 -0500
@@ -490,42 +490,6 @@
-toggle_logging_cb(GntMenuItem *item, gpointer ggconv)
- FinchConv *fc = ggconv;
- PurpleConversation *conv = fc->active_conv;
- gboolean logging = gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item));
- if (logging == purple_conversation_is_logging(conv))
- /* Enable logging first so the message below can be logged. */
- purple_conversation_set_logging(conv, TRUE);
- purple_conversation_write_system_message(conv,
- _("Logging started. Future messages in this "
- "conversation will be logged."), 0);
- purple_conversation_write_system_message(conv,
- _("Logging stopped. Future messages in this "
- "conversation will not be logged."), 0);
- /* Disable the logging second, so that the above message can be logged. */
- purple_conversation_set_logging(conv, FALSE);
- /* Each conversation with the same person will have the same logging setting */
- for (iter = fc->list; iter; iter = iter->next) {
- if (iter->data == conv)
- purple_conversation_set_logging(iter->data, logging);
send_to_cb(GntMenuItem *m, gpointer n)
PurpleAccount *account = g_object_get_data(G_OBJECT(m), "purple_account");
@@ -654,12 +618,6 @@
gnt_menuitem_set_callback(item, invite_cb, ggc);
- item = gnt_menuitem_check_new(_("Enable Logging"));
- gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item),
- purple_conversation_is_logging(ggc->active_conv));
- gnt_menu_add_item(GNT_MENU(sub), item);
- gnt_menuitem_set_callback(item, toggle_logging_cb, ggc);
item = gnt_menuitem_new(_("Plugins"));
gnt_menu_add_item(GNT_MENU(menu), item);
@@ -768,12 +726,6 @@
ggc = g_new0(FinchConv, 1);
- /* Each conversation with the same person will have the same logging setting */
- purple_conversation_set_logging(conv,
- purple_conversation_is_logging(ggc->list->data));
ggc->list = g_list_prepend(ggc->list, conv);
g_object_set_data(G_OBJECT(conv), "finch", ggc);
--- a/finch/gntprefs.c Fri Oct 22 03:33:32 2021 -0500
+++ b/finch/gntprefs.c Sat Oct 23 01:06:57 2021 -0500
@@ -68,12 +68,6 @@
- return purple_log_logger_get_options();
@@ -185,7 +179,6 @@
- {PURPLE_PREF_STRING, "/purple/logging/format", N_("Log format"), get_log_options},
{PURPLE_PREF_BOOLEAN, "/purple/logging/log_ims", N_("Log IMs"), NULL},
{PURPLE_PREF_BOOLEAN, "/purple/logging/log_chats", N_("Log chats"), NULL},
{PURPLE_PREF_BOOLEAN, "/purple/logging/log_system", N_("Log status change events"), NULL},
--- a/finch/plugins/gnthistory.c Fri Oct 22 03:33:32 2021 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
- * Copyright (C) 2006 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-/* Ripped from gtk/plugins/history.c */
-#include <glib/gi18n-lib.h>
-#define HISTORY_PLUGIN_ID "gnt-history"
-#define HISTORY_SIZE (4 * 1024)
-static void historize(PurpleConversation *c)
- PurpleAccount *account = purple_conversation_get_account(c);
- const char *name = purple_conversation_get_name(c);
- const char *alias = name;
- PurpleLogReadFlags flags;
- PurpleMessageFlags mflag;
- if (PURPLE_IS_IM_CONVERSATION(c)) {
- FinchConv *fc = FINCH_CONV(c);
- if (fc->list && fc->list->next) /* We were already in the middle of a conversation. */
- /* If we're not logging, don't show anything.
- * Otherwise, we might show a very old log. */
- if (!purple_prefs_get_bool("/purple/logging/log_ims"))
- /* Find buddies for this conversation. */
- buddies = purple_blist_find_buddies(account, name);
- /* If we found at least one buddy, save the first buddy's alias. */
- alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(buddies->data));
- for (cur = buddies; cur != NULL; cur = cur->next) {
- PurpleBlistNode *node = cur->data;
- ((purple_blist_node_get_sibling_prev(node) != NULL) ||
- (purple_blist_node_get_sibling_next(node) != NULL))) {
- PurpleBlistNode *node2;
- alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(node));
- /* We've found a buddy that matches this conversation. It's part of a
- * PurpleContact with more than one PurpleBuddy. Loop through the PurpleBuddies
- * in the contact and get all the logs. */
- for (node2 = purple_blist_node_get_first_child(purple_blist_node_get_parent(node));
- node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2)) {
- purple_log_get_logs(PURPLE_LOG_IM,
- purple_buddy_get_name(PURPLE_BUDDY(node2)),
- purple_buddy_get_account(PURPLE_BUDDY(node2))),
- logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
- logs = g_list_sort(logs, purple_log_compare);
- } else if (PURPLE_IS_CHAT_CONVERSATION(c)) {
- /* If we're not logging, don't show anything.
- * Otherwise, we might show a very old log. */
- if (!purple_prefs_get_bool("/purple/logging/log_chats"))
- logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account);
- mflag = PURPLE_MESSAGE_NO_LOG | PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_DELAYED;
- history = purple_log_read((PurpleLog*)logs->data, &flags);
- dt = g_date_time_to_local(((PurpleLog *)logs->data)->time);
- date = g_date_time_format(dt, "%c");
- header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), alias, date);
- purple_conversation_write_system_message(c, header, mflag);
- if (flags & PURPLE_LOG_READ_NO_NEWLINE)
- purple_str_strip_char(history, '\n');
- purple_conversation_write_system_message(c, history, mflag);
- purple_conversation_write_system_message(c, "<hr>", mflag);
- g_list_free_full(logs, (GDestroyNotify)purple_log_free);
-history_prefs_check(PurplePlugin *plugin)
- if (!purple_prefs_get_bool("/purple/logging/log_ims") &&
- !purple_prefs_get_bool("/purple/logging/log_chats"))
- PurpleRequestFields *fields = purple_request_fields_new();
- PurpleRequestFieldGroup *group;
- PurpleRequestField *field;
- {"/purple/logging/log_ims", N_("Log IMs")},
- {"/purple/logging/log_chats", N_("Log chats")},
- GList *list = purple_log_logger_get_options();
- const char *system = purple_prefs_get_string("/purple/logging/format");
- group = purple_request_field_group_new(_("Logging"));
- field = purple_request_field_list_new("/purple/logging/format", _("Log format"));
- const char *label = _(list->data);
- list = g_list_delete_link(list, list);
- purple_request_field_list_add_icon(field, label, NULL, list->data);
- if (purple_strequal(system, list->data))
- purple_request_field_list_add_selected(field, label);
- list = g_list_delete_link(list, list);
- purple_request_field_group_add_field(group, field);
- for (iter = 0; prefs[iter].pref; iter++) {
- field = purple_request_field_bool_new(prefs[iter].pref, _(prefs[iter].label),
- purple_prefs_get_bool(prefs[iter].pref));
- purple_request_field_group_add_field(group, field);
- purple_request_fields_add_group(fields, group);
- /* Translators: Please maintain the use of ⇦ or ⇨ to represent the menu hierarchy */
- purple_request_fields(plugin, NULL, _("History Plugin Requires Logging"),
- _("Logging can be enabled from Tools ⇨ Preferences ⇨ Logging.\n\n"
- "Enabling logs for instant messages and/or chats will activate "
- "history for the same conversation type(s)."),
- _("OK"), G_CALLBACK(finch_request_save_in_prefs),
-static void history_prefs_cb(const char *name, PurplePrefType type,
- gconstpointer val, gpointer data)
- history_prefs_check((PurplePlugin *)data);
-static GPluginPluginInfo *
-gnt_history_query(GError **error) {
- const gchar * const authors[] = {
- "Sean Egan <seanegan@gmail.com>",
- "Sadrul H Chowdhury <sadrul@users.sourceforge.net>",
- return finch_plugin_info_new(
- "id", HISTORY_PLUGIN_ID,
- "name", N_("GntHistory"),
- "version", DISPLAY_VERSION,
- "category", N_("User interface"),
- "summary", N_("Shows recently logged conversations in new "
- "description", N_("When a new conversation is opened this plugin will "
- "insert the last conversation into the current "
- "website", PURPLE_WEBSITE,
- "abi-version", PURPLE_ABI_VERSION,
-gnt_history_load(GPluginPlugin *plugin, GError **error) {
- purple_signal_connect(purple_conversations_get_handle(),
- "conversation-created",
- plugin, PURPLE_CALLBACK(historize), NULL);
- purple_prefs_connect_callback(plugin, "/purple/logging/log_ims",
- history_prefs_cb, plugin);
- purple_prefs_connect_callback(plugin, "/purple/logging/log_chats",
- history_prefs_cb, plugin);
- history_prefs_check(plugin);
-gnt_history_unload(GPluginPlugin *plugin, gboolean shutdown, GError **error) {
-GPLUGIN_NATIVE_PLUGIN_DECLARE(gnt_history)
\ No newline at end of file
--- a/finch/plugins/meson.build Fri Oct 22 03:33:32 2021 -0500
+++ b/finch/plugins/meson.build Sat Oct 23 01:06:57 2021 -0500
@@ -16,12 +16,6 @@
install : true, install_dir : FINCH_PLUGINDIR)
-gnthistory = library('gnthistory', 'gnthistory.c',
- c_args : ['-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="Gnt-History"'],
- dependencies : [libpurple_dep, libfinch_dep, glib],
- install : true, install_dir : FINCH_PLUGINDIR)
gntlastlog = library('gntlastlog', 'lastlog.c',
c_args : ['-DG_LOG_USE_STRUCTURED', '-DG_LOG_DOMAIN="Gnt-LastLog"'],
dependencies : [libpurple_dep, libfinch_dep, ncurses, glib],
--- a/libpurple/account.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/account.c Sat Oct 23 01:06:57 2021 -0500
@@ -92,7 +92,6 @@
GList *status_types; /* Status types. */
PurplePresence *presence; /* Presence. */
- PurpleLog *system_log; /* The system log */
PurpleAccountRegistrationCb registration_cb;
void *registration_cb_user_data;
@@ -976,7 +975,6 @@
priv->ui_settings = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, (GDestroyNotify)g_hash_table_destroy);
- priv->system_log = NULL;
priv->privacy_type = PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL;
@@ -1075,9 +1073,6 @@
purple_proxy_info_destroy(priv->proxy_info);
- purple_log_free(priv->system_log);
if (priv->current_error) {
g_free(priv->current_error->description);
g_free(priv->current_error);
@@ -2730,52 +2725,6 @@
return g_value_get_boolean(&setting->value);
-purple_account_get_log(PurpleAccount *account, gboolean create)
- PurpleAccountPrivate *priv;
- g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
- priv = purple_account_get_instance_private(account);
- if(!priv->system_log && create){
- PurplePresence *presence;
- presence = purple_account_get_presence(account);
- login_time = purple_presence_get_login_time(presence);
- dt = g_date_time_new_from_unix_local(login_time);
- dt = g_date_time_new_now_local();
- priv->system_log = purple_log_new(PURPLE_LOG_SYSTEM,
- purple_account_get_username(account),
- return priv->system_log;
-purple_account_destroy_log(PurpleAccount *account)
- PurpleAccountPrivate *priv;
- g_return_if_fail(PURPLE_IS_ACCOUNT(account));
- priv = purple_account_get_instance_private(account);
- purple_log_free(priv->system_log);
- priv->system_log = NULL;
purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy, const char *message)
--- a/libpurple/account.h Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/account.h Sat Oct 23 01:06:57 2021 -0500
@@ -56,7 +56,7 @@
@@ -1041,31 +1041,6 @@
gboolean purple_account_get_ui_bool(PurpleAccount *account, const char *ui,
const char *name, gboolean default_value);
- * purple_account_get_log:
- * @account: The account.
- * @create: Should it be created if it doesn't exist?
- * Returns the system log for an account.
- * Note: Callers should almost always pass %FALSE for @a create.
- * Passing %TRUE could result in an existing log being reopened,
- * if the log has already been closed, which not all loggers deal
-PurpleLog *purple_account_get_log(PurpleAccount *account, gboolean create);
- * purple_account_destroy_log:
- * @account: The account.
- * Frees the system log of an account
-void purple_account_destroy_log(PurpleAccount *account);
* purple_account_add_buddy:
--- a/libpurple/buddyicon.h Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/buddyicon.h Sat Oct 23 01:06:57 2021 -0500
@@ -53,6 +53,7 @@
typedef struct _PurpleBuddyIconSpec PurpleBuddyIconSpec;
--- a/libpurple/buddylist.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/buddylist.c Sat Oct 23 01:06:57 2021 -0500
@@ -24,6 +24,7 @@
#include <glib/gi18n-lib.h>
--- a/libpurple/connection.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/connection.c Sat Oct 23 01:06:57 2021 -0500
@@ -27,7 +27,6 @@
@@ -201,23 +200,6 @@
/* Set the time the account came online */
purple_presence_set_login_time(presence, time(NULL));
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- PurpleLog *log = purple_account_get_log(account, TRUE);
- char *msg = g_strdup_printf(_("+++ %s signed on"),
- purple_account_get_username(account));
- GDateTime *dt = g_date_time_new_from_unix_local(purple_presence_get_login_time(presence));
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_account_get_username(account),
if (ops != NULL && ops->connected != NULL)
@@ -244,27 +226,6 @@
else if (priv->state == PURPLE_CONNECTION_DISCONNECTED) {
- PurpleAccount *account = purple_connection_get_account(gc);
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- PurpleLog *log = purple_account_get_log(account, FALSE);
- char *msg = g_strdup_printf(_("+++ %s signed off"),
- purple_account_get_username(account));
- GDateTime *dt = g_date_time_new_now_utc();
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_account_get_username(account),
- purple_account_destroy_log(account);
if (ops != NULL && ops->disconnected != NULL)
--- a/libpurple/conversations.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/conversations.c Sat Oct 23 01:06:57 2021 -0500
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+#include "conversations.h" #include "purpleprivate.h"
#include "purpleconversationmanager.h"
--- a/libpurple/core.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/core.c Sat Oct 23 01:06:57 2021 -0500
@@ -24,6 +24,7 @@
+#include "conversations.h" @@ -169,7 +170,6 @@
purple_conversation_manager_startup();
purple_whiteboard_manager_startup();
purple_history_manager_startup();
@@ -249,7 +249,6 @@
purple_history_manager_shutdown();
/* Everything after util_uninit cannot try to write things to the
@@ -365,7 +364,6 @@
xdg_dir_exists = g_file_test(purple_data_dir(), G_FILE_TEST_EXISTS);
MIGRATE_TO_XDG_DIR(purple_data_dir(), "certificates");
- MIGRATE_TO_XDG_DIR(purple_data_dir(), "logs");
MIGRATE_TO_XDG_DIR(purple_config_dir(), "accounts.xml");
MIGRATE_TO_XDG_DIR(purple_config_dir(), "blist.xml");
MIGRATE_TO_XDG_DIR(purple_config_dir(), "fs-codec.conf");
--- a/libpurple/idle.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/idle.c Sat Oct 23 01:06:57 2021 -0500
@@ -22,10 +22,10 @@
+#include "conversations.h"
#include "savedstatuses.h"
--- a/libpurple/log.c Fri Oct 22 03:33:32 2021 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1457 +0,0 @@
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-#include <glib/gi18n-lib.h>
-#include <glib/gstdio.h>
-#include "glibcompat.h" /* for purple_g_stat on win32 */
-#include "image-store.h"
-#include "purplemarkup.h"
-static GSList *loggers = NULL;
-static PurpleLogLogger *html_logger;
-static PurpleLogLogger *txt_logger;
-static GHashTable *logsize_users = NULL;
-static GHashTable *logsize_users_decayed = NULL;
-static void log_get_log_sets_common(GHashTable *sets);
-static gsize html_logger_write(PurpleLog *log, PurpleMessageFlags type,
- const char *from, GDateTime *time, const char *message);
-static void html_logger_finalize(PurpleLog *log);
-static GList *html_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account);
-static GList *html_logger_list_syslog(PurpleAccount *account);
-static char *html_logger_read(PurpleLog *log, PurpleLogReadFlags *flags);
-static int html_logger_total_size(PurpleLogType type, const char *name, PurpleAccount *account);
-static gsize txt_logger_write(PurpleLog *log, PurpleMessageFlags type,
- const char *from, GDateTime *time, const char *message);
-static void txt_logger_finalize(PurpleLog *log);
-static GList *txt_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account);
-static GList *txt_logger_list_syslog(PurpleAccount *account);
-static char *txt_logger_read(PurpleLog *log, PurpleLogReadFlags *flags);
-static int txt_logger_total_size(PurpleLogType type, const char *name, PurpleAccount *account);
-/**************************************************************************
- * PUBLIC LOGGING FUNCTIONS ***********************************************
- **************************************************************************/
-PurpleLog *purple_log_new(PurpleLogType type, const char *name, PurpleAccount *account,
- PurpleConversation *conv, GDateTime *time)
- /* IMPORTANT: Make sure to initialize all the members of PurpleLog */
- log = g_slice_new(PurpleLog);
- log->name = g_strdup(purple_normalize(account, name));
- log->account = account;
- log->time = g_date_time_ref(time);
- log->logger = purple_log_logger_get();
- log->logger_data = NULL;
- if (log->logger && log->logger->create)
- log->logger->create(log);
-void purple_log_free(PurpleLog *log)
- if (log->logger && log->logger->finalize)
- log->logger->finalize(log);
- g_date_time_unref(log->time);
- g_slice_free(PurpleLog, log);
-void purple_log_write(PurpleLog *log, PurpleMessageFlags type,
- const char *from, GDateTime *time, const char *message)
- PurpleKeyValuePair *lu;
- gsize written, total = 0;
- g_return_if_fail(log->logger);
- g_return_if_fail(log->logger->write);
- written = (log->logger->write)(log, type, from, time, message);
- lu = purple_key_value_pair_new(purple_normalize(log->account, log->name), log->account);
- if(g_hash_table_lookup_extended(logsize_users, lu, NULL, &ptrsize)) {
- total = GPOINTER_TO_INT(ptrsize);
- g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(total));
- /* The hash table takes ownership of lu, so create a new one
- * for the logsize_users_decayed check below. */
- lu = purple_key_value_pair_new(lu->key, log->account);
- if(g_hash_table_lookup_extended(logsize_users_decayed, lu, NULL, &ptrsize)) {
- total = GPOINTER_TO_INT(ptrsize);
- g_hash_table_replace(logsize_users_decayed, lu, GINT_TO_POINTER(total));
- purple_key_value_pair_free(lu);
-char *purple_log_read(PurpleLog *log, PurpleLogReadFlags *flags)
- PurpleLogReadFlags mflags;
- g_return_val_if_fail(log && log->logger, NULL);
- if (log->logger->read) {
- char *ret = (log->logger->read)(log, flags ? flags : &mflags);
- purple_str_strip_char(ret, '\r');
- return g_strdup(_("<b><font color=\"red\">The logger has no read function</font></b>"));
-int purple_log_get_size(PurpleLog *log)
- g_return_val_if_fail(log && log->logger, 0);
- return log->logger->size(log);
-_purple_logsize_user_hash(PurpleKeyValuePair *lu)
- return g_str_hash(lu->key);
-_purple_logsize_user_equal(PurpleKeyValuePair *lu1, PurpleKeyValuePair *lu2)
- return (lu1->value == lu2->value && purple_strequal(lu1->key, lu2->key));
-int purple_log_get_total_size(PurpleLogType type, const char *name, PurpleAccount *account)
- PurpleKeyValuePair *lu;
- lu = purple_key_value_pair_new(purple_normalize(account, name), account);
- if(g_hash_table_lookup_extended(logsize_users, lu, NULL, &ptrsize)) {
- size = GPOINTER_TO_INT(ptrsize);
- purple_key_value_pair_free(lu);
- for (n = loggers; n; n = n->next) {
- PurpleLogLogger *logger = n->data;
- if(logger->total_size){
- size += (logger->total_size)(type, name, account);
- } else if(logger->list) {
- GList *logs = (logger->list)(type, name, account);
- PurpleLog *log = (PurpleLog*)(logs->data);
- this_size += purple_log_get_size(log);
- logs = g_list_delete_link(logs, logs);
- g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(size));
-gint purple_log_get_activity_score(PurpleLogType type, const char *name, PurpleAccount *account)
- PurpleKeyValuePair *lu;
- lu = purple_key_value_pair_new(purple_normalize(account, name), account);
- if(g_hash_table_lookup_extended(logsize_users_decayed, lu, NULL, &ptrscore)) {
- score = GPOINTER_TO_INT(ptrscore);
- purple_key_value_pair_free(lu);
- GDateTime *now = g_date_time_new_now_utc();
- double score_double = 0.0;
- for (n = loggers; n; n = n->next) {
- PurpleLogLogger *logger = n->data;
- GList *logs = (logger->list)(type, name, account);
- PurpleLog *log = (PurpleLog*)(logs->data);
- /* Activity score counts bytes in the log, exponentially
- decayed with a half-life of 14 days. */
- score_double += purple_log_get_size(log) *
- pow(0.5, g_date_time_difference(now, log->time)/(14LL*G_TIME_SPAN_DAY));
- logs = g_list_delete_link(logs, logs);
- g_date_time_unref(now);
- score = (gint) ceil(score_double);
- g_hash_table_replace(logsize_users_decayed, lu, GINT_TO_POINTER(score));
-gboolean purple_log_is_deletable(PurpleLog *log)
- g_return_val_if_fail(log != NULL, FALSE);
- g_return_val_if_fail(log->logger != NULL, FALSE);
- if (log->logger->remove == NULL)
- if (log->logger->is_deletable != NULL)
- return log->logger->is_deletable(log);
-gboolean purple_log_delete(PurpleLog *log)
- g_return_val_if_fail(log != NULL, FALSE);
- g_return_val_if_fail(log->logger != NULL, FALSE);
- if (log->logger->remove != NULL)
- return log->logger->remove(log);
-purple_log_get_log_dir(PurpleLogType type, const char *name, PurpleAccount *account)
- PurpleProtocol *protocol;
- const char *protocol_name;
- protocol = purple_account_get_protocol(account);
- protocol_name = purple_protocol_get_list_icon(protocol, account, NULL);
- acct_name = g_strdup(purple_escape_filename(purple_normalize(account,
- purple_account_get_username(account))));
- if (type == PURPLE_LOG_CHAT) {
- char *temp = g_strdup_printf("%s.chat", purple_normalize(account, name));
- target = purple_escape_filename(temp);
- } else if(type == PURPLE_LOG_SYSTEM) {
- target = purple_escape_filename(purple_normalize(account, name));
- dir = g_build_filename(purple_data_dir(), "logs", protocol_name, acct_name, target, NULL);
-/****************************************************************************
- * LOGGER FUNCTIONS *********************************************************
- ****************************************************************************/
-static PurpleLogLogger *current_logger = NULL;
-static void logger_pref_cb(const char *name, PurplePrefType type,
- gconstpointer value, gpointer data)
- PurpleLogLogger *logger;
- if (purple_strequal(logger->id, value)) {
- purple_log_logger_set(logger);
- purple_log_logger_set(txt_logger);
-PurpleLogLogger *purple_log_logger_new(const char *id, const char *name, int functions, ...)
- PurpleLogLogger *logger;
- g_return_val_if_fail(id != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
- g_return_val_if_fail(functions >= 1, NULL);
- logger = g_new0(PurpleLogLogger, 1);
- logger->id = g_strdup(id);
- logger->name = g_strdup(name);
- va_start(args, functions);
- logger->create = va_arg(args, void *);
- logger->write = va_arg(args, void *);
- logger->finalize = va_arg(args, void *);
- logger->list = va_arg(args, void *);
- logger->read = va_arg(args, void *);
- logger->size = va_arg(args, void *);
- logger->total_size = va_arg(args, void *);
- logger->list_syslog = va_arg(args, void *);
- logger->get_log_sets = va_arg(args, void *);
- logger->remove = va_arg(args, void *);
- logger->is_deletable = va_arg(args, void *);
- purple_debug_info("log", "Dropping new functions for logger: %s (%s)\n", name, id);
-void purple_log_logger_free(PurpleLogLogger *logger)
-void purple_log_logger_add (PurpleLogLogger *logger)
- g_return_if_fail(logger);
- if (g_slist_find(loggers, logger))
- loggers = g_slist_append(loggers, logger);
- if (purple_strequal(purple_prefs_get_string("/purple/logging/format"), logger->id)) {
- purple_prefs_trigger_callback("/purple/logging/format");
-void purple_log_logger_remove (PurpleLogLogger *logger)
- g_return_if_fail(logger);
- loggers = g_slist_remove(loggers, logger);
-void purple_log_logger_set (PurpleLogLogger *logger)
- g_return_if_fail(logger);
- current_logger = logger;
-PurpleLogLogger *purple_log_logger_get()
-GList *purple_log_logger_get_options(void)
- for (n = loggers; n; n = n->next) {
- list = g_list_append(list, data->name);
- list = g_list_append(list, data->id);
-gint purple_log_compare(gconstpointer y, gconstpointer z)
- const PurpleLog *a = y;
- const PurpleLog *b = z;
- /* Sort in reverse order. */
- return g_date_time_compare(b->time, a->time);
-GList *purple_log_get_logs(PurpleLogType type, const char *name, PurpleAccount *account)
- for (n = loggers; n; n = n->next) {
- PurpleLogLogger *logger = n->data;
- logs = g_list_concat(logger->list(type, name, account), logs);
- return g_list_sort(logs, purple_log_compare);
-gint purple_log_set_compare(gconstpointer y, gconstpointer z)
- const PurpleLogSet *a = y;
- const PurpleLogSet *b = z;
- /* This logic seems weird at first...
- * If either account is NULL, we pretend the accounts are
- * equal. This allows us to detect duplicates that will
- * exist if one logger knows the account and another
- if (a->account != NULL && b->account != NULL) {
- ret = strcmp(purple_account_get_username(a->account), purple_account_get_username(b->account));
- ret = strcmp(a->normalized_name, b->normalized_name);
- return (gint)b->type - (gint)a->type;
-log_set_hash(gconstpointer key)
- const PurpleLogSet *set = key;
- /* The account isn't hashed because we need PurpleLogSets with NULL accounts
- * to be found when we search by a PurpleLogSet that has a non-NULL account
- * but the same type and name. */
- return g_int_hash(&set->type) + g_str_hash(set->name);
-log_set_equal(gconstpointer a, gconstpointer b)
- /* I realize that the choices made for GList and GHashTable
- * make sense for those data types, but I wish the comparison
- * functions were compatible. */
- return !purple_log_set_compare(a, b);
-log_add_log_set_to_hash(GHashTable *sets, PurpleLogSet *set)
- PurpleLogSet *existing_set = g_hash_table_lookup(sets, set);
- if (existing_set == NULL)
- g_hash_table_insert(sets, set, set);
- else if (existing_set->account == NULL && set->account != NULL)
- g_hash_table_replace(sets, set, set);
- purple_log_set_free(set);
-GHashTable *purple_log_get_log_sets(void)
- GHashTable *sets = g_hash_table_new_full(log_set_hash, log_set_equal,
- (GDestroyNotify)purple_log_set_free, NULL);
- /* Get the log sets from all the loggers. */
- for (n = loggers; n; n = n->next) {
- PurpleLogLogger *logger = n->data;
- if (!logger->get_log_sets)
- logger->get_log_sets(log_add_log_set_to_hash, sets);
- log_get_log_sets_common(sets);
- /* Return the GHashTable of unique PurpleLogSets. */
-void purple_log_set_free(PurpleLogSet *set)
- g_return_if_fail(set != NULL);
- if (set->normalized_name != set->name)
- g_free(set->normalized_name);
- g_slice_free(PurpleLogSet, set);
-GList *purple_log_get_system_logs(PurpleAccount *account)
- for (n = loggers; n; n = n->next) {
- PurpleLogLogger *logger = n->data;
- if (!logger->list_syslog)
- logs = g_list_concat(logger->list_syslog(account), logs);
- return g_list_sort(logs, purple_log_compare);
-/****************************************************************************
- * LOG SUBSYSTEM ************************************************************
- ****************************************************************************/
-purple_log_get_handle(void)
-void purple_log_init(void)
- void *handle = purple_log_get_handle();
- purple_prefs_add_none("/purple/logging");
- purple_prefs_add_bool("/purple/logging/log_ims", TRUE);
- purple_prefs_add_bool("/purple/logging/log_chats", TRUE);
- purple_prefs_add_bool("/purple/logging/log_system", FALSE);
- purple_prefs_add_string("/purple/logging/format", "html");
- html_logger = purple_log_logger_new("html", _("HTML"), 11,
- purple_log_common_sizer,
- html_logger_total_size,
- html_logger_list_syslog,
- purple_log_common_deleter,
- purple_log_common_is_deletable);
- purple_log_logger_add(html_logger);
- txt_logger = purple_log_logger_new("txt", _("Plain text"), 11,
- purple_log_common_sizer,
- txt_logger_list_syslog,
- purple_log_common_deleter,
- purple_log_common_is_deletable);
- purple_log_logger_add(txt_logger);
- purple_signal_register(handle, "log-timestamp",
- purple_marshal_POINTER__POINTER_POINTER_BOOLEAN,
- purple_prefs_connect_callback(NULL, "/purple/logging/format",
- purple_prefs_trigger_callback("/purple/logging/format");
- logsize_users = g_hash_table_new_full((GHashFunc)_purple_logsize_user_hash,
- (GEqualFunc)_purple_logsize_user_equal,
- (GDestroyNotify)purple_key_value_pair_free, NULL);
- logsize_users_decayed = g_hash_table_new_full((GHashFunc)_purple_logsize_user_hash,
- (GEqualFunc)_purple_logsize_user_equal,
- (GDestroyNotify)purple_key_value_pair_free, NULL);
- purple_signals_unregister_by_instance(purple_log_get_handle());
- purple_log_logger_remove(html_logger);
- purple_log_logger_free(html_logger);
- purple_log_logger_remove(txt_logger);
- purple_log_logger_free(txt_logger);
- g_hash_table_destroy(logsize_users);
- g_hash_table_destroy(logsize_users_decayed);
-purple_log_copy(PurpleLog *log)
- g_return_val_if_fail(log != NULL, NULL);
- log_copy = g_new(PurpleLog, 1);
-purple_log_get_type(void)
- type = g_boxed_type_register_static("PurpleLog",
- (GBoxedCopyFunc)purple_log_copy,
- (GBoxedFreeFunc)g_free);
-/****************************************************************************
- * LOGGERS ******************************************************************
- ****************************************************************************/
-static char *log_get_timestamp(PurpleLog *log, GDateTime *when)
- dt = g_date_time_new_now_utc();
- show_date = (log->type == PURPLE_LOG_SYSTEM) || (g_date_time_difference(dt, when) > 20L * G_TIME_SPAN_MINUTE);
- date = purple_signal_emit_return_1(purple_log_get_handle(),
- dt = g_date_time_to_local(when);
- date = g_date_time_format(dt, _("%x %X"));
- date = g_date_time_format(dt, "%X");
-/* 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().
- * TODO: XXX: does it really works?
-convert_image_tags(const PurpleLog *log, const char *msg)
- GString *newmsg = NULL;
- while (purple_markup_find_tag("img", tmp, &start, &end, &attributes)) {
- newmsg = g_string_new("");
- /* copy any text before the img tag */
- g_string_append_len(newmsg, tmp, start - tmp);
- if ((idstr = g_datalist_get_data(&attributes, "id")) != NULL)
- gconstpointer image_data;
- const gchar *new_filename = NULL;
- size_t image_byte_count;
- image = purple_image_store_get(imgid);
- /* This should never happen. */
- /* This *does* happen for failed Direct-IMs -DAA */
- g_string_free(newmsg, TRUE);
- g_return_val_if_reached((char *)msg);
- image_data = purple_image_get_data(image);
- image_byte_count = purple_image_get_data_size(image);
- dir = purple_log_get_log_dir(log->type, log->name, log->account);
- new_filename = purple_image_generate_filename(image);
- 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, g_strerror(errno));
- /* Attempt to not leave half-written files around. */
- purple_debug_error("log", "Error deleting partial "
- "file %s: %s\n", path, g_strerror(errno));
- purple_debug_info("log", "Wrote image file: %s\n", path);
- purple_debug_error("log", "Unable to create file %s: %s\n",
- path, g_strerror(errno));
- /* Write the new image tag */
- g_string_append_printf(newmsg, "<img src=\"%s\">", new_filename);
- /* Continue from the end of the tag */
- /* No images were found to change. */
- /* 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;
- dir = purple_log_get_log_dir(log->type, log->name, log->account);
- g_mkdir_with_parents(dir, S_IRUSR | S_IWUSR | S_IXUSR);
- dt = g_date_time_to_local(log->time);
- tz = purple_escape_filename(g_date_time_get_timezone_abbreviation(dt));
- date = g_date_time_format(dt, "%Y-%m-%d.%H%M%S%z");
- filename = g_strdup_printf("%s%s%s", date, tz, ext ? ext : "");
- path = g_build_filename(dir, filename, NULL);
- log->logger_data = data = g_slice_new0(PurpleLogCommonLoggerData);
- data->file = g_fopen(path, "a");
- if (data->file == NULL)
- purple_debug_error("log", "Could not create log file %s", path);
- purple_conversation_write_system_message(log->conv,
- _("Logging of this conversation failed."),
-GList *purple_log_common_lister(PurpleLogType type, const char *name, PurpleAccount *account, const char *ext, PurpleLogLogger *logger)
- path = purple_log_get_log_dir(type, name, account);
- if (!(dir = g_dir_open(path, 0, NULL)))
- while ((filename = g_dir_read_name(dir)))
- if (g_str_has_suffix(filename, ext) &&
- strlen(filename) >= (17 + strlen(ext))) {
- PurpleLogCommonLoggerData *data;
- GDateTime *stamp = purple_str_to_date_time(purple_unescape_filename(filename), FALSE);
- log = purple_log_new(type, name, account, NULL, stamp);
- log->logger_data = data = g_slice_new0(PurpleLogCommonLoggerData);
- data->path = g_build_filename(path, filename, NULL);
- list = g_list_prepend(list, log);
- g_date_time_unref(stamp);
-int purple_log_common_total_sizer(PurpleLogType type, const char *name, PurpleAccount *account, const char *ext)
- path = purple_log_get_log_dir(type, name, account);
- if (!(dir = g_dir_open(path, 0, NULL)))
- while ((filename = g_dir_read_name(dir)))
- if (g_str_has_suffix(filename, ext) &&
- strlen(filename) >= (17 + strlen(ext))) {
- char *tmp = g_build_filename(path, filename, NULL);
- purple_debug_error("log", "Error stating log file: %s\n", tmp);
-int purple_log_common_sizer(PurpleLog *log)
- PurpleLogCommonLoggerData *data = log->logger_data;
- g_return_val_if_fail(data != NULL, 0);
- if (!data->path || g_stat(data->path, &st))
-/* This will build log sets for all loggers that use the common logger
- * functions because they use the same directory structure. */
-static void log_get_log_sets_common(GHashTable *sets)
- gchar *log_path = g_build_filename(purple_data_dir(), "logs", NULL);
- GDir *log_dir = g_dir_open(log_path, 0, NULL);
- while ((protocol = g_dir_read_name(log_dir)) != NULL) {
- gchar *protocol_path = g_build_filename(log_path, protocol, NULL);
- gchar *protocol_unescaped;
- GList *accounts = NULL;
- if ((protocol_dir = g_dir_open(protocol_path, 0, NULL)) == NULL) {
- /* Using g_strdup() to cover the one-in-a-million chance that a
- * protocol's list_icon function uses purple_unescape_filename(). */
- protocol_unescaped = g_strdup(purple_unescape_filename(protocol));
- /* Find all the accounts for protocol. */
- for (account_iter = purple_accounts_get_all() ; account_iter != NULL ; account_iter = account_iter->next) {
- PurpleProtocol *protocol;
- protocol = purple_account_get_protocol((PurpleAccount *)account_iter->data);
- if (purple_strequal(protocol_unescaped, purple_protocol_get_list_icon(protocol, (PurpleAccount *)account_iter->data, NULL)))
- accounts = g_list_prepend(accounts, account_iter->data);
- g_free(protocol_unescaped);
- while ((username = g_dir_read_name(protocol_dir)) != NULL) {
- gchar *username_path = g_build_filename(protocol_path, username, NULL);
- const gchar *username_unescaped;
- PurpleAccount *account = NULL;
- if ((username_dir = g_dir_open(username_path, 0, NULL)) == NULL) {
- /* Find the account for username in the list of accounts for protocol. */
- username_unescaped = purple_unescape_filename(username);
- for (account_iter = g_list_first(accounts) ; account_iter != NULL ; account_iter = account_iter->next) {
- if (purple_strequal(purple_account_get_username((PurpleAccount *)account_iter->data), username_unescaped)) {
- account = account_iter->data;
- /* Don't worry about the cast, name will point to dynamically allocated memory shortly. */
- while ((name = (gchar *)g_dir_read_name(username_dir)) != NULL) {
- /* IMPORTANT: Always initialize all members of PurpleLogSet */
- set = g_slice_new(PurpleLogSet);
- /* Unescape the filename. */
- name = g_strdup(purple_unescape_filename(name));
- /* Get the (possibly new) length of name. */
- set->type = PURPLE_LOG_IM;
- set->account = account;
- /* set->buddy is always set below */
- set->normalized_name = g_strdup(purple_normalize(account, name));
- /* Check for .chat or .system at the end of the name to determine the type. */
- gchar *tmp = &name[len - 7];
- if (purple_strequal(tmp, ".system")) {
- set->type = PURPLE_LOG_SYSTEM;
- gchar *tmp = &name[len - 5];
- if (purple_strequal(tmp, ".chat")) {
- set->type = PURPLE_LOG_CHAT;
- /* Determine if this (account, name) combination exists as a buddy. */
- if (account != NULL && *name != '\0')
- set->buddy = (purple_blist_find_buddy(account, name) != NULL);
- log_add_log_set_to_hash(sets, set);
- g_dir_close(username_dir);
- g_dir_close(protocol_dir);
-gboolean purple_log_common_deleter(PurpleLog *log)
- PurpleLogCommonLoggerData *data;
- g_return_val_if_fail(log != NULL, FALSE);
- data = log->logger_data;
- if (data->path == NULL)
- ret = g_unlink(data->path);
- purple_debug_error("log", "Failed to delete: %s - %s\n", data->path, g_strerror(errno));
- /* I'm not sure that g_unlink() will ever return
- * something other than 0 or -1. -- rlaager */
- purple_debug_error("log", "Failed to delete: %s\n", data->path);
-gboolean purple_log_common_is_deletable(PurpleLog *log)
- PurpleLogCommonLoggerData *data;
- g_return_val_if_fail(log != NULL, FALSE);
- data = log->logger_data;
- if (data->path == NULL)
- dirname = g_path_get_dirname(data->path);
- if (g_access(dirname, W_OK) == 0)
- purple_debug_info("log", "access(%s) failed: %s\n", dirname, g_strerror(errno));
- /* Unless and until someone writes equivalent win32 code,
- * we'll assume the file is deletable. */
-static char *process_txt_log(char *txt, char *to_free)
- /* The to_free argument allows us to save a
- * g_strdup() in some cases. */
- /* g_markup_escape_text requires valid UTF-8 */
- tmp = g_utf8_make_valid(txt, -1);
- tmp = g_markup_escape_text(txt, -1);
- txt = purple_markup_linkify(tmp);
-/****************************
- ** HTML LOGGER *************
- ****************************/
-static gsize html_logger_write(PurpleLog *log, PurpleMessageFlags type,
- const char *from, GDateTime *time, const char *message)
- char *image_corrected_msg;
- PurpleProtocol *protocol = purple_account_get_protocol(log->account);
- PurpleLogCommonLoggerData *data = log->logger_data;
- const char *proto = purple_protocol_get_list_icon(protocol, log->account, NULL);
- purple_log_common_writer(log, ".html");
- data = log->logger_data;
- /* if we can't write to the file, give up before we hurt ourselves */
- if (!data || !data->file) {
- dt = g_date_time_to_local(log->time);
- date = g_date_time_format(dt, "%c");
- written += fprintf(data->file, "<html><head>");
- written += fprintf(data->file, "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");
- written += fprintf(data->file, "<title>");
- if (log->type == PURPLE_LOG_SYSTEM)
- header = g_strdup_printf("System log for account %s (%s) connected at %s",
- purple_account_get_username(log->account), proto, date);
- header = g_strdup_printf("Conversation with %s at %s on %s (%s)",
- log->name, date, purple_account_get_username(log->account), proto);
- written += fprintf(data->file, "%s", header);
- written += fprintf(data->file, "</title></head><body>");
- written += fprintf(data->file, "<h3>%s</h3>\n", header);
- /* if we can't write to the file, give up before we hurt ourselves */
- escaped_from = g_markup_escape_text(from != NULL ? from : "<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){
- written += fprintf(data->file, "---- %s @ %s ----<br/>\n", msg_fixed, date);
- if (type & PURPLE_MESSAGE_SYSTEM)
- written += fprintf(data->file, "<font size=\"2\">(%s)</font><b> %s</b><br/>\n", date, msg_fixed);
- else if (type & PURPLE_MESSAGE_RAW)
- written += fprintf(data->file, "<font size=\"2\">(%s)</font> %s<br/>\n", date, msg_fixed);
- else if (type & PURPLE_MESSAGE_ERROR)
- written += fprintf(data->file, "<font color=\"#FF0000\"><font size=\"2\">(%s)</font><b> %s</b></font><br/>\n", date, msg_fixed);
- else if (type & PURPLE_MESSAGE_AUTO_RESP) {
- if (type & PURPLE_MESSAGE_SEND)
- written += fprintf(data->file, _("<font color=\"#16569E\"><font size=\"2\">(%s)</font> <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, escaped_from, msg_fixed);
- else if (type & PURPLE_MESSAGE_RECV)
- written += fprintf(data->file, _("<font color=\"#A82F2F\"><font size=\"2\">(%s)</font> <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, escaped_from, msg_fixed);
- } else if (type & PURPLE_MESSAGE_RECV) {
- if(purple_message_meify(msg_fixed, -1))
- written += fprintf(data->file, "<font color=\"#062585\"><font size=\"2\">(%s)</font> <b>***%s</b></font> %s<br/>\n",
- date, escaped_from, msg_fixed);
- written += fprintf(data->file, "<font color=\"#A82F2F\"><font size=\"2\">(%s)</font> <b>%s:</b></font> %s<br/>\n",
- date, escaped_from, msg_fixed);
- } else if (type & PURPLE_MESSAGE_SEND) {
- if(purple_message_meify(msg_fixed, -1))
- written += fprintf(data->file, "<font color=\"#062585\"><font size=\"2\">(%s)</font> <b>***%s</b></font> %s<br/>\n",
- date, escaped_from, msg_fixed);
- written += fprintf(data->file, "<font color=\"#16569E\"><font size=\"2\">(%s)</font> <b>%s:</b></font> %s<br/>\n",
- date, escaped_from, msg_fixed);
- purple_debug_error("log", "Unhandled message type.\n");
- written += fprintf(data->file, "<font size=\"2\">(%s)</font><b> %s:</b></font> %s<br/>\n",
- date, escaped_from, msg_fixed);
-static void html_logger_finalize(PurpleLog *log)
- PurpleLogCommonLoggerData *data = log->logger_data;
- fprintf(data->file, "</body></html>\n");
- g_slice_free(PurpleLogCommonLoggerData, data);
-static GList *html_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account)
- return purple_log_common_lister(type, sn, account, ".html", html_logger);
-static GList *html_logger_list_syslog(PurpleAccount *account)
- return purple_log_common_lister(PURPLE_LOG_SYSTEM, ".system", account, ".html", html_logger);
-static char *html_logger_read(PurpleLog *log, PurpleLogReadFlags *flags)
- PurpleLogCommonLoggerData *data = log->logger_data;
- *flags = PURPLE_LOG_READ_NO_NEWLINE;
- if (!data || !data->path)
- return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>"));
- if (g_file_get_contents(data->path, &read, NULL, NULL)) {
- char *minus_header = strchr(read, '\n');
- minus_header = g_strdup(minus_header + 1);
- return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path);
-static int html_logger_total_size(PurpleLogType type, const char *name, PurpleAccount *account)
- return purple_log_common_total_sizer(type, name, account, ".html");
-/****************************
- ** PLAIN TEXT LOGGER *******
- ****************************/
-static gsize txt_logger_write(PurpleLog *log, PurpleMessageFlags type,
- const char *from, GDateTime *time, const char *message)
- PurpleProtocol *protocol = purple_account_get_protocol(log->account);
- PurpleLogCommonLoggerData *data = log->logger_data;
- /* This log is new. We could use the loggers 'new' function, but
- * creating a new file there would result in empty files in the case
- * that you open a convo with someone, but don't say anything.
- const char *proto = purple_protocol_get_list_icon(protocol, log->account, NULL);
- purple_log_common_writer(log, ".txt");
- data = log->logger_data;
- /* if we can't write to the file, give up before we hurt ourselves */
- if(!data || !data->file)
- dt = g_date_time_to_local(log->time);
- date = g_date_time_format(dt, "%c");
- if (log->type == PURPLE_LOG_SYSTEM)
- written += fprintf(data->file, "System log for account %s (%s) connected at %s\n",
- purple_account_get_username(log->account), proto,
- written += fprintf(data->file, "Conversation with %s at %s on %s (%s)\n",
- purple_account_get_username(log->account), proto);
- /* if we can't write to the file, give up before we hurt ourselves */
- stripped = purple_markup_strip_html(message);
- date = log_get_timestamp(log, time);
- if(log->type == PURPLE_LOG_SYSTEM){
- written += fprintf(data->file, "---- %s @ %s ----\n", stripped, date);
- if (type & PURPLE_MESSAGE_SEND ||
- type & PURPLE_MESSAGE_RECV) {
- if (type & PURPLE_MESSAGE_AUTO_RESP) {
- written += fprintf(data->file, _("(%s) %s <AUTO-REPLY>: %s\n"), date,
- if(purple_message_meify(stripped, -1))
- written += fprintf(data->file, "(%s) ***%s %s\n", date, from,
- written += fprintf(data->file, "(%s) %s: %s\n", date, from,
- } else if (type & PURPLE_MESSAGE_SYSTEM ||
- type & PURPLE_MESSAGE_ERROR ||
- type & PURPLE_MESSAGE_RAW)
- written += fprintf(data->file, "(%s) %s\n", date, stripped);
- else if (type & PURPLE_MESSAGE_NO_LOG) {
- /* This shouldn't happen */
- written += fprintf(data->file, "(%s) %s%s %s\n", date, from ? from : "",
- from ? ":" : "", stripped);
-static void txt_logger_finalize(PurpleLog *log)
- PurpleLogCommonLoggerData *data = log->logger_data;
- g_slice_free(PurpleLogCommonLoggerData, data);
-static GList *txt_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account)
- return purple_log_common_lister(type, sn, account, ".txt", txt_logger);
-static GList *txt_logger_list_syslog(PurpleAccount *account)
- return purple_log_common_lister(PURPLE_LOG_SYSTEM, ".system", account, ".txt", txt_logger);
-static char *txt_logger_read(PurpleLog *log, PurpleLogReadFlags *flags)
- char *read, *minus_header;
- PurpleLogCommonLoggerData *data = log->logger_data;
- if (!data || !data->path)
- return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>"));
- if (g_file_get_contents(data->path, &read, NULL, NULL)) {
- minus_header = strchr(read, '\n');
- return process_txt_log(minus_header + 1, read);
- return process_txt_log(read, NULL);
- return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path);
-static int txt_logger_total_size(PurpleLogType type, const char *name, PurpleAccount *account)
- return purple_log_common_total_sizer(type, name, account, ".txt");
--- a/libpurple/log.h Fri Oct 22 03:33:32 2021 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,665 +0,0 @@
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
- * @section_id: libpurple-log
- * @short_description: <filename>log.h</filename>
- * @see_also: <link linkend="chapter-signals-log">Log signals</link>
-#define PURPLE_TYPE_LOG (purple_log_get_type())
-/********************************************************
- * DATA STRUCTURES **************************************
- ********************************************************/
-typedef struct _PurpleLog PurpleLog;
-typedef struct _PurpleLogLogger PurpleLogLogger;
-typedef struct _PurpleLogCommonLoggerData PurpleLogCommonLoggerData;
-typedef struct _PurpleLogSet PurpleLogSet;
- * @PURPLE_LOG_IM: Indicates an IM conversation.
- * @PURPLE_LOG_CHAT: Indicates a chat.
- * @PURPLE_LOG_SYSTEM: Indicates a server log.
- * The individual types of logs.
- * @PURPLE_LOG_READ_NO_NEWLINE: Defines that newlines should be ignored.
- * Flags that should be used when reading a log.
- PURPLE_LOG_READ_NO_NEWLINE = 1
-#include "conversations.h"
-typedef void (*PurpleLogSetCallback) (GHashTable *sets, PurpleLogSet *set);
- * @name: The logger's name
- * @id: An identifier to refer to this logger
- * @create: This gets called when the log is first created. I don't think
- * this is actually needed.
- * @write: This is used to write to the log file
- * @finalize: Called when the log is destroyed
- * @list: This function returns a sorted #GList of available PurpleLogs
- * @read: Given one of the logs returned by the logger's list function,
- * this returns the contents of the log
- * @size: Given one of the logs returned by the logger's list function,
- * this returns the size of the log in bytes
- * @total_size: Returns the total size of all the logs. If this is undefined a
- * default implementation is used
- * @list_syslog: This function returns a sorted #GList of available system
- * @get_log_sets: Adds #PurpleLogSet's to a #GHashTable. By passing the data in
- * the #PurpleLogSet's to list, the caller can get every
- * available #PurpleLog from the logger. Loggers using
- * purple_log_common_writer() (or otherwise storing their logs in
- * the same directory structure as the stock loggers) do not
- * need to implement this function.
- * <sbr/>Loggers which implement this function must create a
- * #PurpleLogSet, then call @cb with @sets and the newly created
- * @remove: Attempts to delete the specified log, indicating success or
- * @is_deletable: Tests whether a log is deletable
- * This struct gets filled out and is included in the PurpleLog. It contains
- * everything needed to write and read from logs.
-struct _PurpleLogLogger {
- void (*create)(PurpleLog *log);
- gsize (*write)(PurpleLog *log,
- PurpleMessageFlags type,
- void (*finalize)(PurpleLog *log);
- GList *(*list)(PurpleLogType type, const char *name, PurpleAccount *account);
- char *(*read)(PurpleLog *log, PurpleLogReadFlags *flags);
- int (*size)(PurpleLog *log);
- int (*total_size)(PurpleLogType type, const char *name, PurpleAccount *account);
- GList *(*list_syslog)(PurpleAccount *account);
- void (*get_log_sets)(PurpleLogSetCallback cb, GHashTable *sets);
- gboolean (*remove)(PurpleLog *log);
- gboolean (*is_deletable)(PurpleLog *log);
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
- * @type: The type of log this is
- * @name: The name of this log
- * @account: The account this log is taking place on
- * @conv: The conversation being logged
- * @time: The time this conversation started, converted to the local
- * @logger: The logging mechanism this log is to use
- * @logger_data: Data used by the log logger
- * A log. Not the wooden type.
- PurpleAccount *account;
- PurpleConversation *conv;
- PurpleLogLogger *logger;
- /* IMPORTANT: Some code in log.c allocates these without zeroing them.
- * IMPORTANT: Update that code if you add members here. */
- * PurpleLogCommonLoggerData:
- * @path: The path to the file.
- * @file: The pointer to the open file handle.
- * @extra_data: User supplied data.
- * A common logger_data struct containing a file handle and path, as well
- * as a pointer to something else for additional data.
-struct _PurpleLogCommonLoggerData {
- * @type: The type of logs available
- * @name: The name of the logs available
- * @account: The account the available logs took place on. This will be
- * %NULL if the account no longer exists. (Depending on a
- * logger's implementation of list, it may not be possible to
- * @buddy: Is this (account, name) a buddy on the buddy list?
- * @normalized_name: The normalized version of @name. It must be set, and may
- * be set to the same pointer value as @name.
- * Describes available logs.
- * By passing the elements of this struct to purple_log_get_logs(), the caller
- * can get all available PurpleLogs.
- PurpleAccount *account;
- /* IMPORTANT: Some code in log.c allocates these without zeroing them.
- * IMPORTANT: Update that code if you add members here. */
-/***************************************/
-/***************************************/
- * Returns: The #GType for the #PurpleLog boxed structure.
-/* TODO Boxing of PurpleLog is a temporary solution to having a GType for
- * logs. This should rather be a GObject instead of a GBoxed.
-GType purple_log_get_type(void);
- * @type: The type of log this is.
- * @name: The name of this conversation (buddy name, chat name,
- * @account: The account the conversation is occurring on
- * @conv: The conversation being logged
- * @time: The time this conversation started
-PurpleLog *purple_log_new(PurpleLogType type, const char *name, PurpleAccount *account,
- PurpleConversation *conv, GDateTime *time);
- * @log: The log to destroy
-void purple_log_free(PurpleLog *log);
- * @log: The log to write to
- * @type: The type of message being logged
- * @from: Whom this message is coming from, or %NULL for
- * @time: A timestamp in UNIX time
- * @message: The message to log
- * Writes to a log file. Assumes you have checked preferences already.
-void purple_log_write(PurpleLog *log,
- PurpleMessageFlags type,
- * @log: The log to read from
- * @flags: The returned logging flags.
- * Returns: The contents of this log in Purple Markup.
-char *purple_log_read(PurpleLog *log, PurpleLogReadFlags *flags);
- * @type: The type of the log
- * @name: The name of the log
- * @account: The account
- * Returns a list of all available logs
- * Returns: (element-type PurpleLog) (transfer full): A sorted list of logs.
-GList *purple_log_get_logs(PurpleLogType type, const char *name, PurpleAccount *account);
- * purple_log_get_log_sets:
- * Returns a GHashTable of PurpleLogSets.
- * A "log set" here means the information necessary to gather the
- * PurpleLogs for a given buddy/chat. This information would be passed
- * to purple_log_list to get a list of PurpleLogs.
- * The primary use of this function is to get a list of everyone the
- * user has ever talked to (assuming he or she uses logging).
- * The GHashTable that's returned will free all log sets in it when
- * destroyed. If a PurpleLogSet is removed from the GHashTable, it
- * must be freed with purple_log_set_free().
- * Returns: (element-type PurpleLogSet PurpleLogSet) (transfer full): All
- * available unique log sets.
-GHashTable *purple_log_get_log_sets(void);
- * purple_log_get_system_logs:
- * @account: The account
- * Returns a list of all available system logs
- * Returns: (element-type PurpleLog) (transfer full): A sorted list of logs.
-GList *purple_log_get_system_logs(PurpleAccount *account);
- * Returns the size of a log
- * Returns: The size of the log, in bytes
-int purple_log_get_size(PurpleLog *log);
- * purple_log_get_total_size:
- * @type: The type of the log
- * @name: The name of the log
- * @account: The account
- * Returns the size, in bytes, of all available logs in this conversation
- * Returns: The size in bytes
-int purple_log_get_total_size(PurpleLogType type, const char *name, PurpleAccount *account);
- * purple_log_get_activity_score:
- * @type: The type of the log
- * @name: The name of the log
- * @account: The account
- * Returns the activity score of a log, based on total size in bytes,
- * which is then decayed based on age
- * Returns: The activity score
-int purple_log_get_activity_score(PurpleLogType type, const char *name, PurpleAccount *account);
- * purple_log_is_deletable:
- * Tests whether a log is deletable
- * A return value of %FALSE indicates that purple_log_delete() will fail on this
- * log, unless something changes between the two calls. A return value of %TRUE,
- * however, does not guarantee the log can be deleted.
- * Returns: A boolean indicating if the log is deletable
-gboolean purple_log_is_deletable(PurpleLog *log);
- * Returns: A boolean indicating success or failure
-gboolean purple_log_delete(PurpleLog *log);
- * purple_log_get_log_dir:
- * @type: The type of the log.
- * @name: The name of the log.
- * @account: The account.
- * Returns the default logger directory Purple uses for a given account
- * and username. This would be where Purple stores logs created by
- * the built-in text or HTML loggers.
- * Returns: The default logger directory for Purple.
-char *purple_log_get_log_dir(PurpleLogType type, const char *name, PurpleAccount *account);
- * @z: Another PurpleLog
- * Implements GCompareFunc for PurpleLogs
- * Returns: A value as specified by GCompareFunc
-gint purple_log_compare(gconstpointer y, gconstpointer z);
- * purple_log_set_compare:
- * @z: Another PurpleLogSet
- * Implements GCompareFunc for PurpleLogSets
- * Returns: A value as specified by GCompareFunc
-gint purple_log_set_compare(gconstpointer y, gconstpointer z);
- * @set: The log set to destroy
-void purple_log_set_free(PurpleLogSet *set);
-/******************************************/
-/* Common Logger Functions */
-/******************************************/
- * purple_log_common_writer:
- * @log: The log to write to.
- * @ext: The file extension to give to this log file.
- * Opens a new log file in the standard Purple log location
- * with the given file extension, named for the current time,
- * for writing. If a log file is already open, the existing
- * file handle is retained. The log's logger_data value is
- * set to a PurpleLogCommonLoggerData struct containing the log
- * file handle and log path.
- * This function is intended to be used as a "common"
- * implementation of a logger's <literal>write</literal> function.
- * It should only be passed to purple_log_logger_new() and never
-void purple_log_common_writer(PurpleLog *log, const char *ext);
- * purple_log_common_lister:
- * @type: The type of the logs being listed.
- * @name: The name of the log.
- * @account: The account of the log.
- * @ext: The file extension this log format uses.
- * @logger: A reference to the logger struct for this log.
- * Returns a sorted list of logs of the requested type.
- * This function should only be used with logs that are written
- * with purple_log_common_writer(). It's intended to be used as
- * a "common" implementation of a logger's <literal>list</literal> function.
- * It should only be passed to purple_log_logger_new() and never
- * Returns: (element-type PurpleLog) (transfer full): A sorted list of logs
- * matching the parameters.
-GList *purple_log_common_lister(PurpleLogType type, const char *name,
- PurpleAccount *account, const char *ext,
- PurpleLogLogger *logger);
- * purple_log_common_total_sizer:
- * @type: The type of the logs being sized.
- * @name: The name of the logs to size
- * (e.g. the username or chat name).
- * @account: The account of the log.
- * @ext: The file extension this log format uses.
- * Returns the total size of all the logs for a given user, with
- * This function should only be used with logs that are written
- * with purple_log_common_writer(). It's intended to be used as
- * a "common" implementation of a logger's <literal>total_size</literal>
- * function. It should only be passed to purple_log_logger_new() and never
- * Returns: The size of all the logs with the specified extension
- * for the specified user.
-int purple_log_common_total_sizer(PurpleLogType type, const char *name,
- PurpleAccount *account, const char *ext);
- * purple_log_common_sizer:
- * @log: The PurpleLog to size.
- * Returns the size of a given PurpleLog.
- * This function should only be used with logs that are written
- * with purple_log_common_writer(). It's intended to be used as
- * a "common" implementation of a logger's <literal>size</literal> function.
- * It should only be passed to purple_log_logger_new() and never
- * Returns: An integer indicating the size of the log in bytes.
-int purple_log_common_sizer(PurpleLog *log);
- * purple_log_common_deleter:
- * @log: The PurpleLog to delete.
- * This function should only be used with logs that are written
- * with purple_log_common_writer(). It's intended to be used as
- * a "common" implementation of a logger's <literal>delete</literal> function.
- * It should only be passed to purple_log_logger_new() and never
- * Returns: A boolean indicating success or failure.
-gboolean purple_log_common_deleter(PurpleLog *log);
- * purple_log_common_is_deletable:
- * @log: The PurpleLog to check.
- * Checks to see if a log is deletable
- * This function should only be used with logs that are written
- * with purple_log_common_writer(). It's intended to be used as
- * a "common" implementation of a logger's <literal>is_deletable</literal>
- * function. It should only be passed to purple_log_logger_new() and never
- * Returns: A boolean indicating if the log is deletable.
-gboolean purple_log_common_is_deletable(PurpleLog *log);
-/******************************************/
-/******************************************/
- * purple_log_logger_new:
- * @id: The logger's id.
- * @name: The logger's name.
- * @functions: The number of functions being passed. The following
- * functions are currently available (in order):
- * <literal>create</literal>, <literal>write</literal>,
- * <literal>finalize</literal>, <literal>list</literal>,
- * <literal>read</literal>, <literal>size</literal>,
- * <literal>total_size</literal>, <literal>list_syslog</literal>,
- * <literal>get_log_sets</literal>, <literal>remove</literal>,
- * <literal>is_deletable</literal>.
- * For details on these functions, see PurpleLogLogger.
- * Functions may not be skipped. For example, passing
- * <literal>create</literal> and <literal>write</literal> is
- * acceptable (for a total of two functions). Passing
- * <literal>create</literal> and <literal>finalize</literal>,
- * however, is not. To accomplish that, the caller must pass
- * <literal>create</literal>, %NULL (a placeholder for
- * <literal>write</literal>), and <literal>finalize</literal>
- * (for a total of 3 functions).
- * @...: The functions used to log.
- * Returns: (transfer full): The new logger.
-PurpleLogLogger *purple_log_logger_new(const char *id, const char *name, int functions, ...);
- * purple_log_logger_free:
- * @logger: The logger to free
-void purple_log_logger_free(PurpleLogLogger *logger);
- * purple_log_logger_add:
- * @logger: The new logger to add
-void purple_log_logger_add (PurpleLogLogger *logger);
- * purple_log_logger_remove:
- * @logger: The logger to remove
-void purple_log_logger_remove (PurpleLogLogger *logger);
- * purple_log_logger_set:
- * @logger: The logger to set
- * Sets the current logger
-void purple_log_logger_set (PurpleLogLogger *logger);
- * purple_log_logger_get:
- * Returns the current logger
- * Returns: (transfer none): The current logger.
-PurpleLogLogger *purple_log_logger_get(void);
- * purple_log_logger_get_options:
- * Returns a GList containing the IDs and names of the registered
- * Returns: (element-type utf8) (transfer container): The list of IDs and names.
-GList *purple_log_logger_get_options(void);
-/**************************************************************************/
-/**************************************************************************/
- * Initializes the log subsystem.
-void purple_log_init(void);
- * purple_log_get_handle:
- * Returns the log subsystem handle.
- * Returns: The log subsystem handle.
-void *purple_log_get_handle(void);
- * Uninitializes the log subsystem.
-void purple_log_uninit(void);
-#endif /* PURPLE_LOG_H */
--- a/libpurple/meson.build Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/meson.build Sat Oct 23 01:06:57 2021 -0500
@@ -20,7 +20,6 @@
@@ -121,7 +120,6 @@
--- a/libpurple/protocol.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/protocol.c Sat Oct 23 01:06:57 2021 -0500
@@ -22,6 +22,7 @@
--- a/libpurple/protocols.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/protocols.c Sat Oct 23 01:06:57 2021 -0500
@@ -37,6 +37,7 @@
#include "purpleprotocolmedia.h"
#include "purpleprotocolserver.h"
/**************************************************************************
--- a/libpurple/purpleaccountpresence.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/purpleaccountpresence.c Sat Oct 23 01:06:57 2021 -0500
@@ -64,32 +64,6 @@
time_t idle_time = purple_presence_get_idle_time(presence);
time_t current_time = time(NULL);
- if(purple_prefs_get_bool("/purple/logging/log_system")) {
- PurpleLog *log = purple_account_get_log(account_presence->account,
- tmp = g_strdup_printf(_("+++ %s became idle"), purple_account_get_username(account_presence->account));
- dt = g_date_time_new_from_unix_local(idle_time);
- tmp = g_strdup_printf(_("+++ %s became unidle"), purple_account_get_username(account_presence->account));
- dt = g_date_time_new_now_utc();
- msg = g_markup_escape_text(tmp, -1);
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_account_get_username(account_presence->account),
gc = purple_account_get_connection(account_presence->account);
if(PURPLE_CONNECTION_IS_CONNECTED(gc)) {
--- a/libpurple/purplebuddypresence.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/purplebuddypresence.c Sat Oct 23 01:06:57 2021 -0500
@@ -135,52 +135,8 @@
PurpleBuddy *buddy = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(presence));
GDateTime *current_time = g_date_time_new_now_utc();
- PurpleAccount *account = purple_buddy_get_account(buddy);
gboolean idle = purple_presence_is_idle(presence);
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- PurpleLog *log = purple_account_get_log(account, FALSE);
- tmp = g_strdup_printf(_("%s became idle"),
- purple_buddy_get_alias(buddy));
- tmp2 = g_markup_escape_text(tmp, -1);
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_buddy_get_alias(buddy),
- else if (old_idle && !idle)
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- PurpleLog *log = purple_account_get_log(account, FALSE);
- tmp = g_strdup_printf(_("%s became unidle"),
- purple_buddy_get_alias(buddy));
- tmp2 = g_markup_escape_text(tmp, -1);
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM,
- purple_buddy_get_alias(buddy),
purple_signal_emit(purple_blist_get_handle(), "buddy-idle-changed", buddy,
--- a/libpurple/purplechatconversation.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/purplechatconversation.c Sat Oct 23 01:06:57 2021 -0500
@@ -28,6 +28,7 @@
#include "purplechatconversation.h"
#include "purpleprivate.h"
GList *ignored; /* Ignored users. */
@@ -203,10 +204,6 @@
purple_chat_conversation_set_nick(chat, username);
- if(purple_prefs_get_bool("/purple/logging/log_chats")) {
- purple_conversation_set_logging(PURPLE_CONVERSATION(chat), TRUE);
--- a/libpurple/purplechatuser.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/purplechatuser.c Sat Oct 23 01:06:57 2021 -0500
@@ -21,6 +21,8 @@
#include "purplechatuser.h"
+#include "conversations.h" --- a/libpurple/purpleconversation.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/purpleconversation.c Sat Oct 23 01:06:57 2021 -0500
@@ -26,6 +26,7 @@
+#include "conversations.h" @@ -46,10 +47,6 @@
char *name; /* The name of the conversation. */
char *title; /* The window title. */
- gboolean logging; /* The status of logging. */
- GList *logs; /* This conversation's logs */
PurpleConversationUiOps *ui_ops; /* UI-specific operations. */
PurpleConnectionFlags features; /* The supported features */
@@ -61,7 +58,6 @@
@@ -235,9 +231,6 @@
priv->title = g_value_dup_string(value);
- purple_conversation_set_logging(conv, g_value_get_boolean(value));
purple_conversation_set_features(conv, g_value_get_flags(value));
@@ -263,9 +256,6 @@
g_value_set_string(value, purple_conversation_get_title(conv));
- g_value_set_boolean(value, purple_conversation_is_logging(conv));
g_value_set_flags(value, purple_conversation_get_features(conv));
@@ -345,7 +335,6 @@
purple_signal_emit(purple_conversations_get_handle(),
"deleting-conversation", conv);
- purple_conversation_close_logs(conv);
purple_conversation_clear_message_history(conv);
if(ops != NULL && ops->destroy_conversation != NULL) {
@@ -388,12 +377,6 @@
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- properties[PROP_LOGGING] = g_param_spec_boolean(
- "logging", "Logging status",
- "Whether logging is enabled or not.",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_FEATURES] = g_param_spec_flags(
"features", "Connection features",
"The connection features of the conversation.",
@@ -606,58 +589,6 @@
-purple_conversation_set_logging(PurpleConversation *conv, gboolean log) {
- PurpleConversationPrivate *priv = NULL;
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- priv = purple_conversation_get_instance_private(conv);
- if(priv->logging != log) {
- if(log && priv->logs == NULL) {
- dt = g_date_time_new_now_local();
- log = purple_log_new(PURPLE_IS_CHAT_CONVERSATION(conv)
- priv->name, priv->account, conv,
- priv->logs = g_list_append(NULL, log);
- g_object_notify_by_pspec(G_OBJECT(conv), properties[PROP_LOGGING]);
- purple_conversation_update(conv, PURPLE_CONVERSATION_UPDATE_LOGGING);
-purple_conversation_is_logging(PurpleConversation *conv) {
- PurpleConversationPrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), FALSE);
- priv = purple_conversation_get_instance_private(conv);
-purple_conversation_close_logs(PurpleConversation *conv) {
- PurpleConversationPrivate *priv = NULL;
- g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
- priv = purple_conversation_get_instance_private(conv);
- g_list_free_full(priv->logs, (GDestroyNotify)purple_log_free);
_purple_conversation_write_common(PurpleConversation *conv,
@@ -746,11 +677,8 @@
- if(!(purple_message_get_flags(pmsg) & PURPLE_MESSAGE_NO_LOG) &&
- purple_conversation_is_logging(conv))
+ if(!(purple_message_get_flags(pmsg) & PURPLE_MESSAGE_NO_LOG))
PurpleHistoryManager *manager = NULL;
@@ -763,20 +691,6 @@
- /* The following should be deleted when the history api is stable. */
- dt = g_date_time_ref(purple_message_get_timestamp(pmsg));
- purple_log_write((PurpleLog *)log->data,
- purple_message_get_flags(pmsg),
- purple_message_get_author_alias(pmsg),
- purple_message_get_contents(pmsg));
--- a/libpurple/purpleconversation.h Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/purpleconversation.h Sat Oct 23 01:06:57 2021 -0500
@@ -139,7 +139,6 @@
#include <purpleconversationuiops.h>
@@ -263,37 +262,6 @@
const char *purple_conversation_get_name(PurpleConversation *conv);
- * purple_conversation_set_logging:
- * @conv: The conversation.
- * @log: %TRUE if logging should be enabled, or %FALSE otherwise.
- * Enables or disables logging for this conversation.
-void purple_conversation_set_logging(PurpleConversation *conv, gboolean log);
- * purple_conversation_is_logging:
- * @conv: The conversation.
- * Returns whether or not logging is enabled for this conversation.
- * Returns: %TRUE if logging is enabled, or %FALSE otherwise.
-gboolean purple_conversation_is_logging(PurpleConversation *conv);
- * purple_conversation_close_logs:
- * @conv: The conversation.
- * Closes any open logs for this conversation.
- * Note that new logs will be opened as necessary (e.g. upon receipt of a
- * message, if the conversation has logging enabled. To disable logging for
- * the remainder of the conversation, use purple_conversation_set_logging().
-void purple_conversation_close_logs(PurpleConversation *conv);
* purple_conversation_write_message:
* @conv: The conversation.
* @msg: The message to write.
--- a/libpurple/purpleimconversation.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/purpleimconversation.c Sat Oct 23 01:06:57 2021 -0500
@@ -22,6 +22,7 @@
#include <libpurple/purpleimconversation.h>
#include <libpurple/debug.h>
+#include <libpurple/conversations.h> #include <libpurple/purpleconversationmanager.h>
#include <libpurple/purpleenums.h>
#include <libpurple/purpleprivate.h>
@@ -178,10 +179,6 @@
purple_buddy_icon_unref(icon);
- if(purple_prefs_get_bool("/purple/logging/log_ims")) {
- purple_conversation_set_logging(PURPLE_CONVERSATION(im), TRUE);
--- a/libpurple/savedstatuses.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/savedstatuses.c Sat Oct 23 01:06:57 2021 -0500
@@ -23,6 +23,7 @@
--- a/libpurple/server.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/server.c Sat Oct 23 01:06:57 2021 -0500
@@ -28,7 +28,6 @@
--- a/libpurple/status.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/status.c Sat Oct 23 01:06:57 2021 -0500
@@ -503,58 +503,6 @@
**************************************************************************/
-notify_buddy_status_update(PurpleBuddy *buddy, PurplePresence *presence,
- PurpleStatus *old_status, PurpleStatus *new_status)
- if (purple_prefs_get_bool("/purple/logging/log_system"))
- GDateTime *current_time = g_date_time_new_now_utc();
- const char *buddy_alias = purple_buddy_get_alias(buddy);
- if (old_status != NULL)
- tmp = g_strdup_printf(_("%s (%s) changed status from %s to %s"), buddy_alias,
- purple_buddy_get_name(buddy),
- purple_status_get_name(old_status),
- purple_status_get_name(new_status));
- logtmp = g_markup_escape_text(tmp, -1);
- /* old_status == NULL when an independent status is toggled. */
- if (purple_status_is_active(new_status))
- tmp = g_strdup_printf(_("%s (%s) is now %s"), buddy_alias,
- purple_buddy_get_name(buddy),
- purple_status_get_name(new_status));
- logtmp = g_markup_escape_text(tmp, -1);
- tmp = g_strdup_printf(_("%s (%s) is no longer %s"), buddy_alias,
- purple_buddy_get_name(buddy),
- purple_status_get_name(new_status));
- logtmp = g_markup_escape_text(tmp, -1);
- log = purple_account_get_log(purple_buddy_get_account(buddy), FALSE);
- purple_log_write(log, PURPLE_MESSAGE_SYSTEM, buddy_alias,
- g_date_time_unref(current_time);
notify_status_update(PurplePresence *presence, PurpleStatus *old_status,
PurpleStatus *new_status)
@@ -572,12 +520,6 @@
ops->status_changed(account, new_status);
- else if (PURPLE_IS_BUDDY_PRESENCE(presence))
- notify_buddy_status_update(purple_buddy_presence_get_buddy(
- PURPLE_BUDDY_PRESENCE(presence)), presence, old_status,
--- a/libpurple/xfer.c Fri Oct 22 03:33:32 2021 -0500
+++ b/libpurple/xfer.c Sat Oct 23 01:06:57 2021 -0500
@@ -38,6 +38,7 @@
#include "purpleconversationmanager.h"
--- a/pidgin/gtkblist.c Fri Oct 22 03:33:32 2021 -0500
+++ b/pidgin/gtkblist.c Sat Oct 23 01:06:57 2021 -0500
@@ -156,7 +156,6 @@
static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
-static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
static PidginBuddyList *gtkblist = NULL;
@@ -3846,7 +3845,6 @@
pidgin_blist_sort_method_reg("none", _("Manually"), sort_method_none);
pidgin_blist_sort_method_reg("alphabetical", _("Alphabetically"), sort_method_alphabetical);
pidgin_blist_sort_method_reg("status", _("By status"), sort_method_status);
- pidgin_blist_sort_method_reg("log_size", _("By recent log activity"), sort_method_log_activity);
id = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type");
@@ -6506,93 +6504,6 @@
-static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter)
- int activity_score = 0, this_log_activity_score = 0;
- const char *buddy_name, *this_buddy_name;
- if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) {
- if(PURPLE_IS_CONTACT(node)) {
- for (n = node->child; n; n = n->next) {
- buddy = (PurpleBuddy*)n;
- activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
- buddy_name = purple_contact_get_alias((PurpleContact*)node);
- } else if(PURPLE_IS_CHAT(node)) {
- /* we don't have a reliable way of getting the log filename
- * from the chat info in the blist, yet */
- gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
- sort_method_none(node, blist, groupiter, cur, iter);
- if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) {
- gtk_tree_store_insert(gtkblist->treemodel, iter, &groupiter, 0);
- gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &n, -1);
- this_log_activity_score = 0;
- if(PURPLE_IS_CONTACT(n)) {
- for (n2 = n->child; n2; n2 = n2->next) {
- buddy = (PurpleBuddy*)n2;
- this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
- this_buddy_name = purple_contact_get_alias((PurpleContact*)n);
- this_buddy_name = NULL;
- cmp = purple_utf8_strcasecmp(buddy_name, this_buddy_name);
- if (!PURPLE_IS_CONTACT(n) || activity_score > this_log_activity_score ||
- ((activity_score == this_log_activity_score) &&
- (cmp < 0 || (cmp == 0 && node < n)))) {
- gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z);
- gtk_tree_store_insert_before(gtkblist->treemodel, iter,
- } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z));
- gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL);
- gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
pidgin_blist_update_sort_methods(void)
--- a/pidgin/gtkconv.c Fri Oct 22 03:33:32 2021 -0500
+++ b/pidgin/gtkconv.c Sat Oct 23 01:06:57 2021 -0500
@@ -149,22 +149,6 @@
static void pidgin_conv_set_position_size(PidginConvWindow *win, int x, int y,
-static PurpleBlistNode *
-get_conversation_blist_node(PurpleConversation *conv)
- PurpleAccount *account = purple_conversation_get_account(conv);
- PurpleBlistNode *node = NULL;
- if (PURPLE_IS_IM_CONVERSATION(conv)) {
- node = PURPLE_BLIST_NODE(purple_blist_find_buddy(account, purple_conversation_get_name(conv)));
- node = node ? node->parent : NULL;
- } else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
- node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, purple_conversation_get_name(conv)));
/**************************************************************************
**************************************************************************/
@@ -1425,7 +1409,6 @@
- purple_conversation_close_logs(old_conv);
gtkconv->active_conv = conv;
purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv);
@@ -2509,7 +2492,6 @@
PidginConversation *gtkconv;
- PurpleBlistNode *convnode;
if (PURPLE_IS_IM_CONVERSATION(conv) && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
g_object_set_data(G_OBJECT(conv), "pidgin", gtkconv);
@@ -2558,12 +2540,6 @@
gtk_box_pack_start(GTK_BOX(tab_cont), pane, TRUE, TRUE, 0);
- convnode = get_conversation_blist_node(conv);
- if (convnode != NULL && purple_blist_node_has_setting(convnode, "enable-logging")) {
- gboolean logging = purple_blist_node_get_bool(convnode, "enable-logging");
- purple_conversation_set_logging(conv, logging);
talkatu_editor_set_toolbar_visible(
TALKATU_EDITOR(gtkconv->editor),
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")
--- a/pidgin/gtkutils.c Fri Oct 22 03:33:32 2021 -0500
+++ b/pidgin/gtkutils.c Sat Oct 23 01:06:57 2021 -0500
@@ -1137,32 +1137,12 @@
g_free(normalized_buddyname);
-static void get_log_set_name(PurpleLogSet *set, gpointer value, PidginCompletionData *data)
- PidginFilterBuddyCompletionEntryFunc filter_func = data->filter_func;
- gpointer user_data = data->filter_func_user_data;
- /* 1. Don't show buddies because we will have gotten them already.
- * 2. The boxes that use this autocomplete code handle only IMs. */
- if (!set->buddy && set->type == PURPLE_LOG_IM) {
- PidginBuddyCompletionEntry entry;
- entry.is_buddy = FALSE;
- entry.entry.logged_buddy = set;
- if (filter_func(&entry, user_data)) {
- add_buddyname_autocomplete_entry(data->store,
- NULL, NULL, set->account, set->name);
add_completion_list(PidginCompletionData *data)
PurpleBlistNode *gnode, *cnode, *bnode;
PidginFilterBuddyCompletionEntryFunc filter_func = data->filter_func;
gpointer user_data = data->filter_func_user_data;
gtk_list_store_clear(data->store);
@@ -1183,14 +1163,14 @@
PidginBuddyCompletionEntry entry;
- entry.entry.buddy = (PurpleBuddy *) bnode;
+ entry.buddy = (PurpleBuddy *) bnode; if (filter_func(&entry, user_data)) {
add_buddyname_autocomplete_entry(data->store,
- purple_buddy_get_contact_alias(entry.entry.buddy),
- purple_buddy_get_account(entry.entry.buddy),
- purple_buddy_get_name(entry.entry.buddy)
+ purple_buddy_get_contact_alias(entry.buddy), + purple_buddy_get_account(entry.buddy), + purple_buddy_get_name(entry.buddy) @@ -1198,11 +1178,6 @@
- sets = purple_log_get_log_sets();
- g_hash_table_foreach(sets, (GHFunc)get_log_set_name, data);
- g_hash_table_destroy(sets);
@@ -1288,11 +1263,7 @@
pidgin_screenname_autocomplete_default_filter(const PidginBuddyCompletionEntry *completion_entry, gpointer all_accounts) {
gboolean all = GPOINTER_TO_INT(all_accounts);
- if (completion_entry->is_buddy) {
- return all || purple_account_is_connected(purple_buddy_get_account(completion_entry->entry.buddy));
- return all || (completion_entry->entry.logged_buddy->account != NULL && purple_account_is_connected(completion_entry->entry.logged_buddy->account));
+ return all || purple_account_is_connected(purple_buddy_get_account(completion_entry->buddy)); void pidgin_set_cursor(GtkWidget *widget, GdkCursorType cursor_type)
--- a/pidgin/gtkutils.h Fri Oct 22 03:33:32 2021 -0500
+++ b/pidgin/gtkutils.h Sat Oct 23 01:06:57 2021 -0500
@@ -46,10 +46,7 @@
- PurpleLogSet *logged_buddy;
} PidginBuddyCompletionEntry;
typedef gboolean (*PidginFilterBuddyCompletionEntryFunc) (const PidginBuddyCompletionEntry *completion_entry, gpointer user_data);
--- a/pidgin/prefs/pidginprefs.c Fri Oct 22 03:33:32 2021 -0500
+++ b/pidgin/prefs/pidginprefs.c Sat Oct 23 01:06:57 2021 -0500
@@ -128,14 +128,6 @@
- PidginPrefCombo format;
@@ -1701,25 +1693,6 @@
-bind_logging_page(PidginPrefsWindow *win)
- win->logging.format.type = PURPLE_PREF_STRING;
- win->logging.format.key = "/purple/logging/format";
- names = purple_log_logger_get_options();
- pidgin_prefs_bind_dropdown_from_list(&win->logging.format, names);
- pidgin_prefs_bind_checkbox("/purple/logging/log_ims",
- pidgin_prefs_bind_checkbox("/purple/logging/log_chats",
- win->logging.log_chats);
- pidgin_prefs_bind_checkbox("/purple/logging/log_system",
- win->logging.log_system);
set_idle_away(PurpleSavedStatus *status)
purple_prefs_set_int("/purple/savedstatus/idleaway", purple_savedstatus_get_creation_time(status));
@@ -2293,7 +2266,6 @@
bind_interface_page(win);
- bind_logging_page(win);
@@ -2384,16 +2356,6 @@
gtk_widget_class_bind_template_callback(widget_class,
- gtk_widget_class_bind_template_child(
- widget_class, PidginPrefsWindow, logging.format.combo);
- gtk_widget_class_bind_template_child(
- widget_class, PidginPrefsWindow, logging.log_ims);
- gtk_widget_class_bind_template_child(
- widget_class, PidginPrefsWindow, logging.log_chats);
- gtk_widget_class_bind_template_child(
- widget_class, PidginPrefsWindow, logging.log_system);
gtk_widget_class_bind_template_child(
widget_class, PidginPrefsWindow, network.stun_server);
@@ -2570,9 +2532,6 @@
const gchar *video_sink = NULL;
/* Rename some old prefs */
- purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_ims", "/purple/logging/log_ims");
- purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_chats", "/purple/logging/log_chats");
purple_prefs_rename(PIDGIN_PREFS_ROOT "/conversations/im/raise_on_events", "/plugins/gtk/X11/notify/method_raise");
purple_prefs_rename_boolean_toggle(PIDGIN_PREFS_ROOT "/conversations/ignore_colors",
@@ -2615,7 +2574,6 @@
purple_prefs_remove(PIDGIN_PREFS_ROOT "/conversations/passthrough_unknown_commands");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/debug/timestamps");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/idle");
- purple_prefs_remove(PIDGIN_PREFS_ROOT "/logging/individual_logs");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/sound/signon");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/sound/silent_signon");
purple_prefs_remove(PIDGIN_PREFS_ROOT "/sound/command");
--- a/pidgin/resources/Prefs/prefs.ui Fri Oct 22 03:33:32 2021 -0500
+++ b/pidgin/resources/Prefs/prefs.ui Sat Oct 23 01:06:57 2021 -0500
@@ -199,14 +199,6 @@
- <object class="GtkListStore" id="logging.format.store">
- <!-- column-name text -->
- <column type="gchararray"/>
- <!-- column-name value -->
- <column type="gchararray"/>
<object class="GtkAdjustment" id="network.ports_range_end.adjustment">
<property name="upper">65535</property>
<property name="step-increment">1</property>
@@ -889,147 +881,6 @@
- <object class="GtkBox" id="logging.page">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="border-width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">18</property>
- <object class="GtkFrame">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label-xalign">0</property>
- <property name="shadow-type">none</property>
- <object class="GtkAlignment">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="left-padding">12</property>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="spacing">6</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Log _format:</property>
- <property name="use-underline">True</property>
- <property name="mnemonic-widget">logging.format.combo</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkComboBox" id="logging.format.combo">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="model">logging.format.store</property>
- <object class="GtkCellRendererText"/>
- <attribute name="text">0</attribute>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <object class="GtkCheckButton" id="logging.log_ims">
- <property name="label" translatable="yes">Log all _instant messages</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="use-underline">True</property>
- <property name="draw-indicator">True</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- <object class="GtkCheckButton" id="logging.log_chats">
- <property name="label" translatable="yes">Log all c_hats</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="use-underline">True</property>
- <property name="draw-indicator">True</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- <object class="GtkCheckButton" id="logging.log_system">
- <property name="label" translatable="yes">Log all _status changes to system log</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="use-underline">True</property>
- <property name="draw-indicator">True</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="label" translatable="yes">Logging</property>
- <attribute name="weight" value="bold"/>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- <property name="name">logging</property>
- <property name="title" translatable="yes">Logging</property>
- <property name="position">2</property>
<object class="GtkBox" id="network.page">
<property name="visible">True</property>
<property name="can-focus">False</property>
--- a/po/POTFILES.in Fri Oct 22 03:33:32 2021 -0500
+++ b/po/POTFILES.in Sat Oct 23 01:06:57 2021 -0500
@@ -44,7 +44,6 @@
libpurple/media/backend-fs2.c
libpurple/media/backend-iface.c