/soc/2015/igor.gajowiak/chatlog: aed0441d29e3: Implemented unrea...
Igor Gajowiak <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: aed0441d29e37505574f4422e1ef5a5ccbbb48bf Author: Igor Gajowiak <[email protected]> Date: 2015-07-07 00:11 +0200 Branch: default URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/aed0441d29e3 Description: Implemented unread messages popup on the program startup. diffstat: libpurple/accounts.c | 32 +++++++++++++++ libpurple/conversation.h | 7 +-- libpurple/genericlog.c | 8 +++ libpurple/genericlog.h | 5 ++ libpurple/plugins/log/logsqlite.c | 81 +++++++++++++++++++++++++++++++++----- 5 files changed, 117 insertions(+), 16 deletions(-) diffs (254 lines): diff --git a/libpurple/accounts.c b/libpurple/accounts.c --- a/libpurple/accounts.c +++ b/libpurple/accounts.c @@ -24,6 +24,7 @@ #include "dbus-maybe.h" #include "debug.h" #include "enums.h" +#include "genericlog.h" #include "network.h" #include "pounce.h" @@ -922,6 +923,35 @@ password_migration_cb(PurpleAccount *acc purple_accounts_schedule_save(); } +static void +show_unread_im_msgs(PurpleConnection *gc) +{ + PurpleAccount *account = purple_connection_get_account(gc); + + g_return_if_fail(account != NULL); + + GList *unread_msgs = NULL; + GError *error = purple_genericlog_get_unread_msgs(account, &unread_msgs); + if(error){ + g_error_free(error); + return; + } + + g_return_if_fail(unread_msgs != NULL); + + GList *it = NULL; + for(it = unread_msgs; it != NULL; it = it->next) { + PurpleMessage *msg = it->data; + + // Create or get a conversation + PurpleIMConversation *conv = purple_im_conversation_new( + account, purple_message_get_author(msg)); + + purple_conversation_write_message(PURPLE_CONVERSATION(conv), msg); + } + g_list_free_full(unread_msgs, (GDestroyNotify) g_object_unref); +} + void purple_accounts_init(void) { @@ -1011,6 +1041,8 @@ purple_accounts_init(void) purple_signal_connect(conn_handle, "signed-on", handle, PURPLE_CALLBACK(signed_on_cb), NULL); + purple_signal_connect(conn_handle, "signed-on", handle, + PURPLE_CALLBACK(show_unread_im_msgs), NULL); purple_signal_connect(conn_handle, "signed-off", handle, PURPLE_CALLBACK(signed_off_cb), NULL); purple_signal_connect(conn_handle, "connection-error", handle, diff --git a/libpurple/conversation.h b/libpurple/conversation.h --- a/libpurple/conversation.h +++ b/libpurple/conversation.h @@ -471,11 +471,8 @@ void purple_conversation_close_logs(Purp /** * purple_conversation_write_message: - * @conv: The conversation. - * @who: The user who sent the message. - * @message: The message to write. - * @flags: The message flags. - * @mtime: The time the message was sent. + * @conv: The conversation. + * @msg: The message. * * Writes to a chat or an IM. */ diff --git a/libpurple/genericlog.c b/libpurple/genericlog.c --- a/libpurple/genericlog.c +++ b/libpurple/genericlog.c @@ -185,6 +185,14 @@ purple_genericlog_mark_as_read(PurpleMes return klass->mark_as_read(msg); } +GError* +purple_genericlog_get_unread_msgs(PurpleAccount* account, GList** result) +{ + PurpleGenericLogClass *klass = + PURPLE_GENERICLOG_GET_CLASS(purple_genericlog_inuse); + return klass->get_unread_msgs(account, result); +} + /**************************************************************************/ /* Error Codes */ /**************************************************************************/ diff --git a/libpurple/genericlog.h b/libpurple/genericlog.h --- a/libpurple/genericlog.h +++ b/libpurple/genericlog.h @@ -55,6 +55,8 @@ struct _PurpleGenericLogClass GError* (*mark_as_read)(PurpleMessage *message); + GError* (*get_unread_msgs)(PurpleAccount *account, GList **result); + GError* (*get_messages)(PurpleAccount *account, GList **result, time_t timestamp, size_t limit); @@ -103,6 +105,9 @@ purple_genericlog_logim(PurpleAccount *a GError* purple_genericlog_mark_as_read(PurpleMessage *msg); +GError* +purple_genericlog_get_unread_msgs(PurpleAccount *account, GList **result); + /**************************************************************************/ /* 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 @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#include <stdlib.h> #include <sqlite3.h> // TODO: Why changing the order of these includes causes a crash?! @@ -64,8 +65,6 @@ sqlite_log_db_exists(const gchar *db_pat static int sqlite_log_create_tables() { - // TODO: Moze warto dodac constraint ze para - // user, protocol jest unikalna? const char *sql_statement = "CREATE TABLE Accounts(" "Id INTEGER PRIMARY KEY AUTOINCREMENT," @@ -74,14 +73,21 @@ sqlite_log_create_tables() "CREATE TABLE Messages(" "Author TEXT," - "Author_alias TEXT," + "AuthorAlias TEXT," "Recipient TEXT NOT NULL," "Contents TEXT NOT NULL," - "Msgtime INTEGER NOT NULL," + "MsgTime INTEGER NOT NULL," "Flags INTEGER NOT NULL," - "Acc INTEGER NOT NULL," - "Seen BOOLEAN DEFAULT FALSE," - "FOREIGN KEY(Acc) REFERENCES Accounts(Id));"; + "AccountId INTEGER NOT NULL," + "Read BOOLEAN DEFAULT 0," + "FOREIGN KEY(AccountId) REFERENCES Accounts(Id)); " + + "CREATE INDEX SeenIndex ON Messages (Read); " + + "CREATE TRIGGER AccountDeleted AFTER DELETE ON Accounts " + "BEGIN " + "DELETE FROM Messages WHERE AccountId = OLD.Id; " + "END; "; return sqlite3_exec(sqlite_log_db, sql_statement, NULL, NULL, NULL); } @@ -161,6 +167,12 @@ sqlite_log_get_max_acc_id() static GError* sqlite_log_log_im(PurpleAccount *account, PurpleMessage *message) { + PurpleMessageFlags msg_flags = purple_message_get_flags(message); + if((msg_flags & PURPLE_MESSAGE_NO_LOG) || + (msg_flags & PURPLE_MESSAGE_SYSTEM) || + (msg_flags & PURPLE_MESSAGE_NOTIFY)) + return NULL; + char *sql_statement; int db_account_id = sqlite_log_db_get_account_id(account); @@ -184,15 +196,16 @@ sqlite_log_log_im(PurpleAccount *account } sql_statement = g_strdup_printf( - "INSERT INTO Messages (Author, Author_alias, Recipient, Contents, Msgtime, Flags, Acc) " - "VALUES(\'%s\', \'%s\', \'%s\', \'%s\', %lu, %d, %d);", + "INSERT INTO Messages " + "VALUES(\'%s\', \'%s\', \'%s\', \'%s\', %lu, %d, %d, %d);", purple_message_get_author(message), purple_message_get_author_alias(message), purple_message_get_recipient(message), purple_message_get_contents(message), purple_message_get_time(message), - purple_message_get_flags(message), - db_account_id); + msg_flags, + db_account_id, + msg_flags & PURPLE_MESSAGE_SEND ? 1 : 0); if(sqlite3_exec(sqlite_log_db, sql_statement, NULL, NULL, NULL) != SQLITE_OK) { g_free(sql_statement); @@ -212,6 +225,51 @@ sqlite_log_mark_as_read(PurpleMessage *m return NULL; } +static int +sqlite_log_get_unread_cb(void *data, int argc, char **argv, char **azColName) +{ + GList **list = (GList**) data; + + PurpleMessage *msg = purple_message_new_incoming(argv[0], argv[1], + atoi(argv[2]), strtoull(argv[3], NULL, 10)); + + if (strcmp(argv[4], "(null)") != 0) + purple_message_set_author_alias(msg, argv[4]); + + purple_message_set_flags(msg, purple_message_get_flags(msg) | + PURPLE_MESSAGE_NO_LOG); + + // Here we can use prepend because we ordered SQLite to + // order elements in a descending order + *list = g_list_prepend(*list, msg); + g_object_ref(msg); + return 0; +} + +static GError* +sqlite_log_get_unread_msgs(PurpleAccount *account, GList **result) +{ + char *sql_statement = g_strdup_printf( + "SELECT Author, Contents, Flags, MsgTime, AuthorAlias " + "FROM Messages JOIN Accounts ON Id = AccountId " + "WHERE Username LIKE \'%s\' AND Read = 0 " + "ORDER BY Username, MsgTime desc", + purple_account_get_username(account)); + + int rc = sqlite3_exec(sqlite_log_db, sql_statement, + sqlite_log_get_unread_cb, result, NULL); + + if (rc != SQLITE_OK) { + g_free(sql_statement); + return g_error_new(purple_genericlog_error_domain(), + PURPLE_GENERICLOG_ERROR_BACKENDFAIL, + "SQLITE database error while getting unread messages"); + } + + g_free(sql_statement); + return NULL; +} + static GError* sqlite_log_activate(void) { @@ -291,6 +349,7 @@ purple_sqlitelog_class_init (PurpleSqlit klass->parent_class.log_im = sqlite_log_log_im; klass->parent_class.mark_as_read = sqlite_log_mark_as_read; + klass->parent_class.get_unread_msgs = sqlite_log_get_unread_msgs; klass->parent_class.activate = sqlite_log_activate; klass->parent_class.deactivate = sqlite_log_deactivate; } _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits