/soc/2015/igor.gajowiak/chatlog: 2867d33d0158: Implemented getti...
Igor Gajowiak <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 2867d33d01586124e4b989cfcc0defae72873ebc Author: Igor Gajowiak <[email protected]> Date: 2015-07-23 23:49 +0200 Branch: default URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/2867d33d0158 Description: Implemented getting all buddies from the generic log. diffstat: libpurple/genericlog.c | 37 ++++++++++++++ libpurple/genericlog.h | 24 +++++++++ libpurple/plugins/log/logsqlite.c | 98 ++++++++++++++++++++++++++++++++++++-- pidgin/gtkgenericlog.c | 79 ++++++++++++++++++++++++++---- 4 files changed, 219 insertions(+), 19 deletions(-) diffs (truncated from 424 to 300 lines): diff --git a/libpurple/genericlog.c b/libpurple/genericlog.c --- a/libpurple/genericlog.c +++ b/libpurple/genericlog.c @@ -297,6 +297,43 @@ purple_genericlog_get_unseen_msgs(Purple return TRUE; } +gboolean +purple_genericlog_get_all_buddies(GList** result, GError** error) +{ + if (!purple_genericlog_inuse) { + if (!error) return FALSE; + + *error = g_error_new(purple_genericlog_error_domain(), + PURPLE_GENERICLOG_ERROR_NOLOG, "No active log"); + return FALSE; + } + + PurpleGenericLogClass *klass = + PURPLE_GENERICLOG_GET_CLASS(purple_genericlog_inuse); + + if (!klass->get_all_buddies) { + if (!error) return FALSE; + + *error = g_error_new(purple_genericlog_error_domain(), + PURPLE_GENERICLOG_ERROR_OPERATIONNOTSUPPORTED, + "%s does not support getting buddies from log", + purple_genericlog_get_id(purple_genericlog_inuse)); + return FALSE; + } + + if (!klass->get_all_buddies(result)) { + if (!error) return FALSE; + + *error = g_error_new(purple_genericlog_error_domain(), + PURPLE_GENERICLOG_ERROR_BACKENDFAIL, + "Getting buddies from %s failed", + purple_genericlog_get_id(purple_genericlog_inuse)); + return FALSE; + } + + return TRUE; +} + /**************************************************************************/ /* Error Codes */ /**************************************************************************/ diff --git a/libpurple/genericlog.h b/libpurple/genericlog.h --- a/libpurple/genericlog.h +++ b/libpurple/genericlog.h @@ -61,6 +61,10 @@ struct _PurpleGenericLog * In case of any error the result is not set. * The client is responsible for freeing the result with * g_list_free_full(result, g_object_unref). + * @get_all_buddies: Gets a list of all #PurpleBuddy objects with at least one + * message in the log. Returns %TRUE if operation succeeds, + * %FALSE otherwise. The client is responsible for freeing + * the result with g_list_free_full(result, g_object_unref). * * The abstract base class for all log implementations. A conforming plugin * must implement at least activate and deactivate methods. Not supported @@ -81,6 +85,8 @@ struct _PurpleGenericLogClass gboolean (*get_unseen_msgs)(PurpleAccount *account, GList **result); + gboolean (*get_all_buddies)(GList **result); + void (*reserved1)(void); void (*reserved2)(void); void (*reserved3)(void); @@ -229,6 +235,24 @@ gboolean purple_genericlog_get_unseen_msgs(PurpleAccount *account, GList **result, GError **error); +/** + * purple_genericlog_get_all_buddies: + * @result[out]: Return location for a #GList containing a list of #PurpleBuddy + * objects. This will not be set in case of any errors. + * @error: Return location for a #GError or %NULL. If provided, this + * will be set to the reason if getting messages fails. + * + * Gets a list of all #PurpleBuddy objects with at least one message in the + * active log. + * + * The caller is responsible for freeing the result with + * g_list_free_full(result, g_object_unref). + * + * Returns: %TRUE if succeeds, %FALSE otherwise. + */ +gboolean +purple_genericlog_get_all_buddies(GList **result, GError **error); + /**************************************************************************/ /* Error Codes */ /**************************************************************************/ 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 @@ -80,8 +80,8 @@ static sqlite3_stmt *insert_message_q = static const char *insert_message_q_str = "INSERT INTO Messages (Author, AuthorAlias, Recipient, " - "Contents, MsgTime, Flags, Seen, AccountId) " - "VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);"; + "Contents, MsgTime, Flags, Seen, Send, AccountId) " + "VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9);"; typedef enum { @@ -92,7 +92,8 @@ typedef enum INSERT_MESSAGE_QUERY_PARAM_MSGTIME = 5, INSERT_MESSAGE_QUERY_PARAM_FLAGS = 6, INSERT_MESSAGE_QUERY_PARAM_SEEN = 7, - INSERT_MESSAGE_QUERY_PARAM_ACCOUNTID = 8, + INSERT_MESSAGE_QUERY_PARAM_SEND = 8, + INSERT_MESSAGE_QUERY_PARAM_ACCOUNTID = 9, } InsertMessageQueryParam; static sqlite3_stmt *get_unseen_msgs_q = NULL; @@ -132,6 +133,26 @@ typedef enum MARK_AS_SEEN_QUERY_PARAM_ID = 1 } MarkAsSeenQueryParam; +static sqlite3_stmt *get_all_buddies_q = NULL; + +static const char *get_all_buddies_q_str = + "SELECT Username, ProtocolId, Author Buddy FROM " + "Messages JOIN Accounts on Accounts.Id = AccountId " + "WHERE Send = 0 " + "GROUP BY Username, ProtocolId, Buddy " + "UNION " + "SELECT Username, ProtocolId, Recipient Buddy FROM " + "Messages JOIN Accounts on Accounts.Id = AccountId " + "WHERE Send = 1 " + "GROUP BY Username, ProtocolId, Buddy;"; + +typedef enum +{ + GET_ALL_BUDDIES_QUERY_COL_USERNAME = 0, + GET_ALL_BUDDIES_QUERY_COL_PROTOCOL = 1, + GET_ALL_BUDDIES_QUERY_COL_BUDDY = 2, +} GetAllBuddiesQueryCol; + static void sqlitelog_finalize_query(sqlite3_stmt **query) { @@ -153,6 +174,7 @@ sqlitelog_finalize_queries() sqlitelog_finalize_query(&insert_message_q); sqlitelog_finalize_query(&get_unseen_msgs_q); sqlitelog_finalize_query(&mark_as_seen_q); + sqlitelog_finalize_query(&get_all_buddies_q); } static gboolean @@ -184,7 +206,8 @@ sqlitelog_prepare_queries() !sqlitelog_prepare_query(insert_account_q_str, &insert_account_q) || !sqlitelog_prepare_query(insert_message_q_str, &insert_message_q) || !sqlitelog_prepare_query(get_unseen_msgs_q_str, &get_unseen_msgs_q) || - !sqlitelog_prepare_query(mark_as_seen_q_str, &mark_as_seen_q)) { + !sqlitelog_prepare_query(mark_as_seen_q_str, &mark_as_seen_q) || + !sqlitelog_prepare_query(get_all_buddies_q_str, &get_all_buddies_q)) { sqlitelog_finalize_queries(); return FALSE; @@ -219,10 +242,12 @@ sqlitelog_create_tables(sqlite3 *db_hand "MsgTime INTEGER NOT NULL," "Flags INTEGER NOT NULL," "Seen BOOLEAN DEFAULT 0," + "Send BOOLEAN NOT NULL," "AccountId INTEGER NOT NULL," "FOREIGN KEY(AccountId) REFERENCES Accounts(Id)); " "CREATE INDEX SeenIndex ON Messages (Seen); " + "CREATE INDEX SendIndex ON Messages (Send); " "CREATE TRIGGER AccountDeleted AFTER DELETE ON Accounts " "BEGIN " @@ -339,9 +364,10 @@ sqlitelog_insert_account(const PurpleAcc } static gboolean -sqlitelog_insert_message(unsigned account_id, const PurpleMessage *msg, - unsigned *id) +sqlitelog_insert_message(PurpleAccount *account, unsigned account_id, + const PurpleMessage *msg, unsigned *id) { + g_assert(account); g_assert(account_id != SQLITELOG_DB_ID_NONE); g_assert(msg); g_assert(id); @@ -349,12 +375,15 @@ sqlitelog_insert_message(unsigned accoun g_assert(insert_message_q); const char *author = purple_message_get_author(msg); + author = author ? purple_normalize(account, author) : NULL; const char *author_alias = purple_message_get_author_alias(msg); const char *recipient = purple_message_get_recipient(msg); + recipient = recipient ? purple_normalize(account, recipient) : NULL; 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; + int send = (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 || @@ -372,6 +401,8 @@ sqlitelog_insert_message(unsigned accoun msg_flags) != SQLITE_OK || sqlite3_bind_int(insert_message_q, INSERT_MESSAGE_QUERY_PARAM_SEEN, seen) != SQLITE_OK || + sqlite3_bind_int(insert_message_q, INSERT_MESSAGE_QUERY_PARAM_SEND, + send) != SQLITE_OK || sqlite3_bind_int(insert_message_q, INSERT_MESSAGE_QUERY_PARAM_ACCOUNTID, account_id) != SQLITE_OK) { return FALSE; @@ -465,6 +496,44 @@ sqlitelog_mark_as_seen_impl(unsigned msg return rc == SQLITE_DONE; } +static gboolean +sqlitelog_get_all_buddies_impl(GList **result) +{ + g_assert(result); + + g_assert(get_all_buddies_q); + + GList *buddies = NULL; + int rc; + while ((rc = sqlite3_step(get_all_buddies_q)) == SQLITE_ROW) { + const char *username = (const char*) sqlite3_column_text( + get_all_buddies_q, GET_ALL_BUDDIES_QUERY_COL_USERNAME); + const char *protocol = (const char*) sqlite3_column_text( + get_all_buddies_q, GET_ALL_BUDDIES_QUERY_COL_PROTOCOL); + const char *buddy = (const char*) sqlite3_column_text( + get_all_buddies_q, GET_ALL_BUDDIES_QUERY_COL_BUDDY); + + PurpleAccount *account = purple_accounts_find(username, protocol); + if (!account) + continue; + + PurpleBuddy *prpl_buddy = purple_blist_find_buddy(account, buddy); + if (!prpl_buddy) + continue; + + buddies = g_list_prepend(buddies, prpl_buddy); + g_object_ref(prpl_buddy); + } + + if (rc != SQLITE_DONE) { + g_list_free_full(buddies, g_object_unref); + return FALSE; + } + + *result = buddies; + return TRUE; +} + /**************************************************************************/ /* PurpleGenericLog API implementation */ /**************************************************************************/ @@ -540,7 +609,7 @@ sqlitelog_log_im(PurpleAccount *account, } unsigned message_id; - if (!sqlitelog_insert_message(account_id, message, &message_id)) + if (!sqlitelog_insert_message(account, account_id, message, &message_id)) return FALSE; g_object_set_data(G_OBJECT(message), SQLITELOG_MESSAGE_ID_ATTR, @@ -583,6 +652,20 @@ sqlitelog_get_unseen_msgs(PurpleAccount return sqlitelog_get_unseen_msgs_impl(account, result); } +static gboolean +sqlitelog_get_all_buddies(GList **result) +{ + g_return_val_if_fail(result != NULL, FALSE); + + if (!sqlitelog_db_handle) { + purple_debug_error(SQLITELOG_DEBUG_CATEGORY, + "Log is not active"); + return FALSE; + } + + return sqlitelog_get_all_buddies_impl(result); +} + /**************************************************************************/ /* GObject stuff */ /**************************************************************************/ @@ -627,6 +710,7 @@ purple_sqlitelog_class_init (PurpleSqlit klass->parent_class.log_im = sqlitelog_log_im; klass->parent_class.mark_as_seen = sqlitelog_mark_as_seen; klass->parent_class.get_unseen_msgs = sqlitelog_get_unseen_msgs; + klass->parent_class.get_all_buddies = sqlitelog_get_all_buddies; } static GType diff --git a/pidgin/gtkgenericlog.c b/pidgin/gtkgenericlog.c --- a/pidgin/gtkgenericlog.c _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits