/soc/2012/tomkiewicz/gg: 41e5ff454167: Gadu-Gadu: ggp_purple_req...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Thu Jul 5 13:31:52 EDT 2012


Changeset: 41e5ff4541677bbd3613cfdcc6d4466fe73087ec
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-06-29 22:36 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/41e5ff454167

Description:

Gadu-Gadu: ggp_purple_request_processing implementation; refactoring of account registration (first stage); cancellable token request

diffstat:

 libpurple/protocols/gg/Makefile.am |    4 +-
 libpurple/protocols/gg/account.c   |  221 ++++++++++++++++++++++++++++++++++--
 libpurple/protocols/gg/account.h   |    5 +-
 libpurple/protocols/gg/gg.c        |  163 +--------------------------
 libpurple/protocols/gg/purple.c    |   50 ++++++++
 libpurple/protocols/gg/purple.h    |   38 ++++++
 libpurple/protocols/gg/utils.c     |   14 --
 libpurple/protocols/gg/utils.h     |   14 --
 8 files changed, 310 insertions(+), 199 deletions(-)

diffs (truncated from 710 to 300 lines):

diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -63,7 +63,9 @@
 	account.h \
 	account.c \
 	deprecated.h \
-	deprecated.c
+	deprecated.c \
+	purple.h \
+	purple.c
 
 AM_CFLAGS = $(st)
 
diff --git a/libpurple/protocols/gg/account.c b/libpurple/protocols/gg/account.c
--- a/libpurple/protocols/gg/account.c
+++ b/libpurple/protocols/gg/account.c
@@ -2,23 +2,35 @@
 
 #include <libgadu.h>
 #include <debug.h>
+#include <request.h>
 
 #include "deprecated.h"
+#include "purple.h"
+#include "utils.h"
+
+/*******************************************************************************
+ * Token requesting.
+ ******************************************************************************/
 
 typedef struct
 {
 	ggp_account_token_cb callback;
+	PurpleConnection *gc;
 	void *user_data;
 	
 	struct gg_http *h;
+	ggp_purple_request_processing_handle *req_processing;
 	guint inpa;
 } ggp_account_token_reqdata;
 
 static void ggp_account_token_handler(gpointer _reqdata, gint fd, PurpleInputCondition cond);
 
-static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token);
+/* user cancel isn't a failure */
+static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token, gboolean failure);
 
-/***********************/
+static void ggp_account_token_request_cancel(PurpleConnection *gc, void *_reqdata);
+
+/******************************************************************************/
 
 void ggp_account_token_free(ggp_account_token *token)
 {
@@ -27,12 +39,24 @@
 	g_free(token);
 }
 
-static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token)
+static void ggp_account_token_cb_call(ggp_account_token_reqdata *reqdata, ggp_account_token *token, gboolean failure)
 {
-	reqdata->callback(token, reqdata->user_data);
+	g_assert(!failure || !token); // failure => not token
+	
+	if (reqdata->req_processing)
+	{
+		ggp_purple_request_processing_done(reqdata->req_processing);
+		reqdata->req_processing = NULL;
+	}
+	reqdata->callback(reqdata->gc, token, reqdata->user_data);
 	purple_input_remove(reqdata->inpa);
 	gg_token_free(reqdata->h);
 	g_free(reqdata);
+	
+	if (failure)
+		purple_notify_error(purple_connection_get_account(reqdata->gc),
+			_("Token Error"),
+			_("Unable to fetch the token.\n"), NULL);
 }
 
 void ggp_account_token_request(PurpleConnection *gc, ggp_account_token_cb callback, void *user_data)
@@ -42,7 +66,7 @@
 	
 	if (!ggp_deprecated_setup_proxy(gc))
 	{
-		callback(NULL, user_data);
+		callback(gc, NULL, user_data);
 		return;
 	}
 	
@@ -50,32 +74,44 @@
 	
 	if (!h)
 	{
-		callback(NULL, user_data);
+		callback(gc, NULL, user_data);
 		return;
 	}
 	
 	reqdata = g_new(ggp_account_token_reqdata, 1);
 	reqdata->callback = callback;
+	reqdata->gc = gc;
 	reqdata->user_data = user_data;
 	reqdata->h = h;
