/soc/2015/igor.gajowiak/chatlog: 38521ffa0033: Implemented skipp...
Igor Gajowiak <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 38521ffa0033c46483d4932827362e97e26cfbeb Author: Igor Gajowiak <[email protected]> Date: 2015-08-17 22:42 +0200 Branch: default URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/38521ffa0033 Description: Implemented skipping duplicates when importing messages. diffstat: libpurple/conversation.c | 4 +- libpurple/genericlog.c | 29 +++++++- libpurple/genericlog.h | 11 ++- libpurple/plugins/log/logsqlite.c | 122 ++++++++++++++++++++++++++++++++++++- 4 files changed, 152 insertions(+), 14 deletions(-) diffs (truncated from 330 to 300 lines): diff --git a/libpurple/conversation.c b/libpurple/conversation.c --- a/libpurple/conversation.c +++ b/libpurple/conversation.c @@ -642,7 +642,9 @@ void } GError *error; - if (!purple_genericlog_log_msg(account, contact, pmsg, &error)) { + int seen = (purple_message_get_flags(pmsg) & PURPLE_MESSAGE_SEND) + ? 1 : 0; + if (!purple_genericlog_log_msg(account, contact, pmsg, seen, &error)) { purple_debug_error("conversation", "Logging failed: %s (code=%d)", error->message, error->code); g_error_free(error); diff --git a/libpurple/genericlog.c b/libpurple/genericlog.c --- a/libpurple/genericlog.c +++ b/libpurple/genericlog.c @@ -261,13 +261,13 @@ purple_genericlog_set_active_log(PurpleG gboolean purple_genericlog_log_msg(PurpleAccount *account, PurpleBlistNode *contact, - PurpleMessage *msg, GError **error) + PurpleMessage *msg, gboolean seen, GError **error) { GENERICLOG_CHECK_CONTACT(contact); DEFINE_GENERICLOG_FUNC_WITH_RETURN(log_msg, "%s does not support IM logging", - "Failed to log IM in %s", account, contact, msg); + "Failed to log IM in %s", account, contact, msg, seen); } gboolean @@ -349,6 +349,18 @@ purple_genericlog_wipe_log_for_contact(P "Removing messages from %s failed", contact); } +static gboolean +_purple_genericlog_import_msg(PurpleAccount *account, PurpleBlistNode *contact, + PurpleMessage *msg, gboolean seen, gboolean *imported, GError **error) +{ + GENERICLOG_CHECK_CONTACT(contact); + + DEFINE_GENERICLOG_FUNC_WITH_RETURN(import_msg, + "%s does not support importing messages", + "Failed to import message into %s", + account, contact, msg, seen, imported); +} + #undef GENERICLOG_CHECK_CONTACT #undef DEFINE_GENERICLOG_FUNC_WITH_RETURN @@ -413,9 +425,15 @@ run_import_iteration(gpointer unused) PurpleBlistNode *contact = g_array_index(contacts, PurpleBlistNode*, i); PurpleMessage *message = g_array_index(messages, PurpleMessage*, i); - /* Should we stop if logging fails? */ - if (purple_genericlog_log_msg(account, contact, message, NULL)) - ++(import_state->imported_messages_count); + gboolean imported; + + /* Should we stop if importing fails? */ + if (!_purple_genericlog_import_msg(account, contact, message, TRUE, + &imported, NULL)) { + continue; + } + + import_state->imported_messages_count += imported ? 1 : 0; } g_array_free(accounts, TRUE); @@ -581,6 +599,7 @@ purple_genericlog_class_init(PurpleGener klass->init_export = NULL; klass->read_chunk = NULL; klass->finalize_export = NULL; + klass->import_msg = NULL; klass->reserved1 = NULL; klass->reserved2 = NULL; diff --git a/libpurple/genericlog.h b/libpurple/genericlog.h --- a/libpurple/genericlog.h +++ b/libpurple/genericlog.h @@ -103,6 +103,9 @@ struct _PurpleGenericLog * export. Returns %TRUE if operation succeeds, * %FALSE otherwise. * @finalize_export: Finalizes an export procedure. + * @import_msg: Imports a message. Behaves same as log_msg, but + * additionally skips duplicates. Returns %TRUE if operation + * succeeds, %FALSE otherwise. * * The abstract base class for all log implementations. A conforming plugin * must implement at least activate and deactivate methods. Not supported @@ -118,7 +121,7 @@ struct _PurpleGenericLogClass void (*deactivate)(void); gboolean (*log_msg) (PurpleAccount *account, PurpleBlistNode* contact, - PurpleMessage *message); + PurpleMessage *message, gboolean seen); gboolean (*mark_as_seen)(PurpleMessage *message); @@ -146,6 +149,9 @@ struct _PurpleGenericLogClass void (*finalize_export) (void *export_state); + gboolean (*import_msg) (PurpleAccount *account, PurpleBlistNode* contact, + PurpleMessage *message, gboolean seen, gboolean *imported); + void (*reserved1)(void); void (*reserved2)(void); void (*reserved3)(void); @@ -272,6 +278,7 @@ purple_genericlog_set_active_log(PurpleG * @account: The account. * @contact The contact, must be PurpleChat or PurpleBuddy. * @msg: The message. + * @seen: %TRUE if message should be marked as seen. * @error: Return location for a #GError or %NULL. If provided, this * will be set to the reason if logging fails. * @@ -281,7 +288,7 @@ purple_genericlog_set_active_log(PurpleG */ gboolean purple_genericlog_log_msg(PurpleAccount *account, PurpleBlistNode* contact, - PurpleMessage *msg, GError **error); + PurpleMessage *msg, gboolean seen, GError **error); /** * purple_genericlog_mark_as_seen: diff --git a/libpurple/plugins/log/logsqlite.c b/libpurple/plugins/log/logsqlite.c --- a/libpurple/plugins/log/logsqlite.c +++ b/libpurple/plugins/log/logsqlite.c @@ -311,6 +311,23 @@ typedef enum DELETE_CONTACT_QUERY_PARAM_ACCOUNTID = 2, } DeleteContactQueryParam; +static sqlite3_stmt *contains_msg_q = NULL; + +static const char *contains_msg_q_str = + "SELECT NULL FROM Messages " + "WHERE AccountId = ?1 AND ContactId = ?2 AND MsgTime = ?3 " + "AND Author IS ?4 AND Recipient IS ?5 AND Contents IS ?6 LIMIT 1;"; + +typedef enum +{ + CONTAINS_MSG_QUERY_PARAM_ACCOUNTID = 1, + CONTAINS_MSG_QUERY_PARAM_CONTACTID = 2, + CONTAINS_MSG_QUERY_PARAM_MSGTIME = 3, + CONTAINS_MSG_QUERY_PARAM_AUTHOR = 4, + CONTAINS_MSG_QUERY_PARAM_RECIPIENT = 5, + CONTAINS_MSG_QUERY_PARAM_CONTENTS = 6, +} ContainsMsgQueryParam; + static void sqlitelog_finalize_query(sqlite3_stmt **query) { @@ -347,6 +364,7 @@ sqlitelog_finalize_queries() sqlitelog_finalize_query(&get_all_contacts_q); sqlitelog_finalize_query(&get_all_days_q); sqlitelog_finalize_query(&delete_contact_q); + sqlitelog_finalize_query(&contains_msg_q); } static gboolean @@ -396,7 +414,8 @@ sqlitelog_prepare_queries() !sqlitelog_prepare_query(mark_as_seen_q_str, &mark_as_seen_q) || !sqlitelog_prepare_query(get_all_contacts_q_str, &get_all_contacts_q) || !sqlitelog_prepare_query(get_all_days_q_str, &get_all_days_q) || - !sqlitelog_prepare_query(delete_contact_q_str, &delete_contact_q)) { + !sqlitelog_prepare_query(delete_contact_q_str, &delete_contact_q) || + !sqlitelog_prepare_query(contains_msg_q_str, &contains_msg_q)) { sqlitelog_finalize_queries(); return FALSE; @@ -695,7 +714,7 @@ sqlitelog_insert_day(guint64 time, unsig static gboolean sqlitelog_insert_message(PurpleAccount *account, unsigned account_id, unsigned contact_id, unsigned day_id, const PurpleMessage *msg, - unsigned *id) + gboolean seen, unsigned *id) { g_assert(account); g_assert(account_id != SQLITELOG_DB_ID_NONE); @@ -714,7 +733,6 @@ sqlitelog_insert_message(PurpleAccount * const char *contents = purple_message_get_contents(msg); guint64 msg_time = purple_message_get_time(msg); PurpleMessageFlags msg_flags = purple_message_get_flags(msg); - int seen = (msg_flags & PURPLE_MESSAGE_SEND) ? 1 : 0; if (sqlite3_bind_text(insert_message_q, INSERT_MESSAGE_QUERY_PARAM_AUTHOR, author, -1, SQLITE_STATIC) != SQLITE_OK || @@ -731,7 +749,7 @@ sqlitelog_insert_message(PurpleAccount * sqlite3_bind_int(insert_message_q, INSERT_MESSAGE_QUERY_PARAM_FLAGS, msg_flags) != SQLITE_OK || sqlite3_bind_int(insert_message_q, INSERT_MESSAGE_QUERY_PARAM_SEEN, - seen) != SQLITE_OK || + seen ? 1 : 0) != SQLITE_OK || sqlite3_bind_int64(insert_message_q, INSERT_MESSAGE_QUERY_PARAM_ACCOUNTID, account_id) != SQLITE_OK || sqlite3_bind_int64(insert_message_q, @@ -1168,6 +1186,73 @@ sqlitelog_delete_contact_impl(PurpleBlis return rc == SQLITE_DONE; } +static gboolean +sqlitelog_contains_msg(PurpleAccount *account, PurpleBlistNode* contact, + PurpleMessage *message, gboolean *result) +{ + g_assert(account); + g_assert(contact); + g_assert(message); + g_assert(result); + + unsigned account_id; + if (!sqlitelog_get_account_id(account, &account_id)) + return FALSE; + + if (account_id == SQLITELOG_DB_ID_NONE) { + *result = FALSE; + return TRUE; + } + + const char *contact_name = PURPLE_IS_CHAT(contact) ? + purple_chat_get_name_only(PURPLE_CHAT(contact)) : + purple_buddy_get_name(PURPLE_BUDDY(contact)); + + if (!contact_name) + return FALSE; + + unsigned contact_id; + if (!sqlitelog_get_contact_id(account_id, contact_name, &contact_id)) + return FALSE; + + if (contact_id == SQLITELOG_DB_ID_NONE) { + *result = FALSE; + return TRUE; + } + + if (sqlite3_bind_int64(contains_msg_q, CONTAINS_MSG_QUERY_PARAM_ACCOUNTID, + account_id) != SQLITE_OK || + sqlite3_bind_int64(contains_msg_q, CONTAINS_MSG_QUERY_PARAM_CONTACTID, + contact_id) != SQLITE_OK || + sqlite3_bind_int64(contains_msg_q, CONTAINS_MSG_QUERY_PARAM_MSGTIME, + purple_message_get_time(message)) != SQLITE_OK || + sqlite3_bind_text(contains_msg_q, CONTAINS_MSG_QUERY_PARAM_AUTHOR, + purple_message_get_author(message), -1, SQLITE_STATIC) + != SQLITE_OK || + sqlite3_bind_text(contains_msg_q, CONTAINS_MSG_QUERY_PARAM_RECIPIENT, + purple_message_get_recipient(message), -1, SQLITE_STATIC) + != SQLITE_OK || + sqlite3_bind_text(contains_msg_q, CONTAINS_MSG_QUERY_PARAM_CONTENTS, + purple_message_get_contents(message), -1, SQLITE_STATIC) + != SQLITE_OK) { + return FALSE; + } + + gboolean msg_found = FALSE; + + int rc; + while ((rc = sqlite3_step(contains_msg_q)) == SQLITE_ROW) + msg_found |= TRUE; + + sqlite3_reset(contains_msg_q); + + if (rc != SQLITE_DONE) + return FALSE; + + *result = msg_found; + return TRUE; +} + /**************************************************************************/ /* PurpleGenericLog API implementation */ /**************************************************************************/ @@ -1235,7 +1320,7 @@ guint64 truncate_to_days(guint64 timesta static gboolean sqlitelog_log_msg(PurpleAccount *account, PurpleBlistNode *contact, - PurpleMessage *message) + PurpleMessage *message, gboolean seen) { g_return_val_if_fail(account != NULL, FALSE); g_return_val_if_fail(contact != NULL, FALSE); @@ -1299,7 +1384,7 @@ sqlitelog_log_msg(PurpleAccount *account unsigned message_id; if (!sqlitelog_insert_message(account, account_id, contact_id, day_id, - message, &message_id)) { + message, seen, &message_id)) { sqlite3_step(rollback_transation_q); return FALSE; } @@ -1442,6 +1527,30 @@ sqlitelog_wipe_log_for_contact(PurpleBli return sqlitelog_delete_contact_impl(contact); } +gboolean sqlitelog_import_msg(PurpleAccount *account, PurpleBlistNode* contact, + PurpleMessage *message, gboolean seen, gboolean *imported) +{ + g_return_val_if_fail(account != NULL, FALSE); + g_return_val_if_fail(contact != NULL, FALSE); _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits