/soc/2015/igor.gajowiak/chatlog: aed0441d29e3: Implemented unrea...
Igor Gajowiak
igor.gajowiak at gmail.com
Mon Jul 6 18:12:08 EDT 2015
Changeset: aed0441d29e37505574f4422e1ef5a5ccbbb48bf
Author: Igor Gajowiak <igor.gajowiak at gmail.com>
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;
}
More information about the Commits
mailing list