/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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.