-	
+	reqdata->req_processing = ggp_purple_request_processing(gc, NULL, reqdata, ggp_account_token_request_cancel);
 	reqdata->inpa = purple_input_add(h->fd, PURPLE_INPUT_READ, ggp_account_token_handler, reqdata);
 }
 
+static void ggp_account_token_request_cancel(PurpleConnection *gc, void *_reqdata)
+{
+	ggp_account_token_reqdata *reqdata = _reqdata;
+
+	purple_debug_info("gg", "ggp_account_token_request_cancel\n");
+	reqdata->req_processing = NULL;
+	gg_http_stop(reqdata->h);
+	ggp_account_token_cb_call(reqdata, NULL, FALSE);
+}
+
 static void ggp_account_token_handler(gpointer _reqdata, gint fd, PurpleInputCondition cond)
 {
 	ggp_account_token_reqdata *reqdata = _reqdata;
 	struct gg_token *token_info;
 	ggp_account_token *token;
 	
-	purple_debug_info("gg", "ggp_account_token_handler: got fd update [check=%d, state=%d]\n",
+	//TODO: verbose mode
+	purple_debug_misc("gg", "ggp_account_token_handler: got fd update [check=%d, state=%d]\n",
 		reqdata->h->check, reqdata->h->state);
 	
-	if (reqdata->h->state == GG_STATE_ERROR || gg_token_watch_fd(reqdata->h) == -1)
+	if (gg_token_watch_fd(reqdata->h) == -1 || reqdata->h->state == GG_STATE_ERROR)
 	{
 		purple_debug_error("gg", "ggp_account_token_handler: failed to request token: %d\n",
 			reqdata->h->error);
-		ggp_account_token_cb_call(reqdata, NULL);
+		ggp_account_token_cb_call(reqdata, NULL, TRUE);
 		return;
 	}
 	
@@ -92,10 +128,11 @@
 	{
 		purple_debug_error("gg", "ggp_account_token_handler: failed to fetch token: %d\n",
 			reqdata->h->error); // TODO: will anything be here in that case?
-		ggp_account_token_cb_call(reqdata, NULL);
+		ggp_account_token_cb_call(reqdata, NULL, TRUE);
 		return;
 	}
 	
+	purple_debug_info("gg", "ggp_account_token_handler: got token\n");
 	
 	token = g_new(ggp_account_token, 1);
 	
@@ -104,5 +141,165 @@
 	token->size = reqdata->h->body_size;
 	token->data = g_memdup(reqdata->h->body, token->size);
 	
-	ggp_account_token_cb_call(reqdata, token);
+	ggp_account_token_cb_call(reqdata, token, FALSE);
 }
+
+/*******************************************************************************
+ * New account registration.
+ ******************************************************************************/
+
+typedef struct
+{
+	ggp_account_token *token;
+	PurpleConnection *gc;
+} ggp_account_register_data;
+
+static void ggp_account_register_dialog(PurpleConnection *gc, ggp_account_token *token, gpointer user_data);
+static void ggp_account_register_dialog_ok(ggp_account_register_data *register_data, PurpleRequestFields *fields);
+static void ggp_account_register_dialog_cancel(ggp_account_register_data *register_data, PurpleRequestFields *fields);
+static void ggp_account_register_completed(ggp_account_register_data *register_data, gboolean success);
+
+/******************************************************************************/
+
+static void ggp_account_register_completed(ggp_account_register_data *register_data, gboolean success)
+{
+	PurpleAccount *account = purple_connection_get_account(register_data->gc);
+	
+	ggp_account_token_free(register_data->token);
+	g_free(register_data);
+	
+	purple_account_disconnect(account);
+	purple_account_register_completed(account, TRUE);
+}
+
+void ggp_account_register(PurpleAccount *account)
+{
+	PurpleConnection *gc = purple_account_get_connection(account);
+	
+	purple_debug_info("gg", "ggp_account_register\n");
+	
+	ggp_account_token_request(gc, ggp_account_register_dialog, NULL);
+}
+
+static void ggp_account_register_dialog(PurpleConnection *gc, ggp_account_token *token, gpointer user_data)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+	PurpleRequestFields *fields;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestField *field;
+	ggp_account_register_data *register_data;
+	
+	purple_debug_info("gg", "ggp_account_register_dialog(%x, %x, %x)\n",
+		(unsigned int)gc, (unsigned int)token, (unsigned int)user_data);
+	if (!token)
+	{
+		purple_account_disconnect(account);
+		purple_account_register_completed(account, FALSE);
+		return;
+	}
+	
+	// TODO: required fields
+	fields = purple_request_fields_new();
+	group = purple_request_field_group_new(NULL);
+	purple_request_fields_add_group(fields, group);
+	
+	field = purple_request_field_string_new("email", _("Email"), "", FALSE);
+	purple_request_field_group_add_field(group, field);
+	
+	field = purple_request_field_string_new("password1", _("Password"), "",
+		FALSE);
+	purple_request_field_string_set_masked(field, TRUE);
+	purple_request_field_group_add_field(group, field);
+	
+	field = purple_request_field_string_new("password2", _("Password (again)"), "",
+		FALSE);
+	purple_request_field_string_set_masked(field, TRUE);
+	purple_request_field_group_add_field(group, field);
+	
+	//TODO: move it into a new group?
+	field = purple_request_field_string_new("token_value",
+		_("Enter captcha text"), "", FALSE);
+	purple_request_field_group_add_field(group, field);
+	
+	field = purple_request_field_image_new("token_image", _("Captcha"),
+		token->data, token->size);
+	purple_request_field_group_add_field(group, field);
+	
+	register_data = g_new(ggp_account_register_data, 1);
+	register_data->gc = gc;
+	register_data->token = token;
+	
+	purple_request_fields(gc,
+		_("Register New Gadu-Gadu Account"),
+		_("Register New Gadu-Gadu Account"),
+		_("Please, fill in the following fields"), fields,
+		_("OK"), G_CALLBACK(ggp_account_register_dialog_ok),
+		_("Cancel"), G_CALLBACK(ggp_account_register_dialog_cancel),
+		account, NULL, NULL, register_data);
+}
+
+static void ggp_account_register_dialog_cancel(ggp_account_register_data *register_data, PurpleRequestFields *fields)
+{
+	purple_debug_info("gg", "ggp_account_register_dialog_cancel(%x, %x)\n",
+		(unsigned int)register_data, (unsigned int)fields);
+
+	ggp_account_register_completed(register_data, FALSE);
+}
+
+static void ggp_account_register_dialog_ok(ggp_account_register_data *register_data, PurpleRequestFields *fields)
+{
+	PurpleAccount *account = purple_connection_get_account(register_data->gc);
+	const gchar *email, *password1, *password2, *token_value;
+	struct gg_http *h;
+	struct gg_pubdir *register_result;
+	uin_t uin;
+
+	purple_debug_info("gg", "ggp_account_register_dialog_ok(%x, %x)\n",
+		(unsigned int)register_data, (unsigned int)fields);
+
+	email = purple_request_fields_get_string(fields, "email");
+	password1 = purple_request_fields_get_string(fields, "password1");
+	password2 = purple_request_fields_get_string(fields, "password2");
+	token_value = purple_request_fields_get_string(fields, "token_value");
+
+	g_assert(email != NULL);
+	g_assert(password1 != NULL);
+	g_assert(password2 != NULL);
+	g_assert(token_value != NULL);
+
+	if (g_utf8_collate(password1, password2) != 0)
+	{
+		purple_debug_warning("gg", "ggp_account_register_dialog_ok: validation failed - passwords does not match\n");
+		purple_notify_error(purple_connection_get_account(register_data->gc),
+			_("TODO: title"),
+			_("Passwords do not match"), NULL);
+		ggp_account_register_completed(register_data, FALSE);
+		return;
+	}
+
+	purple_debug_info("gg", "ggp_account_register_dialog_ok: validation ok [token id=%s, value=%s]\n",
+		register_data->token->id, token_value);
+	h = gg_register3(email, password1, register_data->token->id, token_value, 0); // TODO: async (use code from ggp_account_token_handler)
+	if (h == NULL || !(register_result = h->data) || !register_result->success)
+	{



More information about the Commits mailing list